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