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"}; 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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[] = { 179468cd394eSKiseokJo {"sma1303", 0}, 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 }, 1810*9abcd240SUwe 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