wm8988.c (26312B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * wm8988.c -- WM8988 ALSA SoC audio driver 4 * 5 * Copyright 2009 Wolfson Microelectronics plc 6 * Copyright 2005 Openedhand Ltd. 7 * 8 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 9 */ 10 11#include <linux/module.h> 12#include <linux/moduleparam.h> 13#include <linux/init.h> 14#include <linux/delay.h> 15#include <linux/pm.h> 16#include <linux/i2c.h> 17#include <linux/spi/spi.h> 18#include <linux/slab.h> 19#include <sound/core.h> 20#include <sound/pcm.h> 21#include <sound/pcm_params.h> 22#include <sound/tlv.h> 23#include <sound/soc.h> 24#include <sound/initval.h> 25 26#include "wm8988.h" 27 28/* 29 * wm8988 register cache 30 * We can't read the WM8988 register space when we 31 * are using 2 wire for device control, so we cache them instead. 32 */ 33static const struct reg_default wm8988_reg_defaults[] = { 34 { 0, 0x0097 }, 35 { 1, 0x0097 }, 36 { 2, 0x0079 }, 37 { 3, 0x0079 }, 38 { 5, 0x0008 }, 39 { 7, 0x000a }, 40 { 8, 0x0000 }, 41 { 10, 0x00ff }, 42 { 11, 0x00ff }, 43 { 12, 0x000f }, 44 { 13, 0x000f }, 45 { 16, 0x0000 }, 46 { 17, 0x007b }, 47 { 18, 0x0000 }, 48 { 19, 0x0032 }, 49 { 20, 0x0000 }, 50 { 21, 0x00c3 }, 51 { 22, 0x00c3 }, 52 { 23, 0x00c0 }, 53 { 24, 0x0000 }, 54 { 25, 0x0000 }, 55 { 26, 0x0000 }, 56 { 27, 0x0000 }, 57 { 31, 0x0000 }, 58 { 32, 0x0000 }, 59 { 33, 0x0000 }, 60 { 34, 0x0050 }, 61 { 35, 0x0050 }, 62 { 36, 0x0050 }, 63 { 37, 0x0050 }, 64 { 40, 0x0079 }, 65 { 41, 0x0079 }, 66 { 42, 0x0079 }, 67}; 68 69static bool wm8988_writeable(struct device *dev, unsigned int reg) 70{ 71 switch (reg) { 72 case WM8988_LINVOL: 73 case WM8988_RINVOL: 74 case WM8988_LOUT1V: 75 case WM8988_ROUT1V: 76 case WM8988_ADCDAC: 77 case WM8988_IFACE: 78 case WM8988_SRATE: 79 case WM8988_LDAC: 80 case WM8988_RDAC: 81 case WM8988_BASS: 82 case WM8988_TREBLE: 83 case WM8988_RESET: 84 case WM8988_3D: 85 case WM8988_ALC1: 86 case WM8988_ALC2: 87 case WM8988_ALC3: 88 case WM8988_NGATE: 89 case WM8988_LADC: 90 case WM8988_RADC: 91 case WM8988_ADCTL1: 92 case WM8988_ADCTL2: 93 case WM8988_PWR1: 94 case WM8988_PWR2: 95 case WM8988_ADCTL3: 96 case WM8988_ADCIN: 97 case WM8988_LADCIN: 98 case WM8988_RADCIN: 99 case WM8988_LOUTM1: 100 case WM8988_LOUTM2: 101 case WM8988_ROUTM1: 102 case WM8988_ROUTM2: 103 case WM8988_LOUT2V: 104 case WM8988_ROUT2V: 105 case WM8988_LPPB: 106 return true; 107 default: 108 return false; 109 } 110} 111 112/* codec private data */ 113struct wm8988_priv { 114 struct regmap *regmap; 115 unsigned int sysclk; 116 const struct snd_pcm_hw_constraint_list *sysclk_constraints; 117}; 118 119#define wm8988_reset(c) snd_soc_component_write(c, WM8988_RESET, 0) 120 121/* 122 * WM8988 Controls 123 */ 124 125static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"}; 126static SOC_ENUM_SINGLE_DECL(bass_boost, 127 WM8988_BASS, 7, bass_boost_txt); 128 129static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; 130static SOC_ENUM_SINGLE_DECL(bass_filter, 131 WM8988_BASS, 6, bass_filter_txt); 132 133static const char *treble_txt[] = {"8kHz", "4kHz"}; 134static SOC_ENUM_SINGLE_DECL(treble, 135 WM8988_TREBLE, 6, treble_txt); 136 137static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"}; 138static SOC_ENUM_SINGLE_DECL(stereo_3d_lc, 139 WM8988_3D, 5, stereo_3d_lc_txt); 140 141static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"}; 142static SOC_ENUM_SINGLE_DECL(stereo_3d_uc, 143 WM8988_3D, 6, stereo_3d_uc_txt); 144 145static const char *stereo_3d_func_txt[] = {"Capture", "Playback"}; 146static SOC_ENUM_SINGLE_DECL(stereo_3d_func, 147 WM8988_3D, 7, stereo_3d_func_txt); 148 149static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"}; 150static SOC_ENUM_SINGLE_DECL(alc_func, 151 WM8988_ALC1, 7, alc_func_txt); 152 153static const char *ng_type_txt[] = {"Constant PGA Gain", 154 "Mute ADC Output"}; 155static SOC_ENUM_SINGLE_DECL(ng_type, 156 WM8988_NGATE, 1, ng_type_txt); 157 158static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 159static SOC_ENUM_SINGLE_DECL(deemph, 160 WM8988_ADCDAC, 1, deemph_txt); 161 162static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert", 163 "L + R Invert"}; 164static SOC_ENUM_SINGLE_DECL(adcpol, 165 WM8988_ADCDAC, 5, adcpol_txt); 166 167static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0); 168static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1); 169static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); 170static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 171static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); 172 173static const struct snd_kcontrol_new wm8988_snd_controls[] = { 174 175SOC_ENUM("Bass Boost", bass_boost), 176SOC_ENUM("Bass Filter", bass_filter), 177SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1), 178 179SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0), 180SOC_ENUM("Treble Cut-off", treble), 181 182SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0), 183SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0), 184SOC_ENUM("3D Lower Cut-off", stereo_3d_lc), 185SOC_ENUM("3D Upper Cut-off", stereo_3d_uc), 186SOC_ENUM("3D Mode", stereo_3d_func), 187 188SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0), 189SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0), 190SOC_ENUM("ALC Capture Function", alc_func), 191SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0), 192SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0), 193SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0), 194SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0), 195SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0), 196SOC_ENUM("ALC Capture NG Type", ng_type), 197SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0), 198 199SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0), 200 201SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC, 202 0, 255, 0, adc_tlv), 203SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL, 204 0, 63, 0, pga_tlv), 205SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0), 206SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1), 207 208SOC_ENUM("Playback De-emphasis", deemph), 209 210SOC_ENUM("Capture Polarity", adcpol), 211SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0), 212SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0), 213 214SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv), 215 216SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1, 217 bypass_tlv), 218SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1, 219 bypass_tlv), 220SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1, 221 bypass_tlv), 222SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1, 223 bypass_tlv), 224 225SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V, 226 WM8988_ROUT1V, 7, 1, 0), 227SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V, 228 0, 127, 0, out_tlv), 229 230SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V, 231 WM8988_ROUT2V, 7, 1, 0), 232SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V, 233 0, 127, 0, out_tlv), 234 235}; 236 237/* 238 * DAPM Controls 239 */ 240 241static int wm8988_lrc_control(struct snd_soc_dapm_widget *w, 242 struct snd_kcontrol *kcontrol, int event) 243{ 244 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 245 u16 adctl2 = snd_soc_component_read(component, WM8988_ADCTL2); 246 247 /* Use the DAC to gate LRC if active, otherwise use ADC */ 248 if (snd_soc_component_read(component, WM8988_PWR2) & 0x180) 249 adctl2 &= ~0x4; 250 else 251 adctl2 |= 0x4; 252 253 return snd_soc_component_write(component, WM8988_ADCTL2, adctl2); 254} 255 256static const char *wm8988_line_texts[] = { 257 "Line 1", "Line 2", "PGA", "Differential"}; 258 259static const unsigned int wm8988_line_values[] = { 260 0, 1, 3, 4}; 261 262static const struct soc_enum wm8988_lline_enum = 263 SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7, 264 ARRAY_SIZE(wm8988_line_texts), 265 wm8988_line_texts, 266 wm8988_line_values); 267static const struct snd_kcontrol_new wm8988_left_line_controls = 268 SOC_DAPM_ENUM("Route", wm8988_lline_enum); 269 270static const struct soc_enum wm8988_rline_enum = 271 SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, 272 ARRAY_SIZE(wm8988_line_texts), 273 wm8988_line_texts, 274 wm8988_line_values); 275static const struct snd_kcontrol_new wm8988_right_line_controls = 276 SOC_DAPM_ENUM("Route", wm8988_rline_enum); 277 278/* Left Mixer */ 279static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { 280 SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0), 281 SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0), 282 SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0), 283 SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0), 284}; 285 286/* Right Mixer */ 287static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = { 288 SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0), 289 SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0), 290 SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0), 291 SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0), 292}; 293 294static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"}; 295static const unsigned int wm8988_pga_val[] = { 0, 1, 3 }; 296 297/* Left PGA Mux */ 298static const struct soc_enum wm8988_lpga_enum = 299 SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3, 300 ARRAY_SIZE(wm8988_pga_sel), 301 wm8988_pga_sel, 302 wm8988_pga_val); 303static const struct snd_kcontrol_new wm8988_left_pga_controls = 304 SOC_DAPM_ENUM("Route", wm8988_lpga_enum); 305 306/* Right PGA Mux */ 307static const struct soc_enum wm8988_rpga_enum = 308 SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3, 309 ARRAY_SIZE(wm8988_pga_sel), 310 wm8988_pga_sel, 311 wm8988_pga_val); 312static const struct snd_kcontrol_new wm8988_right_pga_controls = 313 SOC_DAPM_ENUM("Route", wm8988_rpga_enum); 314 315/* Differential Mux */ 316static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; 317static SOC_ENUM_SINGLE_DECL(diffmux, 318 WM8988_ADCIN, 8, wm8988_diff_sel); 319static const struct snd_kcontrol_new wm8988_diffmux_controls = 320 SOC_DAPM_ENUM("Route", diffmux); 321 322/* Mono ADC Mux */ 323static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)", 324 "Mono (Right)", "Digital Mono"}; 325static SOC_ENUM_SINGLE_DECL(monomux, 326 WM8988_ADCIN, 6, wm8988_mono_mux); 327static const struct snd_kcontrol_new wm8988_monomux_controls = 328 SOC_DAPM_ENUM("Route", monomux); 329 330static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = { 331 SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0), 332 333 SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, 334 &wm8988_diffmux_controls), 335 SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, 336 &wm8988_monomux_controls), 337 SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, 338 &wm8988_monomux_controls), 339 340 SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0, 341 &wm8988_left_pga_controls), 342 SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0, 343 &wm8988_right_pga_controls), 344 345 SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, 346 &wm8988_left_line_controls), 347 SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, 348 &wm8988_right_line_controls), 349 350 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0), 351 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0), 352 353 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0), 354 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0), 355 356 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 357 &wm8988_left_mixer_controls[0], 358 ARRAY_SIZE(wm8988_left_mixer_controls)), 359 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, 360 &wm8988_right_mixer_controls[0], 361 ARRAY_SIZE(wm8988_right_mixer_controls)), 362 363 SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0), 364 SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0), 365 SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0), 366 SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0), 367 368 SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control), 369 370 SND_SOC_DAPM_OUTPUT("LOUT1"), 371 SND_SOC_DAPM_OUTPUT("ROUT1"), 372 SND_SOC_DAPM_OUTPUT("LOUT2"), 373 SND_SOC_DAPM_OUTPUT("ROUT2"), 374 SND_SOC_DAPM_OUTPUT("VREF"), 375 376 SND_SOC_DAPM_INPUT("LINPUT1"), 377 SND_SOC_DAPM_INPUT("LINPUT2"), 378 SND_SOC_DAPM_INPUT("RINPUT1"), 379 SND_SOC_DAPM_INPUT("RINPUT2"), 380}; 381 382static const struct snd_soc_dapm_route wm8988_dapm_routes[] = { 383 384 { "Left Line Mux", "Line 1", "LINPUT1" }, 385 { "Left Line Mux", "Line 2", "LINPUT2" }, 386 { "Left Line Mux", "PGA", "Left PGA Mux" }, 387 { "Left Line Mux", "Differential", "Differential Mux" }, 388 389 { "Right Line Mux", "Line 1", "RINPUT1" }, 390 { "Right Line Mux", "Line 2", "RINPUT2" }, 391 { "Right Line Mux", "PGA", "Right PGA Mux" }, 392 { "Right Line Mux", "Differential", "Differential Mux" }, 393 394 { "Left PGA Mux", "Line 1", "LINPUT1" }, 395 { "Left PGA Mux", "Line 2", "LINPUT2" }, 396 { "Left PGA Mux", "Differential", "Differential Mux" }, 397 398 { "Right PGA Mux", "Line 1", "RINPUT1" }, 399 { "Right PGA Mux", "Line 2", "RINPUT2" }, 400 { "Right PGA Mux", "Differential", "Differential Mux" }, 401 402 { "Differential Mux", "Line 1", "LINPUT1" }, 403 { "Differential Mux", "Line 1", "RINPUT1" }, 404 { "Differential Mux", "Line 2", "LINPUT2" }, 405 { "Differential Mux", "Line 2", "RINPUT2" }, 406 407 { "Left ADC Mux", "Stereo", "Left PGA Mux" }, 408 { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, 409 { "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, 410 411 { "Right ADC Mux", "Stereo", "Right PGA Mux" }, 412 { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, 413 { "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, 414 415 { "Left ADC", NULL, "Left ADC Mux" }, 416 { "Right ADC", NULL, "Right ADC Mux" }, 417 418 { "Left Line Mux", "Line 1", "LINPUT1" }, 419 { "Left Line Mux", "Line 2", "LINPUT2" }, 420 { "Left Line Mux", "PGA", "Left PGA Mux" }, 421 { "Left Line Mux", "Differential", "Differential Mux" }, 422 423 { "Right Line Mux", "Line 1", "RINPUT1" }, 424 { "Right Line Mux", "Line 2", "RINPUT2" }, 425 { "Right Line Mux", "PGA", "Right PGA Mux" }, 426 { "Right Line Mux", "Differential", "Differential Mux" }, 427 428 { "Left Mixer", "Playback Switch", "Left DAC" }, 429 { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, 430 { "Left Mixer", "Right Playback Switch", "Right DAC" }, 431 { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, 432 433 { "Right Mixer", "Left Playback Switch", "Left DAC" }, 434 { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, 435 { "Right Mixer", "Playback Switch", "Right DAC" }, 436 { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, 437 438 { "Left Out 1", NULL, "Left Mixer" }, 439 { "LOUT1", NULL, "Left Out 1" }, 440 { "Right Out 1", NULL, "Right Mixer" }, 441 { "ROUT1", NULL, "Right Out 1" }, 442 443 { "Left Out 2", NULL, "Left Mixer" }, 444 { "LOUT2", NULL, "Left Out 2" }, 445 { "Right Out 2", NULL, "Right Mixer" }, 446 { "ROUT2", NULL, "Right Out 2" }, 447}; 448 449struct _coeff_div { 450 u32 mclk; 451 u32 rate; 452 u16 fs; 453 u8 sr:5; 454 u8 usb:1; 455}; 456 457/* codec hifi mclk clock divider coefficients */ 458static const struct _coeff_div coeff_div[] = { 459 /* 8k */ 460 {12288000, 8000, 1536, 0x6, 0x0}, 461 {11289600, 8000, 1408, 0x16, 0x0}, 462 {18432000, 8000, 2304, 0x7, 0x0}, 463 {16934400, 8000, 2112, 0x17, 0x0}, 464 {12000000, 8000, 1500, 0x6, 0x1}, 465 466 /* 11.025k */ 467 {11289600, 11025, 1024, 0x18, 0x0}, 468 {16934400, 11025, 1536, 0x19, 0x0}, 469 {12000000, 11025, 1088, 0x19, 0x1}, 470 471 /* 16k */ 472 {12288000, 16000, 768, 0xa, 0x0}, 473 {18432000, 16000, 1152, 0xb, 0x0}, 474 {12000000, 16000, 750, 0xa, 0x1}, 475 476 /* 22.05k */ 477 {11289600, 22050, 512, 0x1a, 0x0}, 478 {16934400, 22050, 768, 0x1b, 0x0}, 479 {12000000, 22050, 544, 0x1b, 0x1}, 480 481 /* 32k */ 482 {12288000, 32000, 384, 0xc, 0x0}, 483 {18432000, 32000, 576, 0xd, 0x0}, 484 {12000000, 32000, 375, 0xa, 0x1}, 485 486 /* 44.1k */ 487 {11289600, 44100, 256, 0x10, 0x0}, 488 {16934400, 44100, 384, 0x11, 0x0}, 489 {12000000, 44100, 272, 0x11, 0x1}, 490 491 /* 48k */ 492 {12288000, 48000, 256, 0x0, 0x0}, 493 {18432000, 48000, 384, 0x1, 0x0}, 494 {12000000, 48000, 250, 0x0, 0x1}, 495 496 /* 88.2k */ 497 {11289600, 88200, 128, 0x1e, 0x0}, 498 {16934400, 88200, 192, 0x1f, 0x0}, 499 {12000000, 88200, 136, 0x1f, 0x1}, 500 501 /* 96k */ 502 {12288000, 96000, 128, 0xe, 0x0}, 503 {18432000, 96000, 192, 0xf, 0x0}, 504 {12000000, 96000, 125, 0xe, 0x1}, 505}; 506 507static inline int get_coeff(int mclk, int rate) 508{ 509 int i; 510 511 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 512 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) 513 return i; 514 } 515 516 return -EINVAL; 517} 518 519/* The set of rates we can generate from the above for each SYSCLK */ 520 521static const unsigned int rates_12288[] = { 522 8000, 12000, 16000, 24000, 32000, 48000, 96000, 523}; 524 525static const struct snd_pcm_hw_constraint_list constraints_12288 = { 526 .count = ARRAY_SIZE(rates_12288), 527 .list = rates_12288, 528}; 529 530static const unsigned int rates_112896[] = { 531 8000, 11025, 22050, 44100, 532}; 533 534static const struct snd_pcm_hw_constraint_list constraints_112896 = { 535 .count = ARRAY_SIZE(rates_112896), 536 .list = rates_112896, 537}; 538 539static const unsigned int rates_12[] = { 540 8000, 11025, 12000, 16000, 22050, 24000, 32000, 41100, 48000, 541 48000, 88235, 96000, 542}; 543 544static const struct snd_pcm_hw_constraint_list constraints_12 = { 545 .count = ARRAY_SIZE(rates_12), 546 .list = rates_12, 547}; 548 549/* 550 * Note that this should be called from init rather than from hw_params. 551 */ 552static int wm8988_set_dai_sysclk(struct snd_soc_dai *codec_dai, 553 int clk_id, unsigned int freq, int dir) 554{ 555 struct snd_soc_component *component = codec_dai->component; 556 struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component); 557 558 switch (freq) { 559 case 11289600: 560 case 18432000: 561 case 22579200: 562 case 36864000: 563 wm8988->sysclk_constraints = &constraints_112896; 564 wm8988->sysclk = freq; 565 return 0; 566 567 case 12288000: 568 case 16934400: 569 case 24576000: 570 case 33868800: 571 wm8988->sysclk_constraints = &constraints_12288; 572 wm8988->sysclk = freq; 573 return 0; 574 575 case 12000000: 576 case 24000000: 577 wm8988->sysclk_constraints = &constraints_12; 578 wm8988->sysclk = freq; 579 return 0; 580 } 581 return -EINVAL; 582} 583 584static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai, 585 unsigned int fmt) 586{ 587 struct snd_soc_component *component = codec_dai->component; 588 u16 iface = 0; 589 590 /* set master/slave audio interface */ 591 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 592 case SND_SOC_DAIFMT_CBM_CFM: 593 iface = 0x0040; 594 break; 595 case SND_SOC_DAIFMT_CBS_CFS: 596 break; 597 default: 598 return -EINVAL; 599 } 600 601 /* interface format */ 602 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 603 case SND_SOC_DAIFMT_I2S: 604 iface |= 0x0002; 605 break; 606 case SND_SOC_DAIFMT_RIGHT_J: 607 break; 608 case SND_SOC_DAIFMT_LEFT_J: 609 iface |= 0x0001; 610 break; 611 case SND_SOC_DAIFMT_DSP_A: 612 iface |= 0x0003; 613 break; 614 case SND_SOC_DAIFMT_DSP_B: 615 iface |= 0x0013; 616 break; 617 default: 618 return -EINVAL; 619 } 620 621 /* clock inversion */ 622 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 623 case SND_SOC_DAIFMT_NB_NF: 624 break; 625 case SND_SOC_DAIFMT_IB_IF: 626 iface |= 0x0090; 627 break; 628 case SND_SOC_DAIFMT_IB_NF: 629 iface |= 0x0080; 630 break; 631 case SND_SOC_DAIFMT_NB_IF: 632 iface |= 0x0010; 633 break; 634 default: 635 return -EINVAL; 636 } 637 638 snd_soc_component_write(component, WM8988_IFACE, iface); 639 return 0; 640} 641 642static int wm8988_pcm_startup(struct snd_pcm_substream *substream, 643 struct snd_soc_dai *dai) 644{ 645 struct snd_soc_component *component = dai->component; 646 struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component); 647 648 /* The set of sample rates that can be supported depends on the 649 * MCLK supplied to the CODEC - enforce this. 650 */ 651 if (!wm8988->sysclk) { 652 dev_err(component->dev, 653 "No MCLK configured, call set_sysclk() on init\n"); 654 return -EINVAL; 655 } 656 657 snd_pcm_hw_constraint_list(substream->runtime, 0, 658 SNDRV_PCM_HW_PARAM_RATE, 659 wm8988->sysclk_constraints); 660 661 return 0; 662} 663 664static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream, 665 struct snd_pcm_hw_params *params, 666 struct snd_soc_dai *dai) 667{ 668 struct snd_soc_component *component = dai->component; 669 struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component); 670 u16 iface = snd_soc_component_read(component, WM8988_IFACE) & 0x1f3; 671 u16 srate = snd_soc_component_read(component, WM8988_SRATE) & 0x180; 672 int coeff; 673 674 coeff = get_coeff(wm8988->sysclk, params_rate(params)); 675 if (coeff < 0) { 676 coeff = get_coeff(wm8988->sysclk / 2, params_rate(params)); 677 srate |= 0x40; 678 } 679 if (coeff < 0) { 680 dev_err(component->dev, 681 "Unable to configure sample rate %dHz with %dHz MCLK\n", 682 params_rate(params), wm8988->sysclk); 683 return coeff; 684 } 685 686 /* bit size */ 687 switch (params_width(params)) { 688 case 16: 689 break; 690 case 20: 691 iface |= 0x0004; 692 break; 693 case 24: 694 iface |= 0x0008; 695 break; 696 case 32: 697 iface |= 0x000c; 698 break; 699 } 700 701 /* set iface & srate */ 702 snd_soc_component_write(component, WM8988_IFACE, iface); 703 if (coeff >= 0) 704 snd_soc_component_write(component, WM8988_SRATE, srate | 705 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 706 707 return 0; 708} 709 710static int wm8988_mute(struct snd_soc_dai *dai, int mute, int direction) 711{ 712 struct snd_soc_component *component = dai->component; 713 u16 mute_reg = snd_soc_component_read(component, WM8988_ADCDAC) & 0xfff7; 714 715 if (mute) 716 snd_soc_component_write(component, WM8988_ADCDAC, mute_reg | 0x8); 717 else 718 snd_soc_component_write(component, WM8988_ADCDAC, mute_reg); 719 return 0; 720} 721 722static int wm8988_set_bias_level(struct snd_soc_component *component, 723 enum snd_soc_bias_level level) 724{ 725 struct wm8988_priv *wm8988 = snd_soc_component_get_drvdata(component); 726 u16 pwr_reg = snd_soc_component_read(component, WM8988_PWR1) & ~0x1c1; 727 728 switch (level) { 729 case SND_SOC_BIAS_ON: 730 break; 731 732 case SND_SOC_BIAS_PREPARE: 733 /* VREF, VMID=2x50k, digital enabled */ 734 snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x00c0); 735 break; 736 737 case SND_SOC_BIAS_STANDBY: 738 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { 739 regcache_sync(wm8988->regmap); 740 741 /* VREF, VMID=2x5k */ 742 snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x1c1); 743 744 /* Charge caps */ 745 msleep(100); 746 } 747 748 /* VREF, VMID=2*500k, digital stopped */ 749 snd_soc_component_write(component, WM8988_PWR1, pwr_reg | 0x0141); 750 break; 751 752 case SND_SOC_BIAS_OFF: 753 snd_soc_component_write(component, WM8988_PWR1, 0x0000); 754 break; 755 } 756 return 0; 757} 758 759#define WM8988_RATES SNDRV_PCM_RATE_8000_96000 760 761#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 762 SNDRV_PCM_FMTBIT_S24_LE) 763 764static const struct snd_soc_dai_ops wm8988_ops = { 765 .startup = wm8988_pcm_startup, 766 .hw_params = wm8988_pcm_hw_params, 767 .set_fmt = wm8988_set_dai_fmt, 768 .set_sysclk = wm8988_set_dai_sysclk, 769 .mute_stream = wm8988_mute, 770 .no_capture_mute = 1, 771}; 772 773static struct snd_soc_dai_driver wm8988_dai = { 774 .name = "wm8988-hifi", 775 .playback = { 776 .stream_name = "Playback", 777 .channels_min = 1, 778 .channels_max = 2, 779 .rates = WM8988_RATES, 780 .formats = WM8988_FORMATS, 781 }, 782 .capture = { 783 .stream_name = "Capture", 784 .channels_min = 1, 785 .channels_max = 2, 786 .rates = WM8988_RATES, 787 .formats = WM8988_FORMATS, 788 }, 789 .ops = &wm8988_ops, 790 .symmetric_rate = 1, 791}; 792 793static int wm8988_probe(struct snd_soc_component *component) 794{ 795 int ret = 0; 796 797 ret = wm8988_reset(component); 798 if (ret < 0) { 799 dev_err(component->dev, "Failed to issue reset\n"); 800 return ret; 801 } 802 803 /* set the update bits (we always update left then right) */ 804 snd_soc_component_update_bits(component, WM8988_RADC, 0x0100, 0x0100); 805 snd_soc_component_update_bits(component, WM8988_RDAC, 0x0100, 0x0100); 806 snd_soc_component_update_bits(component, WM8988_ROUT1V, 0x0100, 0x0100); 807 snd_soc_component_update_bits(component, WM8988_ROUT2V, 0x0100, 0x0100); 808 snd_soc_component_update_bits(component, WM8988_RINVOL, 0x0100, 0x0100); 809 810 return 0; 811} 812 813static const struct snd_soc_component_driver soc_component_dev_wm8988 = { 814 .probe = wm8988_probe, 815 .set_bias_level = wm8988_set_bias_level, 816 .controls = wm8988_snd_controls, 817 .num_controls = ARRAY_SIZE(wm8988_snd_controls), 818 .dapm_widgets = wm8988_dapm_widgets, 819 .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), 820 .dapm_routes = wm8988_dapm_routes, 821 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), 822 .suspend_bias_off = 1, 823 .idle_bias_on = 1, 824 .use_pmdown_time = 1, 825 .endianness = 1, 826 .non_legacy_dai_naming = 1, 827}; 828 829static const struct regmap_config wm8988_regmap = { 830 .reg_bits = 7, 831 .val_bits = 9, 832 833 .max_register = WM8988_LPPB, 834 .writeable_reg = wm8988_writeable, 835 836 .cache_type = REGCACHE_RBTREE, 837 .reg_defaults = wm8988_reg_defaults, 838 .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults), 839}; 840 841#if defined(CONFIG_SPI_MASTER) 842static int wm8988_spi_probe(struct spi_device *spi) 843{ 844 struct wm8988_priv *wm8988; 845 int ret; 846 847 wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv), 848 GFP_KERNEL); 849 if (wm8988 == NULL) 850 return -ENOMEM; 851 852 wm8988->regmap = devm_regmap_init_spi(spi, &wm8988_regmap); 853 if (IS_ERR(wm8988->regmap)) { 854 ret = PTR_ERR(wm8988->regmap); 855 dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); 856 return ret; 857 } 858 859 spi_set_drvdata(spi, wm8988); 860 861 ret = devm_snd_soc_register_component(&spi->dev, 862 &soc_component_dev_wm8988, &wm8988_dai, 1); 863 return ret; 864} 865 866static struct spi_driver wm8988_spi_driver = { 867 .driver = { 868 .name = "wm8988", 869 }, 870 .probe = wm8988_spi_probe, 871}; 872#endif /* CONFIG_SPI_MASTER */ 873 874#if IS_ENABLED(CONFIG_I2C) 875static int wm8988_i2c_probe(struct i2c_client *i2c) 876{ 877 struct wm8988_priv *wm8988; 878 int ret; 879 880 wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv), 881 GFP_KERNEL); 882 if (wm8988 == NULL) 883 return -ENOMEM; 884 885 i2c_set_clientdata(i2c, wm8988); 886 887 wm8988->regmap = devm_regmap_init_i2c(i2c, &wm8988_regmap); 888 if (IS_ERR(wm8988->regmap)) { 889 ret = PTR_ERR(wm8988->regmap); 890 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); 891 return ret; 892 } 893 894 ret = devm_snd_soc_register_component(&i2c->dev, 895 &soc_component_dev_wm8988, &wm8988_dai, 1); 896 return ret; 897} 898 899static const struct i2c_device_id wm8988_i2c_id[] = { 900 { "wm8988", 0 }, 901 { } 902}; 903MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); 904 905static struct i2c_driver wm8988_i2c_driver = { 906 .driver = { 907 .name = "wm8988", 908 }, 909 .probe_new = wm8988_i2c_probe, 910 .id_table = wm8988_i2c_id, 911}; 912#endif 913 914static int __init wm8988_modinit(void) 915{ 916 int ret = 0; 917#if IS_ENABLED(CONFIG_I2C) 918 ret = i2c_add_driver(&wm8988_i2c_driver); 919 if (ret != 0) { 920 printk(KERN_ERR "Failed to register WM8988 I2C driver: %d\n", 921 ret); 922 } 923#endif 924#if defined(CONFIG_SPI_MASTER) 925 ret = spi_register_driver(&wm8988_spi_driver); 926 if (ret != 0) { 927 printk(KERN_ERR "Failed to register WM8988 SPI driver: %d\n", 928 ret); 929 } 930#endif 931 return ret; 932} 933module_init(wm8988_modinit); 934 935static void __exit wm8988_exit(void) 936{ 937#if IS_ENABLED(CONFIG_I2C) 938 i2c_del_driver(&wm8988_i2c_driver); 939#endif 940#if defined(CONFIG_SPI_MASTER) 941 spi_unregister_driver(&wm8988_spi_driver); 942#endif 943} 944module_exit(wm8988_exit); 945 946 947MODULE_DESCRIPTION("ASoC WM8988 driver"); 948MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 949MODULE_LICENSE("GPL");