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