15 #include <linux/module.h>
20 #include <linux/i2c.h>
24 #include <linux/slab.h>
45 static const struct reg_default wm8776_reg_defaults[] = {
71 static bool wm8776_volatile(
struct device *
dev,
unsigned int reg)
136 outmix_controls,
ARRAY_SIZE(outmix_controls)),
147 {
"Input Mixer",
"AIN1 Switch",
"AIN1" },
148 {
"Input Mixer",
"AIN2 Switch",
"AIN2" },
149 {
"Input Mixer",
"AIN3 Switch",
"AIN3" },
150 {
"Input Mixer",
"AIN4 Switch",
"AIN4" },
151 {
"Input Mixer",
"AIN5 Switch",
"AIN5" },
153 {
"ADC",
NULL,
"Input Mixer" },
155 {
"Output Mixer",
"DAC Switch",
"DAC" },
156 {
"Output Mixer",
"AUX Switch",
"AUX" },
157 {
"Output Mixer",
"Bypass Switch",
"Input Mixer" },
159 {
"VOUT",
NULL,
"Output Mixer" },
161 {
"Headphone PGA",
NULL,
"Output Mixer" },
163 {
"HPOUTL",
NULL,
"Headphone PGA" },
164 {
"HPOUTR",
NULL,
"Headphone PGA" },
170 int reg, iface, master;
172 switch (dai->
driver->id) {
233 static int mclk_ratios[] = {
247 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
248 int iface_reg, iface;
249 int ratio_shift, master;
252 switch (dai->
driver->id) {
282 dev_err(codec->
dev,
"Unsupported sample size: %i\n",
289 for (i = 0; i <
ARRAY_SIZE(mclk_ratios); i++) {
297 "Unable to configure MCLK ratio %d/%d\n",
302 dev_dbg(codec->
dev,
"MCLK is %dfs\n", mclk_ratios[i]);
305 0x7 << ratio_shift, i << ratio_shift);
322 static int wm8776_set_sysclk(
struct snd_soc_dai *dai,
323 int clk_id,
unsigned int freq,
int dir)
326 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
335 static int wm8776_set_bias_level(
struct snd_soc_codec *codec,
338 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
363 #define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
364 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
367 .digital_mute = wm8776_mute,
368 .hw_params = wm8776_hw_params,
369 .set_fmt = wm8776_set_fmt,
370 .set_sysclk = wm8776_set_sysclk,
374 .hw_params = wm8776_hw_params,
375 .set_fmt = wm8776_set_fmt,
376 .set_sysclk = wm8776_set_sysclk,
381 .name =
"wm8776-hifi-playback",
384 .stream_name =
"Playback",
392 .ops = &wm8776_dac_ops,
395 .name =
"wm8776-hifi-capture",
398 .stream_name =
"Capture",
406 .ops = &wm8776_adc_ops,
424 #define wm8776_suspend NULL
425 #define wm8776_resume NULL
434 dev_err(codec->
dev,
"Failed to set cache I/O: %d\n", ret);
438 ret = wm8776_reset(codec);
440 dev_err(codec->
dev,
"Failed to issue reset: %d\n", ret);
462 .probe = wm8776_probe,
463 .remove = wm8776_remove,
466 .set_bias_level = wm8776_set_bias_level,
468 .controls = wm8776_snd_controls,
469 .num_controls =
ARRAY_SIZE(wm8776_snd_controls),
470 .dapm_widgets = wm8776_dapm_widgets,
471 .num_dapm_widgets =
ARRAY_SIZE(wm8776_dapm_widgets),
472 .dapm_routes = routes,
477 { .compatible =
"wlf,wm8776", },
482 static const struct regmap_config wm8776_regmap = {
487 .reg_defaults = wm8776_reg_defaults,
488 .num_reg_defaults =
ARRAY_SIZE(wm8776_reg_defaults),
491 .volatile_reg = wm8776_volatile,
494 #if defined(CONFIG_SPI_MASTER)
506 if (IS_ERR(wm8776->
regmap))
507 return PTR_ERR(wm8776->
regmap);
509 spi_set_drvdata(spi, wm8776);
512 &soc_codec_dev_wm8776, wm8776_dai,
ARRAY_SIZE(wm8776_dai));
523 static struct spi_driver wm8776_spi_driver = {
527 .of_match_table = wm8776_of_match,
529 .probe = wm8776_spi_probe,
534 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
547 if (IS_ERR(wm8776->
regmap))
548 return PTR_ERR(wm8776->
regmap);
550 i2c_set_clientdata(i2c, wm8776);
553 &soc_codec_dev_wm8776, wm8776_dai,
ARRAY_SIZE(wm8776_dai));
571 static struct i2c_driver wm8776_i2c_driver = {
575 .of_match_table = wm8776_of_match,
577 .probe = wm8776_i2c_probe,
579 .id_table = wm8776_i2c_id,
583 static int __init wm8776_modinit(
void)
586 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
587 ret = i2c_add_driver(&wm8776_i2c_driver);
593 #if defined(CONFIG_SPI_MASTER)
604 static void __exit wm8776_exit(
void)
606 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
609 #if defined(CONFIG_SPI_MASTER)
610 spi_unregister_driver(&wm8776_spi_driver);