1576c57e6SKiseok Jo // SPDX-License-Identifier: GPL-2.0-or-later 2576c57e6SKiseok Jo // sma1307.c -- sma1307 ALSA SoC Audio driver 3576c57e6SKiseok Jo // 4576c57e6SKiseok Jo // Copyright 2024 Iron Device Corporation 5576c57e6SKiseok Jo // 6576c57e6SKiseok Jo // Auther: Gyuhwa Park <gyuwha.park@irondevice.com> 7576c57e6SKiseok Jo // Auther: Kiseok Jo <kiseok.jo@irondevice.com> 8576c57e6SKiseok Jo 9576c57e6SKiseok Jo #include <linux/firmware.h> 10576c57e6SKiseok Jo #include <linux/i2c.h> 11576c57e6SKiseok Jo #include <linux/of_gpio.h> 12576c57e6SKiseok Jo #include <linux/regmap.h> 13576c57e6SKiseok Jo #include <sound/pcm_params.h> 14576c57e6SKiseok Jo #include <sound/tlv.h> 15576c57e6SKiseok Jo #include "sma1307.h" 16576c57e6SKiseok Jo 17576c57e6SKiseok Jo #define CHECK_PERIOD_TIME 1 /* sec per HZ */ 18576c57e6SKiseok Jo #define PLL_MATCH(_input_clk_name, _output_clk_name, _input_clk,\ 19576c57e6SKiseok Jo _post_n, _n, _vco, _p_cp)\ 20576c57e6SKiseok Jo {\ 21576c57e6SKiseok Jo .input_clk_name = _input_clk_name,\ 22576c57e6SKiseok Jo .output_clk_name = _output_clk_name,\ 23576c57e6SKiseok Jo .input_clk = _input_clk,\ 24576c57e6SKiseok Jo .post_n = _post_n,\ 25576c57e6SKiseok Jo .n = _n,\ 26576c57e6SKiseok Jo .vco = _vco,\ 27576c57e6SKiseok Jo .p_cp = _p_cp,\ 28576c57e6SKiseok Jo } 29576c57e6SKiseok Jo 30576c57e6SKiseok Jo static const char *setting_file = "sma1307_setting.bin"; 31576c57e6SKiseok Jo #define SMA1307_SETTING_CHECKSUM 0x100000 32576c57e6SKiseok Jo 33576c57e6SKiseok Jo /* PLL clock setting Table */ 34576c57e6SKiseok Jo struct sma1307_pll_match { 35576c57e6SKiseok Jo char *input_clk_name; 36576c57e6SKiseok Jo char *output_clk_name; 37576c57e6SKiseok Jo unsigned int input_clk; 38576c57e6SKiseok Jo unsigned int post_n; 39576c57e6SKiseok Jo unsigned int n; 40576c57e6SKiseok Jo unsigned int vco; 41576c57e6SKiseok Jo unsigned int p_cp; 42576c57e6SKiseok Jo }; 43576c57e6SKiseok Jo 44576c57e6SKiseok Jo struct sma1307_data { 45576c57e6SKiseok Jo char *name; 46576c57e6SKiseok Jo void (*init)(struct regmap *regmap); 47576c57e6SKiseok Jo }; 48576c57e6SKiseok Jo 49576c57e6SKiseok Jo struct sma1307_priv { 50576c57e6SKiseok Jo bool check_fault_status; 51576c57e6SKiseok Jo bool force_mute_status; 52576c57e6SKiseok Jo bool sw_ot1_prot; 53576c57e6SKiseok Jo char *name; 54576c57e6SKiseok Jo enum sma1307_mode amp_mode; 55576c57e6SKiseok Jo int binary_mode; 56576c57e6SKiseok Jo int dapm_aif_in; 57576c57e6SKiseok Jo int dapm_aif_out0; 58576c57e6SKiseok Jo int dapm_aif_out1; 59576c57e6SKiseok Jo int dapm_sdo_en; 60576c57e6SKiseok Jo int dapm_sdo_setting; 61576c57e6SKiseok Jo int num_of_pll_matches; 62576c57e6SKiseok Jo int check_fault_period; 63576c57e6SKiseok Jo struct delayed_work check_fault_work; 64576c57e6SKiseok Jo struct device *dev; 65576c57e6SKiseok Jo struct kobject *kobj; 66576c57e6SKiseok Jo struct mutex default_lock; 67576c57e6SKiseok Jo struct regmap *regmap; 68576c57e6SKiseok Jo struct sma1307_setting_file set; 69576c57e6SKiseok Jo const struct sma1307_pll_match *pll_matches; 70576c57e6SKiseok Jo const struct sma1307_data *data; 71576c57e6SKiseok Jo unsigned int cur_vol; 72576c57e6SKiseok Jo unsigned int format; 73576c57e6SKiseok Jo unsigned int frame_size; 74576c57e6SKiseok Jo unsigned int init_vol; 75576c57e6SKiseok Jo unsigned int last_bclk; 76576c57e6SKiseok Jo unsigned int otp_trm2; 77576c57e6SKiseok Jo unsigned int otp_trm3; 78576c57e6SKiseok Jo unsigned int rev_num; 79576c57e6SKiseok Jo unsigned int sys_clk_id; 80576c57e6SKiseok Jo unsigned int tdm_slot0_rx; 81576c57e6SKiseok Jo unsigned int tdm_slot1_rx; 82576c57e6SKiseok Jo unsigned int tdm_slot0_tx; 83576c57e6SKiseok Jo unsigned int tdm_slot1_tx; 84576c57e6SKiseok Jo unsigned int tsdw_cnt; 85576c57e6SKiseok Jo }; 86576c57e6SKiseok Jo 87576c57e6SKiseok Jo static const struct sma1307_pll_match sma1307_pll_matches[] = { 88576c57e6SKiseok Jo /* in_clk_name, out_clk_name, input_clk post_n, n, vco, p_cp */ 89576c57e6SKiseok Jo PLL_MATCH("1.411MHz", "24.554MHz", 90576c57e6SKiseok Jo 1411200, 0x06, 0xD1, 0x88, 0x00), 91576c57e6SKiseok Jo PLL_MATCH("1.536MHz", "24.576MHz", 92576c57e6SKiseok Jo 1536000, 0x06, 0xC0, 0x88, 0x00), 93576c57e6SKiseok Jo PLL_MATCH("2.822MHz", "24.554MHz", 94576c57e6SKiseok Jo 2822400, 0x06, 0xD1, 0x88, 0x04), 95576c57e6SKiseok Jo PLL_MATCH("3.072MHz", "24.576MHz", 96576c57e6SKiseok Jo 3072000, 0x06, 0x60, 0x88, 0x00), 97576c57e6SKiseok Jo PLL_MATCH("6.144MHz", "24.576MHz", 98576c57e6SKiseok Jo 6144000, 0x06, 0x60, 0x88, 0x04), 99576c57e6SKiseok Jo PLL_MATCH("12.288MHz", "24.576MHz", 100576c57e6SKiseok Jo 12288000, 0x06, 0x60, 0x88, 0x08), 101576c57e6SKiseok Jo PLL_MATCH("19.2MHz", "24.48MHz", 102576c57e6SKiseok Jo 19200000, 0x06, 0x7B, 0x88, 0x0C), 103576c57e6SKiseok Jo PLL_MATCH("24.576MHz", "24.576MHz", 104576c57e6SKiseok Jo 24576000, 0x06, 0x60, 0x88, 0x0C), 105576c57e6SKiseok Jo }; 106576c57e6SKiseok Jo 107576c57e6SKiseok Jo static struct snd_soc_component *sma1307_amp_component; 108576c57e6SKiseok Jo 109576c57e6SKiseok Jo static void sma1307_startup(struct snd_soc_component *); 110576c57e6SKiseok Jo static void sma1307_shutdown(struct snd_soc_component *); 111576c57e6SKiseok Jo static void sma1307_reset(struct snd_soc_component *); 112576c57e6SKiseok Jo static void sma1307_set_binary(struct snd_soc_component *); 113576c57e6SKiseok Jo static void sma1307_set_default(struct snd_soc_component *); 114576c57e6SKiseok Jo 115576c57e6SKiseok Jo /* Initial register value - 6.0W SPK (8ohm load) */ 116576c57e6SKiseok Jo static const struct reg_default sma1307_reg_def[] = { 117576c57e6SKiseok Jo { 0x00, 0x80 }, 118576c57e6SKiseok Jo { 0x01, 0x00 }, 119576c57e6SKiseok Jo { 0x02, 0x52 }, 120576c57e6SKiseok Jo { 0x03, 0x4C }, 121576c57e6SKiseok Jo { 0x04, 0x47 }, 122576c57e6SKiseok Jo { 0x05, 0x42 }, 123576c57e6SKiseok Jo { 0x06, 0x40 }, 124576c57e6SKiseok Jo { 0x07, 0x40 }, 125576c57e6SKiseok Jo { 0x08, 0x3C }, 126576c57e6SKiseok Jo { 0x09, 0x2F }, 127576c57e6SKiseok Jo { 0x0A, 0x32 }, 128576c57e6SKiseok Jo { 0x0B, 0x50 }, 129576c57e6SKiseok Jo { 0x0C, 0x8C }, 130576c57e6SKiseok Jo { 0x0D, 0x00 }, 131576c57e6SKiseok Jo { 0x0E, 0x3F }, 132576c57e6SKiseok Jo { 0x0F, 0x00 }, 133576c57e6SKiseok Jo { 0x10, 0x00 }, 134576c57e6SKiseok Jo { 0x11, 0x00 }, 135576c57e6SKiseok Jo { 0x12, 0x00 }, 136576c57e6SKiseok Jo { 0x13, 0x09 }, 137576c57e6SKiseok Jo { 0x14, 0x12 }, 138576c57e6SKiseok Jo { 0x1C, 0x00 }, 139576c57e6SKiseok Jo { 0x1D, 0x85 }, 140576c57e6SKiseok Jo { 0x1E, 0xA1 }, 141576c57e6SKiseok Jo { 0x1F, 0x67 }, 142576c57e6SKiseok Jo { 0x22, 0x00 }, 143576c57e6SKiseok Jo { 0x23, 0x1F }, 144576c57e6SKiseok Jo { 0x24, 0x7A }, 145576c57e6SKiseok Jo { 0x25, 0x00 }, 146576c57e6SKiseok Jo { 0x26, 0xFF }, 147576c57e6SKiseok Jo { 0x27, 0x39 }, 148576c57e6SKiseok Jo { 0x28, 0x54 }, 149576c57e6SKiseok Jo { 0x29, 0x92 }, 150576c57e6SKiseok Jo { 0x2A, 0xB0 }, 151576c57e6SKiseok Jo { 0x2B, 0xED }, 152576c57e6SKiseok Jo { 0x2C, 0xED }, 153576c57e6SKiseok Jo { 0x2D, 0xFF }, 154576c57e6SKiseok Jo { 0x2E, 0xFF }, 155576c57e6SKiseok Jo { 0x2F, 0xFF }, 156576c57e6SKiseok Jo { 0x30, 0xFF }, 157576c57e6SKiseok Jo { 0x31, 0xFF }, 158576c57e6SKiseok Jo { 0x32, 0xFF }, 159576c57e6SKiseok Jo { 0x34, 0x01 }, 160576c57e6SKiseok Jo { 0x35, 0x17 }, 161576c57e6SKiseok Jo { 0x36, 0x92 }, 162576c57e6SKiseok Jo { 0x37, 0x00 }, 163576c57e6SKiseok Jo { 0x38, 0x01 }, 164576c57e6SKiseok Jo { 0x39, 0x10 }, 165576c57e6SKiseok Jo { 0x3E, 0x01 }, 166576c57e6SKiseok Jo { 0x3F, 0x08 }, 167576c57e6SKiseok Jo { 0x8B, 0x05 }, 168576c57e6SKiseok Jo { 0x8C, 0x50 }, 169576c57e6SKiseok Jo { 0x8D, 0x80 }, 170576c57e6SKiseok Jo { 0x8E, 0x10 }, 171576c57e6SKiseok Jo { 0x8F, 0x02 }, 172576c57e6SKiseok Jo { 0x90, 0x02 }, 173576c57e6SKiseok Jo { 0x91, 0x83 }, 174576c57e6SKiseok Jo { 0x92, 0xC0 }, 175576c57e6SKiseok Jo { 0x93, 0x00 }, 176576c57e6SKiseok Jo { 0x94, 0xA4 }, 177576c57e6SKiseok Jo { 0x95, 0x74 }, 178576c57e6SKiseok Jo { 0x96, 0x57 }, 179576c57e6SKiseok Jo { 0xA2, 0xCC }, 180576c57e6SKiseok Jo { 0xA3, 0x28 }, 181576c57e6SKiseok Jo { 0xA4, 0x40 }, 182576c57e6SKiseok Jo { 0xA5, 0x01 }, 183576c57e6SKiseok Jo { 0xA6, 0x41 }, 184576c57e6SKiseok Jo { 0xA7, 0x08 }, 185576c57e6SKiseok Jo { 0xA8, 0x04 }, 186576c57e6SKiseok Jo { 0xA9, 0x27 }, 187576c57e6SKiseok Jo { 0xAA, 0x10 }, 188576c57e6SKiseok Jo { 0xAB, 0x10 }, 189576c57e6SKiseok Jo { 0xAC, 0x10 }, 190576c57e6SKiseok Jo { 0xAD, 0x0F }, 191576c57e6SKiseok Jo { 0xAE, 0xCD }, 192576c57e6SKiseok Jo { 0xAF, 0x70 }, 193576c57e6SKiseok Jo { 0xB0, 0x03 }, 194576c57e6SKiseok Jo { 0xB1, 0xEF }, 195576c57e6SKiseok Jo { 0xB2, 0x03 }, 196576c57e6SKiseok Jo { 0xB3, 0xEF }, 197576c57e6SKiseok Jo { 0xB4, 0xF3 }, 198576c57e6SKiseok Jo { 0xB5, 0x3D }, 199576c57e6SKiseok Jo }; 200576c57e6SKiseok Jo 201576c57e6SKiseok Jo static bool sma1307_readable_register(struct device *dev, unsigned int reg) 202576c57e6SKiseok Jo { 203576c57e6SKiseok Jo if (reg > SMA1307_FF_DEVICE_INDEX) 204576c57e6SKiseok Jo return false; 205576c57e6SKiseok Jo 206576c57e6SKiseok Jo switch (reg) { 207576c57e6SKiseok Jo case SMA1307_00_SYSTEM_CTRL ... SMA1307_1F_TONE_FINE_VOLUME: 208576c57e6SKiseok Jo case SMA1307_22_COMP_HYS_SEL ... SMA1307_32_BROWN_OUT_PROT19: 209576c57e6SKiseok Jo case SMA1307_34_OCP_SPK ... SMA1307_39_PMT_NZ_VAL: 210576c57e6SKiseok Jo case SMA1307_3B_TEST1 ... SMA1307_3F_ATEST2: 211576c57e6SKiseok Jo case SMA1307_8B_PLL_POST_N ... SMA1307_9A_OTP_TRM3: 212576c57e6SKiseok Jo case SMA1307_A0_PAD_CTRL0 ... SMA1307_BE_MCBS_CTRL2: 213576c57e6SKiseok Jo case SMA1307_F5_READY_FOR_V_SAR: 214576c57e6SKiseok Jo case SMA1307_F7_READY_FOR_T_SAR ... SMA1307_FF_DEVICE_INDEX: 215576c57e6SKiseok Jo break; 216576c57e6SKiseok Jo default: 217576c57e6SKiseok Jo return false; 218576c57e6SKiseok Jo } 219576c57e6SKiseok Jo return true; 220576c57e6SKiseok Jo } 221576c57e6SKiseok Jo 222576c57e6SKiseok Jo static bool sma1307_writeable_register(struct device *dev, unsigned int reg) 223576c57e6SKiseok Jo { 224576c57e6SKiseok Jo if (reg > SMA1307_FF_DEVICE_INDEX) 225576c57e6SKiseok Jo return false; 226576c57e6SKiseok Jo 227576c57e6SKiseok Jo switch (reg) { 228576c57e6SKiseok Jo case SMA1307_00_SYSTEM_CTRL ... SMA1307_1F_TONE_FINE_VOLUME: 229576c57e6SKiseok Jo case SMA1307_22_COMP_HYS_SEL ... SMA1307_32_BROWN_OUT_PROT19: 230576c57e6SKiseok Jo case SMA1307_34_OCP_SPK ... SMA1307_39_PMT_NZ_VAL: 231576c57e6SKiseok Jo case SMA1307_3B_TEST1 ... SMA1307_3F_ATEST2: 232576c57e6SKiseok Jo case SMA1307_8B_PLL_POST_N ... SMA1307_9A_OTP_TRM3: 233576c57e6SKiseok Jo case SMA1307_A0_PAD_CTRL0 ... SMA1307_BE_MCBS_CTRL2: 234576c57e6SKiseok Jo break; 235576c57e6SKiseok Jo default: 236576c57e6SKiseok Jo return false; 237576c57e6SKiseok Jo } 238576c57e6SKiseok Jo return true; 239576c57e6SKiseok Jo } 240576c57e6SKiseok Jo 241576c57e6SKiseok Jo static bool sma1307_volatile_register(struct device *dev, unsigned int reg) 242576c57e6SKiseok Jo { 243576c57e6SKiseok Jo if (reg > SMA1307_FF_DEVICE_INDEX) 244576c57e6SKiseok Jo return false; 245576c57e6SKiseok Jo 246576c57e6SKiseok Jo switch (reg) { 247576c57e6SKiseok Jo case SMA1307_F8_STATUS_T1 ... SMA1307_FF_DEVICE_INDEX: 248576c57e6SKiseok Jo break; 249576c57e6SKiseok Jo default: 250576c57e6SKiseok Jo return false; 251576c57e6SKiseok Jo } 252576c57e6SKiseok Jo return true; 253576c57e6SKiseok Jo } 254576c57e6SKiseok Jo 255576c57e6SKiseok Jo /* DB scale conversion of speaker volume */ 256576c57e6SKiseok Jo static const DECLARE_TLV_DB_SCALE(sma1307_spk_tlv, -6000, 50, 0); 257576c57e6SKiseok Jo 258576c57e6SKiseok Jo static const char *const sma1307_aif_in_source_text[] = { 259576c57e6SKiseok Jo "Mono", "Left", "Right" 260576c57e6SKiseok Jo }; 261576c57e6SKiseok Jo 262576c57e6SKiseok Jo static const char *const sma1307_sdo_setting_text[] = { 263576c57e6SKiseok Jo "Data_One_48k", "Data_Two_48k", "Data_Two_24k", 264576c57e6SKiseok Jo "Clk_PLL", "Clk_OSC" 265576c57e6SKiseok Jo }; 266576c57e6SKiseok Jo 267576c57e6SKiseok Jo static const char *const sma1307_aif_out_source_text[] = { 268576c57e6SKiseok Jo "Disable", "After_FmtC", "After_Mixer", "After_DSP", 269576c57e6SKiseok Jo "Vrms2_Avg", "Battery", "Temperature", "After_Delay" 270576c57e6SKiseok Jo }; 271576c57e6SKiseok Jo 272576c57e6SKiseok Jo static const char *const sma1307_tdm_slot_text[] = { 273576c57e6SKiseok Jo "Slot0", "Slot1", "Slot2", "Slot3", 274576c57e6SKiseok Jo "Slot4", "Slot5", "Slot6", "Slot7" 275576c57e6SKiseok Jo }; 276576c57e6SKiseok Jo 277576c57e6SKiseok Jo static const char *const sma1307_binary_mode_text[] = { 278576c57e6SKiseok Jo "Mode0", "Mode1", "Mode2", "Mode3", "Mode4" 279576c57e6SKiseok Jo }; 280576c57e6SKiseok Jo 281576c57e6SKiseok Jo static const char *const sma1307_reset_text[] = { 282576c57e6SKiseok Jo "Reset" 283576c57e6SKiseok Jo }; 284576c57e6SKiseok Jo 285576c57e6SKiseok Jo static const struct soc_enum sma1307_aif_in_source_enum = 286576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_aif_in_source_text), 287576c57e6SKiseok Jo sma1307_aif_in_source_text); 288576c57e6SKiseok Jo static const struct soc_enum sma1307_sdo_setting_enum = 289576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_sdo_setting_text), 290576c57e6SKiseok Jo sma1307_sdo_setting_text); 291576c57e6SKiseok Jo static const struct soc_enum sma1307_aif_out_source_enum = 292576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_aif_out_source_text), 293576c57e6SKiseok Jo sma1307_aif_out_source_text); 294576c57e6SKiseok Jo static const struct soc_enum sma1307_tdm_slot_enum = 295576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_tdm_slot_text), 296576c57e6SKiseok Jo sma1307_tdm_slot_text); 297576c57e6SKiseok Jo static const struct soc_enum sma1307_binary_mode_enum = 298576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_binary_mode_text), 299576c57e6SKiseok Jo sma1307_binary_mode_text); 300576c57e6SKiseok Jo static const struct soc_enum sma1307_reset_enum = 301576c57e6SKiseok Jo SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(sma1307_reset_text), 302576c57e6SKiseok Jo sma1307_reset_text); 303576c57e6SKiseok Jo 304576c57e6SKiseok Jo static int sma1307_force_mute_get(struct snd_kcontrol *kcontrol, 305576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 306576c57e6SKiseok Jo { 307576c57e6SKiseok Jo struct snd_soc_component *component = 308576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 309576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 310576c57e6SKiseok Jo 311576c57e6SKiseok Jo ucontrol->value.integer.value[0] = (int)sma1307->force_mute_status; 312576c57e6SKiseok Jo 313576c57e6SKiseok Jo return 0; 314576c57e6SKiseok Jo } 315576c57e6SKiseok Jo 316576c57e6SKiseok Jo static int sma1307_force_mute_put(struct snd_kcontrol *kcontrol, 317576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 318576c57e6SKiseok Jo { 319576c57e6SKiseok Jo struct snd_soc_component *component = 320576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 321576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 322576c57e6SKiseok Jo bool change = false, val = (bool)ucontrol->value.integer.value[0]; 323576c57e6SKiseok Jo 324576c57e6SKiseok Jo if (sma1307->force_mute_status == val) { 325576c57e6SKiseok Jo change = false; 326576c57e6SKiseok Jo } else { 327576c57e6SKiseok Jo change = true; 328576c57e6SKiseok Jo sma1307->force_mute_status = val; 329576c57e6SKiseok Jo } 330576c57e6SKiseok Jo 331576c57e6SKiseok Jo return change; 332576c57e6SKiseok Jo } 333576c57e6SKiseok Jo 334576c57e6SKiseok Jo static int sma1307_tdm_slot_get(struct snd_kcontrol *kcontrol, 335576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 336576c57e6SKiseok Jo { 337576c57e6SKiseok Jo struct snd_soc_component *component = 338576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 339576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 340576c57e6SKiseok Jo int val1, val2; 341576c57e6SKiseok Jo 342576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_A5_TDM1, &val1); 343576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_A6_TDM2, &val2); 344576c57e6SKiseok Jo 345576c57e6SKiseok Jo if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX0_POS_NAME)) { 346576c57e6SKiseok Jo ucontrol->value.integer.value[0] 347576c57e6SKiseok Jo = (val1 & SMA1307_TDM_SLOT0_RX_POS_MASK) >> 3; 348576c57e6SKiseok Jo sma1307->tdm_slot0_rx = ucontrol->value.integer.value[0]; 349576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX1_POS_NAME)) { 350576c57e6SKiseok Jo ucontrol->value.integer.value[0] 351576c57e6SKiseok Jo = val1 & SMA1307_TDM_SLOT1_RX_POS_MASK; 352576c57e6SKiseok Jo sma1307->tdm_slot1_rx = ucontrol->value.integer.value[0]; 353576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX0_POS_NAME)) { 354576c57e6SKiseok Jo ucontrol->value.integer.value[0] 355576c57e6SKiseok Jo = (val2 & SMA1307_TDM_SLOT0_TX_POS_MASK) >> 3; 356576c57e6SKiseok Jo sma1307->tdm_slot0_tx = ucontrol->value.integer.value[0]; 357576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX1_POS_NAME)) { 358576c57e6SKiseok Jo ucontrol->value.integer.value[0] 359576c57e6SKiseok Jo = val2 & SMA1307_TDM_SLOT1_TX_POS_MASK; 360576c57e6SKiseok Jo sma1307->tdm_slot1_tx = ucontrol->value.integer.value[0]; 361576c57e6SKiseok Jo } else { 362576c57e6SKiseok Jo return -EINVAL; 363576c57e6SKiseok Jo } 364576c57e6SKiseok Jo 365576c57e6SKiseok Jo return 0; 366576c57e6SKiseok Jo } 367576c57e6SKiseok Jo 368576c57e6SKiseok Jo static int sma1307_tdm_slot_put(struct snd_kcontrol *kcontrol, 369576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 370576c57e6SKiseok Jo { 371576c57e6SKiseok Jo struct snd_soc_component *component = 372576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 373576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 374576c57e6SKiseok Jo int val = (int)ucontrol->value.integer.value[0]; 375576c57e6SKiseok Jo bool change; 376576c57e6SKiseok Jo 377576c57e6SKiseok Jo if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX0_POS_NAME)) { 378576c57e6SKiseok Jo if (sma1307->tdm_slot0_rx == val) 379576c57e6SKiseok Jo change = false; 380576c57e6SKiseok Jo else { 381576c57e6SKiseok Jo change = true; 382576c57e6SKiseok Jo sma1307->tdm_slot0_rx = val; 383576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_A5_TDM1, 384576c57e6SKiseok Jo SMA1307_TDM_SLOT0_RX_POS_MASK, val << 3); 385576c57e6SKiseok Jo } 386576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_TDM_RX1_POS_NAME)) { 387576c57e6SKiseok Jo if (sma1307->tdm_slot1_rx == val) 388576c57e6SKiseok Jo change = false; 389576c57e6SKiseok Jo else { 390576c57e6SKiseok Jo change = true; 391576c57e6SKiseok Jo sma1307->tdm_slot1_rx = val; 392576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_A5_TDM1, 393576c57e6SKiseok Jo SMA1307_TDM_SLOT1_RX_POS_MASK, val); 394576c57e6SKiseok Jo } 395576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX0_POS_NAME)) { 396576c57e6SKiseok Jo if (sma1307->tdm_slot0_tx == val) 397576c57e6SKiseok Jo change = false; 398576c57e6SKiseok Jo else { 399576c57e6SKiseok Jo change = true; 400576c57e6SKiseok Jo sma1307->tdm_slot0_tx = val; 401576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_A6_TDM2, 402576c57e6SKiseok Jo SMA1307_TDM_SLOT0_TX_POS_MASK, val << 3); 403576c57e6SKiseok Jo } 404576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_TDM_TX1_POS_NAME)) { 405576c57e6SKiseok Jo if (sma1307->tdm_slot1_tx == val) 406576c57e6SKiseok Jo change = false; 407576c57e6SKiseok Jo else { 408576c57e6SKiseok Jo change = true; 409576c57e6SKiseok Jo sma1307->tdm_slot1_tx = val; 410576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_A6_TDM2, 411576c57e6SKiseok Jo SMA1307_TDM_SLOT1_TX_POS_MASK, val); 412576c57e6SKiseok Jo } 413576c57e6SKiseok Jo } else { 414576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid Control ID - %s\n", 415576c57e6SKiseok Jo __func__, kcontrol->id.name); 416576c57e6SKiseok Jo return -EINVAL; 417576c57e6SKiseok Jo } 418576c57e6SKiseok Jo 419576c57e6SKiseok Jo return change; 420576c57e6SKiseok Jo } 421576c57e6SKiseok Jo 422576c57e6SKiseok Jo static int sma1307_sw_ot1_prot_get(struct snd_kcontrol *kcontrol, 423576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 424576c57e6SKiseok Jo { 425576c57e6SKiseok Jo struct snd_soc_component *component = 426576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 427576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 428576c57e6SKiseok Jo 429576c57e6SKiseok Jo ucontrol->value.integer.value[0] = (int)sma1307->sw_ot1_prot; 430576c57e6SKiseok Jo 431576c57e6SKiseok Jo return 0; 432576c57e6SKiseok Jo } 433576c57e6SKiseok Jo 434576c57e6SKiseok Jo static int sma1307_sw_ot1_prot_put(struct snd_kcontrol *kcontrol, 435576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 436576c57e6SKiseok Jo { 437576c57e6SKiseok Jo struct snd_soc_component *component = 438576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 439576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 440576c57e6SKiseok Jo bool change = false, val = (bool)ucontrol->value.integer.value[0]; 441576c57e6SKiseok Jo 442576c57e6SKiseok Jo if (sma1307->sw_ot1_prot == val) 443576c57e6SKiseok Jo change = false; 444576c57e6SKiseok Jo else { 445576c57e6SKiseok Jo change = true; 446576c57e6SKiseok Jo sma1307->sw_ot1_prot = val; 447576c57e6SKiseok Jo } 448576c57e6SKiseok Jo 449576c57e6SKiseok Jo return change; 450576c57e6SKiseok Jo } 451576c57e6SKiseok Jo 452576c57e6SKiseok Jo static int sma1307_check_fault_status_get(struct snd_kcontrol *kcontrol, 453576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 454576c57e6SKiseok Jo { 455576c57e6SKiseok Jo struct snd_soc_component *component = 456576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 457576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 458576c57e6SKiseok Jo 459576c57e6SKiseok Jo ucontrol->value.integer.value[0] = (int)sma1307->check_fault_status; 460576c57e6SKiseok Jo 461576c57e6SKiseok Jo return 0; 462576c57e6SKiseok Jo } 463576c57e6SKiseok Jo 464576c57e6SKiseok Jo static int sma1307_check_fault_status_put(struct snd_kcontrol *kcontrol, 465576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 466576c57e6SKiseok Jo { 467576c57e6SKiseok Jo struct snd_soc_component *component = 468576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 469576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 470576c57e6SKiseok Jo bool change = false, val = (bool)ucontrol->value.integer.value[0]; 471576c57e6SKiseok Jo 472576c57e6SKiseok Jo if (sma1307->check_fault_status == val) { 473576c57e6SKiseok Jo change = false; 474576c57e6SKiseok Jo } else { 475576c57e6SKiseok Jo change = true; 476576c57e6SKiseok Jo sma1307->check_fault_status = val; 477576c57e6SKiseok Jo } 478576c57e6SKiseok Jo 479576c57e6SKiseok Jo return change; 480576c57e6SKiseok Jo } 481576c57e6SKiseok Jo 482576c57e6SKiseok Jo static int sma1307_check_fault_period_get(struct snd_kcontrol *kcontrol, 483576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 484576c57e6SKiseok Jo { 485576c57e6SKiseok Jo struct snd_soc_component *component = 486576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 487576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 488576c57e6SKiseok Jo 489576c57e6SKiseok Jo ucontrol->value.integer.value[0] = sma1307->check_fault_period; 490576c57e6SKiseok Jo 491576c57e6SKiseok Jo return 0; 492576c57e6SKiseok Jo } 493576c57e6SKiseok Jo 494576c57e6SKiseok Jo static int sma1307_check_fault_period_put(struct snd_kcontrol *kcontrol, 495576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 496576c57e6SKiseok Jo { 497576c57e6SKiseok Jo struct snd_soc_component *component = 498576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 499576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 500576c57e6SKiseok Jo struct soc_mixer_control *mc = 501576c57e6SKiseok Jo (struct soc_mixer_control *)kcontrol->private_value; 502576c57e6SKiseok Jo bool change = false; 503576c57e6SKiseok Jo int val = ucontrol->value.integer.value[0]; 504576c57e6SKiseok Jo 505576c57e6SKiseok Jo if (val < mc->min || val > mc->max) 506576c57e6SKiseok Jo return -EINVAL; 507576c57e6SKiseok Jo if (sma1307->check_fault_period == val) { 508576c57e6SKiseok Jo change = false; 509576c57e6SKiseok Jo } else { 510576c57e6SKiseok Jo change = true; 511576c57e6SKiseok Jo sma1307->check_fault_period = val; 512576c57e6SKiseok Jo } 513576c57e6SKiseok Jo 514576c57e6SKiseok Jo return change; 515576c57e6SKiseok Jo } 516576c57e6SKiseok Jo 517576c57e6SKiseok Jo static int sma1307_reset_put(struct snd_kcontrol *kcontrol, 518576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 519576c57e6SKiseok Jo { 520576c57e6SKiseok Jo struct snd_soc_component *component = 521576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 522576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 523576c57e6SKiseok Jo 524576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_00_SYSTEM_CTRL, 525576c57e6SKiseok Jo SMA1307_RESET_MASK, SMA1307_RESET_ON); 526576c57e6SKiseok Jo sma1307_reset(component); 527576c57e6SKiseok Jo 528576c57e6SKiseok Jo snd_ctl_notify(component->card->snd_card, SNDRV_CTL_EVENT_MASK_VALUE, 529576c57e6SKiseok Jo &kcontrol->id); 530576c57e6SKiseok Jo 531576c57e6SKiseok Jo return true; 532576c57e6SKiseok Jo } 533576c57e6SKiseok Jo 534576c57e6SKiseok Jo static int sma1307_binary_mode_put(struct snd_kcontrol *kcontrol, 535576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 536576c57e6SKiseok Jo { 537576c57e6SKiseok Jo struct snd_soc_component *component = 538576c57e6SKiseok Jo snd_soc_kcontrol_component(kcontrol); 539576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_kcontrol_chip(kcontrol); 540576c57e6SKiseok Jo 541576c57e6SKiseok Jo sma1307->binary_mode = (int)ucontrol->value.enumerated.item[0]; 542576c57e6SKiseok Jo if (sma1307->set.status) 543576c57e6SKiseok Jo sma1307_set_binary(component); 544576c57e6SKiseok Jo 545576c57e6SKiseok Jo return snd_soc_put_enum_double(kcontrol, ucontrol); 546576c57e6SKiseok Jo } 547576c57e6SKiseok Jo 548576c57e6SKiseok Jo static void sma1307_startup(struct snd_soc_component *component) 549576c57e6SKiseok Jo { 550576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 551576c57e6SKiseok Jo 552576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_A2_TOP_MAN1, 553576c57e6SKiseok Jo SMA1307_PLL_MASK, SMA1307_PLL_ON); 554576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_00_SYSTEM_CTRL, 555576c57e6SKiseok Jo SMA1307_POWER_MASK, SMA1307_POWER_ON); 556576c57e6SKiseok Jo 557576c57e6SKiseok Jo if (sma1307->amp_mode == SMA1307_MONO_MODE) { 558576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 559576c57e6SKiseok Jo SMA1307_10_SYSTEM_CTRL1, 560576c57e6SKiseok Jo SMA1307_SPK_MODE_MASK, 561576c57e6SKiseok Jo SMA1307_SPK_MONO); 562576c57e6SKiseok Jo } else { 563576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 564576c57e6SKiseok Jo SMA1307_10_SYSTEM_CTRL1, 565576c57e6SKiseok Jo SMA1307_SPK_MODE_MASK, 566576c57e6SKiseok Jo SMA1307_SPK_STEREO); 567576c57e6SKiseok Jo } 568576c57e6SKiseok Jo 569576c57e6SKiseok Jo if (sma1307->check_fault_status) { 570576c57e6SKiseok Jo if (sma1307->check_fault_period > 0) 571576c57e6SKiseok Jo queue_delayed_work(system_freezable_wq, 572576c57e6SKiseok Jo &sma1307->check_fault_work, 573576c57e6SKiseok Jo sma1307->check_fault_period * HZ); 574576c57e6SKiseok Jo else 575576c57e6SKiseok Jo queue_delayed_work(system_freezable_wq, 576576c57e6SKiseok Jo &sma1307->check_fault_work, 577576c57e6SKiseok Jo CHECK_PERIOD_TIME * HZ); 578576c57e6SKiseok Jo } 579576c57e6SKiseok Jo } 580576c57e6SKiseok Jo 581576c57e6SKiseok Jo static void sma1307_shutdown(struct snd_soc_component *component) 582576c57e6SKiseok Jo { 583576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 584576c57e6SKiseok Jo 585576c57e6SKiseok Jo /* for SMA1307A */ 586576c57e6SKiseok Jo cancel_delayed_work_sync(&sma1307->check_fault_work); 587576c57e6SKiseok Jo 588576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_0E_MUTE_VOL_CTRL, 589576c57e6SKiseok Jo SMA1307_SPK_MUTE_MASK, SMA1307_SPK_MUTE); 590576c57e6SKiseok Jo /* Need to wait time for mute slope */ 591576c57e6SKiseok Jo msleep(55); 592576c57e6SKiseok Jo 593576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_10_SYSTEM_CTRL1, 594576c57e6SKiseok Jo SMA1307_SPK_MODE_MASK, SMA1307_SPK_OFF); 595576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_A2_TOP_MAN1, 596576c57e6SKiseok Jo SMA1307_PLL_MASK, SMA1307_PLL_OFF); 597576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_00_SYSTEM_CTRL, 598576c57e6SKiseok Jo SMA1307_POWER_MASK, SMA1307_POWER_OFF); 599576c57e6SKiseok Jo } 600576c57e6SKiseok Jo 601576c57e6SKiseok Jo static int sma1307_aif_in_event(struct snd_soc_dapm_widget *w, 602576c57e6SKiseok Jo struct snd_kcontrol *kcontrol, int event) 603576c57e6SKiseok Jo { 604576c57e6SKiseok Jo struct snd_soc_component *component = 605576c57e6SKiseok Jo snd_soc_dapm_to_component(w->dapm); 606576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 607576c57e6SKiseok Jo unsigned int mux = sma1307->dapm_aif_in; 608576c57e6SKiseok Jo 609576c57e6SKiseok Jo switch (event) { 610576c57e6SKiseok Jo case SND_SOC_DAPM_PRE_PMU: 611576c57e6SKiseok Jo switch (mux) { 612576c57e6SKiseok Jo case SMA1307_MONO_MODE: 613576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 614576c57e6SKiseok Jo SMA1307_11_SYSTEM_CTRL2, 615576c57e6SKiseok Jo SMA1307_MONOMIX_MASK, 616576c57e6SKiseok Jo SMA1307_MONOMIX_ON); 617576c57e6SKiseok Jo break; 618576c57e6SKiseok Jo case SMA1307_LEFT_MODE: 619576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 620576c57e6SKiseok Jo SMA1307_11_SYSTEM_CTRL2, 621576c57e6SKiseok Jo SMA1307_MONOMIX_MASK, 622576c57e6SKiseok Jo SMA1307_MONOMIX_OFF); 623576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 624576c57e6SKiseok Jo SMA1307_11_SYSTEM_CTRL2, 625576c57e6SKiseok Jo SMA1307_LR_DATA_SW_MASK, 626576c57e6SKiseok Jo SMA1307_LR_DATA_SW_NORMAL); 627576c57e6SKiseok Jo break; 628576c57e6SKiseok Jo case SMA1307_RIGHT_MODE: 629576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 630576c57e6SKiseok Jo SMA1307_11_SYSTEM_CTRL2, 631576c57e6SKiseok Jo SMA1307_MONOMIX_MASK, 632576c57e6SKiseok Jo SMA1307_MONOMIX_OFF); 633576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 634576c57e6SKiseok Jo SMA1307_11_SYSTEM_CTRL2, 635576c57e6SKiseok Jo SMA1307_LR_DATA_SW_MASK, 636576c57e6SKiseok Jo SMA1307_LR_DATA_SW_SWAP); 637576c57e6SKiseok Jo break; 638576c57e6SKiseok Jo default: 639576c57e6SKiseok Jo 640576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid value (%d)\n", 641576c57e6SKiseok Jo __func__, mux); 642576c57e6SKiseok Jo return -EINVAL; 643576c57e6SKiseok Jo } 644576c57e6SKiseok Jo sma1307->amp_mode = mux; 645576c57e6SKiseok Jo break; 646576c57e6SKiseok Jo } 647576c57e6SKiseok Jo return 0; 648576c57e6SKiseok Jo } 649576c57e6SKiseok Jo 650576c57e6SKiseok Jo static int sma1307_sdo_setting_event(struct snd_soc_dapm_widget *w, 651576c57e6SKiseok Jo struct snd_kcontrol *kcontrol, int event) 652576c57e6SKiseok Jo { 653576c57e6SKiseok Jo struct snd_soc_component *component = 654576c57e6SKiseok Jo snd_soc_dapm_to_component(w->dapm); 655576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 656576c57e6SKiseok Jo unsigned int mux = sma1307->dapm_sdo_setting; 657576c57e6SKiseok Jo 658576c57e6SKiseok Jo switch (event) { 659576c57e6SKiseok Jo case SND_SOC_DAPM_PRE_PMU: 660576c57e6SKiseok Jo switch (mux) { 661576c57e6SKiseok Jo case SMA1307_OUT_DATA_ONE_48K: 662576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 663576c57e6SKiseok Jo SMA1307_A2_TOP_MAN1, 664576c57e6SKiseok Jo SMA1307_SDO_OUTPUT2_MASK, 665576c57e6SKiseok Jo SMA1307_ONE_SDO_PER_CH); 666576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 667576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 668576c57e6SKiseok Jo SMA1307_SDO_OUTPUT3_MASK 669576c57e6SKiseok Jo | 670576c57e6SKiseok Jo SMA1307_DATA_CLK_SEL_MASK, 671576c57e6SKiseok Jo SMA1307_SDO_OUTPUT3_DIS 672576c57e6SKiseok Jo | SMA1307_SDO_DATA); 673576c57e6SKiseok Jo break; 674576c57e6SKiseok Jo case SMA1307_OUT_DATA_TWO_48K: 675576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 676576c57e6SKiseok Jo SMA1307_A2_TOP_MAN1, 677576c57e6SKiseok Jo SMA1307_SDO_OUTPUT2_MASK, 678576c57e6SKiseok Jo SMA1307_TWO_SDO_PER_CH); 679576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 680576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 681576c57e6SKiseok Jo SMA1307_SDO_OUTPUT3_MASK 682576c57e6SKiseok Jo | 683576c57e6SKiseok Jo SMA1307_DATA_CLK_SEL_MASK, 684576c57e6SKiseok Jo SMA1307_SDO_OUTPUT3_DIS 685576c57e6SKiseok Jo | SMA1307_SDO_DATA); 686576c57e6SKiseok Jo break; 687576c57e6SKiseok Jo case SMA1307_OUT_DATA_TWO_24K: 688576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 689576c57e6SKiseok Jo SMA1307_A2_TOP_MAN1, 690576c57e6SKiseok Jo SMA1307_SDO_OUTPUT2_MASK, 691576c57e6SKiseok Jo SMA1307_TWO_SDO_PER_CH); 692576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 693576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 694576c57e6SKiseok Jo SMA1307_SDO_OUTPUT3_MASK 695576c57e6SKiseok Jo | 696576c57e6SKiseok Jo SMA1307_DATA_CLK_SEL_MASK, 697576c57e6SKiseok Jo SMA1307_TWO_SDO_PER_CH_24K 698576c57e6SKiseok Jo | SMA1307_SDO_DATA); 699576c57e6SKiseok Jo break; 700576c57e6SKiseok Jo case SMA1307_OUT_CLK_PLL: 701576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 702576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 703576c57e6SKiseok Jo SMA1307_DATA_CLK_SEL_MASK, 704576c57e6SKiseok Jo SMA1307_SDO_CLK_PLL); 705576c57e6SKiseok Jo 706576c57e6SKiseok Jo break; 707576c57e6SKiseok Jo case SMA1307_OUT_CLK_OSC: 708576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 709576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 710576c57e6SKiseok Jo SMA1307_DATA_CLK_SEL_MASK, 711576c57e6SKiseok Jo SMA1307_SDO_CLK_OSC); 712576c57e6SKiseok Jo 713576c57e6SKiseok Jo break; 714576c57e6SKiseok Jo default: 715576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid value (%d)\n", 716576c57e6SKiseok Jo __func__, mux); 717576c57e6SKiseok Jo return -EINVAL; 718576c57e6SKiseok Jo } 719576c57e6SKiseok Jo break; 720576c57e6SKiseok Jo } 721576c57e6SKiseok Jo return 0; 722576c57e6SKiseok Jo } 723576c57e6SKiseok Jo 724576c57e6SKiseok Jo static int sma1307_aif_out_event(struct snd_soc_dapm_widget *w, 725576c57e6SKiseok Jo struct snd_kcontrol *kcontrol, int event) 726576c57e6SKiseok Jo { 727576c57e6SKiseok Jo struct snd_soc_component *component = 728576c57e6SKiseok Jo snd_soc_dapm_to_component(w->dapm); 729576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 730576c57e6SKiseok Jo unsigned int mux = 0, val = 0, mask = 0; 731576c57e6SKiseok Jo 732576c57e6SKiseok Jo if (!strcmp(w->name, SMA1307_AIF_OUT0_NAME)) { 733576c57e6SKiseok Jo mux = sma1307->dapm_aif_out0; 734576c57e6SKiseok Jo val = mux; 735576c57e6SKiseok Jo mask = SMA1307_SDO_OUT0_SEL_MASK; 736576c57e6SKiseok Jo } else if (!strcmp(w->name, SMA1307_AIF_OUT1_NAME)) { 737576c57e6SKiseok Jo mux = sma1307->dapm_aif_out1; 738576c57e6SKiseok Jo val = mux << 3; 739576c57e6SKiseok Jo mask = SMA1307_SDO_OUT1_SEL_MASK; 740576c57e6SKiseok Jo } else { 741576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid widget - %s\n", 742576c57e6SKiseok Jo __func__, w->name); 743576c57e6SKiseok Jo return -EINVAL; 744576c57e6SKiseok Jo } 745576c57e6SKiseok Jo switch (event) { 746576c57e6SKiseok Jo case SND_SOC_DAPM_PRE_PMU: 747576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, SMA1307_09_OUTPUT_CTRL, 748576c57e6SKiseok Jo mask, val); 749576c57e6SKiseok Jo break; 750576c57e6SKiseok Jo } 751576c57e6SKiseok Jo return 0; 752576c57e6SKiseok Jo } 753576c57e6SKiseok Jo 754576c57e6SKiseok Jo static int sma1307_sdo_event(struct snd_soc_dapm_widget *w, 755576c57e6SKiseok Jo struct snd_kcontrol *kcontrol, int event) 756576c57e6SKiseok Jo { 757576c57e6SKiseok Jo struct snd_soc_component *component = 758576c57e6SKiseok Jo snd_soc_dapm_to_component(w->dapm); 759576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 760576c57e6SKiseok Jo 761576c57e6SKiseok Jo switch (event) { 762576c57e6SKiseok Jo case SND_SOC_DAPM_PRE_PMU: 763576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 764576c57e6SKiseok Jo SMA1307_09_OUTPUT_CTRL, 765576c57e6SKiseok Jo SMA1307_PORT_CONFIG_MASK, 766576c57e6SKiseok Jo SMA1307_OUTPUT_PORT_ENABLE); 767576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 768576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 769576c57e6SKiseok Jo SMA1307_SDO_OUTPUT_MASK, 770576c57e6SKiseok Jo SMA1307_LOGIC_OUTPUT); 771576c57e6SKiseok Jo break; 772576c57e6SKiseok Jo case SND_SOC_DAPM_POST_PMD: 773576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 774576c57e6SKiseok Jo SMA1307_09_OUTPUT_CTRL, 775576c57e6SKiseok Jo SMA1307_PORT_CONFIG_MASK, 776576c57e6SKiseok Jo SMA1307_INPUT_PORT_ONLY); 777576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 778576c57e6SKiseok Jo SMA1307_A3_TOP_MAN2, 779576c57e6SKiseok Jo SMA1307_SDO_OUTPUT_MASK, 780576c57e6SKiseok Jo SMA1307_HIGH_Z_OUTPUT); 781576c57e6SKiseok Jo break; 782576c57e6SKiseok Jo } 783576c57e6SKiseok Jo return 0; 784576c57e6SKiseok Jo } 785576c57e6SKiseok Jo 786576c57e6SKiseok Jo static int sma1307_power_event(struct snd_soc_dapm_widget *w, 787576c57e6SKiseok Jo struct snd_kcontrol *kcontrol, int event) 788576c57e6SKiseok Jo { 789576c57e6SKiseok Jo struct snd_soc_component *component = 790576c57e6SKiseok Jo snd_soc_dapm_to_component(w->dapm); 791576c57e6SKiseok Jo 792576c57e6SKiseok Jo switch (event) { 793576c57e6SKiseok Jo case SND_SOC_DAPM_POST_PMU: 794576c57e6SKiseok Jo sma1307_startup(component); 795576c57e6SKiseok Jo break; 796576c57e6SKiseok Jo case SND_SOC_DAPM_PRE_PMD: 797576c57e6SKiseok Jo sma1307_shutdown(component); 798576c57e6SKiseok Jo break; 799576c57e6SKiseok Jo } 800576c57e6SKiseok Jo return 0; 801576c57e6SKiseok Jo } 802576c57e6SKiseok Jo 803576c57e6SKiseok Jo static int sma1307_dapm_aif_in_get(struct snd_kcontrol *kcontrol, 804576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 805576c57e6SKiseok Jo { 806576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 807576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 808576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 809576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 810576c57e6SKiseok Jo 811576c57e6SKiseok Jo ucontrol->value.enumerated.item[0] = (unsigned int)sma1307->dapm_aif_in; 812576c57e6SKiseok Jo snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 813576c57e6SKiseok Jo 814576c57e6SKiseok Jo return 0; 815576c57e6SKiseok Jo } 816576c57e6SKiseok Jo 817576c57e6SKiseok Jo static int sma1307_dapm_aif_in_put(struct snd_kcontrol *kcontrol, 818576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 819576c57e6SKiseok Jo { 820576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 821576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 822576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 823576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 824576c57e6SKiseok Jo int val = (int)ucontrol->value.enumerated.item[0]; 825576c57e6SKiseok Jo bool change; 826576c57e6SKiseok Jo 827576c57e6SKiseok Jo if ((val < 0) || (val >= ARRAY_SIZE(sma1307_aif_in_source_text))) { 828576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Out of range\n", __func__); 829576c57e6SKiseok Jo return -EINVAL; 830576c57e6SKiseok Jo } 831576c57e6SKiseok Jo 832576c57e6SKiseok Jo if (sma1307->dapm_aif_in != val) { 833576c57e6SKiseok Jo change = true; 834576c57e6SKiseok Jo sma1307->dapm_aif_in = val; 835576c57e6SKiseok Jo } else 836576c57e6SKiseok Jo change = false; 837576c57e6SKiseok Jo 838576c57e6SKiseok Jo snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 839576c57e6SKiseok Jo 840576c57e6SKiseok Jo return change; 841576c57e6SKiseok Jo } 842576c57e6SKiseok Jo 843576c57e6SKiseok Jo static int sma1307_dapm_sdo_setting_get(struct snd_kcontrol *kcontrol, 844576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 845576c57e6SKiseok Jo { 846576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 847576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 848576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 849576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 850576c57e6SKiseok Jo 851576c57e6SKiseok Jo ucontrol->value.enumerated.item[0] = 852576c57e6SKiseok Jo (unsigned int)sma1307->dapm_sdo_setting; 853576c57e6SKiseok Jo snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 854576c57e6SKiseok Jo 855576c57e6SKiseok Jo return 0; 856576c57e6SKiseok Jo } 857576c57e6SKiseok Jo 858576c57e6SKiseok Jo static int sma1307_dapm_sdo_setting_put(struct snd_kcontrol *kcontrol, 859576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 860576c57e6SKiseok Jo { 861576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 862576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 863576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 864576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 865576c57e6SKiseok Jo int val = (int)ucontrol->value.enumerated.item[0]; 866576c57e6SKiseok Jo bool change; 867576c57e6SKiseok Jo 868576c57e6SKiseok Jo if ((val < 0) || (val >= ARRAY_SIZE(sma1307_sdo_setting_text))) { 869576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Out of range\n", __func__); 870576c57e6SKiseok Jo return -EINVAL; 871576c57e6SKiseok Jo } 872576c57e6SKiseok Jo 873576c57e6SKiseok Jo if (sma1307->dapm_sdo_setting != val) { 874576c57e6SKiseok Jo change = true; 875576c57e6SKiseok Jo sma1307->dapm_sdo_setting = val; 876576c57e6SKiseok Jo } else 877576c57e6SKiseok Jo change = false; 878576c57e6SKiseok Jo 879576c57e6SKiseok Jo snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 880576c57e6SKiseok Jo 881576c57e6SKiseok Jo return change; 882576c57e6SKiseok Jo } 883576c57e6SKiseok Jo 884576c57e6SKiseok Jo static int sma1307_dapm_aif_out_get(struct snd_kcontrol *kcontrol, 885576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 886576c57e6SKiseok Jo { 887576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 888576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 889576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 890576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 891576c57e6SKiseok Jo unsigned int val = 0; 892576c57e6SKiseok Jo 893576c57e6SKiseok Jo if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT0_NAME)) { 894576c57e6SKiseok Jo val = (unsigned int)sma1307->dapm_aif_out0; 895576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT1_NAME)) { 896576c57e6SKiseok Jo val = (unsigned int)sma1307->dapm_aif_out1; 897576c57e6SKiseok Jo } else { 898576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid Control ID - %s\n", 899576c57e6SKiseok Jo __func__, kcontrol->id.name); 900576c57e6SKiseok Jo return -EINVAL; 901576c57e6SKiseok Jo } 902576c57e6SKiseok Jo ucontrol->value.enumerated.item[0] = val; 903576c57e6SKiseok Jo snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 904576c57e6SKiseok Jo 905576c57e6SKiseok Jo return 0; 906576c57e6SKiseok Jo } 907576c57e6SKiseok Jo 908576c57e6SKiseok Jo static int sma1307_dapm_aif_out_put(struct snd_kcontrol *kcontrol, 909576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 910576c57e6SKiseok Jo { 911576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 912576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 913576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 914576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 915576c57e6SKiseok Jo int val = (int)ucontrol->value.enumerated.item[0]; 916576c57e6SKiseok Jo bool change; 917576c57e6SKiseok Jo 918576c57e6SKiseok Jo if ((val < 0) || (val >= ARRAY_SIZE(sma1307_aif_out_source_text))) { 919576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Out of range\n", __func__); 920576c57e6SKiseok Jo return -EINVAL; 921576c57e6SKiseok Jo } 922576c57e6SKiseok Jo 923576c57e6SKiseok Jo if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT0_NAME)) { 924576c57e6SKiseok Jo if (sma1307->dapm_aif_out0 != val) { 925576c57e6SKiseok Jo change = true; 926576c57e6SKiseok Jo sma1307->dapm_aif_out0 = val; 927576c57e6SKiseok Jo } else 928576c57e6SKiseok Jo change = false; 929576c57e6SKiseok Jo } else if (!strcmp(kcontrol->id.name, SMA1307_AIF_OUT1_NAME)) { 930576c57e6SKiseok Jo if (sma1307->dapm_aif_out1 != val) { 931576c57e6SKiseok Jo change = true; 932576c57e6SKiseok Jo sma1307->dapm_aif_out1 = val; 933576c57e6SKiseok Jo } else 934576c57e6SKiseok Jo change = false; 935576c57e6SKiseok Jo } else { 936576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid Control ID - %s\n", 937576c57e6SKiseok Jo __func__, kcontrol->id.name); 938576c57e6SKiseok Jo return -EINVAL; 939576c57e6SKiseok Jo } 940576c57e6SKiseok Jo 941576c57e6SKiseok Jo snd_soc_dapm_put_enum_double(kcontrol, ucontrol); 942576c57e6SKiseok Jo 943576c57e6SKiseok Jo return change; 944576c57e6SKiseok Jo } 945576c57e6SKiseok Jo 946576c57e6SKiseok Jo static int sma1307_dapm_sdo_enable_get(struct snd_kcontrol *kcontrol, 947576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 948576c57e6SKiseok Jo { 949576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 950576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 951576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 952576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 953576c57e6SKiseok Jo 954576c57e6SKiseok Jo ucontrol->value.integer.value[0] = (long)sma1307->dapm_sdo_en; 955576c57e6SKiseok Jo snd_soc_dapm_put_volsw(kcontrol, ucontrol); 956576c57e6SKiseok Jo 957576c57e6SKiseok Jo return 0; 958576c57e6SKiseok Jo } 959576c57e6SKiseok Jo 960576c57e6SKiseok Jo static int sma1307_dapm_sdo_enable_put(struct snd_kcontrol *kcontrol, 961576c57e6SKiseok Jo struct snd_ctl_elem_value *ucontrol) 962576c57e6SKiseok Jo { 963576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 964576c57e6SKiseok Jo snd_soc_dapm_kcontrol_dapm(kcontrol); 965576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 966576c57e6SKiseok Jo snd_soc_component_get_drvdata(dapm->component); 967576c57e6SKiseok Jo int val = (int)ucontrol->value.integer.value[0]; 968576c57e6SKiseok Jo bool change; 969576c57e6SKiseok Jo 970576c57e6SKiseok Jo if ((val < 0) || (val > 1)) { 971576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Out of range\n", __func__); 972576c57e6SKiseok Jo return -EINVAL; 973576c57e6SKiseok Jo } 974576c57e6SKiseok Jo 975576c57e6SKiseok Jo if (sma1307->dapm_sdo_en != val) { 976576c57e6SKiseok Jo change = true; 977576c57e6SKiseok Jo sma1307->dapm_sdo_en = val; 978576c57e6SKiseok Jo } else 979576c57e6SKiseok Jo change = false; 980576c57e6SKiseok Jo 981576c57e6SKiseok Jo snd_soc_dapm_put_volsw(kcontrol, ucontrol); 982576c57e6SKiseok Jo 983576c57e6SKiseok Jo return change; 984576c57e6SKiseok Jo } 985576c57e6SKiseok Jo 986576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_aif_in_source_control = { 987576c57e6SKiseok Jo .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 988576c57e6SKiseok Jo .name = SMA1307_AIF_IN_NAME, 989576c57e6SKiseok Jo .info = snd_soc_info_enum_double, 990576c57e6SKiseok Jo .get = sma1307_dapm_aif_in_get, 991576c57e6SKiseok Jo .put = sma1307_dapm_aif_in_put, 992576c57e6SKiseok Jo .private_value = (unsigned long)&sma1307_aif_in_source_enum 993576c57e6SKiseok Jo }; 994576c57e6SKiseok Jo 995576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_sdo_setting_control = { 996576c57e6SKiseok Jo .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 997576c57e6SKiseok Jo .name = "SDO Setting", 998576c57e6SKiseok Jo .info = snd_soc_info_enum_double, 999576c57e6SKiseok Jo .get = sma1307_dapm_sdo_setting_get, 1000576c57e6SKiseok Jo .put = sma1307_dapm_sdo_setting_put, 1001576c57e6SKiseok Jo .private_value = (unsigned long)&sma1307_sdo_setting_enum 1002576c57e6SKiseok Jo }; 1003576c57e6SKiseok Jo 1004576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_aif_out0_source_control = { 1005576c57e6SKiseok Jo .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1006576c57e6SKiseok Jo .name = SMA1307_AIF_OUT0_NAME, 1007576c57e6SKiseok Jo .info = snd_soc_info_enum_double, 1008576c57e6SKiseok Jo .get = sma1307_dapm_aif_out_get, 1009576c57e6SKiseok Jo .put = sma1307_dapm_aif_out_put, 1010576c57e6SKiseok Jo .private_value = (unsigned long)&sma1307_aif_out_source_enum 1011576c57e6SKiseok Jo }; 1012576c57e6SKiseok Jo 1013576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_aif_out1_source_control = { 1014576c57e6SKiseok Jo .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1015576c57e6SKiseok Jo .name = SMA1307_AIF_OUT1_NAME, 1016576c57e6SKiseok Jo .info = snd_soc_info_enum_double, 1017576c57e6SKiseok Jo .get = sma1307_dapm_aif_out_get, 1018576c57e6SKiseok Jo .put = sma1307_dapm_aif_out_put, 1019576c57e6SKiseok Jo .private_value = (unsigned long)&sma1307_aif_out_source_enum 1020576c57e6SKiseok Jo }; 1021576c57e6SKiseok Jo 1022576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_sdo_control = { 1023576c57e6SKiseok Jo .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1024576c57e6SKiseok Jo .name = "Switch", 1025576c57e6SKiseok Jo .info = snd_soc_info_volsw, 1026576c57e6SKiseok Jo .get = sma1307_dapm_sdo_enable_get, 1027576c57e6SKiseok Jo .put = sma1307_dapm_sdo_enable_put, 1028576c57e6SKiseok Jo .private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, 0, 1, 0, 0) 1029576c57e6SKiseok Jo }; 1030576c57e6SKiseok Jo 1031576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_enable_control = 1032576c57e6SKiseok Jo SOC_DAPM_SINGLE("Switch", SMA1307_00_SYSTEM_CTRL, 0, 1, 0); 1033576c57e6SKiseok Jo 1034576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_binary_mode_control[] = { 1035576c57e6SKiseok Jo SOC_ENUM_EXT("Binary Mode", sma1307_binary_mode_enum, 1036576c57e6SKiseok Jo snd_soc_get_enum_double, sma1307_binary_mode_put), 1037576c57e6SKiseok Jo }; 1038576c57e6SKiseok Jo 1039576c57e6SKiseok Jo static const struct snd_kcontrol_new sma1307_snd_controls[] = { 1040576c57e6SKiseok Jo SOC_SINGLE_TLV(SMA1307_VOL_CTRL_NAME, SMA1307_0A_SPK_VOL, 1041576c57e6SKiseok Jo 0, 167, 1, sma1307_spk_tlv), 1042576c57e6SKiseok Jo SOC_ENUM_EXT(SMA1307_TDM_RX0_POS_NAME, sma1307_tdm_slot_enum, 1043576c57e6SKiseok Jo sma1307_tdm_slot_get, sma1307_tdm_slot_put), 1044576c57e6SKiseok Jo SOC_ENUM_EXT(SMA1307_TDM_RX1_POS_NAME, sma1307_tdm_slot_enum, 1045576c57e6SKiseok Jo sma1307_tdm_slot_get, sma1307_tdm_slot_put), 1046576c57e6SKiseok Jo SOC_ENUM_EXT(SMA1307_TDM_TX0_POS_NAME, sma1307_tdm_slot_enum, 1047576c57e6SKiseok Jo sma1307_tdm_slot_get, sma1307_tdm_slot_put), 1048576c57e6SKiseok Jo SOC_ENUM_EXT(SMA1307_TDM_TX1_POS_NAME, sma1307_tdm_slot_enum, 1049576c57e6SKiseok Jo sma1307_tdm_slot_get, sma1307_tdm_slot_put), 1050576c57e6SKiseok Jo SOC_ENUM_EXT(SMA1307_RESET_CTRL_NAME, sma1307_reset_enum, 1051576c57e6SKiseok Jo snd_soc_get_enum_double, sma1307_reset_put), 1052576c57e6SKiseok Jo SOC_SINGLE_BOOL_EXT(SMA1307_FORCE_MUTE_CTRL_NAME, 0, 1053576c57e6SKiseok Jo sma1307_force_mute_get, sma1307_force_mute_put), 1054576c57e6SKiseok Jo SOC_SINGLE_BOOL_EXT(SMA1307_OT1_SW_PROT_CTRL_NAME, 0, 1055576c57e6SKiseok Jo sma1307_sw_ot1_prot_get, sma1307_sw_ot1_prot_put), 1056576c57e6SKiseok Jo SOC_SINGLE_BOOL_EXT(SMA1307_CHECK_FAULT_STATUS_NAME, 0, 1057576c57e6SKiseok Jo sma1307_check_fault_status_get, 1058576c57e6SKiseok Jo sma1307_check_fault_status_put), 1059576c57e6SKiseok Jo SOC_SINGLE_EXT(SMA1307_CHECK_FAULT_PERIOD_NAME, SND_SOC_NOPM, 0, 600, 0, 1060576c57e6SKiseok Jo sma1307_check_fault_period_get, 1061576c57e6SKiseok Jo sma1307_check_fault_period_put), 1062576c57e6SKiseok Jo }; 1063576c57e6SKiseok Jo 1064576c57e6SKiseok Jo static const struct snd_soc_dapm_widget sma1307_dapm_widgets[] = { 1065576c57e6SKiseok Jo /* platform domain */ 1066576c57e6SKiseok Jo SND_SOC_DAPM_OUTPUT("SPK"), 1067576c57e6SKiseok Jo SND_SOC_DAPM_INPUT("SDO"), 1068576c57e6SKiseok Jo 1069576c57e6SKiseok Jo /* path domain */ 1070576c57e6SKiseok Jo SND_SOC_DAPM_MUX_E(SMA1307_AIF_IN_NAME, SND_SOC_NOPM, 0, 0, 1071576c57e6SKiseok Jo &sma1307_aif_in_source_control, 1072576c57e6SKiseok Jo sma1307_aif_in_event, 1073576c57e6SKiseok Jo SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), 1074576c57e6SKiseok Jo SND_SOC_DAPM_MUX_E("SDO Setting", SND_SOC_NOPM, 0, 0, 1075576c57e6SKiseok Jo &sma1307_sdo_setting_control, 1076576c57e6SKiseok Jo sma1307_sdo_setting_event, 1077576c57e6SKiseok Jo SND_SOC_DAPM_PRE_PMU), 1078576c57e6SKiseok Jo SND_SOC_DAPM_MUX_E(SMA1307_AIF_OUT0_NAME, SND_SOC_NOPM, 0, 0, 1079576c57e6SKiseok Jo &sma1307_aif_out0_source_control, 1080576c57e6SKiseok Jo sma1307_aif_out_event, 1081576c57e6SKiseok Jo SND_SOC_DAPM_PRE_PMU), 1082576c57e6SKiseok Jo SND_SOC_DAPM_MUX_E(SMA1307_AIF_OUT1_NAME, SND_SOC_NOPM, 0, 0, 1083576c57e6SKiseok Jo &sma1307_aif_out1_source_control, 1084576c57e6SKiseok Jo sma1307_aif_out_event, 1085576c57e6SKiseok Jo SND_SOC_DAPM_PRE_PMU), 1086576c57e6SKiseok Jo SND_SOC_DAPM_SWITCH_E("SDO Enable", SND_SOC_NOPM, 0, 0, 1087576c57e6SKiseok Jo &sma1307_sdo_control, 1088576c57e6SKiseok Jo sma1307_sdo_event, 1089576c57e6SKiseok Jo SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 1090576c57e6SKiseok Jo SND_SOC_DAPM_MIXER("Entry", SND_SOC_NOPM, 0, 0, NULL, 0), 1091576c57e6SKiseok Jo SND_SOC_DAPM_OUT_DRV_E("AMP Power", SND_SOC_NOPM, 0, 0, NULL, 0, 1092576c57e6SKiseok Jo sma1307_power_event, 1093576c57e6SKiseok Jo SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD | 1094576c57e6SKiseok Jo SND_SOC_DAPM_POST_PMU), 1095576c57e6SKiseok Jo SND_SOC_DAPM_SWITCH("AMP Enable", SND_SOC_NOPM, 0, 0, 1096576c57e6SKiseok Jo &sma1307_enable_control), 1097576c57e6SKiseok Jo 1098576c57e6SKiseok Jo /* stream domain */ 1099576c57e6SKiseok Jo SND_SOC_DAPM_AIF_IN("AIF IN", "Playback", 0, SND_SOC_NOPM, 0, 0), 1100576c57e6SKiseok Jo SND_SOC_DAPM_AIF_OUT("AIF OUT", "Capture", 0, SND_SOC_NOPM, 0, 0), 1101576c57e6SKiseok Jo }; 1102576c57e6SKiseok Jo 1103576c57e6SKiseok Jo static const struct snd_soc_dapm_route sma1307_audio_map[] = { 1104576c57e6SKiseok Jo /* Playback */ 1105576c57e6SKiseok Jo { "AIF IN Source", "Mono", "AIF IN" }, 1106576c57e6SKiseok Jo { "AIF IN Source", "Left", "AIF IN" }, 1107576c57e6SKiseok Jo { "AIF IN Source", "Right", "AIF IN" }, 1108576c57e6SKiseok Jo 1109576c57e6SKiseok Jo { "SDO Enable", "Switch", "AIF IN" }, 1110576c57e6SKiseok Jo 1111576c57e6SKiseok Jo { "SDO Setting", "Data_One_48k", "SDO Enable" }, 1112576c57e6SKiseok Jo { "SDO Setting", "Data_Two_48k", "SDO Enable" }, 1113576c57e6SKiseok Jo { "SDO Setting", "Data_Two_24k", "SDO Enable" }, 1114576c57e6SKiseok Jo { "SDO Setting", "Clk_PLL", "SDO Enable" }, 1115576c57e6SKiseok Jo { "SDO Setting", "Clk_OSC", "SDO Enable" }, 1116576c57e6SKiseok Jo 1117576c57e6SKiseok Jo { "AIF OUT0 Source", "Disable", "SDO Setting" }, 1118576c57e6SKiseok Jo { "AIF OUT0 Source", "After_FmtC", "SDO Setting" }, 1119576c57e6SKiseok Jo { "AIF OUT0 Source", "After_Mixer", "SDO Setting" }, 1120576c57e6SKiseok Jo { "AIF OUT0 Source", "After_DSP", "SDO Setting" }, 1121576c57e6SKiseok Jo { "AIF OUT0 Source", "Vrms2_Avg", "SDO Setting" }, 1122576c57e6SKiseok Jo { "AIF OUT0 Source", "Battery", "SDO Setting" }, 1123576c57e6SKiseok Jo { "AIF OUT0 Source", "Temperature", "SDO Setting" }, 1124576c57e6SKiseok Jo { "AIF OUT0 Source", "After_Delay", "SDO Setting" }, 1125576c57e6SKiseok Jo 1126576c57e6SKiseok Jo { "AIF OUT1 Source", "Disable", "SDO Setting" }, 1127576c57e6SKiseok Jo { "AIF OUT1 Source", "After_FmtC", "SDO Setting" }, 1128576c57e6SKiseok Jo { "AIF OUT1 Source", "After_Mixer", "SDO Setting" }, 1129576c57e6SKiseok Jo { "AIF OUT1 Source", "After_DSP", "SDO Setting" }, 1130576c57e6SKiseok Jo { "AIF OUT1 Source", "Vrms2_Avg", "SDO Setting" }, 1131576c57e6SKiseok Jo { "AIF OUT1 Source", "Battery", "SDO Setting" }, 1132576c57e6SKiseok Jo { "AIF OUT1 Source", "Temperature", "SDO Setting" }, 1133576c57e6SKiseok Jo { "AIF OUT1 Source", "After_Delay", "SDO Setting" }, 1134576c57e6SKiseok Jo 1135576c57e6SKiseok Jo { "Entry", NULL, "AIF OUT0 Source" }, 1136576c57e6SKiseok Jo { "Entry", NULL, "AIF OUT1 Source" }, 1137576c57e6SKiseok Jo { "Entry", NULL, "AIF IN Source" }, 1138576c57e6SKiseok Jo 1139576c57e6SKiseok Jo { "AMP Power", NULL, "Entry" }, 1140576c57e6SKiseok Jo 1141576c57e6SKiseok Jo { "AMP Enable", "Switch", "AMP Power" }, 1142576c57e6SKiseok Jo { "SPK", NULL, "AMP Enable" }, 1143576c57e6SKiseok Jo 1144576c57e6SKiseok Jo /* Capture */ 1145576c57e6SKiseok Jo { "AIF OUT", NULL, "AMP Enable" }, 1146576c57e6SKiseok Jo }; 1147576c57e6SKiseok Jo 1148576c57e6SKiseok Jo static void sma1307_setup_pll(struct snd_soc_component *component, 1149576c57e6SKiseok Jo unsigned int bclk) 1150576c57e6SKiseok Jo { 1151576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1152576c57e6SKiseok Jo 1153576c57e6SKiseok Jo int i = 0; 1154576c57e6SKiseok Jo 1155576c57e6SKiseok Jo dev_dbg(component->dev, "%s: BCLK = %dHz\n", __func__, bclk); 1156576c57e6SKiseok Jo 1157576c57e6SKiseok Jo if (sma1307->sys_clk_id == SMA1307_PLL_CLKIN_MCLK) { 1158576c57e6SKiseok Jo dev_warn(component->dev, "%s: MCLK is not supported\n", 1159576c57e6SKiseok Jo __func__); 1160576c57e6SKiseok Jo } else if (sma1307->sys_clk_id == SMA1307_PLL_CLKIN_BCLK) { 1161576c57e6SKiseok Jo for (i = 0; i < sma1307->num_of_pll_matches; i++) { 1162576c57e6SKiseok Jo if (sma1307->pll_matches[i].input_clk == bclk) 1163576c57e6SKiseok Jo break; 1164576c57e6SKiseok Jo } 1165576c57e6SKiseok Jo if (i == sma1307->num_of_pll_matches) { 1166576c57e6SKiseok Jo dev_warn(component->dev, 1167576c57e6SKiseok Jo "%s: No matching value between pll table and SCK\n", 1168576c57e6SKiseok Jo __func__); 1169576c57e6SKiseok Jo return; 1170576c57e6SKiseok Jo } 1171576c57e6SKiseok Jo 1172576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1173576c57e6SKiseok Jo SMA1307_A2_TOP_MAN1, 1174576c57e6SKiseok Jo SMA1307_PLL_MASK, SMA1307_PLL_ON); 1175576c57e6SKiseok Jo } 1176576c57e6SKiseok Jo 1177576c57e6SKiseok Jo regmap_write(sma1307->regmap, SMA1307_8B_PLL_POST_N, 1178576c57e6SKiseok Jo sma1307->pll_matches[i].post_n); 1179576c57e6SKiseok Jo regmap_write(sma1307->regmap, SMA1307_8C_PLL_N, 1180576c57e6SKiseok Jo sma1307->pll_matches[i].n); 1181576c57e6SKiseok Jo regmap_write(sma1307->regmap, SMA1307_8D_PLL_A_SETTING, 1182576c57e6SKiseok Jo sma1307->pll_matches[i].vco); 1183576c57e6SKiseok Jo regmap_write(sma1307->regmap, SMA1307_8E_PLL_P_CP, 1184576c57e6SKiseok Jo sma1307->pll_matches[i].p_cp); 1185576c57e6SKiseok Jo } 1186576c57e6SKiseok Jo 1187576c57e6SKiseok Jo static int sma1307_dai_hw_params_amp(struct snd_pcm_substream *substream, 1188576c57e6SKiseok Jo struct snd_pcm_hw_params *params, 1189576c57e6SKiseok Jo struct snd_soc_dai *dai) 1190576c57e6SKiseok Jo { 1191576c57e6SKiseok Jo struct snd_soc_component *component = dai->component; 1192576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1193576c57e6SKiseok Jo unsigned int bclk = 0; 1194576c57e6SKiseok Jo 1195576c57e6SKiseok Jo if (sma1307->format == SND_SOC_DAIFMT_DSP_A) 1196576c57e6SKiseok Jo bclk = params_rate(params) * sma1307->frame_size; 1197576c57e6SKiseok Jo else 1198576c57e6SKiseok Jo bclk = params_rate(params) * params_physical_width(params) 1199576c57e6SKiseok Jo * params_channels(params); 1200576c57e6SKiseok Jo 1201576c57e6SKiseok Jo dev_dbg(component->dev, 1202576c57e6SKiseok Jo "%s: rate = %d : bit size = %d : channel = %d\n", 1203576c57e6SKiseok Jo __func__, params_rate(params), params_width(params), 1204576c57e6SKiseok Jo params_channels(params)); 1205576c57e6SKiseok Jo 1206576c57e6SKiseok Jo if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 1207576c57e6SKiseok Jo if (sma1307->sys_clk_id == SMA1307_PLL_CLKIN_BCLK) { 1208576c57e6SKiseok Jo if (sma1307->last_bclk != bclk) { 1209576c57e6SKiseok Jo sma1307_setup_pll(component, bclk); 1210576c57e6SKiseok Jo sma1307->last_bclk = bclk; 1211576c57e6SKiseok Jo } 1212576c57e6SKiseok Jo } 1213576c57e6SKiseok Jo 1214576c57e6SKiseok Jo switch (params_rate(params)) { 1215576c57e6SKiseok Jo case 8000: 1216576c57e6SKiseok Jo case 12000: 1217576c57e6SKiseok Jo case 16000: 1218576c57e6SKiseok Jo case 24000: 1219576c57e6SKiseok Jo case 32000: 1220576c57e6SKiseok Jo case 44100: 1221576c57e6SKiseok Jo case 48000: 1222576c57e6SKiseok Jo break; 1223576c57e6SKiseok Jo 1224576c57e6SKiseok Jo case 96000: 1225576c57e6SKiseok Jo dev_warn(component->dev, 1226576c57e6SKiseok Jo "%s: %d rate not support SDO\n", __func__, 1227576c57e6SKiseok Jo params_rate(params)); 1228576c57e6SKiseok Jo break; 1229576c57e6SKiseok Jo 1230576c57e6SKiseok Jo default: 1231576c57e6SKiseok Jo dev_err(component->dev, "%s: not support rate : %d\n", 1232576c57e6SKiseok Jo __func__, params_rate(params)); 1233576c57e6SKiseok Jo 1234576c57e6SKiseok Jo return -EINVAL; 1235576c57e6SKiseok Jo } 1236576c57e6SKiseok Jo 1237576c57e6SKiseok Jo /* substream->stream is SNDRV_PCM_STREAM_CAPTURE */ 1238576c57e6SKiseok Jo } else { 1239576c57e6SKiseok Jo 1240576c57e6SKiseok Jo switch (params_format(params)) { 1241576c57e6SKiseok Jo case SNDRV_PCM_FORMAT_S16_LE: 1242576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1243576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1244576c57e6SKiseok Jo SMA1307_SCK_RATE_MASK 1245576c57e6SKiseok Jo | 1246576c57e6SKiseok Jo SMA1307_DATA_WIDTH_MASK, 1247576c57e6SKiseok Jo SMA1307_SCK_32FS | 1248576c57e6SKiseok Jo SMA1307_DATA_16BIT); 1249576c57e6SKiseok Jo break; 1250576c57e6SKiseok Jo 1251576c57e6SKiseok Jo case SNDRV_PCM_FORMAT_S24_LE: 1252576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1253576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1254576c57e6SKiseok Jo SMA1307_SCK_RATE_MASK 1255576c57e6SKiseok Jo | 1256576c57e6SKiseok Jo SMA1307_DATA_WIDTH_MASK, 1257576c57e6SKiseok Jo SMA1307_SCK_64FS | 1258576c57e6SKiseok Jo SMA1307_DATA_24BIT); 1259576c57e6SKiseok Jo break; 1260576c57e6SKiseok Jo 1261576c57e6SKiseok Jo case SNDRV_PCM_FORMAT_S32_LE: 1262576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1263576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1264576c57e6SKiseok Jo SMA1307_SCK_RATE_MASK 1265576c57e6SKiseok Jo | 1266576c57e6SKiseok Jo SMA1307_DATA_WIDTH_MASK, 1267576c57e6SKiseok Jo SMA1307_SCK_64FS | 1268576c57e6SKiseok Jo SMA1307_DATA_24BIT); 1269576c57e6SKiseok Jo break; 1270576c57e6SKiseok Jo default: 1271576c57e6SKiseok Jo dev_err(component->dev, 1272576c57e6SKiseok Jo "%s: not support data bit : %d\n", __func__, 1273576c57e6SKiseok Jo params_format(params)); 1274576c57e6SKiseok Jo return -EINVAL; 1275576c57e6SKiseok Jo } 1276576c57e6SKiseok Jo } 1277576c57e6SKiseok Jo 1278576c57e6SKiseok Jo switch (sma1307->format) { 1279576c57e6SKiseok Jo case SND_SOC_DAIFMT_I2S: 1280576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1281576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1282576c57e6SKiseok Jo SMA1307_I2S_MODE_MASK, 1283576c57e6SKiseok Jo SMA1307_STANDARD_I2S); 1284576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1285576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1286576c57e6SKiseok Jo SMA1307_INTERFACE_MASK, 1287576c57e6SKiseok Jo SMA1307_I2S_FORMAT); 1288576c57e6SKiseok Jo break; 1289576c57e6SKiseok Jo case SND_SOC_DAIFMT_LEFT_J: 1290576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1291576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1292576c57e6SKiseok Jo SMA1307_I2S_MODE_MASK, SMA1307_LJ); 1293576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1294576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1295576c57e6SKiseok Jo SMA1307_INTERFACE_MASK, 1296576c57e6SKiseok Jo SMA1307_LJ_FORMAT); 1297576c57e6SKiseok Jo break; 1298576c57e6SKiseok Jo case SND_SOC_DAIFMT_RIGHT_J: 1299576c57e6SKiseok Jo switch (params_width(params)) { 1300576c57e6SKiseok Jo case 16: 1301576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1302576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1303576c57e6SKiseok Jo SMA1307_I2S_MODE_MASK, 1304576c57e6SKiseok Jo SMA1307_RJ_16BIT); 1305576c57e6SKiseok Jo break; 1306576c57e6SKiseok Jo case 24: 1307576c57e6SKiseok Jo case 32: 1308576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1309576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1310576c57e6SKiseok Jo SMA1307_I2S_MODE_MASK, 1311576c57e6SKiseok Jo SMA1307_RJ_24BIT); 1312576c57e6SKiseok Jo break; 1313576c57e6SKiseok Jo } 1314576c57e6SKiseok Jo break; 1315576c57e6SKiseok Jo case SND_SOC_DAIFMT_DSP_A: 1316576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1317576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1318576c57e6SKiseok Jo SMA1307_I2S_MODE_MASK, 1319576c57e6SKiseok Jo SMA1307_STANDARD_I2S); 1320576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1321576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1322576c57e6SKiseok Jo SMA1307_INTERFACE_MASK, 1323576c57e6SKiseok Jo SMA1307_TDM_FORMAT); 1324576c57e6SKiseok Jo break; 1325576c57e6SKiseok Jo } 1326576c57e6SKiseok Jo 1327576c57e6SKiseok Jo switch (params_width(params)) { 1328576c57e6SKiseok Jo case 16: 1329576c57e6SKiseok Jo case 24: 1330576c57e6SKiseok Jo case 32: 1331576c57e6SKiseok Jo break; 1332576c57e6SKiseok Jo default: 1333576c57e6SKiseok Jo dev_err(component->dev, 1334576c57e6SKiseok Jo "%s: not support data bit : %d\n", __func__, 1335576c57e6SKiseok Jo params_format(params)); 1336576c57e6SKiseok Jo return -EINVAL; 1337576c57e6SKiseok Jo } 1338576c57e6SKiseok Jo 1339576c57e6SKiseok Jo return 0; 1340576c57e6SKiseok Jo } 1341576c57e6SKiseok Jo 1342576c57e6SKiseok Jo static int sma1307_dai_set_sysclk_amp(struct snd_soc_dai *dai, 1343576c57e6SKiseok Jo int clk_id, unsigned int freq, int dir) 1344576c57e6SKiseok Jo { 1345576c57e6SKiseok Jo struct snd_soc_component *component = dai->component; 1346576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1347576c57e6SKiseok Jo 1348576c57e6SKiseok Jo switch (clk_id) { 1349576c57e6SKiseok Jo case SMA1307_EXTERNAL_CLOCK_19_2: 1350576c57e6SKiseok Jo case SMA1307_EXTERNAL_CLOCK_24_576: 1351576c57e6SKiseok Jo case SMA1307_PLL_CLKIN_MCLK: 1352576c57e6SKiseok Jo case SMA1307_PLL_CLKIN_BCLK: 1353576c57e6SKiseok Jo break; 1354576c57e6SKiseok Jo default: 1355576c57e6SKiseok Jo dev_err(component->dev, "%s: Invalid clk id: %d\n", 1356576c57e6SKiseok Jo __func__, clk_id); 1357576c57e6SKiseok Jo return -EINVAL; 1358576c57e6SKiseok Jo } 1359576c57e6SKiseok Jo sma1307->sys_clk_id = clk_id; 1360576c57e6SKiseok Jo 1361576c57e6SKiseok Jo return 0; 1362576c57e6SKiseok Jo } 1363576c57e6SKiseok Jo 1364576c57e6SKiseok Jo static int sma1307_dai_set_fmt_amp(struct snd_soc_dai *dai, unsigned int fmt) 1365576c57e6SKiseok Jo { 1366576c57e6SKiseok Jo struct snd_soc_component *component = dai->component; 1367576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1368576c57e6SKiseok Jo 1369576c57e6SKiseok Jo switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1370576c57e6SKiseok Jo 1371576c57e6SKiseok Jo case SND_SOC_DAIFMT_CBC_CFC: 1372576c57e6SKiseok Jo dev_dbg(component->dev, 1373576c57e6SKiseok Jo "%s: %s\n", __func__, "I2S/TDM Device mode"); 1374576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1375576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1376576c57e6SKiseok Jo SMA1307_CONTROLLER_DEVICE_MASK, 1377576c57e6SKiseok Jo SMA1307_DEVICE_MODE); 1378576c57e6SKiseok Jo break; 1379576c57e6SKiseok Jo 1380576c57e6SKiseok Jo case SND_SOC_DAIFMT_CBP_CFP: 1381576c57e6SKiseok Jo dev_dbg(component->dev, 1382576c57e6SKiseok Jo "%s: %s\n", __func__, "I2S/TDM Controller mode"); 1383576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1384576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1385576c57e6SKiseok Jo SMA1307_CONTROLLER_DEVICE_MASK, 1386576c57e6SKiseok Jo SMA1307_CONTROLLER_MODE); 1387576c57e6SKiseok Jo break; 1388576c57e6SKiseok Jo 1389576c57e6SKiseok Jo default: 1390576c57e6SKiseok Jo dev_err(component->dev, 1391576c57e6SKiseok Jo "%s: Unsupported Controller/Device : 0x%x\n", 1392576c57e6SKiseok Jo __func__, fmt); 1393576c57e6SKiseok Jo return -EINVAL; 1394576c57e6SKiseok Jo } 1395576c57e6SKiseok Jo 1396576c57e6SKiseok Jo switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1397576c57e6SKiseok Jo case SND_SOC_DAIFMT_I2S: 1398576c57e6SKiseok Jo case SND_SOC_DAIFMT_RIGHT_J: 1399576c57e6SKiseok Jo case SND_SOC_DAIFMT_LEFT_J: 1400576c57e6SKiseok Jo case SND_SOC_DAIFMT_DSP_A: 1401576c57e6SKiseok Jo case SND_SOC_DAIFMT_DSP_B: 1402576c57e6SKiseok Jo sma1307->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 1403576c57e6SKiseok Jo break; 1404576c57e6SKiseok Jo default: 1405576c57e6SKiseok Jo dev_err(component->dev, 1406576c57e6SKiseok Jo "%s: Unsupported Audio Interface Format : 0x%x\n", 1407576c57e6SKiseok Jo __func__, fmt); 1408576c57e6SKiseok Jo return -EINVAL; 1409576c57e6SKiseok Jo } 1410576c57e6SKiseok Jo 1411576c57e6SKiseok Jo switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1412576c57e6SKiseok Jo 1413576c57e6SKiseok Jo case SND_SOC_DAIFMT_IB_NF: 1414576c57e6SKiseok Jo dev_dbg(component->dev, "%s: %s\n", 1415576c57e6SKiseok Jo __func__, "Invert BCLK + Normal Frame"); 1416576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1417576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1418576c57e6SKiseok Jo SMA1307_SCK_RISING_MASK, 1419576c57e6SKiseok Jo SMA1307_SCK_RISING_EDGE); 1420576c57e6SKiseok Jo break; 1421576c57e6SKiseok Jo case SND_SOC_DAIFMT_IB_IF: 1422576c57e6SKiseok Jo dev_dbg(component->dev, "%s: %s\n", 1423576c57e6SKiseok Jo __func__, "Invert BCLK + Invert Frame"); 1424576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1425576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1426576c57e6SKiseok Jo SMA1307_LEFTPOL_MASK 1427576c57e6SKiseok Jo | SMA1307_SCK_RISING_MASK, 1428576c57e6SKiseok Jo SMA1307_HIGH_FIRST_CH 1429576c57e6SKiseok Jo | SMA1307_SCK_RISING_EDGE); 1430576c57e6SKiseok Jo break; 1431576c57e6SKiseok Jo case SND_SOC_DAIFMT_NB_IF: 1432576c57e6SKiseok Jo dev_dbg(component->dev, "%s: %s\n", 1433576c57e6SKiseok Jo __func__, "Normal BCLK + Invert Frame"); 1434576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1435576c57e6SKiseok Jo SMA1307_01_INPUT_CTRL1, 1436576c57e6SKiseok Jo SMA1307_LEFTPOL_MASK, 1437576c57e6SKiseok Jo SMA1307_HIGH_FIRST_CH); 1438576c57e6SKiseok Jo break; 1439576c57e6SKiseok Jo case SND_SOC_DAIFMT_NB_NF: 1440576c57e6SKiseok Jo dev_dbg(component->dev, "%s: %s\n", 1441576c57e6SKiseok Jo __func__, "Normal BCLK + Normal Frame"); 1442576c57e6SKiseok Jo break; 1443576c57e6SKiseok Jo default: 1444576c57e6SKiseok Jo dev_err(component->dev, 1445576c57e6SKiseok Jo "%s: Unsupported Bit & Frameclock : 0x%x\n", 1446576c57e6SKiseok Jo __func__, fmt); 1447576c57e6SKiseok Jo return -EINVAL; 1448576c57e6SKiseok Jo } 1449576c57e6SKiseok Jo 1450576c57e6SKiseok Jo return 0; 1451576c57e6SKiseok Jo } 1452576c57e6SKiseok Jo 1453576c57e6SKiseok Jo static int sma1307_dai_set_tdm_slot(struct snd_soc_dai *dai, 1454576c57e6SKiseok Jo unsigned int tx_mask, unsigned int rx_mask, 1455576c57e6SKiseok Jo int slots, int slot_width) 1456576c57e6SKiseok Jo { 1457576c57e6SKiseok Jo struct snd_soc_component *component = dai->component; 1458576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1459576c57e6SKiseok Jo 1460576c57e6SKiseok Jo dev_dbg(component->dev, "%s: slots = %d, slot_width - %d\n", 1461576c57e6SKiseok Jo __func__, slots, slot_width); 1462576c57e6SKiseok Jo 1463576c57e6SKiseok Jo sma1307->frame_size = slot_width * slots; 1464576c57e6SKiseok Jo 1465576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1466576c57e6SKiseok Jo SMA1307_A4_TOP_MAN3, 1467576c57e6SKiseok Jo SMA1307_INTERFACE_MASK, SMA1307_TDM_FORMAT); 1468576c57e6SKiseok Jo 1469576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1470576c57e6SKiseok Jo SMA1307_A5_TDM1, 1471576c57e6SKiseok Jo SMA1307_TDM_TX_MODE_MASK, 1472576c57e6SKiseok Jo SMA1307_TDM_TX_MONO); 1473576c57e6SKiseok Jo 1474576c57e6SKiseok Jo switch (slot_width) { 1475576c57e6SKiseok Jo case 16: 1476576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1477576c57e6SKiseok Jo SMA1307_A6_TDM2, 1478576c57e6SKiseok Jo SMA1307_TDM_DL_MASK, 1479576c57e6SKiseok Jo SMA1307_TDM_DL_16); 1480576c57e6SKiseok Jo break; 1481576c57e6SKiseok Jo case 32: 1482576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1483576c57e6SKiseok Jo SMA1307_A6_TDM2, 1484576c57e6SKiseok Jo SMA1307_TDM_DL_MASK, 1485576c57e6SKiseok Jo SMA1307_TDM_DL_32); 1486576c57e6SKiseok Jo break; 1487576c57e6SKiseok Jo default: 1488576c57e6SKiseok Jo dev_err(component->dev, "%s: not support TDM %d slot_width\n", 1489576c57e6SKiseok Jo __func__, slot_width); 1490576c57e6SKiseok Jo return -EINVAL; 1491576c57e6SKiseok Jo } 1492576c57e6SKiseok Jo 1493576c57e6SKiseok Jo switch (slots) { 1494576c57e6SKiseok Jo case 4: 1495576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1496576c57e6SKiseok Jo SMA1307_A6_TDM2, 1497576c57e6SKiseok Jo SMA1307_TDM_N_SLOT_MASK, 1498576c57e6SKiseok Jo SMA1307_TDM_N_SLOT_4); 1499576c57e6SKiseok Jo break; 1500576c57e6SKiseok Jo case 8: 1501576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1502576c57e6SKiseok Jo SMA1307_A6_TDM2, 1503576c57e6SKiseok Jo SMA1307_TDM_N_SLOT_MASK, 1504576c57e6SKiseok Jo SMA1307_TDM_N_SLOT_8); 1505576c57e6SKiseok Jo break; 1506576c57e6SKiseok Jo default: 1507576c57e6SKiseok Jo dev_err(component->dev, "%s: not support TDM %d slots\n", 1508576c57e6SKiseok Jo __func__, slots); 1509576c57e6SKiseok Jo return -EINVAL; 1510576c57e6SKiseok Jo } 1511576c57e6SKiseok Jo 1512576c57e6SKiseok Jo if (sma1307->tdm_slot0_rx < slots) 1513576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1514576c57e6SKiseok Jo SMA1307_A5_TDM1, 1515576c57e6SKiseok Jo SMA1307_TDM_SLOT0_RX_POS_MASK, 1516576c57e6SKiseok Jo sma1307->tdm_slot0_rx << 3); 1517576c57e6SKiseok Jo else 1518576c57e6SKiseok Jo dev_err(component->dev, "%s: Incorrect tdm-slot0-rx %d set\n", 1519576c57e6SKiseok Jo __func__, sma1307->tdm_slot0_rx); 1520576c57e6SKiseok Jo 1521576c57e6SKiseok Jo if (sma1307->tdm_slot1_rx < slots) 1522576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1523576c57e6SKiseok Jo SMA1307_A5_TDM1, 1524576c57e6SKiseok Jo SMA1307_TDM_SLOT1_RX_POS_MASK, 1525576c57e6SKiseok Jo sma1307->tdm_slot1_rx); 1526576c57e6SKiseok Jo else 1527576c57e6SKiseok Jo dev_err(component->dev, "%s: Incorrect tdm-slot1-rx %d set\n", 1528576c57e6SKiseok Jo __func__, sma1307->tdm_slot1_rx); 1529576c57e6SKiseok Jo 1530576c57e6SKiseok Jo if (sma1307->tdm_slot0_tx < slots) 1531576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1532576c57e6SKiseok Jo SMA1307_A6_TDM2, 1533576c57e6SKiseok Jo SMA1307_TDM_SLOT0_TX_POS_MASK, 1534576c57e6SKiseok Jo sma1307->tdm_slot0_tx << 3); 1535576c57e6SKiseok Jo else 1536576c57e6SKiseok Jo dev_err(component->dev, "%s: Incorrect tdm-slot0-tx %d set\n", 1537576c57e6SKiseok Jo __func__, sma1307->tdm_slot0_tx); 1538576c57e6SKiseok Jo 1539576c57e6SKiseok Jo if (sma1307->tdm_slot1_tx < slots) 1540576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1541576c57e6SKiseok Jo SMA1307_A6_TDM2, 1542576c57e6SKiseok Jo SMA1307_TDM_SLOT1_TX_POS_MASK, 1543576c57e6SKiseok Jo sma1307->tdm_slot1_tx); 1544576c57e6SKiseok Jo else 1545576c57e6SKiseok Jo dev_err(component->dev, "%s: Incorrect tdm-slot1-tx %d set\n", 1546576c57e6SKiseok Jo __func__, sma1307->tdm_slot1_tx); 1547576c57e6SKiseok Jo 1548576c57e6SKiseok Jo return 0; 1549576c57e6SKiseok Jo } 1550576c57e6SKiseok Jo 1551576c57e6SKiseok Jo static int sma1307_dai_mute_stream(struct snd_soc_dai *dai, int mute, 1552576c57e6SKiseok Jo int stream) 1553576c57e6SKiseok Jo { 1554576c57e6SKiseok Jo struct snd_soc_component *component = dai->component; 1555576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1556576c57e6SKiseok Jo 1557576c57e6SKiseok Jo if (stream == SNDRV_PCM_STREAM_CAPTURE) 1558576c57e6SKiseok Jo return 0; 1559576c57e6SKiseok Jo if (mute) { 1560576c57e6SKiseok Jo dev_dbg(component->dev, "%s: %s\n", __func__, "MUTE"); 1561576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1562576c57e6SKiseok Jo SMA1307_0E_MUTE_VOL_CTRL, 1563576c57e6SKiseok Jo SMA1307_SPK_MUTE_MASK, 1564576c57e6SKiseok Jo SMA1307_SPK_MUTE); 1565576c57e6SKiseok Jo } else { 1566576c57e6SKiseok Jo if (!sma1307->force_mute_status) { 1567576c57e6SKiseok Jo dev_dbg(component->dev, "%s: %s\n", __func__, 1568576c57e6SKiseok Jo "UNMUTE"); 1569576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1570576c57e6SKiseok Jo SMA1307_0E_MUTE_VOL_CTRL, 1571576c57e6SKiseok Jo SMA1307_SPK_MUTE_MASK, 1572576c57e6SKiseok Jo SMA1307_SPK_UNMUTE); 1573576c57e6SKiseok Jo } else { 1574576c57e6SKiseok Jo dev_dbg(sma1307->dev, "%s: FORCE MUTE!!!\n", __func__); 1575576c57e6SKiseok Jo } 1576576c57e6SKiseok Jo } 1577576c57e6SKiseok Jo 1578576c57e6SKiseok Jo return 0; 1579576c57e6SKiseok Jo } 1580576c57e6SKiseok Jo 1581576c57e6SKiseok Jo static const struct snd_soc_dai_ops sma1307_dai_ops_amp = { 1582576c57e6SKiseok Jo .hw_params = sma1307_dai_hw_params_amp, 1583576c57e6SKiseok Jo .set_fmt = sma1307_dai_set_fmt_amp, 1584576c57e6SKiseok Jo .set_sysclk = sma1307_dai_set_sysclk_amp, 1585576c57e6SKiseok Jo .set_tdm_slot = sma1307_dai_set_tdm_slot, 1586576c57e6SKiseok Jo .mute_stream = sma1307_dai_mute_stream, 1587576c57e6SKiseok Jo }; 1588576c57e6SKiseok Jo 1589576c57e6SKiseok Jo #define SMA1307_RATES_PLAYBACK SNDRV_PCM_RATE_8000_96000 1590576c57e6SKiseok Jo #define SMA1307_RATES_CAPTURE SNDRV_PCM_RATE_8000_48000 1591576c57e6SKiseok Jo #define SMA1307_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \ 1592576c57e6SKiseok Jo SNDRV_PCM_FMTBIT_S32_LE) 1593576c57e6SKiseok Jo 1594576c57e6SKiseok Jo static struct snd_soc_dai_driver sma1307_dai[] = { 1595576c57e6SKiseok Jo { 1596576c57e6SKiseok Jo .name = "sma1307-amplifier", 1597576c57e6SKiseok Jo .id = 0, 1598576c57e6SKiseok Jo .playback = { 1599576c57e6SKiseok Jo .stream_name = "Playback", 1600576c57e6SKiseok Jo .channels_min = 1, 1601576c57e6SKiseok Jo .channels_max = 2, 1602576c57e6SKiseok Jo .rates = SMA1307_RATES_PLAYBACK, 1603576c57e6SKiseok Jo .formats = SMA1307_FORMATS, 1604576c57e6SKiseok Jo }, 1605576c57e6SKiseok Jo .capture = { 1606576c57e6SKiseok Jo .stream_name = "Capture", 1607576c57e6SKiseok Jo .channels_min = 1, 1608576c57e6SKiseok Jo .channels_max = 2, 1609576c57e6SKiseok Jo .rates = SMA1307_RATES_CAPTURE, 1610576c57e6SKiseok Jo .formats = SMA1307_FORMATS, 1611576c57e6SKiseok Jo }, 1612576c57e6SKiseok Jo .ops = &sma1307_dai_ops_amp, 1613576c57e6SKiseok Jo }, 1614576c57e6SKiseok Jo }; 1615576c57e6SKiseok Jo 1616576c57e6SKiseok Jo static void sma1307_check_fault_worker(struct work_struct *work) 1617576c57e6SKiseok Jo { 1618576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 1619576c57e6SKiseok Jo container_of(work, struct sma1307_priv, check_fault_work.work); 1620576c57e6SKiseok Jo unsigned int status1_val, status2_val; 1621576c57e6SKiseok Jo char *envp[3] = { NULL, NULL, NULL }; 1622576c57e6SKiseok Jo 1623576c57e6SKiseok Jo if (sma1307->tsdw_cnt) 1624576c57e6SKiseok Jo regmap_read(sma1307->regmap, 1625576c57e6SKiseok Jo SMA1307_0A_SPK_VOL, &sma1307->cur_vol); 1626576c57e6SKiseok Jo else 1627576c57e6SKiseok Jo regmap_read(sma1307->regmap, 1628576c57e6SKiseok Jo SMA1307_0A_SPK_VOL, &sma1307->init_vol); 1629576c57e6SKiseok Jo 1630576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_FA_STATUS1, &status1_val); 1631576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_FB_STATUS2, &status2_val); 1632576c57e6SKiseok Jo 1633576c57e6SKiseok Jo if (~status1_val & SMA1307_OT1_OK_STATUS) { 1634576c57e6SKiseok Jo dev_crit(sma1307->dev, 1635576c57e6SKiseok Jo "%s: OT1(Over Temperature Level 1)\n", __func__); 1636576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=OT1"); 1637576c57e6SKiseok Jo if (sma1307->sw_ot1_prot) { 1638576c57e6SKiseok Jo /* Volume control (Current Volume -3dB) */ 1639576c57e6SKiseok Jo if ((sma1307->cur_vol + 6) <= 0xFA) { 1640576c57e6SKiseok Jo sma1307->cur_vol += 6; 1641576c57e6SKiseok Jo regmap_write(sma1307->regmap, 1642576c57e6SKiseok Jo SMA1307_0A_SPK_VOL, 1643576c57e6SKiseok Jo sma1307->cur_vol); 1644576c57e6SKiseok Jo envp[1] = kasprintf(GFP_KERNEL, 1645576c57e6SKiseok Jo "VOLUME=0x%02X", sma1307->cur_vol); 1646576c57e6SKiseok Jo } 1647576c57e6SKiseok Jo } 1648576c57e6SKiseok Jo sma1307->tsdw_cnt++; 1649576c57e6SKiseok Jo } else if (sma1307->tsdw_cnt) { 1650576c57e6SKiseok Jo regmap_write(sma1307->regmap, 1651576c57e6SKiseok Jo SMA1307_0A_SPK_VOL, sma1307->init_vol); 1652576c57e6SKiseok Jo sma1307->tsdw_cnt = 0; 1653576c57e6SKiseok Jo sma1307->cur_vol = sma1307->init_vol; 1654576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=OT1_CLEAR"); 1655576c57e6SKiseok Jo envp[1] = kasprintf(GFP_KERNEL, 1656576c57e6SKiseok Jo "VOLUME=0x%02X", sma1307->cur_vol); 1657576c57e6SKiseok Jo } 1658576c57e6SKiseok Jo 1659576c57e6SKiseok Jo if (~status1_val & SMA1307_OT2_OK_STATUS) { 1660576c57e6SKiseok Jo dev_crit(sma1307->dev, 1661576c57e6SKiseok Jo "%s: OT2(Over Temperature Level 2)\n", __func__); 1662576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=OT2"); 1663576c57e6SKiseok Jo } 1664576c57e6SKiseok Jo if (status1_val & SMA1307_UVLO_STATUS) { 1665576c57e6SKiseok Jo dev_crit(sma1307->dev, 1666576c57e6SKiseok Jo "%s: UVLO(Under Voltage Lock Out)\n", __func__); 1667576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=UVLO"); 1668576c57e6SKiseok Jo } 1669576c57e6SKiseok Jo if (status1_val & SMA1307_OVP_BST_STATUS) { 1670576c57e6SKiseok Jo dev_crit(sma1307->dev, 1671576c57e6SKiseok Jo "%s: OVP_BST(Over Voltage Protection)\n", __func__); 1672576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=OVP_BST"); 1673576c57e6SKiseok Jo } 1674576c57e6SKiseok Jo if (status2_val & SMA1307_OCP_SPK_STATUS) { 1675576c57e6SKiseok Jo dev_crit(sma1307->dev, 1676576c57e6SKiseok Jo "%s: OCP_SPK(Over Current Protect SPK)\n", __func__); 1677576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=OCP_SPK"); 1678576c57e6SKiseok Jo } 1679576c57e6SKiseok Jo if (status2_val & SMA1307_OCP_BST_STATUS) { 1680576c57e6SKiseok Jo dev_crit(sma1307->dev, 1681576c57e6SKiseok Jo "%s: OCP_BST(Over Current Protect Boost)\n", __func__); 1682576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=OCP_BST"); 1683576c57e6SKiseok Jo } 1684576c57e6SKiseok Jo if (status2_val & SMA1307_CLK_MON_STATUS) { 1685576c57e6SKiseok Jo dev_crit(sma1307->dev, 1686576c57e6SKiseok Jo "%s: CLK_FAULT(No clock input)\n", __func__); 1687576c57e6SKiseok Jo envp[0] = kasprintf(GFP_KERNEL, "STATUS=CLK_FAULT"); 1688576c57e6SKiseok Jo } 1689576c57e6SKiseok Jo 1690576c57e6SKiseok Jo if (envp[0] != NULL) { 1691576c57e6SKiseok Jo if (kobject_uevent_env(sma1307->kobj, KOBJ_CHANGE, envp)) 1692576c57e6SKiseok Jo dev_err(sma1307->dev, 1693576c57e6SKiseok Jo "%s: Error sending uevent\n", __func__); 1694576c57e6SKiseok Jo kfree(envp[0]); 1695576c57e6SKiseok Jo kfree(envp[1]); 1696576c57e6SKiseok Jo } 1697576c57e6SKiseok Jo 1698576c57e6SKiseok Jo if (sma1307->check_fault_status) { 1699576c57e6SKiseok Jo if (sma1307->check_fault_period > 0) 1700576c57e6SKiseok Jo queue_delayed_work(system_freezable_wq, 1701576c57e6SKiseok Jo &sma1307->check_fault_work, 1702576c57e6SKiseok Jo sma1307->check_fault_period * HZ); 1703576c57e6SKiseok Jo else 1704576c57e6SKiseok Jo queue_delayed_work(system_freezable_wq, 1705576c57e6SKiseok Jo &sma1307->check_fault_work, 1706576c57e6SKiseok Jo CHECK_PERIOD_TIME * HZ); 1707576c57e6SKiseok Jo } 1708576c57e6SKiseok Jo } 1709576c57e6SKiseok Jo 1710576c57e6SKiseok Jo static void sma1307_setting_loaded(struct sma1307_priv *sma1307, const char *file) 1711576c57e6SKiseok Jo { 1712576c57e6SKiseok Jo const struct firmware *fw; 1713576c57e6SKiseok Jo int *data, size, offset, num_mode; 1714*c48a4497SArnd Bergmann int ret; 1715576c57e6SKiseok Jo 1716*c48a4497SArnd Bergmann ret = request_firmware(&fw, file, sma1307->dev); 1717576c57e6SKiseok Jo 1718*c48a4497SArnd Bergmann if (ret) { 1719*c48a4497SArnd Bergmann dev_err(sma1307->dev, "%s: failed to read \"%s\": %pe\n", 1720*c48a4497SArnd Bergmann __func__, setting_file, ERR_PTR(ret)); 1721576c57e6SKiseok Jo sma1307->set.status = false; 1722576c57e6SKiseok Jo return; 1723576c57e6SKiseok Jo } else if ((fw->size) < SMA1307_SETTING_HEADER_SIZE) { 1724576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: Invalid file\n", __func__); 1725576c57e6SKiseok Jo release_firmware(fw); 1726576c57e6SKiseok Jo sma1307->set.status = false; 1727576c57e6SKiseok Jo return; 1728576c57e6SKiseok Jo } 1729576c57e6SKiseok Jo 1730576c57e6SKiseok Jo data = kzalloc(fw->size, GFP_KERNEL); 1731576c57e6SKiseok Jo size = fw->size >> 2; 1732576c57e6SKiseok Jo memcpy(data, fw->data, fw->size); 1733576c57e6SKiseok Jo 1734576c57e6SKiseok Jo release_firmware(fw); 1735576c57e6SKiseok Jo 1736576c57e6SKiseok Jo /* HEADER */ 1737576c57e6SKiseok Jo sma1307->set.header_size = SMA1307_SETTING_HEADER_SIZE; 1738576c57e6SKiseok Jo sma1307->set.checksum = data[sma1307->set.header_size - 2]; 1739576c57e6SKiseok Jo sma1307->set.num_mode = data[sma1307->set.header_size - 1]; 1740576c57e6SKiseok Jo num_mode = sma1307->set.num_mode; 1741576c57e6SKiseok Jo sma1307->set.header = devm_kzalloc(sma1307->dev, 1742576c57e6SKiseok Jo sma1307->set.header_size, 1743576c57e6SKiseok Jo GFP_KERNEL); 1744576c57e6SKiseok Jo memcpy(sma1307->set.header, data, 1745576c57e6SKiseok Jo sma1307->set.header_size * sizeof(int)); 1746576c57e6SKiseok Jo 1747576c57e6SKiseok Jo if ((sma1307->set.checksum >> 8) != SMA1307_SETTING_CHECKSUM) { 1748576c57e6SKiseok Jo dev_err(sma1307->dev, "%s: failed by dismatch \"%s\"\n", 1749576c57e6SKiseok Jo __func__, setting_file); 1750576c57e6SKiseok Jo sma1307->set.status = false; 1751576c57e6SKiseok Jo return; 1752576c57e6SKiseok Jo } 1753576c57e6SKiseok Jo 1754576c57e6SKiseok Jo /* DEFAULT */ 1755576c57e6SKiseok Jo sma1307->set.def_size = SMA1307_SETTING_DEFAULT_SIZE; 1756576c57e6SKiseok Jo sma1307->set.def 1757576c57e6SKiseok Jo = devm_kzalloc(sma1307->dev, 1758576c57e6SKiseok Jo sma1307->set.def_size * sizeof(int), GFP_KERNEL); 1759576c57e6SKiseok Jo memcpy(sma1307->set.def, 1760576c57e6SKiseok Jo &data[sma1307->set.header_size], 1761576c57e6SKiseok Jo sma1307->set.def_size * sizeof(int)); 1762576c57e6SKiseok Jo 1763576c57e6SKiseok Jo /* MODE */ 1764576c57e6SKiseok Jo offset = sma1307->set.header_size + sma1307->set.def_size; 1765576c57e6SKiseok Jo sma1307->set.mode_size = DIV_ROUND_CLOSEST(size - offset, num_mode + 1); 1766576c57e6SKiseok Jo for (int i = 0; i < num_mode; i++) { 1767576c57e6SKiseok Jo sma1307->set.mode_set[i] 1768576c57e6SKiseok Jo = devm_kzalloc(sma1307->dev, 1769576c57e6SKiseok Jo sma1307->set.mode_size * 2 * sizeof(int), 1770576c57e6SKiseok Jo GFP_KERNEL); 1771576c57e6SKiseok Jo for (int j = 0; j < sma1307->set.mode_size; j++) { 1772576c57e6SKiseok Jo sma1307->set.mode_set[i][2 * j] 1773576c57e6SKiseok Jo = data[offset + ((num_mode + 1) * j)]; 1774576c57e6SKiseok Jo sma1307->set.mode_set[i][2 * j + 1] 1775576c57e6SKiseok Jo = data[offset + ((num_mode + 1) * j + i + 1)]; 1776576c57e6SKiseok Jo } 1777576c57e6SKiseok Jo } 1778576c57e6SKiseok Jo 1779576c57e6SKiseok Jo kfree(data); 1780576c57e6SKiseok Jo sma1307->set.status = true; 1781576c57e6SKiseok Jo 1782576c57e6SKiseok Jo } 1783576c57e6SKiseok Jo 1784576c57e6SKiseok Jo static void sma1307_reset(struct snd_soc_component *component) 1785576c57e6SKiseok Jo { 1786576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1787576c57e6SKiseok Jo unsigned int status = 0; 1788576c57e6SKiseok Jo 1789576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_FF_DEVICE_INDEX, &status); 1790576c57e6SKiseok Jo 1791576c57e6SKiseok Jo sma1307->rev_num = status & SMA1307_REV_NUM_STATUS; 1792576c57e6SKiseok Jo dev_dbg(component->dev, "%s: SMA1307 Revision %d\n", 1793576c57e6SKiseok Jo __func__, sma1307->rev_num); 1794576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_99_OTP_TRM2, &sma1307->otp_trm2); 1795576c57e6SKiseok Jo regmap_read(sma1307->regmap, SMA1307_9A_OTP_TRM3, &sma1307->otp_trm3); 1796576c57e6SKiseok Jo 1797576c57e6SKiseok Jo if ((sma1307->otp_trm2 & SMA1307_OTP_STAT_MASK) != SMA1307_OTP_STAT_1) 1798576c57e6SKiseok Jo dev_warn(component->dev, "%s: SMA1307 OTP Status Fail\n", 1799576c57e6SKiseok Jo __func__); 1800576c57e6SKiseok Jo 1801576c57e6SKiseok Jo /* Register Initial Value Setting */ 1802576c57e6SKiseok Jo sma1307_setting_loaded(sma1307, setting_file); 1803576c57e6SKiseok Jo if (sma1307->set.status) 1804576c57e6SKiseok Jo sma1307_set_binary(component); 1805576c57e6SKiseok Jo else 1806576c57e6SKiseok Jo sma1307_set_default(component); 1807576c57e6SKiseok Jo 1808576c57e6SKiseok Jo regmap_update_bits(sma1307->regmap, 1809576c57e6SKiseok Jo SMA1307_93_INT_CTRL, 1810576c57e6SKiseok Jo SMA1307_DIS_INT_MASK, SMA1307_HIGH_Z_INT); 1811576c57e6SKiseok Jo regmap_write(sma1307->regmap, SMA1307_0A_SPK_VOL, sma1307->init_vol); 1812576c57e6SKiseok Jo } 1813576c57e6SKiseok Jo 1814576c57e6SKiseok Jo static void sma1307_set_binary(struct snd_soc_component *component) 1815576c57e6SKiseok Jo { 1816576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1817576c57e6SKiseok Jo int i = 0, mode = 0; 1818576c57e6SKiseok Jo 1819576c57e6SKiseok Jo for (i = 0; i < (sma1307->set.def_size); i++) { 1820576c57e6SKiseok Jo if (sma1307_writeable_register(sma1307->dev, i) 1821576c57e6SKiseok Jo && ((i < SMA1307_97_OTP_TRM0) 1822576c57e6SKiseok Jo || (i > SMA1307_9A_OTP_TRM3))) { 1823576c57e6SKiseok Jo regmap_write(sma1307->regmap, i, sma1307->set.def[i]); 1824576c57e6SKiseok Jo 1825576c57e6SKiseok Jo } 1826576c57e6SKiseok Jo } 1827576c57e6SKiseok Jo for (i = 0; i < (sma1307->set.mode_size); i++) { 1828576c57e6SKiseok Jo if (sma1307_writeable_register(sma1307->dev, i) 1829576c57e6SKiseok Jo && ((i < SMA1307_97_OTP_TRM0) 1830576c57e6SKiseok Jo || (i > SMA1307_9A_OTP_TRM3))) { 1831576c57e6SKiseok Jo mode = sma1307->binary_mode; 1832576c57e6SKiseok Jo regmap_write(sma1307->regmap, 1833576c57e6SKiseok Jo sma1307->set.mode_set[mode][2 * i], 1834576c57e6SKiseok Jo sma1307->set.mode_set[mode][2 * i + 1835576c57e6SKiseok Jo 1]); 1836576c57e6SKiseok Jo } 1837576c57e6SKiseok Jo } 1838576c57e6SKiseok Jo } 1839576c57e6SKiseok Jo 1840576c57e6SKiseok Jo static void sma1307_set_default(struct snd_soc_component *component) 1841576c57e6SKiseok Jo { 1842576c57e6SKiseok Jo struct sma1307_priv *sma1307 = snd_soc_component_get_drvdata(component); 1843576c57e6SKiseok Jo int i = 0; 1844576c57e6SKiseok Jo 1845576c57e6SKiseok Jo for (i = 0; i < (unsigned int)ARRAY_SIZE(sma1307_reg_def); i++) 1846576c57e6SKiseok Jo regmap_write(sma1307->regmap, 1847576c57e6SKiseok Jo sma1307_reg_def[i].reg, 1848576c57e6SKiseok Jo sma1307_reg_def[i].def); 1849576c57e6SKiseok Jo 1850576c57e6SKiseok Jo if (!strcmp(sma1307->name, DEVICE_NAME_SMA1307AQ)) 1851576c57e6SKiseok Jo sma1307->data->init(sma1307->regmap); 1852576c57e6SKiseok Jo } 1853576c57e6SKiseok Jo 1854576c57e6SKiseok Jo static int sma1307_probe(struct snd_soc_component *component) 1855576c57e6SKiseok Jo { 1856576c57e6SKiseok Jo struct snd_soc_dapm_context *dapm = 1857576c57e6SKiseok Jo snd_soc_component_get_dapm(component); 1858576c57e6SKiseok Jo 1859576c57e6SKiseok Jo snd_soc_dapm_sync(dapm); 1860576c57e6SKiseok Jo 1861576c57e6SKiseok Jo sma1307_amp_component = component; 1862576c57e6SKiseok Jo 1863576c57e6SKiseok Jo snd_soc_add_component_controls(component, sma1307_binary_mode_control, 1864576c57e6SKiseok Jo ARRAY_SIZE(sma1307_binary_mode_control)); 1865576c57e6SKiseok Jo sma1307_reset(component); 1866576c57e6SKiseok Jo 1867576c57e6SKiseok Jo return 0; 1868576c57e6SKiseok Jo } 1869576c57e6SKiseok Jo 1870576c57e6SKiseok Jo static const struct snd_soc_component_driver sma1307_component = { 1871576c57e6SKiseok Jo .probe = sma1307_probe, 1872576c57e6SKiseok Jo .controls = sma1307_snd_controls, 1873576c57e6SKiseok Jo .num_controls = ARRAY_SIZE(sma1307_snd_controls), 1874576c57e6SKiseok Jo .dapm_widgets = sma1307_dapm_widgets, 1875576c57e6SKiseok Jo .num_dapm_widgets = ARRAY_SIZE(sma1307_dapm_widgets), 1876576c57e6SKiseok Jo .dapm_routes = sma1307_audio_map, 1877576c57e6SKiseok Jo .num_dapm_routes = ARRAY_SIZE(sma1307_audio_map), 1878576c57e6SKiseok Jo }; 1879576c57e6SKiseok Jo 1880576c57e6SKiseok Jo static const struct regmap_config sma_i2c_regmap = { 1881576c57e6SKiseok Jo .reg_bits = 8, 1882576c57e6SKiseok Jo .val_bits = 8, 1883576c57e6SKiseok Jo 1884576c57e6SKiseok Jo .max_register = SMA1307_FF_DEVICE_INDEX, 1885576c57e6SKiseok Jo .readable_reg = sma1307_readable_register, 1886576c57e6SKiseok Jo .writeable_reg = sma1307_writeable_register, 1887576c57e6SKiseok Jo .volatile_reg = sma1307_volatile_register, 1888576c57e6SKiseok Jo 1889576c57e6SKiseok Jo .reg_defaults = sma1307_reg_def, 1890576c57e6SKiseok Jo .num_reg_defaults = ARRAY_SIZE(sma1307_reg_def), 1891576c57e6SKiseok Jo }; 1892576c57e6SKiseok Jo 1893576c57e6SKiseok Jo static void sma1307aq_init(struct regmap *regmap) 1894576c57e6SKiseok Jo { 1895576c57e6SKiseok Jo /* Guidelines for driving 4ohm load */ 1896576c57e6SKiseok Jo /* Brown Out Protection */ 1897576c57e6SKiseok Jo regmap_write(regmap, SMA1307_02_BROWN_OUT_PROT1, 0x62); 1898576c57e6SKiseok Jo regmap_write(regmap, SMA1307_03_BROWN_OUT_PROT2, 0x5D); 1899576c57e6SKiseok Jo regmap_write(regmap, SMA1307_04_BROWN_OUT_PROT3, 0x57); 1900576c57e6SKiseok Jo regmap_write(regmap, SMA1307_05_BROWN_OUT_PROT8, 0x54); 1901576c57e6SKiseok Jo regmap_write(regmap, SMA1307_06_BROWN_OUT_PROT9, 0x51); 1902576c57e6SKiseok Jo regmap_write(regmap, 1903576c57e6SKiseok Jo SMA1307_07_BROWN_OUT_PROT10, 0x4D); 1904576c57e6SKiseok Jo regmap_write(regmap, 1905576c57e6SKiseok Jo SMA1307_08_BROWN_OUT_PROT11, 0x4B); 1906576c57e6SKiseok Jo regmap_write(regmap, SMA1307_27_BROWN_OUT_PROT4, 0x3C); 1907576c57e6SKiseok Jo regmap_write(regmap, SMA1307_28_BROWN_OUT_PROT5, 0x5B); 1908576c57e6SKiseok Jo regmap_write(regmap, 1909576c57e6SKiseok Jo SMA1307_29_BROWN_OUT_PROT12, 0x78); 1910576c57e6SKiseok Jo regmap_write(regmap, 1911576c57e6SKiseok Jo SMA1307_2A_BROWN_OUT_PROT13, 0x96); 1912576c57e6SKiseok Jo regmap_write(regmap, 1913576c57e6SKiseok Jo SMA1307_2B_BROWN_OUT_PROT14, 0xB4); 1914576c57e6SKiseok Jo regmap_write(regmap, 1915576c57e6SKiseok Jo SMA1307_2C_BROWN_OUT_PROT15, 0xD3); 1916576c57e6SKiseok Jo /* FDPEC Gain */ 1917576c57e6SKiseok Jo regmap_write(regmap, SMA1307_35_FDPEC_CTRL0, 0x16); 1918576c57e6SKiseok Jo /* FLT Vdd */ 1919576c57e6SKiseok Jo regmap_write(regmap, SMA1307_92_FDPEC_CTRL1, 0xA0); 1920576c57e6SKiseok Jo /* Boost Max */ 1921576c57e6SKiseok Jo regmap_write(regmap, SMA1307_AB_BOOST_CTRL4, 0x0F); 1922576c57e6SKiseok Jo } 1923576c57e6SKiseok Jo 1924576c57e6SKiseok Jo static const struct sma1307_data sma1307aq_data = { 1925576c57e6SKiseok Jo .name = DEVICE_NAME_SMA1307AQ, 1926576c57e6SKiseok Jo .init = sma1307aq_init, 1927576c57e6SKiseok Jo }; 1928576c57e6SKiseok Jo 1929576c57e6SKiseok Jo static int sma1307_i2c_probe(struct i2c_client *client) 1930576c57e6SKiseok Jo { 1931576c57e6SKiseok Jo struct sma1307_priv *sma1307; 1932576c57e6SKiseok Jo const struct sma1307_data *data; 1933576c57e6SKiseok Jo int ret = 0; 1934576c57e6SKiseok Jo unsigned int device_info; 1935576c57e6SKiseok Jo 1936576c57e6SKiseok Jo sma1307 = devm_kzalloc(&client->dev, 1937576c57e6SKiseok Jo sizeof(*sma1307), GFP_KERNEL); 1938576c57e6SKiseok Jo if (!sma1307) 1939576c57e6SKiseok Jo return -ENOMEM; 1940576c57e6SKiseok Jo 1941576c57e6SKiseok Jo sma1307->regmap = devm_regmap_init_i2c(client, &sma_i2c_regmap); 1942576c57e6SKiseok Jo if (IS_ERR(sma1307->regmap)) { 1943576c57e6SKiseok Jo return dev_err_probe(&client->dev, PTR_ERR(sma1307->regmap), 1944576c57e6SKiseok Jo "%s: failed to allocate register map\n", __func__); 1945576c57e6SKiseok Jo } 1946576c57e6SKiseok Jo 1947576c57e6SKiseok Jo data = device_get_match_data(&client->dev); 1948576c57e6SKiseok Jo if (!data) 1949576c57e6SKiseok Jo return -ENODEV; 1950576c57e6SKiseok Jo 1951576c57e6SKiseok Jo sma1307->data = data; 1952576c57e6SKiseok Jo 1953576c57e6SKiseok Jo /* set initial value as normal AMP IC status */ 1954576c57e6SKiseok Jo sma1307->name = client->name; 1955576c57e6SKiseok Jo sma1307->format = SND_SOC_DAIFMT_I2S; 1956576c57e6SKiseok Jo sma1307->sys_clk_id = SMA1307_PLL_CLKIN_BCLK; 1957576c57e6SKiseok Jo sma1307->num_of_pll_matches = ARRAY_SIZE(sma1307_pll_matches); 1958576c57e6SKiseok Jo 1959576c57e6SKiseok Jo sma1307->check_fault_period = CHECK_PERIOD_TIME; 1960576c57e6SKiseok Jo sma1307->check_fault_status = true; 1961576c57e6SKiseok Jo sma1307->init_vol = 0x32; 1962576c57e6SKiseok Jo sma1307->cur_vol = sma1307->init_vol; 1963576c57e6SKiseok Jo sma1307->sw_ot1_prot = true; 1964576c57e6SKiseok Jo 1965576c57e6SKiseok Jo mutex_init(&sma1307->default_lock); 1966576c57e6SKiseok Jo 1967576c57e6SKiseok Jo INIT_DELAYED_WORK(&sma1307->check_fault_work, 1968576c57e6SKiseok Jo sma1307_check_fault_worker); 1969576c57e6SKiseok Jo 1970576c57e6SKiseok Jo sma1307->dev = &client->dev; 1971576c57e6SKiseok Jo sma1307->kobj = &client->dev.kobj; 1972576c57e6SKiseok Jo 1973576c57e6SKiseok Jo i2c_set_clientdata(client, sma1307); 1974576c57e6SKiseok Jo 1975576c57e6SKiseok Jo sma1307->pll_matches = sma1307_pll_matches; 1976576c57e6SKiseok Jo 1977576c57e6SKiseok Jo regmap_read(sma1307->regmap, 1978576c57e6SKiseok Jo SMA1307_FF_DEVICE_INDEX, &device_info); 1979576c57e6SKiseok Jo 1980576c57e6SKiseok Jo if ((device_info & 0xF8) != SMA1307_DEVICE_ID) { 1981576c57e6SKiseok Jo dev_err(&client->dev, 1982576c57e6SKiseok Jo "%s: device initialization error (0x%02X)", 1983576c57e6SKiseok Jo __func__, device_info); 1984576c57e6SKiseok Jo return -ENODEV; 1985576c57e6SKiseok Jo } 1986576c57e6SKiseok Jo dev_dbg(&client->dev, "%s: chip version 0x%02X\n", 1987576c57e6SKiseok Jo __func__, device_info); 1988576c57e6SKiseok Jo 1989576c57e6SKiseok Jo i2c_set_clientdata(client, sma1307); 1990576c57e6SKiseok Jo 1991576c57e6SKiseok Jo ret = devm_snd_soc_register_component(&client->dev, 1992576c57e6SKiseok Jo &sma1307_component, sma1307_dai, 1993576c57e6SKiseok Jo 1); 1994576c57e6SKiseok Jo 1995576c57e6SKiseok Jo if (ret) { 1996576c57e6SKiseok Jo dev_err(&client->dev, "%s: failed to register component\n", 1997576c57e6SKiseok Jo __func__); 1998576c57e6SKiseok Jo 1999576c57e6SKiseok Jo return ret; 2000576c57e6SKiseok Jo } 2001576c57e6SKiseok Jo 2002576c57e6SKiseok Jo return ret; 2003576c57e6SKiseok Jo } 2004576c57e6SKiseok Jo 2005576c57e6SKiseok Jo static void sma1307_i2c_remove(struct i2c_client *client) 2006576c57e6SKiseok Jo { 2007576c57e6SKiseok Jo struct sma1307_priv *sma1307 = 2008576c57e6SKiseok Jo (struct sma1307_priv *)i2c_get_clientdata(client); 2009576c57e6SKiseok Jo 2010576c57e6SKiseok Jo cancel_delayed_work_sync(&sma1307->check_fault_work); 2011576c57e6SKiseok Jo } 2012576c57e6SKiseok Jo 2013576c57e6SKiseok Jo static const struct i2c_device_id sma1307_i2c_id[] = { 2014576c57e6SKiseok Jo { "sma1307a", 0 }, 2015576c57e6SKiseok Jo { "sma1307aq", 0 }, 2016576c57e6SKiseok Jo { } 2017576c57e6SKiseok Jo }; 2018576c57e6SKiseok Jo 2019576c57e6SKiseok Jo MODULE_DEVICE_TABLE(i2c, sma1307_i2c_id); 2020576c57e6SKiseok Jo 2021576c57e6SKiseok Jo static const struct of_device_id sma1307_of_match[] = { 2022576c57e6SKiseok Jo { 2023576c57e6SKiseok Jo .compatible = "irondevice,sma1307a", 2024576c57e6SKiseok Jo }, 2025576c57e6SKiseok Jo { 2026576c57e6SKiseok Jo .compatible = "irondevice,sma1307aq", 2027576c57e6SKiseok Jo .data = &sma1307aq_data //AEC-Q100 Qualificated 2028576c57e6SKiseok Jo }, 2029576c57e6SKiseok Jo { } 2030576c57e6SKiseok Jo }; 2031576c57e6SKiseok Jo 2032576c57e6SKiseok Jo MODULE_DEVICE_TABLE(of, sma1307_of_match); 2033576c57e6SKiseok Jo 2034576c57e6SKiseok Jo static struct i2c_driver sma1307_i2c_driver = { 2035576c57e6SKiseok Jo .driver = { 2036576c57e6SKiseok Jo .name = "sma1307", 2037576c57e6SKiseok Jo .of_match_table = sma1307_of_match, 2038576c57e6SKiseok Jo }, 2039576c57e6SKiseok Jo .probe = sma1307_i2c_probe, 2040576c57e6SKiseok Jo .remove = sma1307_i2c_remove, 2041576c57e6SKiseok Jo .id_table = sma1307_i2c_id, 2042576c57e6SKiseok Jo }; 2043576c57e6SKiseok Jo 2044576c57e6SKiseok Jo module_i2c_driver(sma1307_i2c_driver); 2045576c57e6SKiseok Jo 2046576c57e6SKiseok Jo MODULE_DESCRIPTION("ALSA SoC SMA1307 driver"); 2047576c57e6SKiseok Jo MODULE_AUTHOR("Gyuhwa Park, <gyuhwa.park@irondevice.com>"); 2048576c57e6SKiseok Jo MODULE_AUTHOR("KS Jo, <kiseok.jo@irondevice.com>"); 2049576c57e6SKiseok Jo MODULE_LICENSE("GPL"); 2050