0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include <linux/module.h>
0030 #include <linux/kernel.h>
0031 #include <linux/init.h>
0032 #include <linux/delay.h>
0033 #include <linux/pm.h>
0034 #include <linux/i2c.h>
0035 #include <linux/of_device.h>
0036 #include <linux/regmap.h>
0037 #include <linux/spi/spi.h>
0038 #include <linux/slab.h>
0039 #include <sound/core.h>
0040 #include <sound/pcm.h>
0041 #include <sound/pcm_params.h>
0042 #include <sound/soc.h>
0043 #include <sound/initval.h>
0044 #include <sound/tlv.h>
0045 #include <asm/div64.h>
0046
0047 #include "wm8753.h"
0048
0049 static int caps_charge = 2000;
0050 module_param(caps_charge, int, 0);
0051 MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
0052
0053 static int wm8753_hifi_write_dai_fmt(struct snd_soc_component *component,
0054 unsigned int fmt);
0055 static int wm8753_voice_write_dai_fmt(struct snd_soc_component *component,
0056 unsigned int fmt);
0057
0058
0059
0060
0061
0062
0063 static const struct reg_default wm8753_reg_defaults[] = {
0064 { 0x00, 0x0000 },
0065 { 0x01, 0x0008 },
0066 { 0x02, 0x0000 },
0067 { 0x03, 0x000a },
0068 { 0x04, 0x000a },
0069 { 0x05, 0x0033 },
0070 { 0x06, 0x0000 },
0071 { 0x07, 0x0007 },
0072 { 0x08, 0x00ff },
0073 { 0x09, 0x00ff },
0074 { 0x0a, 0x000f },
0075 { 0x0b, 0x000f },
0076 { 0x0c, 0x007b },
0077 { 0x0d, 0x0000 },
0078 { 0x0e, 0x0032 },
0079 { 0x0f, 0x0000 },
0080 { 0x10, 0x00c3 },
0081 { 0x11, 0x00c3 },
0082 { 0x12, 0x00c0 },
0083 { 0x13, 0x0000 },
0084 { 0x14, 0x0000 },
0085 { 0x15, 0x0000 },
0086 { 0x16, 0x0000 },
0087 { 0x17, 0x0000 },
0088 { 0x18, 0x0000 },
0089 { 0x19, 0x0000 },
0090 { 0x1a, 0x0000 },
0091 { 0x1b, 0x0000 },
0092 { 0x1c, 0x0000 },
0093 { 0x1d, 0x0000 },
0094 { 0x1e, 0x0000 },
0095 { 0x1f, 0x0000 },
0096 { 0x20, 0x0055 },
0097 { 0x21, 0x0005 },
0098 { 0x22, 0x0050 },
0099 { 0x23, 0x0055 },
0100 { 0x24, 0x0050 },
0101 { 0x25, 0x0055 },
0102 { 0x26, 0x0050 },
0103 { 0x27, 0x0055 },
0104 { 0x28, 0x0079 },
0105 { 0x29, 0x0079 },
0106 { 0x2a, 0x0079 },
0107 { 0x2b, 0x0079 },
0108 { 0x2c, 0x0079 },
0109 { 0x2d, 0x0000 },
0110 { 0x2e, 0x0000 },
0111 { 0x2f, 0x0000 },
0112 { 0x30, 0x0000 },
0113 { 0x31, 0x0097 },
0114 { 0x32, 0x0097 },
0115 { 0x33, 0x0000 },
0116 { 0x34, 0x0004 },
0117 { 0x35, 0x0000 },
0118 { 0x36, 0x0083 },
0119 { 0x37, 0x0024 },
0120 { 0x38, 0x01ba },
0121 { 0x39, 0x0000 },
0122 { 0x3a, 0x0083 },
0123 { 0x3b, 0x0024 },
0124 { 0x3c, 0x01ba },
0125 { 0x3d, 0x0000 },
0126 { 0x3e, 0x0000 },
0127 { 0x3f, 0x0000 },
0128 };
0129
0130 static bool wm8753_volatile(struct device *dev, unsigned int reg)
0131 {
0132 return reg == WM8753_RESET;
0133 }
0134
0135
0136 struct wm8753_priv {
0137 struct regmap *regmap;
0138 unsigned int sysclk;
0139 unsigned int pcmclk;
0140
0141 unsigned int voice_fmt;
0142 unsigned int hifi_fmt;
0143
0144 int dai_func;
0145 struct delayed_work charge_work;
0146 };
0147
0148 #define wm8753_reset(c) snd_soc_component_write(c, WM8753_RESET, 0)
0149
0150
0151
0152
0153 static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"};
0154 static const char *wm8753_base_filter[] =
0155 {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
0156 "100Hz @ 8kHz", "200Hz @ 8kHz"};
0157 static const char *wm8753_treble[] = {"8kHz", "4kHz"};
0158 static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"};
0159 static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"};
0160 static const char *wm8753_3d_func[] = {"Capture", "Playback"};
0161 static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"};
0162 static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"};
0163 static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"};
0164 static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"};
0165 static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"};
0166 static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
0167 "Line 1", "Line 2"};
0168 static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"};
0169 static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"};
0170 static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"};
0171 static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
0172 static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2",
0173 "Right PGA"};
0174 static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right",
0175 "Left + Right"};
0176 static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"};
0177 static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"};
0178 static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
0179 static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
0180 static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left",
0181 "Analogue Mix Right", "Digital Mono Mix"};
0182 static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
0183 "82Hz @ 8kHz", "170Hz @ 8kHz"};
0184 static const char *wm8753_adc_filter[] = {"HiFi", "Voice"};
0185 static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"};
0186 static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
0187 static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC",
0188 "Channel Swap"};
0189 static const char *wm8753_rout2_phase[] = {"Non Inverted", "Inverted"};
0190
0191 static const struct soc_enum wm8753_enum[] = {
0192 SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base),
0193 SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
0194 SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble),
0195 SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
0196 SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type),
0197 SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func),
0198 SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc),
0199 SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc),
0200 SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
0201 SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
0202 SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase),
0203 SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
0204 SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux),
0205 SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux),
0206 SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux),
0207 SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
0208 SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
0209 SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
0210 SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3),
0211 SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4),
0212 SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel),
0213 SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel),
0214 SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
0215 SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
0216 SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
0217 SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel),
0218 SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
0219 SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
0220 SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase),
0221 };
0222
0223
0224 static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
0225 struct snd_ctl_elem_value *ucontrol)
0226 {
0227 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0228 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
0229
0230 ucontrol->value.enumerated.item[0] = wm8753->dai_func;
0231 return 0;
0232 }
0233
0234 static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
0235 struct snd_ctl_elem_value *ucontrol)
0236 {
0237 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
0238 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
0239 u16 ioctl;
0240
0241 if (wm8753->dai_func == ucontrol->value.enumerated.item[0])
0242 return 0;
0243
0244 if (snd_soc_component_active(component))
0245 return -EBUSY;
0246
0247 ioctl = snd_soc_component_read(component, WM8753_IOCTL);
0248
0249 wm8753->dai_func = ucontrol->value.enumerated.item[0];
0250
0251 if (((ioctl >> 2) & 0x3) == wm8753->dai_func)
0252 return 1;
0253
0254 ioctl = (ioctl & 0x1f3) | (wm8753->dai_func << 2);
0255 snd_soc_component_write(component, WM8753_IOCTL, ioctl);
0256
0257
0258 wm8753_hifi_write_dai_fmt(component, wm8753->hifi_fmt);
0259 wm8753_voice_write_dai_fmt(component, wm8753->voice_fmt);
0260
0261 return 1;
0262 }
0263
0264 static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 300, 0);
0265 static const DECLARE_TLV_DB_SCALE(mic_preamp_tlv, 1200, 600, 0);
0266 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
0267 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
0268 static const DECLARE_TLV_DB_RANGE(out_tlv,
0269
0270 0, 48, TLV_DB_SCALE_ITEM(-25500, 0, 0),
0271 48, 127, TLV_DB_SCALE_ITEM(-7300, 100, 0)
0272 );
0273 static const DECLARE_TLV_DB_SCALE(mix_tlv, -1500, 300, 0);
0274 static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
0275 static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
0276
0277 static const struct snd_kcontrol_new wm8753_snd_controls[] = {
0278 SOC_SINGLE("Hi-Fi DAC Left/Right channel Swap", WM8753_HIFI, 5, 1, 0),
0279 SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
0280
0281 SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
0282 adc_tlv),
0283
0284 SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V,
0285 0, 127, 0, out_tlv),
0286 SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0,
0287 127, 0, out_tlv),
0288
0289 SOC_SINGLE_TLV("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0, out_tlv),
0290
0291 SOC_DOUBLE_R_TLV("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7,
0292 1, mix_tlv),
0293 SOC_DOUBLE_R_TLV("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4,
0294 7, 1, mix_tlv),
0295 SOC_DOUBLE_R_TLV("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7,
0296 1, voice_mix_tlv),
0297
0298 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7,
0299 1, 0),
0300 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7,
0301 1, 0),
0302
0303 SOC_SINGLE_TLV("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1, mix_tlv),
0304 SOC_SINGLE_TLV("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1,
0305 mix_tlv),
0306 SOC_SINGLE_TLV("Mono Voice Playback Volume", WM8753_MOUTM2, 0, 7, 1,
0307 voice_mix_tlv),
0308 SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
0309
0310 SOC_ENUM("Bass Boost", wm8753_enum[0]),
0311 SOC_ENUM("Bass Filter", wm8753_enum[1]),
0312 SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
0313
0314 SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
0315 SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
0316
0317 SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1,
0318 rec_mix_tlv),
0319 SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1,
0320 rec_mix_tlv),
0321
0322 SOC_DOUBLE_R_TLV("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0,
0323 pga_tlv),
0324 SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
0325 SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
0326
0327 SOC_ENUM("Capture Filter Select", wm8753_enum[23]),
0328 SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
0329 SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
0330
0331 SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0),
0332 SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
0333 SOC_ENUM("ALC Capture Function", wm8753_enum[3]),
0334 SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
0335 SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1),
0336 SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
0337 SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0),
0338 SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0),
0339 SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
0340 SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
0341
0342 SOC_ENUM("3D Function", wm8753_enum[5]),
0343 SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
0344 SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
0345 SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0),
0346 SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
0347
0348 SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0),
0349 SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0),
0350
0351 SOC_ENUM("De-emphasis", wm8753_enum[8]),
0352 SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
0353 SOC_ENUM("Playback Phase", wm8753_enum[10]),
0354
0355 SOC_SINGLE_TLV("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0, mic_preamp_tlv),
0356 SOC_SINGLE_TLV("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0, mic_preamp_tlv),
0357
0358 SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
0359
0360 SOC_ENUM("ADC Data Select", wm8753_enum[27]),
0361 SOC_ENUM("ROUT2 Phase", wm8753_enum[28]),
0362 };
0363
0364
0365
0366
0367
0368
0369 static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = {
0370 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
0371 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
0372 SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
0373 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
0374 };
0375
0376
0377 static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = {
0378 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
0379 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
0380 SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
0381 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
0382 };
0383
0384
0385 static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = {
0386 SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
0387 SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
0388 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
0389 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
0390 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
0391 };
0392
0393
0394 static const struct snd_kcontrol_new wm8753_mono2_controls =
0395 SOC_DAPM_ENUM("Route", wm8753_enum[17]);
0396
0397
0398 static const struct snd_kcontrol_new wm8753_out3_controls =
0399 SOC_DAPM_ENUM("Route", wm8753_enum[18]);
0400
0401
0402 static const struct snd_kcontrol_new wm8753_out4_controls =
0403 SOC_DAPM_ENUM("Route", wm8753_enum[19]);
0404
0405
0406 static const struct snd_kcontrol_new wm8753_adc_mono_controls =
0407 SOC_DAPM_ENUM("Route", wm8753_enum[22]);
0408
0409
0410 static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = {
0411 SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
0412 SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
0413 SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
0414 };
0415
0416
0417 static const struct snd_kcontrol_new wm8753_adc_left_controls =
0418 SOC_DAPM_ENUM("Route", wm8753_enum[21]);
0419
0420
0421 static const struct snd_kcontrol_new wm8753_adc_right_controls =
0422 SOC_DAPM_ENUM("Route", wm8753_enum[20]);
0423
0424
0425 static const struct snd_kcontrol_new wm8753_mic_mux_controls =
0426 SOC_DAPM_ENUM("Route", wm8753_enum[16]);
0427
0428
0429 static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = {
0430 SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
0431 SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
0432 SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
0433 SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
0434 };
0435
0436
0437 static const struct snd_kcontrol_new wm8753_line_left_controls =
0438 SOC_DAPM_ENUM("Route", wm8753_enum[14]);
0439
0440
0441 static const struct snd_kcontrol_new wm8753_line_right_controls =
0442 SOC_DAPM_ENUM("Route", wm8753_enum[13]);
0443
0444
0445 static const struct snd_kcontrol_new wm8753_line_mono_controls =
0446 SOC_DAPM_ENUM("Route", wm8753_enum[12]);
0447
0448
0449 static const struct snd_kcontrol_new wm8753_line_mux_mix_controls =
0450 SOC_DAPM_ENUM("Route", wm8753_enum[11]);
0451
0452
0453 static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls =
0454 SOC_DAPM_ENUM("Route", wm8753_enum[15]);
0455
0456
0457 static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls =
0458 SOC_DAPM_ENUM("Route", wm8753_enum[25]);
0459
0460 static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
0461 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
0462 SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0,
0463 &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)),
0464 SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0),
0465 SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0),
0466 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0),
0467 SND_SOC_DAPM_OUTPUT("LOUT1"),
0468 SND_SOC_DAPM_OUTPUT("LOUT2"),
0469 SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0,
0470 &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)),
0471 SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0),
0472 SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0),
0473 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0),
0474 SND_SOC_DAPM_OUTPUT("ROUT1"),
0475 SND_SOC_DAPM_OUTPUT("ROUT2"),
0476 SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0,
0477 &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)),
0478 SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0),
0479 SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0),
0480 SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
0481 SND_SOC_DAPM_OUTPUT("MONO1"),
0482 SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
0483 SND_SOC_DAPM_OUTPUT("MONO2"),
0484 SND_SOC_DAPM_MIXER("Out3 Left + Right", SND_SOC_NOPM, 0, 0, NULL, 0),
0485 SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
0486 SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
0487 SND_SOC_DAPM_OUTPUT("OUT3"),
0488 SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls),
0489 SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
0490 SND_SOC_DAPM_OUTPUT("OUT4"),
0491 SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0,
0492 &wm8753_record_mixer_controls[0],
0493 ARRAY_SIZE(wm8753_record_mixer_controls)),
0494 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0),
0495 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0),
0496 SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0,
0497 &wm8753_adc_mono_controls),
0498 SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0,
0499 &wm8753_adc_mono_controls),
0500 SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0,
0501 &wm8753_adc_left_controls),
0502 SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0,
0503 &wm8753_adc_right_controls),
0504 SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0,
0505 &wm8753_mic_mux_controls),
0506 SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0),
0507 SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
0508 SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0,
0509 &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)),
0510 SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0,
0511 &wm8753_line_left_controls),
0512 SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0,
0513 &wm8753_line_right_controls),
0514 SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0,
0515 &wm8753_line_mono_controls),
0516 SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0,
0517 &wm8753_line_mux_mix_controls),
0518 SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0,
0519 &wm8753_rx_mux_mix_controls),
0520 SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0),
0521 SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0),
0522 SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0,
0523 &wm8753_mic_sel_mux_controls),
0524 SND_SOC_DAPM_INPUT("LINE1"),
0525 SND_SOC_DAPM_INPUT("LINE2"),
0526 SND_SOC_DAPM_INPUT("RXP"),
0527 SND_SOC_DAPM_INPUT("RXN"),
0528 SND_SOC_DAPM_INPUT("ACIN"),
0529 SND_SOC_DAPM_OUTPUT("ACOP"),
0530 SND_SOC_DAPM_INPUT("MIC1N"),
0531 SND_SOC_DAPM_INPUT("MIC1"),
0532 SND_SOC_DAPM_INPUT("MIC2N"),
0533 SND_SOC_DAPM_INPUT("MIC2"),
0534 SND_SOC_DAPM_VMID("VREF"),
0535 };
0536
0537 static const struct snd_soc_dapm_route wm8753_dapm_routes[] = {
0538
0539 {"Left Mixer", "Left Playback Switch", "Left DAC"},
0540 {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
0541 {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
0542 {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
0543
0544
0545 {"Right Mixer", "Right Playback Switch", "Right DAC"},
0546 {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
0547 {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
0548 {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
0549
0550
0551 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
0552 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
0553 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
0554 {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
0555 {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
0556
0557
0558 {"Left Out 1", NULL, "Left Mixer"},
0559 {"Left Out 2", NULL, "Left Mixer"},
0560 {"LOUT1", NULL, "Left Out 1"},
0561 {"LOUT2", NULL, "Left Out 2"},
0562
0563
0564 {"Right Out 1", NULL, "Right Mixer"},
0565 {"Right Out 2", NULL, "Right Mixer"},
0566 {"ROUT1", NULL, "Right Out 1"},
0567 {"ROUT2", NULL, "Right Out 2"},
0568
0569
0570 {"Mono Out 1", NULL, "Mono Mixer"},
0571 {"MONO1", NULL, "Mono Out 1"},
0572
0573
0574 {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
0575 {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
0576 {"Mono 2 Mux", "Left", "Left Mixer"},
0577 {"Mono 2 Mux", "Right", "Right Mixer"},
0578 {"Mono Out 2", NULL, "Mono 2 Mux"},
0579 {"MONO2", NULL, "Mono Out 2"},
0580
0581
0582 {"Out3 Left + Right", NULL, "Left Mixer"},
0583 {"Out3 Left + Right", NULL, "Right Mixer"},
0584 {"Out3 Mux", "VREF", "VREF"},
0585 {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
0586 {"Out3 Mux", "ROUT2", "ROUT2"},
0587 {"Out 3", NULL, "Out3 Mux"},
0588 {"OUT3", NULL, "Out 3"},
0589
0590
0591 {"Out4 Mux", "VREF", "VREF"},
0592 {"Out4 Mux", "Capture ST", "Playback Mixer"},
0593 {"Out4 Mux", "LOUT2", "LOUT2"},
0594 {"Out 4", NULL, "Out4 Mux"},
0595 {"OUT4", NULL, "Out 4"},
0596
0597
0598 {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
0599 {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
0600 {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
0601
0602
0603 {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
0604 {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
0605 {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
0606 {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
0607
0608
0609 {"Capture Left Mux", "PGA", "Left Capture Volume"},
0610 {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
0611 {"Capture Left Mux", "Line", "LINE1"},
0612
0613
0614 {"Capture Right Mux", "PGA", "Right Capture Volume"},
0615 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
0616 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
0617
0618
0619 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
0620 {"Capture Left Mixer", "Stereo", "Capture Left Mux"},
0621 {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
0622 {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
0623 {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
0624 {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
0625 {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
0626 {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
0627 {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
0628 {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
0629
0630
0631 {"Left ADC", NULL, "Capture Left Mixer"},
0632 {"Right ADC", NULL, "Capture Right Mixer"},
0633
0634
0635 {"Left Capture Volume", NULL, "ACIN"},
0636
0637
0638 {"Right Capture Volume", NULL, "Mic 2 Volume"},
0639
0640
0641 {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
0642 {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
0643 {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
0644 {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
0645
0646
0647 {"Line Left Mux", "Line 1", "LINE1"},
0648 {"Line Left Mux", "Rx Mix", "Rx Mixer"},
0649
0650
0651 {"Line Right Mux", "Line 2", "LINE2"},
0652 {"Line Right Mux", "Rx Mix", "Rx Mixer"},
0653
0654
0655 {"Line Mono Mux", "Line Mix", "Line Mixer"},
0656 {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
0657
0658
0659 {"Line Mixer", "Line 1 + 2", "LINE1"},
0660 {"Line Mixer", "Line 1 - 2", "LINE1"},
0661 {"Line Mixer", "Line 1 + 2", "LINE2"},
0662 {"Line Mixer", "Line 1 - 2", "LINE2"},
0663 {"Line Mixer", "Line 1", "LINE1"},
0664 {"Line Mixer", "Line 2", "LINE2"},
0665
0666
0667 {"Rx Mixer", "RXP - RXN", "RXP"},
0668 {"Rx Mixer", "RXP + RXN", "RXP"},
0669 {"Rx Mixer", "RXP - RXN", "RXN"},
0670 {"Rx Mixer", "RXP + RXN", "RXN"},
0671 {"Rx Mixer", "RXP", "RXP"},
0672 {"Rx Mixer", "RXN", "RXN"},
0673
0674
0675 {"Mic 1 Volume", NULL, "MIC1N"},
0676 {"Mic 1 Volume", NULL, "Mic Selection Mux"},
0677
0678
0679 {"Mic 2 Volume", NULL, "MIC2N"},
0680 {"Mic 2 Volume", NULL, "MIC2"},
0681
0682
0683 {"Mic Selection Mux", "Mic 1", "MIC1"},
0684 {"Mic Selection Mux", "Mic 2", "MIC2N"},
0685 {"Mic Selection Mux", "Mic 3", "MIC2"},
0686
0687
0688 {"ACOP", NULL, "ALC Mixer"},
0689 };
0690
0691
0692 struct _pll_div {
0693 u32 div2:1;
0694 u32 n:4;
0695 u32 k:24;
0696 };
0697
0698
0699
0700 #define FIXED_PLL_SIZE ((1 << 22) * 10)
0701
0702 static void pll_factors(struct _pll_div *pll_div, unsigned int target,
0703 unsigned int source)
0704 {
0705 u64 Kpart;
0706 unsigned int K, Ndiv, Nmod;
0707
0708 Ndiv = target / source;
0709 if (Ndiv < 6) {
0710 source >>= 1;
0711 pll_div->div2 = 1;
0712 Ndiv = target / source;
0713 } else
0714 pll_div->div2 = 0;
0715
0716 if ((Ndiv < 6) || (Ndiv > 12))
0717 printk(KERN_WARNING
0718 "wm8753: unsupported N = %u\n", Ndiv);
0719
0720 pll_div->n = Ndiv;
0721 Nmod = target % source;
0722 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
0723
0724 do_div(Kpart, source);
0725
0726 K = Kpart & 0xFFFFFFFF;
0727
0728
0729 if ((K % 10) >= 5)
0730 K += 5;
0731
0732
0733 K /= 10;
0734
0735 pll_div->k = K;
0736 }
0737
0738 static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
0739 int source, unsigned int freq_in, unsigned int freq_out)
0740 {
0741 u16 reg, enable;
0742 int offset;
0743 struct snd_soc_component *component = codec_dai->component;
0744
0745 if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
0746 return -ENODEV;
0747
0748 if (pll_id == WM8753_PLL1) {
0749 offset = 0;
0750 enable = 0x10;
0751 reg = snd_soc_component_read(component, WM8753_CLOCK) & 0xffef;
0752 } else {
0753 offset = 4;
0754 enable = 0x8;
0755 reg = snd_soc_component_read(component, WM8753_CLOCK) & 0xfff7;
0756 }
0757
0758 if (!freq_in || !freq_out) {
0759
0760 snd_soc_component_write(component, WM8753_PLL1CTL1 + offset, 0x0026);
0761 snd_soc_component_write(component, WM8753_CLOCK, reg);
0762 return 0;
0763 } else {
0764 u16 value = 0;
0765 struct _pll_div pll_div;
0766
0767 pll_factors(&pll_div, freq_out * 8, freq_in);
0768
0769
0770
0771 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
0772 snd_soc_component_write(component, WM8753_PLL1CTL2 + offset, value);
0773
0774
0775 value = (pll_div.k & 0x03fe00) >> 9;
0776 snd_soc_component_write(component, WM8753_PLL1CTL3 + offset, value);
0777
0778
0779 value = pll_div.k & 0x0001ff;
0780 snd_soc_component_write(component, WM8753_PLL1CTL4 + offset, value);
0781
0782
0783 snd_soc_component_write(component, WM8753_PLL1CTL1 + offset, 0x0027 |
0784 (pll_div.div2 << 3));
0785 snd_soc_component_write(component, WM8753_CLOCK, reg | enable);
0786 }
0787 return 0;
0788 }
0789
0790 struct _coeff_div {
0791 u32 mclk;
0792 u32 rate;
0793 u8 sr:5;
0794 u8 usb:1;
0795 };
0796
0797
0798 static const struct _coeff_div coeff_div[] = {
0799
0800 {12288000, 8000, 0x6, 0x0},
0801 {11289600, 8000, 0x16, 0x0},
0802 {18432000, 8000, 0x7, 0x0},
0803 {16934400, 8000, 0x17, 0x0},
0804 {12000000, 8000, 0x6, 0x1},
0805
0806
0807 {11289600, 11025, 0x18, 0x0},
0808 {16934400, 11025, 0x19, 0x0},
0809 {12000000, 11025, 0x19, 0x1},
0810
0811
0812 {12288000, 16000, 0xa, 0x0},
0813 {18432000, 16000, 0xb, 0x0},
0814 {12000000, 16000, 0xa, 0x1},
0815
0816
0817 {11289600, 22050, 0x1a, 0x0},
0818 {16934400, 22050, 0x1b, 0x0},
0819 {12000000, 22050, 0x1b, 0x1},
0820
0821
0822 {12288000, 32000, 0xc, 0x0},
0823 {18432000, 32000, 0xd, 0x0},
0824 {12000000, 32000, 0xa, 0x1},
0825
0826
0827 {11289600, 44100, 0x10, 0x0},
0828 {16934400, 44100, 0x11, 0x0},
0829 {12000000, 44100, 0x11, 0x1},
0830
0831
0832 {12288000, 48000, 0x0, 0x0},
0833 {18432000, 48000, 0x1, 0x0},
0834 {12000000, 48000, 0x0, 0x1},
0835
0836
0837 {11289600, 88200, 0x1e, 0x0},
0838 {16934400, 88200, 0x1f, 0x0},
0839 {12000000, 88200, 0x1f, 0x1},
0840
0841
0842 {12288000, 96000, 0xe, 0x0},
0843 {18432000, 96000, 0xf, 0x0},
0844 {12000000, 96000, 0xe, 0x1},
0845 };
0846
0847 static int get_coeff(int mclk, int rate)
0848 {
0849 int i;
0850
0851 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
0852 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
0853 return i;
0854 }
0855 return -EINVAL;
0856 }
0857
0858
0859
0860
0861 static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
0862 int clk_id, unsigned int freq, int dir)
0863 {
0864 struct snd_soc_component *component = codec_dai->component;
0865 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
0866
0867 switch (freq) {
0868 case 11289600:
0869 case 12000000:
0870 case 12288000:
0871 case 16934400:
0872 case 18432000:
0873 if (clk_id == WM8753_MCLK) {
0874 wm8753->sysclk = freq;
0875 return 0;
0876 } else if (clk_id == WM8753_PCMCLK) {
0877 wm8753->pcmclk = freq;
0878 return 0;
0879 }
0880 break;
0881 }
0882 return -EINVAL;
0883 }
0884
0885
0886
0887
0888 static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_component *component,
0889 unsigned int fmt)
0890 {
0891 u16 voice = snd_soc_component_read(component, WM8753_PCM) & 0x01ec;
0892
0893
0894 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0895 case SND_SOC_DAIFMT_I2S:
0896 voice |= 0x0002;
0897 break;
0898 case SND_SOC_DAIFMT_RIGHT_J:
0899 break;
0900 case SND_SOC_DAIFMT_LEFT_J:
0901 voice |= 0x0001;
0902 break;
0903 case SND_SOC_DAIFMT_DSP_A:
0904 voice |= 0x0003;
0905 break;
0906 case SND_SOC_DAIFMT_DSP_B:
0907 voice |= 0x0013;
0908 break;
0909 default:
0910 return -EINVAL;
0911 }
0912
0913 snd_soc_component_write(component, WM8753_PCM, voice);
0914 return 0;
0915 }
0916
0917
0918
0919
0920 static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
0921 struct snd_pcm_hw_params *params,
0922 struct snd_soc_dai *dai)
0923 {
0924 struct snd_soc_component *component = dai->component;
0925 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
0926 u16 voice = snd_soc_component_read(component, WM8753_PCM) & 0x01f3;
0927 u16 srate = snd_soc_component_read(component, WM8753_SRATE1) & 0x017f;
0928
0929
0930 switch (params_width(params)) {
0931 case 16:
0932 break;
0933 case 20:
0934 voice |= 0x0004;
0935 break;
0936 case 24:
0937 voice |= 0x0008;
0938 break;
0939 case 32:
0940 voice |= 0x000c;
0941 break;
0942 }
0943
0944
0945 if (params_rate(params) * 384 == wm8753->pcmclk)
0946 srate |= 0x80;
0947 snd_soc_component_write(component, WM8753_SRATE1, srate);
0948
0949 snd_soc_component_write(component, WM8753_PCM, voice);
0950 return 0;
0951 }
0952
0953
0954
0955
0956 static int wm8753_pcm_set_dai_fmt(struct snd_soc_component *component,
0957 unsigned int fmt)
0958 {
0959 u16 voice, ioctl;
0960
0961 voice = snd_soc_component_read(component, WM8753_PCM) & 0x011f;
0962 ioctl = snd_soc_component_read(component, WM8753_IOCTL) & 0x015d;
0963
0964
0965 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0966 case SND_SOC_DAIFMT_CBS_CFS:
0967 break;
0968 case SND_SOC_DAIFMT_CBM_CFM:
0969 ioctl |= 0x2;
0970 fallthrough;
0971 case SND_SOC_DAIFMT_CBM_CFS:
0972 voice |= 0x0040;
0973 break;
0974 default:
0975 return -EINVAL;
0976 }
0977
0978
0979 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0980 case SND_SOC_DAIFMT_DSP_A:
0981 case SND_SOC_DAIFMT_DSP_B:
0982
0983 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0984 case SND_SOC_DAIFMT_NB_NF:
0985 break;
0986 case SND_SOC_DAIFMT_IB_NF:
0987 voice |= 0x0080;
0988 break;
0989 default:
0990 return -EINVAL;
0991 }
0992 break;
0993 case SND_SOC_DAIFMT_I2S:
0994 case SND_SOC_DAIFMT_RIGHT_J:
0995 case SND_SOC_DAIFMT_LEFT_J:
0996 voice &= ~0x0010;
0997 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0998 case SND_SOC_DAIFMT_NB_NF:
0999 break;
1000 case SND_SOC_DAIFMT_IB_IF:
1001 voice |= 0x0090;
1002 break;
1003 case SND_SOC_DAIFMT_IB_NF:
1004 voice |= 0x0080;
1005 break;
1006 case SND_SOC_DAIFMT_NB_IF:
1007 voice |= 0x0010;
1008 break;
1009 default:
1010 return -EINVAL;
1011 }
1012 break;
1013 default:
1014 return -EINVAL;
1015 }
1016
1017 snd_soc_component_write(component, WM8753_PCM, voice);
1018 snd_soc_component_write(component, WM8753_IOCTL, ioctl);
1019 return 0;
1020 }
1021
1022 static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1023 int div_id, int div)
1024 {
1025 struct snd_soc_component *component = codec_dai->component;
1026 u16 reg;
1027
1028 switch (div_id) {
1029 case WM8753_PCMDIV:
1030 reg = snd_soc_component_read(component, WM8753_CLOCK) & 0x003f;
1031 snd_soc_component_write(component, WM8753_CLOCK, reg | div);
1032 break;
1033 case WM8753_BCLKDIV:
1034 reg = snd_soc_component_read(component, WM8753_SRATE2) & 0x01c7;
1035 snd_soc_component_write(component, WM8753_SRATE2, reg | div);
1036 break;
1037 case WM8753_VXCLKDIV:
1038 reg = snd_soc_component_read(component, WM8753_SRATE2) & 0x003f;
1039 snd_soc_component_write(component, WM8753_SRATE2, reg | div);
1040 break;
1041 default:
1042 return -EINVAL;
1043 }
1044 return 0;
1045 }
1046
1047
1048
1049
1050 static int wm8753_hdac_set_dai_fmt(struct snd_soc_component *component,
1051 unsigned int fmt)
1052 {
1053 u16 hifi = snd_soc_component_read(component, WM8753_HIFI) & 0x01e0;
1054
1055
1056 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1057 case SND_SOC_DAIFMT_I2S:
1058 hifi |= 0x0002;
1059 break;
1060 case SND_SOC_DAIFMT_RIGHT_J:
1061 break;
1062 case SND_SOC_DAIFMT_LEFT_J:
1063 hifi |= 0x0001;
1064 break;
1065 case SND_SOC_DAIFMT_DSP_A:
1066 hifi |= 0x0003;
1067 break;
1068 case SND_SOC_DAIFMT_DSP_B:
1069 hifi |= 0x0013;
1070 break;
1071 default:
1072 return -EINVAL;
1073 }
1074
1075 snd_soc_component_write(component, WM8753_HIFI, hifi);
1076 return 0;
1077 }
1078
1079
1080
1081
1082 static int wm8753_i2s_set_dai_fmt(struct snd_soc_component *component,
1083 unsigned int fmt)
1084 {
1085 u16 ioctl, hifi;
1086
1087 hifi = snd_soc_component_read(component, WM8753_HIFI) & 0x013f;
1088 ioctl = snd_soc_component_read(component, WM8753_IOCTL) & 0x00ae;
1089
1090
1091 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1092 case SND_SOC_DAIFMT_CBS_CFS:
1093 break;
1094 case SND_SOC_DAIFMT_CBM_CFM:
1095 ioctl |= 0x1;
1096 fallthrough;
1097 case SND_SOC_DAIFMT_CBM_CFS:
1098 hifi |= 0x0040;
1099 break;
1100 default:
1101 return -EINVAL;
1102 }
1103
1104
1105 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1106 case SND_SOC_DAIFMT_DSP_A:
1107 case SND_SOC_DAIFMT_DSP_B:
1108
1109 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1110 case SND_SOC_DAIFMT_NB_NF:
1111 break;
1112 case SND_SOC_DAIFMT_IB_NF:
1113 hifi |= 0x0080;
1114 break;
1115 default:
1116 return -EINVAL;
1117 }
1118 break;
1119 case SND_SOC_DAIFMT_I2S:
1120 case SND_SOC_DAIFMT_RIGHT_J:
1121 case SND_SOC_DAIFMT_LEFT_J:
1122 hifi &= ~0x0010;
1123 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1124 case SND_SOC_DAIFMT_NB_NF:
1125 break;
1126 case SND_SOC_DAIFMT_IB_IF:
1127 hifi |= 0x0090;
1128 break;
1129 case SND_SOC_DAIFMT_IB_NF:
1130 hifi |= 0x0080;
1131 break;
1132 case SND_SOC_DAIFMT_NB_IF:
1133 hifi |= 0x0010;
1134 break;
1135 default:
1136 return -EINVAL;
1137 }
1138 break;
1139 default:
1140 return -EINVAL;
1141 }
1142
1143 snd_soc_component_write(component, WM8753_HIFI, hifi);
1144 snd_soc_component_write(component, WM8753_IOCTL, ioctl);
1145 return 0;
1146 }
1147
1148
1149
1150
1151 static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1152 struct snd_pcm_hw_params *params,
1153 struct snd_soc_dai *dai)
1154 {
1155 struct snd_soc_component *component = dai->component;
1156 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1157 u16 srate = snd_soc_component_read(component, WM8753_SRATE1) & 0x01c0;
1158 u16 hifi = snd_soc_component_read(component, WM8753_HIFI) & 0x01f3;
1159 int coeff;
1160
1161
1162 coeff = get_coeff(wm8753->sysclk, params_rate(params));
1163 if (coeff < 0) {
1164 printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
1165 return coeff;
1166 }
1167 snd_soc_component_write(component, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
1168 coeff_div[coeff].usb);
1169
1170
1171 switch (params_width(params)) {
1172 case 16:
1173 break;
1174 case 20:
1175 hifi |= 0x0004;
1176 break;
1177 case 24:
1178 hifi |= 0x0008;
1179 break;
1180 case 32:
1181 hifi |= 0x000c;
1182 break;
1183 }
1184
1185 snd_soc_component_write(component, WM8753_HIFI, hifi);
1186 return 0;
1187 }
1188
1189 static int wm8753_mode1v_set_dai_fmt(struct snd_soc_component *component,
1190 unsigned int fmt)
1191 {
1192 u16 clock;
1193
1194
1195 clock = snd_soc_component_read(component, WM8753_CLOCK) & 0xfffb;
1196 snd_soc_component_write(component, WM8753_CLOCK, clock);
1197
1198 return wm8753_vdac_adc_set_dai_fmt(component, fmt);
1199 }
1200
1201 static int wm8753_mode1h_set_dai_fmt(struct snd_soc_component *component,
1202 unsigned int fmt)
1203 {
1204 return wm8753_hdac_set_dai_fmt(component, fmt);
1205 }
1206
1207 static int wm8753_mode2_set_dai_fmt(struct snd_soc_component *component,
1208 unsigned int fmt)
1209 {
1210 u16 clock;
1211
1212
1213 clock = snd_soc_component_read(component, WM8753_CLOCK) & 0xfffb;
1214 snd_soc_component_write(component, WM8753_CLOCK, clock);
1215
1216 return wm8753_vdac_adc_set_dai_fmt(component, fmt);
1217 }
1218
1219 static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_component *component,
1220 unsigned int fmt)
1221 {
1222 u16 clock;
1223
1224
1225 clock = snd_soc_component_read(component, WM8753_CLOCK) & 0xfffb;
1226 snd_soc_component_write(component, WM8753_CLOCK, clock | 0x4);
1227
1228 if (wm8753_hdac_set_dai_fmt(component, fmt) < 0)
1229 return -EINVAL;
1230 return wm8753_vdac_adc_set_dai_fmt(component, fmt);
1231 }
1232
1233 static int wm8753_hifi_write_dai_fmt(struct snd_soc_component *component,
1234 unsigned int fmt)
1235 {
1236 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1237 int ret = 0;
1238
1239 switch (wm8753->dai_func) {
1240 case 0:
1241 ret = wm8753_mode1h_set_dai_fmt(component, fmt);
1242 break;
1243 case 1:
1244 ret = wm8753_mode2_set_dai_fmt(component, fmt);
1245 break;
1246 case 2:
1247 case 3:
1248 ret = wm8753_mode3_4_set_dai_fmt(component, fmt);
1249 break;
1250 default:
1251 break;
1252 }
1253 if (ret)
1254 return ret;
1255
1256 return wm8753_i2s_set_dai_fmt(component, fmt);
1257 }
1258
1259 static int wm8753_hifi_set_dai_fmt(struct snd_soc_dai *codec_dai,
1260 unsigned int fmt)
1261 {
1262 struct snd_soc_component *component = codec_dai->component;
1263 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1264
1265 wm8753->hifi_fmt = fmt;
1266
1267 return wm8753_hifi_write_dai_fmt(component, fmt);
1268 };
1269
1270 static int wm8753_voice_write_dai_fmt(struct snd_soc_component *component,
1271 unsigned int fmt)
1272 {
1273 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1274 int ret = 0;
1275
1276 if (wm8753->dai_func != 0)
1277 return 0;
1278
1279 ret = wm8753_mode1v_set_dai_fmt(component, fmt);
1280 if (ret)
1281 return ret;
1282 ret = wm8753_pcm_set_dai_fmt(component, fmt);
1283 if (ret)
1284 return ret;
1285
1286 return 0;
1287 };
1288
1289 static int wm8753_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1290 unsigned int fmt)
1291 {
1292 struct snd_soc_component *component = codec_dai->component;
1293 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1294
1295 wm8753->voice_fmt = fmt;
1296
1297 return wm8753_voice_write_dai_fmt(component, fmt);
1298 };
1299
1300 static int wm8753_mute(struct snd_soc_dai *dai, int mute, int direction)
1301 {
1302 struct snd_soc_component *component = dai->component;
1303 u16 mute_reg = snd_soc_component_read(component, WM8753_DAC) & 0xfff7;
1304 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1305
1306
1307
1308 if (mute && wm8753->dai_func == 1) {
1309 if (!snd_soc_component_active(component))
1310 snd_soc_component_write(component, WM8753_DAC, mute_reg | 0x8);
1311 } else {
1312 if (mute)
1313 snd_soc_component_write(component, WM8753_DAC, mute_reg | 0x8);
1314 else
1315 snd_soc_component_write(component, WM8753_DAC, mute_reg);
1316 }
1317
1318 return 0;
1319 }
1320
1321 static void wm8753_charge_work(struct work_struct *work)
1322 {
1323 struct wm8753_priv *wm8753 =
1324 container_of(work, struct wm8753_priv, charge_work.work);
1325
1326
1327 regmap_update_bits(wm8753->regmap, WM8753_PWR1, 0x0180, 0x0100);
1328 }
1329
1330 static int wm8753_set_bias_level(struct snd_soc_component *component,
1331 enum snd_soc_bias_level level)
1332 {
1333 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1334 u16 pwr_reg = snd_soc_component_read(component, WM8753_PWR1) & 0xfe3e;
1335
1336 switch (level) {
1337 case SND_SOC_BIAS_ON:
1338
1339 snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x00c0);
1340 break;
1341 case SND_SOC_BIAS_PREPARE:
1342
1343 flush_delayed_work(&wm8753->charge_work);
1344 break;
1345 case SND_SOC_BIAS_STANDBY:
1346 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
1347
1348 snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x01c1);
1349 schedule_delayed_work(&wm8753->charge_work,
1350 msecs_to_jiffies(caps_charge));
1351 } else {
1352
1353 snd_soc_component_write(component, WM8753_PWR1, pwr_reg | 0x0141);
1354 }
1355 break;
1356 case SND_SOC_BIAS_OFF:
1357 cancel_delayed_work_sync(&wm8753->charge_work);
1358 snd_soc_component_write(component, WM8753_PWR1, 0x0001);
1359 break;
1360 }
1361 return 0;
1362 }
1363
1364 #define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1365 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
1366 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
1367 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
1368
1369 #define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1370 SNDRV_PCM_FMTBIT_S24_LE)
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383 static const struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = {
1384 .hw_params = wm8753_i2s_hw_params,
1385 .mute_stream = wm8753_mute,
1386 .set_fmt = wm8753_hifi_set_dai_fmt,
1387 .set_clkdiv = wm8753_set_dai_clkdiv,
1388 .set_pll = wm8753_set_dai_pll,
1389 .set_sysclk = wm8753_set_dai_sysclk,
1390 .no_capture_mute = 1,
1391 };
1392
1393 static const struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = {
1394 .hw_params = wm8753_pcm_hw_params,
1395 .mute_stream = wm8753_mute,
1396 .set_fmt = wm8753_voice_set_dai_fmt,
1397 .set_clkdiv = wm8753_set_dai_clkdiv,
1398 .set_pll = wm8753_set_dai_pll,
1399 .set_sysclk = wm8753_set_dai_sysclk,
1400 .no_capture_mute = 1,
1401 };
1402
1403 static struct snd_soc_dai_driver wm8753_dai[] = {
1404
1405 { .name = "wm8753-hifi",
1406 .playback = {
1407 .stream_name = "HiFi Playback",
1408 .channels_min = 1,
1409 .channels_max = 2,
1410 .rates = WM8753_RATES,
1411 .formats = WM8753_FORMATS
1412 },
1413 .capture = {
1414 .stream_name = "Capture",
1415 .channels_min = 1,
1416 .channels_max = 2,
1417 .rates = WM8753_RATES,
1418 .formats = WM8753_FORMATS
1419 },
1420 .ops = &wm8753_dai_ops_hifi_mode,
1421 },
1422
1423 { .name = "wm8753-voice",
1424 .playback = {
1425 .stream_name = "Voice Playback",
1426 .channels_min = 1,
1427 .channels_max = 1,
1428 .rates = WM8753_RATES,
1429 .formats = WM8753_FORMATS,
1430 },
1431 .capture = {
1432 .stream_name = "Capture",
1433 .channels_min = 1,
1434 .channels_max = 2,
1435 .rates = WM8753_RATES,
1436 .formats = WM8753_FORMATS,
1437 },
1438 .ops = &wm8753_dai_ops_voice_mode,
1439 },
1440 };
1441
1442 static int wm8753_resume(struct snd_soc_component *component)
1443 {
1444 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1445
1446 regcache_sync(wm8753->regmap);
1447
1448 return 0;
1449 }
1450
1451 static int wm8753_probe(struct snd_soc_component *component)
1452 {
1453 struct wm8753_priv *wm8753 = snd_soc_component_get_drvdata(component);
1454 int ret;
1455
1456 INIT_DELAYED_WORK(&wm8753->charge_work, wm8753_charge_work);
1457
1458 ret = wm8753_reset(component);
1459 if (ret < 0) {
1460 dev_err(component->dev, "Failed to issue reset: %d\n", ret);
1461 return ret;
1462 }
1463
1464 wm8753->dai_func = 0;
1465
1466
1467 snd_soc_component_update_bits(component, WM8753_LDAC, 0x0100, 0x0100);
1468 snd_soc_component_update_bits(component, WM8753_RDAC, 0x0100, 0x0100);
1469 snd_soc_component_update_bits(component, WM8753_LADC, 0x0100, 0x0100);
1470 snd_soc_component_update_bits(component, WM8753_RADC, 0x0100, 0x0100);
1471 snd_soc_component_update_bits(component, WM8753_LOUT1V, 0x0100, 0x0100);
1472 snd_soc_component_update_bits(component, WM8753_ROUT1V, 0x0100, 0x0100);
1473 snd_soc_component_update_bits(component, WM8753_LOUT2V, 0x0100, 0x0100);
1474 snd_soc_component_update_bits(component, WM8753_ROUT2V, 0x0100, 0x0100);
1475 snd_soc_component_update_bits(component, WM8753_LINVOL, 0x0100, 0x0100);
1476 snd_soc_component_update_bits(component, WM8753_RINVOL, 0x0100, 0x0100);
1477
1478 return 0;
1479 }
1480
1481 static const struct snd_soc_component_driver soc_component_dev_wm8753 = {
1482 .probe = wm8753_probe,
1483 .resume = wm8753_resume,
1484 .set_bias_level = wm8753_set_bias_level,
1485 .controls = wm8753_snd_controls,
1486 .num_controls = ARRAY_SIZE(wm8753_snd_controls),
1487 .dapm_widgets = wm8753_dapm_widgets,
1488 .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets),
1489 .dapm_routes = wm8753_dapm_routes,
1490 .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes),
1491 .suspend_bias_off = 1,
1492 .idle_bias_on = 1,
1493 .use_pmdown_time = 1,
1494 .endianness = 1,
1495 };
1496
1497 static const struct of_device_id wm8753_of_match[] = {
1498 { .compatible = "wlf,wm8753", },
1499 { }
1500 };
1501 MODULE_DEVICE_TABLE(of, wm8753_of_match);
1502
1503 static const struct regmap_config wm8753_regmap = {
1504 .reg_bits = 7,
1505 .val_bits = 9,
1506
1507 .max_register = WM8753_ADCTL2,
1508 .volatile_reg = wm8753_volatile,
1509
1510 .cache_type = REGCACHE_RBTREE,
1511 .reg_defaults = wm8753_reg_defaults,
1512 .num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults),
1513 };
1514
1515 #if defined(CONFIG_SPI_MASTER)
1516 static int wm8753_spi_probe(struct spi_device *spi)
1517 {
1518 struct wm8753_priv *wm8753;
1519 int ret;
1520
1521 wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv),
1522 GFP_KERNEL);
1523 if (wm8753 == NULL)
1524 return -ENOMEM;
1525
1526 spi_set_drvdata(spi, wm8753);
1527
1528 wm8753->regmap = devm_regmap_init_spi(spi, &wm8753_regmap);
1529 if (IS_ERR(wm8753->regmap)) {
1530 ret = PTR_ERR(wm8753->regmap);
1531 dev_err(&spi->dev, "Failed to allocate register map: %d\n",
1532 ret);
1533 return ret;
1534 }
1535
1536 ret = devm_snd_soc_register_component(&spi->dev, &soc_component_dev_wm8753,
1537 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1538 if (ret != 0)
1539 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret);
1540
1541 return ret;
1542 }
1543
1544 static struct spi_driver wm8753_spi_driver = {
1545 .driver = {
1546 .name = "wm8753",
1547 .of_match_table = wm8753_of_match,
1548 },
1549 .probe = wm8753_spi_probe,
1550 };
1551 #endif
1552
1553 #if IS_ENABLED(CONFIG_I2C)
1554 static int wm8753_i2c_probe(struct i2c_client *i2c)
1555 {
1556 struct wm8753_priv *wm8753;
1557 int ret;
1558
1559 wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv),
1560 GFP_KERNEL);
1561 if (wm8753 == NULL)
1562 return -ENOMEM;
1563
1564 i2c_set_clientdata(i2c, wm8753);
1565
1566 wm8753->regmap = devm_regmap_init_i2c(i2c, &wm8753_regmap);
1567 if (IS_ERR(wm8753->regmap)) {
1568 ret = PTR_ERR(wm8753->regmap);
1569 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1570 ret);
1571 return ret;
1572 }
1573
1574 ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_wm8753,
1575 wm8753_dai, ARRAY_SIZE(wm8753_dai));
1576 if (ret != 0)
1577 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
1578
1579 return ret;
1580 }
1581
1582 static const struct i2c_device_id wm8753_i2c_id[] = {
1583 { "wm8753", 0 },
1584 { }
1585 };
1586 MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1587
1588 static struct i2c_driver wm8753_i2c_driver = {
1589 .driver = {
1590 .name = "wm8753",
1591 .of_match_table = wm8753_of_match,
1592 },
1593 .probe_new = wm8753_i2c_probe,
1594 .id_table = wm8753_i2c_id,
1595 };
1596 #endif
1597
1598 static int __init wm8753_modinit(void)
1599 {
1600 int ret = 0;
1601 #if IS_ENABLED(CONFIG_I2C)
1602 ret = i2c_add_driver(&wm8753_i2c_driver);
1603 if (ret != 0) {
1604 printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
1605 ret);
1606 }
1607 #endif
1608 #if defined(CONFIG_SPI_MASTER)
1609 ret = spi_register_driver(&wm8753_spi_driver);
1610 if (ret != 0) {
1611 printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
1612 ret);
1613 }
1614 #endif
1615 return ret;
1616 }
1617 module_init(wm8753_modinit);
1618
1619 static void __exit wm8753_exit(void)
1620 {
1621 #if IS_ENABLED(CONFIG_I2C)
1622 i2c_del_driver(&wm8753_i2c_driver);
1623 #endif
1624 #if defined(CONFIG_SPI_MASTER)
1625 spi_unregister_driver(&wm8753_spi_driver);
1626 #endif
1627 }
1628 module_exit(wm8753_exit);
1629
1630 MODULE_DESCRIPTION("ASoC WM8753 driver");
1631 MODULE_AUTHOR("Liam Girdwood");
1632 MODULE_LICENSE("GPL");