xref: /linux/sound/soc/codecs/sma1303.c (revision 33e02dc69afbd8f1b85a51d74d72f139ba4ca623)
168cd394eSKiseokJo // SPDX-License-Identifier: GPL-2.0-or-later
268cd394eSKiseokJo //
368cd394eSKiseokJo // sma1303.c -- sma1303 ALSA SoC Audio driver
468cd394eSKiseokJo //
568cd394eSKiseokJo // Copyright 2023 Iron Device Corporation
668cd394eSKiseokJo //
768cd394eSKiseokJo // Auther: Gyuhwa Park <gyuhwa.park@irondevice.com>
868cd394eSKiseokJo //         Kiseok Jo <kiseok.jo@irondevice.com>
968cd394eSKiseokJo 
10340d79a1SRob Herring #include <linux/mod_devicetable.h>
1168cd394eSKiseokJo #include <linux/module.h>
1268cd394eSKiseokJo #include <linux/moduleparam.h>
1368cd394eSKiseokJo #include <linux/kernel.h>
1468cd394eSKiseokJo #include <linux/init.h>
1568cd394eSKiseokJo #include <linux/delay.h>
1668cd394eSKiseokJo #include <linux/pm.h>
1768cd394eSKiseokJo #include <linux/i2c.h>
1868cd394eSKiseokJo #include <linux/regmap.h>
1968cd394eSKiseokJo #include <sound/core.h>
2068cd394eSKiseokJo #include <sound/pcm.h>
2168cd394eSKiseokJo #include <sound/pcm_params.h>
2268cd394eSKiseokJo #include <sound/soc.h>
2368cd394eSKiseokJo #include <sound/initval.h>
2468cd394eSKiseokJo #include <sound/tlv.h>
2568cd394eSKiseokJo #include <linux/slab.h>
2668cd394eSKiseokJo #include <asm/div64.h>
2768cd394eSKiseokJo 
2868cd394eSKiseokJo #include "sma1303.h"
2968cd394eSKiseokJo 
3068cd394eSKiseokJo #define CHECK_PERIOD_TIME 1 /* sec per HZ */
3168cd394eSKiseokJo #define MAX_CONTROL_NAME 48
3268cd394eSKiseokJo 
3368cd394eSKiseokJo #define PLL_MATCH(_input_clk_name, _output_clk_name, _input_clk,\
3468cd394eSKiseokJo 		_post_n, _n, _vco,  _p_cp)\
3568cd394eSKiseokJo {\
3668cd394eSKiseokJo 	.input_clk_name		= _input_clk_name,\
3768cd394eSKiseokJo 	.output_clk_name	= _output_clk_name,\
3868cd394eSKiseokJo 	.input_clk		= _input_clk,\
3968cd394eSKiseokJo 	.post_n			= _post_n,\
4068cd394eSKiseokJo 	.n			= _n,\
4168cd394eSKiseokJo 	.vco			= _vco,\
4268cd394eSKiseokJo 	.p_cp		= _p_cp,\
4368cd394eSKiseokJo }
4468cd394eSKiseokJo 
4568cd394eSKiseokJo enum sma1303_type {
4668cd394eSKiseokJo 	SMA1303,
4768cd394eSKiseokJo };
4868cd394eSKiseokJo 
4968cd394eSKiseokJo struct sma1303_pll_match {
5068cd394eSKiseokJo 	char *input_clk_name;
5168cd394eSKiseokJo 	char *output_clk_name;
5268cd394eSKiseokJo 	unsigned int input_clk;
5368cd394eSKiseokJo 	unsigned int post_n;
5468cd394eSKiseokJo 	unsigned int n;
5568cd394eSKiseokJo 	unsigned int vco;
5668cd394eSKiseokJo 	unsigned int p_cp;
5768cd394eSKiseokJo };
5868cd394eSKiseokJo 
5968cd394eSKiseokJo struct sma1303_priv {
6068cd394eSKiseokJo 	enum sma1303_type devtype;
6168cd394eSKiseokJo 	struct attribute_group *attr_grp;
6268cd394eSKiseokJo 	struct delayed_work check_fault_work;
6368cd394eSKiseokJo 	struct device *dev;
6468cd394eSKiseokJo 	struct kobject *kobj;
6568cd394eSKiseokJo 	struct regmap *regmap;
6668cd394eSKiseokJo 	struct sma1303_pll_match *pll_matches;
6768cd394eSKiseokJo 	bool amp_power_status;
6868cd394eSKiseokJo 	bool force_mute_status;
6968cd394eSKiseokJo 	int num_of_pll_matches;
7068cd394eSKiseokJo 	int retry_cnt;
7168cd394eSKiseokJo 	unsigned int amp_mode;
7268cd394eSKiseokJo 	unsigned int cur_vol;
7368cd394eSKiseokJo 	unsigned int format;
7468cd394eSKiseokJo 	unsigned int frame_size;
7568cd394eSKiseokJo 	unsigned int init_vol;
7668cd394eSKiseokJo 	unsigned int last_bclk;
7768cd394eSKiseokJo 	unsigned int last_ocp_val;
7868cd394eSKiseokJo 	unsigned int last_over_temp;
7968cd394eSKiseokJo 	unsigned int rev_num;
8068cd394eSKiseokJo 	unsigned int sys_clk_id;
8168cd394eSKiseokJo 	unsigned int tdm_slot_rx;
8268cd394eSKiseokJo 	unsigned int tdm_slot_tx;
8368cd394eSKiseokJo 	unsigned int tsdw_cnt;
8468cd394eSKiseokJo 	long check_fault_period;
8568cd394eSKiseokJo 	long check_fault_status;
8668cd394eSKiseokJo };
8768cd394eSKiseokJo 
8868cd394eSKiseokJo static struct sma1303_pll_match sma1303_pll_matches[] = {
8968cd394eSKiseokJo PLL_MATCH("1.411MHz",  "24.595MHz", 1411200,  0x07, 0xF4, 0x8B, 0x03),
9068cd394eSKiseokJo PLL_MATCH("1.536MHz",  "24.576MHz", 1536000,  0x07, 0xE0, 0x8B, 0x03),
9168cd394eSKiseokJo PLL_MATCH("3.072MHz",  "24.576MHz", 3072000,  0x07, 0x70, 0x8B, 0x03),
9268cd394eSKiseokJo PLL_MATCH("6.144MHz",  "24.576MHz", 6144000,  0x07, 0x70, 0x8B, 0x07),
9368cd394eSKiseokJo PLL_MATCH("12.288MHz", "24.576MHz", 12288000, 0x07, 0x70, 0x8B, 0x0B),
9468cd394eSKiseokJo PLL_MATCH("19.2MHz",   "24.343MHz", 19200000, 0x07, 0x47, 0x8B, 0x0A),
9568cd394eSKiseokJo PLL_MATCH("24.576MHz", "24.576MHz", 24576000, 0x07, 0x70, 0x8B, 0x0F),
9668cd394eSKiseokJo };
9768cd394eSKiseokJo 
9868cd394eSKiseokJo static int sma1303_startup(struct snd_soc_component *);
9968cd394eSKiseokJo static int sma1303_shutdown(struct snd_soc_component *);
10068cd394eSKiseokJo 
10168cd394eSKiseokJo static const struct reg_default sma1303_reg_def[] = {
10268cd394eSKiseokJo 	{ 0x00, 0x80 },
10368cd394eSKiseokJo 	{ 0x01, 0x00 },
10468cd394eSKiseokJo 	{ 0x02, 0x00 },
10568cd394eSKiseokJo 	{ 0x03, 0x11 },
10668cd394eSKiseokJo 	{ 0x04, 0x17 },
10768cd394eSKiseokJo 	{ 0x09, 0x00 },
10868cd394eSKiseokJo 	{ 0x0A, 0x31 },
10968cd394eSKiseokJo 	{ 0x0B, 0x98 },
11068cd394eSKiseokJo 	{ 0x0C, 0x84 },
11168cd394eSKiseokJo 	{ 0x0D, 0x07 },
11268cd394eSKiseokJo 	{ 0x0E, 0x3F },
11368cd394eSKiseokJo 	{ 0x10, 0x00 },
11468cd394eSKiseokJo 	{ 0x11, 0x00 },
11568cd394eSKiseokJo 	{ 0x12, 0x00 },
11668cd394eSKiseokJo 	{ 0x14, 0x5C },
11768cd394eSKiseokJo 	{ 0x15, 0x01 },
11868cd394eSKiseokJo 	{ 0x16, 0x0F },
11968cd394eSKiseokJo 	{ 0x17, 0x0F },
12068cd394eSKiseokJo 	{ 0x18, 0x0F },
12168cd394eSKiseokJo 	{ 0x19, 0x00 },
12268cd394eSKiseokJo 	{ 0x1A, 0x00 },
12368cd394eSKiseokJo 	{ 0x1B, 0x00 },
12468cd394eSKiseokJo 	{ 0x23, 0x19 },
12568cd394eSKiseokJo 	{ 0x24, 0x00 },
12668cd394eSKiseokJo 	{ 0x25, 0x00 },
12768cd394eSKiseokJo 	{ 0x26, 0x04 },
12868cd394eSKiseokJo 	{ 0x33, 0x00 },
12968cd394eSKiseokJo 	{ 0x36, 0x92 },
13068cd394eSKiseokJo 	{ 0x37, 0x27 },
13168cd394eSKiseokJo 	{ 0x3B, 0x5A },
13268cd394eSKiseokJo 	{ 0x3C, 0x20 },
13368cd394eSKiseokJo 	{ 0x3D, 0x00 },
13468cd394eSKiseokJo 	{ 0x3E, 0x03 },
13568cd394eSKiseokJo 	{ 0x3F, 0x0C },
13668cd394eSKiseokJo 	{ 0x8B, 0x07 },
13768cd394eSKiseokJo 	{ 0x8C, 0x70 },
13868cd394eSKiseokJo 	{ 0x8D, 0x8B },
13968cd394eSKiseokJo 	{ 0x8E, 0x6F },
14068cd394eSKiseokJo 	{ 0x8F, 0x03 },
14168cd394eSKiseokJo 	{ 0x90, 0x26 },
14268cd394eSKiseokJo 	{ 0x91, 0x42 },
14368cd394eSKiseokJo 	{ 0x92, 0xE0 },
14468cd394eSKiseokJo 	{ 0x94, 0x35 },
14568cd394eSKiseokJo 	{ 0x95, 0x0C },
14668cd394eSKiseokJo 	{ 0x96, 0x42 },
14768cd394eSKiseokJo 	{ 0x97, 0x95 },
14868cd394eSKiseokJo 	{ 0xA0, 0x00 },
14968cd394eSKiseokJo 	{ 0xA1, 0x3B },
15068cd394eSKiseokJo 	{ 0xA2, 0xC8 },
15168cd394eSKiseokJo 	{ 0xA3, 0x28 },
15268cd394eSKiseokJo 	{ 0xA4, 0x40 },
15368cd394eSKiseokJo 	{ 0xA5, 0x01 },
15468cd394eSKiseokJo 	{ 0xA6, 0x41 },
15568cd394eSKiseokJo 	{ 0xA7, 0x00 },
15668cd394eSKiseokJo };
15768cd394eSKiseokJo 
sma1303_readable_register(struct device * dev,unsigned int reg)15868cd394eSKiseokJo static bool sma1303_readable_register(struct device *dev, unsigned int reg)
15968cd394eSKiseokJo {
16068cd394eSKiseokJo 	bool result;
16168cd394eSKiseokJo 
16268cd394eSKiseokJo 	if (reg > SMA1303_FF_DEVICE_INDEX)
16368cd394eSKiseokJo 		return false;
16468cd394eSKiseokJo 
16568cd394eSKiseokJo 	switch (reg) {
16668cd394eSKiseokJo 	case SMA1303_00_SYSTEM_CTRL ... SMA1303_04_INPUT1_CTRL4:
16768cd394eSKiseokJo 	case SMA1303_09_OUTPUT_CTRL ... SMA1303_0E_MUTE_VOL_CTRL:
16868cd394eSKiseokJo 	case SMA1303_10_SYSTEM_CTRL1 ... SMA1303_12_SYSTEM_CTRL3:
16968cd394eSKiseokJo 	case SMA1303_14_MODULATOR ... SMA1303_1B_BASS_SPK7:
17068cd394eSKiseokJo 	case SMA1303_23_COMP_LIM1 ... SMA1303_26_COMP_LIM4:
17168cd394eSKiseokJo 	case SMA1303_33_SDM_CTRL ... SMA1303_34_OTP_DATA1:
17268cd394eSKiseokJo 	case SMA1303_36_PROTECTION  ... SMA1303_38_OTP_TRM0:
17368cd394eSKiseokJo 	case SMA1303_3B_TEST1  ... SMA1303_3F_ATEST2:
17468cd394eSKiseokJo 	case SMA1303_8B_PLL_POST_N ... SMA1303_92_FDPEC_CTRL:
17568cd394eSKiseokJo 	case SMA1303_94_BOOST_CTRL1 ... SMA1303_97_BOOST_CTRL4:
17668cd394eSKiseokJo 	case SMA1303_A0_PAD_CTRL0 ... SMA1303_A7_CLK_MON:
17768cd394eSKiseokJo 	case SMA1303_FA_STATUS1 ... SMA1303_FB_STATUS2:
17868cd394eSKiseokJo 		result = true;
17968cd394eSKiseokJo 		break;
18068cd394eSKiseokJo 	case SMA1303_FF_DEVICE_INDEX:
18168cd394eSKiseokJo 		result = true;
18268cd394eSKiseokJo 		break;
18368cd394eSKiseokJo 	default:
18468cd394eSKiseokJo 		result = false;
18568cd394eSKiseokJo 		break;
18668cd394eSKiseokJo 	}
18768cd394eSKiseokJo 	return result;
18868cd394eSKiseokJo }
18968cd394eSKiseokJo 
sma1303_writeable_register(struct device * dev,unsigned int reg)19068cd394eSKiseokJo static bool sma1303_writeable_register(struct device *dev, unsigned int reg)
19168cd394eSKiseokJo {
19268cd394eSKiseokJo 	bool result;
19368cd394eSKiseokJo 
19468cd394eSKiseokJo 	if (reg > SMA1303_FF_DEVICE_INDEX)
19568cd394eSKiseokJo 		return false;
19668cd394eSKiseokJo 
19768cd394eSKiseokJo 	switch (reg) {
19868cd394eSKiseokJo 	case SMA1303_00_SYSTEM_CTRL ... SMA1303_04_INPUT1_CTRL4:
19968cd394eSKiseokJo 	case SMA1303_09_OUTPUT_CTRL ... SMA1303_0E_MUTE_VOL_CTRL:
20068cd394eSKiseokJo 	case SMA1303_10_SYSTEM_CTRL1 ... SMA1303_12_SYSTEM_CTRL3:
20168cd394eSKiseokJo 	case SMA1303_14_MODULATOR ... SMA1303_1B_BASS_SPK7:
20268cd394eSKiseokJo 	case SMA1303_23_COMP_LIM1 ... SMA1303_26_COMP_LIM4:
20368cd394eSKiseokJo 	case SMA1303_33_SDM_CTRL:
20468cd394eSKiseokJo 	case SMA1303_36_PROTECTION  ... SMA1303_37_SLOPE_CTRL:
20568cd394eSKiseokJo 	case SMA1303_3B_TEST1  ... SMA1303_3F_ATEST2:
20668cd394eSKiseokJo 	case SMA1303_8B_PLL_POST_N ... SMA1303_92_FDPEC_CTRL:
20768cd394eSKiseokJo 	case SMA1303_94_BOOST_CTRL1 ... SMA1303_97_BOOST_CTRL4:
20868cd394eSKiseokJo 	case SMA1303_A0_PAD_CTRL0 ... SMA1303_A7_CLK_MON:
20968cd394eSKiseokJo 		result = true;
21068cd394eSKiseokJo 		break;
21168cd394eSKiseokJo 	default:
21268cd394eSKiseokJo 		result = false;
21368cd394eSKiseokJo 		break;
21468cd394eSKiseokJo 	}
21568cd394eSKiseokJo 	return result;
21668cd394eSKiseokJo }
21768cd394eSKiseokJo 
sma1303_volatile_register(struct device * dev,unsigned int reg)21868cd394eSKiseokJo static bool sma1303_volatile_register(struct device *dev, unsigned int reg)
21968cd394eSKiseokJo {
22068cd394eSKiseokJo 	bool result;
22168cd394eSKiseokJo 
22268cd394eSKiseokJo 	switch (reg) {
22368cd394eSKiseokJo 	case SMA1303_FA_STATUS1 ... SMA1303_FB_STATUS2:
22468cd394eSKiseokJo 		result = true;
22568cd394eSKiseokJo 		break;
22668cd394eSKiseokJo 	case SMA1303_FF_DEVICE_INDEX:
22768cd394eSKiseokJo 		result = true;
22868cd394eSKiseokJo 		break;
22968cd394eSKiseokJo 	default:
23068cd394eSKiseokJo 		result = false;
23168cd394eSKiseokJo 		break;
23268cd394eSKiseokJo 	}
23368cd394eSKiseokJo 	return result;
23468cd394eSKiseokJo }
23568cd394eSKiseokJo 
23668cd394eSKiseokJo static const DECLARE_TLV_DB_SCALE(sma1303_spk_tlv, -6000, 50, 0);
23768cd394eSKiseokJo 
sma1303_regmap_write(struct sma1303_priv * sma1303,unsigned int reg,unsigned int val)23868cd394eSKiseokJo static int sma1303_regmap_write(struct sma1303_priv *sma1303,
23968cd394eSKiseokJo 				unsigned int reg, unsigned int val)
24068cd394eSKiseokJo {
24168cd394eSKiseokJo 	int ret = 0;
24268cd394eSKiseokJo 	int cnt = sma1303->retry_cnt;
24368cd394eSKiseokJo 
24468cd394eSKiseokJo 	while (cnt--) {
24568cd394eSKiseokJo 		ret = regmap_write(sma1303->regmap, reg, val);
24668cd394eSKiseokJo 		if (ret < 0) {
24768cd394eSKiseokJo 			dev_err(sma1303->dev,
24868cd394eSKiseokJo 					"Failed to write [0x%02X]\n", reg);
24968cd394eSKiseokJo 		} else
25068cd394eSKiseokJo 			break;
25168cd394eSKiseokJo 	}
25268cd394eSKiseokJo 	return ret;
25368cd394eSKiseokJo }
25468cd394eSKiseokJo 
sma1303_regmap_update_bits(struct sma1303_priv * sma1303,unsigned int reg,unsigned int mask,unsigned int val,bool * change)25568cd394eSKiseokJo static int sma1303_regmap_update_bits(struct sma1303_priv *sma1303,
25668cd394eSKiseokJo 	unsigned int reg, unsigned int mask, unsigned int val, bool *change)
25768cd394eSKiseokJo {
25868cd394eSKiseokJo 	int ret = 0;
25968cd394eSKiseokJo 	int cnt = sma1303->retry_cnt;
26068cd394eSKiseokJo 
26168cd394eSKiseokJo 	while (cnt--) {
26268cd394eSKiseokJo 		ret = regmap_update_bits_check(sma1303->regmap, reg,
26368cd394eSKiseokJo 				mask, val, change);
26468cd394eSKiseokJo 		if (ret < 0) {
26568cd394eSKiseokJo 			dev_err(sma1303->dev,
26668cd394eSKiseokJo 					"Failed to update [0x%02X]\n", reg);
26768cd394eSKiseokJo 		} else
26868cd394eSKiseokJo 			break;
26968cd394eSKiseokJo 	}
27068cd394eSKiseokJo 	return ret;
27168cd394eSKiseokJo }
27268cd394eSKiseokJo 
sma1303_regmap_read(struct sma1303_priv * sma1303,unsigned int reg,unsigned int * val)27368cd394eSKiseokJo static int sma1303_regmap_read(struct sma1303_priv *sma1303,
27468cd394eSKiseokJo 			unsigned int reg, unsigned int *val)
27568cd394eSKiseokJo {
27668cd394eSKiseokJo 	int ret = 0;
27768cd394eSKiseokJo 	int cnt = sma1303->retry_cnt;
27868cd394eSKiseokJo 
27968cd394eSKiseokJo 	while (cnt--) {
28068cd394eSKiseokJo 		ret = regmap_read(sma1303->regmap, reg, val);
28168cd394eSKiseokJo 		if (ret < 0) {
28268cd394eSKiseokJo 			dev_err(sma1303->dev,
28368cd394eSKiseokJo 					"Failed to read [0x%02X]\n", reg);
28468cd394eSKiseokJo 		} else
28568cd394eSKiseokJo 			break;
28668cd394eSKiseokJo 	}
28768cd394eSKiseokJo 	return ret;
28868cd394eSKiseokJo }
28968cd394eSKiseokJo 
29068cd394eSKiseokJo static const char * const sma1303_aif_in_source_text[] = {
29168cd394eSKiseokJo 	"Mono", "Left", "Right"};
29268cd394eSKiseokJo static const char * const sma1303_aif_out_source_text[] = {
29368cd394eSKiseokJo 	"Disable", "After_FmtC", "After_Mixer", "After_DSP", "After_Post",
29468cd394eSKiseokJo 		"Clk_PLL", "Clk_OSC"};
2951f5ffd57SKiseok Jo static const char * const sma1303_tdm_slot_text[] = {
2961f5ffd57SKiseok Jo 	"Slot0", "Slot1", "Slot2", "Slot3",
2971f5ffd57SKiseok Jo 	"Slot4", "Slot5", "Slot6", "Slot7"};
29868cd394eSKiseokJo 
29968cd394eSKiseokJo static const struct soc_enum sma1303_aif_in_source_enum =
30068cd394eSKiseokJo 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_aif_in_source_text),
30168cd394eSKiseokJo 			sma1303_aif_in_source_text);
30268cd394eSKiseokJo static const struct soc_enum sma1303_aif_out_source_enum =
30368cd394eSKiseokJo 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_aif_out_source_text),
30468cd394eSKiseokJo 			sma1303_aif_out_source_text);
3051f5ffd57SKiseok Jo static const struct soc_enum sma1303_tdm_slot_enum =
3061f5ffd57SKiseok Jo 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_tdm_slot_text),
3071f5ffd57SKiseok Jo 			sma1303_tdm_slot_text);
30868cd394eSKiseokJo 
sma1303_force_mute_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)30968cd394eSKiseokJo static int sma1303_force_mute_get(struct snd_kcontrol *kcontrol,
31068cd394eSKiseokJo 				struct snd_ctl_elem_value *ucontrol)
31168cd394eSKiseokJo {
31268cd394eSKiseokJo 	struct snd_soc_component *component =
31368cd394eSKiseokJo 		snd_soc_kcontrol_component(kcontrol);
31468cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
31568cd394eSKiseokJo 
31668cd394eSKiseokJo 	ucontrol->value.integer.value[0] = (int)sma1303->force_mute_status;
31768cd394eSKiseokJo 	dev_dbg(sma1303->dev, "%s : Force Mute %s\n", __func__,
31868cd394eSKiseokJo 			sma1303->force_mute_status ? "ON" : "OFF");
31968cd394eSKiseokJo 
32068cd394eSKiseokJo 	return 0;
32168cd394eSKiseokJo }
32268cd394eSKiseokJo 
sma1303_force_mute_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)32368cd394eSKiseokJo static int sma1303_force_mute_put(struct snd_kcontrol *kcontrol,
32468cd394eSKiseokJo 				struct snd_ctl_elem_value *ucontrol)
32568cd394eSKiseokJo {
32668cd394eSKiseokJo 	struct snd_soc_component *component =
32768cd394eSKiseokJo 		snd_soc_kcontrol_component(kcontrol);
32868cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
32968cd394eSKiseokJo 	bool change = false, val = (bool)ucontrol->value.integer.value[0];
33068cd394eSKiseokJo 
33168cd394eSKiseokJo 	if (sma1303->force_mute_status == val)
33268cd394eSKiseokJo 		change = false;
33368cd394eSKiseokJo 	else {
33468cd394eSKiseokJo 		change = true;
33568cd394eSKiseokJo 		sma1303->force_mute_status = val;
33668cd394eSKiseokJo 	}
33768cd394eSKiseokJo 	dev_dbg(sma1303->dev, "%s : Force Mute %s\n", __func__,
33868cd394eSKiseokJo 			sma1303->force_mute_status ? "ON" : "OFF");
33968cd394eSKiseokJo 
34068cd394eSKiseokJo 	return change;
34168cd394eSKiseokJo }
34268cd394eSKiseokJo 
sma1303_postscaler_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)34368cd394eSKiseokJo static int sma1303_postscaler_get(struct snd_kcontrol *kcontrol,
34468cd394eSKiseokJo 				struct snd_ctl_elem_value *ucontrol)
34568cd394eSKiseokJo {
34668cd394eSKiseokJo 	struct snd_soc_component *component =
34768cd394eSKiseokJo 		snd_soc_kcontrol_component(kcontrol);
34868cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
34968cd394eSKiseokJo 	int val, ret;
35068cd394eSKiseokJo 
35168cd394eSKiseokJo 	ret = sma1303_regmap_read(sma1303, SMA1303_90_POSTSCALER, &val);
35268cd394eSKiseokJo 	if (ret < 0)
35368cd394eSKiseokJo 		return -EINVAL;
35468cd394eSKiseokJo 
35568cd394eSKiseokJo 	ucontrol->value.integer.value[0] = (val & 0x7E) >> 1;
35668cd394eSKiseokJo 
35768cd394eSKiseokJo 	return 0;
35868cd394eSKiseokJo }
35968cd394eSKiseokJo 
sma1303_postscaler_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)36068cd394eSKiseokJo static int sma1303_postscaler_put(struct snd_kcontrol *kcontrol,
36168cd394eSKiseokJo 				struct snd_ctl_elem_value *ucontrol)
36268cd394eSKiseokJo {
36368cd394eSKiseokJo 	struct snd_soc_component *component =
36468cd394eSKiseokJo 		snd_soc_kcontrol_component(kcontrol);
36568cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
36668cd394eSKiseokJo 	int ret, val = (int)ucontrol->value.integer.value[0];
36768cd394eSKiseokJo 	bool change;
36868cd394eSKiseokJo 
36968cd394eSKiseokJo 	ret = sma1303_regmap_update_bits(sma1303,
37068cd394eSKiseokJo 			SMA1303_90_POSTSCALER, 0x7E, (val << 1), &change);
37168cd394eSKiseokJo 	if (ret < 0)
37268cd394eSKiseokJo 		return -EINVAL;
37368cd394eSKiseokJo 
37468cd394eSKiseokJo 	return change;
37568cd394eSKiseokJo }
37668cd394eSKiseokJo 
sma1303_tdm_slot_rx_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)3771f5ffd57SKiseok Jo static int sma1303_tdm_slot_rx_get(struct snd_kcontrol *kcontrol,
3781f5ffd57SKiseok Jo 				struct snd_ctl_elem_value *ucontrol)
3791f5ffd57SKiseok Jo {
3801f5ffd57SKiseok Jo 	struct snd_soc_component *component =
3811f5ffd57SKiseok Jo 		snd_soc_kcontrol_component(kcontrol);
3821f5ffd57SKiseok Jo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
3831f5ffd57SKiseok Jo 	int val, ret;
3841f5ffd57SKiseok Jo 
3851f5ffd57SKiseok Jo 	ret = sma1303_regmap_read(sma1303, SMA1303_A5_TDM1, &val);
3861f5ffd57SKiseok Jo 	if (ret < 0)
3871f5ffd57SKiseok Jo 		return -EINVAL;
3881f5ffd57SKiseok Jo 
3891f5ffd57SKiseok Jo 	ucontrol->value.integer.value[0] = (val & 0x38) >> 3;
3901f5ffd57SKiseok Jo 	sma1303->tdm_slot_rx = ucontrol->value.integer.value[0];
3911f5ffd57SKiseok Jo 
3921f5ffd57SKiseok Jo 	return 0;
3931f5ffd57SKiseok Jo }
3941f5ffd57SKiseok Jo 
sma1303_tdm_slot_rx_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)3951f5ffd57SKiseok Jo static int sma1303_tdm_slot_rx_put(struct snd_kcontrol *kcontrol,
3961f5ffd57SKiseok Jo 				struct snd_ctl_elem_value *ucontrol)
3971f5ffd57SKiseok Jo {
3981f5ffd57SKiseok Jo 	struct snd_soc_component *component =
3991f5ffd57SKiseok Jo 		snd_soc_kcontrol_component(kcontrol);
4001f5ffd57SKiseok Jo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
4011f5ffd57SKiseok Jo 	int ret, val = (int)ucontrol->value.integer.value[0];
4021f5ffd57SKiseok Jo 	bool change;
4031f5ffd57SKiseok Jo 
4041f5ffd57SKiseok Jo 	ret = sma1303_regmap_update_bits(sma1303,
4051f5ffd57SKiseok Jo 			SMA1303_A5_TDM1, 0x38, (val << 3), &change);
4061f5ffd57SKiseok Jo 	if (ret < 0)
4071f5ffd57SKiseok Jo 		return -EINVAL;
4081f5ffd57SKiseok Jo 
4091f5ffd57SKiseok Jo 	return change;
4101f5ffd57SKiseok Jo }
4111f5ffd57SKiseok Jo 
sma1303_tdm_slot_tx_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)4121f5ffd57SKiseok Jo static int sma1303_tdm_slot_tx_get(struct snd_kcontrol *kcontrol,
4131f5ffd57SKiseok Jo 				struct snd_ctl_elem_value *ucontrol)
4141f5ffd57SKiseok Jo {
4151f5ffd57SKiseok Jo 	struct snd_soc_component *component =
4161f5ffd57SKiseok Jo 		snd_soc_kcontrol_component(kcontrol);
4171f5ffd57SKiseok Jo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
4181f5ffd57SKiseok Jo 	int val, ret;
4191f5ffd57SKiseok Jo 
4201f5ffd57SKiseok Jo 	ret = sma1303_regmap_read(sma1303, SMA1303_A6_TDM2, &val);
4211f5ffd57SKiseok Jo 	if (ret < 0)
4221f5ffd57SKiseok Jo 		return -EINVAL;
4231f5ffd57SKiseok Jo 
4241f5ffd57SKiseok Jo 	ucontrol->value.integer.value[0] = (val & 0x38) >> 3;
4251f5ffd57SKiseok Jo 	sma1303->tdm_slot_tx = ucontrol->value.integer.value[0];
4261f5ffd57SKiseok Jo 
4271f5ffd57SKiseok Jo 	return 0;
4281f5ffd57SKiseok Jo }
4291f5ffd57SKiseok Jo 
sma1303_tdm_slot_tx_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)4301f5ffd57SKiseok Jo static int sma1303_tdm_slot_tx_put(struct snd_kcontrol *kcontrol,
4311f5ffd57SKiseok Jo 				struct snd_ctl_elem_value *ucontrol)
4321f5ffd57SKiseok Jo {
4331f5ffd57SKiseok Jo 	struct snd_soc_component *component =
4341f5ffd57SKiseok Jo 		snd_soc_kcontrol_component(kcontrol);
4351f5ffd57SKiseok Jo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
4361f5ffd57SKiseok Jo 	int ret, val = (int)ucontrol->value.integer.value[0];
4371f5ffd57SKiseok Jo 	bool change;
4381f5ffd57SKiseok Jo 
4391f5ffd57SKiseok Jo 	ret = sma1303_regmap_update_bits(sma1303,
4401f5ffd57SKiseok Jo 			SMA1303_A6_TDM2, 0x38, (val << 3), &change);
4411f5ffd57SKiseok Jo 	if (ret < 0)
4421f5ffd57SKiseok Jo 		return -EINVAL;
4431f5ffd57SKiseok Jo 
4441f5ffd57SKiseok Jo 	return change;
4451f5ffd57SKiseok Jo }
4461f5ffd57SKiseok Jo 
sma1303_startup(struct snd_soc_component * component)44768cd394eSKiseokJo static int sma1303_startup(struct snd_soc_component *component)
44868cd394eSKiseokJo {
44968cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
45068cd394eSKiseokJo 	bool change = false, temp = false;
45168cd394eSKiseokJo 
45268cd394eSKiseokJo 	sma1303_regmap_update_bits(sma1303, SMA1303_8E_PLL_CTRL,
45368cd394eSKiseokJo 			SMA1303_PLL_PD2_MASK, SMA1303_PLL_OPERATION2, &temp);
45468cd394eSKiseokJo 	if (temp == true)
45568cd394eSKiseokJo 		change = true;
45668cd394eSKiseokJo 
45768cd394eSKiseokJo 	sma1303_regmap_update_bits(sma1303, SMA1303_00_SYSTEM_CTRL,
45868cd394eSKiseokJo 			SMA1303_POWER_MASK, SMA1303_POWER_ON, &temp);
45968cd394eSKiseokJo 	if (temp == true)
46068cd394eSKiseokJo 		change = true;
46168cd394eSKiseokJo 
46268cd394eSKiseokJo 	if (sma1303->amp_mode == SMA1303_MONO) {
46368cd394eSKiseokJo 		sma1303_regmap_update_bits(sma1303,
46468cd394eSKiseokJo 				SMA1303_10_SYSTEM_CTRL1,
46568cd394eSKiseokJo 				SMA1303_SPK_MODE_MASK,
46668cd394eSKiseokJo 				SMA1303_SPK_MONO,
46768cd394eSKiseokJo 				&temp);
46868cd394eSKiseokJo 		if (temp == true)
46968cd394eSKiseokJo 			change = true;
47068cd394eSKiseokJo 
47168cd394eSKiseokJo 	} else {
47268cd394eSKiseokJo 		sma1303_regmap_update_bits(sma1303,
47368cd394eSKiseokJo 				SMA1303_10_SYSTEM_CTRL1,
47468cd394eSKiseokJo 				SMA1303_SPK_MODE_MASK,
47568cd394eSKiseokJo 				SMA1303_SPK_STEREO,
47668cd394eSKiseokJo 				&temp);
47768cd394eSKiseokJo 		if (temp == true)
47868cd394eSKiseokJo 			change = true;
47968cd394eSKiseokJo 	}
48068cd394eSKiseokJo 
48168cd394eSKiseokJo 	if (sma1303->check_fault_status) {
48268cd394eSKiseokJo 		if (sma1303->check_fault_period > 0)
48368cd394eSKiseokJo 			queue_delayed_work(system_freezable_wq,
48468cd394eSKiseokJo 				&sma1303->check_fault_work,
48568cd394eSKiseokJo 					sma1303->check_fault_period * HZ);
48668cd394eSKiseokJo 		else
48768cd394eSKiseokJo 			queue_delayed_work(system_freezable_wq,
48868cd394eSKiseokJo 				&sma1303->check_fault_work,
48968cd394eSKiseokJo 					CHECK_PERIOD_TIME * HZ);
49068cd394eSKiseokJo 	}
49168cd394eSKiseokJo 
49268cd394eSKiseokJo 	sma1303->amp_power_status = true;
49368cd394eSKiseokJo 
49468cd394eSKiseokJo 	return change;
49568cd394eSKiseokJo }
49668cd394eSKiseokJo 
sma1303_shutdown(struct snd_soc_component * component)49768cd394eSKiseokJo static int sma1303_shutdown(struct snd_soc_component *component)
49868cd394eSKiseokJo {
49968cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
50068cd394eSKiseokJo 	bool change = false, temp = false;
50168cd394eSKiseokJo 
50268cd394eSKiseokJo 	cancel_delayed_work_sync(&sma1303->check_fault_work);
50368cd394eSKiseokJo 
50468cd394eSKiseokJo 	sma1303_regmap_update_bits(sma1303, SMA1303_10_SYSTEM_CTRL1,
50568cd394eSKiseokJo 			SMA1303_SPK_MODE_MASK, SMA1303_SPK_OFF, &temp);
50668cd394eSKiseokJo 	if (temp == true)
50768cd394eSKiseokJo 		change = true;
50868cd394eSKiseokJo 
50968cd394eSKiseokJo 	sma1303_regmap_update_bits(sma1303, SMA1303_00_SYSTEM_CTRL,
51068cd394eSKiseokJo 			SMA1303_POWER_MASK, SMA1303_POWER_OFF, &temp);
51168cd394eSKiseokJo 	if (temp == true)
51268cd394eSKiseokJo 		change = true;
51368cd394eSKiseokJo 	sma1303_regmap_update_bits(sma1303, SMA1303_8E_PLL_CTRL,
51468cd394eSKiseokJo 			SMA1303_PLL_PD2_MASK, SMA1303_PLL_PD2, &temp);
51568cd394eSKiseokJo 	if (temp == true)
51668cd394eSKiseokJo 		change = true;
51768cd394eSKiseokJo 
51868cd394eSKiseokJo 	sma1303->amp_power_status = false;
51968cd394eSKiseokJo 
52068cd394eSKiseokJo 	return change;
52168cd394eSKiseokJo }
52268cd394eSKiseokJo 
sma1303_aif_in_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)52368cd394eSKiseokJo static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w,
52468cd394eSKiseokJo 			struct snd_kcontrol *kcontrol, int event)
52568cd394eSKiseokJo {
52668cd394eSKiseokJo 	struct snd_soc_component *component =
52768cd394eSKiseokJo 			snd_soc_dapm_to_component(w->dapm);
52868cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
52968cd394eSKiseokJo 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
53068cd394eSKiseokJo 	int ret = 0;
53168cd394eSKiseokJo 	bool change = false, temp = false;
53268cd394eSKiseokJo 
53368cd394eSKiseokJo 	switch (event) {
53468cd394eSKiseokJo 	case SND_SOC_DAPM_PRE_PMU:
53568cd394eSKiseokJo 		switch (mux) {
53668cd394eSKiseokJo 		case 0:
53768cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
53868cd394eSKiseokJo 					SMA1303_11_SYSTEM_CTRL2,
53968cd394eSKiseokJo 					SMA1303_MONOMIX_MASK,
54068cd394eSKiseokJo 					SMA1303_MONOMIX_ON,
54168cd394eSKiseokJo 					&change);
54268cd394eSKiseokJo 			sma1303->amp_mode = SMA1303_MONO;
54368cd394eSKiseokJo 			break;
54468cd394eSKiseokJo 		case 1:
54568cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
54668cd394eSKiseokJo 					SMA1303_11_SYSTEM_CTRL2,
54768cd394eSKiseokJo 					SMA1303_MONOMIX_MASK,
54868cd394eSKiseokJo 					SMA1303_MONOMIX_OFF,
54968cd394eSKiseokJo 					&temp);
55068cd394eSKiseokJo 			if (temp == true)
55168cd394eSKiseokJo 				change = true;
55268cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
55368cd394eSKiseokJo 					SMA1303_11_SYSTEM_CTRL2,
55468cd394eSKiseokJo 					SMA1303_LR_DATA_SW_MASK,
55568cd394eSKiseokJo 					SMA1303_LR_DATA_SW_NORMAL,
55668cd394eSKiseokJo 					&temp);
55768cd394eSKiseokJo 			if (temp == true)
55868cd394eSKiseokJo 				change = true;
55968cd394eSKiseokJo 			sma1303->amp_mode = SMA1303_STEREO;
56068cd394eSKiseokJo 			break;
56168cd394eSKiseokJo 		case 2:
56268cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
56368cd394eSKiseokJo 					SMA1303_11_SYSTEM_CTRL2,
56468cd394eSKiseokJo 					SMA1303_MONOMIX_MASK,
56568cd394eSKiseokJo 					SMA1303_MONOMIX_OFF,
56668cd394eSKiseokJo 					&temp);
56768cd394eSKiseokJo 			if (temp == true)
56868cd394eSKiseokJo 				change = true;
56968cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
57068cd394eSKiseokJo 					SMA1303_11_SYSTEM_CTRL2,
57168cd394eSKiseokJo 					SMA1303_LR_DATA_SW_MASK,
57251c58a1eSKiseok Jo 					SMA1303_LR_DATA_SW_SWAP,
57368cd394eSKiseokJo 					&temp);
57468cd394eSKiseokJo 			if (temp == true)
57568cd394eSKiseokJo 				change = true;
57668cd394eSKiseokJo 			sma1303->amp_mode = SMA1303_STEREO;
57768cd394eSKiseokJo 			break;
57868cd394eSKiseokJo 		default:
5795b28c049SColin Ian King 			dev_err(sma1303->dev, "%s : Invalid value (%d)\n",
58068cd394eSKiseokJo 								__func__, mux);
58168cd394eSKiseokJo 			return -EINVAL;
58268cd394eSKiseokJo 		}
58368cd394eSKiseokJo 
58468cd394eSKiseokJo 		dev_dbg(sma1303->dev, "%s : Source : %s\n", __func__,
58568cd394eSKiseokJo 					sma1303_aif_in_source_text[mux]);
58668cd394eSKiseokJo 		break;
58768cd394eSKiseokJo 	}
58868cd394eSKiseokJo 	if (ret < 0)
58968cd394eSKiseokJo 		return -EINVAL;
59068cd394eSKiseokJo 	return change;
59168cd394eSKiseokJo }
59268cd394eSKiseokJo 
sma1303_aif_out_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)59368cd394eSKiseokJo static int sma1303_aif_out_event(struct snd_soc_dapm_widget *w,
59468cd394eSKiseokJo 			struct snd_kcontrol *kcontrol, int event)
59568cd394eSKiseokJo {
59668cd394eSKiseokJo 	struct snd_soc_component *component =
59768cd394eSKiseokJo 			snd_soc_dapm_to_component(w->dapm);
59868cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
59968cd394eSKiseokJo 	unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]);
60068cd394eSKiseokJo 	int ret = 0;
60168cd394eSKiseokJo 	bool change = false, temp = false;
60268cd394eSKiseokJo 
60368cd394eSKiseokJo 	switch (event) {
60468cd394eSKiseokJo 	case SND_SOC_DAPM_PRE_PMU:
60568cd394eSKiseokJo 		switch (mux) {
60668cd394eSKiseokJo 		case 0:
60768cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
60868cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
60968cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
61068cd394eSKiseokJo 					SMA1303_NORMAL_SDO,
61168cd394eSKiseokJo 					&temp);
61268cd394eSKiseokJo 			if (temp == true)
61368cd394eSKiseokJo 				change = true;
61468cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
61568cd394eSKiseokJo 					SMA1303_09_OUTPUT_CTRL,
61668cd394eSKiseokJo 					SMA1303_PORT_OUT_SEL_MASK,
61768cd394eSKiseokJo 					SMA1303_OUT_SEL_DISABLE,
61868cd394eSKiseokJo 					&temp);
61968cd394eSKiseokJo 			if (temp == true)
62068cd394eSKiseokJo 				change = true;
62168cd394eSKiseokJo 			break;
62268cd394eSKiseokJo 		case 1:
62368cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
62468cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
62568cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
62668cd394eSKiseokJo 					SMA1303_NORMAL_SDO,
62768cd394eSKiseokJo 					&temp);
62868cd394eSKiseokJo 			if (temp == true)
62968cd394eSKiseokJo 				change = true;
63068cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
63168cd394eSKiseokJo 					SMA1303_09_OUTPUT_CTRL,
63268cd394eSKiseokJo 					SMA1303_PORT_OUT_SEL_MASK,
63368cd394eSKiseokJo 					SMA1303_FORMAT_CONVERTER,
63468cd394eSKiseokJo 					&temp);
63568cd394eSKiseokJo 			if (temp == true)
63668cd394eSKiseokJo 				change = true;
63768cd394eSKiseokJo 			break;
63868cd394eSKiseokJo 		case 2:
63968cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
64068cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
64168cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
64268cd394eSKiseokJo 					SMA1303_NORMAL_SDO,
64368cd394eSKiseokJo 					&temp);
64468cd394eSKiseokJo 			if (temp == true)
64568cd394eSKiseokJo 				change = true;
64668cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
64768cd394eSKiseokJo 					SMA1303_09_OUTPUT_CTRL,
64868cd394eSKiseokJo 					SMA1303_PORT_OUT_SEL_MASK,
64968cd394eSKiseokJo 					SMA1303_MIXER_OUTPUT,
65068cd394eSKiseokJo 					&temp);
65168cd394eSKiseokJo 			if (temp == true)
65268cd394eSKiseokJo 				change = true;
65368cd394eSKiseokJo 			break;
65468cd394eSKiseokJo 		case 3:
65568cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
65668cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
65768cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
65868cd394eSKiseokJo 					SMA1303_NORMAL_SDO,
65968cd394eSKiseokJo 					&temp);
66068cd394eSKiseokJo 			if (temp == true)
66168cd394eSKiseokJo 				change = true;
66268cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
66368cd394eSKiseokJo 					SMA1303_09_OUTPUT_CTRL,
66468cd394eSKiseokJo 					SMA1303_PORT_OUT_SEL_MASK,
66568cd394eSKiseokJo 					SMA1303_SPEAKER_PATH,
66668cd394eSKiseokJo 					&temp);
66768cd394eSKiseokJo 			if (temp == true)
66868cd394eSKiseokJo 				change = true;
66968cd394eSKiseokJo 			break;
67068cd394eSKiseokJo 		case 4:
67168cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
67268cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
67368cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
67468cd394eSKiseokJo 					SMA1303_NORMAL_SDO,
67568cd394eSKiseokJo 					&temp);
67668cd394eSKiseokJo 			if (temp == true)
67768cd394eSKiseokJo 				change = true;
67868cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
67968cd394eSKiseokJo 					SMA1303_09_OUTPUT_CTRL,
68068cd394eSKiseokJo 					SMA1303_PORT_OUT_SEL_MASK,
68168cd394eSKiseokJo 					SMA1303_POSTSCALER_OUTPUT,
68268cd394eSKiseokJo 					&temp);
68368cd394eSKiseokJo 			if (temp == true)
68468cd394eSKiseokJo 				change = true;
68568cd394eSKiseokJo 			break;
68668cd394eSKiseokJo 		case 5:
68768cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
68868cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
68968cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
69068cd394eSKiseokJo 					SMA1303_CLK_OUT_SDO,
69168cd394eSKiseokJo 					&temp);
69268cd394eSKiseokJo 			if (temp == true)
69368cd394eSKiseokJo 				change = true;
69468cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
69568cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
69668cd394eSKiseokJo 					SMA1303_MON_OSC_PLL_MASK,
69768cd394eSKiseokJo 					SMA1303_PLL_SDO,
69868cd394eSKiseokJo 					&temp);
69968cd394eSKiseokJo 			if (temp == true)
70068cd394eSKiseokJo 				change = true;
70168cd394eSKiseokJo 			break;
70268cd394eSKiseokJo 		case 6:
70368cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
70468cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
70568cd394eSKiseokJo 					SMA1303_TEST_CLKO_EN_MASK,
70668cd394eSKiseokJo 					SMA1303_CLK_OUT_SDO,
70768cd394eSKiseokJo 					&temp);
70868cd394eSKiseokJo 			if (temp == true)
70968cd394eSKiseokJo 				change = true;
71068cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
71168cd394eSKiseokJo 					SMA1303_A3_TOP_MAN2,
71268cd394eSKiseokJo 					SMA1303_MON_OSC_PLL_MASK,
71368cd394eSKiseokJo 					SMA1303_OSC_SDO,
71468cd394eSKiseokJo 					&temp);
71568cd394eSKiseokJo 			if (temp == true)
71668cd394eSKiseokJo 				change = true;
71768cd394eSKiseokJo 			break;
71868cd394eSKiseokJo 		default:
7195b28c049SColin Ian King 			dev_err(sma1303->dev, "%s : Invalid value (%d)\n",
72068cd394eSKiseokJo 								__func__, mux);
72168cd394eSKiseokJo 			return -EINVAL;
72268cd394eSKiseokJo 		}
72368cd394eSKiseokJo 
72468cd394eSKiseokJo 		dev_dbg(sma1303->dev, "%s : Source : %s\n", __func__,
72568cd394eSKiseokJo 					sma1303_aif_out_source_text[mux]);
72668cd394eSKiseokJo 		break;
72768cd394eSKiseokJo 	}
72868cd394eSKiseokJo 	if (ret < 0)
72968cd394eSKiseokJo 		return -EINVAL;
73068cd394eSKiseokJo 	return change;
73168cd394eSKiseokJo }
73268cd394eSKiseokJo 
sma1303_sdo_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)73368cd394eSKiseokJo static int sma1303_sdo_event(struct snd_soc_dapm_widget *w,
73468cd394eSKiseokJo 		struct snd_kcontrol *kcontrol, int event)
73568cd394eSKiseokJo {
73668cd394eSKiseokJo 	struct snd_soc_component *component =
73768cd394eSKiseokJo 		snd_soc_dapm_to_component(w->dapm);
73868cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
73968cd394eSKiseokJo 	int ret = 0;
74068cd394eSKiseokJo 	bool change = false, temp = false;
74168cd394eSKiseokJo 
74268cd394eSKiseokJo 	switch (event) {
74368cd394eSKiseokJo 	case SND_SOC_DAPM_PRE_PMU:
74468cd394eSKiseokJo 		dev_dbg(sma1303->dev,
74568cd394eSKiseokJo 			"%s : SND_SOC_DAPM_PRE_PMU\n", __func__);
74668cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
74768cd394eSKiseokJo 				SMA1303_09_OUTPUT_CTRL,
74868cd394eSKiseokJo 				SMA1303_PORT_CONFIG_MASK,
74968cd394eSKiseokJo 				SMA1303_OUTPUT_PORT_ENABLE,
75068cd394eSKiseokJo 				&temp);
75168cd394eSKiseokJo 		if (temp == true)
75268cd394eSKiseokJo 			change = true;
75368cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
75468cd394eSKiseokJo 				SMA1303_A3_TOP_MAN2,
75568cd394eSKiseokJo 				SMA1303_SDO_OUTPUT_MASK,
75668cd394eSKiseokJo 				SMA1303_NORMAL_OUT,
75768cd394eSKiseokJo 				&temp);
75868cd394eSKiseokJo 		if (temp == true)
75968cd394eSKiseokJo 			change = true;
76068cd394eSKiseokJo 		break;
76168cd394eSKiseokJo 	case SND_SOC_DAPM_POST_PMD:
76268cd394eSKiseokJo 		dev_dbg(sma1303->dev,
76368cd394eSKiseokJo 			"%s : SND_SOC_DAPM_POST_PMD\n", __func__);
76468cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
76568cd394eSKiseokJo 				SMA1303_09_OUTPUT_CTRL,
76668cd394eSKiseokJo 				SMA1303_PORT_CONFIG_MASK,
76768cd394eSKiseokJo 				SMA1303_INPUT_PORT_ONLY,
76868cd394eSKiseokJo 				&temp);
76968cd394eSKiseokJo 		if (temp == true)
77068cd394eSKiseokJo 			change = true;
77168cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
77268cd394eSKiseokJo 				SMA1303_A3_TOP_MAN2,
77368cd394eSKiseokJo 				SMA1303_SDO_OUTPUT_MASK,
77468cd394eSKiseokJo 				SMA1303_HIGH_Z_OUT,
77568cd394eSKiseokJo 				&temp);
77668cd394eSKiseokJo 		if (temp == true)
77768cd394eSKiseokJo 			change = true;
77868cd394eSKiseokJo 		break;
77968cd394eSKiseokJo 	}
78068cd394eSKiseokJo 	if (ret < 0)
78168cd394eSKiseokJo 		return -EINVAL;
78268cd394eSKiseokJo 	return change;
78368cd394eSKiseokJo }
78468cd394eSKiseokJo 
sma1303_post_scaler_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)78568cd394eSKiseokJo static int sma1303_post_scaler_event(struct snd_soc_dapm_widget *w,
78668cd394eSKiseokJo 		struct snd_kcontrol *kcontrol, int event)
78768cd394eSKiseokJo {
78868cd394eSKiseokJo 	struct snd_soc_component *component =
78968cd394eSKiseokJo 		snd_soc_dapm_to_component(w->dapm);
79068cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
79168cd394eSKiseokJo 	int ret = 0;
79268cd394eSKiseokJo 	bool change = false;
79368cd394eSKiseokJo 
79468cd394eSKiseokJo 	switch (event) {
79568cd394eSKiseokJo 	case SND_SOC_DAPM_PRE_PMU:
79668cd394eSKiseokJo 		dev_dbg(sma1303->dev,
79768cd394eSKiseokJo 				"%s : SND_SOC_DAPM_PRE_PMU\n", __func__);
79868cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
79968cd394eSKiseokJo 				SMA1303_90_POSTSCALER,
80068cd394eSKiseokJo 				SMA1303_BYP_POST_MASK,
80168cd394eSKiseokJo 				SMA1303_EN_POST_SCALER,
80268cd394eSKiseokJo 				&change);
80368cd394eSKiseokJo 		break;
80468cd394eSKiseokJo 	case SND_SOC_DAPM_POST_PMD:
80568cd394eSKiseokJo 		dev_dbg(sma1303->dev,
80668cd394eSKiseokJo 				"%s : SND_SOC_DAPM_POST_PMD\n", __func__);
80768cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
80868cd394eSKiseokJo 				SMA1303_90_POSTSCALER,
80968cd394eSKiseokJo 				SMA1303_BYP_POST_MASK,
81068cd394eSKiseokJo 				SMA1303_BYP_POST_SCALER,
81168cd394eSKiseokJo 				&change);
81268cd394eSKiseokJo 		break;
81368cd394eSKiseokJo 	}
81468cd394eSKiseokJo 	if (ret < 0)
81568cd394eSKiseokJo 		return -EINVAL;
81668cd394eSKiseokJo 	return change;
81768cd394eSKiseokJo }
81868cd394eSKiseokJo 
sma1303_power_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)81968cd394eSKiseokJo static int sma1303_power_event(struct snd_soc_dapm_widget *w,
82068cd394eSKiseokJo 		struct snd_kcontrol *kcontrol, int event)
82168cd394eSKiseokJo {
82268cd394eSKiseokJo 	struct snd_soc_component *component =
82368cd394eSKiseokJo 		snd_soc_dapm_to_component(w->dapm);
82468cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
82568cd394eSKiseokJo 	int ret = 0;
82668cd394eSKiseokJo 
82768cd394eSKiseokJo 	switch (event) {
82868cd394eSKiseokJo 	case SND_SOC_DAPM_POST_PMU:
82968cd394eSKiseokJo 		dev_dbg(sma1303->dev,
83068cd394eSKiseokJo 			"%s : SND_SOC_DAPM_POST_PMU\n", __func__);
83168cd394eSKiseokJo 		ret = sma1303_startup(component);
83268cd394eSKiseokJo 		break;
83368cd394eSKiseokJo 	case SND_SOC_DAPM_PRE_PMD:
83468cd394eSKiseokJo 		dev_dbg(sma1303->dev,
83568cd394eSKiseokJo 			"%s : SND_SOC_DAPM_PRE_PMD\n", __func__);
83668cd394eSKiseokJo 		ret = sma1303_shutdown(component);
83768cd394eSKiseokJo 		break;
83868cd394eSKiseokJo 	}
83968cd394eSKiseokJo 	return ret;
84068cd394eSKiseokJo }
84168cd394eSKiseokJo 
84268cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_aif_in_source_control =
84368cd394eSKiseokJo 	SOC_DAPM_ENUM("AIF IN Source", sma1303_aif_in_source_enum);
84468cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_aif_out_source_control =
84568cd394eSKiseokJo 	SOC_DAPM_ENUM("AIF OUT Source", sma1303_aif_out_source_enum);
84668cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_sdo_control =
84768cd394eSKiseokJo 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
84868cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_post_scaler_control =
84968cd394eSKiseokJo 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
85068cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_enable_control =
85168cd394eSKiseokJo 	SOC_DAPM_SINGLE_VIRT("Switch", 1);
85268cd394eSKiseokJo 
85368cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_snd_controls[] = {
85468cd394eSKiseokJo 	SOC_SINGLE_TLV("Speaker Volume", SMA1303_0A_SPK_VOL,
85568cd394eSKiseokJo 		0, 167, 1, sma1303_spk_tlv),
85668cd394eSKiseokJo 	SOC_SINGLE_BOOL_EXT("Force Mute Switch", 0,
85768cd394eSKiseokJo 		sma1303_force_mute_get, sma1303_force_mute_put),
85868cd394eSKiseokJo 	SOC_SINGLE_EXT("Postscaler Gain", SMA1303_90_POSTSCALER, 1, 0x30, 0,
85968cd394eSKiseokJo 		sma1303_postscaler_get, sma1303_postscaler_put),
8601f5ffd57SKiseok Jo 	SOC_ENUM_EXT("TDM RX Slot Position", sma1303_tdm_slot_enum,
8611f5ffd57SKiseok Jo 			sma1303_tdm_slot_rx_get, sma1303_tdm_slot_rx_put),
8621f5ffd57SKiseok Jo 	SOC_ENUM_EXT("TDM TX Slot Position", sma1303_tdm_slot_enum,
8631f5ffd57SKiseok Jo 			sma1303_tdm_slot_tx_get, sma1303_tdm_slot_tx_put),
86468cd394eSKiseokJo };
86568cd394eSKiseokJo 
86668cd394eSKiseokJo static const struct snd_soc_dapm_widget sma1303_dapm_widgets[] = {
86768cd394eSKiseokJo 	/* platform domain */
86868cd394eSKiseokJo 	SND_SOC_DAPM_OUTPUT("SPK"),
86968cd394eSKiseokJo 	SND_SOC_DAPM_INPUT("SDO"),
87068cd394eSKiseokJo 
87168cd394eSKiseokJo 	/* path domain */
87268cd394eSKiseokJo 	SND_SOC_DAPM_MUX_E("AIF IN Source", SND_SOC_NOPM, 0, 0,
87368cd394eSKiseokJo 			&sma1303_aif_in_source_control,
87468cd394eSKiseokJo 			sma1303_aif_in_event,
87568cd394eSKiseokJo 			SND_SOC_DAPM_PRE_PMU),
87668cd394eSKiseokJo 	SND_SOC_DAPM_MUX_E("AIF OUT Source", SND_SOC_NOPM, 0, 0,
87768cd394eSKiseokJo 			&sma1303_aif_out_source_control,
87868cd394eSKiseokJo 			sma1303_aif_out_event,
87968cd394eSKiseokJo 			SND_SOC_DAPM_PRE_PMU),
88068cd394eSKiseokJo 	SND_SOC_DAPM_SWITCH_E("SDO Enable", SND_SOC_NOPM, 0, 0,
88168cd394eSKiseokJo 			&sma1303_sdo_control,
88268cd394eSKiseokJo 			sma1303_sdo_event,
88368cd394eSKiseokJo 			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
88468cd394eSKiseokJo 	SND_SOC_DAPM_MIXER("Entry", SND_SOC_NOPM, 0, 0, NULL, 0),
88568cd394eSKiseokJo 	SND_SOC_DAPM_SWITCH_E("Post Scaler", SND_SOC_NOPM, 0, 1,
88668cd394eSKiseokJo 			&sma1303_post_scaler_control,
88768cd394eSKiseokJo 			sma1303_post_scaler_event,
88868cd394eSKiseokJo 			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
88968cd394eSKiseokJo 	SND_SOC_DAPM_OUT_DRV_E("AMP Power", SND_SOC_NOPM, 0, 0, NULL, 0,
89068cd394eSKiseokJo 			sma1303_power_event,
89168cd394eSKiseokJo 			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
89268cd394eSKiseokJo 	SND_SOC_DAPM_SWITCH("AMP Enable", SND_SOC_NOPM, 0, 1,
89368cd394eSKiseokJo 			&sma1303_enable_control),
89468cd394eSKiseokJo 
89568cd394eSKiseokJo 	/* stream domain */
89668cd394eSKiseokJo 	SND_SOC_DAPM_AIF_IN("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0),
89768cd394eSKiseokJo 	SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
89868cd394eSKiseokJo };
89968cd394eSKiseokJo 
90068cd394eSKiseokJo static const struct snd_soc_dapm_route sma1303_audio_map[] = {
90168cd394eSKiseokJo 	/* Playback */
90268cd394eSKiseokJo 	{"AIF IN Source", "Mono", "AIF IN"},
90368cd394eSKiseokJo 	{"AIF IN Source", "Left", "AIF IN"},
90468cd394eSKiseokJo 	{"AIF IN Source", "Right", "AIF IN"},
90568cd394eSKiseokJo 
90668cd394eSKiseokJo 	{"SDO Enable", "Switch", "AIF IN"},
90768cd394eSKiseokJo 	{"AIF OUT Source", "Disable", "SDO Enable"},
90868cd394eSKiseokJo 	{"AIF OUT Source", "After_FmtC", "SDO Enable"},
90968cd394eSKiseokJo 	{"AIF OUT Source", "After_Mixer", "SDO Enable"},
91068cd394eSKiseokJo 	{"AIF OUT Source", "After_DSP", "SDO Enable"},
91168cd394eSKiseokJo 	{"AIF OUT Source", "After_Post", "SDO Enable"},
91268cd394eSKiseokJo 	{"AIF OUT Source", "Clk_PLL", "SDO Enable"},
91368cd394eSKiseokJo 	{"AIF OUT Source", "Clk_OSC", "SDO Enable"},
91468cd394eSKiseokJo 
91568cd394eSKiseokJo 	{"Entry", NULL, "AIF OUT Source"},
91668cd394eSKiseokJo 	{"Entry", NULL, "AIF IN Source"},
91768cd394eSKiseokJo 
91868cd394eSKiseokJo 	{"Post Scaler", "Switch", "Entry"},
91968cd394eSKiseokJo 	{"AMP Power", NULL, "Entry"},
92068cd394eSKiseokJo 	{"AMP Power", NULL, "Entry"},
92168cd394eSKiseokJo 
92268cd394eSKiseokJo 	{"AMP Enable", "Switch", "AMP Power"},
92368cd394eSKiseokJo 	{"SPK", NULL, "AMP Enable"},
92468cd394eSKiseokJo 
92568cd394eSKiseokJo 	/* Capture */
92668cd394eSKiseokJo 	{"AIF OUT", NULL, "AMP Enable"},
92768cd394eSKiseokJo };
92868cd394eSKiseokJo 
sma1303_setup_pll(struct snd_soc_component * component,unsigned int bclk)92968cd394eSKiseokJo static int sma1303_setup_pll(struct snd_soc_component *component,
93068cd394eSKiseokJo 		unsigned int bclk)
93168cd394eSKiseokJo {
93268cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
93368cd394eSKiseokJo 
93468cd394eSKiseokJo 	int i = 0, ret = 0;
93568cd394eSKiseokJo 
93668cd394eSKiseokJo 	dev_dbg(component->dev, "%s : BCLK = %dHz\n",
93768cd394eSKiseokJo 		__func__, bclk);
93868cd394eSKiseokJo 
93968cd394eSKiseokJo 	if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_MCLK) {
94068cd394eSKiseokJo 		dev_dbg(component->dev, "%s : MCLK is not supported\n",
94168cd394eSKiseokJo 		__func__);
94268cd394eSKiseokJo 	} else if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_BCLK) {
94368cd394eSKiseokJo 		for (i = 0; i < sma1303->num_of_pll_matches; i++) {
94468cd394eSKiseokJo 			if (sma1303->pll_matches[i].input_clk == bclk)
94568cd394eSKiseokJo 				break;
94668cd394eSKiseokJo 		}
94768cd394eSKiseokJo 		if (i == sma1303->num_of_pll_matches) {
94868cd394eSKiseokJo 			dev_dbg(component->dev, "%s : No matching value between pll table and SCK\n",
94968cd394eSKiseokJo 					__func__);
95068cd394eSKiseokJo 			return -EINVAL;
95168cd394eSKiseokJo 		}
95268cd394eSKiseokJo 
95368cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
95468cd394eSKiseokJo 				SMA1303_A2_TOP_MAN1,
95568cd394eSKiseokJo 				SMA1303_PLL_PD_MASK|SMA1303_PLL_REF_CLK_MASK,
95668cd394eSKiseokJo 				SMA1303_PLL_OPERATION|SMA1303_PLL_SCK,
95768cd394eSKiseokJo 				NULL);
95868cd394eSKiseokJo 	}
95968cd394eSKiseokJo 
96068cd394eSKiseokJo 	ret += sma1303_regmap_write(sma1303,
96168cd394eSKiseokJo 			SMA1303_8B_PLL_POST_N,
96268cd394eSKiseokJo 			sma1303->pll_matches[i].post_n);
96368cd394eSKiseokJo 
96468cd394eSKiseokJo 	ret += sma1303_regmap_write(sma1303,
96568cd394eSKiseokJo 			SMA1303_8C_PLL_N,
96668cd394eSKiseokJo 			sma1303->pll_matches[i].n);
96768cd394eSKiseokJo 
96868cd394eSKiseokJo 	ret += sma1303_regmap_write(sma1303,
96968cd394eSKiseokJo 			SMA1303_8D_PLL_A_SETTING,
97068cd394eSKiseokJo 			sma1303->pll_matches[i].vco);
97168cd394eSKiseokJo 
97268cd394eSKiseokJo 	ret += sma1303_regmap_write(sma1303,
97368cd394eSKiseokJo 			SMA1303_8F_PLL_P_CP,
97468cd394eSKiseokJo 			sma1303->pll_matches[i].p_cp);
97568cd394eSKiseokJo 	if (ret < 0)
97668cd394eSKiseokJo 		return -EINVAL;
97768cd394eSKiseokJo 
97868cd394eSKiseokJo 	return 0;
97968cd394eSKiseokJo }
98068cd394eSKiseokJo 
sma1303_dai_hw_params_amp(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)98168cd394eSKiseokJo static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream,
98268cd394eSKiseokJo 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
98368cd394eSKiseokJo {
98468cd394eSKiseokJo 	struct snd_soc_component *component = dai->component;
98568cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
98668cd394eSKiseokJo 	unsigned int bclk = 0;
98768cd394eSKiseokJo 	int ret = 0;
98868cd394eSKiseokJo 
98968cd394eSKiseokJo 	if (sma1303->format == SND_SOC_DAIFMT_DSP_A)
99068cd394eSKiseokJo 		bclk = params_rate(params) * sma1303->frame_size;
99168cd394eSKiseokJo 	else
99268cd394eSKiseokJo 		bclk = params_rate(params) * params_physical_width(params)
99368cd394eSKiseokJo 			* params_channels(params);
99468cd394eSKiseokJo 
99568cd394eSKiseokJo 	dev_dbg(component->dev,
99668cd394eSKiseokJo 			"%s : rate = %d : bit size = %d : channel = %d\n",
99768cd394eSKiseokJo 			__func__, params_rate(params), params_width(params),
99868cd394eSKiseokJo 			params_channels(params));
99968cd394eSKiseokJo 
100068cd394eSKiseokJo 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
10012512839dSKiseok Jo 		if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_BCLK) {
100268cd394eSKiseokJo 			if (sma1303->last_bclk != bclk) {
100368cd394eSKiseokJo 				sma1303_setup_pll(component, bclk);
100468cd394eSKiseokJo 				sma1303->last_bclk = bclk;
100568cd394eSKiseokJo 			}
100668cd394eSKiseokJo 		}
100768cd394eSKiseokJo 
100868cd394eSKiseokJo 		switch (params_rate(params)) {
100968cd394eSKiseokJo 		case 8000:
101068cd394eSKiseokJo 		case 12000:
101168cd394eSKiseokJo 		case 16000:
101268cd394eSKiseokJo 		case 24000:
101368cd394eSKiseokJo 		case 32000:
101468cd394eSKiseokJo 		case 44100:
101568cd394eSKiseokJo 		case 48000:
101668cd394eSKiseokJo 		case 96000:
101768cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
101868cd394eSKiseokJo 					SMA1303_A2_TOP_MAN1,
101968cd394eSKiseokJo 					SMA1303_DAC_DN_CONV_MASK,
102068cd394eSKiseokJo 					SMA1303_DAC_DN_CONV_DISABLE,
102168cd394eSKiseokJo 					NULL);
102268cd394eSKiseokJo 
102368cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
102468cd394eSKiseokJo 					SMA1303_01_INPUT1_CTRL1,
102568cd394eSKiseokJo 					SMA1303_LEFTPOL_MASK,
102668cd394eSKiseokJo 					SMA1303_LOW_FIRST_CH,
102768cd394eSKiseokJo 					NULL);
102868cd394eSKiseokJo 			break;
102968cd394eSKiseokJo 
103068cd394eSKiseokJo 		case 192000:
103168cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
103268cd394eSKiseokJo 					SMA1303_A2_TOP_MAN1,
103368cd394eSKiseokJo 					SMA1303_DAC_DN_CONV_MASK,
103468cd394eSKiseokJo 					SMA1303_DAC_DN_CONV_ENABLE,
103568cd394eSKiseokJo 					NULL);
103668cd394eSKiseokJo 
103768cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
103868cd394eSKiseokJo 					SMA1303_01_INPUT1_CTRL1,
103968cd394eSKiseokJo 					SMA1303_LEFTPOL_MASK,
104068cd394eSKiseokJo 					SMA1303_HIGH_FIRST_CH,
104168cd394eSKiseokJo 					NULL);
104268cd394eSKiseokJo 			break;
104368cd394eSKiseokJo 
104468cd394eSKiseokJo 		default:
104568cd394eSKiseokJo 			dev_err(component->dev, "%s not support rate : %d\n",
104668cd394eSKiseokJo 				__func__, params_rate(params));
104768cd394eSKiseokJo 
104868cd394eSKiseokJo 			return -EINVAL;
104968cd394eSKiseokJo 		}
105068cd394eSKiseokJo 
105168cd394eSKiseokJo 	} else {
105268cd394eSKiseokJo 
105368cd394eSKiseokJo 		switch (params_format(params)) {
105468cd394eSKiseokJo 
105568cd394eSKiseokJo 		case SNDRV_PCM_FORMAT_S16_LE:
105668cd394eSKiseokJo 			dev_dbg(component->dev,
105768cd394eSKiseokJo 				"%s set format SNDRV_PCM_FORMAT_S16_LE\n",
105868cd394eSKiseokJo 				__func__);
105968cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
106068cd394eSKiseokJo 					SMA1303_A4_TOP_MAN3,
106168cd394eSKiseokJo 					SMA1303_SCK_RATE_MASK,
106268cd394eSKiseokJo 					SMA1303_SCK_32FS,
106368cd394eSKiseokJo 					NULL);
106468cd394eSKiseokJo 			break;
106568cd394eSKiseokJo 
106668cd394eSKiseokJo 		case SNDRV_PCM_FORMAT_S24_LE:
106768cd394eSKiseokJo 			dev_dbg(component->dev,
106868cd394eSKiseokJo 				"%s set format SNDRV_PCM_FORMAT_S24_LE\n",
106968cd394eSKiseokJo 				__func__);
107068cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
107168cd394eSKiseokJo 					SMA1303_A4_TOP_MAN3,
107268cd394eSKiseokJo 					SMA1303_SCK_RATE_MASK,
107368cd394eSKiseokJo 					SMA1303_SCK_64FS,
107468cd394eSKiseokJo 					NULL);
107568cd394eSKiseokJo 			break;
107668cd394eSKiseokJo 		case SNDRV_PCM_FORMAT_S32_LE:
107768cd394eSKiseokJo 			dev_dbg(component->dev,
107868cd394eSKiseokJo 				"%s set format SNDRV_PCM_FORMAT_S32_LE\n",
107968cd394eSKiseokJo 				__func__);
108068cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
108168cd394eSKiseokJo 					SMA1303_A4_TOP_MAN3,
108268cd394eSKiseokJo 					SMA1303_SCK_RATE_MASK,
108368cd394eSKiseokJo 					SMA1303_SCK_64FS,
108468cd394eSKiseokJo 					NULL);
108568cd394eSKiseokJo 			break;
108668cd394eSKiseokJo 		default:
108768cd394eSKiseokJo 			dev_err(component->dev,
108868cd394eSKiseokJo 				"%s not support data bit : %d\n", __func__,
108968cd394eSKiseokJo 						params_format(params));
109068cd394eSKiseokJo 			return -EINVAL;
109168cd394eSKiseokJo 		}
109268cd394eSKiseokJo 	}
109368cd394eSKiseokJo 
109468cd394eSKiseokJo 	switch (sma1303->format) {
109568cd394eSKiseokJo 	case SND_SOC_DAIFMT_I2S:
109668cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
109768cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
109868cd394eSKiseokJo 				SMA1303_I2S_MODE_MASK,
109968cd394eSKiseokJo 				SMA1303_STANDARD_I2S,
110068cd394eSKiseokJo 				NULL);
110168cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
110268cd394eSKiseokJo 				SMA1303_A4_TOP_MAN3,
110368cd394eSKiseokJo 				SMA1303_O_FORMAT_MASK,
110468cd394eSKiseokJo 				SMA1303_O_FMT_I2S,
110568cd394eSKiseokJo 				NULL);
110668cd394eSKiseokJo 		break;
110768cd394eSKiseokJo 	case SND_SOC_DAIFMT_LEFT_J:
110868cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
110968cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
111068cd394eSKiseokJo 				SMA1303_I2S_MODE_MASK,
111168cd394eSKiseokJo 				SMA1303_LJ,
111268cd394eSKiseokJo 				NULL);
111368cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
111468cd394eSKiseokJo 				SMA1303_A4_TOP_MAN3,
111568cd394eSKiseokJo 				SMA1303_O_FORMAT_MASK,
111668cd394eSKiseokJo 				SMA1303_O_FMT_LJ,
111768cd394eSKiseokJo 				NULL);
111868cd394eSKiseokJo 		break;
111968cd394eSKiseokJo 	case SND_SOC_DAIFMT_RIGHT_J:
112068cd394eSKiseokJo 		switch (params_width(params)) {
112168cd394eSKiseokJo 		case 16:
112268cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
112368cd394eSKiseokJo 					SMA1303_01_INPUT1_CTRL1,
112468cd394eSKiseokJo 					SMA1303_I2S_MODE_MASK,
112568cd394eSKiseokJo 					SMA1303_RJ_16BIT,
112668cd394eSKiseokJo 					NULL);
112768cd394eSKiseokJo 			break;
112868cd394eSKiseokJo 		case 24:
112968cd394eSKiseokJo 		case 32:
113068cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
113168cd394eSKiseokJo 					SMA1303_01_INPUT1_CTRL1,
113268cd394eSKiseokJo 					SMA1303_I2S_MODE_MASK,
113368cd394eSKiseokJo 					SMA1303_RJ_24BIT,
113468cd394eSKiseokJo 					NULL);
113568cd394eSKiseokJo 			break;
113668cd394eSKiseokJo 		}
113768cd394eSKiseokJo 		break;
113868cd394eSKiseokJo 	case SND_SOC_DAIFMT_DSP_A:
113968cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
114068cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
114168cd394eSKiseokJo 				SMA1303_I2S_MODE_MASK,
114268cd394eSKiseokJo 				SMA1303_STANDARD_I2S,
114368cd394eSKiseokJo 				NULL);
114468cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
114568cd394eSKiseokJo 				SMA1303_A4_TOP_MAN3,
114668cd394eSKiseokJo 				SMA1303_O_FORMAT_MASK,
114768cd394eSKiseokJo 				SMA1303_O_FMT_TDM,
114868cd394eSKiseokJo 				NULL);
114968cd394eSKiseokJo 		break;
115068cd394eSKiseokJo 	}
115168cd394eSKiseokJo 
115268cd394eSKiseokJo 	switch (params_width(params)) {
115368cd394eSKiseokJo 	case 16:
115468cd394eSKiseokJo 	case 24:
115568cd394eSKiseokJo 	case 32:
115668cd394eSKiseokJo 		break;
115768cd394eSKiseokJo 	default:
115868cd394eSKiseokJo 		dev_err(component->dev,
115968cd394eSKiseokJo 			"%s not support data bit : %d\n", __func__,
116068cd394eSKiseokJo 					params_format(params));
116168cd394eSKiseokJo 		return -EINVAL;
116268cd394eSKiseokJo 	}
116368cd394eSKiseokJo 	if (ret < 0)
116468cd394eSKiseokJo 		return -EINVAL;
116568cd394eSKiseokJo 
116668cd394eSKiseokJo 	return 0;
116768cd394eSKiseokJo }
116868cd394eSKiseokJo 
sma1303_dai_set_sysclk_amp(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)116968cd394eSKiseokJo static int sma1303_dai_set_sysclk_amp(struct snd_soc_dai *dai,
117068cd394eSKiseokJo 				int clk_id, unsigned int freq, int dir)
117168cd394eSKiseokJo {
117268cd394eSKiseokJo 	struct snd_soc_component *component = dai->component;
117368cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
117468cd394eSKiseokJo 
117568cd394eSKiseokJo 	switch (clk_id) {
117668cd394eSKiseokJo 	case SMA1303_EXTERNAL_CLOCK_19_2:
117768cd394eSKiseokJo 		break;
117868cd394eSKiseokJo 	case SMA1303_EXTERNAL_CLOCK_24_576:
117968cd394eSKiseokJo 		break;
118068cd394eSKiseokJo 	case SMA1303_PLL_CLKIN_MCLK:
118168cd394eSKiseokJo 		break;
118268cd394eSKiseokJo 	case SMA1303_PLL_CLKIN_BCLK:
118368cd394eSKiseokJo 		break;
118468cd394eSKiseokJo 	default:
118568cd394eSKiseokJo 		dev_err(component->dev, "Invalid clk id: %d\n", clk_id);
118668cd394eSKiseokJo 		return -EINVAL;
118768cd394eSKiseokJo 	}
118868cd394eSKiseokJo 	sma1303->sys_clk_id = clk_id;
118968cd394eSKiseokJo 	return 0;
119068cd394eSKiseokJo }
119168cd394eSKiseokJo 
sma1303_dai_mute(struct snd_soc_dai * dai,int mute,int stream)119268cd394eSKiseokJo static int sma1303_dai_mute(struct snd_soc_dai *dai, int mute, int stream)
119368cd394eSKiseokJo {
119468cd394eSKiseokJo 	struct snd_soc_component *component = dai->component;
119568cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
119668cd394eSKiseokJo 	int ret = 0;
119768cd394eSKiseokJo 
119868cd394eSKiseokJo 	if (stream == SNDRV_PCM_STREAM_CAPTURE)
119968cd394eSKiseokJo 		return ret;
120068cd394eSKiseokJo 
120168cd394eSKiseokJo 	if (mute) {
120268cd394eSKiseokJo 		dev_dbg(component->dev, "%s : %s\n", __func__, "MUTE");
120368cd394eSKiseokJo 
120468cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
120568cd394eSKiseokJo 				SMA1303_0E_MUTE_VOL_CTRL,
120668cd394eSKiseokJo 				SMA1303_SPK_MUTE_MASK,
120768cd394eSKiseokJo 				SMA1303_SPK_MUTE,
120868cd394eSKiseokJo 				NULL);
120968cd394eSKiseokJo 
121068cd394eSKiseokJo 		/* Need to wait time for mute slope */
121168cd394eSKiseokJo 		msleep(55);
121268cd394eSKiseokJo 	} else {
121368cd394eSKiseokJo 		if (!sma1303->force_mute_status) {
121468cd394eSKiseokJo 			dev_dbg(component->dev, "%s : %s\n",
121568cd394eSKiseokJo 					__func__, "UNMUTE");
121668cd394eSKiseokJo 			ret += sma1303_regmap_update_bits(sma1303,
121768cd394eSKiseokJo 					SMA1303_0E_MUTE_VOL_CTRL,
121868cd394eSKiseokJo 					SMA1303_SPK_MUTE_MASK,
121968cd394eSKiseokJo 					SMA1303_SPK_UNMUTE,
122068cd394eSKiseokJo 					NULL);
122168cd394eSKiseokJo 		} else {
122268cd394eSKiseokJo 			dev_dbg(sma1303->dev,
122368cd394eSKiseokJo 					"%s : FORCE MUTE!!!\n", __func__);
122468cd394eSKiseokJo 		}
122568cd394eSKiseokJo 	}
122668cd394eSKiseokJo 
122768cd394eSKiseokJo 	if (ret < 0)
122868cd394eSKiseokJo 		return -EINVAL;
122968cd394eSKiseokJo 	return 0;
123068cd394eSKiseokJo }
123168cd394eSKiseokJo 
sma1303_dai_set_fmt_amp(struct snd_soc_dai * dai,unsigned int fmt)123268cd394eSKiseokJo static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai,
123368cd394eSKiseokJo 					unsigned int fmt)
123468cd394eSKiseokJo {
123568cd394eSKiseokJo 	struct snd_soc_component *component  = dai->component;
123668cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
123768cd394eSKiseokJo 	int ret = 0;
123868cd394eSKiseokJo 
123968cd394eSKiseokJo 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
124068cd394eSKiseokJo 
124168cd394eSKiseokJo 	case SND_SOC_DAIFMT_CBC_CFC:
124268cd394eSKiseokJo 		dev_dbg(component->dev,
124368cd394eSKiseokJo 				"%s : %s\n", __func__, "I2S/TDM Device mode");
124468cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
124568cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
124668cd394eSKiseokJo 				SMA1303_CONTROLLER_DEVICE_MASK,
124768cd394eSKiseokJo 				SMA1303_DEVICE_MODE,
124868cd394eSKiseokJo 				NULL);
124968cd394eSKiseokJo 		break;
125068cd394eSKiseokJo 
125168cd394eSKiseokJo 	case SND_SOC_DAIFMT_CBP_CFP:
125268cd394eSKiseokJo 		dev_dbg(component->dev,
125368cd394eSKiseokJo 			"%s : %s\n", __func__, "I2S/TDM Controller mode");
125468cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
125568cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
125668cd394eSKiseokJo 				SMA1303_CONTROLLER_DEVICE_MASK,
125768cd394eSKiseokJo 				SMA1303_CONTROLLER_MODE,
125868cd394eSKiseokJo 				NULL);
125968cd394eSKiseokJo 		break;
126068cd394eSKiseokJo 
126168cd394eSKiseokJo 	default:
126268cd394eSKiseokJo 		dev_err(component->dev,
126368cd394eSKiseokJo 			"Unsupported Controller/Device : 0x%x\n", fmt);
126468cd394eSKiseokJo 		return -EINVAL;
126568cd394eSKiseokJo 	}
126668cd394eSKiseokJo 
126768cd394eSKiseokJo 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
126868cd394eSKiseokJo 
126968cd394eSKiseokJo 	case SND_SOC_DAIFMT_I2S:
127068cd394eSKiseokJo 	case SND_SOC_DAIFMT_RIGHT_J:
127168cd394eSKiseokJo 	case SND_SOC_DAIFMT_LEFT_J:
127268cd394eSKiseokJo 	case SND_SOC_DAIFMT_DSP_A:
127368cd394eSKiseokJo 	case SND_SOC_DAIFMT_DSP_B:
127468cd394eSKiseokJo 		sma1303->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
127568cd394eSKiseokJo 		break;
127668cd394eSKiseokJo 	default:
127768cd394eSKiseokJo 		dev_err(component->dev,
127868cd394eSKiseokJo 			"Unsupported Audio Interface Format : 0x%x\n", fmt);
127968cd394eSKiseokJo 		return -EINVAL;
128068cd394eSKiseokJo 	}
128168cd394eSKiseokJo 
128268cd394eSKiseokJo 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
128368cd394eSKiseokJo 
128468cd394eSKiseokJo 	case SND_SOC_DAIFMT_IB_NF:
128568cd394eSKiseokJo 		dev_dbg(component->dev, "%s : %s\n",
128668cd394eSKiseokJo 			__func__, "Invert BCLK + Normal Frame");
128768cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
128868cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
128968cd394eSKiseokJo 				SMA1303_SCK_RISING_MASK,
129068cd394eSKiseokJo 				SMA1303_SCK_RISING_EDGE,
129168cd394eSKiseokJo 				NULL);
129268cd394eSKiseokJo 		break;
129368cd394eSKiseokJo 	case SND_SOC_DAIFMT_IB_IF:
129468cd394eSKiseokJo 		dev_dbg(component->dev, "%s : %s\n",
129568cd394eSKiseokJo 			__func__, "Invert BCLK + Invert Frame");
129668cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
129768cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
129868cd394eSKiseokJo 				SMA1303_LEFTPOL_MASK|SMA1303_SCK_RISING_MASK,
129968cd394eSKiseokJo 				SMA1303_HIGH_FIRST_CH|SMA1303_SCK_RISING_EDGE,
130068cd394eSKiseokJo 				NULL);
130168cd394eSKiseokJo 		break;
130268cd394eSKiseokJo 	case SND_SOC_DAIFMT_NB_IF:
130368cd394eSKiseokJo 		dev_dbg(component->dev, "%s : %s\n",
130468cd394eSKiseokJo 			__func__, "Normal BCLK + Invert Frame");
130568cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
130668cd394eSKiseokJo 				SMA1303_01_INPUT1_CTRL1,
130768cd394eSKiseokJo 				SMA1303_LEFTPOL_MASK,
130868cd394eSKiseokJo 				SMA1303_HIGH_FIRST_CH,
130968cd394eSKiseokJo 				NULL);
131068cd394eSKiseokJo 		break;
131168cd394eSKiseokJo 	case SND_SOC_DAIFMT_NB_NF:
131268cd394eSKiseokJo 		dev_dbg(component->dev, "%s : %s\n",
131368cd394eSKiseokJo 			__func__, "Normal BCLK + Normal Frame");
131468cd394eSKiseokJo 		break;
131568cd394eSKiseokJo 	default:
131668cd394eSKiseokJo 		dev_err(component->dev,
131768cd394eSKiseokJo 				"Unsupported Bit & Frameclock : 0x%x\n", fmt);
131868cd394eSKiseokJo 		return -EINVAL;
131968cd394eSKiseokJo 	}
132068cd394eSKiseokJo 
132168cd394eSKiseokJo 	if (ret < 0)
132268cd394eSKiseokJo 		return -EINVAL;
132368cd394eSKiseokJo 	return 0;
132468cd394eSKiseokJo }
132568cd394eSKiseokJo 
sma1303_dai_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)132668cd394eSKiseokJo static int sma1303_dai_set_tdm_slot(struct snd_soc_dai *dai,
132768cd394eSKiseokJo 				unsigned int tx_mask, unsigned int rx_mask,
132868cd394eSKiseokJo 				int slots, int slot_width)
132968cd394eSKiseokJo {
133068cd394eSKiseokJo 	struct snd_soc_component *component = dai->component;
133168cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
133268cd394eSKiseokJo 	int ret = 0;
133368cd394eSKiseokJo 
133468cd394eSKiseokJo 	dev_dbg(component->dev, "%s : slots = %d, slot_width - %d\n",
133568cd394eSKiseokJo 			__func__, slots, slot_width);
133668cd394eSKiseokJo 
133768cd394eSKiseokJo 	sma1303->frame_size = slot_width * slots;
133868cd394eSKiseokJo 
133968cd394eSKiseokJo 	ret += sma1303_regmap_update_bits(sma1303,
134068cd394eSKiseokJo 				SMA1303_A4_TOP_MAN3,
134168cd394eSKiseokJo 				SMA1303_O_FORMAT_MASK,
134268cd394eSKiseokJo 				SMA1303_O_FMT_TDM,
134368cd394eSKiseokJo 				NULL);
134468cd394eSKiseokJo 
134568cd394eSKiseokJo 	switch (slot_width) {
134668cd394eSKiseokJo 	case 16:
134768cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
134868cd394eSKiseokJo 					SMA1303_A6_TDM2,
134968cd394eSKiseokJo 					SMA1303_TDM_DL_MASK,
135068cd394eSKiseokJo 					SMA1303_TDM_DL_16,
135168cd394eSKiseokJo 					NULL);
135268cd394eSKiseokJo 		break;
135368cd394eSKiseokJo 	case 32:
135468cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
135568cd394eSKiseokJo 					SMA1303_A6_TDM2,
135668cd394eSKiseokJo 					SMA1303_TDM_DL_MASK,
135768cd394eSKiseokJo 					SMA1303_TDM_DL_32,
135868cd394eSKiseokJo 					NULL);
135968cd394eSKiseokJo 		break;
136068cd394eSKiseokJo 	default:
136168cd394eSKiseokJo 		dev_err(component->dev, "%s not support TDM %d slot_width\n",
136268cd394eSKiseokJo 					__func__, slot_width);
136368cd394eSKiseokJo 		break;
136468cd394eSKiseokJo 	}
136568cd394eSKiseokJo 
136668cd394eSKiseokJo 	switch (slots) {
136768cd394eSKiseokJo 	case 4:
136868cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
136968cd394eSKiseokJo 					SMA1303_A6_TDM2,
137068cd394eSKiseokJo 					SMA1303_TDM_N_SLOT_MASK,
137168cd394eSKiseokJo 					SMA1303_TDM_N_SLOT_4,
137268cd394eSKiseokJo 					NULL);
137368cd394eSKiseokJo 		break;
137468cd394eSKiseokJo 	case 8:
137568cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
137668cd394eSKiseokJo 					SMA1303_A6_TDM2,
137768cd394eSKiseokJo 					SMA1303_TDM_N_SLOT_MASK,
137868cd394eSKiseokJo 					SMA1303_TDM_N_SLOT_8,
137968cd394eSKiseokJo 					NULL);
138068cd394eSKiseokJo 		break;
138168cd394eSKiseokJo 	default:
138268cd394eSKiseokJo 		dev_err(component->dev, "%s not support TDM %d slots\n",
138368cd394eSKiseokJo 				__func__, slots);
138468cd394eSKiseokJo 		break;
138568cd394eSKiseokJo 	}
138668cd394eSKiseokJo 
138768cd394eSKiseokJo 	if (sma1303->tdm_slot_rx < slots)
138868cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
138968cd394eSKiseokJo 					SMA1303_A5_TDM1,
139068cd394eSKiseokJo 					SMA1303_TDM_SLOT1_RX_POS_MASK,
139168cd394eSKiseokJo 					(sma1303->tdm_slot_rx) << 3,
139268cd394eSKiseokJo 					NULL);
139368cd394eSKiseokJo 	else
139468cd394eSKiseokJo 		dev_err(component->dev, "%s Incorrect tdm-slot-rx %d set\n",
139568cd394eSKiseokJo 					__func__, sma1303->tdm_slot_rx);
139668cd394eSKiseokJo 
139768cd394eSKiseokJo 	ret += sma1303_regmap_update_bits(sma1303,
139868cd394eSKiseokJo 				SMA1303_A5_TDM1,
139968cd394eSKiseokJo 				SMA1303_TDM_CLK_POL_MASK,
140068cd394eSKiseokJo 				SMA1303_TDM_CLK_POL_RISE,
140168cd394eSKiseokJo 				NULL);
140268cd394eSKiseokJo 
140368cd394eSKiseokJo 	ret += sma1303_regmap_update_bits(sma1303,
140468cd394eSKiseokJo 				SMA1303_A5_TDM1,
140568cd394eSKiseokJo 				SMA1303_TDM_TX_MODE_MASK,
140668cd394eSKiseokJo 				SMA1303_TDM_TX_MONO,
140768cd394eSKiseokJo 				NULL);
140868cd394eSKiseokJo 
140968cd394eSKiseokJo 	if (sma1303->tdm_slot_tx < slots)
141068cd394eSKiseokJo 		ret += sma1303_regmap_update_bits(sma1303,
141168cd394eSKiseokJo 					SMA1303_A6_TDM2,
141268cd394eSKiseokJo 					SMA1303_TDM_SLOT1_TX_POS_MASK,
141368cd394eSKiseokJo 					(sma1303->tdm_slot_tx) << 3,
141468cd394eSKiseokJo 					NULL);
141568cd394eSKiseokJo 	else
141668cd394eSKiseokJo 		dev_err(component->dev, "%s Incorrect tdm-slot-tx %d set\n",
141768cd394eSKiseokJo 				__func__, sma1303->tdm_slot_tx);
141868cd394eSKiseokJo 
141968cd394eSKiseokJo 	if (ret < 0)
142068cd394eSKiseokJo 		return -EINVAL;
142168cd394eSKiseokJo 	return 0;
142268cd394eSKiseokJo }
142368cd394eSKiseokJo 
142468cd394eSKiseokJo static const struct snd_soc_dai_ops sma1303_dai_ops_amp = {
142568cd394eSKiseokJo 	.set_sysclk = sma1303_dai_set_sysclk_amp,
142668cd394eSKiseokJo 	.set_fmt = sma1303_dai_set_fmt_amp,
142768cd394eSKiseokJo 	.hw_params = sma1303_dai_hw_params_amp,
142868cd394eSKiseokJo 	.mute_stream = sma1303_dai_mute,
142968cd394eSKiseokJo 	.set_tdm_slot = sma1303_dai_set_tdm_slot,
143068cd394eSKiseokJo };
143168cd394eSKiseokJo 
143268cd394eSKiseokJo #define SMA1303_RATES SNDRV_PCM_RATE_8000_192000
143368cd394eSKiseokJo #define SMA1303_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
143468cd394eSKiseokJo 		SNDRV_PCM_FMTBIT_S32_LE)
143568cd394eSKiseokJo 
143668cd394eSKiseokJo static struct snd_soc_dai_driver sma1303_dai[] = {
143768cd394eSKiseokJo 	{
143868cd394eSKiseokJo 		.name = "sma1303-amplifier",
143968cd394eSKiseokJo 		.id = 0,
144068cd394eSKiseokJo 		.playback = {
144168cd394eSKiseokJo 			.stream_name = "Playback",
144268cd394eSKiseokJo 			.channels_min = 1,
144368cd394eSKiseokJo 			.channels_max = 2,
144468cd394eSKiseokJo 			.rates = SMA1303_RATES,
144568cd394eSKiseokJo 			.formats = SMA1303_FORMATS,
144668cd394eSKiseokJo 		},
144768cd394eSKiseokJo 		.capture = {
144868cd394eSKiseokJo 			.stream_name = "Capture",
144968cd394eSKiseokJo 			.channels_min = 1,
145068cd394eSKiseokJo 			.channels_max = 2,
145168cd394eSKiseokJo 			.rates = SMA1303_RATES,
145268cd394eSKiseokJo 			.formats = SMA1303_FORMATS,
145368cd394eSKiseokJo 		},
145468cd394eSKiseokJo 		.ops = &sma1303_dai_ops_amp,
145568cd394eSKiseokJo 	},
145668cd394eSKiseokJo };
145768cd394eSKiseokJo 
sma1303_check_fault_worker(struct work_struct * work)145868cd394eSKiseokJo static void sma1303_check_fault_worker(struct work_struct *work)
145968cd394eSKiseokJo {
146068cd394eSKiseokJo 	struct sma1303_priv *sma1303 =
146168cd394eSKiseokJo 		container_of(work, struct sma1303_priv, check_fault_work.work);
146268cd394eSKiseokJo 	int ret = 0;
146368cd394eSKiseokJo 	unsigned int over_temp, ocp_val, uvlo_val;
146468cd394eSKiseokJo 
146568cd394eSKiseokJo 	if (sma1303->tsdw_cnt)
146668cd394eSKiseokJo 		ret = sma1303_regmap_read(sma1303,
146768cd394eSKiseokJo 			SMA1303_0A_SPK_VOL, &sma1303->cur_vol);
146868cd394eSKiseokJo 	else
146968cd394eSKiseokJo 		ret = sma1303_regmap_read(sma1303,
147068cd394eSKiseokJo 			SMA1303_0A_SPK_VOL, &sma1303->init_vol);
147168cd394eSKiseokJo 
147268cd394eSKiseokJo 	if (ret != 0) {
147368cd394eSKiseokJo 		dev_err(sma1303->dev,
147468cd394eSKiseokJo 			"failed to read SMA1303_0A_SPK_VOL : %d\n", ret);
147568cd394eSKiseokJo 		return;
147668cd394eSKiseokJo 	}
147768cd394eSKiseokJo 
147868cd394eSKiseokJo 	ret = sma1303_regmap_read(sma1303, SMA1303_FA_STATUS1, &over_temp);
147968cd394eSKiseokJo 	if (ret != 0) {
148068cd394eSKiseokJo 		dev_err(sma1303->dev,
148168cd394eSKiseokJo 			"failed to read SMA1303_FA_STATUS1 : %d\n", ret);
148268cd394eSKiseokJo 		return;
148368cd394eSKiseokJo 	}
148468cd394eSKiseokJo 
148568cd394eSKiseokJo 	ret = sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, &ocp_val);
148668cd394eSKiseokJo 	if (ret != 0) {
148768cd394eSKiseokJo 		dev_err(sma1303->dev,
148868cd394eSKiseokJo 			"failed to read SMA1303_FB_STATUS2 : %d\n", ret);
148968cd394eSKiseokJo 		return;
149068cd394eSKiseokJo 	}
149168cd394eSKiseokJo 
149268cd394eSKiseokJo 	ret = sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, &uvlo_val);
149368cd394eSKiseokJo 	if (ret != 0) {
149468cd394eSKiseokJo 		dev_err(sma1303->dev,
149568cd394eSKiseokJo 			"failed to read SMA1303_FF_DEVICE_INDEX : %d\n", ret);
149668cd394eSKiseokJo 		return;
149768cd394eSKiseokJo 	}
149868cd394eSKiseokJo 
149968cd394eSKiseokJo 	if (~over_temp & SMA1303_OT1_OK_STATUS) {
150068cd394eSKiseokJo 		dev_crit(sma1303->dev,
150168cd394eSKiseokJo 			"%s : OT1(Over Temperature Level 1)\n", __func__);
150268cd394eSKiseokJo 
150368cd394eSKiseokJo 		if ((sma1303->cur_vol + 6) <= 0xFF)
150468cd394eSKiseokJo 			sma1303_regmap_write(sma1303,
150568cd394eSKiseokJo 				SMA1303_0A_SPK_VOL, sma1303->cur_vol + 6);
150668cd394eSKiseokJo 
150768cd394eSKiseokJo 		sma1303->tsdw_cnt++;
150868cd394eSKiseokJo 	} else if (sma1303->tsdw_cnt) {
150968cd394eSKiseokJo 		sma1303_regmap_write(sma1303,
151068cd394eSKiseokJo 				SMA1303_0A_SPK_VOL, sma1303->init_vol);
151168cd394eSKiseokJo 		sma1303->tsdw_cnt = 0;
151268cd394eSKiseokJo 		sma1303->cur_vol = sma1303->init_vol;
151368cd394eSKiseokJo 	}
151468cd394eSKiseokJo 
151568cd394eSKiseokJo 	if (~over_temp & SMA1303_OT2_OK_STATUS) {
151668cd394eSKiseokJo 		dev_crit(sma1303->dev,
151768cd394eSKiseokJo 			"%s : OT2(Over Temperature Level 2)\n", __func__);
151868cd394eSKiseokJo 	}
151968cd394eSKiseokJo 	if (ocp_val & SMA1303_OCP_SPK_STATUS) {
152068cd394eSKiseokJo 		dev_crit(sma1303->dev,
152168cd394eSKiseokJo 			"%s : OCP_SPK(Over Current Protect SPK)\n", __func__);
152268cd394eSKiseokJo 	}
152368cd394eSKiseokJo 	if (ocp_val & SMA1303_OCP_BST_STATUS) {
152468cd394eSKiseokJo 		dev_crit(sma1303->dev,
152568cd394eSKiseokJo 			"%s : OCP_BST(Over Current Protect Boost)\n", __func__);
152668cd394eSKiseokJo 	}
152768cd394eSKiseokJo 	if ((ocp_val & SMA1303_CLK_MON_STATUS) && (sma1303->amp_power_status)) {
152868cd394eSKiseokJo 		dev_crit(sma1303->dev,
152968cd394eSKiseokJo 			"%s : CLK_FAULT(No clock input)\n", __func__);
153068cd394eSKiseokJo 	}
153168cd394eSKiseokJo 	if (uvlo_val & SMA1303_UVLO_BST_STATUS) {
153268cd394eSKiseokJo 		dev_crit(sma1303->dev,
153368cd394eSKiseokJo 			"%s : UVLO(Under Voltage Lock Out)\n", __func__);
153468cd394eSKiseokJo 	}
153568cd394eSKiseokJo 
153668cd394eSKiseokJo 	if ((over_temp != sma1303->last_over_temp) ||
153768cd394eSKiseokJo 		(ocp_val != sma1303->last_ocp_val)) {
153868cd394eSKiseokJo 
153968cd394eSKiseokJo 		dev_crit(sma1303->dev, "Please check AMP status");
154068cd394eSKiseokJo 		dev_dbg(sma1303->dev, "STATUS1=0x%02X : STATUS2=0x%02X\n",
154168cd394eSKiseokJo 				over_temp, ocp_val);
154268cd394eSKiseokJo 		sma1303->last_over_temp = over_temp;
154368cd394eSKiseokJo 		sma1303->last_ocp_val = ocp_val;
154468cd394eSKiseokJo 	}
154568cd394eSKiseokJo 
154668cd394eSKiseokJo 	if (sma1303->check_fault_status) {
154768cd394eSKiseokJo 		if (sma1303->check_fault_period > 0)
154868cd394eSKiseokJo 			queue_delayed_work(system_freezable_wq,
154968cd394eSKiseokJo 				&sma1303->check_fault_work,
155068cd394eSKiseokJo 					sma1303->check_fault_period * HZ);
155168cd394eSKiseokJo 		else
155268cd394eSKiseokJo 			queue_delayed_work(system_freezable_wq,
155368cd394eSKiseokJo 				&sma1303->check_fault_work,
155468cd394eSKiseokJo 					CHECK_PERIOD_TIME * HZ);
155568cd394eSKiseokJo 	}
155668cd394eSKiseokJo 
155768cd394eSKiseokJo 	if (!(~over_temp & SMA1303_OT1_OK_STATUS)
155868cd394eSKiseokJo 			&& !(~over_temp & SMA1303_OT2_OK_STATUS)
155968cd394eSKiseokJo 			&& !(ocp_val & SMA1303_OCP_SPK_STATUS)
156068cd394eSKiseokJo 			&& !(ocp_val & SMA1303_OCP_BST_STATUS)
156168cd394eSKiseokJo 			&& !(ocp_val & SMA1303_CLK_MON_STATUS)
156268cd394eSKiseokJo 			&& !(uvlo_val & SMA1303_UVLO_BST_STATUS)) {
156368cd394eSKiseokJo 	}
156468cd394eSKiseokJo }
156568cd394eSKiseokJo 
sma1303_probe(struct snd_soc_component * component)156668cd394eSKiseokJo static int sma1303_probe(struct snd_soc_component *component)
156768cd394eSKiseokJo {
156868cd394eSKiseokJo 	struct snd_soc_dapm_context *dapm =
156968cd394eSKiseokJo 		snd_soc_component_get_dapm(component);
157068cd394eSKiseokJo 
157168cd394eSKiseokJo 	snd_soc_dapm_sync(dapm);
157268cd394eSKiseokJo 
157368cd394eSKiseokJo 	return 0;
157468cd394eSKiseokJo }
157568cd394eSKiseokJo 
sma1303_remove(struct snd_soc_component * component)157668cd394eSKiseokJo static void sma1303_remove(struct snd_soc_component *component)
157768cd394eSKiseokJo {
157868cd394eSKiseokJo 	struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component);
157968cd394eSKiseokJo 
158068cd394eSKiseokJo 	cancel_delayed_work_sync(&sma1303->check_fault_work);
158168cd394eSKiseokJo }
158268cd394eSKiseokJo 
158368cd394eSKiseokJo static const struct snd_soc_component_driver sma1303_component = {
158468cd394eSKiseokJo 	.probe = sma1303_probe,
158568cd394eSKiseokJo 	.remove = sma1303_remove,
158668cd394eSKiseokJo 	.controls = sma1303_snd_controls,
158768cd394eSKiseokJo 	.num_controls = ARRAY_SIZE(sma1303_snd_controls),
158868cd394eSKiseokJo 	.dapm_widgets = sma1303_dapm_widgets,
158968cd394eSKiseokJo 	.num_dapm_widgets = ARRAY_SIZE(sma1303_dapm_widgets),
159068cd394eSKiseokJo 	.dapm_routes = sma1303_audio_map,
159168cd394eSKiseokJo 	.num_dapm_routes = ARRAY_SIZE(sma1303_audio_map),
159268cd394eSKiseokJo };
159368cd394eSKiseokJo 
1594d7d103d1STom Rix static const struct regmap_config sma_i2c_regmap = {
159568cd394eSKiseokJo 	.reg_bits = 8,
159668cd394eSKiseokJo 	.val_bits = 8,
159768cd394eSKiseokJo 
159868cd394eSKiseokJo 	.max_register = SMA1303_FF_DEVICE_INDEX,
159968cd394eSKiseokJo 	.readable_reg = sma1303_readable_register,
160068cd394eSKiseokJo 	.writeable_reg = sma1303_writeable_register,
160168cd394eSKiseokJo 	.volatile_reg = sma1303_volatile_register,
160268cd394eSKiseokJo 
160368cd394eSKiseokJo 	.cache_type = REGCACHE_NONE,
160468cd394eSKiseokJo 	.reg_defaults = sma1303_reg_def,
160568cd394eSKiseokJo 	.num_reg_defaults = ARRAY_SIZE(sma1303_reg_def),
160668cd394eSKiseokJo };
160768cd394eSKiseokJo 
check_fault_period_show(struct device * dev,struct device_attribute * devattr,char * buf)160868cd394eSKiseokJo static ssize_t check_fault_period_show(struct device *dev,
160968cd394eSKiseokJo 	struct device_attribute *devattr, char *buf)
161068cd394eSKiseokJo {
161168cd394eSKiseokJo 	struct sma1303_priv *sma1303 = dev_get_drvdata(dev);
161268cd394eSKiseokJo 
161368cd394eSKiseokJo 	return sysfs_emit(buf, "%ld\n", sma1303->check_fault_period);
161468cd394eSKiseokJo }
161568cd394eSKiseokJo 
check_fault_period_store(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)161668cd394eSKiseokJo static ssize_t check_fault_period_store(struct device *dev,
161768cd394eSKiseokJo 	struct device_attribute *devattr, const char *buf, size_t count)
161868cd394eSKiseokJo {
161968cd394eSKiseokJo 	struct sma1303_priv *sma1303 = dev_get_drvdata(dev);
162068cd394eSKiseokJo 	int ret;
162168cd394eSKiseokJo 
162268cd394eSKiseokJo 	ret = kstrtol(buf, 10, &sma1303->check_fault_period);
162368cd394eSKiseokJo 
162468cd394eSKiseokJo 	if (ret)
162568cd394eSKiseokJo 		return -EINVAL;
162668cd394eSKiseokJo 
162768cd394eSKiseokJo 	return (ssize_t)count;
162868cd394eSKiseokJo }
162968cd394eSKiseokJo 
163068cd394eSKiseokJo static DEVICE_ATTR_RW(check_fault_period);
163168cd394eSKiseokJo 
check_fault_status_show(struct device * dev,struct device_attribute * devattr,char * buf)163268cd394eSKiseokJo static ssize_t check_fault_status_show(struct device *dev,
163368cd394eSKiseokJo 	struct device_attribute *devattr, char *buf)
163468cd394eSKiseokJo {
163568cd394eSKiseokJo 	struct sma1303_priv *sma1303 = dev_get_drvdata(dev);
163668cd394eSKiseokJo 
163768cd394eSKiseokJo 	return sysfs_emit(buf, "%ld\n", sma1303->check_fault_status);
163868cd394eSKiseokJo }
163968cd394eSKiseokJo 
check_fault_status_store(struct device * dev,struct device_attribute * devattr,const char * buf,size_t count)164068cd394eSKiseokJo static ssize_t check_fault_status_store(struct device *dev,
164168cd394eSKiseokJo 	struct device_attribute *devattr, const char *buf, size_t count)
164268cd394eSKiseokJo {
164368cd394eSKiseokJo 	struct sma1303_priv *sma1303 = dev_get_drvdata(dev);
164468cd394eSKiseokJo 	int ret;
164568cd394eSKiseokJo 
164668cd394eSKiseokJo 	ret = kstrtol(buf, 10, &sma1303->check_fault_status);
164768cd394eSKiseokJo 
164868cd394eSKiseokJo 	if (ret)
164968cd394eSKiseokJo 		return -EINVAL;
165068cd394eSKiseokJo 
165168cd394eSKiseokJo 	if (sma1303->check_fault_status) {
165268cd394eSKiseokJo 		if (sma1303->check_fault_period > 0)
165368cd394eSKiseokJo 			queue_delayed_work(system_freezable_wq,
165468cd394eSKiseokJo 				&sma1303->check_fault_work,
165568cd394eSKiseokJo 					sma1303->check_fault_period * HZ);
165668cd394eSKiseokJo 		else
165768cd394eSKiseokJo 			queue_delayed_work(system_freezable_wq,
165868cd394eSKiseokJo 				&sma1303->check_fault_work,
165968cd394eSKiseokJo 					CHECK_PERIOD_TIME * HZ);
166068cd394eSKiseokJo 	}
166168cd394eSKiseokJo 
166268cd394eSKiseokJo 	return (ssize_t)count;
166368cd394eSKiseokJo }
166468cd394eSKiseokJo 
166568cd394eSKiseokJo static DEVICE_ATTR_RW(check_fault_status);
166668cd394eSKiseokJo 
166768cd394eSKiseokJo static struct attribute *sma1303_attr[] = {
166868cd394eSKiseokJo 	&dev_attr_check_fault_period.attr,
166968cd394eSKiseokJo 	&dev_attr_check_fault_status.attr,
167068cd394eSKiseokJo 	NULL,
167168cd394eSKiseokJo };
167268cd394eSKiseokJo 
167368cd394eSKiseokJo static struct attribute_group sma1303_attr_group = {
167468cd394eSKiseokJo 	.attrs = sma1303_attr,
167568cd394eSKiseokJo };
167668cd394eSKiseokJo 
sma1303_i2c_probe(struct i2c_client * client)167730cf0025SUwe Kleine-König static int sma1303_i2c_probe(struct i2c_client *client)
167868cd394eSKiseokJo {
167968cd394eSKiseokJo 	struct sma1303_priv *sma1303;
168068cd394eSKiseokJo 	int ret, i = 0;
168168cd394eSKiseokJo 	unsigned int device_info, status, otp_stat;
168268cd394eSKiseokJo 
168368cd394eSKiseokJo 	sma1303 = devm_kzalloc(&client->dev,
168468cd394eSKiseokJo 				sizeof(struct sma1303_priv), GFP_KERNEL);
168568cd394eSKiseokJo 	if (!sma1303)
168668cd394eSKiseokJo 		return -ENOMEM;
168768cd394eSKiseokJo 	sma1303->dev = &client->dev;
168868cd394eSKiseokJo 
168968cd394eSKiseokJo 	sma1303->regmap = devm_regmap_init_i2c(client, &sma_i2c_regmap);
169068cd394eSKiseokJo 	if (IS_ERR(sma1303->regmap)) {
169168cd394eSKiseokJo 		ret = PTR_ERR(sma1303->regmap);
169268cd394eSKiseokJo 		dev_err(&client->dev,
169368cd394eSKiseokJo 			"Failed to allocate register map: %d\n", ret);
169468cd394eSKiseokJo 
169568cd394eSKiseokJo 		return ret;
169668cd394eSKiseokJo 	}
169768cd394eSKiseokJo 
169868cd394eSKiseokJo 	ret = sma1303_regmap_read(sma1303,
169968cd394eSKiseokJo 			SMA1303_FF_DEVICE_INDEX, &device_info);
170068cd394eSKiseokJo 
170168cd394eSKiseokJo 	if ((ret != 0) || ((device_info & 0xF8) != SMA1303_DEVICE_ID)) {
170268cd394eSKiseokJo 		dev_err(&client->dev, "device initialization error (%d 0x%02X)",
170368cd394eSKiseokJo 				ret, device_info);
170468cd394eSKiseokJo 	}
170568cd394eSKiseokJo 	dev_dbg(&client->dev, "chip version 0x%02X\n", device_info);
170668cd394eSKiseokJo 
170768cd394eSKiseokJo 	ret += sma1303_regmap_update_bits(sma1303,
170868cd394eSKiseokJo 			SMA1303_00_SYSTEM_CTRL,
170968cd394eSKiseokJo 			SMA1303_RESETBYI2C_MASK, SMA1303_RESETBYI2C_RESET,
171068cd394eSKiseokJo 			NULL);
171168cd394eSKiseokJo 
171268cd394eSKiseokJo 	ret += sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, &status);
171368cd394eSKiseokJo 	sma1303->rev_num = status & SMA1303_REV_NUM_STATUS;
171468cd394eSKiseokJo 	if (sma1303->rev_num == SMA1303_REV_NUM_TV0)
171568cd394eSKiseokJo 		dev_dbg(&client->dev, "SMA1303 Trimming Version 0\n");
171668cd394eSKiseokJo 	else if (sma1303->rev_num == SMA1303_REV_NUM_TV1)
171768cd394eSKiseokJo 		dev_dbg(&client->dev, "SMA1303 Trimming Version 1\n");
171868cd394eSKiseokJo 
171968cd394eSKiseokJo 	ret += sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, &otp_stat);
172068cd394eSKiseokJo 	if (ret < 0)
172168cd394eSKiseokJo 		dev_err(&client->dev,
172268cd394eSKiseokJo 			"failed to read, register: %02X, ret: %d\n",
172368cd394eSKiseokJo 				SMA1303_FF_DEVICE_INDEX, ret);
172468cd394eSKiseokJo 
172568cd394eSKiseokJo 	if (((sma1303->rev_num == SMA1303_REV_NUM_TV0) &&
172668cd394eSKiseokJo 		((otp_stat & 0x0E) == SMA1303_OTP_STAT_OK_0)) ||
172768cd394eSKiseokJo 		((sma1303->rev_num != SMA1303_REV_NUM_TV0) &&
172868cd394eSKiseokJo 		((otp_stat & 0x0C) == SMA1303_OTP_STAT_OK_1)))
172968cd394eSKiseokJo 		dev_dbg(&client->dev, "SMA1303 OTP Status Successful\n");
173068cd394eSKiseokJo 	else
173168cd394eSKiseokJo 		dev_dbg(&client->dev, "SMA1303 OTP Status Fail\n");
173268cd394eSKiseokJo 
173368cd394eSKiseokJo 	for (i = 0; i < (unsigned int)ARRAY_SIZE(sma1303_reg_def); i++)
173468cd394eSKiseokJo 		ret += sma1303_regmap_write(sma1303,
173568cd394eSKiseokJo 				sma1303_reg_def[i].reg,
173668cd394eSKiseokJo 				sma1303_reg_def[i].def);
173768cd394eSKiseokJo 
173868cd394eSKiseokJo 	sma1303->amp_mode = SMA1303_MONO;
173968cd394eSKiseokJo 	sma1303->amp_power_status = false;
174068cd394eSKiseokJo 	sma1303->check_fault_period = CHECK_PERIOD_TIME;
174168cd394eSKiseokJo 	sma1303->check_fault_status = true;
174268cd394eSKiseokJo 	sma1303->force_mute_status = false;
174368cd394eSKiseokJo 	sma1303->init_vol = 0x31;
174468cd394eSKiseokJo 	sma1303->cur_vol = sma1303->init_vol;
174568cd394eSKiseokJo 	sma1303->last_bclk = 0;
174668cd394eSKiseokJo 	sma1303->last_ocp_val = 0x08;
174768cd394eSKiseokJo 	sma1303->last_over_temp = 0xC0;
174868cd394eSKiseokJo 	sma1303->tsdw_cnt = 0;
17491edc70c3SKiseok Jo 	sma1303->retry_cnt = SMA1303_I2C_RETRY_COUNT;
17501f5ffd57SKiseok Jo 	sma1303->tdm_slot_rx = 0;
17511f5ffd57SKiseok Jo 	sma1303->tdm_slot_tx = 0;
17522512839dSKiseok Jo 	sma1303->sys_clk_id = SMA1303_PLL_CLKIN_BCLK;
175368cd394eSKiseokJo 
175468cd394eSKiseokJo 	sma1303->dev = &client->dev;
175568cd394eSKiseokJo 	sma1303->kobj = &client->dev.kobj;
175668cd394eSKiseokJo 
175768cd394eSKiseokJo 	INIT_DELAYED_WORK(&sma1303->check_fault_work,
175868cd394eSKiseokJo 		sma1303_check_fault_worker);
175968cd394eSKiseokJo 
176068cd394eSKiseokJo 	i2c_set_clientdata(client, sma1303);
176168cd394eSKiseokJo 
176268cd394eSKiseokJo 	sma1303->pll_matches = sma1303_pll_matches;
176368cd394eSKiseokJo 	sma1303->num_of_pll_matches =
176468cd394eSKiseokJo 		ARRAY_SIZE(sma1303_pll_matches);
176568cd394eSKiseokJo 
176668cd394eSKiseokJo 	ret = devm_snd_soc_register_component(&client->dev,
176768cd394eSKiseokJo 			&sma1303_component, sma1303_dai, 1);
176868cd394eSKiseokJo 	if (ret) {
176968cd394eSKiseokJo 		dev_err(&client->dev, "Failed to register component");
177068cd394eSKiseokJo 
177168cd394eSKiseokJo 		return ret;
177268cd394eSKiseokJo 	}
177368cd394eSKiseokJo 
177468cd394eSKiseokJo 	sma1303->attr_grp = &sma1303_attr_group;
177568cd394eSKiseokJo 	ret = sysfs_create_group(sma1303->kobj, sma1303->attr_grp);
177668cd394eSKiseokJo 	if (ret) {
177768cd394eSKiseokJo 		dev_err(&client->dev,
177868cd394eSKiseokJo 			"failed to create attribute group [%d]\n", ret);
177968cd394eSKiseokJo 		sma1303->attr_grp = NULL;
178068cd394eSKiseokJo 	}
178168cd394eSKiseokJo 
178268cd394eSKiseokJo 	return ret;
178368cd394eSKiseokJo }
178468cd394eSKiseokJo 
sma1303_i2c_remove(struct i2c_client * client)178568cd394eSKiseokJo static void sma1303_i2c_remove(struct i2c_client *client)
178668cd394eSKiseokJo {
178768cd394eSKiseokJo 	struct sma1303_priv *sma1303 =
178868cd394eSKiseokJo 		(struct sma1303_priv *) i2c_get_clientdata(client);
178968cd394eSKiseokJo 
179068cd394eSKiseokJo 	cancel_delayed_work_sync(&sma1303->check_fault_work);
179168cd394eSKiseokJo }
179268cd394eSKiseokJo 
179368cd394eSKiseokJo static const struct i2c_device_id sma1303_i2c_id[] = {
1794*ba2a2c37SUwe Kleine-König 	{"sma1303"},
179568cd394eSKiseokJo 	{}
179668cd394eSKiseokJo };
179768cd394eSKiseokJo MODULE_DEVICE_TABLE(i2c, sma1303_i2c_id);
179868cd394eSKiseokJo 
179968cd394eSKiseokJo static const struct of_device_id sma1303_of_match[] = {
180068cd394eSKiseokJo 	{ .compatible = "irondevice,sma1303", },
180168cd394eSKiseokJo 	{ }
180268cd394eSKiseokJo };
180368cd394eSKiseokJo MODULE_DEVICE_TABLE(of, sma1303_of_match);
180468cd394eSKiseokJo 
180568cd394eSKiseokJo static struct i2c_driver sma1303_i2c_driver = {
180668cd394eSKiseokJo 	.driver = {
180768cd394eSKiseokJo 		.name = "sma1303",
180868cd394eSKiseokJo 		.of_match_table = sma1303_of_match,
180968cd394eSKiseokJo 	},
18109abcd240SUwe Kleine-König 	.probe = sma1303_i2c_probe,
181168cd394eSKiseokJo 	.remove = sma1303_i2c_remove,
181268cd394eSKiseokJo 	.id_table = sma1303_i2c_id,
181368cd394eSKiseokJo };
181468cd394eSKiseokJo 
181568cd394eSKiseokJo module_i2c_driver(sma1303_i2c_driver);
181668cd394eSKiseokJo 
181768cd394eSKiseokJo MODULE_DESCRIPTION("ALSA SoC SMA1303 driver");
181868cd394eSKiseokJo MODULE_AUTHOR("Gyuhwa Park, <gyuhwa.park@irondevice.com>");
181968cd394eSKiseokJo MODULE_AUTHOR("Kiseok Jo, <kiseok.jo@irondevice.com>");
182068cd394eSKiseokJo MODULE_LICENSE("GPL v2");
1821