Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * wm8988.c -- WM8988 ALSA SoC audio driver
0004  *
0005  * Copyright 2009 Wolfson Microelectronics plc
0006  * Copyright 2005 Openedhand Ltd.
0007  *
0008  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/moduleparam.h>
0013 #include <linux/init.h>
0014 #include <linux/delay.h>
0015 #include <linux/pm.h>
0016 #include <linux/i2c.h>
0017 #include <linux/spi/spi.h>
0018 #include <linux/slab.h>
0019 #include <sound/core.h>
0020 #include <sound/pcm.h>
0021 #include <sound/pcm_params.h>
0022 #include <sound/tlv.h>
0023 #include <sound/soc.h>
0024 #include <sound/initval.h>
0025 
0026 #include "wm8988.h"
0027 
0028 /*
0029  * wm8988 register cache
0030  * We can't read the WM8988 register space when we
0031  * are using 2 wire for device control, so we cache them instead.
0032  */
0033 static const struct reg_default wm8988_reg_defaults[] = {
0034     { 0, 0x0097 },
0035     { 1, 0x0097 },
0036     { 2, 0x0079 },
0037     { 3, 0x0079 },
0038     { 5, 0x0008 },
0039     { 7, 0x000a },
0040     { 8, 0x0000 },
0041     { 10, 0x00ff },
0042     { 11, 0x00ff },
0043     { 12, 0x000f },
0044     { 13, 0x000f },
0045     { 16, 0x0000 },
0046     { 17, 0x007b },
0047     { 18, 0x0000 },
0048     { 19, 0x0032 },
0049     { 20, 0x0000 },
0050     { 21, 0x00c3 },
0051     { 22, 0x00c3 },
0052     { 23, 0x00c0 },
0053     { 24, 0x0000 },
0054     { 25, 0x0000 },
0055     { 26, 0x0000 },
0056     { 27, 0x0000 },
0057     { 31, 0x0000 },
0058     { 32, 0x0000 },
0059     { 33, 0x0000 },
0060     { 34, 0x0050 },
0061     { 35, 0x0050 },
0062     { 36, 0x0050 },
0063     { 37, 0x0050 },
0064     { 40, 0x0079 },
0065     { 41, 0x0079 },
0066     { 42, 0x0079 },
0067 };
0068 
0069 static bool wm8988_writeable(struct device *dev, unsigned int reg)
0070 {
0071     switch (reg) {
0072     case WM8988_LINVOL:
0073     case WM8988_RINVOL:
0074     case WM8988_LOUT1V:
0075     case WM8988_ROUT1V:
0076     case WM8988_ADCDAC:
0077     case WM8988_IFACE:
0078     case WM8988_SRATE:
0079     case WM8988_LDAC:
0080     case WM8988_RDAC:
0081     case WM8988_BASS:
0082     case WM8988_TREBLE:
0083     case WM8988_RESET:
0084     case WM8988_3D:
0085     case WM8988_ALC1:
0086     case WM8988_ALC2:
0087     case WM8988_ALC3:
0088     case WM8988_NGATE:
0089     case WM8988_LADC:
0090     case WM8988_RADC:
0091     case WM8988_ADCTL1:
0092     case WM8988_ADCTL2:
0093     case WM8988_PWR1:
0094     case WM8988_PWR2:
0095     case WM8988_ADCTL3:
0096     case WM8988_ADCIN:
0097     case WM8988_LADCIN:
0098     case WM8988_RADCIN:
0099     case WM8988_LOUTM1:
0100     case WM8988_LOUTM2:
0101     case WM8988_ROUTM1:
0102     case WM8988_ROUTM2:
0103     case WM8988_LOUT2V:
0104     case WM8988_ROUT2V:
0105     case WM8988_LPPB:
0106         return true;
0107     default:
0108         return false;
0109     }
0110 }
0111 
0112 /* codec private data */
0113 struct wm8988_priv {
0114     struct regmap *regmap;
0115     unsigned int sysclk;
0116     const struct snd_pcm_hw_constraint_list *sysclk_constraints;
0117 };
0118 
0119 #define wm8988_reset(c) snd_soc_component_write(c, WM8988_RESET, 0)
0120 
0121 /*
0122  * WM8988 Controls
0123  */
0124 
0125 static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"};
0126 static SOC_ENUM_SINGLE_DECL(bass_boost,
0127                 WM8988_BASS, 7, bass_boost_txt);
0128 
0129 static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
0130 static SOC_ENUM_SINGLE_DECL(bass_filter,
0131                 WM8988_BASS, 6, bass_filter_txt);
0132 
0133 static const char *treble_txt[] = {"8kHz", "4kHz"};
0134 static SOC_ENUM_SINGLE_DECL(treble,
0135                 WM8988_TREBLE, 6, treble_txt);
0136 
0137 static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"};
0138 static SOC_ENUM_SINGLE_DECL(stereo_3d_lc,
0139                 WM8988_3D, 5, stereo_3d_lc_txt);
0140 
0141 static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"};
0142 static SOC_ENUM_SINGLE_DECL(stereo_3d_uc,
0143                 WM8988_3D, 6, stereo_3d_uc_txt);
0144 
0145 static const char *stereo_3d_func_txt[] = {"Capture", "Playback"};
0146 static SOC_ENUM_SINGLE_DECL(stereo_3d_func,
0147                 WM8988_3D, 7, stereo_3d_func_txt);
0148 
0149 static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"};
0150 static SOC_ENUM_SINGLE_DECL(alc_func,
0151                 WM8988_ALC1, 7, alc_func_txt);
0152 
0153 static const char *ng_type_txt[] = {"Constant PGA Gain",
0154                     "Mute ADC Output"};
0155 static SOC_ENUM_SINGLE_DECL(ng_type,
0156                 WM8988_NGATE, 1, ng_type_txt);
0157 
0158 static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"};
0159 static SOC_ENUM_SINGLE_DECL(deemph,
0160                 WM8988_ADCDAC, 1, deemph_txt);
0161 
0162 static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert",
0163                    "L + R Invert"};
0164 static SOC_ENUM_SINGLE_DECL(adcpol,
0165                 WM8988_ADCDAC, 5, adcpol_txt);
0166 
0167 static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
0168 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
0169 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
0170 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
0171 static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
0172 
0173 static const struct snd_kcontrol_new wm8988_snd_controls[] = {
0174 
0175 SOC_ENUM("Bass Boost", bass_boost),
0176 SOC_ENUM("Bass Filter", bass_filter),
0177 SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1),
0178 
0179 SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0),
0180 SOC_ENUM("Treble Cut-off", treble),
0181 
0182 SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0),
0183 SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0),
0184 SOC_ENUM("3D Lower Cut-off", stereo_3d_lc),
0185 SOC_ENUM("3D Upper Cut-off", stereo_3d_uc),
0186 SOC_ENUM("3D Mode", stereo_3d_func),
0187 
0188 SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0),
0189 SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0),
0190 SOC_ENUM("ALC Capture Function", alc_func),
0191 SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0),
0192 SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0),
0193 SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0),
0194 SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0),
0195 SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0),
0196 SOC_ENUM("ALC Capture NG Type", ng_type),
0197 SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0),
0198 
0199 SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0),
0200 
0201 SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC,
0202          0, 255, 0, adc_tlv),
0203 SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL,
0204          0, 63, 0, pga_tlv),
0205 SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0),
0206 SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1),
0207 
0208 SOC_ENUM("Playback De-emphasis", deemph),
0209 
0210 SOC_ENUM("Capture Polarity", adcpol),
0211 SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0),
0212 SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0),
0213 
0214 SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv),
0215 
0216 SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1,
0217            bypass_tlv),
0218 SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1,
0219            bypass_tlv),
0220 SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1,
0221            bypass_tlv),
0222 SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1,
0223            bypass_tlv),
0224 
0225 SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V,
0226          WM8988_ROUT1V, 7, 1, 0),
0227 SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V,
0228          0, 127, 0, out_tlv),
0229 
0230 SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V,
0231          WM8988_ROUT2V, 7, 1, 0),
0232 SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
0233          0, 127, 0, out_tlv),
0234 
0235 };
0236 
0237 /*
0238  * DAPM Controls
0239  */
0240 
0241 static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
0242                   struct snd_kcontrol *kcontrol, int event)
0243 {
0244     struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
0245     u16 adctl2 = snd_soc_component_read(component, WM8988_ADCTL2);
0246 
0247     /* Use the DAC to gate LRC if active, otherwise use ADC */
0248     if (snd_soc_component_read(component, WM8988_PWR2) & 0x180)
0249         adctl2 &= ~0x4;
0250     else
0251         adctl2 |= 0x4;
0252 
0253     return snd_soc_component_write(component, WM8988_ADCTL2, adctl2);
0254 }
0255 
0256 static const char *wm8988_line_texts[] = {
0257     "Line 1", "Line 2", "PGA", "Differential"};
0258 
0259 static const unsigned int wm8988_line_values[] = {
0260     0, 1, 3, 4};
0261 
0262 static const struct soc_enum wm8988_lline_enum =
0263     SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7,
0264                   ARRAY_SIZE(wm8988_line_texts),
0265                   wm8988_line_texts,
0266                   wm8988_line_values);
0267 static const struct snd_kcontrol_new wm8988_left_line_controls =
0268     SOC_DAPM_ENUM("Route", wm8988_lline_enum);
0269 
0270 static const struct soc_enum wm8988_rline_enum =
0271     SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7,
0272                   ARRAY_SIZE(wm8988_line_texts),
0273                   wm8988_line_texts,
0274                   wm8988_line_values);
0275 static const struct snd_kcontrol_new wm8988_right_line_controls =
0276     SOC_DAPM_ENUM("Route", wm8988_rline_enum);
0277 
0278 /* Left Mixer */
0279 static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {
0280     SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0),
0281     SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0),
0282     SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0),
0283     SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0),
0284 };
0285 
0286 /* Right Mixer */
0287 static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = {
0288     SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0),
0289     SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0),
0290     SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0),
0291     SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0),
0292 };
0293 
0294 static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"};
0295 static const unsigned int wm8988_pga_val[] = { 0, 1, 3 };
0296 
0297 /* Left PGA Mux */
0298 static const struct soc_enum wm8988_lpga_enum =
0299     SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3,
0300                   ARRAY_SIZE(wm8988_pga_sel),
0301                   wm8988_pga_sel,
0302                   wm8988_pga_val);
0303 static const struct snd_kcontrol_new wm8988_left_pga_controls =
0304     SOC_DAPM_ENUM("Route", wm8988_lpga_enum);
0305 
0306 /* Right PGA Mux */
0307 static const struct soc_enum wm8988_rpga_enum =
0308     SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3,
0309                   ARRAY_SIZE(wm8988_pga_sel),
0310                   wm8988_pga_sel,
0311                   wm8988_pga_val);
0312 static const struct snd_kcontrol_new wm8988_right_pga_controls =
0313     SOC_DAPM_ENUM("Route", wm8988_rpga_enum);
0314 
0315 /* Differential Mux */
0316 static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"};
0317 static SOC_ENUM_SINGLE_DECL(diffmux,
0318                 WM8988_ADCIN, 8, wm8988_diff_sel);
0319 static const struct snd_kcontrol_new wm8988_diffmux_controls =
0320     SOC_DAPM_ENUM("Route", diffmux);
0321 
0322 /* Mono ADC Mux */
0323 static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)",
0324     "Mono (Right)", "Digital Mono"};
0325 static SOC_ENUM_SINGLE_DECL(monomux,
0326                 WM8988_ADCIN, 6, wm8988_mono_mux);
0327 static const struct snd_kcontrol_new wm8988_monomux_controls =
0328     SOC_DAPM_ENUM("Route", monomux);
0329 
0330 static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = {
0331     SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0),
0332 
0333     SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
0334         &wm8988_diffmux_controls),
0335     SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
0336         &wm8988_monomux_controls),
0337     SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
0338         &wm8988_monomux_controls),
0339 
0340     SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0,
0341         &wm8988_left_pga_controls),
0342     SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0,
0343         &wm8988_right_pga_controls),
0344 
0345     SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
0346         &wm8988_left_line_controls),
0347     SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
0348         &wm8988_right_line_controls),
0349 
0350     SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0),
0351     SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0),
0352 
0353     SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0),
0354     SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0),
0355 
0356     SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
0357         &wm8988_left_mixer_controls[0],
0358         ARRAY_SIZE(wm8988_left_mixer_controls)),
0359     SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
0360         &wm8988_right_mixer_controls[0],
0361         ARRAY_SIZE(wm8988_right_mixer_controls)),
0362 
0363     SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0),
0364     SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0),
0365     SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0),
0366     SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0),
0367 
0368     SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control),
0369 
0370     SND_SOC_DAPM_OUTPUT("LOUT1"),
0371     SND_SOC_DAPM_OUTPUT("ROUT1"),
0372     SND_SOC_DAPM_OUTPUT("LOUT2"),
0373     SND_SOC_DAPM_OUTPUT("ROUT2"),
0374     SND_SOC_DAPM_OUTPUT("VREF"),
0375 
0376     SND_SOC_DAPM_INPUT("LINPUT1"),
0377     SND_SOC_DAPM_INPUT("LINPUT2"),
0378     SND_SOC_DAPM_INPUT("RINPUT1"),
0379     SND_SOC_DAPM_INPUT("RINPUT2"),
0380 };
0381 
0382 static const struct snd_soc_dapm_route wm8988_dapm_routes[] = {
0383 
0384     { "Left Line Mux", "Line 1", "LINPUT1" },
0385     { "Left Line Mux", "Line 2", "LINPUT2" },
0386     { "Left Line Mux", "PGA", "Left PGA Mux" },
0387     { "Left Line Mux", "Differential", "Differential Mux" },
0388 
0389     { "Right Line Mux", "Line 1", "RINPUT1" },
0390     { "Right Line Mux", "Line 2", "RINPUT2" },
0391     { "Right Line Mux", "PGA", "Right PGA Mux" },
0392     { "Right Line Mux", "Differential", "Differential Mux" },
0393 
0394     { "Left PGA Mux", "Line 1", "LINPUT1" },
0395     { "Left PGA Mux", "Line 2", "LINPUT2" },
0396     { "Left PGA Mux", "Differential", "Differential Mux" },
0397 
0398     { "Right PGA Mux", "Line 1", "RINPUT1" },
0399     { "Right PGA Mux", "Line 2", "RINPUT2" },
0400     { "Right PGA Mux", "Differential", "Differential Mux" },
0401 
0402     { "Differential Mux", "Line 1", "LINPUT1" },
0403     { "Differential Mux", "Line 1", "RINPUT1" },
0404     { "Differential Mux", "Line 2", "LINPUT2" },
0405     { "Differential Mux", "Line 2", "RINPUT2" },
0406 
0407     { "Left ADC Mux", "Stereo", "Left PGA Mux" },
0408     { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" },
0409     { "Left ADC Mux", "Digital Mono", "Left PGA Mux" },
0410 
0411     { "Right ADC Mux", "Stereo", "Right PGA Mux" },
0412     { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" },
0413     { "Right ADC Mux", "Digital Mono", "Right PGA Mux" },
0414 
0415     { "Left ADC", NULL, "Left ADC Mux" },
0416     { "Right ADC", NULL, "Right ADC Mux" },
0417 
0418     { "Left Line Mux", "Line 1", "LINPUT1" },
0419     { "Left Line Mux", "Line 2", "LINPUT2" },
0420     { "Left Line Mux", "PGA", "Left PGA Mux" },
0421     { "Left Line Mux", "Differential", "Differential Mux" },
0422 
0423     { "Right Line Mux", "Line 1", "RINPUT1" },
0424     { "Right Line Mux", "Line 2", "RINPUT2" },
0425     { "Right Line Mux", "PGA", "Right PGA Mux" },
0426     { "Right Line Mux", "Differential", "Differential Mux" },
0427 
0428     { "Left Mixer", "Playback Switch", "Left DAC" },
0429     { "Left Mixer", "Left Bypass Switch", "Left Line Mux" },
0430     { "Left Mixer", "Right Playback Switch", "Right DAC" },
0431     { "Left Mixer", "Right Bypass Switch", "Right Line Mux" },
0432 
0433     { "Right Mixer", "Left Playback Switch", "Left DAC" },
0434     { "Right Mixer", "Left Bypass Switch", "Left Line Mux" },
0435     { "Right Mixer", "Playback Switch", "Right DAC" },
0436     { "Right Mixer", "Right Bypass Switch", "Right Line Mux" },
0437 
0438     { "Left Out 1", NULL, "Left Mixer" },
0439     { "LOUT1", NULL, "Left Out 1" },
0440     { "Right Out 1", NULL, "Right Mixer" },
0441     { "ROUT1", NULL, "Right Out 1" },
0442 
0443     { "Left Out 2", NULL, "Left Mixer" },
0444     { "LOUT2", NULL, "Left Out 2" },
0445     { "Right Out 2", NULL, "Right Mixer" },
0446     { "ROUT2", NULL, "Right Out 2" },
0447 };
0448 
0449 struct _coeff_div {
0450     u32 mclk;
0451     u32 rate;
0452     u16 fs;
0453     u8 sr:5;
0454     u8 usb:1;
0455 };
0456 
0457 /* codec hifi mclk clock divider coefficients */
0458 static const struct _coeff_div coeff_div[] = {
0459     /* 8k */
0460     {12288000, 8000, 1536, 0x6, 0x0},
0461     {11289600, 8000, 1408, 0x16, 0x0},
0462     {18432000, 8000, 2304, 0x7, 0x0},
0463     {16934400, 8000, 2112, 0x17, 0x0},
0464     {12000000, 8000, 1500, 0x6, 0x1},
0465 
0466     /* 11.025k */
0467     {11289600, 11025, 1024, 0x18, 0x0},
0468     {16934400, 11025, 1536, 0x19, 0x0},
0469     {12000000, 11025, 1088, 0x19, 0x1},
0470 
0471     /* 16k */
0472     {12288000, 16000, 768, 0xa, 0x0},
0473     {18432000, 16000, 1152, 0xb, 0x0},
0474     {12000000, 16000, 750, 0xa, 0x1},
0475 
0476     /* 22.05k */
0477     {11289600, 22050, 512, 0x1a, 0x0},
0478     {16934400, 22050, 768, 0x1b, 0x0},
0479     {12000000, 22050, 544, 0x1b, 0x1},
0480 
0481     /* 32k */
0482     {12288000, 32000, 384, 0xc, 0x0},
0483     {18432000, 32000, 576, 0xd, 0x0},
0484     {12000000, 32000, 375, 0xa, 0x1},
0485 
0486     /* 44.1k */
0487     {11289600, 44100, 256, 0x10, 0x0},
0488     {16934400, 44100, 384, 0x11, 0x0},
0489     {12000000, 44100, 272, 0x11, 0x1},
0490 
0491     /* 48k */
0492     {12288000, 48000, 256, 0x0, 0x0},
0493     {18432000, 48000, 384, 0x1, 0x0},
0494     {12000000, 48000, 250, 0x0, 0x1},
0495 
0496     /* 88.2k */
0497     {11289600, 88200, 128, 0x1e, 0x0},
0498     {16934400, 88200, 192, 0x1f, 0x0},
0499     {12000000, 88200, 136, 0x1f, 0x1},
0500 
0501     /* 96k */
0502     {12288000, 96000, 128, 0xe, 0x0},
0503     {18432000, 96000, 192, 0xf, 0x0},
0504     {12000000, 96000, 125, 0xe, 0x1},
0505 };
0506 
0507 static inline int get_coeff(int mclk, int rate)
0508 {
0509     int i;
0510 
0511     for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
0512         if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
0513             return i;
0514     }
0515 
0516     return -EINVAL;
0517 }
0518 
0519 /* The set of rates we can generate from the above for each SYSCLK */
0520 
0521 static const unsigned int rates_12288[] = {
0522     8000, 12000, 16000, 24000, 32000, 48000, 96000,
0523 };
0524 
0525 static const struct snd_pcm_hw_constraint_list constraints_12288 = {
0526     .count  = ARRAY_SIZE(rates_12288),
0527     .list   = rates_12288,
0528 };
0529 
0530 static const unsigned int rates_112896[] = {
0531     8000, 11025, 22050, 44100,
0532 };
0533 
0534 static const struct snd_pcm_hw_constraint_list constraints_112896 = {
0535     .count  = ARRAY_SIZE(rates_112896),
0536     .list   = rates_112896,
0537 };
0538 
0539 static const unsigned int rates_12[] = {
0540     8000, 11025, 12000, 16000, 22050, 24000, 32000, 41100, 48000,
0541     48000, 88235, 96000,
0542 };
0543 
0544 static const struct snd_pcm_hw_constraint_list constraints_12 = {
0545     .count  = ARRAY_SIZE(rates_12),
0546     .list   = rates_12,
0547 };
0548 
0549 /*
0550  * Note that this should be called from init rather than from hw_params.
0551  */
0552 static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai,
0553         int clk_id, unsigned int freq, int dir)
0554 {
0555     struct snd_soc_component *component = codec_dai->component;
0556     struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
0557 
0558     switch (freq) {
0559     case 11289600:
0560     case 18432000:
0561     case 22579200:
0562     case 36864000:
0563         wm8988->sysclk_constraints = &constraints_112896;
0564         wm8988->sysclk = freq;
0565         return 0;
0566 
0567     case 12288000:
0568     case 16934400:
0569     case 24576000:
0570     case 33868800:
0571         wm8988->sysclk_constraints = &constraints_12288;
0572         wm8988->sysclk = freq;
0573         return 0;
0574 
0575     case 12000000:
0576     case 24000000:
0577         wm8988->sysclk_constraints = &constraints_12;
0578         wm8988->sysclk = freq;
0579         return 0;
0580     }
0581     return -EINVAL;
0582 }
0583 
0584 static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
0585         unsigned int fmt)
0586 {
0587     struct snd_soc_component *component = codec_dai->component;
0588     u16 iface = 0;
0589 
0590     /* set master/slave audio interface */
0591     switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
0592     case SND_SOC_DAIFMT_CBM_CFM:
0593         iface = 0x0040;
0594         break;
0595     case SND_SOC_DAIFMT_CBS_CFS:
0596         break;
0597     default:
0598         return -EINVAL;
0599     }
0600 
0601     /* interface format */
0602     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0603     case SND_SOC_DAIFMT_I2S:
0604         iface |= 0x0002;
0605         break;
0606     case SND_SOC_DAIFMT_RIGHT_J:
0607         break;
0608     case SND_SOC_DAIFMT_LEFT_J:
0609         iface |= 0x0001;
0610         break;
0611     case SND_SOC_DAIFMT_DSP_A:
0612         iface |= 0x0003;
0613         break;
0614     case SND_SOC_DAIFMT_DSP_B:
0615         iface |= 0x0013;
0616         break;
0617     default:
0618         return -EINVAL;
0619     }
0620 
0621     /* clock inversion */
0622     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0623     case SND_SOC_DAIFMT_NB_NF:
0624         break;
0625     case SND_SOC_DAIFMT_IB_IF:
0626         iface |= 0x0090;
0627         break;
0628     case SND_SOC_DAIFMT_IB_NF:
0629         iface |= 0x0080;
0630         break;
0631     case SND_SOC_DAIFMT_NB_IF:
0632         iface |= 0x0010;
0633         break;
0634     default:
0635         return -EINVAL;
0636     }
0637 
0638     snd_soc_component_write(component, WM8988_IFACE, iface);
0639     return 0;
0640 }
0641 
0642 static int wm8988_pcm_startup(struct snd_pcm_substream *substream,
0643                   struct snd_soc_dai *dai)
0644 {
0645     struct snd_soc_component *component = dai->component;
0646     struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
0647 
0648     /* The set of sample rates that can be supported depends on the
0649      * MCLK supplied to the CODEC - enforce this.
0650      */
0651     if (!wm8988->sysclk) {
0652         dev_err(component->dev,
0653             "No MCLK configured, call set_sysclk() on init\n");
0654         return -EINVAL;
0655     }
0656 
0657     snd_pcm_hw_constraint_list(substream->runtime, 0,
0658                    SNDRV_PCM_HW_PARAM_RATE,
0659                    wm8988->sysclk_constraints);
0660 
0661     return 0;
0662 }
0663 
0664 static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
0665                 struct snd_pcm_hw_params *params,
0666                 struct snd_soc_dai *dai)
0667 {
0668     struct snd_soc_component *component = dai->component;
0669     struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
0670     u16 iface = snd_soc_component_read(component, WM8988_IFACE) & 0x1f3;
0671     u16 srate = snd_soc_component_read(component, WM8988_SRATE) & 0x180;
0672     int coeff;
0673 
0674     coeff = get_coeff(wm8988->sysclk, params_rate(params));
0675     if (coeff < 0) {
0676         coeff = get_coeff(wm8988->sysclk / 2, params_rate(params));
0677         srate |= 0x40;
0678     }
0679     if (coeff < 0) {
0680         dev_err(component->dev,
0681             "Unable to configure sample rate %dHz with %dHz MCLK\n",
0682             params_rate(params), wm8988->sysclk);
0683         return coeff;
0684     }
0685 
0686     /* bit size */
0687     switch (params_width(params)) {
0688     case 16:
0689         break;
0690     case 20:
0691         iface |= 0x0004;
0692         break;
0693     case 24:
0694         iface |= 0x0008;
0695         break;
0696     case 32:
0697         iface |= 0x000c;
0698         break;
0699     }
0700 
0701     /* set iface & srate */
0702     snd_soc_component_write(component, WM8988_IFACE, iface);
0703     if (coeff >= 0)
0704         snd_soc_component_write(component, WM8988_SRATE, srate |
0705             (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
0706 
0707     return 0;
0708 }
0709 
0710 static int wm8988_mute(struct snd_soc_dai *dai, int mute, int direction)
0711 {
0712     struct snd_soc_component *component = dai->component;
0713     u16 mute_reg = snd_soc_component_read(component, WM8988_ADCDAC) & 0xfff7;
0714 
0715     if (mute)
0716         snd_soc_component_write(component, WM8988_ADCDAC, mute_reg | 0x8);
0717     else
0718         snd_soc_component_write(component, WM8988_ADCDAC, mute_reg);
0719     return 0;
0720 }
0721 
0722 static int wm8988_set_bias_level(struct snd_soc_component *component,
0723                  enum snd_soc_bias_level level)
0724 {
0725     struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component);
0726     u16 pwr_reg = snd_soc_component_read(component, WM8988_PWR1) & ~0x1c1;
0727 
0728     switch (level) {
0729     case SND_SOC_BIAS_ON:
0730         break;
0731 
0732     case SND_SOC_BIAS_PREPARE:
0733         /* VREF, VMID=2x50k, digital enabled */
0734         snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x00c0);
0735         break;
0736 
0737     case SND_SOC_BIAS_STANDBY:
0738         if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
0739             regcache_sync(wm8988->regmap);
0740 
0741             /* VREF, VMID=2x5k */
0742             snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x1c1);
0743 
0744             /* Charge caps */
0745             msleep(100);
0746         }
0747 
0748         /* VREF, VMID=2*500k, digital stopped */
0749         snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x0141);
0750         break;
0751 
0752     case SND_SOC_BIAS_OFF:
0753         snd_soc_component_write(component, WM8988_PWR1, 0x0000);
0754         break;
0755     }
0756     return 0;
0757 }
0758 
0759 #define WM8988_RATES SNDRV_PCM_RATE_8000_96000
0760 
0761 #define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0762     SNDRV_PCM_FMTBIT_S24_LE)
0763 
0764 static const struct snd_soc_dai_ops wm8988_ops = {
0765     .startup = wm8988_pcm_startup,
0766     .hw_params = wm8988_pcm_hw_params,
0767     .set_fmt = wm8988_set_dai_fmt,
0768     .set_sysclk = wm8988_set_dai_sysclk,
0769     .mute_stream = wm8988_mute,
0770     .no_capture_mute = 1,
0771 };
0772 
0773 static struct snd_soc_dai_driver wm8988_dai = {
0774     .name = "wm8988-hifi",
0775     .playback = {
0776         .stream_name = "Playback",
0777         .channels_min = 1,
0778         .channels_max = 2,
0779         .rates = WM8988_RATES,
0780         .formats = WM8988_FORMATS,
0781     },
0782     .capture = {
0783         .stream_name = "Capture",
0784         .channels_min = 1,
0785         .channels_max = 2,
0786         .rates = WM8988_RATES,
0787         .formats = WM8988_FORMATS,
0788      },
0789     .ops = &wm8988_ops,
0790     .symmetric_rate = 1,
0791 };
0792 
0793 static int wm8988_probe(struct snd_soc_component *component)
0794 {
0795     int ret = 0;
0796 
0797     ret = wm8988_reset(component);
0798     if (ret < 0) {
0799         dev_err(component->dev, "Failed to issue reset\n");
0800         return ret;
0801     }
0802 
0803     /* set the update bits (we always update left then right) */
0804     snd_soc_component_update_bits(component, WM8988_RADC, 0x0100, 0x0100);
0805     snd_soc_component_update_bits(component, WM8988_RDAC, 0x0100, 0x0100);
0806     snd_soc_component_update_bits(component, WM8988_ROUT1V, 0x0100, 0x0100);
0807     snd_soc_component_update_bits(component, WM8988_ROUT2V, 0x0100, 0x0100);
0808     snd_soc_component_update_bits(component, WM8988_RINVOL, 0x0100, 0x0100);
0809 
0810     return 0;
0811 }
0812 
0813 static const struct snd_soc_component_driver soc_component_dev_wm8988 = {
0814     .probe          = wm8988_probe,
0815     .set_bias_level     = wm8988_set_bias_level,
0816     .controls       = wm8988_snd_controls,
0817     .num_controls       = ARRAY_SIZE(wm8988_snd_controls),
0818     .dapm_widgets       = wm8988_dapm_widgets,
0819     .num_dapm_widgets   = ARRAY_SIZE(wm8988_dapm_widgets),
0820     .dapm_routes        = wm8988_dapm_routes,
0821     .num_dapm_routes    = ARRAY_SIZE(wm8988_dapm_routes),
0822     .suspend_bias_off   = 1,
0823     .idle_bias_on       = 1,
0824     .use_pmdown_time    = 1,
0825     .endianness     = 1,
0826 };
0827 
0828 static const struct regmap_config wm8988_regmap = {
0829     .reg_bits = 7,
0830     .val_bits = 9,
0831 
0832     .max_register = WM8988_LPPB,
0833     .writeable_reg = wm8988_writeable,
0834 
0835     .cache_type = REGCACHE_RBTREE,
0836     .reg_defaults = wm8988_reg_defaults,
0837     .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults),
0838 };
0839 
0840 #if defined(CONFIG_SPI_MASTER)
0841 static int wm8988_spi_probe(struct spi_device *spi)
0842 {
0843     struct wm8988_priv *wm8988;
0844     int ret;
0845 
0846     wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv),
0847                   GFP_KERNEL);
0848     if (wm8988 == NULL)
0849         return -ENOMEM;
0850 
0851     wm8988->regmap = devm_regmap_init_spi(spi, &wm8988_regmap);
0852     if (IS_ERR(wm8988->regmap)) {
0853         ret = PTR_ERR(wm8988->regmap);
0854         dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
0855         return ret;
0856     }
0857 
0858     spi_set_drvdata(spi, wm8988);
0859 
0860     ret = devm_snd_soc_register_component(&spi->dev,
0861             &soc_component_dev_wm8988, &wm8988_dai, 1);
0862     return ret;
0863 }
0864 
0865 static struct spi_driver wm8988_spi_driver = {
0866     .driver = {
0867         .name   = "wm8988",
0868     },
0869     .probe      = wm8988_spi_probe,
0870 };
0871 #endif /* CONFIG_SPI_MASTER */
0872 
0873 #if IS_ENABLED(CONFIG_I2C)
0874 static int wm8988_i2c_probe(struct i2c_client *i2c)
0875 {
0876     struct wm8988_priv *wm8988;
0877     int ret;
0878 
0879     wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv),
0880                   GFP_KERNEL);
0881     if (wm8988 == NULL)
0882         return -ENOMEM;
0883 
0884     i2c_set_clientdata(i2c, wm8988);
0885 
0886     wm8988->regmap = devm_regmap_init_i2c(i2c, &wm8988_regmap);
0887     if (IS_ERR(wm8988->regmap)) {
0888         ret = PTR_ERR(wm8988->regmap);
0889         dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
0890         return ret;
0891     }
0892 
0893     ret = devm_snd_soc_register_component(&i2c->dev,
0894             &soc_component_dev_wm8988, &wm8988_dai, 1);
0895     return ret;
0896 }
0897 
0898 static const struct i2c_device_id wm8988_i2c_id[] = {
0899     { "wm8988", 0 },
0900     { }
0901 };
0902 MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id);
0903 
0904 static struct i2c_driver wm8988_i2c_driver = {
0905     .driver = {
0906         .name = "wm8988",
0907     },
0908     .probe_new = wm8988_i2c_probe,
0909     .id_table = wm8988_i2c_id,
0910 };
0911 #endif
0912 
0913 static int __init wm8988_modinit(void)
0914 {
0915     int ret = 0;
0916 #if IS_ENABLED(CONFIG_I2C)
0917     ret = i2c_add_driver(&wm8988_i2c_driver);
0918     if (ret != 0) {
0919         printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n",
0920                ret);
0921     }
0922 #endif
0923 #if defined(CONFIG_SPI_MASTER)
0924     ret = spi_register_driver(&wm8988_spi_driver);
0925     if (ret != 0) {
0926         printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n",
0927                ret);
0928     }
0929 #endif
0930     return ret;
0931 }
0932 module_init(wm8988_modinit);
0933 
0934 static void __exit wm8988_exit(void)
0935 {
0936 #if IS_ENABLED(CONFIG_I2C)
0937     i2c_del_driver(&wm8988_i2c_driver);
0938 #endif
0939 #if defined(CONFIG_SPI_MASTER)
0940     spi_unregister_driver(&wm8988_spi_driver);
0941 #endif
0942 }
0943 module_exit(wm8988_exit);
0944 
0945 
0946 MODULE_DESCRIPTION("ASoC WM8988 driver");
0947 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0948 MODULE_LICENSE("GPL");