xref: /linux/sound/soc/codecs/sma1307.c (revision 576c57e6b4c1d734bcb7cc33dde9a99a9383b520)
1*576c57e6SKiseok Jo // SPDX-License-Identifier: GPL-2.0-or-later
2*576c57e6SKiseok Jo // sma1307.c -- sma1307 ALSA SoC Audio driver
3*576c57e6SKiseok Jo //
4*576c57e6SKiseok Jo // Copyright 2024 Iron Device Corporation
5*576c57e6SKiseok Jo //
6*576c57e6SKiseok Jo // Auther: Gyuhwa Park <gyuwha.park@irondevice.com>
7*576c57e6SKiseok Jo // Auther: Kiseok Jo <kiseok.jo@irondevice.com>
8*576c57e6SKiseok Jo 
9*576c57e6SKiseok Jo #include <linux/firmware.h>
10*576c57e6SKiseok Jo #include <linux/i2c.h>
11*576c57e6SKiseok Jo #include <linux/of_gpio.h>
12*576c57e6SKiseok Jo #include <linux/regmap.h>
13*576c57e6SKiseok Jo #include <sound/pcm_params.h>
14*576c57e6SKiseok Jo #include <sound/tlv.h>
15*576c57e6SKiseok Jo #include "sma1307.h"
16*576c57e6SKiseok Jo 
17*576c57e6SKiseok Jo #define CHECK_PERIOD_TIME 1	/* sec per HZ */
18*576c57e6SKiseok Jo #define PLL_MATCH(_input_clk_name, _output_clk_name, _input_clk,\
19*576c57e6SKiseok Jo 		_post_n, _n, _vco,  _p_cp)\
20*576c57e6SKiseok Jo {\
21*576c57e6SKiseok Jo 	.input_clk_name		= _input_clk_name,\
22*576c57e6SKiseok Jo 	.output_clk_name	= _output_clk_name,\
23*576c57e6SKiseok Jo 	.input_clk		= _input_clk,\
24*576c57e6SKiseok Jo 	.post_n			= _post_n,\
25*576c57e6SKiseok Jo 	.n			= _n,\
26*576c57e6SKiseok Jo 	.vco			= _vco,\
27*576c57e6SKiseok Jo 	.p_cp			= _p_cp,\
28*576c57e6SKiseok Jo }
29*576c57e6SKiseok Jo 
30*576c57e6SKiseok Jo static const char *setting_file = "sma1307_setting.bin";
31*576c57e6SKiseok Jo #define SMA1307_SETTING_CHECKSUM 0x100000
32*576c57e6SKiseok Jo 
33*576c57e6SKiseok Jo /* PLL clock setting Table */
34*576c57e6SKiseok Jo struct sma1307_pll_match {
35*576c57e6SKiseok Jo 	char *input_clk_name;
36*576c57e6SKiseok Jo 	char *output_clk_name;
37*576c57e6SKiseok Jo 	unsigned int input_clk;
38*576c57e6SKiseok Jo 	unsigned int post_n;
39*576c57e6SKiseok Jo 	unsigned int n;
40*576c57e6SKiseok Jo 	unsigned int vco;
41*576c57e6SKiseok Jo 	unsigned int p_cp;
42*576c57e6SKiseok Jo };
43*576c57e6SKiseok Jo 
44*576c57e6SKiseok Jo struct sma1307_data {
45*576c57e6SKiseok Jo 	char *name;
46*576c57e6SKiseok Jo 	void (*init)(struct regmap *regmap);
47*576c57e6SKiseok Jo };
48*576c57e6SKiseok Jo 
49*576c57e6SKiseok Jo struct sma1307_priv {
50*576c57e6SKiseok Jo 	bool check_fault_status;
51*576c57e6SKiseok Jo 	bool force_mute_status;
52*576c57e6SKiseok Jo 	bool sw_ot1_prot;
53*576c57e6SKiseok Jo 	char *name;
54*576c57e6SKiseok Jo 	enum sma1307_mode amp_mode;
55*576c57e6SKiseok Jo 	int binary_mode;
56*576c57e6SKiseok Jo 	int dapm_aif_in;
57*576c57e6SKiseok Jo 	int dapm_aif_out0;
58*576c57e6SKiseok Jo 	int dapm_aif_out1;
59*576c57e6SKiseok Jo 	int dapm_sdo_en;
60*576c57e6SKiseok Jo 	int dapm_sdo_setting;
61*576c57e6SKiseok Jo 	int num_of_pll_matches;
62*576c57e6SKiseok Jo 	int check_fault_period;
63*576c57e6SKiseok Jo 	struct delayed_work check_fault_work;
64*576c57e6SKiseok Jo 	struct device *dev;
65*576c57e6SKiseok Jo 	struct kobject *kobj;
66*576c57e6SKiseok Jo 	struct mutex default_lock;
67*576c57e6SKiseok Jo 	struct regmap *regmap;
68*576c57e6SKiseok Jo 	struct sma1307_setting_file set;
69*576c57e6SKiseok Jo 	const struct sma1307_pll_match *pll_matches;
70*576c57e6SKiseok Jo 	const struct sma1307_data *data;
71*576c57e6SKiseok Jo 	unsigned int cur_vol;
72*576c57e6SKiseok Jo 	unsigned int format;
73*576c57e6SKiseok Jo 	unsigned int frame_size;
74*576c57e6SKiseok Jo 	unsigned int init_vol;
75*576c57e6SKiseok Jo 	unsigned int last_bclk;
76*576c57e6SKiseok Jo 	unsigned int otp_trm2;
77*576c57e6SKiseok Jo 	unsigned int otp_trm3;
78*576c57e6SKiseok Jo 	unsigned int rev_num;
79*576c57e6SKiseok Jo 	unsigned int sys_clk_id;
80*576c57e6SKiseok Jo 	unsigned int tdm_slot0_rx;
81*576c57e6SKiseok Jo 	unsigned int tdm_slot1_rx;
82*576c57e6SKiseok Jo 	unsigned int tdm_slot0_tx;
83*576c57e6SKiseok Jo 	unsigned int tdm_slot1_tx;
84*576c57e6SKiseok Jo 	unsigned int tsdw_cnt;
85*576c57e6SKiseok Jo };
86*576c57e6SKiseok Jo 
87*576c57e6SKiseok Jo static const struct sma1307_pll_match sma1307_pll_matches[] = {
88*576c57e6SKiseok Jo 	/* in_clk_name, out_clk_name, input_clk post_n, n, vco, p_cp */
89*576c57e6SKiseok Jo 	PLL_MATCH("1.411MHz", "24.554MHz",
90*576c57e6SKiseok Jo 		  1411200, 0x06, 0xD1, 0x88, 0x00),
91*576c57e6SKiseok Jo 	PLL_MATCH("1.536MHz", "24.576MHz",
92*576c57e6SKiseok Jo 		  1536000, 0x06, 0xC0, 0x88, 0x00),
93*576c57e6SKiseok Jo 	PLL_MATCH("2.822MHz", "24.554MHz",
94*576c57e6SKiseok Jo 		  2822400, 0x06, 0xD1, 0x88, 0x04),
95*576c57e6SKiseok Jo 	PLL_MATCH("3.072MHz", "24.576MHz",
96*576c57e6SKiseok Jo 		  3072000, 0x06, 0x60, 0x88, 0x00),
97*576c57e6SKiseok Jo 	PLL_MATCH("6.144MHz", "24.576MHz",
98*576c57e6SKiseok Jo 		  6144000, 0x06, 0x60, 0x88, 0x04),
99*576c57e6SKiseok Jo 	PLL_MATCH("12.288MHz", "24.576MHz",
100*576c57e6SKiseok Jo 		  12288000, 0x06, 0x60, 0x88, 0x08),
101*576c57e6SKiseok Jo 	PLL_MATCH("19.2MHz", "24.48MHz",
102*576c57e6SKiseok Jo 		  19200000, 0x06, 0x7B, 0x88, 0x0C),
103*576c57e6SKiseok Jo 	PLL_MATCH("24.576MHz", "24.576MHz",
104*576c57e6SKiseok Jo 		  24576000, 0x06, 0x60, 0x88, 0x0C),
105*576c57e6SKiseok Jo };
106*576c57e6SKiseok Jo 
107*576c57e6SKiseok Jo static struct snd_soc_component *sma1307_amp_component;
108*576c57e6SKiseok Jo 
109*576c57e6SKiseok Jo static void sma1307_startup(struct snd_soc_component *);
110*576c57e6SKiseok Jo static void sma1307_shutdown(struct snd_soc_component *);
111*576c57e6SKiseok Jo static void sma1307_reset(struct snd_soc_component *);
112*576c57e6SKiseok Jo static void sma1307_set_binary(struct snd_soc_component *);
113*576c57e6SKiseok Jo static void sma1307_set_default(struct snd_soc_component *);
114*576c57e6SKiseok Jo 
115*576c57e6SKiseok Jo /* Initial register value - 6.0W SPK (8ohm load)  */
116*576c57e6SKiseok Jo static const struct reg_default sma1307_reg_def[] = {
117*576c57e6SKiseok Jo 	{ 0x00, 0x80 },
118*576c57e6SKiseok Jo 	{ 0x01, 0x00 },
119*576c57e6SKiseok Jo 	{ 0x02, 0x52 },
120*576c57e6SKiseok Jo 	{ 0x03, 0x4C },
121*576c57e6SKiseok Jo 	{ 0x04, 0x47 },
122*576c57e6SKiseok Jo 	{ 0x05, 0x42 },
123*576c57e6SKiseok Jo 	{ 0x06, 0x40 },
124*576c57e6SKiseok Jo 	{ 0x07, 0x40 },
125*576c57e6SKiseok Jo 	{ 0x08, 0x3C },
126*576c57e6SKiseok Jo 	{ 0x09, 0x2F },
127*576c57e6SKiseok Jo 	{ 0x0A, 0x32 },
128*576c57e6SKiseok Jo 	{ 0x0B, 0x50 },
129*576c57e6SKiseok Jo 	{ 0x0C, 0x8C },
130*576c57e6SKiseok Jo 	{ 0x0D, 0x00 },
131*576c57e6SKiseok Jo 	{ 0x0E, 0x3F },
132*576c57e6SKiseok Jo 	{ 0x0F, 0x00 },
133*576c57e6SKiseok Jo 	{ 0x10, 0x00 },
134*576c57e6SKiseok Jo 	{ 0x11, 0x00 },
135*576c57e6SKiseok Jo 	{ 0x12, 0x00 },
136*576c57e6SKiseok Jo 	{ 0x13, 0x09 },
137*576c57e6SKiseok Jo 	{ 0x14, 0x12 },
138*576c57e6SKiseok Jo 	{ 0x1C, 0x00 },
139*576c57e6SKiseok Jo 	{ 0x1D, 0x85 },
140*576c57e6SKiseok Jo 	{ 0x1E, 0xA1 },
141*576c57e6SKiseok Jo 	{ 0x1F, 0x67 },
142*576c57e6SKiseok Jo 	{ 0x22, 0x00 },
143*576c57e6SKiseok Jo 	{ 0x23, 0x1F },
144*576c57e6SKiseok Jo 	{ 0x24, 0x7A },
145*576c57e6SKiseok Jo 	{ 0x25, 0x00 },
146*576c57e6SKiseok Jo 	{ 0x26, 0xFF },
147*576c57e6SKiseok Jo 	{ 0x27, 0x39 },
148*576c57e6SKiseok Jo 	{ 0x28, 0x54 },
149*576c57e6SKiseok Jo 	{ 0x29, 0x92 },
150*576c57e6SKiseok Jo 	{ 0x2A, 0xB0 },
151*576c57e6SKiseok Jo 	{ 0x2B, 0xED },
152*576c57e6SKiseok Jo 	{ 0x2C, 0xED },
153*576c57e6SKiseok Jo 	{ 0x2D, 0xFF },
154*576c57e6SKiseok Jo 	{ 0x2E, 0xFF },
155*576c57e6SKiseok Jo 	{ 0x2F, 0xFF },
156*576c57e6SKiseok Jo 	{ 0x30, 0xFF },
157*576c57e6SKiseok Jo 	{ 0x31, 0xFF },
158*576c57e6SKiseok Jo 	{ 0x32, 0xFF },
159*576c57e6SKiseok Jo 	{ 0x34, 0x01 },
160*576c57e6SKiseok Jo 	{ 0x35, 0x17 },
161*576c57e6SKiseok Jo 	{ 0x36, 0x92 },
162*576c57e6SKiseok Jo 	{ 0x37, 0x00 },
163*576c57e6SKiseok Jo 	{ 0x38, 0x01 },
164*576c57e6SKiseok Jo 	{ 0x39, 0x10 },
165*576c57e6SKiseok Jo 	{ 0x3E, 0x01 },
166*576c57e6SKiseok Jo 	{ 0x3F, 0x08 },
167*576c57e6SKiseok Jo 	{ 0x8B, 0x05 },
168*576c57e6SKiseok Jo 	{ 0x8C, 0x50 },
169*576c57e6SKiseok Jo 	{ 0x8D, 0x80 },
170*576c57e6SKiseok Jo 	{ 0x8E, 0x10 },
171*576c57e6SKiseok Jo 	{ 0x8F, 0x02 },
172*576c57e6SKiseok Jo 	{ 0x90, 0x02 },
173*576c57e6SKiseok Jo 	{ 0x91, 0x83 },
174*576c57e6SKiseok Jo 	{ 0x92, 0xC0 },
175*576c57e6SKiseok Jo 	{ 0x93, 0x00 },
176*576c57e6SKiseok Jo 	{ 0x94, 0xA4 },
177*576c57e6SKiseok Jo 	{ 0x95, 0x74 },
178*576c57e6SKiseok Jo 	{ 0x96, 0x57 },
179*576c57e6SKiseok Jo 	{ 0xA2, 0xCC },
180*576c57e6SKiseok Jo 	{ 0xA3, 0x28 },
181*576c57e6SKiseok Jo 	{ 0xA4, 0x40 },
182*576c57e6SKiseok Jo 	{ 0xA5, 0x01 },
183*576c57e6SKiseok Jo 	{ 0xA6, 0x41 },
184*576c57e6SKiseok Jo 	{ 0xA7, 0x08 },
185*576c57e6SKiseok Jo 	{ 0xA8, 0x04 },
186*576c57e6SKiseok Jo 	{ 0xA9, 0x27 },
187*576c57e6SKiseok Jo 	{ 0xAA, 0x10 },
188*576c57e6SKiseok Jo 	{ 0xAB, 0x10 },
189*576c57e6SKiseok Jo 	{ 0xAC, 0x10 },
190*576c57e6SKiseok Jo 	{ 0xAD, 0x0F },
191*576c57e6SKiseok Jo 	{ 0xAE, 0xCD },
192*576c57e6SKiseok Jo 	{ 0xAF, 0x70 },
193*576c57e6SKiseok Jo 	{ 0xB0, 0x03 },
194*576c57e6SKiseok Jo 	{ 0xB1, 0xEF },
195*576c57e6SKiseok Jo 	{ 0xB2, 0x03 },
196*576c57e6SKiseok Jo 	{ 0xB3, 0xEF },
197*576c57e6SKiseok Jo 	{ 0xB4, 0xF3 },
198*576c57e6SKiseok Jo 	{ 0xB5, 0x3D },
199*576c57e6SKiseok Jo };
200*576c57e6SKiseok Jo 
201*576c57e6SKiseok Jo static bool sma1307_readable_register(struct device *dev, unsigned int reg)
202*576c57e6SKiseok Jo {
203*576c57e6SKiseok Jo 	if (reg > SMA1307_FF_DEVICE_INDEX)
204*576c57e6SKiseok Jo 		return false;
205*576c57e6SKiseok Jo 
206*576c57e6SKiseok Jo 	switch (reg) {
207*576c57e6SKiseok Jo 	case SMA1307_00_SYSTEM_CTRL ... SMA1307_1F_TONE_FINE_VOLUME:
208*576c57e6SKiseok Jo 	case SMA1307_22_COMP_HYS_SEL ... SMA1307_32_BROWN_OUT_PROT19:
209*576c57e6SKiseok Jo 	case SMA1307_34_OCP_SPK ... SMA1307_39_PMT_NZ_VAL:
210*576c57e6SKiseok Jo 	case SMA1307_3B_TEST1 ... SMA1307_3F_ATEST2:
211*576c57e6SKiseok Jo 	case SMA1307_8B_PLL_POST_N ... SMA1307_9A_OTP_TRM3:
212*576c57e6SKiseok Jo 	case SMA1307_A0_PAD_CTRL0 ... SMA1307_BE_MCBS_CTRL2:
213*576c57e6SKiseok Jo 	case SMA1307_F5_READY_FOR_V_SAR:
214*576c57e6SKiseok Jo 	case SMA1307_F7_READY_FOR_T_SAR ... SMA1307_FF_DEVICE_INDEX:
215*576c57e6SKiseok Jo 		break;
216*576c57e6SKiseok Jo 	default:
217*576c57e6SKiseok Jo 		return false;
218*576c57e6SKiseok Jo 	}
219*576c57e6SKiseok Jo 	return true;
220*576c57e6SKiseok Jo }
221*576c57e6SKiseok Jo 
222*576c57e6SKiseok Jo static bool sma1307_writeable_register(struct device *dev, unsigned int reg)
223*576c57e6SKiseok Jo {
224*576c57e6SKiseok Jo 	if (reg > SMA1307_FF_DEVICE_INDEX)
225*576c57e6SKiseok Jo 		return false;
226*576c57e6SKiseok Jo 
227*576c57e6SKiseok Jo 	switch (reg) {
228*576c57e6SKiseok Jo 	case SMA1307_00_SYSTEM_CTRL ... SMA1307_1F_TONE_FINE_VOLUME:
229*576c57e6SKiseok Jo 	case SMA1307_22_COMP_HYS_SEL ... SMA1307_32_BROWN_OUT_PROT19:
230*576c57e6SKiseok Jo 	case SMA1307_34_OCP_SPK ... SMA1307_39_PMT_NZ_VAL:
231*576c57e6SKiseok Jo 	case SMA1307_3B_TEST1 ... SMA1307_3F_ATEST2:
232*576c57e6SKiseok Jo 	case SMA1307_8B_PLL_POST_N ... SMA1307_9A_OTP_TRM3:
233*576c57e6SKiseok Jo 	case SMA1307_A0_PAD_CTRL0 ... SMA1307_BE_MCBS_CTRL2:
234*576c57e6SKiseok Jo 		break;
235*576c57e6SKiseok Jo 	default:
236*576c57e6SKiseok Jo 		return false;
237*576c57e6SKiseok Jo 	}
238*576c57e6SKiseok Jo 	return true;
239*576c57e6SKiseok Jo }
240*576c57e6SKiseok Jo 
241*576c57e6SKiseok Jo static bool sma1307_volatile_register(struct device *dev, unsigned int reg)
242*576c57e6SKiseok Jo {
243*576c57e6SKiseok Jo 	if (reg > SMA1307_FF_DEVICE_INDEX)
244*576c57e6SKiseok Jo 		return false;
245*576c57e6SKiseok Jo 
246*576c57e6SKiseok Jo 	switch (reg) {
247*576c57e6SKiseok Jo 	case SMA1307_F8_STATUS_T1 ... SMA1307_FF_DEVICE_INDEX:
248*576c57e6SKiseok Jo 		break;
249*576c57e6SKiseok Jo 	default:
250*576c57e6SKiseok Jo 		return false;
251*576c57e6SKiseok Jo 	}
252*576c57e6SKiseok Jo 	return true;
253*576c57e6SKiseok Jo }
254*576c57e6SKiseok Jo 
255*576c57e6SKiseok Jo /* DB scale conversion of speaker volume */
256*576c57e6SKiseok Jo static const DECLARE_TLV_DB_SCALE(sma1307_spk_tlv, -6000, 50, 0);
257*576c57e6SKiseok Jo 
258*576c57e6SKiseok Jo static const char *const sma1307_aif_in_source_text[] = {
259*576c57e6SKiseok Jo 	"Mono", "Left", "Right"
260*576c57e6SKiseok Jo };
261*576c57e6SKiseok Jo 
262*576c57e6SKiseok Jo static const char *const sma1307_sdo_setting_text[] = {
263*576c57e6SKiseok Jo 	"Data_One_48k", "Data_Two_48k", "Data_Two_24k",
264*576c57e6SKiseok Jo 	"Clk_PLL", "Clk_OSC"
265*576c57e6SKiseok Jo };
266*576c57e6SKiseok Jo 
267*576c57e6SKiseok Jo static const char *const sma1307_aif_out_source_text[] = {
268*576c57e6SKiseok Jo 	"Disable", "After_FmtC", "After_Mixer", "After_DSP",
269*576c57e6SKiseok Jo 	"Vrms2_Avg", "Battery", "Temperature", "After_Delay"
270*576c57e6SKiseok Jo };
271*576c57e6SKiseok Jo 
272*576c57e6SKiseok Jo static const char *const sma1307_tdm_slot_text[] = {
273*576c57e6SKiseok Jo 	"Slot0", "Slot1", "Slot2", "Slot3",
274*576c57e6SKiseok Jo 	"Slot4", "Slot5", "Slot6", "Slot7"
275*576c57e6SKiseok Jo };
276*576c57e6SKiseok Jo 
277*576c57e6SKiseok Jo static const char *const sma1307_binary_mode_text[] = {
278*576c57e6SKiseok Jo 	"Mode0", "Mode1", "Mode2", "Mode3", "Mode4"
279*576c57e6SKiseok Jo };
280*576c57e6SKiseok Jo 
281*576c57e6SKiseok Jo static const char *const sma1307_reset_text[] = {
282*576c57e6SKiseok Jo 	"Reset"
283*576c57e6SKiseok Jo };
284*576c57e6SKiseok Jo 
285*576c57e6SKiseok Jo static const struct soc_enum sma1307_aif_in_source_enum =
286*576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_aif_in_source_text),
287*576c57e6SKiseok Jo 		    sma1307_aif_in_source_text);
288*576c57e6SKiseok Jo static const struct soc_enum sma1307_sdo_setting_enum =
289*576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_sdo_setting_text),
290*576c57e6SKiseok Jo 		    sma1307_sdo_setting_text);
291*576c57e6SKiseok Jo static const struct soc_enum sma1307_aif_out_source_enum =
292*576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_aif_out_source_text),
293*576c57e6SKiseok Jo 		    sma1307_aif_out_source_text);
294*576c57e6SKiseok Jo static const struct soc_enum sma1307_tdm_slot_enum =
295*576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_tdm_slot_text),
296*576c57e6SKiseok Jo 		    sma1307_tdm_slot_text);
297*576c57e6SKiseok Jo static const struct soc_enum sma1307_binary_mode_enum =
298*576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_binary_mode_text),
299*576c57e6SKiseok Jo 		    sma1307_binary_mode_text);
300*576c57e6SKiseok Jo static const struct soc_enum sma1307_reset_enum =
301*576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_reset_text),
302*576c57e6SKiseok Jo 		    sma1307_reset_text);
303*576c57e6SKiseok Jo 
304*576c57e6SKiseok Jo static int sma1307_force_mute_get(struct snd_kcontrol *kcontrol,
305*576c57e6SKiseok Jo 				  struct snd_ctl_elem_value *ucontrol)
306*576c57e6SKiseok Jo {
307*576c57e6SKiseok Jo 	struct snd_soc_component *component =
308*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
309*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
310*576c57e6SKiseok Jo 
311*576c57e6SKiseok Jo 	ucontrol->value.integer.value[0] = (int)sma1307->force_mute_status;
312*576c57e6SKiseok Jo 
313*576c57e6SKiseok Jo 	return 0;
314*576c57e6SKiseok Jo }
315*576c57e6SKiseok Jo 
316*576c57e6SKiseok Jo static int sma1307_force_mute_put(struct snd_kcontrol *kcontrol,
317*576c57e6SKiseok Jo 				  struct snd_ctl_elem_value *ucontrol)
318*576c57e6SKiseok Jo {
319*576c57e6SKiseok Jo 	struct snd_soc_component *component =
320*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
321*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
322*576c57e6SKiseok Jo 	bool change = false, val = (bool)ucontrol->value.integer.value[0];
323*576c57e6SKiseok Jo 
324*576c57e6SKiseok Jo 	if (sma1307->force_mute_status == val) {
325*576c57e6SKiseok Jo 		change = false;
326*576c57e6SKiseok Jo 	} else {
327*576c57e6SKiseok Jo 		change = true;
328*576c57e6SKiseok Jo 		sma1307->force_mute_status = val;
329*576c57e6SKiseok Jo 	}
330*576c57e6SKiseok Jo 
331*576c57e6SKiseok Jo 	return change;
332*576c57e6SKiseok Jo }
333*576c57e6SKiseok Jo 
334*576c57e6SKiseok Jo static int sma1307_tdm_slot_get(struct snd_kcontrol *kcontrol,
335*576c57e6SKiseok Jo 				struct snd_ctl_elem_value *ucontrol)
336*576c57e6SKiseok Jo {
337*576c57e6SKiseok Jo 	struct snd_soc_component *component =
338*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
339*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
340*576c57e6SKiseok Jo 	int val1, val2;
341*576c57e6SKiseok Jo 
342*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_A5_TDM1, &val1);
343*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_A6_TDM2, &val2);
344*576c57e6SKiseok Jo 
345*576c57e6SKiseok Jo 	if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX0_POS_NAME)) {
346*576c57e6SKiseok Jo 		ucontrol->value.integer.value[0]
347*576c57e6SKiseok Jo 		    = (val1 & SMA1307_TDM_SLOT0_RX_POS_MASK) >> 3;
348*576c57e6SKiseok Jo 		sma1307->tdm_slot0_rx = ucontrol->value.integer.value[0];
349*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX1_POS_NAME)) {
350*576c57e6SKiseok Jo 		ucontrol->value.integer.value[0]
351*576c57e6SKiseok Jo 		    = val1 & SMA1307_TDM_SLOT1_RX_POS_MASK;
352*576c57e6SKiseok Jo 		sma1307->tdm_slot1_rx = ucontrol->value.integer.value[0];
353*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX0_POS_NAME)) {
354*576c57e6SKiseok Jo 		ucontrol->value.integer.value[0]
355*576c57e6SKiseok Jo 		    = (val2 & SMA1307_TDM_SLOT0_TX_POS_MASK) >> 3;
356*576c57e6SKiseok Jo 		sma1307->tdm_slot0_tx = ucontrol->value.integer.value[0];
357*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX1_POS_NAME)) {
358*576c57e6SKiseok Jo 		ucontrol->value.integer.value[0]
359*576c57e6SKiseok Jo 		    = val2 & SMA1307_TDM_SLOT1_TX_POS_MASK;
360*576c57e6SKiseok Jo 		sma1307->tdm_slot1_tx = ucontrol->value.integer.value[0];
361*576c57e6SKiseok Jo 	} else {
362*576c57e6SKiseok Jo 		return -EINVAL;
363*576c57e6SKiseok Jo 	}
364*576c57e6SKiseok Jo 
365*576c57e6SKiseok Jo 	return 0;
366*576c57e6SKiseok Jo }
367*576c57e6SKiseok Jo 
368*576c57e6SKiseok Jo static int sma1307_tdm_slot_put(struct snd_kcontrol *kcontrol,
369*576c57e6SKiseok Jo 				struct snd_ctl_elem_value *ucontrol)
370*576c57e6SKiseok Jo {
371*576c57e6SKiseok Jo 	struct snd_soc_component *component =
372*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
373*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
374*576c57e6SKiseok Jo 	int val = (int)ucontrol->value.integer.value[0];
375*576c57e6SKiseok Jo 	bool change;
376*576c57e6SKiseok Jo 
377*576c57e6SKiseok Jo 	if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX0_POS_NAME)) {
378*576c57e6SKiseok Jo 		if (sma1307->tdm_slot0_rx == val)
379*576c57e6SKiseok Jo 			change = false;
380*576c57e6SKiseok Jo 		else {
381*576c57e6SKiseok Jo 			change = true;
382*576c57e6SKiseok Jo 			sma1307->tdm_slot0_rx = val;
383*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap, SMA1307_A5_TDM1,
384*576c57e6SKiseok Jo 				SMA1307_TDM_SLOT0_RX_POS_MASK, val << 3);
385*576c57e6SKiseok Jo 		}
386*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX1_POS_NAME)) {
387*576c57e6SKiseok Jo 		if (sma1307->tdm_slot1_rx == val)
388*576c57e6SKiseok Jo 			change = false;
389*576c57e6SKiseok Jo 		else {
390*576c57e6SKiseok Jo 			change = true;
391*576c57e6SKiseok Jo 			sma1307->tdm_slot1_rx = val;
392*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap, SMA1307_A5_TDM1,
393*576c57e6SKiseok Jo 				SMA1307_TDM_SLOT1_RX_POS_MASK, val);
394*576c57e6SKiseok Jo 		}
395*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX0_POS_NAME)) {
396*576c57e6SKiseok Jo 		if (sma1307->tdm_slot0_tx == val)
397*576c57e6SKiseok Jo 			change = false;
398*576c57e6SKiseok Jo 		else {
399*576c57e6SKiseok Jo 			change = true;
400*576c57e6SKiseok Jo 			sma1307->tdm_slot0_tx = val;
401*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap, SMA1307_A6_TDM2,
402*576c57e6SKiseok Jo 				SMA1307_TDM_SLOT0_TX_POS_MASK, val << 3);
403*576c57e6SKiseok Jo 		}
404*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX1_POS_NAME)) {
405*576c57e6SKiseok Jo 		if (sma1307->tdm_slot1_tx == val)
406*576c57e6SKiseok Jo 			change = false;
407*576c57e6SKiseok Jo 		else {
408*576c57e6SKiseok Jo 			change = true;
409*576c57e6SKiseok Jo 			sma1307->tdm_slot1_tx = val;
410*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap, SMA1307_A6_TDM2,
411*576c57e6SKiseok Jo 				SMA1307_TDM_SLOT1_TX_POS_MASK, val);
412*576c57e6SKiseok Jo 		}
413*576c57e6SKiseok Jo 	} else {
414*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Invalid Control ID - %s\n",
415*576c57e6SKiseok Jo 			__func__, kcontrol->id.name);
416*576c57e6SKiseok Jo 		return -EINVAL;
417*576c57e6SKiseok Jo 	}
418*576c57e6SKiseok Jo 
419*576c57e6SKiseok Jo 	return change;
420*576c57e6SKiseok Jo }
421*576c57e6SKiseok Jo 
422*576c57e6SKiseok Jo static int sma1307_sw_ot1_prot_get(struct snd_kcontrol *kcontrol,
423*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
424*576c57e6SKiseok Jo {
425*576c57e6SKiseok Jo 	struct snd_soc_component *component =
426*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
427*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
428*576c57e6SKiseok Jo 
429*576c57e6SKiseok Jo 	ucontrol->value.integer.value[0] = (int)sma1307->sw_ot1_prot;
430*576c57e6SKiseok Jo 
431*576c57e6SKiseok Jo 	return 0;
432*576c57e6SKiseok Jo }
433*576c57e6SKiseok Jo 
434*576c57e6SKiseok Jo static int sma1307_sw_ot1_prot_put(struct snd_kcontrol *kcontrol,
435*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
436*576c57e6SKiseok Jo {
437*576c57e6SKiseok Jo 	struct snd_soc_component *component =
438*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
439*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
440*576c57e6SKiseok Jo 	bool change = false, val = (bool)ucontrol->value.integer.value[0];
441*576c57e6SKiseok Jo 
442*576c57e6SKiseok Jo 	if (sma1307->sw_ot1_prot == val)
443*576c57e6SKiseok Jo 		change = false;
444*576c57e6SKiseok Jo 	else {
445*576c57e6SKiseok Jo 		change = true;
446*576c57e6SKiseok Jo 		sma1307->sw_ot1_prot = val;
447*576c57e6SKiseok Jo 	}
448*576c57e6SKiseok Jo 
449*576c57e6SKiseok Jo 	return change;
450*576c57e6SKiseok Jo }
451*576c57e6SKiseok Jo 
452*576c57e6SKiseok Jo static int sma1307_check_fault_status_get(struct snd_kcontrol *kcontrol,
453*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
454*576c57e6SKiseok Jo {
455*576c57e6SKiseok Jo 	struct snd_soc_component *component =
456*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
457*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
458*576c57e6SKiseok Jo 
459*576c57e6SKiseok Jo 	ucontrol->value.integer.value[0] = (int)sma1307->check_fault_status;
460*576c57e6SKiseok Jo 
461*576c57e6SKiseok Jo 	return 0;
462*576c57e6SKiseok Jo }
463*576c57e6SKiseok Jo 
464*576c57e6SKiseok Jo static int sma1307_check_fault_status_put(struct snd_kcontrol *kcontrol,
465*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
466*576c57e6SKiseok Jo {
467*576c57e6SKiseok Jo 	struct snd_soc_component *component =
468*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
469*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
470*576c57e6SKiseok Jo 	bool change = false, val = (bool)ucontrol->value.integer.value[0];
471*576c57e6SKiseok Jo 
472*576c57e6SKiseok Jo 	if (sma1307->check_fault_status == val) {
473*576c57e6SKiseok Jo 		change = false;
474*576c57e6SKiseok Jo 	} else {
475*576c57e6SKiseok Jo 		change = true;
476*576c57e6SKiseok Jo 		sma1307->check_fault_status = val;
477*576c57e6SKiseok Jo 	}
478*576c57e6SKiseok Jo 
479*576c57e6SKiseok Jo 	return change;
480*576c57e6SKiseok Jo }
481*576c57e6SKiseok Jo 
482*576c57e6SKiseok Jo static int sma1307_check_fault_period_get(struct snd_kcontrol *kcontrol,
483*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
484*576c57e6SKiseok Jo {
485*576c57e6SKiseok Jo 	struct snd_soc_component *component =
486*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
487*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
488*576c57e6SKiseok Jo 
489*576c57e6SKiseok Jo 	ucontrol->value.integer.value[0] = sma1307->check_fault_period;
490*576c57e6SKiseok Jo 
491*576c57e6SKiseok Jo 	return 0;
492*576c57e6SKiseok Jo }
493*576c57e6SKiseok Jo 
494*576c57e6SKiseok Jo static int sma1307_check_fault_period_put(struct snd_kcontrol *kcontrol,
495*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
496*576c57e6SKiseok Jo {
497*576c57e6SKiseok Jo 	struct snd_soc_component *component =
498*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
499*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
500*576c57e6SKiseok Jo 	struct soc_mixer_control *mc =
501*576c57e6SKiseok Jo 		(struct soc_mixer_control *)kcontrol->private_value;
502*576c57e6SKiseok Jo 	bool change = false;
503*576c57e6SKiseok Jo 	int val  = ucontrol->value.integer.value[0];
504*576c57e6SKiseok Jo 
505*576c57e6SKiseok Jo 	if (val < mc->min || val > mc->max)
506*576c57e6SKiseok Jo 		return -EINVAL;
507*576c57e6SKiseok Jo 	if (sma1307->check_fault_period == val) {
508*576c57e6SKiseok Jo 		change = false;
509*576c57e6SKiseok Jo 	} else {
510*576c57e6SKiseok Jo 		change = true;
511*576c57e6SKiseok Jo 		sma1307->check_fault_period = val;
512*576c57e6SKiseok Jo 	}
513*576c57e6SKiseok Jo 
514*576c57e6SKiseok Jo 	return change;
515*576c57e6SKiseok Jo }
516*576c57e6SKiseok Jo 
517*576c57e6SKiseok Jo static int sma1307_reset_put(struct snd_kcontrol *kcontrol,
518*576c57e6SKiseok Jo 			     struct snd_ctl_elem_value *ucontrol)
519*576c57e6SKiseok Jo {
520*576c57e6SKiseok Jo 	struct snd_soc_component *component =
521*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
522*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
523*576c57e6SKiseok Jo 
524*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_00_SYSTEM_CTRL,
525*576c57e6SKiseok Jo 				   SMA1307_RESET_MASK, SMA1307_RESET_ON);
526*576c57e6SKiseok Jo 	sma1307_reset(component);
527*576c57e6SKiseok Jo 
528*576c57e6SKiseok Jo 	snd_ctl_notify(component->card->snd_card, SNDRV_CTL_EVENT_MASK_VALUE,
529*576c57e6SKiseok Jo 					&kcontrol->id);
530*576c57e6SKiseok Jo 
531*576c57e6SKiseok Jo 	return true;
532*576c57e6SKiseok Jo }
533*576c57e6SKiseok Jo 
534*576c57e6SKiseok Jo static int sma1307_binary_mode_put(struct snd_kcontrol *kcontrol,
535*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
536*576c57e6SKiseok Jo {
537*576c57e6SKiseok Jo 	struct snd_soc_component *component =
538*576c57e6SKiseok Jo 	    snd_soc_kcontrol_component(kcontrol);
539*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_kcontrol_chip(kcontrol);
540*576c57e6SKiseok Jo 
541*576c57e6SKiseok Jo 	sma1307->binary_mode = (int)ucontrol->value.enumerated.item[0];
542*576c57e6SKiseok Jo 	if (sma1307->set.status)
543*576c57e6SKiseok Jo 		sma1307_set_binary(component);
544*576c57e6SKiseok Jo 
545*576c57e6SKiseok Jo 	return snd_soc_put_enum_double(kcontrol, ucontrol);
546*576c57e6SKiseok Jo }
547*576c57e6SKiseok Jo 
548*576c57e6SKiseok Jo static void sma1307_startup(struct snd_soc_component *component)
549*576c57e6SKiseok Jo {
550*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
551*576c57e6SKiseok Jo 
552*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_A2_TOP_MAN1,
553*576c57e6SKiseok Jo 				   SMA1307_PLL_MASK, SMA1307_PLL_ON);
554*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_00_SYSTEM_CTRL,
555*576c57e6SKiseok Jo 				   SMA1307_POWER_MASK, SMA1307_POWER_ON);
556*576c57e6SKiseok Jo 
557*576c57e6SKiseok Jo 	if (sma1307->amp_mode == SMA1307_MONO_MODE) {
558*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
559*576c57e6SKiseok Jo 					   SMA1307_10_SYSTEM_CTRL1,
560*576c57e6SKiseok Jo 					   SMA1307_SPK_MODE_MASK,
561*576c57e6SKiseok Jo 					   SMA1307_SPK_MONO);
562*576c57e6SKiseok Jo 	} else {
563*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
564*576c57e6SKiseok Jo 					   SMA1307_10_SYSTEM_CTRL1,
565*576c57e6SKiseok Jo 					   SMA1307_SPK_MODE_MASK,
566*576c57e6SKiseok Jo 					   SMA1307_SPK_STEREO);
567*576c57e6SKiseok Jo 	}
568*576c57e6SKiseok Jo 
569*576c57e6SKiseok Jo 	if (sma1307->check_fault_status) {
570*576c57e6SKiseok Jo 		if (sma1307->check_fault_period > 0)
571*576c57e6SKiseok Jo 			queue_delayed_work(system_freezable_wq,
572*576c57e6SKiseok Jo 					   &sma1307->check_fault_work,
573*576c57e6SKiseok Jo 					   sma1307->check_fault_period * HZ);
574*576c57e6SKiseok Jo 		else
575*576c57e6SKiseok Jo 			queue_delayed_work(system_freezable_wq,
576*576c57e6SKiseok Jo 					   &sma1307->check_fault_work,
577*576c57e6SKiseok Jo 					   CHECK_PERIOD_TIME * HZ);
578*576c57e6SKiseok Jo 	}
579*576c57e6SKiseok Jo }
580*576c57e6SKiseok Jo 
581*576c57e6SKiseok Jo static void sma1307_shutdown(struct snd_soc_component *component)
582*576c57e6SKiseok Jo {
583*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
584*576c57e6SKiseok Jo 
585*576c57e6SKiseok Jo 	/* for SMA1307A */
586*576c57e6SKiseok Jo 	cancel_delayed_work_sync(&sma1307->check_fault_work);
587*576c57e6SKiseok Jo 
588*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_0E_MUTE_VOL_CTRL,
589*576c57e6SKiseok Jo 				   SMA1307_SPK_MUTE_MASK, SMA1307_SPK_MUTE);
590*576c57e6SKiseok Jo 	/* Need to wait time for mute slope */
591*576c57e6SKiseok Jo 	msleep(55);
592*576c57e6SKiseok Jo 
593*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_10_SYSTEM_CTRL1,
594*576c57e6SKiseok Jo 				   SMA1307_SPK_MODE_MASK, SMA1307_SPK_OFF);
595*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_A2_TOP_MAN1,
596*576c57e6SKiseok Jo 				   SMA1307_PLL_MASK, SMA1307_PLL_OFF);
597*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap, SMA1307_00_SYSTEM_CTRL,
598*576c57e6SKiseok Jo 				   SMA1307_POWER_MASK, SMA1307_POWER_OFF);
599*576c57e6SKiseok Jo }
600*576c57e6SKiseok Jo 
601*576c57e6SKiseok Jo static int sma1307_aif_in_event(struct snd_soc_dapm_widget *w,
602*576c57e6SKiseok Jo 				struct snd_kcontrol *kcontrol, int event)
603*576c57e6SKiseok Jo {
604*576c57e6SKiseok Jo 	struct snd_soc_component *component =
605*576c57e6SKiseok Jo 	    snd_soc_dapm_to_component(w->dapm);
606*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
607*576c57e6SKiseok Jo 	unsigned int mux = sma1307->dapm_aif_in;
608*576c57e6SKiseok Jo 
609*576c57e6SKiseok Jo 	switch (event) {
610*576c57e6SKiseok Jo 	case SND_SOC_DAPM_PRE_PMU:
611*576c57e6SKiseok Jo 		switch (mux) {
612*576c57e6SKiseok Jo 		case SMA1307_MONO_MODE:
613*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
614*576c57e6SKiseok Jo 						   SMA1307_11_SYSTEM_CTRL2,
615*576c57e6SKiseok Jo 						   SMA1307_MONOMIX_MASK,
616*576c57e6SKiseok Jo 						   SMA1307_MONOMIX_ON);
617*576c57e6SKiseok Jo 			break;
618*576c57e6SKiseok Jo 		case SMA1307_LEFT_MODE:
619*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
620*576c57e6SKiseok Jo 						   SMA1307_11_SYSTEM_CTRL2,
621*576c57e6SKiseok Jo 						   SMA1307_MONOMIX_MASK,
622*576c57e6SKiseok Jo 						   SMA1307_MONOMIX_OFF);
623*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
624*576c57e6SKiseok Jo 						   SMA1307_11_SYSTEM_CTRL2,
625*576c57e6SKiseok Jo 						   SMA1307_LR_DATA_SW_MASK,
626*576c57e6SKiseok Jo 						   SMA1307_LR_DATA_SW_NORMAL);
627*576c57e6SKiseok Jo 			break;
628*576c57e6SKiseok Jo 		case SMA1307_RIGHT_MODE:
629*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
630*576c57e6SKiseok Jo 						   SMA1307_11_SYSTEM_CTRL2,
631*576c57e6SKiseok Jo 						   SMA1307_MONOMIX_MASK,
632*576c57e6SKiseok Jo 						   SMA1307_MONOMIX_OFF);
633*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
634*576c57e6SKiseok Jo 						   SMA1307_11_SYSTEM_CTRL2,
635*576c57e6SKiseok Jo 						   SMA1307_LR_DATA_SW_MASK,
636*576c57e6SKiseok Jo 						   SMA1307_LR_DATA_SW_SWAP);
637*576c57e6SKiseok Jo 			break;
638*576c57e6SKiseok Jo 		default:
639*576c57e6SKiseok Jo 
640*576c57e6SKiseok Jo 			dev_err(sma1307->dev, "%s: Invalid value (%d)\n",
641*576c57e6SKiseok Jo 				__func__, mux);
642*576c57e6SKiseok Jo 			return -EINVAL;
643*576c57e6SKiseok Jo 		}
644*576c57e6SKiseok Jo 		sma1307->amp_mode = mux;
645*576c57e6SKiseok Jo 		break;
646*576c57e6SKiseok Jo 	}
647*576c57e6SKiseok Jo 	return 0;
648*576c57e6SKiseok Jo }
649*576c57e6SKiseok Jo 
650*576c57e6SKiseok Jo static int sma1307_sdo_setting_event(struct snd_soc_dapm_widget *w,
651*576c57e6SKiseok Jo 				     struct snd_kcontrol *kcontrol, int event)
652*576c57e6SKiseok Jo {
653*576c57e6SKiseok Jo 	struct snd_soc_component *component =
654*576c57e6SKiseok Jo 	    snd_soc_dapm_to_component(w->dapm);
655*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
656*576c57e6SKiseok Jo 	unsigned int mux = sma1307->dapm_sdo_setting;
657*576c57e6SKiseok Jo 
658*576c57e6SKiseok Jo 	switch (event) {
659*576c57e6SKiseok Jo 	case SND_SOC_DAPM_PRE_PMU:
660*576c57e6SKiseok Jo 		switch (mux) {
661*576c57e6SKiseok Jo 		case SMA1307_OUT_DATA_ONE_48K:
662*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
663*576c57e6SKiseok Jo 						   SMA1307_A2_TOP_MAN1,
664*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT2_MASK,
665*576c57e6SKiseok Jo 						   SMA1307_ONE_SDO_PER_CH);
666*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
667*576c57e6SKiseok Jo 						   SMA1307_A3_TOP_MAN2,
668*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT3_MASK
669*576c57e6SKiseok Jo 						   |
670*576c57e6SKiseok Jo 						   SMA1307_DATA_CLK_SEL_MASK,
671*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT3_DIS
672*576c57e6SKiseok Jo 						   | SMA1307_SDO_DATA);
673*576c57e6SKiseok Jo 			break;
674*576c57e6SKiseok Jo 		case SMA1307_OUT_DATA_TWO_48K:
675*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
676*576c57e6SKiseok Jo 						   SMA1307_A2_TOP_MAN1,
677*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT2_MASK,
678*576c57e6SKiseok Jo 						   SMA1307_TWO_SDO_PER_CH);
679*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
680*576c57e6SKiseok Jo 						   SMA1307_A3_TOP_MAN2,
681*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT3_MASK
682*576c57e6SKiseok Jo 						   |
683*576c57e6SKiseok Jo 						   SMA1307_DATA_CLK_SEL_MASK,
684*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT3_DIS
685*576c57e6SKiseok Jo 						   | SMA1307_SDO_DATA);
686*576c57e6SKiseok Jo 			break;
687*576c57e6SKiseok Jo 		case SMA1307_OUT_DATA_TWO_24K:
688*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
689*576c57e6SKiseok Jo 						   SMA1307_A2_TOP_MAN1,
690*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT2_MASK,
691*576c57e6SKiseok Jo 						   SMA1307_TWO_SDO_PER_CH);
692*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
693*576c57e6SKiseok Jo 						   SMA1307_A3_TOP_MAN2,
694*576c57e6SKiseok Jo 						   SMA1307_SDO_OUTPUT3_MASK
695*576c57e6SKiseok Jo 						   |
696*576c57e6SKiseok Jo 						   SMA1307_DATA_CLK_SEL_MASK,
697*576c57e6SKiseok Jo 						   SMA1307_TWO_SDO_PER_CH_24K
698*576c57e6SKiseok Jo 						   | SMA1307_SDO_DATA);
699*576c57e6SKiseok Jo 			break;
700*576c57e6SKiseok Jo 		case SMA1307_OUT_CLK_PLL:
701*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
702*576c57e6SKiseok Jo 						   SMA1307_A3_TOP_MAN2,
703*576c57e6SKiseok Jo 						   SMA1307_DATA_CLK_SEL_MASK,
704*576c57e6SKiseok Jo 						   SMA1307_SDO_CLK_PLL);
705*576c57e6SKiseok Jo 
706*576c57e6SKiseok Jo 			break;
707*576c57e6SKiseok Jo 		case SMA1307_OUT_CLK_OSC:
708*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
709*576c57e6SKiseok Jo 						   SMA1307_A3_TOP_MAN2,
710*576c57e6SKiseok Jo 						   SMA1307_DATA_CLK_SEL_MASK,
711*576c57e6SKiseok Jo 						   SMA1307_SDO_CLK_OSC);
712*576c57e6SKiseok Jo 
713*576c57e6SKiseok Jo 			break;
714*576c57e6SKiseok Jo 		default:
715*576c57e6SKiseok Jo 			dev_err(sma1307->dev, "%s: Invalid value (%d)\n",
716*576c57e6SKiseok Jo 				__func__, mux);
717*576c57e6SKiseok Jo 			return -EINVAL;
718*576c57e6SKiseok Jo 		}
719*576c57e6SKiseok Jo 		break;
720*576c57e6SKiseok Jo 	}
721*576c57e6SKiseok Jo 	return 0;
722*576c57e6SKiseok Jo }
723*576c57e6SKiseok Jo 
724*576c57e6SKiseok Jo static int sma1307_aif_out_event(struct snd_soc_dapm_widget *w,
725*576c57e6SKiseok Jo 				 struct snd_kcontrol *kcontrol, int event)
726*576c57e6SKiseok Jo {
727*576c57e6SKiseok Jo 	struct snd_soc_component *component =
728*576c57e6SKiseok Jo 	    snd_soc_dapm_to_component(w->dapm);
729*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
730*576c57e6SKiseok Jo 	unsigned int mux = 0, val = 0, mask = 0;
731*576c57e6SKiseok Jo 
732*576c57e6SKiseok Jo 	if (!strcmp(w->name, SMA1307_AIF_OUT0_NAME)) {
733*576c57e6SKiseok Jo 		mux = sma1307->dapm_aif_out0;
734*576c57e6SKiseok Jo 		val = mux;
735*576c57e6SKiseok Jo 		mask = SMA1307_SDO_OUT0_SEL_MASK;
736*576c57e6SKiseok Jo 	} else if (!strcmp(w->name, SMA1307_AIF_OUT1_NAME)) {
737*576c57e6SKiseok Jo 		mux = sma1307->dapm_aif_out1;
738*576c57e6SKiseok Jo 		val = mux << 3;
739*576c57e6SKiseok Jo 		mask = SMA1307_SDO_OUT1_SEL_MASK;
740*576c57e6SKiseok Jo 	} else {
741*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Invalid widget - %s\n",
742*576c57e6SKiseok Jo 			__func__, w->name);
743*576c57e6SKiseok Jo 		return -EINVAL;
744*576c57e6SKiseok Jo 	}
745*576c57e6SKiseok Jo 	switch (event) {
746*576c57e6SKiseok Jo 	case SND_SOC_DAPM_PRE_PMU:
747*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap, SMA1307_09_OUTPUT_CTRL,
748*576c57e6SKiseok Jo 					   mask, val);
749*576c57e6SKiseok Jo 		break;
750*576c57e6SKiseok Jo 	}
751*576c57e6SKiseok Jo 	return 0;
752*576c57e6SKiseok Jo }
753*576c57e6SKiseok Jo 
754*576c57e6SKiseok Jo static int sma1307_sdo_event(struct snd_soc_dapm_widget *w,
755*576c57e6SKiseok Jo 			     struct snd_kcontrol *kcontrol, int event)
756*576c57e6SKiseok Jo {
757*576c57e6SKiseok Jo 	struct snd_soc_component *component =
758*576c57e6SKiseok Jo 	    snd_soc_dapm_to_component(w->dapm);
759*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
760*576c57e6SKiseok Jo 
761*576c57e6SKiseok Jo 	switch (event) {
762*576c57e6SKiseok Jo 	case SND_SOC_DAPM_PRE_PMU:
763*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
764*576c57e6SKiseok Jo 					   SMA1307_09_OUTPUT_CTRL,
765*576c57e6SKiseok Jo 					   SMA1307_PORT_CONFIG_MASK,
766*576c57e6SKiseok Jo 					   SMA1307_OUTPUT_PORT_ENABLE);
767*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
768*576c57e6SKiseok Jo 					   SMA1307_A3_TOP_MAN2,
769*576c57e6SKiseok Jo 					   SMA1307_SDO_OUTPUT_MASK,
770*576c57e6SKiseok Jo 					   SMA1307_LOGIC_OUTPUT);
771*576c57e6SKiseok Jo 		break;
772*576c57e6SKiseok Jo 	case SND_SOC_DAPM_POST_PMD:
773*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
774*576c57e6SKiseok Jo 					   SMA1307_09_OUTPUT_CTRL,
775*576c57e6SKiseok Jo 					   SMA1307_PORT_CONFIG_MASK,
776*576c57e6SKiseok Jo 					   SMA1307_INPUT_PORT_ONLY);
777*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
778*576c57e6SKiseok Jo 					   SMA1307_A3_TOP_MAN2,
779*576c57e6SKiseok Jo 					   SMA1307_SDO_OUTPUT_MASK,
780*576c57e6SKiseok Jo 					   SMA1307_HIGH_Z_OUTPUT);
781*576c57e6SKiseok Jo 		break;
782*576c57e6SKiseok Jo 	}
783*576c57e6SKiseok Jo 	return 0;
784*576c57e6SKiseok Jo }
785*576c57e6SKiseok Jo 
786*576c57e6SKiseok Jo static int sma1307_power_event(struct snd_soc_dapm_widget *w,
787*576c57e6SKiseok Jo 			       struct snd_kcontrol *kcontrol, int event)
788*576c57e6SKiseok Jo {
789*576c57e6SKiseok Jo 	struct snd_soc_component *component =
790*576c57e6SKiseok Jo 	    snd_soc_dapm_to_component(w->dapm);
791*576c57e6SKiseok Jo 
792*576c57e6SKiseok Jo 	switch (event) {
793*576c57e6SKiseok Jo 	case SND_SOC_DAPM_POST_PMU:
794*576c57e6SKiseok Jo 		sma1307_startup(component);
795*576c57e6SKiseok Jo 		break;
796*576c57e6SKiseok Jo 	case SND_SOC_DAPM_PRE_PMD:
797*576c57e6SKiseok Jo 		sma1307_shutdown(component);
798*576c57e6SKiseok Jo 		break;
799*576c57e6SKiseok Jo 	}
800*576c57e6SKiseok Jo 	return 0;
801*576c57e6SKiseok Jo }
802*576c57e6SKiseok Jo 
803*576c57e6SKiseok Jo static int sma1307_dapm_aif_in_get(struct snd_kcontrol *kcontrol,
804*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
805*576c57e6SKiseok Jo {
806*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
807*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
808*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
809*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
810*576c57e6SKiseok Jo 
811*576c57e6SKiseok Jo 	ucontrol->value.enumerated.item[0] = (unsigned int)sma1307->dapm_aif_in;
812*576c57e6SKiseok Jo 	snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
813*576c57e6SKiseok Jo 
814*576c57e6SKiseok Jo 	return 0;
815*576c57e6SKiseok Jo }
816*576c57e6SKiseok Jo 
817*576c57e6SKiseok Jo static int sma1307_dapm_aif_in_put(struct snd_kcontrol *kcontrol,
818*576c57e6SKiseok Jo 				   struct snd_ctl_elem_value *ucontrol)
819*576c57e6SKiseok Jo {
820*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
821*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
822*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
823*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
824*576c57e6SKiseok Jo 	int val = (int)ucontrol->value.enumerated.item[0];
825*576c57e6SKiseok Jo 	bool change;
826*576c57e6SKiseok Jo 
827*576c57e6SKiseok Jo 	if ((val < 0) || (val >= ARRAY_SIZE(sma1307_aif_in_source_text))) {
828*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Out of range\n", __func__);
829*576c57e6SKiseok Jo 		return -EINVAL;
830*576c57e6SKiseok Jo 	}
831*576c57e6SKiseok Jo 
832*576c57e6SKiseok Jo 	if (sma1307->dapm_aif_in != val) {
833*576c57e6SKiseok Jo 		change = true;
834*576c57e6SKiseok Jo 		sma1307->dapm_aif_in = val;
835*576c57e6SKiseok Jo 	} else
836*576c57e6SKiseok Jo 		change = false;
837*576c57e6SKiseok Jo 
838*576c57e6SKiseok Jo 	snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
839*576c57e6SKiseok Jo 
840*576c57e6SKiseok Jo 	return change;
841*576c57e6SKiseok Jo }
842*576c57e6SKiseok Jo 
843*576c57e6SKiseok Jo static int sma1307_dapm_sdo_setting_get(struct snd_kcontrol *kcontrol,
844*576c57e6SKiseok Jo 					struct snd_ctl_elem_value *ucontrol)
845*576c57e6SKiseok Jo {
846*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
847*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
848*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
849*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
850*576c57e6SKiseok Jo 
851*576c57e6SKiseok Jo 	ucontrol->value.enumerated.item[0] =
852*576c57e6SKiseok Jo 	    (unsigned int)sma1307->dapm_sdo_setting;
853*576c57e6SKiseok Jo 	snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
854*576c57e6SKiseok Jo 
855*576c57e6SKiseok Jo 	return 0;
856*576c57e6SKiseok Jo }
857*576c57e6SKiseok Jo 
858*576c57e6SKiseok Jo static int sma1307_dapm_sdo_setting_put(struct snd_kcontrol *kcontrol,
859*576c57e6SKiseok Jo 					struct snd_ctl_elem_value *ucontrol)
860*576c57e6SKiseok Jo {
861*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
862*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
863*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
864*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
865*576c57e6SKiseok Jo 	int val = (int)ucontrol->value.enumerated.item[0];
866*576c57e6SKiseok Jo 	bool change;
867*576c57e6SKiseok Jo 
868*576c57e6SKiseok Jo 	if ((val < 0) || (val >= ARRAY_SIZE(sma1307_sdo_setting_text))) {
869*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Out of range\n", __func__);
870*576c57e6SKiseok Jo 		return -EINVAL;
871*576c57e6SKiseok Jo 	}
872*576c57e6SKiseok Jo 
873*576c57e6SKiseok Jo 	if (sma1307->dapm_sdo_setting != val) {
874*576c57e6SKiseok Jo 		change = true;
875*576c57e6SKiseok Jo 		sma1307->dapm_sdo_setting = val;
876*576c57e6SKiseok Jo 	} else
877*576c57e6SKiseok Jo 		change = false;
878*576c57e6SKiseok Jo 
879*576c57e6SKiseok Jo 	snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
880*576c57e6SKiseok Jo 
881*576c57e6SKiseok Jo 	return change;
882*576c57e6SKiseok Jo }
883*576c57e6SKiseok Jo 
884*576c57e6SKiseok Jo static int sma1307_dapm_aif_out_get(struct snd_kcontrol *kcontrol,
885*576c57e6SKiseok Jo 				    struct snd_ctl_elem_value *ucontrol)
886*576c57e6SKiseok Jo {
887*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
888*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
889*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
890*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
891*576c57e6SKiseok Jo 	unsigned int val = 0;
892*576c57e6SKiseok Jo 
893*576c57e6SKiseok Jo 	if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT0_NAME)) {
894*576c57e6SKiseok Jo 		val = (unsigned int)sma1307->dapm_aif_out0;
895*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT1_NAME)) {
896*576c57e6SKiseok Jo 		val = (unsigned int)sma1307->dapm_aif_out1;
897*576c57e6SKiseok Jo 	} else {
898*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Invalid Control ID - %s\n",
899*576c57e6SKiseok Jo 			__func__, kcontrol->id.name);
900*576c57e6SKiseok Jo 		return -EINVAL;
901*576c57e6SKiseok Jo 	}
902*576c57e6SKiseok Jo 	ucontrol->value.enumerated.item[0] = val;
903*576c57e6SKiseok Jo 	snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
904*576c57e6SKiseok Jo 
905*576c57e6SKiseok Jo 	return 0;
906*576c57e6SKiseok Jo }
907*576c57e6SKiseok Jo 
908*576c57e6SKiseok Jo static int sma1307_dapm_aif_out_put(struct snd_kcontrol *kcontrol,
909*576c57e6SKiseok Jo 				    struct snd_ctl_elem_value *ucontrol)
910*576c57e6SKiseok Jo {
911*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
912*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
913*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
914*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
915*576c57e6SKiseok Jo 	int val = (int)ucontrol->value.enumerated.item[0];
916*576c57e6SKiseok Jo 	bool change;
917*576c57e6SKiseok Jo 
918*576c57e6SKiseok Jo 	if ((val < 0) || (val >= ARRAY_SIZE(sma1307_aif_out_source_text))) {
919*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Out of range\n", __func__);
920*576c57e6SKiseok Jo 		return -EINVAL;
921*576c57e6SKiseok Jo 	}
922*576c57e6SKiseok Jo 
923*576c57e6SKiseok Jo 	if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT0_NAME)) {
924*576c57e6SKiseok Jo 		if (sma1307->dapm_aif_out0 != val) {
925*576c57e6SKiseok Jo 			change = true;
926*576c57e6SKiseok Jo 			sma1307->dapm_aif_out0 = val;
927*576c57e6SKiseok Jo 		} else
928*576c57e6SKiseok Jo 			change = false;
929*576c57e6SKiseok Jo 	} else if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT1_NAME)) {
930*576c57e6SKiseok Jo 		if (sma1307->dapm_aif_out1 != val) {
931*576c57e6SKiseok Jo 			change = true;
932*576c57e6SKiseok Jo 			sma1307->dapm_aif_out1 = val;
933*576c57e6SKiseok Jo 		} else
934*576c57e6SKiseok Jo 			change = false;
935*576c57e6SKiseok Jo 	} else {
936*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Invalid Control ID - %s\n",
937*576c57e6SKiseok Jo 			__func__, kcontrol->id.name);
938*576c57e6SKiseok Jo 		return -EINVAL;
939*576c57e6SKiseok Jo 	}
940*576c57e6SKiseok Jo 
941*576c57e6SKiseok Jo 	snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
942*576c57e6SKiseok Jo 
943*576c57e6SKiseok Jo 	return change;
944*576c57e6SKiseok Jo }
945*576c57e6SKiseok Jo 
946*576c57e6SKiseok Jo static int sma1307_dapm_sdo_enable_get(struct snd_kcontrol *kcontrol,
947*576c57e6SKiseok Jo 				       struct snd_ctl_elem_value *ucontrol)
948*576c57e6SKiseok Jo {
949*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
950*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
951*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
952*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
953*576c57e6SKiseok Jo 
954*576c57e6SKiseok Jo 	ucontrol->value.integer.value[0] = (long)sma1307->dapm_sdo_en;
955*576c57e6SKiseok Jo 	snd_soc_dapm_put_volsw(kcontrol, ucontrol);
956*576c57e6SKiseok Jo 
957*576c57e6SKiseok Jo 	return 0;
958*576c57e6SKiseok Jo }
959*576c57e6SKiseok Jo 
960*576c57e6SKiseok Jo static int sma1307_dapm_sdo_enable_put(struct snd_kcontrol *kcontrol,
961*576c57e6SKiseok Jo 				       struct snd_ctl_elem_value *ucontrol)
962*576c57e6SKiseok Jo {
963*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
964*576c57e6SKiseok Jo 	    snd_soc_dapm_kcontrol_dapm(kcontrol);
965*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
966*576c57e6SKiseok Jo 	    snd_soc_component_get_drvdata(dapm->component);
967*576c57e6SKiseok Jo 	int val = (int)ucontrol->value.integer.value[0];
968*576c57e6SKiseok Jo 	bool change;
969*576c57e6SKiseok Jo 
970*576c57e6SKiseok Jo 	if ((val < 0) || (val > 1)) {
971*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Out of range\n", __func__);
972*576c57e6SKiseok Jo 		return -EINVAL;
973*576c57e6SKiseok Jo 	}
974*576c57e6SKiseok Jo 
975*576c57e6SKiseok Jo 	if (sma1307->dapm_sdo_en != val) {
976*576c57e6SKiseok Jo 		change = true;
977*576c57e6SKiseok Jo 		sma1307->dapm_sdo_en = val;
978*576c57e6SKiseok Jo 	} else
979*576c57e6SKiseok Jo 		change = false;
980*576c57e6SKiseok Jo 
981*576c57e6SKiseok Jo 	snd_soc_dapm_put_volsw(kcontrol, ucontrol);
982*576c57e6SKiseok Jo 
983*576c57e6SKiseok Jo 	return change;
984*576c57e6SKiseok Jo }
985*576c57e6SKiseok Jo 
986*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_aif_in_source_control = {
987*576c57e6SKiseok Jo 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
988*576c57e6SKiseok Jo 	.name = SMA1307_AIF_IN_NAME,
989*576c57e6SKiseok Jo 	.info = snd_soc_info_enum_double,
990*576c57e6SKiseok Jo 	.get = sma1307_dapm_aif_in_get,
991*576c57e6SKiseok Jo 	.put = sma1307_dapm_aif_in_put,
992*576c57e6SKiseok Jo 	.private_value = (unsigned long)&sma1307_aif_in_source_enum
993*576c57e6SKiseok Jo };
994*576c57e6SKiseok Jo 
995*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_sdo_setting_control = {
996*576c57e6SKiseok Jo 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
997*576c57e6SKiseok Jo 	.name = "SDO Setting",
998*576c57e6SKiseok Jo 	.info = snd_soc_info_enum_double,
999*576c57e6SKiseok Jo 	.get = sma1307_dapm_sdo_setting_get,
1000*576c57e6SKiseok Jo 	.put = sma1307_dapm_sdo_setting_put,
1001*576c57e6SKiseok Jo 	.private_value = (unsigned long)&sma1307_sdo_setting_enum
1002*576c57e6SKiseok Jo };
1003*576c57e6SKiseok Jo 
1004*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_aif_out0_source_control = {
1005*576c57e6SKiseok Jo 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1006*576c57e6SKiseok Jo 	.name = SMA1307_AIF_OUT0_NAME,
1007*576c57e6SKiseok Jo 	.info = snd_soc_info_enum_double,
1008*576c57e6SKiseok Jo 	.get = sma1307_dapm_aif_out_get,
1009*576c57e6SKiseok Jo 	.put = sma1307_dapm_aif_out_put,
1010*576c57e6SKiseok Jo 	.private_value = (unsigned long)&sma1307_aif_out_source_enum
1011*576c57e6SKiseok Jo };
1012*576c57e6SKiseok Jo 
1013*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_aif_out1_source_control = {
1014*576c57e6SKiseok Jo 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1015*576c57e6SKiseok Jo 	.name = SMA1307_AIF_OUT1_NAME,
1016*576c57e6SKiseok Jo 	.info = snd_soc_info_enum_double,
1017*576c57e6SKiseok Jo 	.get = sma1307_dapm_aif_out_get,
1018*576c57e6SKiseok Jo 	.put = sma1307_dapm_aif_out_put,
1019*576c57e6SKiseok Jo 	.private_value = (unsigned long)&sma1307_aif_out_source_enum
1020*576c57e6SKiseok Jo };
1021*576c57e6SKiseok Jo 
1022*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_sdo_control = {
1023*576c57e6SKiseok Jo 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1024*576c57e6SKiseok Jo 	.name = "Switch",
1025*576c57e6SKiseok Jo 	.info = snd_soc_info_volsw,
1026*576c57e6SKiseok Jo 	.get = sma1307_dapm_sdo_enable_get,
1027*576c57e6SKiseok Jo 	.put = sma1307_dapm_sdo_enable_put,
1028*576c57e6SKiseok Jo 	.private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, 0, 1, 0, 0)
1029*576c57e6SKiseok Jo };
1030*576c57e6SKiseok Jo 
1031*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_enable_control =
1032*576c57e6SKiseok Jo 	SOC_DAPM_SINGLE("Switch", SMA1307_00_SYSTEM_CTRL, 0, 1, 0);
1033*576c57e6SKiseok Jo 
1034*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_binary_mode_control[] = {
1035*576c57e6SKiseok Jo 	SOC_ENUM_EXT("Binary Mode", sma1307_binary_mode_enum,
1036*576c57e6SKiseok Jo 			snd_soc_get_enum_double, sma1307_binary_mode_put),
1037*576c57e6SKiseok Jo };
1038*576c57e6SKiseok Jo 
1039*576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_snd_controls[] = {
1040*576c57e6SKiseok Jo 	SOC_SINGLE_TLV(SMA1307_VOL_CTRL_NAME, SMA1307_0A_SPK_VOL,
1041*576c57e6SKiseok Jo 		       0, 167, 1, sma1307_spk_tlv),
1042*576c57e6SKiseok Jo 	SOC_ENUM_EXT(SMA1307_TDM_RX0_POS_NAME, sma1307_tdm_slot_enum,
1043*576c57e6SKiseok Jo 		     sma1307_tdm_slot_get, sma1307_tdm_slot_put),
1044*576c57e6SKiseok Jo 	SOC_ENUM_EXT(SMA1307_TDM_RX1_POS_NAME, sma1307_tdm_slot_enum,
1045*576c57e6SKiseok Jo 		     sma1307_tdm_slot_get, sma1307_tdm_slot_put),
1046*576c57e6SKiseok Jo 	SOC_ENUM_EXT(SMA1307_TDM_TX0_POS_NAME, sma1307_tdm_slot_enum,
1047*576c57e6SKiseok Jo 		     sma1307_tdm_slot_get, sma1307_tdm_slot_put),
1048*576c57e6SKiseok Jo 	SOC_ENUM_EXT(SMA1307_TDM_TX1_POS_NAME, sma1307_tdm_slot_enum,
1049*576c57e6SKiseok Jo 		     sma1307_tdm_slot_get, sma1307_tdm_slot_put),
1050*576c57e6SKiseok Jo 	SOC_ENUM_EXT(SMA1307_RESET_CTRL_NAME, sma1307_reset_enum,
1051*576c57e6SKiseok Jo 			    snd_soc_get_enum_double, sma1307_reset_put),
1052*576c57e6SKiseok Jo 	SOC_SINGLE_BOOL_EXT(SMA1307_FORCE_MUTE_CTRL_NAME, 0,
1053*576c57e6SKiseok Jo 			    sma1307_force_mute_get, sma1307_force_mute_put),
1054*576c57e6SKiseok Jo 	SOC_SINGLE_BOOL_EXT(SMA1307_OT1_SW_PROT_CTRL_NAME, 0,
1055*576c57e6SKiseok Jo 			    sma1307_sw_ot1_prot_get, sma1307_sw_ot1_prot_put),
1056*576c57e6SKiseok Jo 	SOC_SINGLE_BOOL_EXT(SMA1307_CHECK_FAULT_STATUS_NAME, 0,
1057*576c57e6SKiseok Jo 			sma1307_check_fault_status_get,
1058*576c57e6SKiseok Jo 			sma1307_check_fault_status_put),
1059*576c57e6SKiseok Jo 	SOC_SINGLE_EXT(SMA1307_CHECK_FAULT_PERIOD_NAME, SND_SOC_NOPM, 0, 600, 0,
1060*576c57e6SKiseok Jo 			sma1307_check_fault_period_get,
1061*576c57e6SKiseok Jo 			sma1307_check_fault_period_put),
1062*576c57e6SKiseok Jo };
1063*576c57e6SKiseok Jo 
1064*576c57e6SKiseok Jo static const struct snd_soc_dapm_widget sma1307_dapm_widgets[] = {
1065*576c57e6SKiseok Jo 	/* platform domain */
1066*576c57e6SKiseok Jo 	SND_SOC_DAPM_OUTPUT("SPK"),
1067*576c57e6SKiseok Jo 	SND_SOC_DAPM_INPUT("SDO"),
1068*576c57e6SKiseok Jo 
1069*576c57e6SKiseok Jo 	/* path domain */
1070*576c57e6SKiseok Jo 	SND_SOC_DAPM_MUX_E(SMA1307_AIF_IN_NAME, SND_SOC_NOPM, 0, 0,
1071*576c57e6SKiseok Jo 			   &sma1307_aif_in_source_control,
1072*576c57e6SKiseok Jo 			   sma1307_aif_in_event,
1073*576c57e6SKiseok Jo 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
1074*576c57e6SKiseok Jo 	SND_SOC_DAPM_MUX_E("SDO Setting", SND_SOC_NOPM, 0, 0,
1075*576c57e6SKiseok Jo 			   &sma1307_sdo_setting_control,
1076*576c57e6SKiseok Jo 			   sma1307_sdo_setting_event,
1077*576c57e6SKiseok Jo 			   SND_SOC_DAPM_PRE_PMU),
1078*576c57e6SKiseok Jo 	SND_SOC_DAPM_MUX_E(SMA1307_AIF_OUT0_NAME, SND_SOC_NOPM, 0, 0,
1079*576c57e6SKiseok Jo 			   &sma1307_aif_out0_source_control,
1080*576c57e6SKiseok Jo 			   sma1307_aif_out_event,
1081*576c57e6SKiseok Jo 			   SND_SOC_DAPM_PRE_PMU),
1082*576c57e6SKiseok Jo 	SND_SOC_DAPM_MUX_E(SMA1307_AIF_OUT1_NAME, SND_SOC_NOPM, 0, 0,
1083*576c57e6SKiseok Jo 			   &sma1307_aif_out1_source_control,
1084*576c57e6SKiseok Jo 			   sma1307_aif_out_event,
1085*576c57e6SKiseok Jo 			   SND_SOC_DAPM_PRE_PMU),
1086*576c57e6SKiseok Jo 	SND_SOC_DAPM_SWITCH_E("SDO Enable", SND_SOC_NOPM, 0, 0,
1087*576c57e6SKiseok Jo 			      &sma1307_sdo_control,
1088*576c57e6SKiseok Jo 			      sma1307_sdo_event,
1089*576c57e6SKiseok Jo 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1090*576c57e6SKiseok Jo 	SND_SOC_DAPM_MIXER("Entry", SND_SOC_NOPM, 0, 0, NULL, 0),
1091*576c57e6SKiseok Jo 	SND_SOC_DAPM_OUT_DRV_E("AMP Power", SND_SOC_NOPM, 0, 0, NULL, 0,
1092*576c57e6SKiseok Jo 			       sma1307_power_event,
1093*576c57e6SKiseok Jo 			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
1094*576c57e6SKiseok Jo 			       SND_SOC_DAPM_POST_PMU),
1095*576c57e6SKiseok Jo 	SND_SOC_DAPM_SWITCH("AMP Enable", SND_SOC_NOPM, 0, 0,
1096*576c57e6SKiseok Jo 			    &sma1307_enable_control),
1097*576c57e6SKiseok Jo 
1098*576c57e6SKiseok Jo 	/* stream domain */
1099*576c57e6SKiseok Jo 	SND_SOC_DAPM_AIF_IN("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0),
1100*576c57e6SKiseok Jo 	SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
1101*576c57e6SKiseok Jo };
1102*576c57e6SKiseok Jo 
1103*576c57e6SKiseok Jo static const struct snd_soc_dapm_route sma1307_audio_map[] = {
1104*576c57e6SKiseok Jo 	/* Playback */
1105*576c57e6SKiseok Jo 	{ "AIF IN Source", "Mono", "AIF IN" },
1106*576c57e6SKiseok Jo 	{ "AIF IN Source", "Left", "AIF IN" },
1107*576c57e6SKiseok Jo 	{ "AIF IN Source", "Right", "AIF IN" },
1108*576c57e6SKiseok Jo 
1109*576c57e6SKiseok Jo 	{ "SDO Enable", "Switch", "AIF IN" },
1110*576c57e6SKiseok Jo 
1111*576c57e6SKiseok Jo 	{ "SDO Setting", "Data_One_48k", "SDO Enable" },
1112*576c57e6SKiseok Jo 	{ "SDO Setting", "Data_Two_48k", "SDO Enable" },
1113*576c57e6SKiseok Jo 	{ "SDO Setting", "Data_Two_24k", "SDO Enable" },
1114*576c57e6SKiseok Jo 	{ "SDO Setting", "Clk_PLL", "SDO Enable" },
1115*576c57e6SKiseok Jo 	{ "SDO Setting", "Clk_OSC", "SDO Enable" },
1116*576c57e6SKiseok Jo 
1117*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "Disable", "SDO Setting" },
1118*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "After_FmtC", "SDO Setting" },
1119*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "After_Mixer", "SDO Setting" },
1120*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "After_DSP", "SDO Setting" },
1121*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "Vrms2_Avg", "SDO Setting" },
1122*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "Battery", "SDO Setting" },
1123*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "Temperature", "SDO Setting" },
1124*576c57e6SKiseok Jo 	{ "AIF OUT0 Source", "After_Delay", "SDO Setting" },
1125*576c57e6SKiseok Jo 
1126*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "Disable", "SDO Setting" },
1127*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "After_FmtC", "SDO Setting" },
1128*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "After_Mixer", "SDO Setting" },
1129*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "After_DSP", "SDO Setting" },
1130*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "Vrms2_Avg", "SDO Setting" },
1131*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "Battery", "SDO Setting" },
1132*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "Temperature", "SDO Setting" },
1133*576c57e6SKiseok Jo 	{ "AIF OUT1 Source", "After_Delay", "SDO Setting" },
1134*576c57e6SKiseok Jo 
1135*576c57e6SKiseok Jo 	{ "Entry", NULL, "AIF OUT0 Source" },
1136*576c57e6SKiseok Jo 	{ "Entry", NULL, "AIF OUT1 Source" },
1137*576c57e6SKiseok Jo 	{ "Entry", NULL, "AIF IN Source" },
1138*576c57e6SKiseok Jo 
1139*576c57e6SKiseok Jo 	{ "AMP Power", NULL, "Entry" },
1140*576c57e6SKiseok Jo 
1141*576c57e6SKiseok Jo 	{ "AMP Enable", "Switch", "AMP Power" },
1142*576c57e6SKiseok Jo 	{ "SPK", NULL, "AMP Enable" },
1143*576c57e6SKiseok Jo 
1144*576c57e6SKiseok Jo 	/* Capture */
1145*576c57e6SKiseok Jo 	{ "AIF OUT", NULL, "AMP Enable" },
1146*576c57e6SKiseok Jo };
1147*576c57e6SKiseok Jo 
1148*576c57e6SKiseok Jo static void sma1307_setup_pll(struct snd_soc_component *component,
1149*576c57e6SKiseok Jo 			      unsigned int bclk)
1150*576c57e6SKiseok Jo {
1151*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1152*576c57e6SKiseok Jo 
1153*576c57e6SKiseok Jo 	int i = 0;
1154*576c57e6SKiseok Jo 
1155*576c57e6SKiseok Jo 	dev_dbg(component->dev, "%s: BCLK = %dHz\n", __func__, bclk);
1156*576c57e6SKiseok Jo 
1157*576c57e6SKiseok Jo 	if (sma1307->sys_clk_id == SMA1307_PLL_CLKIN_MCLK) {
1158*576c57e6SKiseok Jo 		dev_warn(component->dev, "%s: MCLK is not supported\n",
1159*576c57e6SKiseok Jo 			 __func__);
1160*576c57e6SKiseok Jo 	} else if (sma1307->sys_clk_id == SMA1307_PLL_CLKIN_BCLK) {
1161*576c57e6SKiseok Jo 		for (i = 0; i < sma1307->num_of_pll_matches; i++) {
1162*576c57e6SKiseok Jo 			if (sma1307->pll_matches[i].input_clk == bclk)
1163*576c57e6SKiseok Jo 				break;
1164*576c57e6SKiseok Jo 		}
1165*576c57e6SKiseok Jo 		if (i == sma1307->num_of_pll_matches) {
1166*576c57e6SKiseok Jo 			dev_warn(component->dev,
1167*576c57e6SKiseok Jo 				 "%s: No matching value between pll table and SCK\n",
1168*576c57e6SKiseok Jo 				 __func__);
1169*576c57e6SKiseok Jo 			return;
1170*576c57e6SKiseok Jo 		}
1171*576c57e6SKiseok Jo 
1172*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1173*576c57e6SKiseok Jo 					   SMA1307_A2_TOP_MAN1,
1174*576c57e6SKiseok Jo 					   SMA1307_PLL_MASK, SMA1307_PLL_ON);
1175*576c57e6SKiseok Jo 	}
1176*576c57e6SKiseok Jo 
1177*576c57e6SKiseok Jo 	regmap_write(sma1307->regmap, SMA1307_8B_PLL_POST_N,
1178*576c57e6SKiseok Jo 			     sma1307->pll_matches[i].post_n);
1179*576c57e6SKiseok Jo 	regmap_write(sma1307->regmap, SMA1307_8C_PLL_N,
1180*576c57e6SKiseok Jo 			     sma1307->pll_matches[i].n);
1181*576c57e6SKiseok Jo 	regmap_write(sma1307->regmap, SMA1307_8D_PLL_A_SETTING,
1182*576c57e6SKiseok Jo 			     sma1307->pll_matches[i].vco);
1183*576c57e6SKiseok Jo 	regmap_write(sma1307->regmap, SMA1307_8E_PLL_P_CP,
1184*576c57e6SKiseok Jo 			     sma1307->pll_matches[i].p_cp);
1185*576c57e6SKiseok Jo }
1186*576c57e6SKiseok Jo 
1187*576c57e6SKiseok Jo static int sma1307_dai_hw_params_amp(struct snd_pcm_substream *substream,
1188*576c57e6SKiseok Jo 				     struct snd_pcm_hw_params *params,
1189*576c57e6SKiseok Jo 				     struct snd_soc_dai *dai)
1190*576c57e6SKiseok Jo {
1191*576c57e6SKiseok Jo 	struct snd_soc_component *component = dai->component;
1192*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1193*576c57e6SKiseok Jo 	unsigned int bclk = 0;
1194*576c57e6SKiseok Jo 	int ret = 0;
1195*576c57e6SKiseok Jo 
1196*576c57e6SKiseok Jo 	if (sma1307->format == SND_SOC_DAIFMT_DSP_A)
1197*576c57e6SKiseok Jo 		bclk = params_rate(params) * sma1307->frame_size;
1198*576c57e6SKiseok Jo 	else
1199*576c57e6SKiseok Jo 		bclk = params_rate(params) * params_physical_width(params)
1200*576c57e6SKiseok Jo 		    * params_channels(params);
1201*576c57e6SKiseok Jo 
1202*576c57e6SKiseok Jo 	dev_dbg(component->dev,
1203*576c57e6SKiseok Jo 		 "%s: rate = %d : bit size = %d : channel = %d\n",
1204*576c57e6SKiseok Jo 		 __func__, params_rate(params), params_width(params),
1205*576c57e6SKiseok Jo 		 params_channels(params));
1206*576c57e6SKiseok Jo 
1207*576c57e6SKiseok Jo 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1208*576c57e6SKiseok Jo 		if (sma1307->sys_clk_id == SMA1307_PLL_CLKIN_BCLK) {
1209*576c57e6SKiseok Jo 			if (sma1307->last_bclk != bclk) {
1210*576c57e6SKiseok Jo 				sma1307_setup_pll(component, bclk);
1211*576c57e6SKiseok Jo 				sma1307->last_bclk = bclk;
1212*576c57e6SKiseok Jo 			}
1213*576c57e6SKiseok Jo 		}
1214*576c57e6SKiseok Jo 
1215*576c57e6SKiseok Jo 		switch (params_rate(params)) {
1216*576c57e6SKiseok Jo 		case 8000:
1217*576c57e6SKiseok Jo 		case 12000:
1218*576c57e6SKiseok Jo 		case 16000:
1219*576c57e6SKiseok Jo 		case 24000:
1220*576c57e6SKiseok Jo 		case 32000:
1221*576c57e6SKiseok Jo 		case 44100:
1222*576c57e6SKiseok Jo 		case 48000:
1223*576c57e6SKiseok Jo 			break;
1224*576c57e6SKiseok Jo 
1225*576c57e6SKiseok Jo 		case 96000:
1226*576c57e6SKiseok Jo 			dev_warn(component->dev,
1227*576c57e6SKiseok Jo 				 "%s: %d rate not support SDO\n", __func__,
1228*576c57e6SKiseok Jo 				 params_rate(params));
1229*576c57e6SKiseok Jo 			break;
1230*576c57e6SKiseok Jo 
1231*576c57e6SKiseok Jo 		default:
1232*576c57e6SKiseok Jo 			dev_err(component->dev, "%s: not support rate : %d\n",
1233*576c57e6SKiseok Jo 				__func__, params_rate(params));
1234*576c57e6SKiseok Jo 
1235*576c57e6SKiseok Jo 			return -EINVAL;
1236*576c57e6SKiseok Jo 		}
1237*576c57e6SKiseok Jo 
1238*576c57e6SKiseok Jo 		/* substream->stream is SNDRV_PCM_STREAM_CAPTURE */
1239*576c57e6SKiseok Jo 	} else {
1240*576c57e6SKiseok Jo 
1241*576c57e6SKiseok Jo 		switch (params_format(params)) {
1242*576c57e6SKiseok Jo 		case SNDRV_PCM_FORMAT_S16_LE:
1243*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
1244*576c57e6SKiseok Jo 						   SMA1307_A4_TOP_MAN3,
1245*576c57e6SKiseok Jo 						   SMA1307_SCK_RATE_MASK
1246*576c57e6SKiseok Jo 						   |
1247*576c57e6SKiseok Jo 						   SMA1307_DATA_WIDTH_MASK,
1248*576c57e6SKiseok Jo 						   SMA1307_SCK_32FS |
1249*576c57e6SKiseok Jo 						   SMA1307_DATA_16BIT);
1250*576c57e6SKiseok Jo 			break;
1251*576c57e6SKiseok Jo 
1252*576c57e6SKiseok Jo 		case SNDRV_PCM_FORMAT_S24_LE:
1253*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
1254*576c57e6SKiseok Jo 						   SMA1307_A4_TOP_MAN3,
1255*576c57e6SKiseok Jo 						   SMA1307_SCK_RATE_MASK
1256*576c57e6SKiseok Jo 						   |
1257*576c57e6SKiseok Jo 						   SMA1307_DATA_WIDTH_MASK,
1258*576c57e6SKiseok Jo 						   SMA1307_SCK_64FS |
1259*576c57e6SKiseok Jo 						   SMA1307_DATA_24BIT);
1260*576c57e6SKiseok Jo 			break;
1261*576c57e6SKiseok Jo 
1262*576c57e6SKiseok Jo 		case SNDRV_PCM_FORMAT_S32_LE:
1263*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
1264*576c57e6SKiseok Jo 						   SMA1307_A4_TOP_MAN3,
1265*576c57e6SKiseok Jo 						   SMA1307_SCK_RATE_MASK
1266*576c57e6SKiseok Jo 						   |
1267*576c57e6SKiseok Jo 						   SMA1307_DATA_WIDTH_MASK,
1268*576c57e6SKiseok Jo 						   SMA1307_SCK_64FS |
1269*576c57e6SKiseok Jo 						   SMA1307_DATA_24BIT);
1270*576c57e6SKiseok Jo 			break;
1271*576c57e6SKiseok Jo 		default:
1272*576c57e6SKiseok Jo 			dev_err(component->dev,
1273*576c57e6SKiseok Jo 				"%s: not support data bit : %d\n", __func__,
1274*576c57e6SKiseok Jo 				params_format(params));
1275*576c57e6SKiseok Jo 			return -EINVAL;
1276*576c57e6SKiseok Jo 		}
1277*576c57e6SKiseok Jo 	}
1278*576c57e6SKiseok Jo 
1279*576c57e6SKiseok Jo 	switch (sma1307->format) {
1280*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_I2S:
1281*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1282*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1283*576c57e6SKiseok Jo 					   SMA1307_I2S_MODE_MASK,
1284*576c57e6SKiseok Jo 					   SMA1307_STANDARD_I2S);
1285*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1286*576c57e6SKiseok Jo 					   SMA1307_A4_TOP_MAN3,
1287*576c57e6SKiseok Jo 					   SMA1307_INTERFACE_MASK,
1288*576c57e6SKiseok Jo 					   SMA1307_I2S_FORMAT);
1289*576c57e6SKiseok Jo 		break;
1290*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_LEFT_J:
1291*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1292*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1293*576c57e6SKiseok Jo 					   SMA1307_I2S_MODE_MASK, SMA1307_LJ);
1294*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1295*576c57e6SKiseok Jo 					   SMA1307_A4_TOP_MAN3,
1296*576c57e6SKiseok Jo 					   SMA1307_INTERFACE_MASK,
1297*576c57e6SKiseok Jo 					   SMA1307_LJ_FORMAT);
1298*576c57e6SKiseok Jo 		break;
1299*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_RIGHT_J:
1300*576c57e6SKiseok Jo 		switch (params_width(params)) {
1301*576c57e6SKiseok Jo 		case 16:
1302*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
1303*576c57e6SKiseok Jo 						   SMA1307_01_INPUT_CTRL1,
1304*576c57e6SKiseok Jo 						   SMA1307_I2S_MODE_MASK,
1305*576c57e6SKiseok Jo 						   SMA1307_RJ_16BIT);
1306*576c57e6SKiseok Jo 			break;
1307*576c57e6SKiseok Jo 		case 24:
1308*576c57e6SKiseok Jo 		case 32:
1309*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
1310*576c57e6SKiseok Jo 						   SMA1307_01_INPUT_CTRL1,
1311*576c57e6SKiseok Jo 						   SMA1307_I2S_MODE_MASK,
1312*576c57e6SKiseok Jo 						   SMA1307_RJ_24BIT);
1313*576c57e6SKiseok Jo 			break;
1314*576c57e6SKiseok Jo 		}
1315*576c57e6SKiseok Jo 		break;
1316*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_DSP_A:
1317*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1318*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1319*576c57e6SKiseok Jo 					   SMA1307_I2S_MODE_MASK,
1320*576c57e6SKiseok Jo 					   SMA1307_STANDARD_I2S);
1321*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1322*576c57e6SKiseok Jo 					   SMA1307_A4_TOP_MAN3,
1323*576c57e6SKiseok Jo 					   SMA1307_INTERFACE_MASK,
1324*576c57e6SKiseok Jo 					   SMA1307_TDM_FORMAT);
1325*576c57e6SKiseok Jo 		break;
1326*576c57e6SKiseok Jo 	}
1327*576c57e6SKiseok Jo 
1328*576c57e6SKiseok Jo 	switch (params_width(params)) {
1329*576c57e6SKiseok Jo 	case 16:
1330*576c57e6SKiseok Jo 	case 24:
1331*576c57e6SKiseok Jo 	case 32:
1332*576c57e6SKiseok Jo 		break;
1333*576c57e6SKiseok Jo 	default:
1334*576c57e6SKiseok Jo 		dev_err(component->dev,
1335*576c57e6SKiseok Jo 			"%s: not support data bit : %d\n", __func__,
1336*576c57e6SKiseok Jo 			params_format(params));
1337*576c57e6SKiseok Jo 		return -EINVAL;
1338*576c57e6SKiseok Jo 	}
1339*576c57e6SKiseok Jo 	if (ret < 0)
1340*576c57e6SKiseok Jo 		return -EINVAL;
1341*576c57e6SKiseok Jo 
1342*576c57e6SKiseok Jo 	return 0;
1343*576c57e6SKiseok Jo }
1344*576c57e6SKiseok Jo 
1345*576c57e6SKiseok Jo static int sma1307_dai_set_sysclk_amp(struct snd_soc_dai *dai,
1346*576c57e6SKiseok Jo 				      int clk_id, unsigned int freq, int dir)
1347*576c57e6SKiseok Jo {
1348*576c57e6SKiseok Jo 	struct snd_soc_component *component = dai->component;
1349*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1350*576c57e6SKiseok Jo 
1351*576c57e6SKiseok Jo 	switch (clk_id) {
1352*576c57e6SKiseok Jo 	case SMA1307_EXTERNAL_CLOCK_19_2:
1353*576c57e6SKiseok Jo 	case SMA1307_EXTERNAL_CLOCK_24_576:
1354*576c57e6SKiseok Jo 	case SMA1307_PLL_CLKIN_MCLK:
1355*576c57e6SKiseok Jo 	case SMA1307_PLL_CLKIN_BCLK:
1356*576c57e6SKiseok Jo 		break;
1357*576c57e6SKiseok Jo 	default:
1358*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: Invalid clk id: %d\n",
1359*576c57e6SKiseok Jo 			__func__, clk_id);
1360*576c57e6SKiseok Jo 		return -EINVAL;
1361*576c57e6SKiseok Jo 	}
1362*576c57e6SKiseok Jo 	sma1307->sys_clk_id = clk_id;
1363*576c57e6SKiseok Jo 
1364*576c57e6SKiseok Jo 	return 0;
1365*576c57e6SKiseok Jo }
1366*576c57e6SKiseok Jo 
1367*576c57e6SKiseok Jo static int sma1307_dai_set_fmt_amp(struct snd_soc_dai *dai, unsigned int fmt)
1368*576c57e6SKiseok Jo {
1369*576c57e6SKiseok Jo 	struct snd_soc_component *component = dai->component;
1370*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1371*576c57e6SKiseok Jo 
1372*576c57e6SKiseok Jo 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1373*576c57e6SKiseok Jo 
1374*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_CBC_CFC:
1375*576c57e6SKiseok Jo 		dev_dbg(component->dev,
1376*576c57e6SKiseok Jo 			 "%s: %s\n", __func__, "I2S/TDM Device mode");
1377*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1378*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1379*576c57e6SKiseok Jo 					   SMA1307_CONTROLLER_DEVICE_MASK,
1380*576c57e6SKiseok Jo 					   SMA1307_DEVICE_MODE);
1381*576c57e6SKiseok Jo 		break;
1382*576c57e6SKiseok Jo 
1383*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_CBP_CFP:
1384*576c57e6SKiseok Jo 		dev_dbg(component->dev,
1385*576c57e6SKiseok Jo 			 "%s: %s\n", __func__, "I2S/TDM Controller mode");
1386*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1387*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1388*576c57e6SKiseok Jo 					   SMA1307_CONTROLLER_DEVICE_MASK,
1389*576c57e6SKiseok Jo 					   SMA1307_CONTROLLER_MODE);
1390*576c57e6SKiseok Jo 		break;
1391*576c57e6SKiseok Jo 
1392*576c57e6SKiseok Jo 	default:
1393*576c57e6SKiseok Jo 		dev_err(component->dev,
1394*576c57e6SKiseok Jo 			"%s: Unsupported Controller/Device : 0x%x\n",
1395*576c57e6SKiseok Jo 			__func__, fmt);
1396*576c57e6SKiseok Jo 		return -EINVAL;
1397*576c57e6SKiseok Jo 	}
1398*576c57e6SKiseok Jo 
1399*576c57e6SKiseok Jo 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1400*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_I2S:
1401*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_RIGHT_J:
1402*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_LEFT_J:
1403*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_DSP_A:
1404*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_DSP_B:
1405*576c57e6SKiseok Jo 		sma1307->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
1406*576c57e6SKiseok Jo 		break;
1407*576c57e6SKiseok Jo 	default:
1408*576c57e6SKiseok Jo 		dev_err(component->dev,
1409*576c57e6SKiseok Jo 			"%s: Unsupported Audio Interface Format : 0x%x\n",
1410*576c57e6SKiseok Jo 			__func__, fmt);
1411*576c57e6SKiseok Jo 		return -EINVAL;
1412*576c57e6SKiseok Jo 	}
1413*576c57e6SKiseok Jo 
1414*576c57e6SKiseok Jo 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1415*576c57e6SKiseok Jo 
1416*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_IB_NF:
1417*576c57e6SKiseok Jo 		dev_dbg(component->dev, "%s: %s\n",
1418*576c57e6SKiseok Jo 			 __func__, "Invert BCLK + Normal Frame");
1419*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1420*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1421*576c57e6SKiseok Jo 					   SMA1307_SCK_RISING_MASK,
1422*576c57e6SKiseok Jo 					   SMA1307_SCK_RISING_EDGE);
1423*576c57e6SKiseok Jo 		break;
1424*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_IB_IF:
1425*576c57e6SKiseok Jo 		dev_dbg(component->dev, "%s: %s\n",
1426*576c57e6SKiseok Jo 			 __func__, "Invert BCLK + Invert Frame");
1427*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1428*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1429*576c57e6SKiseok Jo 					   SMA1307_LEFTPOL_MASK
1430*576c57e6SKiseok Jo 					   | SMA1307_SCK_RISING_MASK,
1431*576c57e6SKiseok Jo 					   SMA1307_HIGH_FIRST_CH
1432*576c57e6SKiseok Jo 					   | SMA1307_SCK_RISING_EDGE);
1433*576c57e6SKiseok Jo 		break;
1434*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_NB_IF:
1435*576c57e6SKiseok Jo 		dev_dbg(component->dev, "%s: %s\n",
1436*576c57e6SKiseok Jo 			 __func__, "Normal BCLK + Invert Frame");
1437*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1438*576c57e6SKiseok Jo 					   SMA1307_01_INPUT_CTRL1,
1439*576c57e6SKiseok Jo 					   SMA1307_LEFTPOL_MASK,
1440*576c57e6SKiseok Jo 					   SMA1307_HIGH_FIRST_CH);
1441*576c57e6SKiseok Jo 		break;
1442*576c57e6SKiseok Jo 	case SND_SOC_DAIFMT_NB_NF:
1443*576c57e6SKiseok Jo 		dev_dbg(component->dev, "%s: %s\n",
1444*576c57e6SKiseok Jo 			 __func__, "Normal BCLK + Normal Frame");
1445*576c57e6SKiseok Jo 		break;
1446*576c57e6SKiseok Jo 	default:
1447*576c57e6SKiseok Jo 		dev_err(component->dev,
1448*576c57e6SKiseok Jo 			"%s: Unsupported Bit & Frameclock : 0x%x\n",
1449*576c57e6SKiseok Jo 			__func__, fmt);
1450*576c57e6SKiseok Jo 		return -EINVAL;
1451*576c57e6SKiseok Jo 	}
1452*576c57e6SKiseok Jo 
1453*576c57e6SKiseok Jo 	return 0;
1454*576c57e6SKiseok Jo }
1455*576c57e6SKiseok Jo 
1456*576c57e6SKiseok Jo static int sma1307_dai_set_tdm_slot(struct snd_soc_dai *dai,
1457*576c57e6SKiseok Jo 				    unsigned int tx_mask, unsigned int rx_mask,
1458*576c57e6SKiseok Jo 				    int slots, int slot_width)
1459*576c57e6SKiseok Jo {
1460*576c57e6SKiseok Jo 	struct snd_soc_component *component = dai->component;
1461*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1462*576c57e6SKiseok Jo 
1463*576c57e6SKiseok Jo 	dev_dbg(component->dev, "%s: slots = %d, slot_width - %d\n",
1464*576c57e6SKiseok Jo 		 __func__, slots, slot_width);
1465*576c57e6SKiseok Jo 
1466*576c57e6SKiseok Jo 	sma1307->frame_size = slot_width * slots;
1467*576c57e6SKiseok Jo 
1468*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap,
1469*576c57e6SKiseok Jo 				   SMA1307_A4_TOP_MAN3,
1470*576c57e6SKiseok Jo 				   SMA1307_INTERFACE_MASK, SMA1307_TDM_FORMAT);
1471*576c57e6SKiseok Jo 
1472*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap,
1473*576c57e6SKiseok Jo 				   SMA1307_A5_TDM1,
1474*576c57e6SKiseok Jo 				   SMA1307_TDM_TX_MODE_MASK,
1475*576c57e6SKiseok Jo 				   SMA1307_TDM_TX_MONO);
1476*576c57e6SKiseok Jo 
1477*576c57e6SKiseok Jo 	switch (slot_width) {
1478*576c57e6SKiseok Jo 	case 16:
1479*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1480*576c57e6SKiseok Jo 					   SMA1307_A6_TDM2,
1481*576c57e6SKiseok Jo 					   SMA1307_TDM_DL_MASK,
1482*576c57e6SKiseok Jo 					   SMA1307_TDM_DL_16);
1483*576c57e6SKiseok Jo 		break;
1484*576c57e6SKiseok Jo 	case 32:
1485*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1486*576c57e6SKiseok Jo 					   SMA1307_A6_TDM2,
1487*576c57e6SKiseok Jo 					   SMA1307_TDM_DL_MASK,
1488*576c57e6SKiseok Jo 					   SMA1307_TDM_DL_32);
1489*576c57e6SKiseok Jo 		break;
1490*576c57e6SKiseok Jo 	default:
1491*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: not support TDM %d slot_width\n",
1492*576c57e6SKiseok Jo 			__func__, slot_width);
1493*576c57e6SKiseok Jo 		return -EINVAL;
1494*576c57e6SKiseok Jo 	}
1495*576c57e6SKiseok Jo 
1496*576c57e6SKiseok Jo 	switch (slots) {
1497*576c57e6SKiseok Jo 	case 4:
1498*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1499*576c57e6SKiseok Jo 					   SMA1307_A6_TDM2,
1500*576c57e6SKiseok Jo 					   SMA1307_TDM_N_SLOT_MASK,
1501*576c57e6SKiseok Jo 					   SMA1307_TDM_N_SLOT_4);
1502*576c57e6SKiseok Jo 		break;
1503*576c57e6SKiseok Jo 	case 8:
1504*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1505*576c57e6SKiseok Jo 					   SMA1307_A6_TDM2,
1506*576c57e6SKiseok Jo 					   SMA1307_TDM_N_SLOT_MASK,
1507*576c57e6SKiseok Jo 					   SMA1307_TDM_N_SLOT_8);
1508*576c57e6SKiseok Jo 		break;
1509*576c57e6SKiseok Jo 	default:
1510*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: not support TDM %d slots\n",
1511*576c57e6SKiseok Jo 			__func__, slots);
1512*576c57e6SKiseok Jo 		return -EINVAL;
1513*576c57e6SKiseok Jo 	}
1514*576c57e6SKiseok Jo 
1515*576c57e6SKiseok Jo 	if (sma1307->tdm_slot0_rx < slots)
1516*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1517*576c57e6SKiseok Jo 					   SMA1307_A5_TDM1,
1518*576c57e6SKiseok Jo 					   SMA1307_TDM_SLOT0_RX_POS_MASK,
1519*576c57e6SKiseok Jo 					   sma1307->tdm_slot0_rx << 3);
1520*576c57e6SKiseok Jo 	else
1521*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: Incorrect tdm-slot0-rx %d set\n",
1522*576c57e6SKiseok Jo 			__func__, sma1307->tdm_slot0_rx);
1523*576c57e6SKiseok Jo 
1524*576c57e6SKiseok Jo 	if (sma1307->tdm_slot1_rx < slots)
1525*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1526*576c57e6SKiseok Jo 					   SMA1307_A5_TDM1,
1527*576c57e6SKiseok Jo 					   SMA1307_TDM_SLOT1_RX_POS_MASK,
1528*576c57e6SKiseok Jo 					   sma1307->tdm_slot1_rx);
1529*576c57e6SKiseok Jo 	else
1530*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: Incorrect tdm-slot1-rx %d set\n",
1531*576c57e6SKiseok Jo 			__func__, sma1307->tdm_slot1_rx);
1532*576c57e6SKiseok Jo 
1533*576c57e6SKiseok Jo 	if (sma1307->tdm_slot0_tx < slots)
1534*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1535*576c57e6SKiseok Jo 					   SMA1307_A6_TDM2,
1536*576c57e6SKiseok Jo 					   SMA1307_TDM_SLOT0_TX_POS_MASK,
1537*576c57e6SKiseok Jo 					   sma1307->tdm_slot0_tx << 3);
1538*576c57e6SKiseok Jo 	else
1539*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: Incorrect tdm-slot0-tx %d set\n",
1540*576c57e6SKiseok Jo 			__func__, sma1307->tdm_slot0_tx);
1541*576c57e6SKiseok Jo 
1542*576c57e6SKiseok Jo 	if (sma1307->tdm_slot1_tx < slots)
1543*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1544*576c57e6SKiseok Jo 					   SMA1307_A6_TDM2,
1545*576c57e6SKiseok Jo 					   SMA1307_TDM_SLOT1_TX_POS_MASK,
1546*576c57e6SKiseok Jo 					   sma1307->tdm_slot1_tx);
1547*576c57e6SKiseok Jo 	else
1548*576c57e6SKiseok Jo 		dev_err(component->dev, "%s: Incorrect tdm-slot1-tx %d set\n",
1549*576c57e6SKiseok Jo 			__func__, sma1307->tdm_slot1_tx);
1550*576c57e6SKiseok Jo 
1551*576c57e6SKiseok Jo 	return 0;
1552*576c57e6SKiseok Jo }
1553*576c57e6SKiseok Jo 
1554*576c57e6SKiseok Jo static int sma1307_dai_mute_stream(struct snd_soc_dai *dai, int mute,
1555*576c57e6SKiseok Jo 				   int stream)
1556*576c57e6SKiseok Jo {
1557*576c57e6SKiseok Jo 	struct snd_soc_component *component = dai->component;
1558*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1559*576c57e6SKiseok Jo 
1560*576c57e6SKiseok Jo 	if (stream == SNDRV_PCM_STREAM_CAPTURE)
1561*576c57e6SKiseok Jo 		return 0;
1562*576c57e6SKiseok Jo 	if (mute) {
1563*576c57e6SKiseok Jo 		dev_dbg(component->dev, "%s: %s\n", __func__, "MUTE");
1564*576c57e6SKiseok Jo 		regmap_update_bits(sma1307->regmap,
1565*576c57e6SKiseok Jo 					   SMA1307_0E_MUTE_VOL_CTRL,
1566*576c57e6SKiseok Jo 					   SMA1307_SPK_MUTE_MASK,
1567*576c57e6SKiseok Jo 					   SMA1307_SPK_MUTE);
1568*576c57e6SKiseok Jo 	} else {
1569*576c57e6SKiseok Jo 		if (!sma1307->force_mute_status) {
1570*576c57e6SKiseok Jo 			dev_dbg(component->dev, "%s: %s\n", __func__,
1571*576c57e6SKiseok Jo 					 "UNMUTE");
1572*576c57e6SKiseok Jo 			regmap_update_bits(sma1307->regmap,
1573*576c57e6SKiseok Jo 						SMA1307_0E_MUTE_VOL_CTRL,
1574*576c57e6SKiseok Jo 						SMA1307_SPK_MUTE_MASK,
1575*576c57e6SKiseok Jo 						SMA1307_SPK_UNMUTE);
1576*576c57e6SKiseok Jo 		} else {
1577*576c57e6SKiseok Jo 			dev_dbg(sma1307->dev, "%s: FORCE MUTE!!!\n", __func__);
1578*576c57e6SKiseok Jo 		}
1579*576c57e6SKiseok Jo 	}
1580*576c57e6SKiseok Jo 
1581*576c57e6SKiseok Jo 	return 0;
1582*576c57e6SKiseok Jo }
1583*576c57e6SKiseok Jo 
1584*576c57e6SKiseok Jo static const struct snd_soc_dai_ops sma1307_dai_ops_amp = {
1585*576c57e6SKiseok Jo 	.hw_params = sma1307_dai_hw_params_amp,
1586*576c57e6SKiseok Jo 	.set_fmt = sma1307_dai_set_fmt_amp,
1587*576c57e6SKiseok Jo 	.set_sysclk = sma1307_dai_set_sysclk_amp,
1588*576c57e6SKiseok Jo 	.set_tdm_slot = sma1307_dai_set_tdm_slot,
1589*576c57e6SKiseok Jo 	.mute_stream = sma1307_dai_mute_stream,
1590*576c57e6SKiseok Jo };
1591*576c57e6SKiseok Jo 
1592*576c57e6SKiseok Jo #define SMA1307_RATES_PLAYBACK SNDRV_PCM_RATE_8000_96000
1593*576c57e6SKiseok Jo #define SMA1307_RATES_CAPTURE SNDRV_PCM_RATE_8000_48000
1594*576c57e6SKiseok Jo #define SMA1307_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
1595*576c57e6SKiseok Jo 		SNDRV_PCM_FMTBIT_S32_LE)
1596*576c57e6SKiseok Jo 
1597*576c57e6SKiseok Jo static struct snd_soc_dai_driver sma1307_dai[] = {
1598*576c57e6SKiseok Jo 	{
1599*576c57e6SKiseok Jo 	 .name = "sma1307-amplifier",
1600*576c57e6SKiseok Jo 	 .id = 0,
1601*576c57e6SKiseok Jo 	 .playback = {
1602*576c57e6SKiseok Jo 		      .stream_name = "Playback",
1603*576c57e6SKiseok Jo 		      .channels_min = 1,
1604*576c57e6SKiseok Jo 		      .channels_max = 2,
1605*576c57e6SKiseok Jo 		      .rates = SMA1307_RATES_PLAYBACK,
1606*576c57e6SKiseok Jo 		      .formats = SMA1307_FORMATS,
1607*576c57e6SKiseok Jo 		      },
1608*576c57e6SKiseok Jo 	 .capture = {
1609*576c57e6SKiseok Jo 		     .stream_name = "Capture",
1610*576c57e6SKiseok Jo 		     .channels_min = 1,
1611*576c57e6SKiseok Jo 		     .channels_max = 2,
1612*576c57e6SKiseok Jo 		     .rates = SMA1307_RATES_CAPTURE,
1613*576c57e6SKiseok Jo 		     .formats = SMA1307_FORMATS,
1614*576c57e6SKiseok Jo 		     },
1615*576c57e6SKiseok Jo 	 .ops = &sma1307_dai_ops_amp,
1616*576c57e6SKiseok Jo 	  },
1617*576c57e6SKiseok Jo };
1618*576c57e6SKiseok Jo 
1619*576c57e6SKiseok Jo static void sma1307_check_fault_worker(struct work_struct *work)
1620*576c57e6SKiseok Jo {
1621*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
1622*576c57e6SKiseok Jo 	    container_of(work, struct sma1307_priv, check_fault_work.work);
1623*576c57e6SKiseok Jo 	unsigned int status1_val, status2_val;
1624*576c57e6SKiseok Jo 	char *envp[3] = { NULL, NULL, NULL };
1625*576c57e6SKiseok Jo 
1626*576c57e6SKiseok Jo 	if (sma1307->tsdw_cnt)
1627*576c57e6SKiseok Jo 		regmap_read(sma1307->regmap,
1628*576c57e6SKiseok Jo 			SMA1307_0A_SPK_VOL, &sma1307->cur_vol);
1629*576c57e6SKiseok Jo 	else
1630*576c57e6SKiseok Jo 		regmap_read(sma1307->regmap,
1631*576c57e6SKiseok Jo 			SMA1307_0A_SPK_VOL, &sma1307->init_vol);
1632*576c57e6SKiseok Jo 
1633*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_FA_STATUS1, &status1_val);
1634*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_FB_STATUS2, &status2_val);
1635*576c57e6SKiseok Jo 
1636*576c57e6SKiseok Jo 	if (~status1_val & SMA1307_OT1_OK_STATUS) {
1637*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1638*576c57e6SKiseok Jo 			 "%s: OT1(Over Temperature Level 1)\n", __func__);
1639*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=OT1");
1640*576c57e6SKiseok Jo 		if (sma1307->sw_ot1_prot) {
1641*576c57e6SKiseok Jo 			/* Volume control (Current Volume -3dB) */
1642*576c57e6SKiseok Jo 			if ((sma1307->cur_vol + 6) <= 0xFA) {
1643*576c57e6SKiseok Jo 				sma1307->cur_vol += 6;
1644*576c57e6SKiseok Jo 				regmap_write(sma1307->regmap,
1645*576c57e6SKiseok Jo 						     SMA1307_0A_SPK_VOL,
1646*576c57e6SKiseok Jo 						     sma1307->cur_vol);
1647*576c57e6SKiseok Jo 				envp[1] = kasprintf(GFP_KERNEL,
1648*576c57e6SKiseok Jo 					"VOLUME=0x%02X", sma1307->cur_vol);
1649*576c57e6SKiseok Jo 			}
1650*576c57e6SKiseok Jo 		}
1651*576c57e6SKiseok Jo 		sma1307->tsdw_cnt++;
1652*576c57e6SKiseok Jo 	} else if (sma1307->tsdw_cnt) {
1653*576c57e6SKiseok Jo 		regmap_write(sma1307->regmap,
1654*576c57e6SKiseok Jo 				     SMA1307_0A_SPK_VOL, sma1307->init_vol);
1655*576c57e6SKiseok Jo 		sma1307->tsdw_cnt = 0;
1656*576c57e6SKiseok Jo 		sma1307->cur_vol = sma1307->init_vol;
1657*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=OT1_CLEAR");
1658*576c57e6SKiseok Jo 		envp[1] = kasprintf(GFP_KERNEL,
1659*576c57e6SKiseok Jo 				"VOLUME=0x%02X", sma1307->cur_vol);
1660*576c57e6SKiseok Jo 	}
1661*576c57e6SKiseok Jo 
1662*576c57e6SKiseok Jo 	if (~status1_val & SMA1307_OT2_OK_STATUS) {
1663*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1664*576c57e6SKiseok Jo 			 "%s: OT2(Over Temperature Level 2)\n", __func__);
1665*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=OT2");
1666*576c57e6SKiseok Jo 	}
1667*576c57e6SKiseok Jo 	if (status1_val & SMA1307_UVLO_STATUS) {
1668*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1669*576c57e6SKiseok Jo 			 "%s: UVLO(Under Voltage Lock Out)\n", __func__);
1670*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=UVLO");
1671*576c57e6SKiseok Jo 	}
1672*576c57e6SKiseok Jo 	if (status1_val & SMA1307_OVP_BST_STATUS) {
1673*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1674*576c57e6SKiseok Jo 			 "%s: OVP_BST(Over Voltage Protection)\n", __func__);
1675*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=OVP_BST");
1676*576c57e6SKiseok Jo 	}
1677*576c57e6SKiseok Jo 	if (status2_val & SMA1307_OCP_SPK_STATUS) {
1678*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1679*576c57e6SKiseok Jo 			 "%s: OCP_SPK(Over Current Protect SPK)\n", __func__);
1680*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=OCP_SPK");
1681*576c57e6SKiseok Jo 	}
1682*576c57e6SKiseok Jo 	if (status2_val & SMA1307_OCP_BST_STATUS) {
1683*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1684*576c57e6SKiseok Jo 			 "%s: OCP_BST(Over Current Protect Boost)\n", __func__);
1685*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=OCP_BST");
1686*576c57e6SKiseok Jo 	}
1687*576c57e6SKiseok Jo 	if (status2_val & SMA1307_CLK_MON_STATUS) {
1688*576c57e6SKiseok Jo 		dev_crit(sma1307->dev,
1689*576c57e6SKiseok Jo 			 "%s: CLK_FAULT(No clock input)\n", __func__);
1690*576c57e6SKiseok Jo 		envp[0] = kasprintf(GFP_KERNEL, "STATUS=CLK_FAULT");
1691*576c57e6SKiseok Jo 	}
1692*576c57e6SKiseok Jo 
1693*576c57e6SKiseok Jo 	if (envp[0] != NULL) {
1694*576c57e6SKiseok Jo 		if (kobject_uevent_env(sma1307->kobj, KOBJ_CHANGE, envp))
1695*576c57e6SKiseok Jo 			dev_err(sma1307->dev,
1696*576c57e6SKiseok Jo 				"%s: Error sending uevent\n", __func__);
1697*576c57e6SKiseok Jo 		kfree(envp[0]);
1698*576c57e6SKiseok Jo 		kfree(envp[1]);
1699*576c57e6SKiseok Jo 	}
1700*576c57e6SKiseok Jo 
1701*576c57e6SKiseok Jo 	if (sma1307->check_fault_status) {
1702*576c57e6SKiseok Jo 		if (sma1307->check_fault_period > 0)
1703*576c57e6SKiseok Jo 			queue_delayed_work(system_freezable_wq,
1704*576c57e6SKiseok Jo 					   &sma1307->check_fault_work,
1705*576c57e6SKiseok Jo 					   sma1307->check_fault_period * HZ);
1706*576c57e6SKiseok Jo 		else
1707*576c57e6SKiseok Jo 			queue_delayed_work(system_freezable_wq,
1708*576c57e6SKiseok Jo 					   &sma1307->check_fault_work,
1709*576c57e6SKiseok Jo 					   CHECK_PERIOD_TIME * HZ);
1710*576c57e6SKiseok Jo 	}
1711*576c57e6SKiseok Jo }
1712*576c57e6SKiseok Jo 
1713*576c57e6SKiseok Jo static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *file)
1714*576c57e6SKiseok Jo {
1715*576c57e6SKiseok Jo 	const struct firmware *fw;
1716*576c57e6SKiseok Jo 	int *data, size, offset, num_mode;
1717*576c57e6SKiseok Jo 
1718*576c57e6SKiseok Jo 	request_firmware(&fw, file, sma1307->dev);
1719*576c57e6SKiseok Jo 
1720*576c57e6SKiseok Jo 	if (!fw) {
1721*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: failed to read \"%s\"\n",
1722*576c57e6SKiseok Jo 			__func__, setting_file);
1723*576c57e6SKiseok Jo 		release_firmware(fw);
1724*576c57e6SKiseok Jo 		sma1307->set.status = false;
1725*576c57e6SKiseok Jo 		return;
1726*576c57e6SKiseok Jo 	} else if ((fw->size) < SMA1307_SETTING_HEADER_SIZE) {
1727*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: Invalid file\n", __func__);
1728*576c57e6SKiseok Jo 		release_firmware(fw);
1729*576c57e6SKiseok Jo 		sma1307->set.status = false;
1730*576c57e6SKiseok Jo 		return;
1731*576c57e6SKiseok Jo 	}
1732*576c57e6SKiseok Jo 
1733*576c57e6SKiseok Jo 	data = kzalloc(fw->size, GFP_KERNEL);
1734*576c57e6SKiseok Jo 	size = fw->size >> 2;
1735*576c57e6SKiseok Jo 	memcpy(data, fw->data, fw->size);
1736*576c57e6SKiseok Jo 
1737*576c57e6SKiseok Jo 	release_firmware(fw);
1738*576c57e6SKiseok Jo 
1739*576c57e6SKiseok Jo 	/* HEADER */
1740*576c57e6SKiseok Jo 	sma1307->set.header_size = SMA1307_SETTING_HEADER_SIZE;
1741*576c57e6SKiseok Jo 	sma1307->set.checksum = data[sma1307->set.header_size - 2];
1742*576c57e6SKiseok Jo 	sma1307->set.num_mode = data[sma1307->set.header_size - 1];
1743*576c57e6SKiseok Jo 	num_mode = sma1307->set.num_mode;
1744*576c57e6SKiseok Jo 	sma1307->set.header = devm_kzalloc(sma1307->dev,
1745*576c57e6SKiseok Jo 					   sma1307->set.header_size,
1746*576c57e6SKiseok Jo 					   GFP_KERNEL);
1747*576c57e6SKiseok Jo 	memcpy(sma1307->set.header, data,
1748*576c57e6SKiseok Jo 	       sma1307->set.header_size * sizeof(int));
1749*576c57e6SKiseok Jo 
1750*576c57e6SKiseok Jo 	if ((sma1307->set.checksum >> 8) != SMA1307_SETTING_CHECKSUM) {
1751*576c57e6SKiseok Jo 		dev_err(sma1307->dev, "%s: failed by dismatch \"%s\"\n",
1752*576c57e6SKiseok Jo 			__func__, setting_file);
1753*576c57e6SKiseok Jo 		sma1307->set.status = false;
1754*576c57e6SKiseok Jo 		return;
1755*576c57e6SKiseok Jo 	}
1756*576c57e6SKiseok Jo 
1757*576c57e6SKiseok Jo 	/* DEFAULT */
1758*576c57e6SKiseok Jo 	sma1307->set.def_size = SMA1307_SETTING_DEFAULT_SIZE;
1759*576c57e6SKiseok Jo 	sma1307->set.def
1760*576c57e6SKiseok Jo 	    = devm_kzalloc(sma1307->dev,
1761*576c57e6SKiseok Jo 			   sma1307->set.def_size * sizeof(int), GFP_KERNEL);
1762*576c57e6SKiseok Jo 	memcpy(sma1307->set.def,
1763*576c57e6SKiseok Jo 	       &data[sma1307->set.header_size],
1764*576c57e6SKiseok Jo 	       sma1307->set.def_size * sizeof(int));
1765*576c57e6SKiseok Jo 
1766*576c57e6SKiseok Jo 	/* MODE */
1767*576c57e6SKiseok Jo 	offset = sma1307->set.header_size + sma1307->set.def_size;
1768*576c57e6SKiseok Jo 	sma1307->set.mode_size = DIV_ROUND_CLOSEST(size - offset, num_mode + 1);
1769*576c57e6SKiseok Jo 	for (int i = 0; i < num_mode; i++) {
1770*576c57e6SKiseok Jo 		sma1307->set.mode_set[i]
1771*576c57e6SKiseok Jo 		    = devm_kzalloc(sma1307->dev,
1772*576c57e6SKiseok Jo 				   sma1307->set.mode_size * 2 * sizeof(int),
1773*576c57e6SKiseok Jo 				   GFP_KERNEL);
1774*576c57e6SKiseok Jo 		for (int j = 0; j < sma1307->set.mode_size; j++) {
1775*576c57e6SKiseok Jo 			sma1307->set.mode_set[i][2 * j]
1776*576c57e6SKiseok Jo 			    = data[offset + ((num_mode + 1) * j)];
1777*576c57e6SKiseok Jo 			sma1307->set.mode_set[i][2 * j + 1]
1778*576c57e6SKiseok Jo 			    = data[offset + ((num_mode + 1) * j + i + 1)];
1779*576c57e6SKiseok Jo 		}
1780*576c57e6SKiseok Jo 	}
1781*576c57e6SKiseok Jo 
1782*576c57e6SKiseok Jo 	kfree(data);
1783*576c57e6SKiseok Jo 	sma1307->set.status = true;
1784*576c57e6SKiseok Jo 
1785*576c57e6SKiseok Jo }
1786*576c57e6SKiseok Jo 
1787*576c57e6SKiseok Jo static void sma1307_reset(struct snd_soc_component *component)
1788*576c57e6SKiseok Jo {
1789*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1790*576c57e6SKiseok Jo 	unsigned int status = 0;
1791*576c57e6SKiseok Jo 
1792*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_FF_DEVICE_INDEX, &status);
1793*576c57e6SKiseok Jo 
1794*576c57e6SKiseok Jo 	sma1307->rev_num = status & SMA1307_REV_NUM_STATUS;
1795*576c57e6SKiseok Jo 	dev_dbg(component->dev, "%s: SMA1307 Revision %d\n",
1796*576c57e6SKiseok Jo 			 __func__, sma1307->rev_num);
1797*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_99_OTP_TRM2, &sma1307->otp_trm2);
1798*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap, SMA1307_9A_OTP_TRM3, &sma1307->otp_trm3);
1799*576c57e6SKiseok Jo 
1800*576c57e6SKiseok Jo 	if ((sma1307->otp_trm2 & SMA1307_OTP_STAT_MASK) != SMA1307_OTP_STAT_1)
1801*576c57e6SKiseok Jo 		dev_warn(component->dev, "%s: SMA1307 OTP Status Fail\n",
1802*576c57e6SKiseok Jo 			 __func__);
1803*576c57e6SKiseok Jo 
1804*576c57e6SKiseok Jo 	/* Register Initial Value Setting */
1805*576c57e6SKiseok Jo 	sma1307_setting_loaded(sma1307, setting_file);
1806*576c57e6SKiseok Jo 	if (sma1307->set.status)
1807*576c57e6SKiseok Jo 		sma1307_set_binary(component);
1808*576c57e6SKiseok Jo 	else
1809*576c57e6SKiseok Jo 		sma1307_set_default(component);
1810*576c57e6SKiseok Jo 
1811*576c57e6SKiseok Jo 	regmap_update_bits(sma1307->regmap,
1812*576c57e6SKiseok Jo 				   SMA1307_93_INT_CTRL,
1813*576c57e6SKiseok Jo 				   SMA1307_DIS_INT_MASK, SMA1307_HIGH_Z_INT);
1814*576c57e6SKiseok Jo 	regmap_write(sma1307->regmap, SMA1307_0A_SPK_VOL, sma1307->init_vol);
1815*576c57e6SKiseok Jo }
1816*576c57e6SKiseok Jo 
1817*576c57e6SKiseok Jo static void sma1307_set_binary(struct snd_soc_component *component)
1818*576c57e6SKiseok Jo {
1819*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1820*576c57e6SKiseok Jo 	int i = 0, mode = 0;
1821*576c57e6SKiseok Jo 
1822*576c57e6SKiseok Jo 	for (i = 0; i < (sma1307->set.def_size); i++) {
1823*576c57e6SKiseok Jo 		if (sma1307_writeable_register(sma1307->dev, i)
1824*576c57e6SKiseok Jo 		    && ((i < SMA1307_97_OTP_TRM0)
1825*576c57e6SKiseok Jo 			|| (i > SMA1307_9A_OTP_TRM3))) {
1826*576c57e6SKiseok Jo 			regmap_write(sma1307->regmap, i, sma1307->set.def[i]);
1827*576c57e6SKiseok Jo 
1828*576c57e6SKiseok Jo 		}
1829*576c57e6SKiseok Jo 	}
1830*576c57e6SKiseok Jo 	for (i = 0; i < (sma1307->set.mode_size); i++) {
1831*576c57e6SKiseok Jo 		if (sma1307_writeable_register(sma1307->dev, i)
1832*576c57e6SKiseok Jo 		    && ((i < SMA1307_97_OTP_TRM0)
1833*576c57e6SKiseok Jo 			|| (i > SMA1307_9A_OTP_TRM3))) {
1834*576c57e6SKiseok Jo 			mode = sma1307->binary_mode;
1835*576c57e6SKiseok Jo 			regmap_write(sma1307->regmap,
1836*576c57e6SKiseok Jo 					     sma1307->set.mode_set[mode][2 * i],
1837*576c57e6SKiseok Jo 					     sma1307->set.mode_set[mode][2 * i +
1838*576c57e6SKiseok Jo 									 1]);
1839*576c57e6SKiseok Jo 		}
1840*576c57e6SKiseok Jo 	}
1841*576c57e6SKiseok Jo }
1842*576c57e6SKiseok Jo 
1843*576c57e6SKiseok Jo static void sma1307_set_default(struct snd_soc_component *component)
1844*576c57e6SKiseok Jo {
1845*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component);
1846*576c57e6SKiseok Jo 	int i = 0;
1847*576c57e6SKiseok Jo 
1848*576c57e6SKiseok Jo 	for (i = 0; i < (unsigned int)ARRAY_SIZE(sma1307_reg_def); i++)
1849*576c57e6SKiseok Jo 		regmap_write(sma1307->regmap,
1850*576c57e6SKiseok Jo 				     sma1307_reg_def[i].reg,
1851*576c57e6SKiseok Jo 				     sma1307_reg_def[i].def);
1852*576c57e6SKiseok Jo 
1853*576c57e6SKiseok Jo 	if (!strcmp(sma1307->name, DEVICE_NAME_SMA1307AQ))
1854*576c57e6SKiseok Jo 		sma1307->data->init(sma1307->regmap);
1855*576c57e6SKiseok Jo }
1856*576c57e6SKiseok Jo 
1857*576c57e6SKiseok Jo static int sma1307_probe(struct snd_soc_component *component)
1858*576c57e6SKiseok Jo {
1859*576c57e6SKiseok Jo 	struct snd_soc_dapm_context *dapm =
1860*576c57e6SKiseok Jo 	    snd_soc_component_get_dapm(component);
1861*576c57e6SKiseok Jo 
1862*576c57e6SKiseok Jo 	snd_soc_dapm_sync(dapm);
1863*576c57e6SKiseok Jo 
1864*576c57e6SKiseok Jo 	sma1307_amp_component = component;
1865*576c57e6SKiseok Jo 
1866*576c57e6SKiseok Jo 	snd_soc_add_component_controls(component, sma1307_binary_mode_control,
1867*576c57e6SKiseok Jo 			ARRAY_SIZE(sma1307_binary_mode_control));
1868*576c57e6SKiseok Jo 	sma1307_reset(component);
1869*576c57e6SKiseok Jo 
1870*576c57e6SKiseok Jo 	return 0;
1871*576c57e6SKiseok Jo }
1872*576c57e6SKiseok Jo 
1873*576c57e6SKiseok Jo static const struct snd_soc_component_driver sma1307_component = {
1874*576c57e6SKiseok Jo 	.probe = sma1307_probe,
1875*576c57e6SKiseok Jo 	.controls = sma1307_snd_controls,
1876*576c57e6SKiseok Jo 	.num_controls = ARRAY_SIZE(sma1307_snd_controls),
1877*576c57e6SKiseok Jo 	.dapm_widgets = sma1307_dapm_widgets,
1878*576c57e6SKiseok Jo 	.num_dapm_widgets = ARRAY_SIZE(sma1307_dapm_widgets),
1879*576c57e6SKiseok Jo 	.dapm_routes = sma1307_audio_map,
1880*576c57e6SKiseok Jo 	.num_dapm_routes = ARRAY_SIZE(sma1307_audio_map),
1881*576c57e6SKiseok Jo };
1882*576c57e6SKiseok Jo 
1883*576c57e6SKiseok Jo static const struct regmap_config sma_i2c_regmap = {
1884*576c57e6SKiseok Jo 	.reg_bits = 8,
1885*576c57e6SKiseok Jo 	.val_bits = 8,
1886*576c57e6SKiseok Jo 
1887*576c57e6SKiseok Jo 	.max_register = SMA1307_FF_DEVICE_INDEX,
1888*576c57e6SKiseok Jo 	.readable_reg = sma1307_readable_register,
1889*576c57e6SKiseok Jo 	.writeable_reg = sma1307_writeable_register,
1890*576c57e6SKiseok Jo 	.volatile_reg = sma1307_volatile_register,
1891*576c57e6SKiseok Jo 
1892*576c57e6SKiseok Jo 	.reg_defaults = sma1307_reg_def,
1893*576c57e6SKiseok Jo 	.num_reg_defaults = ARRAY_SIZE(sma1307_reg_def),
1894*576c57e6SKiseok Jo };
1895*576c57e6SKiseok Jo 
1896*576c57e6SKiseok Jo static void sma1307aq_init(struct regmap *regmap)
1897*576c57e6SKiseok Jo {
1898*576c57e6SKiseok Jo 	/* Guidelines for driving 4ohm load */
1899*576c57e6SKiseok Jo 	/* Brown Out Protection */
1900*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_02_BROWN_OUT_PROT1, 0x62);
1901*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_03_BROWN_OUT_PROT2, 0x5D);
1902*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_04_BROWN_OUT_PROT3, 0x57);
1903*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_05_BROWN_OUT_PROT8, 0x54);
1904*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_06_BROWN_OUT_PROT9, 0x51);
1905*576c57e6SKiseok Jo 	regmap_write(regmap,
1906*576c57e6SKiseok Jo 			     SMA1307_07_BROWN_OUT_PROT10, 0x4D);
1907*576c57e6SKiseok Jo 	regmap_write(regmap,
1908*576c57e6SKiseok Jo 			     SMA1307_08_BROWN_OUT_PROT11, 0x4B);
1909*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_27_BROWN_OUT_PROT4, 0x3C);
1910*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_28_BROWN_OUT_PROT5, 0x5B);
1911*576c57e6SKiseok Jo 	regmap_write(regmap,
1912*576c57e6SKiseok Jo 			     SMA1307_29_BROWN_OUT_PROT12, 0x78);
1913*576c57e6SKiseok Jo 	regmap_write(regmap,
1914*576c57e6SKiseok Jo 			     SMA1307_2A_BROWN_OUT_PROT13, 0x96);
1915*576c57e6SKiseok Jo 	regmap_write(regmap,
1916*576c57e6SKiseok Jo 			     SMA1307_2B_BROWN_OUT_PROT14, 0xB4);
1917*576c57e6SKiseok Jo 	regmap_write(regmap,
1918*576c57e6SKiseok Jo 			     SMA1307_2C_BROWN_OUT_PROT15, 0xD3);
1919*576c57e6SKiseok Jo 	/* FDPEC Gain */
1920*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_35_FDPEC_CTRL0, 0x16);
1921*576c57e6SKiseok Jo 	/* FLT Vdd */
1922*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_92_FDPEC_CTRL1, 0xA0);
1923*576c57e6SKiseok Jo 	/* Boost Max */
1924*576c57e6SKiseok Jo 	regmap_write(regmap, SMA1307_AB_BOOST_CTRL4, 0x0F);
1925*576c57e6SKiseok Jo }
1926*576c57e6SKiseok Jo 
1927*576c57e6SKiseok Jo static const struct sma1307_data sma1307aq_data = {
1928*576c57e6SKiseok Jo 	.name = DEVICE_NAME_SMA1307AQ,
1929*576c57e6SKiseok Jo 	.init = sma1307aq_init,
1930*576c57e6SKiseok Jo };
1931*576c57e6SKiseok Jo 
1932*576c57e6SKiseok Jo static int sma1307_i2c_probe(struct i2c_client *client)
1933*576c57e6SKiseok Jo {
1934*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307;
1935*576c57e6SKiseok Jo 	const struct sma1307_data *data;
1936*576c57e6SKiseok Jo 	int ret = 0;
1937*576c57e6SKiseok Jo 	unsigned int device_info;
1938*576c57e6SKiseok Jo 
1939*576c57e6SKiseok Jo 	sma1307 = devm_kzalloc(&client->dev,
1940*576c57e6SKiseok Jo 			       sizeof(*sma1307), GFP_KERNEL);
1941*576c57e6SKiseok Jo 	if (!sma1307)
1942*576c57e6SKiseok Jo 		return -ENOMEM;
1943*576c57e6SKiseok Jo 
1944*576c57e6SKiseok Jo 	sma1307->regmap = devm_regmap_init_i2c(client, &sma_i2c_regmap);
1945*576c57e6SKiseok Jo 	if (IS_ERR(sma1307->regmap)) {
1946*576c57e6SKiseok Jo 		return dev_err_probe(&client->dev, PTR_ERR(sma1307->regmap),
1947*576c57e6SKiseok Jo 			"%s: failed to allocate register map\n", __func__);
1948*576c57e6SKiseok Jo 	}
1949*576c57e6SKiseok Jo 
1950*576c57e6SKiseok Jo 	data = device_get_match_data(&client->dev);
1951*576c57e6SKiseok Jo 	if (!data)
1952*576c57e6SKiseok Jo 		return -ENODEV;
1953*576c57e6SKiseok Jo 
1954*576c57e6SKiseok Jo 	sma1307->data = data;
1955*576c57e6SKiseok Jo 
1956*576c57e6SKiseok Jo 	/* set initial value as normal AMP IC status */
1957*576c57e6SKiseok Jo 	sma1307->name = client->name;
1958*576c57e6SKiseok Jo 	sma1307->format = SND_SOC_DAIFMT_I2S;
1959*576c57e6SKiseok Jo 	sma1307->sys_clk_id = SMA1307_PLL_CLKIN_BCLK;
1960*576c57e6SKiseok Jo 	sma1307->num_of_pll_matches = ARRAY_SIZE(sma1307_pll_matches);
1961*576c57e6SKiseok Jo 
1962*576c57e6SKiseok Jo 	sma1307->check_fault_period = CHECK_PERIOD_TIME;
1963*576c57e6SKiseok Jo 	sma1307->check_fault_status = true;
1964*576c57e6SKiseok Jo 	sma1307->init_vol = 0x32;
1965*576c57e6SKiseok Jo 	sma1307->cur_vol = sma1307->init_vol;
1966*576c57e6SKiseok Jo 	sma1307->sw_ot1_prot = true;
1967*576c57e6SKiseok Jo 
1968*576c57e6SKiseok Jo 	mutex_init(&sma1307->default_lock);
1969*576c57e6SKiseok Jo 
1970*576c57e6SKiseok Jo 	INIT_DELAYED_WORK(&sma1307->check_fault_work,
1971*576c57e6SKiseok Jo 			  sma1307_check_fault_worker);
1972*576c57e6SKiseok Jo 
1973*576c57e6SKiseok Jo 	sma1307->dev = &client->dev;
1974*576c57e6SKiseok Jo 	sma1307->kobj = &client->dev.kobj;
1975*576c57e6SKiseok Jo 
1976*576c57e6SKiseok Jo 	i2c_set_clientdata(client, sma1307);
1977*576c57e6SKiseok Jo 
1978*576c57e6SKiseok Jo 	sma1307->pll_matches = sma1307_pll_matches;
1979*576c57e6SKiseok Jo 
1980*576c57e6SKiseok Jo 	regmap_read(sma1307->regmap,
1981*576c57e6SKiseok Jo 				  SMA1307_FF_DEVICE_INDEX, &device_info);
1982*576c57e6SKiseok Jo 
1983*576c57e6SKiseok Jo 	if ((device_info & 0xF8) != SMA1307_DEVICE_ID) {
1984*576c57e6SKiseok Jo 		dev_err(&client->dev,
1985*576c57e6SKiseok Jo 			"%s: device initialization error (0x%02X)",
1986*576c57e6SKiseok Jo 				__func__, device_info);
1987*576c57e6SKiseok Jo 		return -ENODEV;
1988*576c57e6SKiseok Jo 	}
1989*576c57e6SKiseok Jo 	dev_dbg(&client->dev, "%s: chip version 0x%02X\n",
1990*576c57e6SKiseok Jo 		 __func__, device_info);
1991*576c57e6SKiseok Jo 
1992*576c57e6SKiseok Jo 	i2c_set_clientdata(client, sma1307);
1993*576c57e6SKiseok Jo 
1994*576c57e6SKiseok Jo 	ret = devm_snd_soc_register_component(&client->dev,
1995*576c57e6SKiseok Jo 					      &sma1307_component, sma1307_dai,
1996*576c57e6SKiseok Jo 					      1);
1997*576c57e6SKiseok Jo 
1998*576c57e6SKiseok Jo 	if (ret) {
1999*576c57e6SKiseok Jo 		dev_err(&client->dev, "%s: failed to register component\n",
2000*576c57e6SKiseok Jo 			__func__);
2001*576c57e6SKiseok Jo 
2002*576c57e6SKiseok Jo 		return ret;
2003*576c57e6SKiseok Jo 	}
2004*576c57e6SKiseok Jo 
2005*576c57e6SKiseok Jo 	return ret;
2006*576c57e6SKiseok Jo }
2007*576c57e6SKiseok Jo 
2008*576c57e6SKiseok Jo static void sma1307_i2c_remove(struct i2c_client *client)
2009*576c57e6SKiseok Jo {
2010*576c57e6SKiseok Jo 	struct sma1307_priv *sma1307 =
2011*576c57e6SKiseok Jo 	    (struct sma1307_priv *)i2c_get_clientdata(client);
2012*576c57e6SKiseok Jo 
2013*576c57e6SKiseok Jo 	cancel_delayed_work_sync(&sma1307->check_fault_work);
2014*576c57e6SKiseok Jo }
2015*576c57e6SKiseok Jo 
2016*576c57e6SKiseok Jo static const struct i2c_device_id sma1307_i2c_id[] = {
2017*576c57e6SKiseok Jo 	{ "sma1307a", 0 },
2018*576c57e6SKiseok Jo 	{ "sma1307aq", 0 },
2019*576c57e6SKiseok Jo 	{ }
2020*576c57e6SKiseok Jo };
2021*576c57e6SKiseok Jo 
2022*576c57e6SKiseok Jo MODULE_DEVICE_TABLE(i2c, sma1307_i2c_id);
2023*576c57e6SKiseok Jo 
2024*576c57e6SKiseok Jo static const struct of_device_id sma1307_of_match[] = {
2025*576c57e6SKiseok Jo 	{
2026*576c57e6SKiseok Jo 		.compatible = "irondevice,sma1307a",
2027*576c57e6SKiseok Jo 	},
2028*576c57e6SKiseok Jo 	{
2029*576c57e6SKiseok Jo 		.compatible = "irondevice,sma1307aq",
2030*576c57e6SKiseok Jo 		.data = &sma1307aq_data //AEC-Q100 Qualificated
2031*576c57e6SKiseok Jo 	},
2032*576c57e6SKiseok Jo 	{ }
2033*576c57e6SKiseok Jo };
2034*576c57e6SKiseok Jo 
2035*576c57e6SKiseok Jo MODULE_DEVICE_TABLE(of, sma1307_of_match);
2036*576c57e6SKiseok Jo 
2037*576c57e6SKiseok Jo static struct i2c_driver sma1307_i2c_driver = {
2038*576c57e6SKiseok Jo 	.driver = {
2039*576c57e6SKiseok Jo 		   .name = "sma1307",
2040*576c57e6SKiseok Jo 		   .of_match_table = sma1307_of_match,
2041*576c57e6SKiseok Jo 		    },
2042*576c57e6SKiseok Jo 	.probe = sma1307_i2c_probe,
2043*576c57e6SKiseok Jo 	.remove = sma1307_i2c_remove,
2044*576c57e6SKiseok Jo 	.id_table = sma1307_i2c_id,
2045*576c57e6SKiseok Jo };
2046*576c57e6SKiseok Jo 
2047*576c57e6SKiseok Jo module_i2c_driver(sma1307_i2c_driver);
2048*576c57e6SKiseok Jo 
2049*576c57e6SKiseok Jo MODULE_DESCRIPTION("ALSA SoC SMA1307 driver");
2050*576c57e6SKiseok Jo MODULE_AUTHOR("Gyuhwa Park, <gyuhwa.park@irondevice.com>");
2051*576c57e6SKiseok Jo MODULE_AUTHOR("KS Jo, <kiseok.jo@irondevice.com>");
2052*576c57e6SKiseok Jo MODULE_LICENSE("GPL");
2053