linux/sound/soc/codecs/wm8750.c
<<
>>
Prefs
   1/*
   2 * wm8750.c -- WM8750 ALSA SoC audio driver
   3 *
   4 * Copyright 2005 Openedhand Ltd.
   5 *
   6 * Author: Richard Purdie <richard@openedhand.com>
   7 *
   8 * Based on WM8753.c
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/moduleparam.h>
  17#include <linux/init.h>
  18#include <linux/delay.h>
  19#include <linux/pm.h>
  20#include <linux/i2c.h>
  21#include <linux/regmap.h>
  22#include <linux/spi/spi.h>
  23#include <linux/slab.h>
  24#include <linux/of_device.h>
  25#include <sound/core.h>
  26#include <sound/pcm.h>
  27#include <sound/pcm_params.h>
  28#include <sound/soc.h>
  29#include <sound/initval.h>
  30
  31#include "wm8750.h"
  32
  33/*
  34 * wm8750 register cache
  35 * We can't read the WM8750 register space when we
  36 * are using 2 wire for device control, so we cache them instead.
  37 */
  38static const struct reg_default wm8750_reg_defaults[] = {
  39        {  0, 0x0097 },
  40        {  1, 0x0097 },
  41        {  2, 0x0079 },
  42        {  3, 0x0079 },
  43        {  4, 0x0000 },
  44        {  5, 0x0008 },
  45        {  6, 0x0000 },
  46        {  7, 0x000a },
  47        {  8, 0x0000 },
  48        {  9, 0x0000 },
  49        { 10, 0x00ff },
  50        { 11, 0x00ff },
  51        { 12, 0x000f },
  52        { 13, 0x000f },
  53        { 14, 0x0000 },
  54        { 15, 0x0000 },
  55        { 16, 0x0000 },
  56        { 17, 0x007b },
  57        { 18, 0x0000 },
  58        { 19, 0x0032 },
  59        { 20, 0x0000 },
  60        { 21, 0x00c3 },
  61        { 22, 0x00c3 },
  62        { 23, 0x00c0 },
  63        { 24, 0x0000 },
  64        { 25, 0x0000 },
  65        { 26, 0x0000 },
  66        { 27, 0x0000 },
  67        { 28, 0x0000 },
  68        { 29, 0x0000 },
  69        { 30, 0x0000 },
  70        { 31, 0x0000 },
  71        { 32, 0x0000 },
  72        { 33, 0x0000 },
  73        { 34, 0x0050 },
  74        { 35, 0x0050 },
  75        { 36, 0x0050 },
  76        { 37, 0x0050 },
  77        { 38, 0x0050 },
  78        { 39, 0x0050 },
  79        { 40, 0x0079 },
  80        { 41, 0x0079 },
  81        { 42, 0x0079 },
  82};
  83
  84/* codec private data */
  85struct wm8750_priv {
  86        unsigned int sysclk;
  87};
  88
  89#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
  90
  91/*
  92 * WM8750 Controls
  93 */
  94static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"};
  95static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
  96static const char *wm8750_treble[] = {"8kHz", "4kHz"};
  97static const char *wm8750_3d_lc[] = {"200Hz", "500Hz"};
  98static const char *wm8750_3d_uc[] = {"2.2kHz", "1.5kHz"};
  99static const char *wm8750_3d_func[] = {"Capture", "Playback"};
 100static const char *wm8750_alc_func[] = {"Off", "Right", "Left", "Stereo"};
 101static const char *wm8750_ng_type[] = {"Constant PGA Gain",
 102        "Mute ADC Output"};
 103static const char *wm8750_line_mux[] = {"Line 1", "Line 2", "Line 3", "PGA",
 104        "Differential"};
 105static const char *wm8750_pga_sel[] = {"Line 1", "Line 2", "Line 3",
 106        "Differential"};
 107static const char *wm8750_out3[] = {"VREF", "ROUT1 + Vol", "MonoOut",
 108        "ROUT1"};
 109static const char *wm8750_diff_sel[] = {"Line 1", "Line 2"};
 110static const char *wm8750_adcpol[] = {"Normal", "L Invert", "R Invert",
 111        "L + R Invert"};
 112static const char *wm8750_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
 113static const char *wm8750_mono_mux[] = {"Stereo", "Mono (Left)",
 114        "Mono (Right)", "Digital Mono"};
 115
 116static const struct soc_enum wm8750_enum[] = {
 117SOC_ENUM_SINGLE(WM8750_BASS, 7, 2, wm8750_bass),
 118SOC_ENUM_SINGLE(WM8750_BASS, 6, 2, wm8750_bass_filter),
 119SOC_ENUM_SINGLE(WM8750_TREBLE, 6, 2, wm8750_treble),
 120SOC_ENUM_SINGLE(WM8750_3D, 5, 2, wm8750_3d_lc),
 121SOC_ENUM_SINGLE(WM8750_3D, 6, 2, wm8750_3d_uc),
 122SOC_ENUM_SINGLE(WM8750_3D, 7, 2, wm8750_3d_func),
 123SOC_ENUM_SINGLE(WM8750_ALC1, 7, 4, wm8750_alc_func),
 124SOC_ENUM_SINGLE(WM8750_NGATE, 1, 2, wm8750_ng_type),
 125SOC_ENUM_SINGLE(WM8750_LOUTM1, 0, 5, wm8750_line_mux),
 126SOC_ENUM_SINGLE(WM8750_ROUTM1, 0, 5, wm8750_line_mux),
 127SOC_ENUM_SINGLE(WM8750_LADCIN, 6, 4, wm8750_pga_sel), /* 10 */
 128SOC_ENUM_SINGLE(WM8750_RADCIN, 6, 4, wm8750_pga_sel),
 129SOC_ENUM_SINGLE(WM8750_ADCTL2, 7, 4, wm8750_out3),
 130SOC_ENUM_SINGLE(WM8750_ADCIN, 8, 2, wm8750_diff_sel),
 131SOC_ENUM_SINGLE(WM8750_ADCDAC, 5, 4, wm8750_adcpol),
 132SOC_ENUM_SINGLE(WM8750_ADCDAC, 1, 4, wm8750_deemph),
 133SOC_ENUM_SINGLE(WM8750_ADCIN, 6, 4, wm8750_mono_mux), /* 16 */
 134
 135};
 136
 137static const struct snd_kcontrol_new wm8750_snd_controls[] = {
 138
 139SOC_DOUBLE_R("Capture Volume", WM8750_LINVOL, WM8750_RINVOL, 0, 63, 0),
 140SOC_DOUBLE_R("Capture ZC Switch", WM8750_LINVOL, WM8750_RINVOL, 6, 1, 0),
 141SOC_DOUBLE_R("Capture Switch", WM8750_LINVOL, WM8750_RINVOL, 7, 1, 1),
 142
 143SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8750_LOUT1V,
 144        WM8750_ROUT1V, 7, 1, 0),
 145SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8750_LOUT2V,
 146        WM8750_ROUT2V, 7, 1, 0),
 147
 148SOC_ENUM("Playback De-emphasis", wm8750_enum[15]),
 149
 150SOC_ENUM("Capture Polarity", wm8750_enum[14]),
 151SOC_SINGLE("Playback 6dB Attenuate", WM8750_ADCDAC, 7, 1, 0),
 152SOC_SINGLE("Capture 6dB Attenuate", WM8750_ADCDAC, 8, 1, 0),
 153
 154SOC_DOUBLE_R("PCM Volume", WM8750_LDAC, WM8750_RDAC, 0, 255, 0),
 155
 156SOC_ENUM("Bass Boost", wm8750_enum[0]),
 157SOC_ENUM("Bass Filter", wm8750_enum[1]),
 158SOC_SINGLE("Bass Volume", WM8750_BASS, 0, 15, 1),
 159
 160SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 1),
 161SOC_ENUM("Treble Cut-off", wm8750_enum[2]),
 162
 163SOC_SINGLE("3D Switch", WM8750_3D, 0, 1, 0),
 164SOC_SINGLE("3D Volume", WM8750_3D, 1, 15, 0),
 165SOC_ENUM("3D Lower Cut-off", wm8750_enum[3]),
 166SOC_ENUM("3D Upper Cut-off", wm8750_enum[4]),
 167SOC_ENUM("3D Mode", wm8750_enum[5]),
 168
 169SOC_SINGLE("ALC Capture Target Volume", WM8750_ALC1, 0, 7, 0),
 170SOC_SINGLE("ALC Capture Max Volume", WM8750_ALC1, 4, 7, 0),
 171SOC_ENUM("ALC Capture Function", wm8750_enum[6]),
 172SOC_SINGLE("ALC Capture ZC Switch", WM8750_ALC2, 7, 1, 0),
 173SOC_SINGLE("ALC Capture Hold Time", WM8750_ALC2, 0, 15, 0),
 174SOC_SINGLE("ALC Capture Decay Time", WM8750_ALC3, 4, 15, 0),
 175SOC_SINGLE("ALC Capture Attack Time", WM8750_ALC3, 0, 15, 0),
 176SOC_SINGLE("ALC Capture NG Threshold", WM8750_NGATE, 3, 31, 0),
 177SOC_ENUM("ALC Capture NG Type", wm8750_enum[4]),
 178SOC_SINGLE("ALC Capture NG Switch", WM8750_NGATE, 0, 1, 0),
 179
 180SOC_SINGLE("Left ADC Capture Volume", WM8750_LADC, 0, 255, 0),
 181SOC_SINGLE("Right ADC Capture Volume", WM8750_RADC, 0, 255, 0),
 182
 183SOC_SINGLE("ZC Timeout Switch", WM8750_ADCTL1, 0, 1, 0),
 184SOC_SINGLE("Playback Invert Switch", WM8750_ADCTL1, 1, 1, 0),
 185
 186SOC_SINGLE("Right Speaker Playback Invert Switch", WM8750_ADCTL2, 4, 1, 0),
 187
 188/* Unimplemented */
 189/* ADCDAC Bit 0 - ADCHPD */
 190/* ADCDAC Bit 4 - HPOR */
 191/* ADCTL1 Bit 2,3 - DATSEL */
 192/* ADCTL1 Bit 4,5 - DMONOMIX */
 193/* ADCTL1 Bit 6,7 - VSEL */
 194/* ADCTL2 Bit 2 - LRCM */
 195/* ADCTL2 Bit 3 - TRI */
 196/* ADCTL3 Bit 5 - HPFLREN */
 197/* ADCTL3 Bit 6 - VROI */
 198/* ADCTL3 Bit 7,8 - ADCLRM */
 199/* ADCIN Bit 4 - LDCM */
 200/* ADCIN Bit 5 - RDCM */
 201
 202SOC_DOUBLE_R("Mic Boost", WM8750_LADCIN, WM8750_RADCIN, 4, 3, 0),
 203
 204SOC_DOUBLE_R("Bypass Left Playback Volume", WM8750_LOUTM1,
 205        WM8750_LOUTM2, 4, 7, 1),
 206SOC_DOUBLE_R("Bypass Right Playback Volume", WM8750_ROUTM1,
 207        WM8750_ROUTM2, 4, 7, 1),
 208SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8750_MOUTM1,
 209        WM8750_MOUTM2, 4, 7, 1),
 210
 211SOC_SINGLE("Mono Playback ZC Switch", WM8750_MOUTV, 7, 1, 0),
 212
 213SOC_DOUBLE_R("Headphone Playback Volume", WM8750_LOUT1V, WM8750_ROUT1V,
 214        0, 127, 0),
 215SOC_DOUBLE_R("Speaker Playback Volume", WM8750_LOUT2V, WM8750_ROUT2V,
 216        0, 127, 0),
 217
 218SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0),
 219
 220};
 221
 222/*
 223 * DAPM Controls
 224 */
 225
 226/* Left Mixer */
 227static const struct snd_kcontrol_new wm8750_left_mixer_controls[] = {
 228SOC_DAPM_SINGLE("Playback Switch", WM8750_LOUTM1, 8, 1, 0),
 229SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_LOUTM1, 7, 1, 0),
 230SOC_DAPM_SINGLE("Right Playback Switch", WM8750_LOUTM2, 8, 1, 0),
 231SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_LOUTM2, 7, 1, 0),
 232};
 233
 234/* Right Mixer */
 235static const struct snd_kcontrol_new wm8750_right_mixer_controls[] = {
 236SOC_DAPM_SINGLE("Left Playback Switch", WM8750_ROUTM1, 8, 1, 0),
 237SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_ROUTM1, 7, 1, 0),
 238SOC_DAPM_SINGLE("Playback Switch", WM8750_ROUTM2, 8, 1, 0),
 239SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_ROUTM2, 7, 1, 0),
 240};
 241
 242/* Mono Mixer */
 243static const struct snd_kcontrol_new wm8750_mono_mixer_controls[] = {
 244SOC_DAPM_SINGLE("Left Playback Switch", WM8750_MOUTM1, 8, 1, 0),
 245SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_MOUTM1, 7, 1, 0),
 246SOC_DAPM_SINGLE("Right Playback Switch", WM8750_MOUTM2, 8, 1, 0),
 247SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_MOUTM2, 7, 1, 0),
 248};
 249
 250/* Left Line Mux */
 251static const struct snd_kcontrol_new wm8750_left_line_controls =
 252SOC_DAPM_ENUM("Route", wm8750_enum[8]);
 253
 254/* Right Line Mux */
 255static const struct snd_kcontrol_new wm8750_right_line_controls =
 256SOC_DAPM_ENUM("Route", wm8750_enum[9]);
 257
 258/* Left PGA Mux */
 259static const struct snd_kcontrol_new wm8750_left_pga_controls =
 260SOC_DAPM_ENUM("Route", wm8750_enum[10]);
 261
 262/* Right PGA Mux */
 263static const struct snd_kcontrol_new wm8750_right_pga_controls =
 264SOC_DAPM_ENUM("Route", wm8750_enum[11]);
 265
 266/* Out 3 Mux */
 267static const struct snd_kcontrol_new wm8750_out3_controls =
 268SOC_DAPM_ENUM("Route", wm8750_enum[12]);
 269
 270/* Differential Mux */
 271static const struct snd_kcontrol_new wm8750_diffmux_controls =
 272SOC_DAPM_ENUM("Route", wm8750_enum[13]);
 273
 274/* Mono ADC Mux */
 275static const struct snd_kcontrol_new wm8750_monomux_controls =
 276SOC_DAPM_ENUM("Route", wm8750_enum[16]);
 277
 278static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
 279        SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
 280                &wm8750_left_mixer_controls[0],
 281                ARRAY_SIZE(wm8750_left_mixer_controls)),
 282        SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
 283                &wm8750_right_mixer_controls[0],
 284                ARRAY_SIZE(wm8750_right_mixer_controls)),
 285        SND_SOC_DAPM_MIXER("Mono Mixer", WM8750_PWR2, 2, 0,
 286                &wm8750_mono_mixer_controls[0],
 287                ARRAY_SIZE(wm8750_mono_mixer_controls)),
 288
 289        SND_SOC_DAPM_PGA("Right Out 2", WM8750_PWR2, 3, 0, NULL, 0),
 290        SND_SOC_DAPM_PGA("Left Out 2", WM8750_PWR2, 4, 0, NULL, 0),
 291        SND_SOC_DAPM_PGA("Right Out 1", WM8750_PWR2, 5, 0, NULL, 0),
 292        SND_SOC_DAPM_PGA("Left Out 1", WM8750_PWR2, 6, 0, NULL, 0),
 293        SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8750_PWR2, 7, 0),
 294        SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8750_PWR2, 8, 0),
 295
 296        SND_SOC_DAPM_MICBIAS("Mic Bias", WM8750_PWR1, 1, 0),
 297        SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8750_PWR1, 2, 0),
 298        SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8750_PWR1, 3, 0),
 299
 300        SND_SOC_DAPM_MUX("Left PGA Mux", WM8750_PWR1, 5, 0,
 301                &wm8750_left_pga_controls),
 302        SND_SOC_DAPM_MUX("Right PGA Mux", WM8750_PWR1, 4, 0,
 303                &wm8750_right_pga_controls),
 304        SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
 305                &wm8750_left_line_controls),
 306        SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
 307                &wm8750_right_line_controls),
 308
 309        SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8750_out3_controls),
 310        SND_SOC_DAPM_PGA("Out 3", WM8750_PWR2, 1, 0, NULL, 0),
 311        SND_SOC_DAPM_PGA("Mono Out 1", WM8750_PWR2, 2, 0, NULL, 0),
 312
 313        SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
 314                &wm8750_diffmux_controls),
 315        SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
 316                &wm8750_monomux_controls),
 317        SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
 318                &wm8750_monomux_controls),
 319
 320        SND_SOC_DAPM_OUTPUT("LOUT1"),
 321        SND_SOC_DAPM_OUTPUT("ROUT1"),
 322        SND_SOC_DAPM_OUTPUT("LOUT2"),
 323        SND_SOC_DAPM_OUTPUT("ROUT2"),
 324        SND_SOC_DAPM_OUTPUT("MONO1"),
 325        SND_SOC_DAPM_OUTPUT("OUT3"),
 326        SND_SOC_DAPM_OUTPUT("VREF"),
 327
 328        SND_SOC_DAPM_INPUT("LINPUT1"),
 329        SND_SOC_DAPM_INPUT("LINPUT2"),
 330        SND_SOC_DAPM_INPUT("LINPUT3"),
 331        SND_SOC_DAPM_INPUT("RINPUT1"),
 332        SND_SOC_DAPM_INPUT("RINPUT2"),
 333        SND_SOC_DAPM_INPUT("RINPUT3"),
 334};
 335
 336static const struct snd_soc_dapm_route wm8750_dapm_routes[] = {
 337        /* left mixer */
 338        {"Left Mixer", "Playback Switch", "Left DAC"},
 339        {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
 340        {"Left Mixer", "Right Playback Switch", "Right DAC"},
 341        {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
 342
 343        /* right mixer */
 344        {"Right Mixer", "Left Playback Switch", "Left DAC"},
 345        {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
 346        {"Right Mixer", "Playback Switch", "Right DAC"},
 347        {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
 348
 349        /* left out 1 */
 350        {"Left Out 1", NULL, "Left Mixer"},
 351        {"LOUT1", NULL, "Left Out 1"},
 352
 353        /* left out 2 */
 354        {"Left Out 2", NULL, "Left Mixer"},
 355        {"LOUT2", NULL, "Left Out 2"},
 356
 357        /* right out 1 */
 358        {"Right Out 1", NULL, "Right Mixer"},
 359        {"ROUT1", NULL, "Right Out 1"},
 360
 361        /* right out 2 */
 362        {"Right Out 2", NULL, "Right Mixer"},
 363        {"ROUT2", NULL, "Right Out 2"},
 364
 365        /* mono mixer */
 366        {"Mono Mixer", "Left Playback Switch", "Left DAC"},
 367        {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
 368        {"Mono Mixer", "Right Playback Switch", "Right DAC"},
 369        {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
 370
 371        /* mono out */
 372        {"Mono Out 1", NULL, "Mono Mixer"},
 373        {"MONO1", NULL, "Mono Out 1"},
 374
 375        /* out 3 */
 376        {"Out3 Mux", "VREF", "VREF"},
 377        {"Out3 Mux", "ROUT1 + Vol", "ROUT1"},
 378        {"Out3 Mux", "ROUT1", "Right Mixer"},
 379        {"Out3 Mux", "MonoOut", "MONO1"},
 380        {"Out 3", NULL, "Out3 Mux"},
 381        {"OUT3", NULL, "Out 3"},
 382
 383        /* Left Line Mux */
 384        {"Left Line Mux", "Line 1", "LINPUT1"},
 385        {"Left Line Mux", "Line 2", "LINPUT2"},
 386        {"Left Line Mux", "Line 3", "LINPUT3"},
 387        {"Left Line Mux", "PGA", "Left PGA Mux"},
 388        {"Left Line Mux", "Differential", "Differential Mux"},
 389
 390        /* Right Line Mux */
 391        {"Right Line Mux", "Line 1", "RINPUT1"},
 392        {"Right Line Mux", "Line 2", "RINPUT2"},
 393        {"Right Line Mux", "Line 3", "RINPUT3"},
 394        {"Right Line Mux", "PGA", "Right PGA Mux"},
 395        {"Right Line Mux", "Differential", "Differential Mux"},
 396
 397        /* Left PGA Mux */
 398        {"Left PGA Mux", "Line 1", "LINPUT1"},
 399        {"Left PGA Mux", "Line 2", "LINPUT2"},
 400        {"Left PGA Mux", "Line 3", "LINPUT3"},
 401        {"Left PGA Mux", "Differential", "Differential Mux"},
 402
 403        /* Right PGA Mux */
 404        {"Right PGA Mux", "Line 1", "RINPUT1"},
 405        {"Right PGA Mux", "Line 2", "RINPUT2"},
 406        {"Right PGA Mux", "Line 3", "RINPUT3"},
 407        {"Right PGA Mux", "Differential", "Differential Mux"},
 408
 409        /* Differential Mux */
 410        {"Differential Mux", "Line 1", "LINPUT1"},
 411        {"Differential Mux", "Line 1", "RINPUT1"},
 412        {"Differential Mux", "Line 2", "LINPUT2"},
 413        {"Differential Mux", "Line 2", "RINPUT2"},
 414
 415        /* Left ADC Mux */
 416        {"Left ADC Mux", "Stereo", "Left PGA Mux"},
 417        {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
 418        {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
 419
 420        /* Right ADC Mux */
 421        {"Right ADC Mux", "Stereo", "Right PGA Mux"},
 422        {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
 423        {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
 424
 425        /* ADC */
 426        {"Left ADC", NULL, "Left ADC Mux"},
 427        {"Right ADC", NULL, "Right ADC Mux"},
 428};
 429
 430struct _coeff_div {
 431        u32 mclk;
 432        u32 rate;
 433        u16 fs;
 434        u8 sr:5;
 435        u8 usb:1;
 436};
 437
 438/* codec hifi mclk clock divider coefficients */
 439static const struct _coeff_div coeff_div[] = {
 440        /* 8k */
 441        {12288000, 8000, 1536, 0x6, 0x0},
 442        {11289600, 8000, 1408, 0x16, 0x0},
 443        {18432000, 8000, 2304, 0x7, 0x0},
 444        {16934400, 8000, 2112, 0x17, 0x0},
 445        {12000000, 8000, 1500, 0x6, 0x1},
 446
 447        /* 11.025k */
 448        {11289600, 11025, 1024, 0x18, 0x0},
 449        {16934400, 11025, 1536, 0x19, 0x0},
 450        {12000000, 11025, 1088, 0x19, 0x1},
 451
 452        /* 16k */
 453        {12288000, 16000, 768, 0xa, 0x0},
 454        {18432000, 16000, 1152, 0xb, 0x0},
 455        {12000000, 16000, 750, 0xa, 0x1},
 456
 457        /* 22.05k */
 458        {11289600, 22050, 512, 0x1a, 0x0},
 459        {16934400, 22050, 768, 0x1b, 0x0},
 460        {12000000, 22050, 544, 0x1b, 0x1},
 461
 462        /* 32k */
 463        {12288000, 32000, 384, 0xc, 0x0},
 464        {18432000, 32000, 576, 0xd, 0x0},
 465        {12000000, 32000, 375, 0xa, 0x1},
 466
 467        /* 44.1k */
 468        {11289600, 44100, 256, 0x10, 0x0},
 469        {16934400, 44100, 384, 0x11, 0x0},
 470        {12000000, 44100, 272, 0x11, 0x1},
 471
 472        /* 48k */
 473        {12288000, 48000, 256, 0x0, 0x0},
 474        {18432000, 48000, 384, 0x1, 0x0},
 475        {12000000, 48000, 250, 0x0, 0x1},
 476
 477        /* 88.2k */
 478        {11289600, 88200, 128, 0x1e, 0x0},
 479        {16934400, 88200, 192, 0x1f, 0x0},
 480        {12000000, 88200, 136, 0x1f, 0x1},
 481
 482        /* 96k */
 483        {12288000, 96000, 128, 0xe, 0x0},
 484        {18432000, 96000, 192, 0xf, 0x0},
 485        {12000000, 96000, 125, 0xe, 0x1},
 486};
 487
 488static inline int get_coeff(int mclk, int rate)
 489{
 490        int i;
 491
 492        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
 493                if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
 494                        return i;
 495        }
 496
 497        printk(KERN_ERR "wm8750: could not get coeff for mclk %d @ rate %d\n",
 498                mclk, rate);
 499        return -EINVAL;
 500}
 501
 502static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 503                int clk_id, unsigned int freq, int dir)
 504{
 505        struct snd_soc_codec *codec = codec_dai->codec;
 506        struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
 507
 508        switch (freq) {
 509        case 11289600:
 510        case 12000000:
 511        case 12288000:
 512        case 16934400:
 513        case 18432000:
 514                wm8750->sysclk = freq;
 515                return 0;
 516        }
 517        return -EINVAL;
 518}
 519
 520static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
 521                unsigned int fmt)
 522{
 523        struct snd_soc_codec *codec = codec_dai->codec;
 524        u16 iface = 0;
 525
 526        /* set master/slave audio interface */
 527        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 528        case SND_SOC_DAIFMT_CBM_CFM:
 529                iface = 0x0040;
 530                break;
 531        case SND_SOC_DAIFMT_CBS_CFS:
 532                break;
 533        default:
 534                return -EINVAL;
 535        }
 536
 537        /* interface format */
 538        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 539        case SND_SOC_DAIFMT_I2S:
 540                iface |= 0x0002;
 541                break;
 542        case SND_SOC_DAIFMT_RIGHT_J:
 543                break;
 544        case SND_SOC_DAIFMT_LEFT_J:
 545                iface |= 0x0001;
 546                break;
 547        case SND_SOC_DAIFMT_DSP_A:
 548                iface |= 0x0003;
 549                break;
 550        case SND_SOC_DAIFMT_DSP_B:
 551                iface |= 0x0013;
 552                break;
 553        default:
 554                return -EINVAL;
 555        }
 556
 557        /* clock inversion */
 558        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 559        case SND_SOC_DAIFMT_NB_NF:
 560                break;
 561        case SND_SOC_DAIFMT_IB_IF:
 562                iface |= 0x0090;
 563                break;
 564        case SND_SOC_DAIFMT_IB_NF:
 565                iface |= 0x0080;
 566                break;
 567        case SND_SOC_DAIFMT_NB_IF:
 568                iface |= 0x0010;
 569                break;
 570        default:
 571                return -EINVAL;
 572        }
 573
 574        snd_soc_write(codec, WM8750_IFACE, iface);
 575        return 0;
 576}
 577
 578static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
 579                                struct snd_pcm_hw_params *params,
 580                                struct snd_soc_dai *dai)
 581{
 582        struct snd_soc_codec *codec = dai->codec;
 583        struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
 584        u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
 585        u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
 586        int coeff = get_coeff(wm8750->sysclk, params_rate(params));
 587
 588        /* bit size */
 589        switch (params_format(params)) {
 590        case SNDRV_PCM_FORMAT_S16_LE:
 591                break;
 592        case SNDRV_PCM_FORMAT_S20_3LE:
 593                iface |= 0x0004;
 594                break;
 595        case SNDRV_PCM_FORMAT_S24_LE:
 596                iface |= 0x0008;
 597                break;
 598        case SNDRV_PCM_FORMAT_S32_LE:
 599                iface |= 0x000c;
 600                break;
 601        }
 602
 603        /* set iface & srate */
 604        snd_soc_write(codec, WM8750_IFACE, iface);
 605        if (coeff >= 0)
 606                snd_soc_write(codec, WM8750_SRATE, srate |
 607                        (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
 608
 609        return 0;
 610}
 611
 612static int wm8750_mute(struct snd_soc_dai *dai, int mute)
 613{
 614        struct snd_soc_codec *codec = dai->codec;
 615        u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
 616
 617        if (mute)
 618                snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
 619        else
 620                snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
 621        return 0;
 622}
 623
 624static int wm8750_set_bias_level(struct snd_soc_codec *codec,
 625                                 enum snd_soc_bias_level level)
 626{
 627        u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
 628
 629        switch (level) {
 630        case SND_SOC_BIAS_ON:
 631                /* set vmid to 50k and unmute dac */
 632                snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
 633                break;
 634        case SND_SOC_BIAS_PREPARE:
 635                break;
 636        case SND_SOC_BIAS_STANDBY:
 637                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 638                        snd_soc_cache_sync(codec);
 639
 640                        /* Set VMID to 5k */
 641                        snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
 642
 643                        /* ...and ramp */
 644                        msleep(1000);
 645                }
 646
 647                /* mute dac and set vmid to 500k, enable VREF */
 648                snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
 649                break;
 650        case SND_SOC_BIAS_OFF:
 651                snd_soc_write(codec, WM8750_PWR1, 0x0001);
 652                break;
 653        }
 654        codec->dapm.bias_level = level;
 655        return 0;
 656}
 657
 658#define WM8750_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
 659        SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
 660        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
 661
 662#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 663        SNDRV_PCM_FMTBIT_S24_LE)
 664
 665static const struct snd_soc_dai_ops wm8750_dai_ops = {
 666        .hw_params      = wm8750_pcm_hw_params,
 667        .digital_mute   = wm8750_mute,
 668        .set_fmt        = wm8750_set_dai_fmt,
 669        .set_sysclk     = wm8750_set_dai_sysclk,
 670};
 671
 672static struct snd_soc_dai_driver wm8750_dai = {
 673        .name = "wm8750-hifi",
 674        .playback = {
 675                .stream_name = "Playback",
 676                .channels_min = 1,
 677                .channels_max = 2,
 678                .rates = WM8750_RATES,
 679                .formats = WM8750_FORMATS,},
 680        .capture = {
 681                .stream_name = "Capture",
 682                .channels_min = 1,
 683                .channels_max = 2,
 684                .rates = WM8750_RATES,
 685                .formats = WM8750_FORMATS,},
 686        .ops = &wm8750_dai_ops,
 687};
 688
 689static int wm8750_suspend(struct snd_soc_codec *codec)
 690{
 691        wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
 692        return 0;
 693}
 694
 695static int wm8750_resume(struct snd_soc_codec *codec)
 696{
 697        wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 698        return 0;
 699}
 700
 701static int wm8750_probe(struct snd_soc_codec *codec)
 702{
 703        int ret;
 704
 705        ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 706        if (ret < 0) {
 707                printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
 708                return ret;
 709        }
 710
 711        ret = wm8750_reset(codec);
 712        if (ret < 0) {
 713                printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
 714                return ret;
 715        }
 716
 717        /* charge output caps */
 718        wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 719
 720        /* set the update bits */
 721        snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
 722        snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
 723        snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
 724        snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
 725        snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
 726        snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
 727        snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
 728        snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
 729
 730        return ret;
 731}
 732
 733static int wm8750_remove(struct snd_soc_codec *codec)
 734{
 735        wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
 736        return 0;
 737}
 738
 739static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
 740        .probe =        wm8750_probe,
 741        .remove =       wm8750_remove,
 742        .suspend =      wm8750_suspend,
 743        .resume =       wm8750_resume,
 744        .set_bias_level = wm8750_set_bias_level,
 745
 746        .controls = wm8750_snd_controls,
 747        .num_controls = ARRAY_SIZE(wm8750_snd_controls),
 748        .dapm_widgets = wm8750_dapm_widgets,
 749        .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
 750        .dapm_routes = wm8750_dapm_routes,
 751        .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes),
 752};
 753
 754static const struct of_device_id wm8750_of_match[] = {
 755        { .compatible = "wlf,wm8750", },
 756        { .compatible = "wlf,wm8987", },
 757        { }
 758};
 759MODULE_DEVICE_TABLE(of, wm8750_of_match);
 760
 761static const struct regmap_config wm8750_regmap = {
 762        .reg_bits = 7,
 763        .val_bits = 9,
 764        .max_register = WM8750_MOUTV,
 765
 766        .reg_defaults = wm8750_reg_defaults,
 767        .num_reg_defaults = ARRAY_SIZE(wm8750_reg_defaults),
 768        .cache_type = REGCACHE_RBTREE,
 769};
 770
 771#if defined(CONFIG_SPI_MASTER)
 772static int wm8750_spi_probe(struct spi_device *spi)
 773{
 774        struct wm8750_priv *wm8750;
 775        struct regmap *regmap;
 776        int ret;
 777
 778        wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv),
 779                              GFP_KERNEL);
 780        if (wm8750 == NULL)
 781                return -ENOMEM;
 782
 783        regmap = devm_regmap_init_spi(spi, &wm8750_regmap);
 784        if (IS_ERR(regmap))
 785                return PTR_ERR(regmap);
 786
 787        spi_set_drvdata(spi, wm8750);
 788
 789        ret = snd_soc_register_codec(&spi->dev,
 790                        &soc_codec_dev_wm8750, &wm8750_dai, 1);
 791        return ret;
 792}
 793
 794static int wm8750_spi_remove(struct spi_device *spi)
 795{
 796        snd_soc_unregister_codec(&spi->dev);
 797        return 0;
 798}
 799
 800static const struct spi_device_id wm8750_spi_ids[] = {
 801        { "wm8750", 0 },
 802        { "wm8987", 0 },
 803        { },
 804};
 805MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
 806
 807static struct spi_driver wm8750_spi_driver = {
 808        .driver = {
 809                .name   = "wm8750",
 810                .owner  = THIS_MODULE,
 811                .of_match_table = wm8750_of_match,
 812        },
 813        .id_table       = wm8750_spi_ids,
 814        .probe          = wm8750_spi_probe,
 815        .remove         = wm8750_spi_remove,
 816};
 817#endif /* CONFIG_SPI_MASTER */
 818
 819#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 820static int wm8750_i2c_probe(struct i2c_client *i2c,
 821                            const struct i2c_device_id *id)
 822{
 823        struct wm8750_priv *wm8750;
 824        struct regmap *regmap;
 825        int ret;
 826
 827        wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv),
 828                              GFP_KERNEL);
 829        if (wm8750 == NULL)
 830                return -ENOMEM;
 831
 832        i2c_set_clientdata(i2c, wm8750);
 833
 834        regmap = devm_regmap_init_i2c(i2c, &wm8750_regmap);
 835        if (IS_ERR(regmap))
 836                return PTR_ERR(regmap);
 837
 838        ret =  snd_soc_register_codec(&i2c->dev,
 839                        &soc_codec_dev_wm8750, &wm8750_dai, 1);
 840        return ret;
 841}
 842
 843static int wm8750_i2c_remove(struct i2c_client *client)
 844{
 845        snd_soc_unregister_codec(&client->dev);
 846        return 0;
 847}
 848
 849static const struct i2c_device_id wm8750_i2c_id[] = {
 850        { "wm8750", 0 },
 851        { "wm8987", 0 },
 852        { }
 853};
 854MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
 855
 856static struct i2c_driver wm8750_i2c_driver = {
 857        .driver = {
 858                .name = "wm8750",
 859                .owner = THIS_MODULE,
 860                .of_match_table = wm8750_of_match,
 861        },
 862        .probe =    wm8750_i2c_probe,
 863        .remove =   wm8750_i2c_remove,
 864        .id_table = wm8750_i2c_id,
 865};
 866#endif
 867
 868static int __init wm8750_modinit(void)
 869{
 870        int ret = 0;
 871#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 872        ret = i2c_add_driver(&wm8750_i2c_driver);
 873        if (ret != 0) {
 874                printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
 875                       ret);
 876        }
 877#endif
 878#if defined(CONFIG_SPI_MASTER)
 879        ret = spi_register_driver(&wm8750_spi_driver);
 880        if (ret != 0) {
 881                printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
 882                       ret);
 883        }
 884#endif
 885        return ret;
 886}
 887module_init(wm8750_modinit);
 888
 889static void __exit wm8750_exit(void)
 890{
 891#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 892        i2c_del_driver(&wm8750_i2c_driver);
 893#endif
 894#if defined(CONFIG_SPI_MASTER)
 895        spi_unregister_driver(&wm8750_spi_driver);
 896#endif
 897}
 898module_exit(wm8750_exit);
 899
 900MODULE_DESCRIPTION("ASoC WM8750 driver");
 901MODULE_AUTHOR("Liam Girdwood");
 902MODULE_LICENSE("GPL");
 903