1805 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * max98088.c -- MAX98088 ALSA SoC Audio driver4 *5 * Copyright 2010 Maxim Integrated Products6 */7 8#include <linux/module.h>9#include <linux/moduleparam.h>10#include <linux/kernel.h>11#include <linux/init.h>12#include <linux/delay.h>13#include <linux/pm.h>14#include <linux/i2c.h>15#include <linux/regmap.h>16#include <linux/clk.h>17#include <sound/core.h>18#include <sound/pcm.h>19#include <sound/pcm_params.h>20#include <sound/soc.h>21#include <sound/initval.h>22#include <sound/tlv.h>23#include <linux/slab.h>24#include <asm/div64.h>25#include <sound/max98088.h>26#include "max98088.h"27 28enum max98088_type {29 MAX98088,30 MAX98089,31};32 33struct max98088_cdata {34 unsigned int rate;35 unsigned int fmt;36 int eq_sel;37};38 39struct max98088_priv {40 struct regmap *regmap;41 enum max98088_type devtype;42 struct max98088_pdata *pdata;43 struct clk *mclk;44 unsigned char mclk_prescaler;45 unsigned int sysclk;46 struct max98088_cdata dai[2];47 int eq_textcnt;48 const char **eq_texts;49 struct soc_enum eq_enum;50 u8 ina_state;51 u8 inb_state;52 unsigned int ex_mode;53 unsigned int digmic;54 unsigned int mic1pre;55 unsigned int mic2pre;56 unsigned int extmic_mode;57};58 59static const struct reg_default max98088_reg[] = {60 { 0xf, 0x00 }, /* 0F interrupt enable */61 62 { 0x10, 0x00 }, /* 10 master clock */63 { 0x11, 0x00 }, /* 11 DAI1 clock mode */64 { 0x12, 0x00 }, /* 12 DAI1 clock control */65 { 0x13, 0x00 }, /* 13 DAI1 clock control */66 { 0x14, 0x00 }, /* 14 DAI1 format */67 { 0x15, 0x00 }, /* 15 DAI1 clock */68 { 0x16, 0x00 }, /* 16 DAI1 config */69 { 0x17, 0x00 }, /* 17 DAI1 TDM */70 { 0x18, 0x00 }, /* 18 DAI1 filters */71 { 0x19, 0x00 }, /* 19 DAI2 clock mode */72 { 0x1a, 0x00 }, /* 1A DAI2 clock control */73 { 0x1b, 0x00 }, /* 1B DAI2 clock control */74 { 0x1c, 0x00 }, /* 1C DAI2 format */75 { 0x1d, 0x00 }, /* 1D DAI2 clock */76 { 0x1e, 0x00 }, /* 1E DAI2 config */77 { 0x1f, 0x00 }, /* 1F DAI2 TDM */78 79 { 0x20, 0x00 }, /* 20 DAI2 filters */80 { 0x21, 0x00 }, /* 21 data config */81 { 0x22, 0x00 }, /* 22 DAC mixer */82 { 0x23, 0x00 }, /* 23 left ADC mixer */83 { 0x24, 0x00 }, /* 24 right ADC mixer */84 { 0x25, 0x00 }, /* 25 left HP mixer */85 { 0x26, 0x00 }, /* 26 right HP mixer */86 { 0x27, 0x00 }, /* 27 HP control */87 { 0x28, 0x00 }, /* 28 left REC mixer */88 { 0x29, 0x00 }, /* 29 right REC mixer */89 { 0x2a, 0x00 }, /* 2A REC control */90 { 0x2b, 0x00 }, /* 2B left SPK mixer */91 { 0x2c, 0x00 }, /* 2C right SPK mixer */92 { 0x2d, 0x00 }, /* 2D SPK control */93 { 0x2e, 0x00 }, /* 2E sidetone */94 { 0x2f, 0x00 }, /* 2F DAI1 playback level */95 96 { 0x30, 0x00 }, /* 30 DAI1 playback level */97 { 0x31, 0x00 }, /* 31 DAI2 playback level */98 { 0x32, 0x00 }, /* 32 DAI2 playbakc level */99 { 0x33, 0x00 }, /* 33 left ADC level */100 { 0x34, 0x00 }, /* 34 right ADC level */101 { 0x35, 0x00 }, /* 35 MIC1 level */102 { 0x36, 0x00 }, /* 36 MIC2 level */103 { 0x37, 0x00 }, /* 37 INA level */104 { 0x38, 0x00 }, /* 38 INB level */105 { 0x39, 0x00 }, /* 39 left HP volume */106 { 0x3a, 0x00 }, /* 3A right HP volume */107 { 0x3b, 0x00 }, /* 3B left REC volume */108 { 0x3c, 0x00 }, /* 3C right REC volume */109 { 0x3d, 0x00 }, /* 3D left SPK volume */110 { 0x3e, 0x00 }, /* 3E right SPK volume */111 { 0x3f, 0x00 }, /* 3F MIC config */112 113 { 0x40, 0x00 }, /* 40 MIC threshold */114 { 0x41, 0x00 }, /* 41 excursion limiter filter */115 { 0x42, 0x00 }, /* 42 excursion limiter threshold */116 { 0x43, 0x00 }, /* 43 ALC */117 { 0x44, 0x00 }, /* 44 power limiter threshold */118 { 0x45, 0x00 }, /* 45 power limiter config */119 { 0x46, 0x00 }, /* 46 distortion limiter config */120 { 0x47, 0x00 }, /* 47 audio input */121 { 0x48, 0x00 }, /* 48 microphone */122 { 0x49, 0x00 }, /* 49 level control */123 { 0x4a, 0x00 }, /* 4A bypass switches */124 { 0x4b, 0x00 }, /* 4B jack detect */125 { 0x4c, 0x00 }, /* 4C input enable */126 { 0x4d, 0x00 }, /* 4D output enable */127 { 0x4e, 0xF0 }, /* 4E bias control */128 { 0x4f, 0x00 }, /* 4F DAC power */129 130 { 0x50, 0x0F }, /* 50 DAC power */131 { 0x51, 0x00 }, /* 51 system */132 { 0x52, 0x00 }, /* 52 DAI1 EQ1 */133 { 0x53, 0x00 }, /* 53 DAI1 EQ1 */134 { 0x54, 0x00 }, /* 54 DAI1 EQ1 */135 { 0x55, 0x00 }, /* 55 DAI1 EQ1 */136 { 0x56, 0x00 }, /* 56 DAI1 EQ1 */137 { 0x57, 0x00 }, /* 57 DAI1 EQ1 */138 { 0x58, 0x00 }, /* 58 DAI1 EQ1 */139 { 0x59, 0x00 }, /* 59 DAI1 EQ1 */140 { 0x5a, 0x00 }, /* 5A DAI1 EQ1 */141 { 0x5b, 0x00 }, /* 5B DAI1 EQ1 */142 { 0x5c, 0x00 }, /* 5C DAI1 EQ2 */143 { 0x5d, 0x00 }, /* 5D DAI1 EQ2 */144 { 0x5e, 0x00 }, /* 5E DAI1 EQ2 */145 { 0x5f, 0x00 }, /* 5F DAI1 EQ2 */146 147 { 0x60, 0x00 }, /* 60 DAI1 EQ2 */148 { 0x61, 0x00 }, /* 61 DAI1 EQ2 */149 { 0x62, 0x00 }, /* 62 DAI1 EQ2 */150 { 0x63, 0x00 }, /* 63 DAI1 EQ2 */151 { 0x64, 0x00 }, /* 64 DAI1 EQ2 */152 { 0x65, 0x00 }, /* 65 DAI1 EQ2 */153 { 0x66, 0x00 }, /* 66 DAI1 EQ3 */154 { 0x67, 0x00 }, /* 67 DAI1 EQ3 */155 { 0x68, 0x00 }, /* 68 DAI1 EQ3 */156 { 0x69, 0x00 }, /* 69 DAI1 EQ3 */157 { 0x6a, 0x00 }, /* 6A DAI1 EQ3 */158 { 0x6b, 0x00 }, /* 6B DAI1 EQ3 */159 { 0x6c, 0x00 }, /* 6C DAI1 EQ3 */160 { 0x6d, 0x00 }, /* 6D DAI1 EQ3 */161 { 0x6e, 0x00 }, /* 6E DAI1 EQ3 */162 { 0x6f, 0x00 }, /* 6F DAI1 EQ3 */163 164 { 0x70, 0x00 }, /* 70 DAI1 EQ4 */165 { 0x71, 0x00 }, /* 71 DAI1 EQ4 */166 { 0x72, 0x00 }, /* 72 DAI1 EQ4 */167 { 0x73, 0x00 }, /* 73 DAI1 EQ4 */168 { 0x74, 0x00 }, /* 74 DAI1 EQ4 */169 { 0x75, 0x00 }, /* 75 DAI1 EQ4 */170 { 0x76, 0x00 }, /* 76 DAI1 EQ4 */171 { 0x77, 0x00 }, /* 77 DAI1 EQ4 */172 { 0x78, 0x00 }, /* 78 DAI1 EQ4 */173 { 0x79, 0x00 }, /* 79 DAI1 EQ4 */174 { 0x7a, 0x00 }, /* 7A DAI1 EQ5 */175 { 0x7b, 0x00 }, /* 7B DAI1 EQ5 */176 { 0x7c, 0x00 }, /* 7C DAI1 EQ5 */177 { 0x7d, 0x00 }, /* 7D DAI1 EQ5 */178 { 0x7e, 0x00 }, /* 7E DAI1 EQ5 */179 { 0x7f, 0x00 }, /* 7F DAI1 EQ5 */180 181 { 0x80, 0x00 }, /* 80 DAI1 EQ5 */182 { 0x81, 0x00 }, /* 81 DAI1 EQ5 */183 { 0x82, 0x00 }, /* 82 DAI1 EQ5 */184 { 0x83, 0x00 }, /* 83 DAI1 EQ5 */185 { 0x84, 0x00 }, /* 84 DAI2 EQ1 */186 { 0x85, 0x00 }, /* 85 DAI2 EQ1 */187 { 0x86, 0x00 }, /* 86 DAI2 EQ1 */188 { 0x87, 0x00 }, /* 87 DAI2 EQ1 */189 { 0x88, 0x00 }, /* 88 DAI2 EQ1 */190 { 0x89, 0x00 }, /* 89 DAI2 EQ1 */191 { 0x8a, 0x00 }, /* 8A DAI2 EQ1 */192 { 0x8b, 0x00 }, /* 8B DAI2 EQ1 */193 { 0x8c, 0x00 }, /* 8C DAI2 EQ1 */194 { 0x8d, 0x00 }, /* 8D DAI2 EQ1 */195 { 0x8e, 0x00 }, /* 8E DAI2 EQ2 */196 { 0x8f, 0x00 }, /* 8F DAI2 EQ2 */197 198 { 0x90, 0x00 }, /* 90 DAI2 EQ2 */199 { 0x91, 0x00 }, /* 91 DAI2 EQ2 */200 { 0x92, 0x00 }, /* 92 DAI2 EQ2 */201 { 0x93, 0x00 }, /* 93 DAI2 EQ2 */202 { 0x94, 0x00 }, /* 94 DAI2 EQ2 */203 { 0x95, 0x00 }, /* 95 DAI2 EQ2 */204 { 0x96, 0x00 }, /* 96 DAI2 EQ2 */205 { 0x97, 0x00 }, /* 97 DAI2 EQ2 */206 { 0x98, 0x00 }, /* 98 DAI2 EQ3 */207 { 0x99, 0x00 }, /* 99 DAI2 EQ3 */208 { 0x9a, 0x00 }, /* 9A DAI2 EQ3 */209 { 0x9b, 0x00 }, /* 9B DAI2 EQ3 */210 { 0x9c, 0x00 }, /* 9C DAI2 EQ3 */211 { 0x9d, 0x00 }, /* 9D DAI2 EQ3 */212 { 0x9e, 0x00 }, /* 9E DAI2 EQ3 */213 { 0x9f, 0x00 }, /* 9F DAI2 EQ3 */214 215 { 0xa0, 0x00 }, /* A0 DAI2 EQ3 */216 { 0xa1, 0x00 }, /* A1 DAI2 EQ3 */217 { 0xa2, 0x00 }, /* A2 DAI2 EQ4 */218 { 0xa3, 0x00 }, /* A3 DAI2 EQ4 */219 { 0xa4, 0x00 }, /* A4 DAI2 EQ4 */220 { 0xa5, 0x00 }, /* A5 DAI2 EQ4 */221 { 0xa6, 0x00 }, /* A6 DAI2 EQ4 */222 { 0xa7, 0x00 }, /* A7 DAI2 EQ4 */223 { 0xa8, 0x00 }, /* A8 DAI2 EQ4 */224 { 0xa9, 0x00 }, /* A9 DAI2 EQ4 */225 { 0xaa, 0x00 }, /* AA DAI2 EQ4 */226 { 0xab, 0x00 }, /* AB DAI2 EQ4 */227 { 0xac, 0x00 }, /* AC DAI2 EQ5 */228 { 0xad, 0x00 }, /* AD DAI2 EQ5 */229 { 0xae, 0x00 }, /* AE DAI2 EQ5 */230 { 0xaf, 0x00 }, /* AF DAI2 EQ5 */231 232 { 0xb0, 0x00 }, /* B0 DAI2 EQ5 */233 { 0xb1, 0x00 }, /* B1 DAI2 EQ5 */234 { 0xb2, 0x00 }, /* B2 DAI2 EQ5 */235 { 0xb3, 0x00 }, /* B3 DAI2 EQ5 */236 { 0xb4, 0x00 }, /* B4 DAI2 EQ5 */237 { 0xb5, 0x00 }, /* B5 DAI2 EQ5 */238 { 0xb6, 0x00 }, /* B6 DAI1 biquad */239 { 0xb7, 0x00 }, /* B7 DAI1 biquad */240 { 0xb8 ,0x00 }, /* B8 DAI1 biquad */241 { 0xb9, 0x00 }, /* B9 DAI1 biquad */242 { 0xba, 0x00 }, /* BA DAI1 biquad */243 { 0xbb, 0x00 }, /* BB DAI1 biquad */244 { 0xbc, 0x00 }, /* BC DAI1 biquad */245 { 0xbd, 0x00 }, /* BD DAI1 biquad */246 { 0xbe, 0x00 }, /* BE DAI1 biquad */247 { 0xbf, 0x00 }, /* BF DAI1 biquad */248 249 { 0xc0, 0x00 }, /* C0 DAI2 biquad */250 { 0xc1, 0x00 }, /* C1 DAI2 biquad */251 { 0xc2, 0x00 }, /* C2 DAI2 biquad */252 { 0xc3, 0x00 }, /* C3 DAI2 biquad */253 { 0xc4, 0x00 }, /* C4 DAI2 biquad */254 { 0xc5, 0x00 }, /* C5 DAI2 biquad */255 { 0xc6, 0x00 }, /* C6 DAI2 biquad */256 { 0xc7, 0x00 }, /* C7 DAI2 biquad */257 { 0xc8, 0x00 }, /* C8 DAI2 biquad */258 { 0xc9, 0x00 }, /* C9 DAI2 biquad */259};260 261static bool max98088_readable_register(struct device *dev, unsigned int reg)262{263 switch (reg) {264 case M98088_REG_00_IRQ_STATUS ... 0xC9:265 case M98088_REG_FF_REV_ID:266 return true;267 default:268 return false;269 }270}271 272static bool max98088_writeable_register(struct device *dev, unsigned int reg)273{274 switch (reg) {275 case M98088_REG_03_BATTERY_VOLTAGE ... 0xC9:276 return true;277 default:278 return false;279 }280}281 282static bool max98088_volatile_register(struct device *dev, unsigned int reg)283{284 switch (reg) {285 case M98088_REG_00_IRQ_STATUS ... M98088_REG_03_BATTERY_VOLTAGE:286 case M98088_REG_FF_REV_ID:287 return true;288 default:289 return false;290 }291}292 293static const struct regmap_config max98088_regmap = {294 .reg_bits = 8,295 .val_bits = 8,296 297 .readable_reg = max98088_readable_register,298 .writeable_reg = max98088_writeable_register,299 .volatile_reg = max98088_volatile_register,300 .max_register = 0xff,301 302 .reg_defaults = max98088_reg,303 .num_reg_defaults = ARRAY_SIZE(max98088_reg),304 .cache_type = REGCACHE_RBTREE,305};306 307/*308 * Load equalizer DSP coefficient configurations registers309 */310static void m98088_eq_band(struct snd_soc_component *component, unsigned int dai,311 unsigned int band, u16 *coefs)312{313 unsigned int eq_reg;314 unsigned int i;315 316 if (WARN_ON(band > 4) ||317 WARN_ON(dai > 1))318 return;319 320 /* Load the base register address */321 eq_reg = dai ? M98088_REG_84_DAI2_EQ_BASE : M98088_REG_52_DAI1_EQ_BASE;322 323 /* Add the band address offset, note adjustment for word address */324 eq_reg += band * (M98088_COEFS_PER_BAND << 1);325 326 /* Step through the registers and coefs */327 for (i = 0; i < M98088_COEFS_PER_BAND; i++) {328 snd_soc_component_write(component, eq_reg++, M98088_BYTE1(coefs[i]));329 snd_soc_component_write(component, eq_reg++, M98088_BYTE0(coefs[i]));330 }331}332 333/*334 * Excursion limiter modes335 */336static const char *max98088_exmode_texts[] = {337 "Off", "100Hz", "400Hz", "600Hz", "800Hz", "1000Hz", "200-400Hz",338 "400-600Hz", "400-800Hz",339};340 341static const unsigned int max98088_exmode_values[] = {342 0x00, 0x43, 0x10, 0x20, 0x30, 0x40, 0x11, 0x22, 0x32343};344 345static SOC_VALUE_ENUM_SINGLE_DECL(max98088_exmode_enum,346 M98088_REG_41_SPKDHP, 0, 127,347 max98088_exmode_texts,348 max98088_exmode_values);349 350static const char *max98088_ex_thresh[] = { /* volts PP */351 "0.6", "1.2", "1.8", "2.4", "3.0", "3.6", "4.2", "4.8"};352static SOC_ENUM_SINGLE_DECL(max98088_ex_thresh_enum,353 M98088_REG_42_SPKDHP_THRESH, 0,354 max98088_ex_thresh);355 356static const char *max98088_fltr_mode[] = {"Voice", "Music" };357static SOC_ENUM_SINGLE_DECL(max98088_filter_mode_enum,358 M98088_REG_18_DAI1_FILTERS, 7,359 max98088_fltr_mode);360 361static const char *max98088_extmic_text[] = { "None", "MIC1", "MIC2" };362 363static SOC_ENUM_SINGLE_DECL(max98088_extmic_enum,364 M98088_REG_48_CFG_MIC, 0,365 max98088_extmic_text);366 367static const struct snd_kcontrol_new max98088_extmic_mux =368 SOC_DAPM_ENUM("External MIC Mux", max98088_extmic_enum);369 370static const char *max98088_dai1_fltr[] = {371 "Off", "fc=258/fs=16k", "fc=500/fs=16k",372 "fc=258/fs=8k", "fc=500/fs=8k", "fc=200"};373static SOC_ENUM_SINGLE_DECL(max98088_dai1_dac_filter_enum,374 M98088_REG_18_DAI1_FILTERS, 0,375 max98088_dai1_fltr);376static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum,377 M98088_REG_18_DAI1_FILTERS, 4,378 max98088_dai1_fltr);379 380static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol,381 struct snd_ctl_elem_value *ucontrol)382{383 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);384 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);385 unsigned int sel = ucontrol->value.integer.value[0];386 387 max98088->mic1pre = sel;388 snd_soc_component_update_bits(component, M98088_REG_35_LVL_MIC1, M98088_MICPRE_MASK,389 (1+sel)<<M98088_MICPRE_SHIFT);390 391 return 0;392}393 394static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol,395 struct snd_ctl_elem_value *ucontrol)396{397 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);398 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);399 400 ucontrol->value.integer.value[0] = max98088->mic1pre;401 return 0;402}403 404static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol,405 struct snd_ctl_elem_value *ucontrol)406{407 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);408 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);409 unsigned int sel = ucontrol->value.integer.value[0];410 411 max98088->mic2pre = sel;412 snd_soc_component_update_bits(component, M98088_REG_36_LVL_MIC2, M98088_MICPRE_MASK,413 (1+sel)<<M98088_MICPRE_SHIFT);414 415 return 0;416}417 418static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol,419 struct snd_ctl_elem_value *ucontrol)420{421 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);422 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);423 424 ucontrol->value.integer.value[0] = max98088->mic2pre;425 return 0;426}427 428static const DECLARE_TLV_DB_RANGE(max98088_micboost_tlv,429 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0),430 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0)431);432 433static const DECLARE_TLV_DB_RANGE(max98088_hp_tlv,434 0, 6, TLV_DB_SCALE_ITEM(-6700, 400, 0),435 7, 14, TLV_DB_SCALE_ITEM(-4000, 300, 0),436 15, 21, TLV_DB_SCALE_ITEM(-1700, 200, 0),437 22, 27, TLV_DB_SCALE_ITEM(-400, 100, 0),438 28, 31, TLV_DB_SCALE_ITEM(150, 50, 0)439);440 441static const DECLARE_TLV_DB_RANGE(max98088_spk_tlv,442 0, 6, TLV_DB_SCALE_ITEM(-6200, 400, 0),443 7, 14, TLV_DB_SCALE_ITEM(-3500, 300, 0),444 15, 21, TLV_DB_SCALE_ITEM(-1200, 200, 0),445 22, 27, TLV_DB_SCALE_ITEM(100, 100, 0),446 28, 31, TLV_DB_SCALE_ITEM(650, 50, 0)447);448 449static const struct snd_kcontrol_new max98088_snd_controls[] = {450 451 SOC_DOUBLE_R_TLV("Headphone Volume", M98088_REG_39_LVL_HP_L,452 M98088_REG_3A_LVL_HP_R, 0, 31, 0, max98088_hp_tlv),453 SOC_DOUBLE_R_TLV("Speaker Volume", M98088_REG_3D_LVL_SPK_L,454 M98088_REG_3E_LVL_SPK_R, 0, 31, 0, max98088_spk_tlv),455 SOC_DOUBLE_R_TLV("Receiver Volume", M98088_REG_3B_LVL_REC_L,456 M98088_REG_3C_LVL_REC_R, 0, 31, 0, max98088_spk_tlv),457 458 SOC_DOUBLE_R("Headphone Switch", M98088_REG_39_LVL_HP_L,459 M98088_REG_3A_LVL_HP_R, 7, 1, 1),460 SOC_DOUBLE_R("Speaker Switch", M98088_REG_3D_LVL_SPK_L,461 M98088_REG_3E_LVL_SPK_R, 7, 1, 1),462 SOC_DOUBLE_R("Receiver Switch", M98088_REG_3B_LVL_REC_L,463 M98088_REG_3C_LVL_REC_R, 7, 1, 1),464 465 SOC_SINGLE("MIC1 Volume", M98088_REG_35_LVL_MIC1, 0, 31, 1),466 SOC_SINGLE("MIC2 Volume", M98088_REG_36_LVL_MIC2, 0, 31, 1),467 468 SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",469 M98088_REG_35_LVL_MIC1, 5, 2, 0,470 max98088_mic1pre_get, max98088_mic1pre_set,471 max98088_micboost_tlv),472 SOC_SINGLE_EXT_TLV("MIC2 Boost Volume",473 M98088_REG_36_LVL_MIC2, 5, 2, 0,474 max98088_mic2pre_get, max98088_mic2pre_set,475 max98088_micboost_tlv),476 477 SOC_SINGLE("Noise Gate Threshold", M98088_REG_40_MICAGC_THRESH,478 4, 15, 0),479 480 SOC_SINGLE("INA Volume", M98088_REG_37_LVL_INA, 0, 7, 1),481 SOC_SINGLE("INB Volume", M98088_REG_38_LVL_INB, 0, 7, 1),482 483 SOC_SINGLE("ADCL Volume", M98088_REG_33_LVL_ADC_L, 0, 15, 0),484 SOC_SINGLE("ADCR Volume", M98088_REG_34_LVL_ADC_R, 0, 15, 0),485 486 SOC_SINGLE("ADCL Boost Volume", M98088_REG_33_LVL_ADC_L, 4, 3, 0),487 SOC_SINGLE("ADCR Boost Volume", M98088_REG_34_LVL_ADC_R, 4, 3, 0),488 489 SOC_SINGLE("EQ1 Switch", M98088_REG_49_CFG_LEVEL, 0, 1, 0),490 SOC_SINGLE("EQ2 Switch", M98088_REG_49_CFG_LEVEL, 1, 1, 0),491 492 SOC_ENUM("EX Limiter Mode", max98088_exmode_enum),493 SOC_ENUM("EX Limiter Threshold", max98088_ex_thresh_enum),494 495 SOC_ENUM("DAI1 Filter Mode", max98088_filter_mode_enum),496 SOC_ENUM("DAI1 DAC Filter", max98088_dai1_dac_filter_enum),497 SOC_ENUM("DAI1 ADC Filter", max98088_dai1_adc_filter_enum),498 SOC_SINGLE("DAI2 DC Block Switch", M98088_REG_20_DAI2_FILTERS,499 0, 1, 0),500 501 SOC_SINGLE("ALC Switch", M98088_REG_43_SPKALC_COMP, 7, 1, 0),502 SOC_SINGLE("ALC Threshold", M98088_REG_43_SPKALC_COMP, 0, 7, 0),503 SOC_SINGLE("ALC Multiband", M98088_REG_43_SPKALC_COMP, 3, 1, 0),504 SOC_SINGLE("ALC Release Time", M98088_REG_43_SPKALC_COMP, 4, 7, 0),505 506 SOC_SINGLE("PWR Limiter Threshold", M98088_REG_44_PWRLMT_CFG,507 4, 15, 0),508 SOC_SINGLE("PWR Limiter Weight", M98088_REG_44_PWRLMT_CFG, 0, 7, 0),509 SOC_SINGLE("PWR Limiter Time1", M98088_REG_45_PWRLMT_TIME, 0, 15, 0),510 SOC_SINGLE("PWR Limiter Time2", M98088_REG_45_PWRLMT_TIME, 4, 15, 0),511 512 SOC_SINGLE("THD Limiter Threshold", M98088_REG_46_THDLMT_CFG, 4, 15, 0),513 SOC_SINGLE("THD Limiter Time", M98088_REG_46_THDLMT_CFG, 0, 7, 0),514};515 516/* Left speaker mixer switch */517static const struct snd_kcontrol_new max98088_left_speaker_mixer_controls[] = {518 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),519 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),520 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 0, 1, 0),521 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 7, 1, 0),522 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 5, 1, 0),523 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 6, 1, 0),524 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 1, 1, 0),525 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 2, 1, 0),526 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2B_MIX_SPK_LEFT, 3, 1, 0),527 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2B_MIX_SPK_LEFT, 4, 1, 0),528};529 530/* Right speaker mixer switch */531static const struct snd_kcontrol_new max98088_right_speaker_mixer_controls[] = {532 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0),533 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0),534 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 7, 1, 0),535 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 0, 1, 0),536 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 5, 1, 0),537 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 6, 1, 0),538 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 1, 1, 0),539 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 2, 1, 0),540 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 3, 1, 0),541 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_2C_MIX_SPK_RIGHT, 4, 1, 0),542};543 544/* Left headphone mixer switch */545static const struct snd_kcontrol_new max98088_left_hp_mixer_controls[] = {546 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),547 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),548 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 0, 1, 0),549 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_25_MIX_HP_LEFT, 7, 1, 0),550 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_25_MIX_HP_LEFT, 5, 1, 0),551 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_25_MIX_HP_LEFT, 6, 1, 0),552 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_25_MIX_HP_LEFT, 1, 1, 0),553 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_25_MIX_HP_LEFT, 2, 1, 0),554 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_25_MIX_HP_LEFT, 3, 1, 0),555 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_25_MIX_HP_LEFT, 4, 1, 0),556};557 558/* Right headphone mixer switch */559static const struct snd_kcontrol_new max98088_right_hp_mixer_controls[] = {560 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0),561 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0),562 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 7, 1, 0),563 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 0, 1, 0),564 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_26_MIX_HP_RIGHT, 5, 1, 0),565 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_26_MIX_HP_RIGHT, 6, 1, 0),566 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_26_MIX_HP_RIGHT, 1, 1, 0),567 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_26_MIX_HP_RIGHT, 2, 1, 0),568 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_26_MIX_HP_RIGHT, 3, 1, 0),569 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_26_MIX_HP_RIGHT, 4, 1, 0),570};571 572/* Left earpiece/receiver mixer switch */573static const struct snd_kcontrol_new max98088_left_rec_mixer_controls[] = {574 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),575 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),576 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 0, 1, 0),577 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_28_MIX_REC_LEFT, 7, 1, 0),578 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_28_MIX_REC_LEFT, 5, 1, 0),579 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_28_MIX_REC_LEFT, 6, 1, 0),580 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_28_MIX_REC_LEFT, 1, 1, 0),581 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_28_MIX_REC_LEFT, 2, 1, 0),582 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_28_MIX_REC_LEFT, 3, 1, 0),583 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_28_MIX_REC_LEFT, 4, 1, 0),584};585 586/* Right earpiece/receiver mixer switch */587static const struct snd_kcontrol_new max98088_right_rec_mixer_controls[] = {588 SOC_DAPM_SINGLE("Left DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0),589 SOC_DAPM_SINGLE("Right DAC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0),590 SOC_DAPM_SINGLE("Left DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 7, 1, 0),591 SOC_DAPM_SINGLE("Right DAC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 0, 1, 0),592 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_29_MIX_REC_RIGHT, 5, 1, 0),593 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_29_MIX_REC_RIGHT, 6, 1, 0),594 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_29_MIX_REC_RIGHT, 1, 1, 0),595 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_29_MIX_REC_RIGHT, 2, 1, 0),596 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_29_MIX_REC_RIGHT, 3, 1, 0),597 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_29_MIX_REC_RIGHT, 4, 1, 0),598};599 600/* Left ADC mixer switch */601static const struct snd_kcontrol_new max98088_left_ADC_mixer_controls[] = {602 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_23_MIX_ADC_LEFT, 7, 1, 0),603 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_23_MIX_ADC_LEFT, 6, 1, 0),604 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_23_MIX_ADC_LEFT, 3, 1, 0),605 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_23_MIX_ADC_LEFT, 2, 1, 0),606 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_23_MIX_ADC_LEFT, 1, 1, 0),607 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_23_MIX_ADC_LEFT, 0, 1, 0),608};609 610/* Right ADC mixer switch */611static const struct snd_kcontrol_new max98088_right_ADC_mixer_controls[] = {612 SOC_DAPM_SINGLE("MIC1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 7, 1, 0),613 SOC_DAPM_SINGLE("MIC2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 6, 1, 0),614 SOC_DAPM_SINGLE("INA1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 3, 1, 0),615 SOC_DAPM_SINGLE("INA2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 2, 1, 0),616 SOC_DAPM_SINGLE("INB1 Switch", M98088_REG_24_MIX_ADC_RIGHT, 1, 1, 0),617 SOC_DAPM_SINGLE("INB2 Switch", M98088_REG_24_MIX_ADC_RIGHT, 0, 1, 0),618};619 620static int max98088_mic_event(struct snd_soc_dapm_widget *w,621 struct snd_kcontrol *kcontrol, int event)622{623 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);624 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);625 626 switch (event) {627 case SND_SOC_DAPM_POST_PMU:628 if (w->reg == M98088_REG_35_LVL_MIC1) {629 snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK,630 (1+max98088->mic1pre)<<M98088_MICPRE_SHIFT);631 } else {632 snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK,633 (1+max98088->mic2pre)<<M98088_MICPRE_SHIFT);634 }635 break;636 case SND_SOC_DAPM_POST_PMD:637 snd_soc_component_update_bits(component, w->reg, M98088_MICPRE_MASK, 0);638 break;639 default:640 return -EINVAL;641 }642 643 return 0;644}645 646/*647 * The line inputs are 2-channel stereo inputs with the left648 * and right channels sharing a common PGA power control signal.649 */650static int max98088_line_pga(struct snd_soc_dapm_widget *w,651 int event, int line, u8 channel)652{653 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);654 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);655 u8 *state;656 657 if (WARN_ON(!(channel == 1 || channel == 2)))658 return -EINVAL;659 660 switch (line) {661 case LINE_INA:662 state = &max98088->ina_state;663 break;664 case LINE_INB:665 state = &max98088->inb_state;666 break;667 default:668 return -EINVAL;669 }670 671 switch (event) {672 case SND_SOC_DAPM_POST_PMU:673 *state |= channel;674 snd_soc_component_update_bits(component, w->reg,675 (1 << w->shift), (1 << w->shift));676 break;677 case SND_SOC_DAPM_POST_PMD:678 *state &= ~channel;679 if (*state == 0) {680 snd_soc_component_update_bits(component, w->reg,681 (1 << w->shift), 0);682 }683 break;684 default:685 return -EINVAL;686 }687 688 return 0;689}690 691static int max98088_pga_ina1_event(struct snd_soc_dapm_widget *w,692 struct snd_kcontrol *k, int event)693{694 return max98088_line_pga(w, event, LINE_INA, 1);695}696 697static int max98088_pga_ina2_event(struct snd_soc_dapm_widget *w,698 struct snd_kcontrol *k, int event)699{700 return max98088_line_pga(w, event, LINE_INA, 2);701}702 703static int max98088_pga_inb1_event(struct snd_soc_dapm_widget *w,704 struct snd_kcontrol *k, int event)705{706 return max98088_line_pga(w, event, LINE_INB, 1);707}708 709static int max98088_pga_inb2_event(struct snd_soc_dapm_widget *w,710 struct snd_kcontrol *k, int event)711{712 return max98088_line_pga(w, event, LINE_INB, 2);713}714 715static const struct snd_soc_dapm_widget max98088_dapm_widgets[] = {716 717 SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 1, 0),718 SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", M98088_REG_4C_PWR_EN_IN, 0, 0),719 720 SND_SOC_DAPM_DAC("DACL1", "HiFi Playback",721 M98088_REG_4D_PWR_EN_OUT, 1, 0),722 SND_SOC_DAPM_DAC("DACR1", "HiFi Playback",723 M98088_REG_4D_PWR_EN_OUT, 0, 0),724 SND_SOC_DAPM_DAC("DACL2", "Aux Playback",725 M98088_REG_4D_PWR_EN_OUT, 1, 0),726 SND_SOC_DAPM_DAC("DACR2", "Aux Playback",727 M98088_REG_4D_PWR_EN_OUT, 0, 0),728 729 SND_SOC_DAPM_PGA("HP Left Out", M98088_REG_4D_PWR_EN_OUT,730 7, 0, NULL, 0),731 SND_SOC_DAPM_PGA("HP Right Out", M98088_REG_4D_PWR_EN_OUT,732 6, 0, NULL, 0),733 734 SND_SOC_DAPM_PGA("SPK Left Out", M98088_REG_4D_PWR_EN_OUT,735 5, 0, NULL, 0),736 SND_SOC_DAPM_PGA("SPK Right Out", M98088_REG_4D_PWR_EN_OUT,737 4, 0, NULL, 0),738 739 SND_SOC_DAPM_PGA("REC Left Out", M98088_REG_4D_PWR_EN_OUT,740 3, 0, NULL, 0),741 SND_SOC_DAPM_PGA("REC Right Out", M98088_REG_4D_PWR_EN_OUT,742 2, 0, NULL, 0),743 744 SND_SOC_DAPM_MUX("External MIC", SND_SOC_NOPM, 0, 0,745 &max98088_extmic_mux),746 747 SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,748 &max98088_left_hp_mixer_controls[0],749 ARRAY_SIZE(max98088_left_hp_mixer_controls)),750 751 SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,752 &max98088_right_hp_mixer_controls[0],753 ARRAY_SIZE(max98088_right_hp_mixer_controls)),754 755 SND_SOC_DAPM_MIXER("Left SPK Mixer", SND_SOC_NOPM, 0, 0,756 &max98088_left_speaker_mixer_controls[0],757 ARRAY_SIZE(max98088_left_speaker_mixer_controls)),758 759 SND_SOC_DAPM_MIXER("Right SPK Mixer", SND_SOC_NOPM, 0, 0,760 &max98088_right_speaker_mixer_controls[0],761 ARRAY_SIZE(max98088_right_speaker_mixer_controls)),762 763 SND_SOC_DAPM_MIXER("Left REC Mixer", SND_SOC_NOPM, 0, 0,764 &max98088_left_rec_mixer_controls[0],765 ARRAY_SIZE(max98088_left_rec_mixer_controls)),766 767 SND_SOC_DAPM_MIXER("Right REC Mixer", SND_SOC_NOPM, 0, 0,768 &max98088_right_rec_mixer_controls[0],769 ARRAY_SIZE(max98088_right_rec_mixer_controls)),770 771 SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,772 &max98088_left_ADC_mixer_controls[0],773 ARRAY_SIZE(max98088_left_ADC_mixer_controls)),774 775 SND_SOC_DAPM_MIXER("Right ADC Mixer", SND_SOC_NOPM, 0, 0,776 &max98088_right_ADC_mixer_controls[0],777 ARRAY_SIZE(max98088_right_ADC_mixer_controls)),778 779 SND_SOC_DAPM_PGA_E("MIC1 Input", M98088_REG_35_LVL_MIC1,780 5, 0, NULL, 0, max98088_mic_event,781 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),782 783 SND_SOC_DAPM_PGA_E("MIC2 Input", M98088_REG_36_LVL_MIC2,784 5, 0, NULL, 0, max98088_mic_event,785 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),786 787 SND_SOC_DAPM_PGA_E("INA1 Input", M98088_REG_4C_PWR_EN_IN,788 7, 0, NULL, 0, max98088_pga_ina1_event,789 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),790 791 SND_SOC_DAPM_PGA_E("INA2 Input", M98088_REG_4C_PWR_EN_IN,792 7, 0, NULL, 0, max98088_pga_ina2_event,793 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),794 795 SND_SOC_DAPM_PGA_E("INB1 Input", M98088_REG_4C_PWR_EN_IN,796 6, 0, NULL, 0, max98088_pga_inb1_event,797 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),798 799 SND_SOC_DAPM_PGA_E("INB2 Input", M98088_REG_4C_PWR_EN_IN,800 6, 0, NULL, 0, max98088_pga_inb2_event,801 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),802 803 SND_SOC_DAPM_MICBIAS("MICBIAS", M98088_REG_4C_PWR_EN_IN, 3, 0),804 805 SND_SOC_DAPM_OUTPUT("HPL"),806 SND_SOC_DAPM_OUTPUT("HPR"),807 SND_SOC_DAPM_OUTPUT("SPKL"),808 SND_SOC_DAPM_OUTPUT("SPKR"),809 SND_SOC_DAPM_OUTPUT("RECL"),810 SND_SOC_DAPM_OUTPUT("RECR"),811 812 SND_SOC_DAPM_INPUT("MIC1"),813 SND_SOC_DAPM_INPUT("MIC2"),814 SND_SOC_DAPM_INPUT("INA1"),815 SND_SOC_DAPM_INPUT("INA2"),816 SND_SOC_DAPM_INPUT("INB1"),817 SND_SOC_DAPM_INPUT("INB2"),818};819 820static const struct snd_soc_dapm_route max98088_audio_map[] = {821 /* Left headphone output mixer */822 {"Left HP Mixer", "Left DAC1 Switch", "DACL1"},823 {"Left HP Mixer", "Left DAC2 Switch", "DACL2"},824 {"Left HP Mixer", "Right DAC1 Switch", "DACR1"},825 {"Left HP Mixer", "Right DAC2 Switch", "DACR2"},826 {"Left HP Mixer", "MIC1 Switch", "MIC1 Input"},827 {"Left HP Mixer", "MIC2 Switch", "MIC2 Input"},828 {"Left HP Mixer", "INA1 Switch", "INA1 Input"},829 {"Left HP Mixer", "INA2 Switch", "INA2 Input"},830 {"Left HP Mixer", "INB1 Switch", "INB1 Input"},831 {"Left HP Mixer", "INB2 Switch", "INB2 Input"},832 833 /* Right headphone output mixer */834 {"Right HP Mixer", "Left DAC1 Switch", "DACL1"},835 {"Right HP Mixer", "Left DAC2 Switch", "DACL2" },836 {"Right HP Mixer", "Right DAC1 Switch", "DACR1"},837 {"Right HP Mixer", "Right DAC2 Switch", "DACR2"},838 {"Right HP Mixer", "MIC1 Switch", "MIC1 Input"},839 {"Right HP Mixer", "MIC2 Switch", "MIC2 Input"},840 {"Right HP Mixer", "INA1 Switch", "INA1 Input"},841 {"Right HP Mixer", "INA2 Switch", "INA2 Input"},842 {"Right HP Mixer", "INB1 Switch", "INB1 Input"},843 {"Right HP Mixer", "INB2 Switch", "INB2 Input"},844 845 /* Left speaker output mixer */846 {"Left SPK Mixer", "Left DAC1 Switch", "DACL1"},847 {"Left SPK Mixer", "Left DAC2 Switch", "DACL2"},848 {"Left SPK Mixer", "Right DAC1 Switch", "DACR1"},849 {"Left SPK Mixer", "Right DAC2 Switch", "DACR2"},850 {"Left SPK Mixer", "MIC1 Switch", "MIC1 Input"},851 {"Left SPK Mixer", "MIC2 Switch", "MIC2 Input"},852 {"Left SPK Mixer", "INA1 Switch", "INA1 Input"},853 {"Left SPK Mixer", "INA2 Switch", "INA2 Input"},854 {"Left SPK Mixer", "INB1 Switch", "INB1 Input"},855 {"Left SPK Mixer", "INB2 Switch", "INB2 Input"},856 857 /* Right speaker output mixer */858 {"Right SPK Mixer", "Left DAC1 Switch", "DACL1"},859 {"Right SPK Mixer", "Left DAC2 Switch", "DACL2"},860 {"Right SPK Mixer", "Right DAC1 Switch", "DACR1"},861 {"Right SPK Mixer", "Right DAC2 Switch", "DACR2"},862 {"Right SPK Mixer", "MIC1 Switch", "MIC1 Input"},863 {"Right SPK Mixer", "MIC2 Switch", "MIC2 Input"},864 {"Right SPK Mixer", "INA1 Switch", "INA1 Input"},865 {"Right SPK Mixer", "INA2 Switch", "INA2 Input"},866 {"Right SPK Mixer", "INB1 Switch", "INB1 Input"},867 {"Right SPK Mixer", "INB2 Switch", "INB2 Input"},868 869 /* Earpiece/Receiver output mixer */870 {"Left REC Mixer", "Left DAC1 Switch", "DACL1"},871 {"Left REC Mixer", "Left DAC2 Switch", "DACL2"},872 {"Left REC Mixer", "Right DAC1 Switch", "DACR1"},873 {"Left REC Mixer", "Right DAC2 Switch", "DACR2"},874 {"Left REC Mixer", "MIC1 Switch", "MIC1 Input"},875 {"Left REC Mixer", "MIC2 Switch", "MIC2 Input"},876 {"Left REC Mixer", "INA1 Switch", "INA1 Input"},877 {"Left REC Mixer", "INA2 Switch", "INA2 Input"},878 {"Left REC Mixer", "INB1 Switch", "INB1 Input"},879 {"Left REC Mixer", "INB2 Switch", "INB2 Input"},880 881 /* Earpiece/Receiver output mixer */882 {"Right REC Mixer", "Left DAC1 Switch", "DACL1"},883 {"Right REC Mixer", "Left DAC2 Switch", "DACL2"},884 {"Right REC Mixer", "Right DAC1 Switch", "DACR1"},885 {"Right REC Mixer", "Right DAC2 Switch", "DACR2"},886 {"Right REC Mixer", "MIC1 Switch", "MIC1 Input"},887 {"Right REC Mixer", "MIC2 Switch", "MIC2 Input"},888 {"Right REC Mixer", "INA1 Switch", "INA1 Input"},889 {"Right REC Mixer", "INA2 Switch", "INA2 Input"},890 {"Right REC Mixer", "INB1 Switch", "INB1 Input"},891 {"Right REC Mixer", "INB2 Switch", "INB2 Input"},892 893 {"HP Left Out", NULL, "Left HP Mixer"},894 {"HP Right Out", NULL, "Right HP Mixer"},895 {"SPK Left Out", NULL, "Left SPK Mixer"},896 {"SPK Right Out", NULL, "Right SPK Mixer"},897 {"REC Left Out", NULL, "Left REC Mixer"},898 {"REC Right Out", NULL, "Right REC Mixer"},899 900 {"HPL", NULL, "HP Left Out"},901 {"HPR", NULL, "HP Right Out"},902 {"SPKL", NULL, "SPK Left Out"},903 {"SPKR", NULL, "SPK Right Out"},904 {"RECL", NULL, "REC Left Out"},905 {"RECR", NULL, "REC Right Out"},906 907 /* Left ADC input mixer */908 {"Left ADC Mixer", "MIC1 Switch", "MIC1 Input"},909 {"Left ADC Mixer", "MIC2 Switch", "MIC2 Input"},910 {"Left ADC Mixer", "INA1 Switch", "INA1 Input"},911 {"Left ADC Mixer", "INA2 Switch", "INA2 Input"},912 {"Left ADC Mixer", "INB1 Switch", "INB1 Input"},913 {"Left ADC Mixer", "INB2 Switch", "INB2 Input"},914 915 /* Right ADC input mixer */916 {"Right ADC Mixer", "MIC1 Switch", "MIC1 Input"},917 {"Right ADC Mixer", "MIC2 Switch", "MIC2 Input"},918 {"Right ADC Mixer", "INA1 Switch", "INA1 Input"},919 {"Right ADC Mixer", "INA2 Switch", "INA2 Input"},920 {"Right ADC Mixer", "INB1 Switch", "INB1 Input"},921 {"Right ADC Mixer", "INB2 Switch", "INB2 Input"},922 923 /* Inputs */924 {"ADCL", NULL, "Left ADC Mixer"},925 {"ADCR", NULL, "Right ADC Mixer"},926 {"INA1 Input", NULL, "INA1"},927 {"INA2 Input", NULL, "INA2"},928 {"INB1 Input", NULL, "INB1"},929 {"INB2 Input", NULL, "INB2"},930 {"MIC1 Input", NULL, "MIC1"},931 {"MIC2 Input", NULL, "MIC2"},932};933 934/* codec mclk clock divider coefficients */935static const struct {936 u32 rate;937 u8 sr;938} rate_table[] = {939 {8000, 0x10},940 {11025, 0x20},941 {16000, 0x30},942 {22050, 0x40},943 {24000, 0x50},944 {32000, 0x60},945 {44100, 0x70},946 {48000, 0x80},947 {88200, 0x90},948 {96000, 0xA0},949};950 951static inline int rate_value(int rate, u8 *value)952{953 int i;954 955 for (i = 0; i < ARRAY_SIZE(rate_table); i++) {956 if (rate_table[i].rate >= rate) {957 *value = rate_table[i].sr;958 return 0;959 }960 }961 *value = rate_table[0].sr;962 return -EINVAL;963}964 965static int max98088_dai1_hw_params(struct snd_pcm_substream *substream,966 struct snd_pcm_hw_params *params,967 struct snd_soc_dai *dai)968{969 struct snd_soc_component *component = dai->component;970 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);971 struct max98088_cdata *cdata;972 unsigned long long ni;973 unsigned int rate;974 u8 regval;975 976 cdata = &max98088->dai[0];977 978 rate = params_rate(params);979 980 switch (params_width(params)) {981 case 16:982 snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,983 M98088_DAI_WS, 0);984 break;985 case 24:986 snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,987 M98088_DAI_WS, M98088_DAI_WS);988 break;989 default:990 return -EINVAL;991 }992 993 snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);994 995 if (rate_value(rate, ®val))996 return -EINVAL;997 998 snd_soc_component_update_bits(component, M98088_REG_11_DAI1_CLKMODE,999 M98088_CLKMODE_MASK, regval);1000 cdata->rate = rate;1001 1002 /* Configure NI when operating as master */1003 if (snd_soc_component_read(component, M98088_REG_14_DAI1_FORMAT)1004 & M98088_DAI_MAS) {1005 unsigned long pclk;1006 1007 if (max98088->sysclk == 0) {1008 dev_err(component->dev, "Invalid system clock frequency\n");1009 return -EINVAL;1010 }1011 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)1012 * (unsigned long long int)rate;1013 pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler);1014 ni = DIV_ROUND_CLOSEST_ULL(ni, pclk);1015 snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,1016 (ni >> 8) & 0x7F);1017 snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO,1018 ni & 0xFF);1019 }1020 1021 /* Update sample rate mode */1022 if (rate < 50000)1023 snd_soc_component_update_bits(component, M98088_REG_18_DAI1_FILTERS,1024 M98088_DAI_DHF, 0);1025 else1026 snd_soc_component_update_bits(component, M98088_REG_18_DAI1_FILTERS,1027 M98088_DAI_DHF, M98088_DAI_DHF);1028 1029 snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,1030 M98088_SHDNRUN);1031 1032 return 0;1033}1034 1035static int max98088_dai2_hw_params(struct snd_pcm_substream *substream,1036 struct snd_pcm_hw_params *params,1037 struct snd_soc_dai *dai)1038{1039 struct snd_soc_component *component = dai->component;1040 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1041 struct max98088_cdata *cdata;1042 unsigned long long ni;1043 unsigned int rate;1044 u8 regval;1045 1046 cdata = &max98088->dai[1];1047 1048 rate = params_rate(params);1049 1050 switch (params_width(params)) {1051 case 16:1052 snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,1053 M98088_DAI_WS, 0);1054 break;1055 case 24:1056 snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,1057 M98088_DAI_WS, M98088_DAI_WS);1058 break;1059 default:1060 return -EINVAL;1061 }1062 1063 snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN, 0);1064 1065 if (rate_value(rate, ®val))1066 return -EINVAL;1067 1068 snd_soc_component_update_bits(component, M98088_REG_19_DAI2_CLKMODE,1069 M98088_CLKMODE_MASK, regval);1070 cdata->rate = rate;1071 1072 /* Configure NI when operating as master */1073 if (snd_soc_component_read(component, M98088_REG_1C_DAI2_FORMAT)1074 & M98088_DAI_MAS) {1075 unsigned long pclk;1076 1077 if (max98088->sysclk == 0) {1078 dev_err(component->dev, "Invalid system clock frequency\n");1079 return -EINVAL;1080 }1081 ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL)1082 * (unsigned long long int)rate;1083 pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler);1084 ni = DIV_ROUND_CLOSEST_ULL(ni, pclk);1085 snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,1086 (ni >> 8) & 0x7F);1087 snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO,1088 ni & 0xFF);1089 }1090 1091 /* Update sample rate mode */1092 if (rate < 50000)1093 snd_soc_component_update_bits(component, M98088_REG_20_DAI2_FILTERS,1094 M98088_DAI_DHF, 0);1095 else1096 snd_soc_component_update_bits(component, M98088_REG_20_DAI2_FILTERS,1097 M98088_DAI_DHF, M98088_DAI_DHF);1098 1099 snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS, M98088_SHDNRUN,1100 M98088_SHDNRUN);1101 1102 return 0;1103}1104 1105static int max98088_dai_set_sysclk(struct snd_soc_dai *dai,1106 int clk_id, unsigned int freq, int dir)1107{1108 struct snd_soc_component *component = dai->component;1109 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1110 1111 /* Requested clock frequency is already setup */1112 if (freq == max98088->sysclk)1113 return 0;1114 1115 if (!IS_ERR(max98088->mclk)) {1116 freq = clk_round_rate(max98088->mclk, freq);1117 clk_set_rate(max98088->mclk, freq);1118 }1119 1120 /* Setup clocks for slave mode, and using the PLL1121 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)1122 * 0x02 (when master clk is 20MHz to 30MHz)..1123 */1124 if ((freq >= 10000000) && (freq < 20000000)) {1125 snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x10);1126 max98088->mclk_prescaler = 1;1127 } else if ((freq >= 20000000) && (freq < 30000000)) {1128 snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x20);1129 max98088->mclk_prescaler = 2;1130 } else {1131 dev_err(component->dev, "Invalid master clock frequency\n");1132 return -EINVAL;1133 }1134 1135 if (snd_soc_component_read(component, M98088_REG_51_PWR_SYS) & M98088_SHDNRUN) {1136 snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS,1137 M98088_SHDNRUN, 0);1138 snd_soc_component_update_bits(component, M98088_REG_51_PWR_SYS,1139 M98088_SHDNRUN, M98088_SHDNRUN);1140 }1141 1142 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);1143 1144 max98088->sysclk = freq;1145 return 0;1146}1147 1148static int max98088_dai1_set_fmt(struct snd_soc_dai *codec_dai,1149 unsigned int fmt)1150{1151 struct snd_soc_component *component = codec_dai->component;1152 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1153 struct max98088_cdata *cdata;1154 u8 reg15val;1155 u8 reg14val = 0;1156 1157 cdata = &max98088->dai[0];1158 1159 if (fmt != cdata->fmt) {1160 cdata->fmt = fmt;1161 1162 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {1163 case SND_SOC_DAIFMT_CBC_CFC:1164 /* Consumer mode PLL */1165 snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI,1166 0x80);1167 snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO,1168 0x00);1169 break;1170 case SND_SOC_DAIFMT_CBP_CFP:1171 /* Set to provider mode */1172 reg14val |= M98088_DAI_MAS;1173 break;1174 default:1175 dev_err(component->dev, "Clock mode unsupported");1176 return -EINVAL;1177 }1178 1179 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1180 case SND_SOC_DAIFMT_I2S:1181 reg14val |= M98088_DAI_DLY;1182 break;1183 case SND_SOC_DAIFMT_LEFT_J:1184 break;1185 default:1186 return -EINVAL;1187 }1188 1189 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {1190 case SND_SOC_DAIFMT_NB_NF:1191 break;1192 case SND_SOC_DAIFMT_NB_IF:1193 reg14val |= M98088_DAI_WCI;1194 break;1195 case SND_SOC_DAIFMT_IB_NF:1196 reg14val |= M98088_DAI_BCI;1197 break;1198 case SND_SOC_DAIFMT_IB_IF:1199 reg14val |= M98088_DAI_BCI|M98088_DAI_WCI;1200 break;1201 default:1202 return -EINVAL;1203 }1204 1205 snd_soc_component_update_bits(component, M98088_REG_14_DAI1_FORMAT,1206 M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |1207 M98088_DAI_WCI, reg14val);1208 1209 reg15val = M98088_DAI_BSEL64;1210 if (max98088->digmic)1211 reg15val |= M98088_DAI_OSR64;1212 snd_soc_component_write(component, M98088_REG_15_DAI1_CLOCK, reg15val);1213 }1214 1215 return 0;1216}1217 1218static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,1219 unsigned int fmt)1220{1221 struct snd_soc_component *component = codec_dai->component;1222 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1223 struct max98088_cdata *cdata;1224 u8 reg1Cval = 0;1225 1226 cdata = &max98088->dai[1];1227 1228 if (fmt != cdata->fmt) {1229 cdata->fmt = fmt;1230 1231 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {1232 case SND_SOC_DAIFMT_CBC_CFC:1233 /* Consumer mode PLL */1234 snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI,1235 0x80);1236 snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO,1237 0x00);1238 break;1239 case SND_SOC_DAIFMT_CBP_CFP:1240 /* Set to provider mode */1241 reg1Cval |= M98088_DAI_MAS;1242 break;1243 default:1244 dev_err(component->dev, "Clock mode unsupported");1245 return -EINVAL;1246 }1247 1248 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1249 case SND_SOC_DAIFMT_I2S:1250 reg1Cval |= M98088_DAI_DLY;1251 break;1252 case SND_SOC_DAIFMT_LEFT_J:1253 break;1254 default:1255 return -EINVAL;1256 }1257 1258 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {1259 case SND_SOC_DAIFMT_NB_NF:1260 break;1261 case SND_SOC_DAIFMT_NB_IF:1262 reg1Cval |= M98088_DAI_WCI;1263 break;1264 case SND_SOC_DAIFMT_IB_NF:1265 reg1Cval |= M98088_DAI_BCI;1266 break;1267 case SND_SOC_DAIFMT_IB_IF:1268 reg1Cval |= M98088_DAI_BCI|M98088_DAI_WCI;1269 break;1270 default:1271 return -EINVAL;1272 }1273 1274 snd_soc_component_update_bits(component, M98088_REG_1C_DAI2_FORMAT,1275 M98088_DAI_MAS | M98088_DAI_DLY | M98088_DAI_BCI |1276 M98088_DAI_WCI, reg1Cval);1277 1278 snd_soc_component_write(component, M98088_REG_1D_DAI2_CLOCK,1279 M98088_DAI_BSEL64);1280 }1281 1282 return 0;1283}1284 1285static int max98088_dai1_mute(struct snd_soc_dai *codec_dai, int mute,1286 int direction)1287{1288 struct snd_soc_component *component = codec_dai->component;1289 int reg;1290 1291 if (mute)1292 reg = M98088_DAI_MUTE;1293 else1294 reg = 0;1295 1296 snd_soc_component_update_bits(component, M98088_REG_2F_LVL_DAI1_PLAY,1297 M98088_DAI_MUTE_MASK, reg);1298 return 0;1299}1300 1301static int max98088_dai2_mute(struct snd_soc_dai *codec_dai, int mute,1302 int direction)1303{1304 struct snd_soc_component *component = codec_dai->component;1305 int reg;1306 1307 if (mute)1308 reg = M98088_DAI_MUTE;1309 else1310 reg = 0;1311 1312 snd_soc_component_update_bits(component, M98088_REG_31_LVL_DAI2_PLAY,1313 M98088_DAI_MUTE_MASK, reg);1314 return 0;1315}1316 1317static int max98088_set_bias_level(struct snd_soc_component *component,1318 enum snd_soc_bias_level level)1319{1320 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1321 int ret;1322 1323 switch (level) {1324 case SND_SOC_BIAS_ON:1325 break;1326 1327 case SND_SOC_BIAS_PREPARE:1328 /*1329 * SND_SOC_BIAS_PREPARE is called while preparing for a1330 * transition to ON or away from ON. If current bias_level1331 * is SND_SOC_BIAS_ON, then it is preparing for a transition1332 * away from ON. Disable the clock in that case, otherwise1333 * enable it.1334 */1335 if (!IS_ERR(max98088->mclk)) {1336 if (snd_soc_component_get_bias_level(component) ==1337 SND_SOC_BIAS_ON) {1338 clk_disable_unprepare(max98088->mclk);1339 } else {1340 ret = clk_prepare_enable(max98088->mclk);1341 if (ret)1342 return ret;1343 }1344 }1345 break;1346 1347 case SND_SOC_BIAS_STANDBY:1348 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)1349 regcache_sync(max98088->regmap);1350 1351 snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN,1352 M98088_MBEN, M98088_MBEN);1353 break;1354 1355 case SND_SOC_BIAS_OFF:1356 snd_soc_component_update_bits(component, M98088_REG_4C_PWR_EN_IN,1357 M98088_MBEN, 0);1358 regcache_mark_dirty(max98088->regmap);1359 break;1360 }1361 return 0;1362}1363 1364#define MAX98088_RATES SNDRV_PCM_RATE_8000_960001365#define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)1366 1367static const struct snd_soc_dai_ops max98088_dai1_ops = {1368 .set_sysclk = max98088_dai_set_sysclk,1369 .set_fmt = max98088_dai1_set_fmt,1370 .hw_params = max98088_dai1_hw_params,1371 .mute_stream = max98088_dai1_mute,1372 .no_capture_mute = 1,1373};1374 1375static const struct snd_soc_dai_ops max98088_dai2_ops = {1376 .set_sysclk = max98088_dai_set_sysclk,1377 .set_fmt = max98088_dai2_set_fmt,1378 .hw_params = max98088_dai2_hw_params,1379 .mute_stream = max98088_dai2_mute,1380 .no_capture_mute = 1,1381};1382 1383static struct snd_soc_dai_driver max98088_dai[] = {1384{1385 .name = "HiFi",1386 .playback = {1387 .stream_name = "HiFi Playback",1388 .channels_min = 1,1389 .channels_max = 2,1390 .rates = MAX98088_RATES,1391 .formats = MAX98088_FORMATS,1392 },1393 .capture = {1394 .stream_name = "HiFi Capture",1395 .channels_min = 1,1396 .channels_max = 2,1397 .rates = MAX98088_RATES,1398 .formats = MAX98088_FORMATS,1399 },1400 .ops = &max98088_dai1_ops,1401},1402{1403 .name = "Aux",1404 .playback = {1405 .stream_name = "Aux Playback",1406 .channels_min = 1,1407 .channels_max = 2,1408 .rates = MAX98088_RATES,1409 .formats = MAX98088_FORMATS,1410 },1411 .ops = &max98088_dai2_ops,1412}1413};1414 1415static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"};1416 1417static int max98088_get_channel(struct snd_soc_component *component, const char *name)1418{1419 int ret;1420 1421 ret = match_string(eq_mode_name, ARRAY_SIZE(eq_mode_name), name);1422 if (ret < 0)1423 dev_err(component->dev, "Bad EQ channel name '%s'\n", name);1424 return ret;1425}1426 1427static void max98088_setup_eq1(struct snd_soc_component *component)1428{1429 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1430 struct max98088_pdata *pdata = max98088->pdata;1431 struct max98088_eq_cfg *coef_set;1432 int best, best_val, save, i, sel, fs;1433 struct max98088_cdata *cdata;1434 1435 cdata = &max98088->dai[0];1436 1437 if (!pdata || !max98088->eq_textcnt)1438 return;1439 1440 /* Find the selected configuration with nearest sample rate */1441 fs = cdata->rate;1442 sel = cdata->eq_sel;1443 1444 best = 0;1445 best_val = INT_MAX;1446 for (i = 0; i < pdata->eq_cfgcnt; i++) {1447 if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 &&1448 abs(pdata->eq_cfg[i].rate - fs) < best_val) {1449 best = i;1450 best_val = abs(pdata->eq_cfg[i].rate - fs);1451 }1452 }1453 1454 dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",1455 pdata->eq_cfg[best].name,1456 pdata->eq_cfg[best].rate, fs);1457 1458 /* Disable EQ while configuring, and save current on/off state */1459 save = snd_soc_component_read(component, M98088_REG_49_CFG_LEVEL);1460 snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, 0);1461 1462 coef_set = &pdata->eq_cfg[sel];1463 1464 m98088_eq_band(component, 0, 0, coef_set->band1);1465 m98088_eq_band(component, 0, 1, coef_set->band2);1466 m98088_eq_band(component, 0, 2, coef_set->band3);1467 m98088_eq_band(component, 0, 3, coef_set->band4);1468 m98088_eq_band(component, 0, 4, coef_set->band5);1469 1470 /* Restore the original on/off state */1471 snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ1EN, save);1472}1473 1474static void max98088_setup_eq2(struct snd_soc_component *component)1475{1476 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1477 struct max98088_pdata *pdata = max98088->pdata;1478 struct max98088_eq_cfg *coef_set;1479 int best, best_val, save, i, sel, fs;1480 struct max98088_cdata *cdata;1481 1482 cdata = &max98088->dai[1];1483 1484 if (!pdata || !max98088->eq_textcnt)1485 return;1486 1487 /* Find the selected configuration with nearest sample rate */1488 fs = cdata->rate;1489 1490 sel = cdata->eq_sel;1491 best = 0;1492 best_val = INT_MAX;1493 for (i = 0; i < pdata->eq_cfgcnt; i++) {1494 if (strcmp(pdata->eq_cfg[i].name, max98088->eq_texts[sel]) == 0 &&1495 abs(pdata->eq_cfg[i].rate - fs) < best_val) {1496 best = i;1497 best_val = abs(pdata->eq_cfg[i].rate - fs);1498 }1499 }1500 1501 dev_dbg(component->dev, "Selected %s/%dHz for %dHz sample rate\n",1502 pdata->eq_cfg[best].name,1503 pdata->eq_cfg[best].rate, fs);1504 1505 /* Disable EQ while configuring, and save current on/off state */1506 save = snd_soc_component_read(component, M98088_REG_49_CFG_LEVEL);1507 snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN, 0);1508 1509 coef_set = &pdata->eq_cfg[sel];1510 1511 m98088_eq_band(component, 1, 0, coef_set->band1);1512 m98088_eq_band(component, 1, 1, coef_set->band2);1513 m98088_eq_band(component, 1, 2, coef_set->band3);1514 m98088_eq_band(component, 1, 3, coef_set->band4);1515 m98088_eq_band(component, 1, 4, coef_set->band5);1516 1517 /* Restore the original on/off state */1518 snd_soc_component_update_bits(component, M98088_REG_49_CFG_LEVEL, M98088_EQ2EN,1519 save);1520}1521 1522static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol,1523 struct snd_ctl_elem_value *ucontrol)1524{1525 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1526 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1527 struct max98088_pdata *pdata = max98088->pdata;1528 int channel = max98088_get_channel(component, kcontrol->id.name);1529 struct max98088_cdata *cdata;1530 int sel = ucontrol->value.enumerated.item[0];1531 1532 if (channel < 0)1533 return channel;1534 1535 cdata = &max98088->dai[channel];1536 1537 if (sel >= pdata->eq_cfgcnt)1538 return -EINVAL;1539 1540 cdata->eq_sel = sel;1541 1542 switch (channel) {1543 case 0:1544 max98088_setup_eq1(component);1545 break;1546 case 1:1547 max98088_setup_eq2(component);1548 break;1549 }1550 1551 return 0;1552}1553 1554static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol,1555 struct snd_ctl_elem_value *ucontrol)1556{1557 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1558 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1559 int channel = max98088_get_channel(component, kcontrol->id.name);1560 struct max98088_cdata *cdata;1561 1562 if (channel < 0)1563 return channel;1564 1565 cdata = &max98088->dai[channel];1566 ucontrol->value.enumerated.item[0] = cdata->eq_sel;1567 return 0;1568}1569 1570static void max98088_handle_eq_pdata(struct snd_soc_component *component)1571{1572 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1573 struct max98088_pdata *pdata = max98088->pdata;1574 struct max98088_eq_cfg *cfg;1575 unsigned int cfgcnt;1576 int i, j;1577 const char **t;1578 int ret;1579 struct snd_kcontrol_new controls[] = {1580 SOC_ENUM_EXT((char *)eq_mode_name[0],1581 max98088->eq_enum,1582 max98088_get_eq_enum,1583 max98088_put_eq_enum),1584 SOC_ENUM_EXT((char *)eq_mode_name[1],1585 max98088->eq_enum,1586 max98088_get_eq_enum,1587 max98088_put_eq_enum),1588 };1589 BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(eq_mode_name));1590 1591 cfg = pdata->eq_cfg;1592 cfgcnt = pdata->eq_cfgcnt;1593 1594 /* Setup an array of texts for the equalizer enum.1595 * This is based on Mark Brown's equalizer driver code.1596 */1597 max98088->eq_textcnt = 0;1598 max98088->eq_texts = NULL;1599 for (i = 0; i < cfgcnt; i++) {1600 for (j = 0; j < max98088->eq_textcnt; j++) {1601 if (strcmp(cfg[i].name, max98088->eq_texts[j]) == 0)1602 break;1603 }1604 1605 if (j != max98088->eq_textcnt)1606 continue;1607 1608 /* Expand the array */1609 t = krealloc(max98088->eq_texts,1610 sizeof(char *) * (max98088->eq_textcnt + 1),1611 GFP_KERNEL);1612 if (t == NULL)1613 continue;1614 1615 /* Store the new entry */1616 t[max98088->eq_textcnt] = cfg[i].name;1617 max98088->eq_textcnt++;1618 max98088->eq_texts = t;1619 }1620 1621 /* Now point the soc_enum to .texts array items */1622 max98088->eq_enum.texts = max98088->eq_texts;1623 max98088->eq_enum.items = max98088->eq_textcnt;1624 1625 ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));1626 if (ret != 0)1627 dev_err(component->dev, "Failed to add EQ control: %d\n", ret);1628}1629 1630static void max98088_handle_pdata(struct snd_soc_component *component)1631{1632 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1633 struct max98088_pdata *pdata = max98088->pdata;1634 u8 regval = 0;1635 1636 if (!pdata) {1637 dev_dbg(component->dev, "No platform data\n");1638 return;1639 }1640 1641 /* Configure mic for analog/digital mic mode */1642 if (pdata->digmic_left_mode)1643 regval |= M98088_DIGMIC_L;1644 1645 if (pdata->digmic_right_mode)1646 regval |= M98088_DIGMIC_R;1647 1648 max98088->digmic = (regval ? 1 : 0);1649 1650 snd_soc_component_write(component, M98088_REG_48_CFG_MIC, regval);1651 1652 /* Configure receiver output */1653 regval = ((pdata->receiver_mode) ? M98088_REC_LINEMODE : 0);1654 snd_soc_component_update_bits(component, M98088_REG_2A_MIC_REC_CNTL,1655 M98088_REC_LINEMODE_MASK, regval);1656 1657 /* Configure equalizers */1658 if (pdata->eq_cfgcnt)1659 max98088_handle_eq_pdata(component);1660}1661 1662static int max98088_probe(struct snd_soc_component *component)1663{1664 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1665 struct max98088_cdata *cdata;1666 int ret = 0;1667 1668 regcache_mark_dirty(max98088->regmap);1669 1670 /* initialize private data */1671 1672 max98088->sysclk = (unsigned)-1;1673 max98088->eq_textcnt = 0;1674 1675 cdata = &max98088->dai[0];1676 cdata->rate = (unsigned)-1;1677 cdata->fmt = (unsigned)-1;1678 cdata->eq_sel = 0;1679 1680 cdata = &max98088->dai[1];1681 cdata->rate = (unsigned)-1;1682 cdata->fmt = (unsigned)-1;1683 cdata->eq_sel = 0;1684 1685 max98088->ina_state = 0;1686 max98088->inb_state = 0;1687 max98088->ex_mode = 0;1688 max98088->digmic = 0;1689 max98088->mic1pre = 0;1690 max98088->mic2pre = 0;1691 1692 ret = snd_soc_component_read(component, M98088_REG_FF_REV_ID);1693 if (ret < 0) {1694 dev_err(component->dev, "Failed to read device revision: %d\n",1695 ret);1696 goto err_access;1697 }1698 dev_info(component->dev, "revision %c\n", ret - 0x40 + 'A');1699 1700 snd_soc_component_write(component, M98088_REG_51_PWR_SYS, M98088_PWRSV);1701 1702 snd_soc_component_write(component, M98088_REG_0F_IRQ_ENABLE, 0x00);1703 1704 snd_soc_component_write(component, M98088_REG_22_MIX_DAC,1705 M98088_DAI1L_TO_DACL|M98088_DAI2L_TO_DACL|1706 M98088_DAI1R_TO_DACR|M98088_DAI2R_TO_DACR);1707 1708 snd_soc_component_write(component, M98088_REG_4E_BIAS_CNTL, 0xF0);1709 snd_soc_component_write(component, M98088_REG_50_DAC_BIAS2, 0x0F);1710 1711 snd_soc_component_write(component, M98088_REG_16_DAI1_IOCFG,1712 M98088_S1NORMAL|M98088_SDATA);1713 1714 snd_soc_component_write(component, M98088_REG_1E_DAI2_IOCFG,1715 M98088_S2NORMAL|M98088_SDATA);1716 1717 max98088_handle_pdata(component);1718 1719err_access:1720 return ret;1721}1722 1723static void max98088_remove(struct snd_soc_component *component)1724{1725 struct max98088_priv *max98088 = snd_soc_component_get_drvdata(component);1726 1727 kfree(max98088->eq_texts);1728}1729 1730static const struct snd_soc_component_driver soc_component_dev_max98088 = {1731 .probe = max98088_probe,1732 .remove = max98088_remove,1733 .set_bias_level = max98088_set_bias_level,1734 .controls = max98088_snd_controls,1735 .num_controls = ARRAY_SIZE(max98088_snd_controls),1736 .dapm_widgets = max98088_dapm_widgets,1737 .num_dapm_widgets = ARRAY_SIZE(max98088_dapm_widgets),1738 .dapm_routes = max98088_audio_map,1739 .num_dapm_routes = ARRAY_SIZE(max98088_audio_map),1740 .suspend_bias_off = 1,1741 .idle_bias_on = 1,1742 .use_pmdown_time = 1,1743 .endianness = 1,1744};1745 1746static const struct i2c_device_id max98088_i2c_id[] = {1747 { "max98088", MAX98088 },1748 { "max98089", MAX98089 },1749 { }1750};1751MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);1752 1753static int max98088_i2c_probe(struct i2c_client *i2c)1754{1755 struct max98088_priv *max98088;1756 const struct i2c_device_id *id;1757 1758 max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv),1759 GFP_KERNEL);1760 if (max98088 == NULL)1761 return -ENOMEM;1762 1763 max98088->regmap = devm_regmap_init_i2c(i2c, &max98088_regmap);1764 if (IS_ERR(max98088->regmap))1765 return PTR_ERR(max98088->regmap);1766 1767 max98088->mclk = devm_clk_get(&i2c->dev, "mclk");1768 if (IS_ERR(max98088->mclk))1769 if (PTR_ERR(max98088->mclk) == -EPROBE_DEFER)1770 return PTR_ERR(max98088->mclk);1771 1772 id = i2c_match_id(max98088_i2c_id, i2c);1773 max98088->devtype = id->driver_data;1774 1775 i2c_set_clientdata(i2c, max98088);1776 max98088->pdata = i2c->dev.platform_data;1777 1778 return devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_max98088,1779 &max98088_dai[0], 2);1780}1781 1782#if defined(CONFIG_OF)1783static const struct of_device_id max98088_of_match[] = {1784 { .compatible = "maxim,max98088" },1785 { .compatible = "maxim,max98089" },1786 { }1787};1788MODULE_DEVICE_TABLE(of, max98088_of_match);1789#endif1790 1791static struct i2c_driver max98088_i2c_driver = {1792 .driver = {1793 .name = "max98088",1794 .of_match_table = of_match_ptr(max98088_of_match),1795 },1796 .probe = max98088_i2c_probe,1797 .id_table = max98088_i2c_id,1798};1799 1800module_i2c_driver(max98088_i2c_driver);1801 1802MODULE_DESCRIPTION("ALSA SoC MAX98088 driver");1803MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin");1804MODULE_LICENSE("GPL");1805