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 1068cd394eSKiseokJo #include <linux/module.h> 1168cd394eSKiseokJo #include <linux/moduleparam.h> 1268cd394eSKiseokJo #include <linux/kernel.h> 1368cd394eSKiseokJo #include <linux/init.h> 1468cd394eSKiseokJo #include <linux/delay.h> 1568cd394eSKiseokJo #include <linux/pm.h> 1668cd394eSKiseokJo #include <linux/i2c.h> 1768cd394eSKiseokJo #include <linux/regmap.h> 1868cd394eSKiseokJo #include <sound/core.h> 1968cd394eSKiseokJo #include <sound/pcm.h> 2068cd394eSKiseokJo #include <sound/pcm_params.h> 2168cd394eSKiseokJo #include <sound/soc.h> 2268cd394eSKiseokJo #include <sound/initval.h> 2368cd394eSKiseokJo #include <sound/tlv.h> 2468cd394eSKiseokJo #include <linux/of_device.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 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 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 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 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 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 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"}; 29568cd394eSKiseokJo 29668cd394eSKiseokJo static const struct soc_enum sma1303_aif_in_source_enum = 29768cd394eSKiseokJo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_aif_in_source_text), 29868cd394eSKiseokJo sma1303_aif_in_source_text); 29968cd394eSKiseokJo static const struct soc_enum sma1303_aif_out_source_enum = 30068cd394eSKiseokJo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1303_aif_out_source_text), 30168cd394eSKiseokJo sma1303_aif_out_source_text); 30268cd394eSKiseokJo 30368cd394eSKiseokJo static int sma1303_force_mute_get(struct snd_kcontrol *kcontrol, 30468cd394eSKiseokJo struct snd_ctl_elem_value *ucontrol) 30568cd394eSKiseokJo { 30668cd394eSKiseokJo struct snd_soc_component *component = 30768cd394eSKiseokJo snd_soc_kcontrol_component(kcontrol); 30868cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 30968cd394eSKiseokJo 31068cd394eSKiseokJo ucontrol->value.integer.value[0] = (int)sma1303->force_mute_status; 31168cd394eSKiseokJo dev_dbg(sma1303->dev, "%s : Force Mute %s\n", __func__, 31268cd394eSKiseokJo sma1303->force_mute_status ? "ON" : "OFF"); 31368cd394eSKiseokJo 31468cd394eSKiseokJo return 0; 31568cd394eSKiseokJo } 31668cd394eSKiseokJo 31768cd394eSKiseokJo static int sma1303_force_mute_put(struct snd_kcontrol *kcontrol, 31868cd394eSKiseokJo struct snd_ctl_elem_value *ucontrol) 31968cd394eSKiseokJo { 32068cd394eSKiseokJo struct snd_soc_component *component = 32168cd394eSKiseokJo snd_soc_kcontrol_component(kcontrol); 32268cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 32368cd394eSKiseokJo bool change = false, val = (bool)ucontrol->value.integer.value[0]; 32468cd394eSKiseokJo 32568cd394eSKiseokJo if (sma1303->force_mute_status == val) 32668cd394eSKiseokJo change = false; 32768cd394eSKiseokJo else { 32868cd394eSKiseokJo change = true; 32968cd394eSKiseokJo sma1303->force_mute_status = val; 33068cd394eSKiseokJo } 33168cd394eSKiseokJo dev_dbg(sma1303->dev, "%s : Force Mute %s\n", __func__, 33268cd394eSKiseokJo sma1303->force_mute_status ? "ON" : "OFF"); 33368cd394eSKiseokJo 33468cd394eSKiseokJo return change; 33568cd394eSKiseokJo } 33668cd394eSKiseokJo 33768cd394eSKiseokJo static int sma1303_postscaler_get(struct snd_kcontrol *kcontrol, 33868cd394eSKiseokJo struct snd_ctl_elem_value *ucontrol) 33968cd394eSKiseokJo { 34068cd394eSKiseokJo struct snd_soc_component *component = 34168cd394eSKiseokJo snd_soc_kcontrol_component(kcontrol); 34268cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 34368cd394eSKiseokJo int val, ret; 34468cd394eSKiseokJo 34568cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, SMA1303_90_POSTSCALER, &val); 34668cd394eSKiseokJo if (ret < 0) 34768cd394eSKiseokJo return -EINVAL; 34868cd394eSKiseokJo 34968cd394eSKiseokJo ucontrol->value.integer.value[0] = (val & 0x7E) >> 1; 35068cd394eSKiseokJo 35168cd394eSKiseokJo return 0; 35268cd394eSKiseokJo } 35368cd394eSKiseokJo 35468cd394eSKiseokJo static int sma1303_postscaler_put(struct snd_kcontrol *kcontrol, 35568cd394eSKiseokJo struct snd_ctl_elem_value *ucontrol) 35668cd394eSKiseokJo { 35768cd394eSKiseokJo struct snd_soc_component *component = 35868cd394eSKiseokJo snd_soc_kcontrol_component(kcontrol); 35968cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 36068cd394eSKiseokJo int ret, val = (int)ucontrol->value.integer.value[0]; 36168cd394eSKiseokJo bool change; 36268cd394eSKiseokJo 36368cd394eSKiseokJo ret = sma1303_regmap_update_bits(sma1303, 36468cd394eSKiseokJo SMA1303_90_POSTSCALER, 0x7E, (val << 1), &change); 36568cd394eSKiseokJo if (ret < 0) 36668cd394eSKiseokJo return -EINVAL; 36768cd394eSKiseokJo 36868cd394eSKiseokJo return change; 36968cd394eSKiseokJo } 37068cd394eSKiseokJo 37168cd394eSKiseokJo static int sma1303_startup(struct snd_soc_component *component) 37268cd394eSKiseokJo { 37368cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 37468cd394eSKiseokJo bool change = false, temp = false; 37568cd394eSKiseokJo 37668cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, SMA1303_8E_PLL_CTRL, 37768cd394eSKiseokJo SMA1303_PLL_PD2_MASK, SMA1303_PLL_OPERATION2, &temp); 37868cd394eSKiseokJo if (temp == true) 37968cd394eSKiseokJo change = true; 38068cd394eSKiseokJo 38168cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, SMA1303_00_SYSTEM_CTRL, 38268cd394eSKiseokJo SMA1303_POWER_MASK, SMA1303_POWER_ON, &temp); 38368cd394eSKiseokJo if (temp == true) 38468cd394eSKiseokJo change = true; 38568cd394eSKiseokJo 38668cd394eSKiseokJo if (sma1303->amp_mode == SMA1303_MONO) { 38768cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, 38868cd394eSKiseokJo SMA1303_10_SYSTEM_CTRL1, 38968cd394eSKiseokJo SMA1303_SPK_MODE_MASK, 39068cd394eSKiseokJo SMA1303_SPK_MONO, 39168cd394eSKiseokJo &temp); 39268cd394eSKiseokJo if (temp == true) 39368cd394eSKiseokJo change = true; 39468cd394eSKiseokJo 39568cd394eSKiseokJo } else { 39668cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, 39768cd394eSKiseokJo SMA1303_10_SYSTEM_CTRL1, 39868cd394eSKiseokJo SMA1303_SPK_MODE_MASK, 39968cd394eSKiseokJo SMA1303_SPK_STEREO, 40068cd394eSKiseokJo &temp); 40168cd394eSKiseokJo if (temp == true) 40268cd394eSKiseokJo change = true; 40368cd394eSKiseokJo } 40468cd394eSKiseokJo 40568cd394eSKiseokJo if (sma1303->check_fault_status) { 40668cd394eSKiseokJo if (sma1303->check_fault_period > 0) 40768cd394eSKiseokJo queue_delayed_work(system_freezable_wq, 40868cd394eSKiseokJo &sma1303->check_fault_work, 40968cd394eSKiseokJo sma1303->check_fault_period * HZ); 41068cd394eSKiseokJo else 41168cd394eSKiseokJo queue_delayed_work(system_freezable_wq, 41268cd394eSKiseokJo &sma1303->check_fault_work, 41368cd394eSKiseokJo CHECK_PERIOD_TIME * HZ); 41468cd394eSKiseokJo } 41568cd394eSKiseokJo 41668cd394eSKiseokJo sma1303->amp_power_status = true; 41768cd394eSKiseokJo 41868cd394eSKiseokJo return change; 41968cd394eSKiseokJo } 42068cd394eSKiseokJo 42168cd394eSKiseokJo static int sma1303_shutdown(struct snd_soc_component *component) 42268cd394eSKiseokJo { 42368cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 42468cd394eSKiseokJo bool change = false, temp = false; 42568cd394eSKiseokJo 42668cd394eSKiseokJo cancel_delayed_work_sync(&sma1303->check_fault_work); 42768cd394eSKiseokJo 42868cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, SMA1303_10_SYSTEM_CTRL1, 42968cd394eSKiseokJo SMA1303_SPK_MODE_MASK, SMA1303_SPK_OFF, &temp); 43068cd394eSKiseokJo if (temp == true) 43168cd394eSKiseokJo change = true; 43268cd394eSKiseokJo 43368cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, SMA1303_00_SYSTEM_CTRL, 43468cd394eSKiseokJo SMA1303_POWER_MASK, SMA1303_POWER_OFF, &temp); 43568cd394eSKiseokJo if (temp == true) 43668cd394eSKiseokJo change = true; 43768cd394eSKiseokJo sma1303_regmap_update_bits(sma1303, SMA1303_8E_PLL_CTRL, 43868cd394eSKiseokJo SMA1303_PLL_PD2_MASK, SMA1303_PLL_PD2, &temp); 43968cd394eSKiseokJo if (temp == true) 44068cd394eSKiseokJo change = true; 44168cd394eSKiseokJo 44268cd394eSKiseokJo sma1303->amp_power_status = false; 44368cd394eSKiseokJo 44468cd394eSKiseokJo return change; 44568cd394eSKiseokJo } 44668cd394eSKiseokJo 44768cd394eSKiseokJo static int sma1303_aif_in_event(struct snd_soc_dapm_widget *w, 44868cd394eSKiseokJo struct snd_kcontrol *kcontrol, int event) 44968cd394eSKiseokJo { 45068cd394eSKiseokJo struct snd_soc_component *component = 45168cd394eSKiseokJo snd_soc_dapm_to_component(w->dapm); 45268cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 45368cd394eSKiseokJo unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); 45468cd394eSKiseokJo int ret = 0; 45568cd394eSKiseokJo bool change = false, temp = false; 45668cd394eSKiseokJo 45768cd394eSKiseokJo switch (event) { 45868cd394eSKiseokJo case SND_SOC_DAPM_PRE_PMU: 45968cd394eSKiseokJo switch (mux) { 46068cd394eSKiseokJo case 0: 46168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 46268cd394eSKiseokJo SMA1303_11_SYSTEM_CTRL2, 46368cd394eSKiseokJo SMA1303_MONOMIX_MASK, 46468cd394eSKiseokJo SMA1303_MONOMIX_ON, 46568cd394eSKiseokJo &change); 46668cd394eSKiseokJo sma1303->amp_mode = SMA1303_MONO; 46768cd394eSKiseokJo break; 46868cd394eSKiseokJo case 1: 46968cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 47068cd394eSKiseokJo SMA1303_11_SYSTEM_CTRL2, 47168cd394eSKiseokJo SMA1303_MONOMIX_MASK, 47268cd394eSKiseokJo SMA1303_MONOMIX_OFF, 47368cd394eSKiseokJo &temp); 47468cd394eSKiseokJo if (temp == true) 47568cd394eSKiseokJo change = true; 47668cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 47768cd394eSKiseokJo SMA1303_11_SYSTEM_CTRL2, 47868cd394eSKiseokJo SMA1303_LR_DATA_SW_MASK, 47968cd394eSKiseokJo SMA1303_LR_DATA_SW_NORMAL, 48068cd394eSKiseokJo &temp); 48168cd394eSKiseokJo if (temp == true) 48268cd394eSKiseokJo change = true; 48368cd394eSKiseokJo sma1303->amp_mode = SMA1303_STEREO; 48468cd394eSKiseokJo break; 48568cd394eSKiseokJo case 2: 48668cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 48768cd394eSKiseokJo SMA1303_11_SYSTEM_CTRL2, 48868cd394eSKiseokJo SMA1303_MONOMIX_MASK, 48968cd394eSKiseokJo SMA1303_MONOMIX_OFF, 49068cd394eSKiseokJo &temp); 49168cd394eSKiseokJo if (temp == true) 49268cd394eSKiseokJo change = true; 49368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 49468cd394eSKiseokJo SMA1303_11_SYSTEM_CTRL2, 49568cd394eSKiseokJo SMA1303_LR_DATA_SW_MASK, 49668cd394eSKiseokJo SMA1303_LR_DATA_SW_NORMAL, 49768cd394eSKiseokJo &temp); 49868cd394eSKiseokJo if (temp == true) 49968cd394eSKiseokJo change = true; 50068cd394eSKiseokJo sma1303->amp_mode = SMA1303_STEREO; 50168cd394eSKiseokJo break; 50268cd394eSKiseokJo default: 5035b28c049SColin Ian King dev_err(sma1303->dev, "%s : Invalid value (%d)\n", 50468cd394eSKiseokJo __func__, mux); 50568cd394eSKiseokJo return -EINVAL; 50668cd394eSKiseokJo } 50768cd394eSKiseokJo 50868cd394eSKiseokJo dev_dbg(sma1303->dev, "%s : Source : %s\n", __func__, 50968cd394eSKiseokJo sma1303_aif_in_source_text[mux]); 51068cd394eSKiseokJo break; 51168cd394eSKiseokJo } 51268cd394eSKiseokJo if (ret < 0) 51368cd394eSKiseokJo return -EINVAL; 51468cd394eSKiseokJo return change; 51568cd394eSKiseokJo } 51668cd394eSKiseokJo 51768cd394eSKiseokJo static int sma1303_aif_out_event(struct snd_soc_dapm_widget *w, 51868cd394eSKiseokJo struct snd_kcontrol *kcontrol, int event) 51968cd394eSKiseokJo { 52068cd394eSKiseokJo struct snd_soc_component *component = 52168cd394eSKiseokJo snd_soc_dapm_to_component(w->dapm); 52268cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 52368cd394eSKiseokJo unsigned int mux = dapm_kcontrol_get_value(w->kcontrols[0]); 52468cd394eSKiseokJo int ret = 0; 52568cd394eSKiseokJo bool change = false, temp = false; 52668cd394eSKiseokJo 52768cd394eSKiseokJo switch (event) { 52868cd394eSKiseokJo case SND_SOC_DAPM_PRE_PMU: 52968cd394eSKiseokJo switch (mux) { 53068cd394eSKiseokJo case 0: 53168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 53268cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 53368cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 53468cd394eSKiseokJo SMA1303_NORMAL_SDO, 53568cd394eSKiseokJo &temp); 53668cd394eSKiseokJo if (temp == true) 53768cd394eSKiseokJo change = true; 53868cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 53968cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 54068cd394eSKiseokJo SMA1303_PORT_OUT_SEL_MASK, 54168cd394eSKiseokJo SMA1303_OUT_SEL_DISABLE, 54268cd394eSKiseokJo &temp); 54368cd394eSKiseokJo if (temp == true) 54468cd394eSKiseokJo change = true; 54568cd394eSKiseokJo break; 54668cd394eSKiseokJo case 1: 54768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 54868cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 54968cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 55068cd394eSKiseokJo SMA1303_NORMAL_SDO, 55168cd394eSKiseokJo &temp); 55268cd394eSKiseokJo if (temp == true) 55368cd394eSKiseokJo change = true; 55468cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 55568cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 55668cd394eSKiseokJo SMA1303_PORT_OUT_SEL_MASK, 55768cd394eSKiseokJo SMA1303_FORMAT_CONVERTER, 55868cd394eSKiseokJo &temp); 55968cd394eSKiseokJo if (temp == true) 56068cd394eSKiseokJo change = true; 56168cd394eSKiseokJo break; 56268cd394eSKiseokJo case 2: 56368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 56468cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 56568cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 56668cd394eSKiseokJo SMA1303_NORMAL_SDO, 56768cd394eSKiseokJo &temp); 56868cd394eSKiseokJo if (temp == true) 56968cd394eSKiseokJo change = true; 57068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 57168cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 57268cd394eSKiseokJo SMA1303_PORT_OUT_SEL_MASK, 57368cd394eSKiseokJo SMA1303_MIXER_OUTPUT, 57468cd394eSKiseokJo &temp); 57568cd394eSKiseokJo if (temp == true) 57668cd394eSKiseokJo change = true; 57768cd394eSKiseokJo break; 57868cd394eSKiseokJo case 3: 57968cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 58068cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 58168cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 58268cd394eSKiseokJo SMA1303_NORMAL_SDO, 58368cd394eSKiseokJo &temp); 58468cd394eSKiseokJo if (temp == true) 58568cd394eSKiseokJo change = true; 58668cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 58768cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 58868cd394eSKiseokJo SMA1303_PORT_OUT_SEL_MASK, 58968cd394eSKiseokJo SMA1303_SPEAKER_PATH, 59068cd394eSKiseokJo &temp); 59168cd394eSKiseokJo if (temp == true) 59268cd394eSKiseokJo change = true; 59368cd394eSKiseokJo break; 59468cd394eSKiseokJo case 4: 59568cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 59668cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 59768cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 59868cd394eSKiseokJo SMA1303_NORMAL_SDO, 59968cd394eSKiseokJo &temp); 60068cd394eSKiseokJo if (temp == true) 60168cd394eSKiseokJo change = true; 60268cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 60368cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 60468cd394eSKiseokJo SMA1303_PORT_OUT_SEL_MASK, 60568cd394eSKiseokJo SMA1303_POSTSCALER_OUTPUT, 60668cd394eSKiseokJo &temp); 60768cd394eSKiseokJo if (temp == true) 60868cd394eSKiseokJo change = true; 60968cd394eSKiseokJo break; 61068cd394eSKiseokJo case 5: 61168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 61268cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 61368cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 61468cd394eSKiseokJo SMA1303_CLK_OUT_SDO, 61568cd394eSKiseokJo &temp); 61668cd394eSKiseokJo if (temp == true) 61768cd394eSKiseokJo change = true; 61868cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 61968cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 62068cd394eSKiseokJo SMA1303_MON_OSC_PLL_MASK, 62168cd394eSKiseokJo SMA1303_PLL_SDO, 62268cd394eSKiseokJo &temp); 62368cd394eSKiseokJo if (temp == true) 62468cd394eSKiseokJo change = true; 62568cd394eSKiseokJo break; 62668cd394eSKiseokJo case 6: 62768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 62868cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 62968cd394eSKiseokJo SMA1303_TEST_CLKO_EN_MASK, 63068cd394eSKiseokJo SMA1303_CLK_OUT_SDO, 63168cd394eSKiseokJo &temp); 63268cd394eSKiseokJo if (temp == true) 63368cd394eSKiseokJo change = true; 63468cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 63568cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 63668cd394eSKiseokJo SMA1303_MON_OSC_PLL_MASK, 63768cd394eSKiseokJo SMA1303_OSC_SDO, 63868cd394eSKiseokJo &temp); 63968cd394eSKiseokJo if (temp == true) 64068cd394eSKiseokJo change = true; 64168cd394eSKiseokJo break; 64268cd394eSKiseokJo default: 6435b28c049SColin Ian King dev_err(sma1303->dev, "%s : Invalid value (%d)\n", 64468cd394eSKiseokJo __func__, mux); 64568cd394eSKiseokJo return -EINVAL; 64668cd394eSKiseokJo } 64768cd394eSKiseokJo 64868cd394eSKiseokJo dev_dbg(sma1303->dev, "%s : Source : %s\n", __func__, 64968cd394eSKiseokJo sma1303_aif_out_source_text[mux]); 65068cd394eSKiseokJo break; 65168cd394eSKiseokJo } 65268cd394eSKiseokJo if (ret < 0) 65368cd394eSKiseokJo return -EINVAL; 65468cd394eSKiseokJo return change; 65568cd394eSKiseokJo } 65668cd394eSKiseokJo 65768cd394eSKiseokJo static int sma1303_sdo_event(struct snd_soc_dapm_widget *w, 65868cd394eSKiseokJo struct snd_kcontrol *kcontrol, int event) 65968cd394eSKiseokJo { 66068cd394eSKiseokJo struct snd_soc_component *component = 66168cd394eSKiseokJo snd_soc_dapm_to_component(w->dapm); 66268cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 66368cd394eSKiseokJo int ret = 0; 66468cd394eSKiseokJo bool change = false, temp = false; 66568cd394eSKiseokJo 66668cd394eSKiseokJo switch (event) { 66768cd394eSKiseokJo case SND_SOC_DAPM_PRE_PMU: 66868cd394eSKiseokJo dev_dbg(sma1303->dev, 66968cd394eSKiseokJo "%s : SND_SOC_DAPM_PRE_PMU\n", __func__); 67068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 67168cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 67268cd394eSKiseokJo SMA1303_PORT_CONFIG_MASK, 67368cd394eSKiseokJo SMA1303_OUTPUT_PORT_ENABLE, 67468cd394eSKiseokJo &temp); 67568cd394eSKiseokJo if (temp == true) 67668cd394eSKiseokJo change = true; 67768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 67868cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 67968cd394eSKiseokJo SMA1303_SDO_OUTPUT_MASK, 68068cd394eSKiseokJo SMA1303_NORMAL_OUT, 68168cd394eSKiseokJo &temp); 68268cd394eSKiseokJo if (temp == true) 68368cd394eSKiseokJo change = true; 68468cd394eSKiseokJo break; 68568cd394eSKiseokJo case SND_SOC_DAPM_POST_PMD: 68668cd394eSKiseokJo dev_dbg(sma1303->dev, 68768cd394eSKiseokJo "%s : SND_SOC_DAPM_POST_PMD\n", __func__); 68868cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 68968cd394eSKiseokJo SMA1303_09_OUTPUT_CTRL, 69068cd394eSKiseokJo SMA1303_PORT_CONFIG_MASK, 69168cd394eSKiseokJo SMA1303_INPUT_PORT_ONLY, 69268cd394eSKiseokJo &temp); 69368cd394eSKiseokJo if (temp == true) 69468cd394eSKiseokJo change = true; 69568cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 69668cd394eSKiseokJo SMA1303_A3_TOP_MAN2, 69768cd394eSKiseokJo SMA1303_SDO_OUTPUT_MASK, 69868cd394eSKiseokJo SMA1303_HIGH_Z_OUT, 69968cd394eSKiseokJo &temp); 70068cd394eSKiseokJo if (temp == true) 70168cd394eSKiseokJo change = true; 70268cd394eSKiseokJo break; 70368cd394eSKiseokJo } 70468cd394eSKiseokJo if (ret < 0) 70568cd394eSKiseokJo return -EINVAL; 70668cd394eSKiseokJo return change; 70768cd394eSKiseokJo } 70868cd394eSKiseokJo 70968cd394eSKiseokJo static int sma1303_post_scaler_event(struct snd_soc_dapm_widget *w, 71068cd394eSKiseokJo struct snd_kcontrol *kcontrol, int event) 71168cd394eSKiseokJo { 71268cd394eSKiseokJo struct snd_soc_component *component = 71368cd394eSKiseokJo snd_soc_dapm_to_component(w->dapm); 71468cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 71568cd394eSKiseokJo int ret = 0; 71668cd394eSKiseokJo bool change = false; 71768cd394eSKiseokJo 71868cd394eSKiseokJo switch (event) { 71968cd394eSKiseokJo case SND_SOC_DAPM_PRE_PMU: 72068cd394eSKiseokJo dev_dbg(sma1303->dev, 72168cd394eSKiseokJo "%s : SND_SOC_DAPM_PRE_PMU\n", __func__); 72268cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 72368cd394eSKiseokJo SMA1303_90_POSTSCALER, 72468cd394eSKiseokJo SMA1303_BYP_POST_MASK, 72568cd394eSKiseokJo SMA1303_EN_POST_SCALER, 72668cd394eSKiseokJo &change); 72768cd394eSKiseokJo break; 72868cd394eSKiseokJo case SND_SOC_DAPM_POST_PMD: 72968cd394eSKiseokJo dev_dbg(sma1303->dev, 73068cd394eSKiseokJo "%s : SND_SOC_DAPM_POST_PMD\n", __func__); 73168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 73268cd394eSKiseokJo SMA1303_90_POSTSCALER, 73368cd394eSKiseokJo SMA1303_BYP_POST_MASK, 73468cd394eSKiseokJo SMA1303_BYP_POST_SCALER, 73568cd394eSKiseokJo &change); 73668cd394eSKiseokJo break; 73768cd394eSKiseokJo } 73868cd394eSKiseokJo if (ret < 0) 73968cd394eSKiseokJo return -EINVAL; 74068cd394eSKiseokJo return change; 74168cd394eSKiseokJo } 74268cd394eSKiseokJo 74368cd394eSKiseokJo static int sma1303_power_event(struct snd_soc_dapm_widget *w, 74468cd394eSKiseokJo struct snd_kcontrol *kcontrol, int event) 74568cd394eSKiseokJo { 74668cd394eSKiseokJo struct snd_soc_component *component = 74768cd394eSKiseokJo snd_soc_dapm_to_component(w->dapm); 74868cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 74968cd394eSKiseokJo int ret = 0; 75068cd394eSKiseokJo 75168cd394eSKiseokJo switch (event) { 75268cd394eSKiseokJo case SND_SOC_DAPM_POST_PMU: 75368cd394eSKiseokJo dev_dbg(sma1303->dev, 75468cd394eSKiseokJo "%s : SND_SOC_DAPM_POST_PMU\n", __func__); 75568cd394eSKiseokJo ret = sma1303_startup(component); 75668cd394eSKiseokJo break; 75768cd394eSKiseokJo case SND_SOC_DAPM_PRE_PMD: 75868cd394eSKiseokJo dev_dbg(sma1303->dev, 75968cd394eSKiseokJo "%s : SND_SOC_DAPM_PRE_PMD\n", __func__); 76068cd394eSKiseokJo ret = sma1303_shutdown(component); 76168cd394eSKiseokJo break; 76268cd394eSKiseokJo } 76368cd394eSKiseokJo return ret; 76468cd394eSKiseokJo } 76568cd394eSKiseokJo 76668cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_aif_in_source_control = 76768cd394eSKiseokJo SOC_DAPM_ENUM("AIF IN Source", sma1303_aif_in_source_enum); 76868cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_aif_out_source_control = 76968cd394eSKiseokJo SOC_DAPM_ENUM("AIF OUT Source", sma1303_aif_out_source_enum); 77068cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_sdo_control = 77168cd394eSKiseokJo SOC_DAPM_SINGLE_VIRT("Switch", 1); 77268cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_post_scaler_control = 77368cd394eSKiseokJo SOC_DAPM_SINGLE_VIRT("Switch", 1); 77468cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_enable_control = 77568cd394eSKiseokJo SOC_DAPM_SINGLE_VIRT("Switch", 1); 77668cd394eSKiseokJo 77768cd394eSKiseokJo static const struct snd_kcontrol_new sma1303_snd_controls[] = { 77868cd394eSKiseokJo SOC_SINGLE_TLV("Speaker Volume", SMA1303_0A_SPK_VOL, 77968cd394eSKiseokJo 0, 167, 1, sma1303_spk_tlv), 78068cd394eSKiseokJo SOC_SINGLE_BOOL_EXT("Force Mute Switch", 0, 78168cd394eSKiseokJo sma1303_force_mute_get, sma1303_force_mute_put), 78268cd394eSKiseokJo SOC_SINGLE_EXT("Postscaler Gain", SMA1303_90_POSTSCALER, 1, 0x30, 0, 78368cd394eSKiseokJo sma1303_postscaler_get, sma1303_postscaler_put), 78468cd394eSKiseokJo }; 78568cd394eSKiseokJo 78668cd394eSKiseokJo static const struct snd_soc_dapm_widget sma1303_dapm_widgets[] = { 78768cd394eSKiseokJo /* platform domain */ 78868cd394eSKiseokJo SND_SOC_DAPM_OUTPUT("SPK"), 78968cd394eSKiseokJo SND_SOC_DAPM_INPUT("SDO"), 79068cd394eSKiseokJo 79168cd394eSKiseokJo /* path domain */ 79268cd394eSKiseokJo SND_SOC_DAPM_MUX_E("AIF IN Source", SND_SOC_NOPM, 0, 0, 79368cd394eSKiseokJo &sma1303_aif_in_source_control, 79468cd394eSKiseokJo sma1303_aif_in_event, 79568cd394eSKiseokJo SND_SOC_DAPM_PRE_PMU), 79668cd394eSKiseokJo SND_SOC_DAPM_MUX_E("AIF OUT Source", SND_SOC_NOPM, 0, 0, 79768cd394eSKiseokJo &sma1303_aif_out_source_control, 79868cd394eSKiseokJo sma1303_aif_out_event, 79968cd394eSKiseokJo SND_SOC_DAPM_PRE_PMU), 80068cd394eSKiseokJo SND_SOC_DAPM_SWITCH_E("SDO Enable", SND_SOC_NOPM, 0, 0, 80168cd394eSKiseokJo &sma1303_sdo_control, 80268cd394eSKiseokJo sma1303_sdo_event, 80368cd394eSKiseokJo SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 80468cd394eSKiseokJo SND_SOC_DAPM_MIXER("Entry", SND_SOC_NOPM, 0, 0, NULL, 0), 80568cd394eSKiseokJo SND_SOC_DAPM_SWITCH_E("Post Scaler", SND_SOC_NOPM, 0, 1, 80668cd394eSKiseokJo &sma1303_post_scaler_control, 80768cd394eSKiseokJo sma1303_post_scaler_event, 80868cd394eSKiseokJo SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 80968cd394eSKiseokJo SND_SOC_DAPM_OUT_DRV_E("AMP Power", SND_SOC_NOPM, 0, 0, NULL, 0, 81068cd394eSKiseokJo sma1303_power_event, 81168cd394eSKiseokJo SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 81268cd394eSKiseokJo SND_SOC_DAPM_SWITCH("AMP Enable", SND_SOC_NOPM, 0, 1, 81368cd394eSKiseokJo &sma1303_enable_control), 81468cd394eSKiseokJo 81568cd394eSKiseokJo /* stream domain */ 81668cd394eSKiseokJo SND_SOC_DAPM_AIF_IN("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0), 81768cd394eSKiseokJo SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0), 81868cd394eSKiseokJo }; 81968cd394eSKiseokJo 82068cd394eSKiseokJo static const struct snd_soc_dapm_route sma1303_audio_map[] = { 82168cd394eSKiseokJo /* Playback */ 82268cd394eSKiseokJo {"AIF IN Source", "Mono", "AIF IN"}, 82368cd394eSKiseokJo {"AIF IN Source", "Left", "AIF IN"}, 82468cd394eSKiseokJo {"AIF IN Source", "Right", "AIF IN"}, 82568cd394eSKiseokJo 82668cd394eSKiseokJo {"SDO Enable", "Switch", "AIF IN"}, 82768cd394eSKiseokJo {"AIF OUT Source", "Disable", "SDO Enable"}, 82868cd394eSKiseokJo {"AIF OUT Source", "After_FmtC", "SDO Enable"}, 82968cd394eSKiseokJo {"AIF OUT Source", "After_Mixer", "SDO Enable"}, 83068cd394eSKiseokJo {"AIF OUT Source", "After_DSP", "SDO Enable"}, 83168cd394eSKiseokJo {"AIF OUT Source", "After_Post", "SDO Enable"}, 83268cd394eSKiseokJo {"AIF OUT Source", "Clk_PLL", "SDO Enable"}, 83368cd394eSKiseokJo {"AIF OUT Source", "Clk_OSC", "SDO Enable"}, 83468cd394eSKiseokJo 83568cd394eSKiseokJo {"Entry", NULL, "AIF OUT Source"}, 83668cd394eSKiseokJo {"Entry", NULL, "AIF IN Source"}, 83768cd394eSKiseokJo 83868cd394eSKiseokJo {"Post Scaler", "Switch", "Entry"}, 83968cd394eSKiseokJo {"AMP Power", NULL, "Entry"}, 84068cd394eSKiseokJo {"AMP Power", NULL, "Entry"}, 84168cd394eSKiseokJo 84268cd394eSKiseokJo {"AMP Enable", "Switch", "AMP Power"}, 84368cd394eSKiseokJo {"SPK", NULL, "AMP Enable"}, 84468cd394eSKiseokJo 84568cd394eSKiseokJo /* Capture */ 84668cd394eSKiseokJo {"AIF OUT", NULL, "AMP Enable"}, 84768cd394eSKiseokJo }; 84868cd394eSKiseokJo 84968cd394eSKiseokJo static int sma1303_setup_pll(struct snd_soc_component *component, 85068cd394eSKiseokJo unsigned int bclk) 85168cd394eSKiseokJo { 85268cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 85368cd394eSKiseokJo 85468cd394eSKiseokJo int i = 0, ret = 0; 85568cd394eSKiseokJo 85668cd394eSKiseokJo dev_dbg(component->dev, "%s : BCLK = %dHz\n", 85768cd394eSKiseokJo __func__, bclk); 85868cd394eSKiseokJo 85968cd394eSKiseokJo if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_MCLK) { 86068cd394eSKiseokJo dev_dbg(component->dev, "%s : MCLK is not supported\n", 86168cd394eSKiseokJo __func__); 86268cd394eSKiseokJo } else if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_BCLK) { 86368cd394eSKiseokJo for (i = 0; i < sma1303->num_of_pll_matches; i++) { 86468cd394eSKiseokJo if (sma1303->pll_matches[i].input_clk == bclk) 86568cd394eSKiseokJo break; 86668cd394eSKiseokJo } 86768cd394eSKiseokJo if (i == sma1303->num_of_pll_matches) { 86868cd394eSKiseokJo dev_dbg(component->dev, "%s : No matching value between pll table and SCK\n", 86968cd394eSKiseokJo __func__); 87068cd394eSKiseokJo return -EINVAL; 87168cd394eSKiseokJo } 87268cd394eSKiseokJo 87368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 87468cd394eSKiseokJo SMA1303_A2_TOP_MAN1, 87568cd394eSKiseokJo SMA1303_PLL_PD_MASK|SMA1303_PLL_REF_CLK_MASK, 87668cd394eSKiseokJo SMA1303_PLL_OPERATION|SMA1303_PLL_SCK, 87768cd394eSKiseokJo NULL); 87868cd394eSKiseokJo } 87968cd394eSKiseokJo 88068cd394eSKiseokJo ret += sma1303_regmap_write(sma1303, 88168cd394eSKiseokJo SMA1303_8B_PLL_POST_N, 88268cd394eSKiseokJo sma1303->pll_matches[i].post_n); 88368cd394eSKiseokJo 88468cd394eSKiseokJo ret += sma1303_regmap_write(sma1303, 88568cd394eSKiseokJo SMA1303_8C_PLL_N, 88668cd394eSKiseokJo sma1303->pll_matches[i].n); 88768cd394eSKiseokJo 88868cd394eSKiseokJo ret += sma1303_regmap_write(sma1303, 88968cd394eSKiseokJo SMA1303_8D_PLL_A_SETTING, 89068cd394eSKiseokJo sma1303->pll_matches[i].vco); 89168cd394eSKiseokJo 89268cd394eSKiseokJo ret += sma1303_regmap_write(sma1303, 89368cd394eSKiseokJo SMA1303_8F_PLL_P_CP, 89468cd394eSKiseokJo sma1303->pll_matches[i].p_cp); 89568cd394eSKiseokJo if (ret < 0) 89668cd394eSKiseokJo return -EINVAL; 89768cd394eSKiseokJo 89868cd394eSKiseokJo return 0; 89968cd394eSKiseokJo } 90068cd394eSKiseokJo 90168cd394eSKiseokJo static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream, 90268cd394eSKiseokJo struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 90368cd394eSKiseokJo { 90468cd394eSKiseokJo struct snd_soc_component *component = dai->component; 90568cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 90668cd394eSKiseokJo unsigned int bclk = 0; 90768cd394eSKiseokJo int ret = 0; 90868cd394eSKiseokJo 90968cd394eSKiseokJo if (sma1303->format == SND_SOC_DAIFMT_DSP_A) 91068cd394eSKiseokJo bclk = params_rate(params) * sma1303->frame_size; 91168cd394eSKiseokJo else 91268cd394eSKiseokJo bclk = params_rate(params) * params_physical_width(params) 91368cd394eSKiseokJo * params_channels(params); 91468cd394eSKiseokJo 91568cd394eSKiseokJo dev_dbg(component->dev, 91668cd394eSKiseokJo "%s : rate = %d : bit size = %d : channel = %d\n", 91768cd394eSKiseokJo __func__, params_rate(params), params_width(params), 91868cd394eSKiseokJo params_channels(params)); 91968cd394eSKiseokJo 92068cd394eSKiseokJo if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 92168cd394eSKiseokJo 92268cd394eSKiseokJo if (sma1303->sys_clk_id == SMA1303_PLL_CLKIN_MCLK 92368cd394eSKiseokJo || sma1303->sys_clk_id == SMA1303_PLL_CLKIN_BCLK) { 92468cd394eSKiseokJo 92568cd394eSKiseokJo if (sma1303->last_bclk != bclk) { 92668cd394eSKiseokJo sma1303_setup_pll(component, bclk); 92768cd394eSKiseokJo sma1303->last_bclk = bclk; 92868cd394eSKiseokJo } 92968cd394eSKiseokJo } 93068cd394eSKiseokJo 93168cd394eSKiseokJo switch (params_rate(params)) { 93268cd394eSKiseokJo case 8000: 93368cd394eSKiseokJo case 12000: 93468cd394eSKiseokJo case 16000: 93568cd394eSKiseokJo case 24000: 93668cd394eSKiseokJo case 32000: 93768cd394eSKiseokJo case 44100: 93868cd394eSKiseokJo case 48000: 93968cd394eSKiseokJo case 96000: 94068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 94168cd394eSKiseokJo SMA1303_A2_TOP_MAN1, 94268cd394eSKiseokJo SMA1303_DAC_DN_CONV_MASK, 94368cd394eSKiseokJo SMA1303_DAC_DN_CONV_DISABLE, 94468cd394eSKiseokJo NULL); 94568cd394eSKiseokJo 94668cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 94768cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 94868cd394eSKiseokJo SMA1303_LEFTPOL_MASK, 94968cd394eSKiseokJo SMA1303_LOW_FIRST_CH, 95068cd394eSKiseokJo NULL); 95168cd394eSKiseokJo break; 95268cd394eSKiseokJo 95368cd394eSKiseokJo case 192000: 95468cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 95568cd394eSKiseokJo SMA1303_A2_TOP_MAN1, 95668cd394eSKiseokJo SMA1303_DAC_DN_CONV_MASK, 95768cd394eSKiseokJo SMA1303_DAC_DN_CONV_ENABLE, 95868cd394eSKiseokJo NULL); 95968cd394eSKiseokJo 96068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 96168cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 96268cd394eSKiseokJo SMA1303_LEFTPOL_MASK, 96368cd394eSKiseokJo SMA1303_HIGH_FIRST_CH, 96468cd394eSKiseokJo NULL); 96568cd394eSKiseokJo break; 96668cd394eSKiseokJo 96768cd394eSKiseokJo default: 96868cd394eSKiseokJo dev_err(component->dev, "%s not support rate : %d\n", 96968cd394eSKiseokJo __func__, params_rate(params)); 97068cd394eSKiseokJo 97168cd394eSKiseokJo return -EINVAL; 97268cd394eSKiseokJo } 97368cd394eSKiseokJo 97468cd394eSKiseokJo } else { 97568cd394eSKiseokJo 97668cd394eSKiseokJo switch (params_format(params)) { 97768cd394eSKiseokJo 97868cd394eSKiseokJo case SNDRV_PCM_FORMAT_S16_LE: 97968cd394eSKiseokJo dev_dbg(component->dev, 98068cd394eSKiseokJo "%s set format SNDRV_PCM_FORMAT_S16_LE\n", 98168cd394eSKiseokJo __func__); 98268cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 98368cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 98468cd394eSKiseokJo SMA1303_SCK_RATE_MASK, 98568cd394eSKiseokJo SMA1303_SCK_32FS, 98668cd394eSKiseokJo NULL); 98768cd394eSKiseokJo break; 98868cd394eSKiseokJo 98968cd394eSKiseokJo case SNDRV_PCM_FORMAT_S24_LE: 99068cd394eSKiseokJo dev_dbg(component->dev, 99168cd394eSKiseokJo "%s set format SNDRV_PCM_FORMAT_S24_LE\n", 99268cd394eSKiseokJo __func__); 99368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 99468cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 99568cd394eSKiseokJo SMA1303_SCK_RATE_MASK, 99668cd394eSKiseokJo SMA1303_SCK_64FS, 99768cd394eSKiseokJo NULL); 99868cd394eSKiseokJo break; 99968cd394eSKiseokJo case SNDRV_PCM_FORMAT_S32_LE: 100068cd394eSKiseokJo dev_dbg(component->dev, 100168cd394eSKiseokJo "%s set format SNDRV_PCM_FORMAT_S32_LE\n", 100268cd394eSKiseokJo __func__); 100368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 100468cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 100568cd394eSKiseokJo SMA1303_SCK_RATE_MASK, 100668cd394eSKiseokJo SMA1303_SCK_64FS, 100768cd394eSKiseokJo NULL); 100868cd394eSKiseokJo break; 100968cd394eSKiseokJo default: 101068cd394eSKiseokJo dev_err(component->dev, 101168cd394eSKiseokJo "%s not support data bit : %d\n", __func__, 101268cd394eSKiseokJo params_format(params)); 101368cd394eSKiseokJo return -EINVAL; 101468cd394eSKiseokJo } 101568cd394eSKiseokJo } 101668cd394eSKiseokJo 101768cd394eSKiseokJo switch (sma1303->format) { 101868cd394eSKiseokJo case SND_SOC_DAIFMT_I2S: 101968cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 102068cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 102168cd394eSKiseokJo SMA1303_I2S_MODE_MASK, 102268cd394eSKiseokJo SMA1303_STANDARD_I2S, 102368cd394eSKiseokJo NULL); 102468cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 102568cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 102668cd394eSKiseokJo SMA1303_O_FORMAT_MASK, 102768cd394eSKiseokJo SMA1303_O_FMT_I2S, 102868cd394eSKiseokJo NULL); 102968cd394eSKiseokJo break; 103068cd394eSKiseokJo case SND_SOC_DAIFMT_LEFT_J: 103168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 103268cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 103368cd394eSKiseokJo SMA1303_I2S_MODE_MASK, 103468cd394eSKiseokJo SMA1303_LJ, 103568cd394eSKiseokJo NULL); 103668cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 103768cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 103868cd394eSKiseokJo SMA1303_O_FORMAT_MASK, 103968cd394eSKiseokJo SMA1303_O_FMT_LJ, 104068cd394eSKiseokJo NULL); 104168cd394eSKiseokJo break; 104268cd394eSKiseokJo case SND_SOC_DAIFMT_RIGHT_J: 104368cd394eSKiseokJo switch (params_width(params)) { 104468cd394eSKiseokJo case 16: 104568cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 104668cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 104768cd394eSKiseokJo SMA1303_I2S_MODE_MASK, 104868cd394eSKiseokJo SMA1303_RJ_16BIT, 104968cd394eSKiseokJo NULL); 105068cd394eSKiseokJo break; 105168cd394eSKiseokJo case 24: 105268cd394eSKiseokJo case 32: 105368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 105468cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 105568cd394eSKiseokJo SMA1303_I2S_MODE_MASK, 105668cd394eSKiseokJo SMA1303_RJ_24BIT, 105768cd394eSKiseokJo NULL); 105868cd394eSKiseokJo break; 105968cd394eSKiseokJo } 106068cd394eSKiseokJo break; 106168cd394eSKiseokJo case SND_SOC_DAIFMT_DSP_A: 106268cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 106368cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 106468cd394eSKiseokJo SMA1303_I2S_MODE_MASK, 106568cd394eSKiseokJo SMA1303_STANDARD_I2S, 106668cd394eSKiseokJo NULL); 106768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 106868cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 106968cd394eSKiseokJo SMA1303_O_FORMAT_MASK, 107068cd394eSKiseokJo SMA1303_O_FMT_TDM, 107168cd394eSKiseokJo NULL); 107268cd394eSKiseokJo break; 107368cd394eSKiseokJo } 107468cd394eSKiseokJo 107568cd394eSKiseokJo switch (params_width(params)) { 107668cd394eSKiseokJo case 16: 107768cd394eSKiseokJo case 24: 107868cd394eSKiseokJo case 32: 107968cd394eSKiseokJo break; 108068cd394eSKiseokJo default: 108168cd394eSKiseokJo dev_err(component->dev, 108268cd394eSKiseokJo "%s not support data bit : %d\n", __func__, 108368cd394eSKiseokJo params_format(params)); 108468cd394eSKiseokJo return -EINVAL; 108568cd394eSKiseokJo } 108668cd394eSKiseokJo if (ret < 0) 108768cd394eSKiseokJo return -EINVAL; 108868cd394eSKiseokJo 108968cd394eSKiseokJo return 0; 109068cd394eSKiseokJo } 109168cd394eSKiseokJo 109268cd394eSKiseokJo static int sma1303_dai_set_sysclk_amp(struct snd_soc_dai *dai, 109368cd394eSKiseokJo int clk_id, unsigned int freq, int dir) 109468cd394eSKiseokJo { 109568cd394eSKiseokJo struct snd_soc_component *component = dai->component; 109668cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 109768cd394eSKiseokJo 109868cd394eSKiseokJo switch (clk_id) { 109968cd394eSKiseokJo case SMA1303_EXTERNAL_CLOCK_19_2: 110068cd394eSKiseokJo break; 110168cd394eSKiseokJo case SMA1303_EXTERNAL_CLOCK_24_576: 110268cd394eSKiseokJo break; 110368cd394eSKiseokJo case SMA1303_PLL_CLKIN_MCLK: 110468cd394eSKiseokJo break; 110568cd394eSKiseokJo case SMA1303_PLL_CLKIN_BCLK: 110668cd394eSKiseokJo break; 110768cd394eSKiseokJo default: 110868cd394eSKiseokJo dev_err(component->dev, "Invalid clk id: %d\n", clk_id); 110968cd394eSKiseokJo return -EINVAL; 111068cd394eSKiseokJo } 111168cd394eSKiseokJo sma1303->sys_clk_id = clk_id; 111268cd394eSKiseokJo return 0; 111368cd394eSKiseokJo } 111468cd394eSKiseokJo 111568cd394eSKiseokJo static int sma1303_dai_mute(struct snd_soc_dai *dai, int mute, int stream) 111668cd394eSKiseokJo { 111768cd394eSKiseokJo struct snd_soc_component *component = dai->component; 111868cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 111968cd394eSKiseokJo int ret = 0; 112068cd394eSKiseokJo 112168cd394eSKiseokJo if (stream == SNDRV_PCM_STREAM_CAPTURE) 112268cd394eSKiseokJo return ret; 112368cd394eSKiseokJo 112468cd394eSKiseokJo if (mute) { 112568cd394eSKiseokJo dev_dbg(component->dev, "%s : %s\n", __func__, "MUTE"); 112668cd394eSKiseokJo 112768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 112868cd394eSKiseokJo SMA1303_0E_MUTE_VOL_CTRL, 112968cd394eSKiseokJo SMA1303_SPK_MUTE_MASK, 113068cd394eSKiseokJo SMA1303_SPK_MUTE, 113168cd394eSKiseokJo NULL); 113268cd394eSKiseokJo 113368cd394eSKiseokJo /* Need to wait time for mute slope */ 113468cd394eSKiseokJo msleep(55); 113568cd394eSKiseokJo } else { 113668cd394eSKiseokJo if (!sma1303->force_mute_status) { 113768cd394eSKiseokJo dev_dbg(component->dev, "%s : %s\n", 113868cd394eSKiseokJo __func__, "UNMUTE"); 113968cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 114068cd394eSKiseokJo SMA1303_0E_MUTE_VOL_CTRL, 114168cd394eSKiseokJo SMA1303_SPK_MUTE_MASK, 114268cd394eSKiseokJo SMA1303_SPK_UNMUTE, 114368cd394eSKiseokJo NULL); 114468cd394eSKiseokJo } else { 114568cd394eSKiseokJo dev_dbg(sma1303->dev, 114668cd394eSKiseokJo "%s : FORCE MUTE!!!\n", __func__); 114768cd394eSKiseokJo } 114868cd394eSKiseokJo } 114968cd394eSKiseokJo 115068cd394eSKiseokJo if (ret < 0) 115168cd394eSKiseokJo return -EINVAL; 115268cd394eSKiseokJo return 0; 115368cd394eSKiseokJo } 115468cd394eSKiseokJo 115568cd394eSKiseokJo static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai, 115668cd394eSKiseokJo unsigned int fmt) 115768cd394eSKiseokJo { 115868cd394eSKiseokJo struct snd_soc_component *component = dai->component; 115968cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 116068cd394eSKiseokJo int ret = 0; 116168cd394eSKiseokJo 116268cd394eSKiseokJo switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 116368cd394eSKiseokJo 116468cd394eSKiseokJo case SND_SOC_DAIFMT_CBC_CFC: 116568cd394eSKiseokJo dev_dbg(component->dev, 116668cd394eSKiseokJo "%s : %s\n", __func__, "I2S/TDM Device mode"); 116768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 116868cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 116968cd394eSKiseokJo SMA1303_CONTROLLER_DEVICE_MASK, 117068cd394eSKiseokJo SMA1303_DEVICE_MODE, 117168cd394eSKiseokJo NULL); 117268cd394eSKiseokJo break; 117368cd394eSKiseokJo 117468cd394eSKiseokJo case SND_SOC_DAIFMT_CBP_CFP: 117568cd394eSKiseokJo dev_dbg(component->dev, 117668cd394eSKiseokJo "%s : %s\n", __func__, "I2S/TDM Controller mode"); 117768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 117868cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 117968cd394eSKiseokJo SMA1303_CONTROLLER_DEVICE_MASK, 118068cd394eSKiseokJo SMA1303_CONTROLLER_MODE, 118168cd394eSKiseokJo NULL); 118268cd394eSKiseokJo break; 118368cd394eSKiseokJo 118468cd394eSKiseokJo default: 118568cd394eSKiseokJo dev_err(component->dev, 118668cd394eSKiseokJo "Unsupported Controller/Device : 0x%x\n", fmt); 118768cd394eSKiseokJo return -EINVAL; 118868cd394eSKiseokJo } 118968cd394eSKiseokJo 119068cd394eSKiseokJo switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 119168cd394eSKiseokJo 119268cd394eSKiseokJo case SND_SOC_DAIFMT_I2S: 119368cd394eSKiseokJo case SND_SOC_DAIFMT_RIGHT_J: 119468cd394eSKiseokJo case SND_SOC_DAIFMT_LEFT_J: 119568cd394eSKiseokJo case SND_SOC_DAIFMT_DSP_A: 119668cd394eSKiseokJo case SND_SOC_DAIFMT_DSP_B: 119768cd394eSKiseokJo sma1303->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 119868cd394eSKiseokJo break; 119968cd394eSKiseokJo default: 120068cd394eSKiseokJo dev_err(component->dev, 120168cd394eSKiseokJo "Unsupported Audio Interface Format : 0x%x\n", fmt); 120268cd394eSKiseokJo return -EINVAL; 120368cd394eSKiseokJo } 120468cd394eSKiseokJo 120568cd394eSKiseokJo switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 120668cd394eSKiseokJo 120768cd394eSKiseokJo case SND_SOC_DAIFMT_IB_NF: 120868cd394eSKiseokJo dev_dbg(component->dev, "%s : %s\n", 120968cd394eSKiseokJo __func__, "Invert BCLK + Normal Frame"); 121068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 121168cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 121268cd394eSKiseokJo SMA1303_SCK_RISING_MASK, 121368cd394eSKiseokJo SMA1303_SCK_RISING_EDGE, 121468cd394eSKiseokJo NULL); 121568cd394eSKiseokJo break; 121668cd394eSKiseokJo case SND_SOC_DAIFMT_IB_IF: 121768cd394eSKiseokJo dev_dbg(component->dev, "%s : %s\n", 121868cd394eSKiseokJo __func__, "Invert BCLK + Invert Frame"); 121968cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 122068cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 122168cd394eSKiseokJo SMA1303_LEFTPOL_MASK|SMA1303_SCK_RISING_MASK, 122268cd394eSKiseokJo SMA1303_HIGH_FIRST_CH|SMA1303_SCK_RISING_EDGE, 122368cd394eSKiseokJo NULL); 122468cd394eSKiseokJo break; 122568cd394eSKiseokJo case SND_SOC_DAIFMT_NB_IF: 122668cd394eSKiseokJo dev_dbg(component->dev, "%s : %s\n", 122768cd394eSKiseokJo __func__, "Normal BCLK + Invert Frame"); 122868cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 122968cd394eSKiseokJo SMA1303_01_INPUT1_CTRL1, 123068cd394eSKiseokJo SMA1303_LEFTPOL_MASK, 123168cd394eSKiseokJo SMA1303_HIGH_FIRST_CH, 123268cd394eSKiseokJo NULL); 123368cd394eSKiseokJo break; 123468cd394eSKiseokJo case SND_SOC_DAIFMT_NB_NF: 123568cd394eSKiseokJo dev_dbg(component->dev, "%s : %s\n", 123668cd394eSKiseokJo __func__, "Normal BCLK + Normal Frame"); 123768cd394eSKiseokJo break; 123868cd394eSKiseokJo default: 123968cd394eSKiseokJo dev_err(component->dev, 124068cd394eSKiseokJo "Unsupported Bit & Frameclock : 0x%x\n", fmt); 124168cd394eSKiseokJo return -EINVAL; 124268cd394eSKiseokJo } 124368cd394eSKiseokJo 124468cd394eSKiseokJo if (ret < 0) 124568cd394eSKiseokJo return -EINVAL; 124668cd394eSKiseokJo return 0; 124768cd394eSKiseokJo } 124868cd394eSKiseokJo 124968cd394eSKiseokJo static int sma1303_dai_set_tdm_slot(struct snd_soc_dai *dai, 125068cd394eSKiseokJo unsigned int tx_mask, unsigned int rx_mask, 125168cd394eSKiseokJo int slots, int slot_width) 125268cd394eSKiseokJo { 125368cd394eSKiseokJo struct snd_soc_component *component = dai->component; 125468cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 125568cd394eSKiseokJo int ret = 0; 125668cd394eSKiseokJo 125768cd394eSKiseokJo dev_dbg(component->dev, "%s : slots = %d, slot_width - %d\n", 125868cd394eSKiseokJo __func__, slots, slot_width); 125968cd394eSKiseokJo 126068cd394eSKiseokJo sma1303->frame_size = slot_width * slots; 126168cd394eSKiseokJo 126268cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 126368cd394eSKiseokJo SMA1303_A4_TOP_MAN3, 126468cd394eSKiseokJo SMA1303_O_FORMAT_MASK, 126568cd394eSKiseokJo SMA1303_O_FMT_TDM, 126668cd394eSKiseokJo NULL); 126768cd394eSKiseokJo 126868cd394eSKiseokJo switch (slot_width) { 126968cd394eSKiseokJo case 16: 127068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 127168cd394eSKiseokJo SMA1303_A6_TDM2, 127268cd394eSKiseokJo SMA1303_TDM_DL_MASK, 127368cd394eSKiseokJo SMA1303_TDM_DL_16, 127468cd394eSKiseokJo NULL); 127568cd394eSKiseokJo break; 127668cd394eSKiseokJo case 32: 127768cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 127868cd394eSKiseokJo SMA1303_A6_TDM2, 127968cd394eSKiseokJo SMA1303_TDM_DL_MASK, 128068cd394eSKiseokJo SMA1303_TDM_DL_32, 128168cd394eSKiseokJo NULL); 128268cd394eSKiseokJo break; 128368cd394eSKiseokJo default: 128468cd394eSKiseokJo dev_err(component->dev, "%s not support TDM %d slot_width\n", 128568cd394eSKiseokJo __func__, slot_width); 128668cd394eSKiseokJo break; 128768cd394eSKiseokJo } 128868cd394eSKiseokJo 128968cd394eSKiseokJo switch (slots) { 129068cd394eSKiseokJo case 4: 129168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 129268cd394eSKiseokJo SMA1303_A6_TDM2, 129368cd394eSKiseokJo SMA1303_TDM_N_SLOT_MASK, 129468cd394eSKiseokJo SMA1303_TDM_N_SLOT_4, 129568cd394eSKiseokJo NULL); 129668cd394eSKiseokJo break; 129768cd394eSKiseokJo case 8: 129868cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 129968cd394eSKiseokJo SMA1303_A6_TDM2, 130068cd394eSKiseokJo SMA1303_TDM_N_SLOT_MASK, 130168cd394eSKiseokJo SMA1303_TDM_N_SLOT_8, 130268cd394eSKiseokJo NULL); 130368cd394eSKiseokJo break; 130468cd394eSKiseokJo default: 130568cd394eSKiseokJo dev_err(component->dev, "%s not support TDM %d slots\n", 130668cd394eSKiseokJo __func__, slots); 130768cd394eSKiseokJo break; 130868cd394eSKiseokJo } 130968cd394eSKiseokJo 131068cd394eSKiseokJo if (sma1303->tdm_slot_rx < slots) 131168cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 131268cd394eSKiseokJo SMA1303_A5_TDM1, 131368cd394eSKiseokJo SMA1303_TDM_SLOT1_RX_POS_MASK, 131468cd394eSKiseokJo (sma1303->tdm_slot_rx) << 3, 131568cd394eSKiseokJo NULL); 131668cd394eSKiseokJo else 131768cd394eSKiseokJo dev_err(component->dev, "%s Incorrect tdm-slot-rx %d set\n", 131868cd394eSKiseokJo __func__, sma1303->tdm_slot_rx); 131968cd394eSKiseokJo 132068cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 132168cd394eSKiseokJo SMA1303_A5_TDM1, 132268cd394eSKiseokJo SMA1303_TDM_CLK_POL_MASK, 132368cd394eSKiseokJo SMA1303_TDM_CLK_POL_RISE, 132468cd394eSKiseokJo NULL); 132568cd394eSKiseokJo 132668cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 132768cd394eSKiseokJo SMA1303_A5_TDM1, 132868cd394eSKiseokJo SMA1303_TDM_TX_MODE_MASK, 132968cd394eSKiseokJo SMA1303_TDM_TX_MONO, 133068cd394eSKiseokJo NULL); 133168cd394eSKiseokJo 133268cd394eSKiseokJo if (sma1303->tdm_slot_tx < slots) 133368cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 133468cd394eSKiseokJo SMA1303_A6_TDM2, 133568cd394eSKiseokJo SMA1303_TDM_SLOT1_TX_POS_MASK, 133668cd394eSKiseokJo (sma1303->tdm_slot_tx) << 3, 133768cd394eSKiseokJo NULL); 133868cd394eSKiseokJo else 133968cd394eSKiseokJo dev_err(component->dev, "%s Incorrect tdm-slot-tx %d set\n", 134068cd394eSKiseokJo __func__, sma1303->tdm_slot_tx); 134168cd394eSKiseokJo 134268cd394eSKiseokJo if (ret < 0) 134368cd394eSKiseokJo return -EINVAL; 134468cd394eSKiseokJo return 0; 134568cd394eSKiseokJo } 134668cd394eSKiseokJo 134768cd394eSKiseokJo static const struct snd_soc_dai_ops sma1303_dai_ops_amp = { 134868cd394eSKiseokJo .set_sysclk = sma1303_dai_set_sysclk_amp, 134968cd394eSKiseokJo .set_fmt = sma1303_dai_set_fmt_amp, 135068cd394eSKiseokJo .hw_params = sma1303_dai_hw_params_amp, 135168cd394eSKiseokJo .mute_stream = sma1303_dai_mute, 135268cd394eSKiseokJo .set_tdm_slot = sma1303_dai_set_tdm_slot, 135368cd394eSKiseokJo }; 135468cd394eSKiseokJo 135568cd394eSKiseokJo #define SMA1303_RATES SNDRV_PCM_RATE_8000_192000 135668cd394eSKiseokJo #define SMA1303_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ 135768cd394eSKiseokJo SNDRV_PCM_FMTBIT_S32_LE) 135868cd394eSKiseokJo 135968cd394eSKiseokJo static struct snd_soc_dai_driver sma1303_dai[] = { 136068cd394eSKiseokJo { 136168cd394eSKiseokJo .name = "sma1303-amplifier", 136268cd394eSKiseokJo .id = 0, 136368cd394eSKiseokJo .playback = { 136468cd394eSKiseokJo .stream_name = "Playback", 136568cd394eSKiseokJo .channels_min = 1, 136668cd394eSKiseokJo .channels_max = 2, 136768cd394eSKiseokJo .rates = SMA1303_RATES, 136868cd394eSKiseokJo .formats = SMA1303_FORMATS, 136968cd394eSKiseokJo }, 137068cd394eSKiseokJo .capture = { 137168cd394eSKiseokJo .stream_name = "Capture", 137268cd394eSKiseokJo .channels_min = 1, 137368cd394eSKiseokJo .channels_max = 2, 137468cd394eSKiseokJo .rates = SMA1303_RATES, 137568cd394eSKiseokJo .formats = SMA1303_FORMATS, 137668cd394eSKiseokJo }, 137768cd394eSKiseokJo .ops = &sma1303_dai_ops_amp, 137868cd394eSKiseokJo }, 137968cd394eSKiseokJo }; 138068cd394eSKiseokJo 138168cd394eSKiseokJo static void sma1303_check_fault_worker(struct work_struct *work) 138268cd394eSKiseokJo { 138368cd394eSKiseokJo struct sma1303_priv *sma1303 = 138468cd394eSKiseokJo container_of(work, struct sma1303_priv, check_fault_work.work); 138568cd394eSKiseokJo int ret = 0; 138668cd394eSKiseokJo unsigned int over_temp, ocp_val, uvlo_val; 138768cd394eSKiseokJo 138868cd394eSKiseokJo if (sma1303->tsdw_cnt) 138968cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, 139068cd394eSKiseokJo SMA1303_0A_SPK_VOL, &sma1303->cur_vol); 139168cd394eSKiseokJo else 139268cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, 139368cd394eSKiseokJo SMA1303_0A_SPK_VOL, &sma1303->init_vol); 139468cd394eSKiseokJo 139568cd394eSKiseokJo if (ret != 0) { 139668cd394eSKiseokJo dev_err(sma1303->dev, 139768cd394eSKiseokJo "failed to read SMA1303_0A_SPK_VOL : %d\n", ret); 139868cd394eSKiseokJo return; 139968cd394eSKiseokJo } 140068cd394eSKiseokJo 140168cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, SMA1303_FA_STATUS1, &over_temp); 140268cd394eSKiseokJo if (ret != 0) { 140368cd394eSKiseokJo dev_err(sma1303->dev, 140468cd394eSKiseokJo "failed to read SMA1303_FA_STATUS1 : %d\n", ret); 140568cd394eSKiseokJo return; 140668cd394eSKiseokJo } 140768cd394eSKiseokJo 140868cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, &ocp_val); 140968cd394eSKiseokJo if (ret != 0) { 141068cd394eSKiseokJo dev_err(sma1303->dev, 141168cd394eSKiseokJo "failed to read SMA1303_FB_STATUS2 : %d\n", ret); 141268cd394eSKiseokJo return; 141368cd394eSKiseokJo } 141468cd394eSKiseokJo 141568cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, &uvlo_val); 141668cd394eSKiseokJo if (ret != 0) { 141768cd394eSKiseokJo dev_err(sma1303->dev, 141868cd394eSKiseokJo "failed to read SMA1303_FF_DEVICE_INDEX : %d\n", ret); 141968cd394eSKiseokJo return; 142068cd394eSKiseokJo } 142168cd394eSKiseokJo 142268cd394eSKiseokJo if (~over_temp & SMA1303_OT1_OK_STATUS) { 142368cd394eSKiseokJo dev_crit(sma1303->dev, 142468cd394eSKiseokJo "%s : OT1(Over Temperature Level 1)\n", __func__); 142568cd394eSKiseokJo 142668cd394eSKiseokJo if ((sma1303->cur_vol + 6) <= 0xFF) 142768cd394eSKiseokJo sma1303_regmap_write(sma1303, 142868cd394eSKiseokJo SMA1303_0A_SPK_VOL, sma1303->cur_vol + 6); 142968cd394eSKiseokJo 143068cd394eSKiseokJo sma1303->tsdw_cnt++; 143168cd394eSKiseokJo } else if (sma1303->tsdw_cnt) { 143268cd394eSKiseokJo sma1303_regmap_write(sma1303, 143368cd394eSKiseokJo SMA1303_0A_SPK_VOL, sma1303->init_vol); 143468cd394eSKiseokJo sma1303->tsdw_cnt = 0; 143568cd394eSKiseokJo sma1303->cur_vol = sma1303->init_vol; 143668cd394eSKiseokJo } 143768cd394eSKiseokJo 143868cd394eSKiseokJo if (~over_temp & SMA1303_OT2_OK_STATUS) { 143968cd394eSKiseokJo dev_crit(sma1303->dev, 144068cd394eSKiseokJo "%s : OT2(Over Temperature Level 2)\n", __func__); 144168cd394eSKiseokJo } 144268cd394eSKiseokJo if (ocp_val & SMA1303_OCP_SPK_STATUS) { 144368cd394eSKiseokJo dev_crit(sma1303->dev, 144468cd394eSKiseokJo "%s : OCP_SPK(Over Current Protect SPK)\n", __func__); 144568cd394eSKiseokJo } 144668cd394eSKiseokJo if (ocp_val & SMA1303_OCP_BST_STATUS) { 144768cd394eSKiseokJo dev_crit(sma1303->dev, 144868cd394eSKiseokJo "%s : OCP_BST(Over Current Protect Boost)\n", __func__); 144968cd394eSKiseokJo } 145068cd394eSKiseokJo if ((ocp_val & SMA1303_CLK_MON_STATUS) && (sma1303->amp_power_status)) { 145168cd394eSKiseokJo dev_crit(sma1303->dev, 145268cd394eSKiseokJo "%s : CLK_FAULT(No clock input)\n", __func__); 145368cd394eSKiseokJo } 145468cd394eSKiseokJo if (uvlo_val & SMA1303_UVLO_BST_STATUS) { 145568cd394eSKiseokJo dev_crit(sma1303->dev, 145668cd394eSKiseokJo "%s : UVLO(Under Voltage Lock Out)\n", __func__); 145768cd394eSKiseokJo } 145868cd394eSKiseokJo 145968cd394eSKiseokJo if ((over_temp != sma1303->last_over_temp) || 146068cd394eSKiseokJo (ocp_val != sma1303->last_ocp_val)) { 146168cd394eSKiseokJo 146268cd394eSKiseokJo dev_crit(sma1303->dev, "Please check AMP status"); 146368cd394eSKiseokJo dev_dbg(sma1303->dev, "STATUS1=0x%02X : STATUS2=0x%02X\n", 146468cd394eSKiseokJo over_temp, ocp_val); 146568cd394eSKiseokJo sma1303->last_over_temp = over_temp; 146668cd394eSKiseokJo sma1303->last_ocp_val = ocp_val; 146768cd394eSKiseokJo } 146868cd394eSKiseokJo 146968cd394eSKiseokJo if (sma1303->check_fault_status) { 147068cd394eSKiseokJo if (sma1303->check_fault_period > 0) 147168cd394eSKiseokJo queue_delayed_work(system_freezable_wq, 147268cd394eSKiseokJo &sma1303->check_fault_work, 147368cd394eSKiseokJo sma1303->check_fault_period * HZ); 147468cd394eSKiseokJo else 147568cd394eSKiseokJo queue_delayed_work(system_freezable_wq, 147668cd394eSKiseokJo &sma1303->check_fault_work, 147768cd394eSKiseokJo CHECK_PERIOD_TIME * HZ); 147868cd394eSKiseokJo } 147968cd394eSKiseokJo 148068cd394eSKiseokJo if (!(~over_temp & SMA1303_OT1_OK_STATUS) 148168cd394eSKiseokJo && !(~over_temp & SMA1303_OT2_OK_STATUS) 148268cd394eSKiseokJo && !(ocp_val & SMA1303_OCP_SPK_STATUS) 148368cd394eSKiseokJo && !(ocp_val & SMA1303_OCP_BST_STATUS) 148468cd394eSKiseokJo && !(ocp_val & SMA1303_CLK_MON_STATUS) 148568cd394eSKiseokJo && !(uvlo_val & SMA1303_UVLO_BST_STATUS)) { 148668cd394eSKiseokJo } 148768cd394eSKiseokJo } 148868cd394eSKiseokJo 148968cd394eSKiseokJo static int sma1303_probe(struct snd_soc_component *component) 149068cd394eSKiseokJo { 149168cd394eSKiseokJo struct snd_soc_dapm_context *dapm = 149268cd394eSKiseokJo snd_soc_component_get_dapm(component); 149368cd394eSKiseokJo 149468cd394eSKiseokJo snd_soc_dapm_sync(dapm); 149568cd394eSKiseokJo 149668cd394eSKiseokJo return 0; 149768cd394eSKiseokJo } 149868cd394eSKiseokJo 149968cd394eSKiseokJo static void sma1303_remove(struct snd_soc_component *component) 150068cd394eSKiseokJo { 150168cd394eSKiseokJo struct sma1303_priv *sma1303 = snd_soc_component_get_drvdata(component); 150268cd394eSKiseokJo 150368cd394eSKiseokJo cancel_delayed_work_sync(&sma1303->check_fault_work); 150468cd394eSKiseokJo } 150568cd394eSKiseokJo 150668cd394eSKiseokJo static const struct snd_soc_component_driver sma1303_component = { 150768cd394eSKiseokJo .probe = sma1303_probe, 150868cd394eSKiseokJo .remove = sma1303_remove, 150968cd394eSKiseokJo .controls = sma1303_snd_controls, 151068cd394eSKiseokJo .num_controls = ARRAY_SIZE(sma1303_snd_controls), 151168cd394eSKiseokJo .dapm_widgets = sma1303_dapm_widgets, 151268cd394eSKiseokJo .num_dapm_widgets = ARRAY_SIZE(sma1303_dapm_widgets), 151368cd394eSKiseokJo .dapm_routes = sma1303_audio_map, 151468cd394eSKiseokJo .num_dapm_routes = ARRAY_SIZE(sma1303_audio_map), 151568cd394eSKiseokJo }; 151668cd394eSKiseokJo 151768cd394eSKiseokJo const struct regmap_config sma_i2c_regmap = { 151868cd394eSKiseokJo .reg_bits = 8, 151968cd394eSKiseokJo .val_bits = 8, 152068cd394eSKiseokJo 152168cd394eSKiseokJo .max_register = SMA1303_FF_DEVICE_INDEX, 152268cd394eSKiseokJo .readable_reg = sma1303_readable_register, 152368cd394eSKiseokJo .writeable_reg = sma1303_writeable_register, 152468cd394eSKiseokJo .volatile_reg = sma1303_volatile_register, 152568cd394eSKiseokJo 152668cd394eSKiseokJo .cache_type = REGCACHE_NONE, 152768cd394eSKiseokJo .reg_defaults = sma1303_reg_def, 152868cd394eSKiseokJo .num_reg_defaults = ARRAY_SIZE(sma1303_reg_def), 152968cd394eSKiseokJo }; 153068cd394eSKiseokJo 153168cd394eSKiseokJo static ssize_t check_fault_period_show(struct device *dev, 153268cd394eSKiseokJo struct device_attribute *devattr, char *buf) 153368cd394eSKiseokJo { 153468cd394eSKiseokJo struct sma1303_priv *sma1303 = dev_get_drvdata(dev); 153568cd394eSKiseokJo 153668cd394eSKiseokJo return sysfs_emit(buf, "%ld\n", sma1303->check_fault_period); 153768cd394eSKiseokJo } 153868cd394eSKiseokJo 153968cd394eSKiseokJo static ssize_t check_fault_period_store(struct device *dev, 154068cd394eSKiseokJo struct device_attribute *devattr, const char *buf, size_t count) 154168cd394eSKiseokJo { 154268cd394eSKiseokJo struct sma1303_priv *sma1303 = dev_get_drvdata(dev); 154368cd394eSKiseokJo int ret; 154468cd394eSKiseokJo 154568cd394eSKiseokJo ret = kstrtol(buf, 10, &sma1303->check_fault_period); 154668cd394eSKiseokJo 154768cd394eSKiseokJo if (ret) 154868cd394eSKiseokJo return -EINVAL; 154968cd394eSKiseokJo 155068cd394eSKiseokJo return (ssize_t)count; 155168cd394eSKiseokJo } 155268cd394eSKiseokJo 155368cd394eSKiseokJo static DEVICE_ATTR_RW(check_fault_period); 155468cd394eSKiseokJo 155568cd394eSKiseokJo static ssize_t check_fault_status_show(struct device *dev, 155668cd394eSKiseokJo struct device_attribute *devattr, char *buf) 155768cd394eSKiseokJo { 155868cd394eSKiseokJo struct sma1303_priv *sma1303 = dev_get_drvdata(dev); 155968cd394eSKiseokJo 156068cd394eSKiseokJo return sysfs_emit(buf, "%ld\n", sma1303->check_fault_status); 156168cd394eSKiseokJo } 156268cd394eSKiseokJo 156368cd394eSKiseokJo static ssize_t check_fault_status_store(struct device *dev, 156468cd394eSKiseokJo struct device_attribute *devattr, const char *buf, size_t count) 156568cd394eSKiseokJo { 156668cd394eSKiseokJo struct sma1303_priv *sma1303 = dev_get_drvdata(dev); 156768cd394eSKiseokJo int ret; 156868cd394eSKiseokJo 156968cd394eSKiseokJo ret = kstrtol(buf, 10, &sma1303->check_fault_status); 157068cd394eSKiseokJo 157168cd394eSKiseokJo if (ret) 157268cd394eSKiseokJo return -EINVAL; 157368cd394eSKiseokJo 157468cd394eSKiseokJo if (sma1303->check_fault_status) { 157568cd394eSKiseokJo if (sma1303->check_fault_period > 0) 157668cd394eSKiseokJo queue_delayed_work(system_freezable_wq, 157768cd394eSKiseokJo &sma1303->check_fault_work, 157868cd394eSKiseokJo sma1303->check_fault_period * HZ); 157968cd394eSKiseokJo else 158068cd394eSKiseokJo queue_delayed_work(system_freezable_wq, 158168cd394eSKiseokJo &sma1303->check_fault_work, 158268cd394eSKiseokJo CHECK_PERIOD_TIME * HZ); 158368cd394eSKiseokJo } 158468cd394eSKiseokJo 158568cd394eSKiseokJo return (ssize_t)count; 158668cd394eSKiseokJo } 158768cd394eSKiseokJo 158868cd394eSKiseokJo static DEVICE_ATTR_RW(check_fault_status); 158968cd394eSKiseokJo 159068cd394eSKiseokJo static struct attribute *sma1303_attr[] = { 159168cd394eSKiseokJo &dev_attr_check_fault_period.attr, 159268cd394eSKiseokJo &dev_attr_check_fault_status.attr, 159368cd394eSKiseokJo NULL, 159468cd394eSKiseokJo }; 159568cd394eSKiseokJo 159668cd394eSKiseokJo static struct attribute_group sma1303_attr_group = { 159768cd394eSKiseokJo .attrs = sma1303_attr, 159868cd394eSKiseokJo }; 159968cd394eSKiseokJo 160030cf0025SUwe Kleine-König static int sma1303_i2c_probe(struct i2c_client *client) 160168cd394eSKiseokJo { 160268cd394eSKiseokJo struct sma1303_priv *sma1303; 160368cd394eSKiseokJo struct device_node *np = client->dev.of_node; 160468cd394eSKiseokJo int ret, i = 0; 160568cd394eSKiseokJo u32 value = 0; 160668cd394eSKiseokJo unsigned int device_info, status, otp_stat; 160768cd394eSKiseokJo 160868cd394eSKiseokJo sma1303 = devm_kzalloc(&client->dev, 160968cd394eSKiseokJo sizeof(struct sma1303_priv), GFP_KERNEL); 161068cd394eSKiseokJo if (!sma1303) 161168cd394eSKiseokJo return -ENOMEM; 161268cd394eSKiseokJo sma1303->dev = &client->dev; 161368cd394eSKiseokJo 161468cd394eSKiseokJo sma1303->regmap = devm_regmap_init_i2c(client, &sma_i2c_regmap); 161568cd394eSKiseokJo if (IS_ERR(sma1303->regmap)) { 161668cd394eSKiseokJo ret = PTR_ERR(sma1303->regmap); 161768cd394eSKiseokJo dev_err(&client->dev, 161868cd394eSKiseokJo "Failed to allocate register map: %d\n", ret); 161968cd394eSKiseokJo 162068cd394eSKiseokJo return ret; 162168cd394eSKiseokJo } 162268cd394eSKiseokJo 162368cd394eSKiseokJo if (np) { 162468cd394eSKiseokJo if (!of_property_read_u32(np, "tdm-slot-rx", &value)) { 162568cd394eSKiseokJo dev_dbg(&client->dev, 162668cd394eSKiseokJo "tdm slot rx is '%d' from DT\n", value); 162768cd394eSKiseokJo sma1303->tdm_slot_rx = value; 162868cd394eSKiseokJo } else { 162968cd394eSKiseokJo dev_dbg(&client->dev, 163068cd394eSKiseokJo "Default setting of tdm slot rx is '0'\n"); 163168cd394eSKiseokJo sma1303->tdm_slot_rx = 0; 163268cd394eSKiseokJo } 163368cd394eSKiseokJo if (!of_property_read_u32(np, "tdm-slot-tx", &value)) { 163468cd394eSKiseokJo dev_dbg(&client->dev, 163568cd394eSKiseokJo "tdm slot tx is '%u' from DT\n", value); 163668cd394eSKiseokJo sma1303->tdm_slot_tx = value; 163768cd394eSKiseokJo } else { 163868cd394eSKiseokJo dev_dbg(&client->dev, 163968cd394eSKiseokJo "Default setting of tdm slot tx is '0'\n"); 164068cd394eSKiseokJo sma1303->tdm_slot_tx = 0; 164168cd394eSKiseokJo } 164268cd394eSKiseokJo if (!of_property_read_u32(np, "sys-clk-id", &value)) { 164368cd394eSKiseokJo switch (value) { 164468cd394eSKiseokJo case SMA1303_EXTERNAL_CLOCK_19_2: 164568cd394eSKiseokJo case SMA1303_EXTERNAL_CLOCK_24_576: 164668cd394eSKiseokJo case SMA1303_PLL_CLKIN_MCLK: 164768cd394eSKiseokJo dev_dbg(&client->dev, "MCLK is not supported\n"); 164868cd394eSKiseokJo break; 164968cd394eSKiseokJo case SMA1303_PLL_CLKIN_BCLK: 165068cd394eSKiseokJo dev_dbg(&client->dev, 165168cd394eSKiseokJo "Take an BCLK(SCK) and covert it to an internal PLL for use\n"); 165268cd394eSKiseokJo break; 165368cd394eSKiseokJo default: 165468cd394eSKiseokJo dev_err(&client->dev, 165568cd394eSKiseokJo "Invalid sys-clk-id: %u\n", value); 165668cd394eSKiseokJo return -EINVAL; 165768cd394eSKiseokJo } 165868cd394eSKiseokJo sma1303->sys_clk_id = value; 165968cd394eSKiseokJo } else { 166068cd394eSKiseokJo dev_dbg(&client->dev, "Use the internal PLL clock by default\n"); 166168cd394eSKiseokJo sma1303->sys_clk_id = SMA1303_PLL_CLKIN_BCLK; 166268cd394eSKiseokJo } 166368cd394eSKiseokJo } else { 166468cd394eSKiseokJo dev_err(&client->dev, 166568cd394eSKiseokJo "device node initialization error\n"); 166668cd394eSKiseokJo devm_kfree(&client->dev, sma1303); 166768cd394eSKiseokJo return -ENODEV; 166868cd394eSKiseokJo } 166968cd394eSKiseokJo 167068cd394eSKiseokJo ret = sma1303_regmap_read(sma1303, 167168cd394eSKiseokJo SMA1303_FF_DEVICE_INDEX, &device_info); 167268cd394eSKiseokJo 167368cd394eSKiseokJo if ((ret != 0) || ((device_info & 0xF8) != SMA1303_DEVICE_ID)) { 167468cd394eSKiseokJo dev_err(&client->dev, "device initialization error (%d 0x%02X)", 167568cd394eSKiseokJo ret, device_info); 167668cd394eSKiseokJo } 167768cd394eSKiseokJo dev_dbg(&client->dev, "chip version 0x%02X\n", device_info); 167868cd394eSKiseokJo 167968cd394eSKiseokJo ret += sma1303_regmap_update_bits(sma1303, 168068cd394eSKiseokJo SMA1303_00_SYSTEM_CTRL, 168168cd394eSKiseokJo SMA1303_RESETBYI2C_MASK, SMA1303_RESETBYI2C_RESET, 168268cd394eSKiseokJo NULL); 168368cd394eSKiseokJo 168468cd394eSKiseokJo ret += sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, &status); 168568cd394eSKiseokJo sma1303->rev_num = status & SMA1303_REV_NUM_STATUS; 168668cd394eSKiseokJo if (sma1303->rev_num == SMA1303_REV_NUM_TV0) 168768cd394eSKiseokJo dev_dbg(&client->dev, "SMA1303 Trimming Version 0\n"); 168868cd394eSKiseokJo else if (sma1303->rev_num == SMA1303_REV_NUM_TV1) 168968cd394eSKiseokJo dev_dbg(&client->dev, "SMA1303 Trimming Version 1\n"); 169068cd394eSKiseokJo 169168cd394eSKiseokJo ret += sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, &otp_stat); 169268cd394eSKiseokJo if (ret < 0) 169368cd394eSKiseokJo dev_err(&client->dev, 169468cd394eSKiseokJo "failed to read, register: %02X, ret: %d\n", 169568cd394eSKiseokJo SMA1303_FF_DEVICE_INDEX, ret); 169668cd394eSKiseokJo 169768cd394eSKiseokJo if (((sma1303->rev_num == SMA1303_REV_NUM_TV0) && 169868cd394eSKiseokJo ((otp_stat & 0x0E) == SMA1303_OTP_STAT_OK_0)) || 169968cd394eSKiseokJo ((sma1303->rev_num != SMA1303_REV_NUM_TV0) && 170068cd394eSKiseokJo ((otp_stat & 0x0C) == SMA1303_OTP_STAT_OK_1))) 170168cd394eSKiseokJo dev_dbg(&client->dev, "SMA1303 OTP Status Successful\n"); 170268cd394eSKiseokJo else 170368cd394eSKiseokJo dev_dbg(&client->dev, "SMA1303 OTP Status Fail\n"); 170468cd394eSKiseokJo 170568cd394eSKiseokJo for (i = 0; i < (unsigned int)ARRAY_SIZE(sma1303_reg_def); i++) 170668cd394eSKiseokJo ret += sma1303_regmap_write(sma1303, 170768cd394eSKiseokJo sma1303_reg_def[i].reg, 170868cd394eSKiseokJo sma1303_reg_def[i].def); 170968cd394eSKiseokJo 171068cd394eSKiseokJo sma1303->amp_mode = SMA1303_MONO; 171168cd394eSKiseokJo sma1303->amp_power_status = false; 171268cd394eSKiseokJo sma1303->check_fault_period = CHECK_PERIOD_TIME; 171368cd394eSKiseokJo sma1303->check_fault_status = true; 171468cd394eSKiseokJo sma1303->force_mute_status = false; 171568cd394eSKiseokJo sma1303->init_vol = 0x31; 171668cd394eSKiseokJo sma1303->cur_vol = sma1303->init_vol; 171768cd394eSKiseokJo sma1303->last_bclk = 0; 171868cd394eSKiseokJo sma1303->last_ocp_val = 0x08; 171968cd394eSKiseokJo sma1303->last_over_temp = 0xC0; 172068cd394eSKiseokJo sma1303->tsdw_cnt = 0; 1721*1edc70c3SKiseok Jo sma1303->retry_cnt = SMA1303_I2C_RETRY_COUNT; 172268cd394eSKiseokJo 172368cd394eSKiseokJo sma1303->dev = &client->dev; 172468cd394eSKiseokJo sma1303->kobj = &client->dev.kobj; 172568cd394eSKiseokJo 172668cd394eSKiseokJo INIT_DELAYED_WORK(&sma1303->check_fault_work, 172768cd394eSKiseokJo sma1303_check_fault_worker); 172868cd394eSKiseokJo 172968cd394eSKiseokJo i2c_set_clientdata(client, sma1303); 173068cd394eSKiseokJo 173168cd394eSKiseokJo sma1303->pll_matches = sma1303_pll_matches; 173268cd394eSKiseokJo sma1303->num_of_pll_matches = 173368cd394eSKiseokJo ARRAY_SIZE(sma1303_pll_matches); 173468cd394eSKiseokJo 173568cd394eSKiseokJo ret = devm_snd_soc_register_component(&client->dev, 173668cd394eSKiseokJo &sma1303_component, sma1303_dai, 1); 173768cd394eSKiseokJo if (ret) { 173868cd394eSKiseokJo dev_err(&client->dev, "Failed to register component"); 173968cd394eSKiseokJo 174068cd394eSKiseokJo return ret; 174168cd394eSKiseokJo } 174268cd394eSKiseokJo 174368cd394eSKiseokJo sma1303->attr_grp = &sma1303_attr_group; 174468cd394eSKiseokJo ret = sysfs_create_group(sma1303->kobj, sma1303->attr_grp); 174568cd394eSKiseokJo if (ret) { 174668cd394eSKiseokJo dev_err(&client->dev, 174768cd394eSKiseokJo "failed to create attribute group [%d]\n", ret); 174868cd394eSKiseokJo sma1303->attr_grp = NULL; 174968cd394eSKiseokJo } 175068cd394eSKiseokJo 175168cd394eSKiseokJo return ret; 175268cd394eSKiseokJo } 175368cd394eSKiseokJo 175468cd394eSKiseokJo static void sma1303_i2c_remove(struct i2c_client *client) 175568cd394eSKiseokJo { 175668cd394eSKiseokJo struct sma1303_priv *sma1303 = 175768cd394eSKiseokJo (struct sma1303_priv *) i2c_get_clientdata(client); 175868cd394eSKiseokJo 175968cd394eSKiseokJo cancel_delayed_work_sync(&sma1303->check_fault_work); 176068cd394eSKiseokJo } 176168cd394eSKiseokJo 176268cd394eSKiseokJo static const struct i2c_device_id sma1303_i2c_id[] = { 176368cd394eSKiseokJo {"sma1303", 0}, 176468cd394eSKiseokJo {} 176568cd394eSKiseokJo }; 176668cd394eSKiseokJo MODULE_DEVICE_TABLE(i2c, sma1303_i2c_id); 176768cd394eSKiseokJo 176868cd394eSKiseokJo static const struct of_device_id sma1303_of_match[] = { 176968cd394eSKiseokJo { .compatible = "irondevice,sma1303", }, 177068cd394eSKiseokJo { } 177168cd394eSKiseokJo }; 177268cd394eSKiseokJo MODULE_DEVICE_TABLE(of, sma1303_of_match); 177368cd394eSKiseokJo 177468cd394eSKiseokJo static struct i2c_driver sma1303_i2c_driver = { 177568cd394eSKiseokJo .driver = { 177668cd394eSKiseokJo .name = "sma1303", 177768cd394eSKiseokJo .of_match_table = sma1303_of_match, 177868cd394eSKiseokJo }, 177930cf0025SUwe Kleine-König .probe_new = sma1303_i2c_probe, 178068cd394eSKiseokJo .remove = sma1303_i2c_remove, 178168cd394eSKiseokJo .id_table = sma1303_i2c_id, 178268cd394eSKiseokJo }; 178368cd394eSKiseokJo 178468cd394eSKiseokJo module_i2c_driver(sma1303_i2c_driver); 178568cd394eSKiseokJo 178668cd394eSKiseokJo MODULE_DESCRIPTION("ALSA SoC SMA1303 driver"); 178768cd394eSKiseokJo MODULE_AUTHOR("Gyuhwa Park, <gyuhwa.park@irondevice.com>"); 178868cd394eSKiseokJo MODULE_AUTHOR("Kiseok Jo, <kiseok.jo@irondevice.com>"); 178968cd394eSKiseokJo MODULE_LICENSE("GPL v2"); 1790