Linux Audio

Check our new training course

Loading...
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * wm2200.c  --  WM2200 ALSA SoC Audio driver
   4 *
   5 * Copyright 2012 Wolfson Microelectronics plc
   6 *
   7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
 
 
 
 
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/moduleparam.h>
  12#include <linux/init.h>
  13#include <linux/delay.h>
  14#include <linux/pm.h>
  15#include <linux/firmware.h>
  16#include <linux/gcd.h>
  17#include <linux/gpio/consumer.h>
  18#include <linux/i2c.h>
  19#include <linux/pm_runtime.h>
  20#include <linux/regulator/consumer.h>
  21#include <linux/regulator/fixed.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/soc.h>
  27#include <sound/jack.h>
  28#include <sound/initval.h>
  29#include <sound/tlv.h>
  30#include <sound/wm2200.h>
  31
  32#include "wm2200.h"
  33#include "wm_adsp.h"
  34
  35#define WM2200_DSP_CONTROL_1                   0x00
  36#define WM2200_DSP_CONTROL_2                   0x02
  37#define WM2200_DSP_CONTROL_3                   0x03
  38#define WM2200_DSP_CONTROL_4                   0x04
  39#define WM2200_DSP_CONTROL_5                   0x06
  40#define WM2200_DSP_CONTROL_6                   0x07
  41#define WM2200_DSP_CONTROL_7                   0x08
  42#define WM2200_DSP_CONTROL_8                   0x09
  43#define WM2200_DSP_CONTROL_9                   0x0A
  44#define WM2200_DSP_CONTROL_10                  0x0B
  45#define WM2200_DSP_CONTROL_11                  0x0C
  46#define WM2200_DSP_CONTROL_12                  0x0D
  47#define WM2200_DSP_CONTROL_13                  0x0F
  48#define WM2200_DSP_CONTROL_14                  0x10
  49#define WM2200_DSP_CONTROL_15                  0x11
  50#define WM2200_DSP_CONTROL_16                  0x12
  51#define WM2200_DSP_CONTROL_17                  0x13
  52#define WM2200_DSP_CONTROL_18                  0x14
  53#define WM2200_DSP_CONTROL_19                  0x16
  54#define WM2200_DSP_CONTROL_20                  0x17
  55#define WM2200_DSP_CONTROL_21                  0x18
  56#define WM2200_DSP_CONTROL_22                  0x1A
  57#define WM2200_DSP_CONTROL_23                  0x1B
  58#define WM2200_DSP_CONTROL_24                  0x1C
  59#define WM2200_DSP_CONTROL_25                  0x1E
  60#define WM2200_DSP_CONTROL_26                  0x20
  61#define WM2200_DSP_CONTROL_27                  0x21
  62#define WM2200_DSP_CONTROL_28                  0x22
  63#define WM2200_DSP_CONTROL_29                  0x23
  64#define WM2200_DSP_CONTROL_30                  0x24
  65#define WM2200_DSP_CONTROL_31                  0x26
  66
  67/* The code assumes DCVDD is generated internally */
  68#define WM2200_NUM_CORE_SUPPLIES 2
  69static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
  70	"DBVDD",
  71	"LDOVDD",
  72};
  73
 
 
 
 
 
 
 
  74/* codec private data */
  75struct wm2200_priv {
  76	struct wm_adsp dsp[2];
  77	struct regmap *regmap;
  78	struct device *dev;
  79	struct snd_soc_component *component;
  80	struct wm2200_pdata pdata;
  81	struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
  82	struct gpio_desc *ldo_ena;
  83	struct gpio_desc *reset;
  84
  85	struct completion fll_lock;
  86	int fll_fout;
  87	int fll_fref;
  88	int fll_src;
  89
  90	int rev;
  91	int sysclk;
  92
  93	unsigned int symmetric_rates:1;
  94};
  95
  96#define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1)
  97#define WM2200_DSP_SPACING 12288
  98
  99#define WM2200_DSP1_DM_BASE (WM2200_DSP_RANGE_BASE + (0 * WM2200_DSP_SPACING))
 100#define WM2200_DSP1_PM_BASE (WM2200_DSP_RANGE_BASE + (1 * WM2200_DSP_SPACING))
 101#define WM2200_DSP1_ZM_BASE (WM2200_DSP_RANGE_BASE + (2 * WM2200_DSP_SPACING))
 102#define WM2200_DSP2_DM_BASE (WM2200_DSP_RANGE_BASE + (3 * WM2200_DSP_SPACING))
 103#define WM2200_DSP2_PM_BASE (WM2200_DSP_RANGE_BASE + (4 * WM2200_DSP_SPACING))
 104#define WM2200_DSP2_ZM_BASE (WM2200_DSP_RANGE_BASE + (5 * WM2200_DSP_SPACING))
 105
 106static const struct regmap_range_cfg wm2200_ranges[] = {
 107	{ .name = "DSP1DM", .range_min = WM2200_DSP1_DM_BASE,
 108	  .range_max = WM2200_DSP1_DM_BASE + 12287,
 109	  .selector_reg = WM2200_DSP1_CONTROL_3,
 110	  .selector_mask = WM2200_DSP1_PAGE_BASE_DM_0_MASK,
 111	  .selector_shift = WM2200_DSP1_PAGE_BASE_DM_0_SHIFT,
 112	  .window_start = WM2200_DSP1_DM_0, .window_len = 2048, },
 113
 114	{ .name = "DSP1PM", .range_min = WM2200_DSP1_PM_BASE,
 115	  .range_max = WM2200_DSP1_PM_BASE + 12287,
 116	  .selector_reg = WM2200_DSP1_CONTROL_2,
 117	  .selector_mask = WM2200_DSP1_PAGE_BASE_PM_0_MASK,
 118	  .selector_shift = WM2200_DSP1_PAGE_BASE_PM_0_SHIFT,
 119	  .window_start = WM2200_DSP1_PM_0, .window_len = 768, },
 120
 121	{ .name = "DSP1ZM", .range_min = WM2200_DSP1_ZM_BASE,
 122	  .range_max = WM2200_DSP1_ZM_BASE + 2047,
 123	  .selector_reg = WM2200_DSP1_CONTROL_4,
 124	  .selector_mask = WM2200_DSP1_PAGE_BASE_ZM_0_MASK,
 125	  .selector_shift = WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT,
 126	  .window_start = WM2200_DSP1_ZM_0, .window_len = 1024, },
 127
 128	{ .name = "DSP2DM", .range_min = WM2200_DSP2_DM_BASE,
 129	  .range_max = WM2200_DSP2_DM_BASE + 4095,
 130	  .selector_reg = WM2200_DSP2_CONTROL_3,
 131	  .selector_mask = WM2200_DSP2_PAGE_BASE_DM_0_MASK,
 132	  .selector_shift = WM2200_DSP2_PAGE_BASE_DM_0_SHIFT,
 133	  .window_start = WM2200_DSP2_DM_0, .window_len = 2048, },
 134
 135	{ .name = "DSP2PM", .range_min = WM2200_DSP2_PM_BASE,
 136	  .range_max = WM2200_DSP2_PM_BASE + 11287,
 137	  .selector_reg = WM2200_DSP2_CONTROL_2,
 138	  .selector_mask = WM2200_DSP2_PAGE_BASE_PM_0_MASK,
 139	  .selector_shift = WM2200_DSP2_PAGE_BASE_PM_0_SHIFT,
 140	  .window_start = WM2200_DSP2_PM_0, .window_len = 768, },
 141
 142	{ .name = "DSP2ZM", .range_min = WM2200_DSP2_ZM_BASE,
 143	  .range_max = WM2200_DSP2_ZM_BASE + 2047,
 144	  .selector_reg = WM2200_DSP2_CONTROL_4,
 145	  .selector_mask = WM2200_DSP2_PAGE_BASE_ZM_0_MASK,
 146	  .selector_shift = WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT,
 147	  .window_start = WM2200_DSP2_ZM_0, .window_len = 1024, },
 148};
 149
 150static const struct cs_dsp_region wm2200_dsp1_regions[] = {
 151	{ .type = WMFW_ADSP1_PM, .base = WM2200_DSP1_PM_BASE },
 152	{ .type = WMFW_ADSP1_DM, .base = WM2200_DSP1_DM_BASE },
 153	{ .type = WMFW_ADSP1_ZM, .base = WM2200_DSP1_ZM_BASE },
 154};
 155
 156static const struct cs_dsp_region wm2200_dsp2_regions[] = {
 157	{ .type = WMFW_ADSP1_PM, .base = WM2200_DSP2_PM_BASE },
 158	{ .type = WMFW_ADSP1_DM, .base = WM2200_DSP2_DM_BASE },
 159	{ .type = WMFW_ADSP1_ZM, .base = WM2200_DSP2_ZM_BASE },
 160};
 161
 162static const struct reg_default wm2200_reg_defaults[] = {
 163	{ 0x000B, 0x0000 },   /* R11    - Tone Generator 1 */
 164	{ 0x0102, 0x0000 },   /* R258   - Clocking 3 */
 165	{ 0x0103, 0x0011 },   /* R259   - Clocking 4 */
 166	{ 0x0111, 0x0000 },   /* R273   - FLL Control 1 */
 167	{ 0x0112, 0x0000 },   /* R274   - FLL Control 2 */
 168	{ 0x0113, 0x0000 },   /* R275   - FLL Control 3 */
 169	{ 0x0114, 0x0000 },   /* R276   - FLL Control 4 */
 170	{ 0x0116, 0x0177 },   /* R278   - FLL Control 6 */
 171	{ 0x0117, 0x0004 },   /* R279   - FLL Control 7 */
 172	{ 0x0119, 0x0000 },   /* R281   - FLL EFS 1 */
 173	{ 0x011A, 0x0002 },   /* R282   - FLL EFS 2 */
 174	{ 0x0200, 0x0000 },   /* R512   - Mic Charge Pump 1 */
 175	{ 0x0201, 0x03FF },   /* R513   - Mic Charge Pump 2 */
 176	{ 0x0202, 0x9BDE },   /* R514   - DM Charge Pump 1 */
 177	{ 0x020C, 0x0000 },   /* R524   - Mic Bias Ctrl 1 */
 178	{ 0x020D, 0x0000 },   /* R525   - Mic Bias Ctrl 2 */
 179	{ 0x020F, 0x0000 },   /* R527   - Ear Piece Ctrl 1 */
 180	{ 0x0210, 0x0000 },   /* R528   - Ear Piece Ctrl 2 */
 181	{ 0x0301, 0x0000 },   /* R769   - Input Enables */
 182	{ 0x0302, 0x2240 },   /* R770   - IN1L Control */
 183	{ 0x0303, 0x0040 },   /* R771   - IN1R Control */
 184	{ 0x0304, 0x2240 },   /* R772   - IN2L Control */
 185	{ 0x0305, 0x0040 },   /* R773   - IN2R Control */
 186	{ 0x0306, 0x2240 },   /* R774   - IN3L Control */
 187	{ 0x0307, 0x0040 },   /* R775   - IN3R Control */
 188	{ 0x030A, 0x0000 },   /* R778   - RXANC_SRC */
 189	{ 0x030B, 0x0022 },   /* R779   - Input Volume Ramp */
 190	{ 0x030C, 0x0180 },   /* R780   - ADC Digital Volume 1L */
 191	{ 0x030D, 0x0180 },   /* R781   - ADC Digital Volume 1R */
 192	{ 0x030E, 0x0180 },   /* R782   - ADC Digital Volume 2L */
 193	{ 0x030F, 0x0180 },   /* R783   - ADC Digital Volume 2R */
 194	{ 0x0310, 0x0180 },   /* R784   - ADC Digital Volume 3L */
 195	{ 0x0311, 0x0180 },   /* R785   - ADC Digital Volume 3R */
 196	{ 0x0400, 0x0000 },   /* R1024  - Output Enables */
 197	{ 0x0401, 0x0000 },   /* R1025  - DAC Volume Limit 1L */
 198	{ 0x0402, 0x0000 },   /* R1026  - DAC Volume Limit 1R */
 199	{ 0x0403, 0x0000 },   /* R1027  - DAC Volume Limit 2L */
 200	{ 0x0404, 0x0000 },   /* R1028  - DAC Volume Limit 2R */
 201	{ 0x0409, 0x0000 },   /* R1033  - DAC AEC Control 1 */
 202	{ 0x040A, 0x0022 },   /* R1034  - Output Volume Ramp */
 203	{ 0x040B, 0x0180 },   /* R1035  - DAC Digital Volume 1L */
 204	{ 0x040C, 0x0180 },   /* R1036  - DAC Digital Volume 1R */
 205	{ 0x040D, 0x0180 },   /* R1037  - DAC Digital Volume 2L */
 206	{ 0x040E, 0x0180 },   /* R1038  - DAC Digital Volume 2R */
 207	{ 0x0417, 0x0069 },   /* R1047  - PDM 1 */
 208	{ 0x0418, 0x0000 },   /* R1048  - PDM 2 */
 209	{ 0x0500, 0x0000 },   /* R1280  - Audio IF 1_1 */
 210	{ 0x0501, 0x0008 },   /* R1281  - Audio IF 1_2 */
 211	{ 0x0502, 0x0000 },   /* R1282  - Audio IF 1_3 */
 212	{ 0x0503, 0x0000 },   /* R1283  - Audio IF 1_4 */
 213	{ 0x0504, 0x0000 },   /* R1284  - Audio IF 1_5 */
 214	{ 0x0505, 0x0001 },   /* R1285  - Audio IF 1_6 */
 215	{ 0x0506, 0x0001 },   /* R1286  - Audio IF 1_7 */
 216	{ 0x0507, 0x0000 },   /* R1287  - Audio IF 1_8 */
 217	{ 0x0508, 0x0000 },   /* R1288  - Audio IF 1_9 */
 218	{ 0x0509, 0x0000 },   /* R1289  - Audio IF 1_10 */
 219	{ 0x050A, 0x0000 },   /* R1290  - Audio IF 1_11 */
 220	{ 0x050B, 0x0000 },   /* R1291  - Audio IF 1_12 */
 221	{ 0x050C, 0x0000 },   /* R1292  - Audio IF 1_13 */
 222	{ 0x050D, 0x0000 },   /* R1293  - Audio IF 1_14 */
 223	{ 0x050E, 0x0000 },   /* R1294  - Audio IF 1_15 */
 224	{ 0x050F, 0x0000 },   /* R1295  - Audio IF 1_16 */
 225	{ 0x0510, 0x0000 },   /* R1296  - Audio IF 1_17 */
 226	{ 0x0511, 0x0000 },   /* R1297  - Audio IF 1_18 */
 227	{ 0x0512, 0x0000 },   /* R1298  - Audio IF 1_19 */
 228	{ 0x0513, 0x0000 },   /* R1299  - Audio IF 1_20 */
 229	{ 0x0514, 0x0000 },   /* R1300  - Audio IF 1_21 */
 230	{ 0x0515, 0x0001 },   /* R1301  - Audio IF 1_22 */
 231	{ 0x0600, 0x0000 },   /* R1536  - OUT1LMIX Input 1 Source */
 232	{ 0x0601, 0x0080 },   /* R1537  - OUT1LMIX Input 1 Volume */
 233	{ 0x0602, 0x0000 },   /* R1538  - OUT1LMIX Input 2 Source */
 234	{ 0x0603, 0x0080 },   /* R1539  - OUT1LMIX Input 2 Volume */
 235	{ 0x0604, 0x0000 },   /* R1540  - OUT1LMIX Input 3 Source */
 236	{ 0x0605, 0x0080 },   /* R1541  - OUT1LMIX Input 3 Volume */
 237	{ 0x0606, 0x0000 },   /* R1542  - OUT1LMIX Input 4 Source */
 238	{ 0x0607, 0x0080 },   /* R1543  - OUT1LMIX Input 4 Volume */
 239	{ 0x0608, 0x0000 },   /* R1544  - OUT1RMIX Input 1 Source */
 240	{ 0x0609, 0x0080 },   /* R1545  - OUT1RMIX Input 1 Volume */
 241	{ 0x060A, 0x0000 },   /* R1546  - OUT1RMIX Input 2 Source */
 242	{ 0x060B, 0x0080 },   /* R1547  - OUT1RMIX Input 2 Volume */
 243	{ 0x060C, 0x0000 },   /* R1548  - OUT1RMIX Input 3 Source */
 244	{ 0x060D, 0x0080 },   /* R1549  - OUT1RMIX Input 3 Volume */
 245	{ 0x060E, 0x0000 },   /* R1550  - OUT1RMIX Input 4 Source */
 246	{ 0x060F, 0x0080 },   /* R1551  - OUT1RMIX Input 4 Volume */
 247	{ 0x0610, 0x0000 },   /* R1552  - OUT2LMIX Input 1 Source */
 248	{ 0x0611, 0x0080 },   /* R1553  - OUT2LMIX Input 1 Volume */
 249	{ 0x0612, 0x0000 },   /* R1554  - OUT2LMIX Input 2 Source */
 250	{ 0x0613, 0x0080 },   /* R1555  - OUT2LMIX Input 2 Volume */
 251	{ 0x0614, 0x0000 },   /* R1556  - OUT2LMIX Input 3 Source */
 252	{ 0x0615, 0x0080 },   /* R1557  - OUT2LMIX Input 3 Volume */
 253	{ 0x0616, 0x0000 },   /* R1558  - OUT2LMIX Input 4 Source */
 254	{ 0x0617, 0x0080 },   /* R1559  - OUT2LMIX Input 4 Volume */
 255	{ 0x0618, 0x0000 },   /* R1560  - OUT2RMIX Input 1 Source */
 256	{ 0x0619, 0x0080 },   /* R1561  - OUT2RMIX Input 1 Volume */
 257	{ 0x061A, 0x0000 },   /* R1562  - OUT2RMIX Input 2 Source */
 258	{ 0x061B, 0x0080 },   /* R1563  - OUT2RMIX Input 2 Volume */
 259	{ 0x061C, 0x0000 },   /* R1564  - OUT2RMIX Input 3 Source */
 260	{ 0x061D, 0x0080 },   /* R1565  - OUT2RMIX Input 3 Volume */
 261	{ 0x061E, 0x0000 },   /* R1566  - OUT2RMIX Input 4 Source */
 262	{ 0x061F, 0x0080 },   /* R1567  - OUT2RMIX Input 4 Volume */
 263	{ 0x0620, 0x0000 },   /* R1568  - AIF1TX1MIX Input 1 Source */
 264	{ 0x0621, 0x0080 },   /* R1569  - AIF1TX1MIX Input 1 Volume */
 265	{ 0x0622, 0x0000 },   /* R1570  - AIF1TX1MIX Input 2 Source */
 266	{ 0x0623, 0x0080 },   /* R1571  - AIF1TX1MIX Input 2 Volume */
 267	{ 0x0624, 0x0000 },   /* R1572  - AIF1TX1MIX Input 3 Source */
 268	{ 0x0625, 0x0080 },   /* R1573  - AIF1TX1MIX Input 3 Volume */
 269	{ 0x0626, 0x0000 },   /* R1574  - AIF1TX1MIX Input 4 Source */
 270	{ 0x0627, 0x0080 },   /* R1575  - AIF1TX1MIX Input 4 Volume */
 271	{ 0x0628, 0x0000 },   /* R1576  - AIF1TX2MIX Input 1 Source */
 272	{ 0x0629, 0x0080 },   /* R1577  - AIF1TX2MIX Input 1 Volume */
 273	{ 0x062A, 0x0000 },   /* R1578  - AIF1TX2MIX Input 2 Source */
 274	{ 0x062B, 0x0080 },   /* R1579  - AIF1TX2MIX Input 2 Volume */
 275	{ 0x062C, 0x0000 },   /* R1580  - AIF1TX2MIX Input 3 Source */
 276	{ 0x062D, 0x0080 },   /* R1581  - AIF1TX2MIX Input 3 Volume */
 277	{ 0x062E, 0x0000 },   /* R1582  - AIF1TX2MIX Input 4 Source */
 278	{ 0x062F, 0x0080 },   /* R1583  - AIF1TX2MIX Input 4 Volume */
 279	{ 0x0630, 0x0000 },   /* R1584  - AIF1TX3MIX Input 1 Source */
 280	{ 0x0631, 0x0080 },   /* R1585  - AIF1TX3MIX Input 1 Volume */
 281	{ 0x0632, 0x0000 },   /* R1586  - AIF1TX3MIX Input 2 Source */
 282	{ 0x0633, 0x0080 },   /* R1587  - AIF1TX3MIX Input 2 Volume */
 283	{ 0x0634, 0x0000 },   /* R1588  - AIF1TX3MIX Input 3 Source */
 284	{ 0x0635, 0x0080 },   /* R1589  - AIF1TX3MIX Input 3 Volume */
 285	{ 0x0636, 0x0000 },   /* R1590  - AIF1TX3MIX Input 4 Source */
 286	{ 0x0637, 0x0080 },   /* R1591  - AIF1TX3MIX Input 4 Volume */
 287	{ 0x0638, 0x0000 },   /* R1592  - AIF1TX4MIX Input 1 Source */
 288	{ 0x0639, 0x0080 },   /* R1593  - AIF1TX4MIX Input 1 Volume */
 289	{ 0x063A, 0x0000 },   /* R1594  - AIF1TX4MIX Input 2 Source */
 290	{ 0x063B, 0x0080 },   /* R1595  - AIF1TX4MIX Input 2 Volume */
 291	{ 0x063C, 0x0000 },   /* R1596  - AIF1TX4MIX Input 3 Source */
 292	{ 0x063D, 0x0080 },   /* R1597  - AIF1TX4MIX Input 3 Volume */
 293	{ 0x063E, 0x0000 },   /* R1598  - AIF1TX4MIX Input 4 Source */
 294	{ 0x063F, 0x0080 },   /* R1599  - AIF1TX4MIX Input 4 Volume */
 295	{ 0x0640, 0x0000 },   /* R1600  - AIF1TX5MIX Input 1 Source */
 296	{ 0x0641, 0x0080 },   /* R1601  - AIF1TX5MIX Input 1 Volume */
 297	{ 0x0642, 0x0000 },   /* R1602  - AIF1TX5MIX Input 2 Source */
 298	{ 0x0643, 0x0080 },   /* R1603  - AIF1TX5MIX Input 2 Volume */
 299	{ 0x0644, 0x0000 },   /* R1604  - AIF1TX5MIX Input 3 Source */
 300	{ 0x0645, 0x0080 },   /* R1605  - AIF1TX5MIX Input 3 Volume */
 301	{ 0x0646, 0x0000 },   /* R1606  - AIF1TX5MIX Input 4 Source */
 302	{ 0x0647, 0x0080 },   /* R1607  - AIF1TX5MIX Input 4 Volume */
 303	{ 0x0648, 0x0000 },   /* R1608  - AIF1TX6MIX Input 1 Source */
 304	{ 0x0649, 0x0080 },   /* R1609  - AIF1TX6MIX Input 1 Volume */
 305	{ 0x064A, 0x0000 },   /* R1610  - AIF1TX6MIX Input 2 Source */
 306	{ 0x064B, 0x0080 },   /* R1611  - AIF1TX6MIX Input 2 Volume */
 307	{ 0x064C, 0x0000 },   /* R1612  - AIF1TX6MIX Input 3 Source */
 308	{ 0x064D, 0x0080 },   /* R1613  - AIF1TX6MIX Input 3 Volume */
 309	{ 0x064E, 0x0000 },   /* R1614  - AIF1TX6MIX Input 4 Source */
 310	{ 0x064F, 0x0080 },   /* R1615  - AIF1TX6MIX Input 4 Volume */
 311	{ 0x0650, 0x0000 },   /* R1616  - EQLMIX Input 1 Source */
 312	{ 0x0651, 0x0080 },   /* R1617  - EQLMIX Input 1 Volume */
 313	{ 0x0652, 0x0000 },   /* R1618  - EQLMIX Input 2 Source */
 314	{ 0x0653, 0x0080 },   /* R1619  - EQLMIX Input 2 Volume */
 315	{ 0x0654, 0x0000 },   /* R1620  - EQLMIX Input 3 Source */
 316	{ 0x0655, 0x0080 },   /* R1621  - EQLMIX Input 3 Volume */
 317	{ 0x0656, 0x0000 },   /* R1622  - EQLMIX Input 4 Source */
 318	{ 0x0657, 0x0080 },   /* R1623  - EQLMIX Input 4 Volume */
 319	{ 0x0658, 0x0000 },   /* R1624  - EQRMIX Input 1 Source */
 320	{ 0x0659, 0x0080 },   /* R1625  - EQRMIX Input 1 Volume */
 321	{ 0x065A, 0x0000 },   /* R1626  - EQRMIX Input 2 Source */
 322	{ 0x065B, 0x0080 },   /* R1627  - EQRMIX Input 2 Volume */
 323	{ 0x065C, 0x0000 },   /* R1628  - EQRMIX Input 3 Source */
 324	{ 0x065D, 0x0080 },   /* R1629  - EQRMIX Input 3 Volume */
 325	{ 0x065E, 0x0000 },   /* R1630  - EQRMIX Input 4 Source */
 326	{ 0x065F, 0x0080 },   /* R1631  - EQRMIX Input 4 Volume */
 327	{ 0x0660, 0x0000 },   /* R1632  - LHPF1MIX Input 1 Source */
 328	{ 0x0661, 0x0080 },   /* R1633  - LHPF1MIX Input 1 Volume */
 329	{ 0x0662, 0x0000 },   /* R1634  - LHPF1MIX Input 2 Source */
 330	{ 0x0663, 0x0080 },   /* R1635  - LHPF1MIX Input 2 Volume */
 331	{ 0x0664, 0x0000 },   /* R1636  - LHPF1MIX Input 3 Source */
 332	{ 0x0665, 0x0080 },   /* R1637  - LHPF1MIX Input 3 Volume */
 333	{ 0x0666, 0x0000 },   /* R1638  - LHPF1MIX Input 4 Source */
 334	{ 0x0667, 0x0080 },   /* R1639  - LHPF1MIX Input 4 Volume */
 335	{ 0x0668, 0x0000 },   /* R1640  - LHPF2MIX Input 1 Source */
 336	{ 0x0669, 0x0080 },   /* R1641  - LHPF2MIX Input 1 Volume */
 337	{ 0x066A, 0x0000 },   /* R1642  - LHPF2MIX Input 2 Source */
 338	{ 0x066B, 0x0080 },   /* R1643  - LHPF2MIX Input 2 Volume */
 339	{ 0x066C, 0x0000 },   /* R1644  - LHPF2MIX Input 3 Source */
 340	{ 0x066D, 0x0080 },   /* R1645  - LHPF2MIX Input 3 Volume */
 341	{ 0x066E, 0x0000 },   /* R1646  - LHPF2MIX Input 4 Source */
 342	{ 0x066F, 0x0080 },   /* R1647  - LHPF2MIX Input 4 Volume */
 343	{ 0x0670, 0x0000 },   /* R1648  - DSP1LMIX Input 1 Source */
 344	{ 0x0671, 0x0080 },   /* R1649  - DSP1LMIX Input 1 Volume */
 345	{ 0x0672, 0x0000 },   /* R1650  - DSP1LMIX Input 2 Source */
 346	{ 0x0673, 0x0080 },   /* R1651  - DSP1LMIX Input 2 Volume */
 347	{ 0x0674, 0x0000 },   /* R1652  - DSP1LMIX Input 3 Source */
 348	{ 0x0675, 0x0080 },   /* R1653  - DSP1LMIX Input 3 Volume */
 349	{ 0x0676, 0x0000 },   /* R1654  - DSP1LMIX Input 4 Source */
 350	{ 0x0677, 0x0080 },   /* R1655  - DSP1LMIX Input 4 Volume */
 351	{ 0x0678, 0x0000 },   /* R1656  - DSP1RMIX Input 1 Source */
 352	{ 0x0679, 0x0080 },   /* R1657  - DSP1RMIX Input 1 Volume */
 353	{ 0x067A, 0x0000 },   /* R1658  - DSP1RMIX Input 2 Source */
 354	{ 0x067B, 0x0080 },   /* R1659  - DSP1RMIX Input 2 Volume */
 355	{ 0x067C, 0x0000 },   /* R1660  - DSP1RMIX Input 3 Source */
 356	{ 0x067D, 0x0080 },   /* R1661  - DSP1RMIX Input 3 Volume */
 357	{ 0x067E, 0x0000 },   /* R1662  - DSP1RMIX Input 4 Source */
 358	{ 0x067F, 0x0080 },   /* R1663  - DSP1RMIX Input 4 Volume */
 359	{ 0x0680, 0x0000 },   /* R1664  - DSP1AUX1MIX Input 1 Source */
 360	{ 0x0681, 0x0000 },   /* R1665  - DSP1AUX2MIX Input 1 Source */
 361	{ 0x0682, 0x0000 },   /* R1666  - DSP1AUX3MIX Input 1 Source */
 362	{ 0x0683, 0x0000 },   /* R1667  - DSP1AUX4MIX Input 1 Source */
 363	{ 0x0684, 0x0000 },   /* R1668  - DSP1AUX5MIX Input 1 Source */
 364	{ 0x0685, 0x0000 },   /* R1669  - DSP1AUX6MIX Input 1 Source */
 365	{ 0x0686, 0x0000 },   /* R1670  - DSP2LMIX Input 1 Source */
 366	{ 0x0687, 0x0080 },   /* R1671  - DSP2LMIX Input 1 Volume */
 367	{ 0x0688, 0x0000 },   /* R1672  - DSP2LMIX Input 2 Source */
 368	{ 0x0689, 0x0080 },   /* R1673  - DSP2LMIX Input 2 Volume */
 369	{ 0x068A, 0x0000 },   /* R1674  - DSP2LMIX Input 3 Source */
 370	{ 0x068B, 0x0080 },   /* R1675  - DSP2LMIX Input 3 Volume */
 371	{ 0x068C, 0x0000 },   /* R1676  - DSP2LMIX Input 4 Source */
 372	{ 0x068D, 0x0080 },   /* R1677  - DSP2LMIX Input 4 Volume */
 373	{ 0x068E, 0x0000 },   /* R1678  - DSP2RMIX Input 1 Source */
 374	{ 0x068F, 0x0080 },   /* R1679  - DSP2RMIX Input 1 Volume */
 375	{ 0x0690, 0x0000 },   /* R1680  - DSP2RMIX Input 2 Source */
 376	{ 0x0691, 0x0080 },   /* R1681  - DSP2RMIX Input 2 Volume */
 377	{ 0x0692, 0x0000 },   /* R1682  - DSP2RMIX Input 3 Source */
 378	{ 0x0693, 0x0080 },   /* R1683  - DSP2RMIX Input 3 Volume */
 379	{ 0x0694, 0x0000 },   /* R1684  - DSP2RMIX Input 4 Source */
 380	{ 0x0695, 0x0080 },   /* R1685  - DSP2RMIX Input 4 Volume */
 381	{ 0x0696, 0x0000 },   /* R1686  - DSP2AUX1MIX Input 1 Source */
 382	{ 0x0697, 0x0000 },   /* R1687  - DSP2AUX2MIX Input 1 Source */
 383	{ 0x0698, 0x0000 },   /* R1688  - DSP2AUX3MIX Input 1 Source */
 384	{ 0x0699, 0x0000 },   /* R1689  - DSP2AUX4MIX Input 1 Source */
 385	{ 0x069A, 0x0000 },   /* R1690  - DSP2AUX5MIX Input 1 Source */
 386	{ 0x069B, 0x0000 },   /* R1691  - DSP2AUX6MIX Input 1 Source */
 387	{ 0x0700, 0xA101 },   /* R1792  - GPIO CTRL 1 */
 388	{ 0x0701, 0xA101 },   /* R1793  - GPIO CTRL 2 */
 389	{ 0x0702, 0xA101 },   /* R1794  - GPIO CTRL 3 */
 390	{ 0x0703, 0xA101 },   /* R1795  - GPIO CTRL 4 */
 391	{ 0x0709, 0x0000 },   /* R1801  - Misc Pad Ctrl 1 */
 392	{ 0x0801, 0x00FF },   /* R2049  - Interrupt Status 1 Mask */
 393	{ 0x0804, 0xFFFF },   /* R2052  - Interrupt Status 2 Mask */
 394	{ 0x0808, 0x0000 },   /* R2056  - Interrupt Control */
 395	{ 0x0900, 0x0000 },   /* R2304  - EQL_1 */
 396	{ 0x0901, 0x0000 },   /* R2305  - EQL_2 */
 397	{ 0x0902, 0x0000 },   /* R2306  - EQL_3 */
 398	{ 0x0903, 0x0000 },   /* R2307  - EQL_4 */
 399	{ 0x0904, 0x0000 },   /* R2308  - EQL_5 */
 400	{ 0x0905, 0x0000 },   /* R2309  - EQL_6 */
 401	{ 0x0906, 0x0000 },   /* R2310  - EQL_7 */
 402	{ 0x0907, 0x0000 },   /* R2311  - EQL_8 */
 403	{ 0x0908, 0x0000 },   /* R2312  - EQL_9 */
 404	{ 0x0909, 0x0000 },   /* R2313  - EQL_10 */
 405	{ 0x090A, 0x0000 },   /* R2314  - EQL_11 */
 406	{ 0x090B, 0x0000 },   /* R2315  - EQL_12 */
 407	{ 0x090C, 0x0000 },   /* R2316  - EQL_13 */
 408	{ 0x090D, 0x0000 },   /* R2317  - EQL_14 */
 409	{ 0x090E, 0x0000 },   /* R2318  - EQL_15 */
 410	{ 0x090F, 0x0000 },   /* R2319  - EQL_16 */
 411	{ 0x0910, 0x0000 },   /* R2320  - EQL_17 */
 412	{ 0x0911, 0x0000 },   /* R2321  - EQL_18 */
 413	{ 0x0912, 0x0000 },   /* R2322  - EQL_19 */
 414	{ 0x0913, 0x0000 },   /* R2323  - EQL_20 */
 415	{ 0x0916, 0x0000 },   /* R2326  - EQR_1 */
 416	{ 0x0917, 0x0000 },   /* R2327  - EQR_2 */
 417	{ 0x0918, 0x0000 },   /* R2328  - EQR_3 */
 418	{ 0x0919, 0x0000 },   /* R2329  - EQR_4 */
 419	{ 0x091A, 0x0000 },   /* R2330  - EQR_5 */
 420	{ 0x091B, 0x0000 },   /* R2331  - EQR_6 */
 421	{ 0x091C, 0x0000 },   /* R2332  - EQR_7 */
 422	{ 0x091D, 0x0000 },   /* R2333  - EQR_8 */
 423	{ 0x091E, 0x0000 },   /* R2334  - EQR_9 */
 424	{ 0x091F, 0x0000 },   /* R2335  - EQR_10 */
 425	{ 0x0920, 0x0000 },   /* R2336  - EQR_11 */
 426	{ 0x0921, 0x0000 },   /* R2337  - EQR_12 */
 427	{ 0x0922, 0x0000 },   /* R2338  - EQR_13 */
 428	{ 0x0923, 0x0000 },   /* R2339  - EQR_14 */
 429	{ 0x0924, 0x0000 },   /* R2340  - EQR_15 */
 430	{ 0x0925, 0x0000 },   /* R2341  - EQR_16 */
 431	{ 0x0926, 0x0000 },   /* R2342  - EQR_17 */
 432	{ 0x0927, 0x0000 },   /* R2343  - EQR_18 */
 433	{ 0x0928, 0x0000 },   /* R2344  - EQR_19 */
 434	{ 0x0929, 0x0000 },   /* R2345  - EQR_20 */
 435	{ 0x093E, 0x0000 },   /* R2366  - HPLPF1_1 */
 436	{ 0x093F, 0x0000 },   /* R2367  - HPLPF1_2 */
 437	{ 0x0942, 0x0000 },   /* R2370  - HPLPF2_1 */
 438	{ 0x0943, 0x0000 },   /* R2371  - HPLPF2_2 */
 439	{ 0x0A00, 0x0000 },   /* R2560  - DSP1 Control 1 */
 440	{ 0x0A02, 0x0000 },   /* R2562  - DSP1 Control 2 */
 441	{ 0x0A03, 0x0000 },   /* R2563  - DSP1 Control 3 */
 442	{ 0x0A04, 0x0000 },   /* R2564  - DSP1 Control 4 */
 443	{ 0x0A06, 0x0000 },   /* R2566  - DSP1 Control 5 */
 444	{ 0x0A07, 0x0000 },   /* R2567  - DSP1 Control 6 */
 445	{ 0x0A08, 0x0000 },   /* R2568  - DSP1 Control 7 */
 446	{ 0x0A09, 0x0000 },   /* R2569  - DSP1 Control 8 */
 447	{ 0x0A0A, 0x0000 },   /* R2570  - DSP1 Control 9 */
 448	{ 0x0A0B, 0x0000 },   /* R2571  - DSP1 Control 10 */
 449	{ 0x0A0C, 0x0000 },   /* R2572  - DSP1 Control 11 */
 450	{ 0x0A0D, 0x0000 },   /* R2573  - DSP1 Control 12 */
 451	{ 0x0A0F, 0x0000 },   /* R2575  - DSP1 Control 13 */
 452	{ 0x0A10, 0x0000 },   /* R2576  - DSP1 Control 14 */
 453	{ 0x0A11, 0x0000 },   /* R2577  - DSP1 Control 15 */
 454	{ 0x0A12, 0x0000 },   /* R2578  - DSP1 Control 16 */
 455	{ 0x0A13, 0x0000 },   /* R2579  - DSP1 Control 17 */
 456	{ 0x0A14, 0x0000 },   /* R2580  - DSP1 Control 18 */
 457	{ 0x0A16, 0x0000 },   /* R2582  - DSP1 Control 19 */
 458	{ 0x0A17, 0x0000 },   /* R2583  - DSP1 Control 20 */
 459	{ 0x0A18, 0x0000 },   /* R2584  - DSP1 Control 21 */
 460	{ 0x0A1A, 0x1800 },   /* R2586  - DSP1 Control 22 */
 461	{ 0x0A1B, 0x1000 },   /* R2587  - DSP1 Control 23 */
 462	{ 0x0A1C, 0x0400 },   /* R2588  - DSP1 Control 24 */
 463	{ 0x0A1E, 0x0000 },   /* R2590  - DSP1 Control 25 */
 464	{ 0x0A20, 0x0000 },   /* R2592  - DSP1 Control 26 */
 465	{ 0x0A21, 0x0000 },   /* R2593  - DSP1 Control 27 */
 466	{ 0x0A22, 0x0000 },   /* R2594  - DSP1 Control 28 */
 467	{ 0x0A23, 0x0000 },   /* R2595  - DSP1 Control 29 */
 468	{ 0x0A24, 0x0000 },   /* R2596  - DSP1 Control 30 */
 469	{ 0x0A26, 0x0000 },   /* R2598  - DSP1 Control 31 */
 470	{ 0x0B00, 0x0000 },   /* R2816  - DSP2 Control 1 */
 471	{ 0x0B02, 0x0000 },   /* R2818  - DSP2 Control 2 */
 472	{ 0x0B03, 0x0000 },   /* R2819  - DSP2 Control 3 */
 473	{ 0x0B04, 0x0000 },   /* R2820  - DSP2 Control 4 */
 474	{ 0x0B06, 0x0000 },   /* R2822  - DSP2 Control 5 */
 475	{ 0x0B07, 0x0000 },   /* R2823  - DSP2 Control 6 */
 476	{ 0x0B08, 0x0000 },   /* R2824  - DSP2 Control 7 */
 477	{ 0x0B09, 0x0000 },   /* R2825  - DSP2 Control 8 */
 478	{ 0x0B0A, 0x0000 },   /* R2826  - DSP2 Control 9 */
 479	{ 0x0B0B, 0x0000 },   /* R2827  - DSP2 Control 10 */
 480	{ 0x0B0C, 0x0000 },   /* R2828  - DSP2 Control 11 */
 481	{ 0x0B0D, 0x0000 },   /* R2829  - DSP2 Control 12 */
 482	{ 0x0B0F, 0x0000 },   /* R2831  - DSP2 Control 13 */
 483	{ 0x0B10, 0x0000 },   /* R2832  - DSP2 Control 14 */
 484	{ 0x0B11, 0x0000 },   /* R2833  - DSP2 Control 15 */
 485	{ 0x0B12, 0x0000 },   /* R2834  - DSP2 Control 16 */
 486	{ 0x0B13, 0x0000 },   /* R2835  - DSP2 Control 17 */
 487	{ 0x0B14, 0x0000 },   /* R2836  - DSP2 Control 18 */
 488	{ 0x0B16, 0x0000 },   /* R2838  - DSP2 Control 19 */
 489	{ 0x0B17, 0x0000 },   /* R2839  - DSP2 Control 20 */
 490	{ 0x0B18, 0x0000 },   /* R2840  - DSP2 Control 21 */
 491	{ 0x0B1A, 0x0800 },   /* R2842  - DSP2 Control 22 */
 492	{ 0x0B1B, 0x1000 },   /* R2843  - DSP2 Control 23 */
 493	{ 0x0B1C, 0x0400 },   /* R2844  - DSP2 Control 24 */
 494	{ 0x0B1E, 0x0000 },   /* R2846  - DSP2 Control 25 */
 495	{ 0x0B20, 0x0000 },   /* R2848  - DSP2 Control 26 */
 496	{ 0x0B21, 0x0000 },   /* R2849  - DSP2 Control 27 */
 497	{ 0x0B22, 0x0000 },   /* R2850  - DSP2 Control 28 */
 498	{ 0x0B23, 0x0000 },   /* R2851  - DSP2 Control 29 */
 499	{ 0x0B24, 0x0000 },   /* R2852  - DSP2 Control 30 */
 500	{ 0x0B26, 0x0000 },   /* R2854  - DSP2 Control 31 */
 501};
 502
 503static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
 504{
 505	int i;
 506
 507	for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++)
 508		if ((reg >= wm2200_ranges[i].window_start &&
 509		     reg <= wm2200_ranges[i].window_start +
 510		     wm2200_ranges[i].window_len) ||
 511		    (reg >= wm2200_ranges[i].range_min &&
 512		     reg <= wm2200_ranges[i].range_max))
 513			return true;
 514
 515	switch (reg) {
 516	case WM2200_SOFTWARE_RESET:
 517	case WM2200_DEVICE_REVISION:
 518	case WM2200_ADPS1_IRQ0:
 519	case WM2200_ADPS1_IRQ1:
 520	case WM2200_INTERRUPT_STATUS_1:
 521	case WM2200_INTERRUPT_STATUS_2:
 522	case WM2200_INTERRUPT_RAW_STATUS_2:
 523		return true;
 524	default:
 525		return false;
 526	}
 527}
 528
 529static bool wm2200_readable_register(struct device *dev, unsigned int reg)
 530{
 531	int i;
 532
 533	for (i = 0; i < ARRAY_SIZE(wm2200_ranges); i++)
 534		if ((reg >= wm2200_ranges[i].window_start &&
 535		     reg <= wm2200_ranges[i].window_start +
 536		     wm2200_ranges[i].window_len) ||
 537		    (reg >= wm2200_ranges[i].range_min &&
 538		     reg <= wm2200_ranges[i].range_max))
 539			return true;
 540
 541	switch (reg) {
 542	case WM2200_SOFTWARE_RESET:
 543	case WM2200_DEVICE_REVISION:
 544	case WM2200_TONE_GENERATOR_1:
 545	case WM2200_CLOCKING_3:
 546	case WM2200_CLOCKING_4:
 547	case WM2200_FLL_CONTROL_1:
 548	case WM2200_FLL_CONTROL_2:
 549	case WM2200_FLL_CONTROL_3:
 550	case WM2200_FLL_CONTROL_4:
 551	case WM2200_FLL_CONTROL_6:
 552	case WM2200_FLL_CONTROL_7:
 553	case WM2200_FLL_EFS_1:
 554	case WM2200_FLL_EFS_2:
 555	case WM2200_MIC_CHARGE_PUMP_1:
 556	case WM2200_MIC_CHARGE_PUMP_2:
 557	case WM2200_DM_CHARGE_PUMP_1:
 558	case WM2200_MIC_BIAS_CTRL_1:
 559	case WM2200_MIC_BIAS_CTRL_2:
 560	case WM2200_EAR_PIECE_CTRL_1:
 561	case WM2200_EAR_PIECE_CTRL_2:
 562	case WM2200_INPUT_ENABLES:
 563	case WM2200_IN1L_CONTROL:
 564	case WM2200_IN1R_CONTROL:
 565	case WM2200_IN2L_CONTROL:
 566	case WM2200_IN2R_CONTROL:
 567	case WM2200_IN3L_CONTROL:
 568	case WM2200_IN3R_CONTROL:
 569	case WM2200_RXANC_SRC:
 570	case WM2200_INPUT_VOLUME_RAMP:
 571	case WM2200_ADC_DIGITAL_VOLUME_1L:
 572	case WM2200_ADC_DIGITAL_VOLUME_1R:
 573	case WM2200_ADC_DIGITAL_VOLUME_2L:
 574	case WM2200_ADC_DIGITAL_VOLUME_2R:
 575	case WM2200_ADC_DIGITAL_VOLUME_3L:
 576	case WM2200_ADC_DIGITAL_VOLUME_3R:
 577	case WM2200_OUTPUT_ENABLES:
 578	case WM2200_DAC_VOLUME_LIMIT_1L:
 579	case WM2200_DAC_VOLUME_LIMIT_1R:
 580	case WM2200_DAC_VOLUME_LIMIT_2L:
 581	case WM2200_DAC_VOLUME_LIMIT_2R:
 582	case WM2200_DAC_AEC_CONTROL_1:
 583	case WM2200_OUTPUT_VOLUME_RAMP:
 584	case WM2200_DAC_DIGITAL_VOLUME_1L:
 585	case WM2200_DAC_DIGITAL_VOLUME_1R:
 586	case WM2200_DAC_DIGITAL_VOLUME_2L:
 587	case WM2200_DAC_DIGITAL_VOLUME_2R:
 588	case WM2200_PDM_1:
 589	case WM2200_PDM_2:
 590	case WM2200_AUDIO_IF_1_1:
 591	case WM2200_AUDIO_IF_1_2:
 592	case WM2200_AUDIO_IF_1_3:
 593	case WM2200_AUDIO_IF_1_4:
 594	case WM2200_AUDIO_IF_1_5:
 595	case WM2200_AUDIO_IF_1_6:
 596	case WM2200_AUDIO_IF_1_7:
 597	case WM2200_AUDIO_IF_1_8:
 598	case WM2200_AUDIO_IF_1_9:
 599	case WM2200_AUDIO_IF_1_10:
 600	case WM2200_AUDIO_IF_1_11:
 601	case WM2200_AUDIO_IF_1_12:
 602	case WM2200_AUDIO_IF_1_13:
 603	case WM2200_AUDIO_IF_1_14:
 604	case WM2200_AUDIO_IF_1_15:
 605	case WM2200_AUDIO_IF_1_16:
 606	case WM2200_AUDIO_IF_1_17:
 607	case WM2200_AUDIO_IF_1_18:
 608	case WM2200_AUDIO_IF_1_19:
 609	case WM2200_AUDIO_IF_1_20:
 610	case WM2200_AUDIO_IF_1_21:
 611	case WM2200_AUDIO_IF_1_22:
 612	case WM2200_OUT1LMIX_INPUT_1_SOURCE:
 613	case WM2200_OUT1LMIX_INPUT_1_VOLUME:
 614	case WM2200_OUT1LMIX_INPUT_2_SOURCE:
 615	case WM2200_OUT1LMIX_INPUT_2_VOLUME:
 616	case WM2200_OUT1LMIX_INPUT_3_SOURCE:
 617	case WM2200_OUT1LMIX_INPUT_3_VOLUME:
 618	case WM2200_OUT1LMIX_INPUT_4_SOURCE:
 619	case WM2200_OUT1LMIX_INPUT_4_VOLUME:
 620	case WM2200_OUT1RMIX_INPUT_1_SOURCE:
 621	case WM2200_OUT1RMIX_INPUT_1_VOLUME:
 622	case WM2200_OUT1RMIX_INPUT_2_SOURCE:
 623	case WM2200_OUT1RMIX_INPUT_2_VOLUME:
 624	case WM2200_OUT1RMIX_INPUT_3_SOURCE:
 625	case WM2200_OUT1RMIX_INPUT_3_VOLUME:
 626	case WM2200_OUT1RMIX_INPUT_4_SOURCE:
 627	case WM2200_OUT1RMIX_INPUT_4_VOLUME:
 628	case WM2200_OUT2LMIX_INPUT_1_SOURCE:
 629	case WM2200_OUT2LMIX_INPUT_1_VOLUME:
 630	case WM2200_OUT2LMIX_INPUT_2_SOURCE:
 631	case WM2200_OUT2LMIX_INPUT_2_VOLUME:
 632	case WM2200_OUT2LMIX_INPUT_3_SOURCE:
 633	case WM2200_OUT2LMIX_INPUT_3_VOLUME:
 634	case WM2200_OUT2LMIX_INPUT_4_SOURCE:
 635	case WM2200_OUT2LMIX_INPUT_4_VOLUME:
 636	case WM2200_OUT2RMIX_INPUT_1_SOURCE:
 637	case WM2200_OUT2RMIX_INPUT_1_VOLUME:
 638	case WM2200_OUT2RMIX_INPUT_2_SOURCE:
 639	case WM2200_OUT2RMIX_INPUT_2_VOLUME:
 640	case WM2200_OUT2RMIX_INPUT_3_SOURCE:
 641	case WM2200_OUT2RMIX_INPUT_3_VOLUME:
 642	case WM2200_OUT2RMIX_INPUT_4_SOURCE:
 643	case WM2200_OUT2RMIX_INPUT_4_VOLUME:
 644	case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
 645	case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
 646	case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
 647	case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
 648	case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
 649	case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
 650	case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
 651	case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
 652	case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
 653	case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
 654	case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
 655	case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
 656	case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
 657	case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
 658	case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
 659	case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
 660	case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
 661	case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
 662	case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
 663	case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
 664	case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
 665	case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
 666	case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
 667	case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
 668	case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
 669	case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
 670	case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
 671	case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
 672	case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
 673	case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
 674	case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
 675	case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
 676	case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
 677	case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
 678	case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
 679	case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
 680	case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
 681	case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
 682	case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
 683	case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
 684	case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
 685	case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
 686	case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
 687	case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
 688	case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
 689	case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
 690	case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
 691	case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
 692	case WM2200_EQLMIX_INPUT_1_SOURCE:
 693	case WM2200_EQLMIX_INPUT_1_VOLUME:
 694	case WM2200_EQLMIX_INPUT_2_SOURCE:
 695	case WM2200_EQLMIX_INPUT_2_VOLUME:
 696	case WM2200_EQLMIX_INPUT_3_SOURCE:
 697	case WM2200_EQLMIX_INPUT_3_VOLUME:
 698	case WM2200_EQLMIX_INPUT_4_SOURCE:
 699	case WM2200_EQLMIX_INPUT_4_VOLUME:
 700	case WM2200_EQRMIX_INPUT_1_SOURCE:
 701	case WM2200_EQRMIX_INPUT_1_VOLUME:
 702	case WM2200_EQRMIX_INPUT_2_SOURCE:
 703	case WM2200_EQRMIX_INPUT_2_VOLUME:
 704	case WM2200_EQRMIX_INPUT_3_SOURCE:
 705	case WM2200_EQRMIX_INPUT_3_VOLUME:
 706	case WM2200_EQRMIX_INPUT_4_SOURCE:
 707	case WM2200_EQRMIX_INPUT_4_VOLUME:
 708	case WM2200_LHPF1MIX_INPUT_1_SOURCE:
 709	case WM2200_LHPF1MIX_INPUT_1_VOLUME:
 710	case WM2200_LHPF1MIX_INPUT_2_SOURCE:
 711	case WM2200_LHPF1MIX_INPUT_2_VOLUME:
 712	case WM2200_LHPF1MIX_INPUT_3_SOURCE:
 713	case WM2200_LHPF1MIX_INPUT_3_VOLUME:
 714	case WM2200_LHPF1MIX_INPUT_4_SOURCE:
 715	case WM2200_LHPF1MIX_INPUT_4_VOLUME:
 716	case WM2200_LHPF2MIX_INPUT_1_SOURCE:
 717	case WM2200_LHPF2MIX_INPUT_1_VOLUME:
 718	case WM2200_LHPF2MIX_INPUT_2_SOURCE:
 719	case WM2200_LHPF2MIX_INPUT_2_VOLUME:
 720	case WM2200_LHPF2MIX_INPUT_3_SOURCE:
 721	case WM2200_LHPF2MIX_INPUT_3_VOLUME:
 722	case WM2200_LHPF2MIX_INPUT_4_SOURCE:
 723	case WM2200_LHPF2MIX_INPUT_4_VOLUME:
 724	case WM2200_DSP1LMIX_INPUT_1_SOURCE:
 725	case WM2200_DSP1LMIX_INPUT_1_VOLUME:
 726	case WM2200_DSP1LMIX_INPUT_2_SOURCE:
 727	case WM2200_DSP1LMIX_INPUT_2_VOLUME:
 728	case WM2200_DSP1LMIX_INPUT_3_SOURCE:
 729	case WM2200_DSP1LMIX_INPUT_3_VOLUME:
 730	case WM2200_DSP1LMIX_INPUT_4_SOURCE:
 731	case WM2200_DSP1LMIX_INPUT_4_VOLUME:
 732	case WM2200_DSP1RMIX_INPUT_1_SOURCE:
 733	case WM2200_DSP1RMIX_INPUT_1_VOLUME:
 734	case WM2200_DSP1RMIX_INPUT_2_SOURCE:
 735	case WM2200_DSP1RMIX_INPUT_2_VOLUME:
 736	case WM2200_DSP1RMIX_INPUT_3_SOURCE:
 737	case WM2200_DSP1RMIX_INPUT_3_VOLUME:
 738	case WM2200_DSP1RMIX_INPUT_4_SOURCE:
 739	case WM2200_DSP1RMIX_INPUT_4_VOLUME:
 740	case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
 741	case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
 742	case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
 743	case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
 744	case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
 745	case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
 746	case WM2200_DSP2LMIX_INPUT_1_SOURCE:
 747	case WM2200_DSP2LMIX_INPUT_1_VOLUME:
 748	case WM2200_DSP2LMIX_INPUT_2_SOURCE:
 749	case WM2200_DSP2LMIX_INPUT_2_VOLUME:
 750	case WM2200_DSP2LMIX_INPUT_3_SOURCE:
 751	case WM2200_DSP2LMIX_INPUT_3_VOLUME:
 752	case WM2200_DSP2LMIX_INPUT_4_SOURCE:
 753	case WM2200_DSP2LMIX_INPUT_4_VOLUME:
 754	case WM2200_DSP2RMIX_INPUT_1_SOURCE:
 755	case WM2200_DSP2RMIX_INPUT_1_VOLUME:
 756	case WM2200_DSP2RMIX_INPUT_2_SOURCE:
 757	case WM2200_DSP2RMIX_INPUT_2_VOLUME:
 758	case WM2200_DSP2RMIX_INPUT_3_SOURCE:
 759	case WM2200_DSP2RMIX_INPUT_3_VOLUME:
 760	case WM2200_DSP2RMIX_INPUT_4_SOURCE:
 761	case WM2200_DSP2RMIX_INPUT_4_VOLUME:
 762	case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
 763	case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
 764	case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
 765	case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
 766	case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
 767	case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
 768	case WM2200_GPIO_CTRL_1:
 769	case WM2200_GPIO_CTRL_2:
 770	case WM2200_GPIO_CTRL_3:
 771	case WM2200_GPIO_CTRL_4:
 772	case WM2200_ADPS1_IRQ0:
 773	case WM2200_ADPS1_IRQ1:
 774	case WM2200_MISC_PAD_CTRL_1:
 775	case WM2200_INTERRUPT_STATUS_1:
 776	case WM2200_INTERRUPT_STATUS_1_MASK:
 777	case WM2200_INTERRUPT_STATUS_2:
 778	case WM2200_INTERRUPT_RAW_STATUS_2:
 779	case WM2200_INTERRUPT_STATUS_2_MASK:
 780	case WM2200_INTERRUPT_CONTROL:
 781	case WM2200_EQL_1:
 782	case WM2200_EQL_2:
 783	case WM2200_EQL_3:
 784	case WM2200_EQL_4:
 785	case WM2200_EQL_5:
 786	case WM2200_EQL_6:
 787	case WM2200_EQL_7:
 788	case WM2200_EQL_8:
 789	case WM2200_EQL_9:
 790	case WM2200_EQL_10:
 791	case WM2200_EQL_11:
 792	case WM2200_EQL_12:
 793	case WM2200_EQL_13:
 794	case WM2200_EQL_14:
 795	case WM2200_EQL_15:
 796	case WM2200_EQL_16:
 797	case WM2200_EQL_17:
 798	case WM2200_EQL_18:
 799	case WM2200_EQL_19:
 800	case WM2200_EQL_20:
 801	case WM2200_EQR_1:
 802	case WM2200_EQR_2:
 803	case WM2200_EQR_3:
 804	case WM2200_EQR_4:
 805	case WM2200_EQR_5:
 806	case WM2200_EQR_6:
 807	case WM2200_EQR_7:
 808	case WM2200_EQR_8:
 809	case WM2200_EQR_9:
 810	case WM2200_EQR_10:
 811	case WM2200_EQR_11:
 812	case WM2200_EQR_12:
 813	case WM2200_EQR_13:
 814	case WM2200_EQR_14:
 815	case WM2200_EQR_15:
 816	case WM2200_EQR_16:
 817	case WM2200_EQR_17:
 818	case WM2200_EQR_18:
 819	case WM2200_EQR_19:
 820	case WM2200_EQR_20:
 821	case WM2200_HPLPF1_1:
 822	case WM2200_HPLPF1_2:
 823	case WM2200_HPLPF2_1:
 824	case WM2200_HPLPF2_2:
 825	case WM2200_DSP1_CONTROL_1:
 826	case WM2200_DSP1_CONTROL_2:
 827	case WM2200_DSP1_CONTROL_3:
 828	case WM2200_DSP1_CONTROL_4:
 829	case WM2200_DSP1_CONTROL_5:
 830	case WM2200_DSP1_CONTROL_6:
 831	case WM2200_DSP1_CONTROL_7:
 832	case WM2200_DSP1_CONTROL_8:
 833	case WM2200_DSP1_CONTROL_9:
 834	case WM2200_DSP1_CONTROL_10:
 835	case WM2200_DSP1_CONTROL_11:
 836	case WM2200_DSP1_CONTROL_12:
 837	case WM2200_DSP1_CONTROL_13:
 838	case WM2200_DSP1_CONTROL_14:
 839	case WM2200_DSP1_CONTROL_15:
 840	case WM2200_DSP1_CONTROL_16:
 841	case WM2200_DSP1_CONTROL_17:
 842	case WM2200_DSP1_CONTROL_18:
 843	case WM2200_DSP1_CONTROL_19:
 844	case WM2200_DSP1_CONTROL_20:
 845	case WM2200_DSP1_CONTROL_21:
 846	case WM2200_DSP1_CONTROL_22:
 847	case WM2200_DSP1_CONTROL_23:
 848	case WM2200_DSP1_CONTROL_24:
 849	case WM2200_DSP1_CONTROL_25:
 850	case WM2200_DSP1_CONTROL_26:
 851	case WM2200_DSP1_CONTROL_27:
 852	case WM2200_DSP1_CONTROL_28:
 853	case WM2200_DSP1_CONTROL_29:
 854	case WM2200_DSP1_CONTROL_30:
 855	case WM2200_DSP1_CONTROL_31:
 856	case WM2200_DSP2_CONTROL_1:
 857	case WM2200_DSP2_CONTROL_2:
 858	case WM2200_DSP2_CONTROL_3:
 859	case WM2200_DSP2_CONTROL_4:
 860	case WM2200_DSP2_CONTROL_5:
 861	case WM2200_DSP2_CONTROL_6:
 862	case WM2200_DSP2_CONTROL_7:
 863	case WM2200_DSP2_CONTROL_8:
 864	case WM2200_DSP2_CONTROL_9:
 865	case WM2200_DSP2_CONTROL_10:
 866	case WM2200_DSP2_CONTROL_11:
 867	case WM2200_DSP2_CONTROL_12:
 868	case WM2200_DSP2_CONTROL_13:
 869	case WM2200_DSP2_CONTROL_14:
 870	case WM2200_DSP2_CONTROL_15:
 871	case WM2200_DSP2_CONTROL_16:
 872	case WM2200_DSP2_CONTROL_17:
 873	case WM2200_DSP2_CONTROL_18:
 874	case WM2200_DSP2_CONTROL_19:
 875	case WM2200_DSP2_CONTROL_20:
 876	case WM2200_DSP2_CONTROL_21:
 877	case WM2200_DSP2_CONTROL_22:
 878	case WM2200_DSP2_CONTROL_23:
 879	case WM2200_DSP2_CONTROL_24:
 880	case WM2200_DSP2_CONTROL_25:
 881	case WM2200_DSP2_CONTROL_26:
 882	case WM2200_DSP2_CONTROL_27:
 883	case WM2200_DSP2_CONTROL_28:
 884	case WM2200_DSP2_CONTROL_29:
 885	case WM2200_DSP2_CONTROL_30:
 886	case WM2200_DSP2_CONTROL_31:
 887		return true;
 888	default:
 889		return false;
 890	}
 891}
 892
 893static const struct reg_sequence wm2200_reva_patch[] = {
 894	{ 0x07, 0x0003 },
 895	{ 0x102, 0x0200 },
 896	{ 0x203, 0x0084 },
 897	{ 0x201, 0x83FF },
 898	{ 0x20C, 0x0062 },
 899	{ 0x20D, 0x0062 },
 900	{ 0x207, 0x2002 },
 901	{ 0x208, 0x20C0 },
 902	{ 0x21D, 0x01C0 },
 903	{ 0x50A, 0x0001 },
 904	{ 0x50B, 0x0002 },
 905	{ 0x50C, 0x0003 },
 906	{ 0x50D, 0x0004 },
 907	{ 0x50E, 0x0005 },
 908	{ 0x510, 0x0001 },
 909	{ 0x511, 0x0002 },
 910	{ 0x512, 0x0003 },
 911	{ 0x513, 0x0004 },
 912	{ 0x514, 0x0005 },
 913	{ 0x515, 0x0000 },
 914	{ 0x201, 0x8084 },
 915	{ 0x202, 0xBBDE },
 916	{ 0x203, 0x00EC },
 917	{ 0x500, 0x8000 },
 918	{ 0x507, 0x1820 },
 919	{ 0x508, 0x1820 },
 920	{ 0x505, 0x0300 },
 921	{ 0x506, 0x0300 },
 922	{ 0x302, 0x2280 },
 923	{ 0x303, 0x0080 },
 924	{ 0x304, 0x2280 },
 925	{ 0x305, 0x0080 },
 926	{ 0x306, 0x2280 },
 927	{ 0x307, 0x0080 },
 928	{ 0x401, 0x0080 },
 929	{ 0x402, 0x0080 },
 930	{ 0x417, 0x3069 },
 931	{ 0x900, 0x6318 },
 932	{ 0x901, 0x6300 },
 933	{ 0x902, 0x0FC8 },
 934	{ 0x903, 0x03FE },
 935	{ 0x904, 0x00E0 },
 936	{ 0x905, 0x1EC4 },
 937	{ 0x906, 0xF136 },
 938	{ 0x907, 0x0409 },
 939	{ 0x908, 0x04CC },
 940	{ 0x909, 0x1C9B },
 941	{ 0x90A, 0xF337 },
 942	{ 0x90B, 0x040B },
 943	{ 0x90C, 0x0CBB },
 944	{ 0x90D, 0x16F8 },
 945	{ 0x90E, 0xF7D9 },
 946	{ 0x90F, 0x040A },
 947	{ 0x910, 0x1F14 },
 948	{ 0x911, 0x058C },
 949	{ 0x912, 0x0563 },
 950	{ 0x913, 0x4000 },
 951	{ 0x916, 0x6318 },
 952	{ 0x917, 0x6300 },
 953	{ 0x918, 0x0FC8 },
 954	{ 0x919, 0x03FE },
 955	{ 0x91A, 0x00E0 },
 956	{ 0x91B, 0x1EC4 },
 957	{ 0x91C, 0xF136 },
 958	{ 0x91D, 0x0409 },
 959	{ 0x91E, 0x04CC },
 960	{ 0x91F, 0x1C9B },
 961	{ 0x920, 0xF337 },
 962	{ 0x921, 0x040B },
 963	{ 0x922, 0x0CBB },
 964	{ 0x923, 0x16F8 },
 965	{ 0x924, 0xF7D9 },
 966	{ 0x925, 0x040A },
 967	{ 0x926, 0x1F14 },
 968	{ 0x927, 0x058C },
 969	{ 0x928, 0x0563 },
 970	{ 0x929, 0x4000 },
 971	{ 0x709, 0x2000 },
 972	{ 0x207, 0x200E },
 973	{ 0x208, 0x20D4 },
 974	{ 0x20A, 0x0080 },
 975	{ 0x07, 0x0000 },
 976};
 977
 978static int wm2200_reset(struct wm2200_priv *wm2200)
 979{
 980	if (wm2200->reset) {
 981		/* Descriptor flagged active low, so this will be inverted */
 982		gpiod_set_value_cansleep(wm2200->reset, 1);
 983		gpiod_set_value_cansleep(wm2200->reset, 0);
 984
 985		return 0;
 986	} else {
 987		return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
 988				    0x2200);
 989	}
 990}
 991
 992static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
 993static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
 994static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
 995
 996static const char * const wm2200_mixer_texts[] = {
 997	"None",
 998	"Tone Generator",
 999	"AEC Loopback",
1000	"IN1L",
1001	"IN1R",
1002	"IN2L",
1003	"IN2R",
1004	"IN3L",
1005	"IN3R",
1006	"AIF1RX1",
1007	"AIF1RX2",
1008	"AIF1RX3",
1009	"AIF1RX4",
1010	"AIF1RX5",
1011	"AIF1RX6",
1012	"EQL",
1013	"EQR",
1014	"LHPF1",
1015	"LHPF2",
 
 
1016	"DSP1.1",
1017	"DSP1.2",
1018	"DSP1.3",
1019	"DSP1.4",
1020	"DSP1.5",
1021	"DSP1.6",
1022	"DSP2.1",
1023	"DSP2.2",
1024	"DSP2.3",
1025	"DSP2.4",
1026	"DSP2.5",
1027	"DSP2.6",
1028};
1029
1030static unsigned int wm2200_mixer_values[] = {
1031	0x00,
1032	0x04,   /* Tone */
1033	0x08,   /* AEC */
1034	0x10,   /* Input */
1035	0x11,
1036	0x12,
1037	0x13,
1038	0x14,
1039	0x15,
1040	0x20,   /* AIF */
1041	0x21,
1042	0x22,
1043	0x23,
1044	0x24,
1045	0x25,
1046	0x50,   /* EQ */
1047	0x51,
 
1048	0x60,   /* LHPF1 */
1049	0x61,   /* LHPF2 */
1050	0x68,   /* DSP1 */
1051	0x69,
1052	0x6a,
1053	0x6b,
1054	0x6c,
1055	0x6d,
1056	0x70,   /* DSP2 */
1057	0x71,
1058	0x72,
1059	0x73,
1060	0x74,
1061	0x75,
1062};
1063
1064#define WM2200_MIXER_CONTROLS(name, base) \
1065	SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
1066		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
1067	SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
1068		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
1069	SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
1070		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
1071	SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
1072		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
1073
1074#define WM2200_MUX_ENUM_DECL(name, reg) \
1075	SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, 			\
1076				   wm2200_mixer_texts, wm2200_mixer_values)
1077
1078#define WM2200_MUX_CTL_DECL(name) \
1079	const struct snd_kcontrol_new name##_mux =	\
1080		SOC_DAPM_ENUM("Route", name##_enum)
1081
1082#define WM2200_MIXER_ENUMS(name, base_reg) \
1083	static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg);	     \
1084	static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2);  \
1085	static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4);  \
1086	static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6);  \
1087	static WM2200_MUX_CTL_DECL(name##_in1); \
1088	static WM2200_MUX_CTL_DECL(name##_in2); \
1089	static WM2200_MUX_CTL_DECL(name##_in3); \
1090	static WM2200_MUX_CTL_DECL(name##_in4)
1091
1092#define WM2200_DSP_ENUMS(name, base_reg) \
1093	static WM2200_MUX_ENUM_DECL(name##_aux1_enum, base_reg);     \
1094	static WM2200_MUX_ENUM_DECL(name##_aux2_enum, base_reg + 1); \
1095	static WM2200_MUX_ENUM_DECL(name##_aux3_enum, base_reg + 2); \
1096	static WM2200_MUX_ENUM_DECL(name##_aux4_enum, base_reg + 3); \
1097	static WM2200_MUX_ENUM_DECL(name##_aux5_enum, base_reg + 4); \
1098	static WM2200_MUX_ENUM_DECL(name##_aux6_enum, base_reg + 5); \
1099	static WM2200_MUX_CTL_DECL(name##_aux1); \
1100	static WM2200_MUX_CTL_DECL(name##_aux2); \
1101	static WM2200_MUX_CTL_DECL(name##_aux3); \
1102	static WM2200_MUX_CTL_DECL(name##_aux4); \
1103	static WM2200_MUX_CTL_DECL(name##_aux5); \
1104	static WM2200_MUX_CTL_DECL(name##_aux6);
1105
1106static const char *wm2200_rxanc_input_sel_texts[] = {
1107	"None", "IN1", "IN2", "IN3",
1108};
1109
1110static SOC_ENUM_SINGLE_DECL(wm2200_rxanc_input_sel,
1111			    WM2200_RXANC_SRC,
1112			    WM2200_IN_RXANC_SEL_SHIFT,
1113			    wm2200_rxanc_input_sel_texts);
1114
1115static const struct snd_kcontrol_new wm2200_snd_controls[] = {
1116SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
1117	   WM2200_IN1_OSR_SHIFT, 1, 0),
1118SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
1119	   WM2200_IN2_OSR_SHIFT, 1, 0),
1120SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
1121	   WM2200_IN3_OSR_SHIFT, 1, 0),
1122
1123SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
1124		 WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
1125SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
1126		 WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
1127SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
1128		 WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
1129
1130SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
1131	     WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
1132SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_2L,
1133	     WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
1134SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_3L,
1135	     WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
1136
1137SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
1138		 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
1139		 0xbf, 0, digital_tlv),
1140SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
1141		 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
1142		 0xbf, 0, digital_tlv),
1143SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1144		 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
1145		 0xbf, 0, digital_tlv),
1146
1147SND_SOC_BYTES_MASK("EQL Coefficients", WM2200_EQL_1, 20, WM2200_EQL_ENA),
1148SND_SOC_BYTES_MASK("EQR Coefficients", WM2200_EQR_1, 20, WM2200_EQR_ENA),
1149
1150SND_SOC_BYTES("LHPF1 Coefficients", WM2200_HPLPF1_2, 1),
1151SND_SOC_BYTES("LHPF2 Coefficients", WM2200_HPLPF2_2, 1),
1152
1153SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1154	   WM2200_OUT1_OSR_SHIFT, 1, 0),
1155SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1156	   WM2200_OUT2_OSR_SHIFT, 1, 0),
1157
1158SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1159	     WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
1160SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
1161		 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
1162		 digital_tlv),
1163SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
1164		 WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
1165		 0x46, 0, out_tlv),
1166
1167SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1168	     WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
1169SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
1170		 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
1171		 digital_tlv),
1172SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
1173	   WM2200_SPK1R_MUTE_SHIFT, 1, 1),
1174SOC_ENUM("RxANC Src", wm2200_rxanc_input_sel),
1175
1176WM_ADSP_FW_CONTROL("DSP1", 0),
1177WM_ADSP_FW_CONTROL("DSP2", 1),
1178};
1179
1180WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
1181WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
1182WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
1183WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
1184
1185WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
1186WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
1187WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
1188WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
1189WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
1190WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
1191
1192WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
1193WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
1194
1195WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
1196WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
1197WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
1198WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
1199
1200WM2200_DSP_ENUMS(DSP1, WM2200_DSP1AUX1MIX_INPUT_1_SOURCE);
1201WM2200_DSP_ENUMS(DSP2, WM2200_DSP2AUX1MIX_INPUT_1_SOURCE);
1202
1203WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
1204WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
1205
1206#define WM2200_MUX(name, ctrl) \
1207	SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
1208
1209#define WM2200_MIXER_WIDGETS(name, name_str)	\
1210	WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
1211	WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
1212	WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
1213	WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
1214	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
1215
1216#define WM2200_DSP_WIDGETS(name, name_str) \
1217	WM2200_MIXER_WIDGETS(name##L, name_str "L"), \
1218	WM2200_MIXER_WIDGETS(name##R, name_str "R"), \
1219	WM2200_MUX(name_str " Aux 1", &name##_aux1_mux), \
1220	WM2200_MUX(name_str " Aux 2", &name##_aux2_mux), \
1221	WM2200_MUX(name_str " Aux 3", &name##_aux3_mux), \
1222	WM2200_MUX(name_str " Aux 4", &name##_aux4_mux), \
1223	WM2200_MUX(name_str " Aux 5", &name##_aux5_mux), \
1224	WM2200_MUX(name_str " Aux 6", &name##_aux6_mux)
1225
1226#define WM2200_MIXER_INPUT_ROUTES(name)	\
1227	{ name, "Tone Generator", "Tone Generator" }, \
1228	{ name, "AEC Loopback", "AEC Loopback" }, \
1229        { name, "IN1L", "IN1L PGA" }, \
1230        { name, "IN1R", "IN1R PGA" }, \
1231        { name, "IN2L", "IN2L PGA" }, \
1232        { name, "IN2R", "IN2R PGA" }, \
1233        { name, "IN3L", "IN3L PGA" }, \
1234        { name, "IN3R", "IN3R PGA" }, \
1235        { name, "DSP1.1", "DSP1" }, \
1236        { name, "DSP1.2", "DSP1" }, \
1237        { name, "DSP1.3", "DSP1" }, \
1238        { name, "DSP1.4", "DSP1" }, \
1239        { name, "DSP1.5", "DSP1" }, \
1240        { name, "DSP1.6", "DSP1" }, \
1241        { name, "DSP2.1", "DSP2" }, \
1242        { name, "DSP2.2", "DSP2" }, \
1243        { name, "DSP2.3", "DSP2" }, \
1244        { name, "DSP2.4", "DSP2" }, \
1245        { name, "DSP2.5", "DSP2" }, \
1246        { name, "DSP2.6", "DSP2" }, \
1247        { name, "AIF1RX1", "AIF1RX1" }, \
1248        { name, "AIF1RX2", "AIF1RX2" }, \
1249        { name, "AIF1RX3", "AIF1RX3" }, \
1250        { name, "AIF1RX4", "AIF1RX4" }, \
1251        { name, "AIF1RX5", "AIF1RX5" }, \
1252        { name, "AIF1RX6", "AIF1RX6" }, \
1253        { name, "EQL", "EQL" }, \
1254        { name, "EQR", "EQR" }, \
1255        { name, "LHPF1", "LHPF1" }, \
1256        { name, "LHPF2", "LHPF2" }
1257
1258#define WM2200_MIXER_ROUTES(widget, name) \
1259	{ widget, NULL, name " Mixer" },         \
1260	{ name " Mixer", NULL, name " Input 1" }, \
1261	{ name " Mixer", NULL, name " Input 2" }, \
1262	{ name " Mixer", NULL, name " Input 3" }, \
1263	{ name " Mixer", NULL, name " Input 4" }, \
1264	WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
1265	WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
1266	WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
1267	WM2200_MIXER_INPUT_ROUTES(name " Input 4")
1268
1269#define WM2200_DSP_AUX_ROUTES(name) \
1270	{ name, NULL, name " Aux 1" }, \
1271	{ name, NULL, name " Aux 2" }, \
1272	{ name, NULL, name " Aux 3" }, \
1273	{ name, NULL, name " Aux 4" }, \
1274	{ name, NULL, name " Aux 5" }, \
1275	{ name, NULL, name " Aux 6" }, \
1276	WM2200_MIXER_INPUT_ROUTES(name " Aux 1"), \
1277	WM2200_MIXER_INPUT_ROUTES(name " Aux 2"), \
1278	WM2200_MIXER_INPUT_ROUTES(name " Aux 3"), \
1279	WM2200_MIXER_INPUT_ROUTES(name " Aux 4"), \
1280	WM2200_MIXER_INPUT_ROUTES(name " Aux 5"), \
1281	WM2200_MIXER_INPUT_ROUTES(name " Aux 6")
1282
1283static const char *wm2200_aec_loopback_texts[] = {
1284	"OUT1L", "OUT1R", "OUT2L", "OUT2R",
1285};
1286
1287static SOC_ENUM_SINGLE_DECL(wm2200_aec_loopback,
1288			    WM2200_DAC_AEC_CONTROL_1,
1289			    WM2200_AEC_LOOPBACK_SRC_SHIFT,
1290			    wm2200_aec_loopback_texts);
1291
1292static const struct snd_kcontrol_new wm2200_aec_loopback_mux =
1293	SOC_DAPM_ENUM("AEC Loopback", wm2200_aec_loopback);
1294
1295static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
1296SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
1297		    NULL, 0),
1298SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
1299		    NULL, 0),
1300SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
1301		    NULL, 0),
1302SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
1303		    0, NULL, 0),
1304SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
1305		    0, NULL, 0),
1306SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
1307SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20, 0),
1308
1309SND_SOC_DAPM_INPUT("IN1L"),
1310SND_SOC_DAPM_INPUT("IN1R"),
1311SND_SOC_DAPM_INPUT("IN2L"),
1312SND_SOC_DAPM_INPUT("IN2R"),
1313SND_SOC_DAPM_INPUT("IN3L"),
1314SND_SOC_DAPM_INPUT("IN3R"),
1315
1316SND_SOC_DAPM_SIGGEN("TONE"),
1317SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
1318		 WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
1319
1320SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
1321		 NULL, 0),
1322SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
1323		 NULL, 0),
1324SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
1325		 NULL, 0),
1326SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
1327		 NULL, 0),
1328SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
1329		 NULL, 0),
1330SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
1331		 NULL, 0),
1332
1333SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
1334		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
1335SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
1336		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
1337SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
1338		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
1339SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
1340		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
1341SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
1342		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
1343SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
1344		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
1345
1346SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
1347SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
1348
1349SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
1350		 NULL, 0),
1351SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
1352		 NULL, 0),
1353
1354WM_ADSP1("DSP1", 0),
1355WM_ADSP1("DSP2", 1),
1356
1357SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
1358		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
1359SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
1360		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
1361SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
1362		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
1363SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
1364		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
1365SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
1366		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
1367SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
1368		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
1369
1370SND_SOC_DAPM_MUX("AEC Loopback", WM2200_DAC_AEC_CONTROL_1,
1371		 WM2200_AEC_LOOPBACK_ENA_SHIFT, 0, &wm2200_aec_loopback_mux),
1372
1373SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
1374		   WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
1375SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
1376		   WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
1377
1378SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1379		   WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
1380SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1381		   WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
1382SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1383		   WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
1384
1385SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1386		   WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
1387SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1388		   WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
1389SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1390		   WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
1391
1392SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1393		   WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
1394SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1395		   WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
1396SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1397		   WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
1398
1399SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1400		   WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
1401SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1402		   WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
1403SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1404		   WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
1405
1406SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
1407		 0, NULL, 0),
1408SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
1409		 0, NULL, 0),
1410
1411SND_SOC_DAPM_OUTPUT("EPOUTLN"),
1412SND_SOC_DAPM_OUTPUT("EPOUTLP"),
1413SND_SOC_DAPM_OUTPUT("EPOUTRN"),
1414SND_SOC_DAPM_OUTPUT("EPOUTRP"),
1415SND_SOC_DAPM_OUTPUT("SPK"),
1416
1417WM2200_MIXER_WIDGETS(EQL, "EQL"),
1418WM2200_MIXER_WIDGETS(EQR, "EQR"),
1419
1420WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
1421WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
1422
1423WM2200_DSP_WIDGETS(DSP1, "DSP1"),
1424WM2200_DSP_WIDGETS(DSP2, "DSP2"),
 
 
1425
1426WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1427WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1428WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1429WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1430WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1431WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1432
1433WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
1434WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
1435WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
1436WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
1437};
1438
1439static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
1440	/* Everything needs SYSCLK but only hook up things on the edge
1441	 * of the chip */
1442	{ "IN1L", NULL, "SYSCLK" },
1443	{ "IN1R", NULL, "SYSCLK" },
1444	{ "IN2L", NULL, "SYSCLK" },
1445	{ "IN2R", NULL, "SYSCLK" },
1446	{ "IN3L", NULL, "SYSCLK" },
1447	{ "IN3R", NULL, "SYSCLK" },
1448	{ "OUT1L", NULL, "SYSCLK" },
1449	{ "OUT1R", NULL, "SYSCLK" },
1450	{ "OUT2L", NULL, "SYSCLK" },
1451	{ "OUT2R", NULL, "SYSCLK" },
1452	{ "AIF1RX1", NULL, "SYSCLK" },
1453	{ "AIF1RX2", NULL, "SYSCLK" },
1454	{ "AIF1RX3", NULL, "SYSCLK" },
1455	{ "AIF1RX4", NULL, "SYSCLK" },
1456	{ "AIF1RX5", NULL, "SYSCLK" },
1457	{ "AIF1RX6", NULL, "SYSCLK" },
1458	{ "AIF1TX1", NULL, "SYSCLK" },
1459	{ "AIF1TX2", NULL, "SYSCLK" },
1460	{ "AIF1TX3", NULL, "SYSCLK" },
1461	{ "AIF1TX4", NULL, "SYSCLK" },
1462	{ "AIF1TX5", NULL, "SYSCLK" },
1463	{ "AIF1TX6", NULL, "SYSCLK" },
1464
1465	{ "IN1L", NULL, "AVDD" },
1466	{ "IN1R", NULL, "AVDD" },
1467	{ "IN2L", NULL, "AVDD" },
1468	{ "IN2R", NULL, "AVDD" },
1469	{ "IN3L", NULL, "AVDD" },
1470	{ "IN3R", NULL, "AVDD" },
1471	{ "OUT1L", NULL, "AVDD" },
1472	{ "OUT1R", NULL, "AVDD" },
1473
1474	{ "IN1L PGA", NULL, "IN1L" },
1475	{ "IN1R PGA", NULL, "IN1R" },
1476	{ "IN2L PGA", NULL, "IN2L" },
1477	{ "IN2R PGA", NULL, "IN2R" },
1478	{ "IN3L PGA", NULL, "IN3L" },
1479	{ "IN3R PGA", NULL, "IN3R" },
1480
1481	{ "Tone Generator", NULL, "TONE" },
1482
1483	{ "CP2", NULL, "CPVDD" },
1484	{ "MICBIAS1", NULL, "CP2" },
1485	{ "MICBIAS2", NULL, "CP2" },
1486
1487	{ "CP1", NULL, "CPVDD" },
1488	{ "EPD_LN", NULL, "CP1" },
1489	{ "EPD_LP", NULL, "CP1" },
1490	{ "EPD_RN", NULL, "CP1" },
1491	{ "EPD_RP", NULL, "CP1" },
1492
1493	{ "EPD_LP", NULL, "OUT1L" },
1494	{ "EPD_OUTP_LP", NULL, "EPD_LP" },
1495	{ "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
1496	{ "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
1497
1498	{ "EPD_LN", NULL, "OUT1L" },
1499	{ "EPD_OUTP_LN", NULL, "EPD_LN" },
1500	{ "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
1501	{ "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
1502
1503	{ "EPD_RP", NULL, "OUT1R" },
1504	{ "EPD_OUTP_RP", NULL, "EPD_RP" },
1505	{ "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
1506	{ "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
1507
1508	{ "EPD_RN", NULL, "OUT1R" },
1509	{ "EPD_OUTP_RN", NULL, "EPD_RN" },
1510	{ "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
1511	{ "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
1512
1513	{ "SPK", NULL, "OUT2L" },
1514	{ "SPK", NULL, "OUT2R" },
1515
1516	{ "AEC Loopback", "OUT1L", "OUT1L" },
1517	{ "AEC Loopback", "OUT1R", "OUT1R" },
1518	{ "AEC Loopback", "OUT2L", "OUT2L" },
1519	{ "AEC Loopback", "OUT2R", "OUT2R" },
1520
1521	WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
1522	WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
1523	WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
1524	WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
1525
1526	WM2200_DSP_AUX_ROUTES("DSP1"),
1527	WM2200_DSP_AUX_ROUTES("DSP2"),
1528
1529	WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
1530	WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
1531	WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
1532	WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
1533
1534	WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1535	WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1536	WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1537	WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1538	WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1539	WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1540
1541	WM2200_MIXER_ROUTES("EQL", "EQL"),
1542	WM2200_MIXER_ROUTES("EQR", "EQR"),
1543
1544	WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
1545	WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
1546};
1547
1548static int wm2200_probe(struct snd_soc_component *component)
1549{
1550	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
 
1551
1552	wm2200->component = component;
 
 
1553
1554	return 0;
 
 
 
 
 
 
1555}
1556
1557static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1558{
1559	struct snd_soc_component *component = dai->component;
1560	int lrclk, bclk, fmt_val;
1561
1562	lrclk = 0;
1563	bclk = 0;
1564
1565	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1566	case SND_SOC_DAIFMT_DSP_A:
1567		fmt_val = 0;
1568		break;
 
 
 
1569	case SND_SOC_DAIFMT_I2S:
1570		fmt_val = 2;
1571		break;
 
 
 
1572	default:
1573		dev_err(component->dev, "Unsupported DAI format %d\n",
1574			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1575		return -EINVAL;
1576	}
1577
1578	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1579	case SND_SOC_DAIFMT_CBS_CFS:
1580		break;
1581	case SND_SOC_DAIFMT_CBS_CFM:
1582		lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1583		break;
1584	case SND_SOC_DAIFMT_CBM_CFS:
1585		bclk |= WM2200_AIF1_BCLK_MSTR;
1586		break;
1587	case SND_SOC_DAIFMT_CBM_CFM:
1588		lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1589		bclk |= WM2200_AIF1_BCLK_MSTR;
1590		break;
1591	default:
1592		dev_err(component->dev, "Unsupported master mode %d\n",
1593			fmt & SND_SOC_DAIFMT_MASTER_MASK);
1594		return -EINVAL;
1595	}
1596
1597	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1598	case SND_SOC_DAIFMT_NB_NF:
1599		break;
1600	case SND_SOC_DAIFMT_IB_IF:
1601		bclk |= WM2200_AIF1_BCLK_INV;
1602		lrclk |= WM2200_AIF1TX_LRCLK_INV;
1603		break;
1604	case SND_SOC_DAIFMT_IB_NF:
1605		bclk |= WM2200_AIF1_BCLK_INV;
1606		break;
1607	case SND_SOC_DAIFMT_NB_IF:
1608		lrclk |= WM2200_AIF1TX_LRCLK_INV;
1609		break;
1610	default:
1611		return -EINVAL;
1612	}
1613
1614	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
1615			    WM2200_AIF1_BCLK_INV, bclk);
1616	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2,
1617			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1618			    lrclk);
1619	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_3,
1620			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1621			    lrclk);
1622	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_5,
1623			    WM2200_AIF1_FMT_MASK, fmt_val);
1624
1625	return 0;
1626}
1627
1628static int wm2200_sr_code[] = {
1629	0,
1630	12000,
1631	24000,
1632	48000,
1633	96000,
1634	192000,
1635	384000,
1636	768000,
1637	0,
1638	11025,
1639	22050,
1640	44100,
1641	88200,
1642	176400,
1643	352800,
1644	705600,
1645	4000,
1646	8000,
1647	16000,
1648	32000,
1649	64000,
1650	128000,
1651	256000,
1652	512000,
1653};
1654
1655#define WM2200_NUM_BCLK_RATES 12
1656
1657static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
1658	6144000,
1659	3072000,
1660	2048000,
1661	1536000,
1662	768000,
1663	512000,
1664	384000,
1665	256000,
1666	192000,
1667	128000,
1668	96000,
1669	64000,
1670};	
1671
1672static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
1673	5644800,
1674	3763200,
1675	2882400,
1676	1881600,
1677	1411200,
1678	705600,
1679	470400,
1680	352800,
1681	176400,
1682	117600,
1683	88200,
1684	58800,
1685};
1686
1687static int wm2200_hw_params(struct snd_pcm_substream *substream,
1688			    struct snd_pcm_hw_params *params,
1689			    struct snd_soc_dai *dai)
1690{
1691	struct snd_soc_component *component = dai->component;
1692	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
1693	int i, bclk, lrclk, wl, fl, sr_code;
1694	int *bclk_rates;
1695
1696	/* Data sizes if not using TDM */
1697	wl = params_width(params);
1698	if (wl < 0)
1699		return wl;
1700	fl = snd_soc_params_to_frame_size(params);
1701	if (fl < 0)
1702		return fl;
1703
1704	dev_dbg(component->dev, "Word length %d bits, frame length %d bits\n",
1705		wl, fl);
1706
1707	/* Target BCLK rate */
1708	bclk = snd_soc_params_to_bclk(params);
1709	if (bclk < 0)
1710		return bclk;
1711
1712	if (!wm2200->sysclk) {
1713		dev_err(component->dev, "SYSCLK has no rate set\n");
1714		return -EINVAL;
1715	}
1716
1717	for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
1718		if (wm2200_sr_code[i] == params_rate(params))
1719			break;
1720	if (i == ARRAY_SIZE(wm2200_sr_code)) {
1721		dev_err(component->dev, "Unsupported sample rate: %dHz\n",
1722			params_rate(params));
1723		return -EINVAL;
1724	}
1725	sr_code = i;
1726
1727	dev_dbg(component->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
1728		bclk, wm2200->sysclk);
1729
1730	if (wm2200->sysclk % 4000)
1731		bclk_rates = wm2200_bclk_rates_cd;
1732	else
1733		bclk_rates = wm2200_bclk_rates_dat;
1734
1735	for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
1736		if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1737			break;
1738	if (i == WM2200_NUM_BCLK_RATES) {
1739		dev_err(component->dev,
1740			"No valid BCLK for %dHz found from %dHz SYSCLK\n",
1741			bclk, wm2200->sysclk);
1742		return -EINVAL;
1743	}
1744
1745	bclk = i;
1746	dev_dbg(component->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1747	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_1,
1748			    WM2200_AIF1_BCLK_DIV_MASK, bclk);
1749
1750	lrclk = bclk_rates[bclk] / params_rate(params);
1751	dev_dbg(component->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1752	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1753	    wm2200->symmetric_rates)
1754		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_7,
1755				    WM2200_AIF1RX_BCPF_MASK, lrclk);
1756	else
1757		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_6,
1758				    WM2200_AIF1TX_BCPF_MASK, lrclk);
1759
1760	i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
1761	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1762		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_9,
1763				    WM2200_AIF1RX_WL_MASK |
1764				    WM2200_AIF1RX_SLOT_LEN_MASK, i);
1765	else
1766		snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_8,
1767				    WM2200_AIF1TX_WL_MASK |
1768				    WM2200_AIF1TX_SLOT_LEN_MASK, i);
1769
1770	snd_soc_component_update_bits(component, WM2200_CLOCKING_4,
1771			    WM2200_SAMPLE_RATE_1_MASK, sr_code);
1772
1773	return 0;
1774}
1775
1776static int wm2200_set_sysclk(struct snd_soc_component *component, int clk_id,
 
 
 
 
 
1777			     int source, unsigned int freq, int dir)
1778{
1779	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
1780	int fval;
1781
1782	switch (clk_id) {
1783	case WM2200_CLK_SYSCLK:
1784		break;
1785
1786	default:
1787		dev_err(component->dev, "Unknown clock %d\n", clk_id);
1788		return -EINVAL;
1789	}
1790
1791	switch (source) {
1792	case WM2200_CLKSRC_MCLK1:
1793	case WM2200_CLKSRC_MCLK2:
1794	case WM2200_CLKSRC_FLL:
1795	case WM2200_CLKSRC_BCLK1:
1796		break;
1797	default:
1798		dev_err(component->dev, "Invalid source %d\n", source);
1799		return -EINVAL;
1800	}
1801
1802	switch (freq) {
1803	case 22579200:
1804	case 24576000:
1805		fval = 2;
1806		break;
1807	default:
1808		dev_err(component->dev, "Invalid clock rate: %d\n", freq);
1809		return -EINVAL;
1810	}
1811
1812	/* TODO: Check if MCLKs are in use and enable/disable pulls to
1813	 * match.
1814	 */
1815
1816	snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
1817			    WM2200_SYSCLK_SRC_MASK,
1818			    fval << WM2200_SYSCLK_FREQ_SHIFT | source);
1819
1820	wm2200->sysclk = freq;
1821
1822	return 0;
1823}
1824
1825struct _fll_div {
1826	u16 fll_fratio;
1827	u16 fll_outdiv;
1828	u16 fll_refclk_div;
1829	u16 n;
1830	u16 theta;
1831	u16 lambda;
1832};
1833
1834static struct {
1835	unsigned int min;
1836	unsigned int max;
1837	u16 fll_fratio;
1838	int ratio;
1839} fll_fratios[] = {
1840	{       0,    64000, 4, 16 },
1841	{   64000,   128000, 3,  8 },
1842	{  128000,   256000, 2,  4 },
1843	{  256000,  1000000, 1,  2 },
1844	{ 1000000, 13500000, 0,  1 },
1845};
1846
1847static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1848		       unsigned int Fout)
1849{
1850	unsigned int target;
1851	unsigned int div;
1852	unsigned int fratio, gcd_fll;
1853	int i;
1854
1855	/* Fref must be <=13.5MHz */
1856	div = 1;
1857	fll_div->fll_refclk_div = 0;
1858	while ((Fref / div) > 13500000) {
1859		div *= 2;
1860		fll_div->fll_refclk_div++;
1861
1862		if (div > 8) {
1863			pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1864			       Fref);
1865			return -EINVAL;
1866		}
1867	}
1868
1869	pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1870
1871	/* Apply the division for our remaining calculations */
1872	Fref /= div;
1873
1874	/* Fvco should be 90-100MHz; don't check the upper bound */
1875	div = 2;
1876	while (Fout * div < 90000000) {
1877		div++;
1878		if (div > 64) {
1879			pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1880			       Fout);
1881			return -EINVAL;
1882		}
1883	}
1884	target = Fout * div;
1885	fll_div->fll_outdiv = div - 1;
1886
1887	pr_debug("FLL Fvco=%dHz\n", target);
1888
1889	/* Find an appropraite FLL_FRATIO and factor it out of the target */
1890	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1891		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1892			fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1893			fratio = fll_fratios[i].ratio;
1894			break;
1895		}
1896	}
1897	if (i == ARRAY_SIZE(fll_fratios)) {
1898		pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1899		return -EINVAL;
1900	}
1901
1902	fll_div->n = target / (fratio * Fref);
1903
1904	if (target % Fref == 0) {
1905		fll_div->theta = 0;
1906		fll_div->lambda = 0;
1907	} else {
1908		gcd_fll = gcd(target, fratio * Fref);
1909
1910		fll_div->theta = (target - (fll_div->n * fratio * Fref))
1911			/ gcd_fll;
1912		fll_div->lambda = (fratio * Fref) / gcd_fll;
1913	}
1914
1915	pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1916		 fll_div->n, fll_div->theta, fll_div->lambda);
1917	pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1918		 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1919		 fll_div->fll_refclk_div);
1920
1921	return 0;
1922}
1923
1924static int wm2200_set_fll(struct snd_soc_component *component, int fll_id, int source,
1925			  unsigned int Fref, unsigned int Fout)
1926{
1927	struct i2c_client *i2c = to_i2c_client(component->dev);
1928	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
1929	struct _fll_div factors;
1930	int ret, i, timeout;
1931	unsigned long time_left;
1932
1933	if (!Fout) {
1934		dev_dbg(component->dev, "FLL disabled");
1935
1936		if (wm2200->fll_fout)
1937			pm_runtime_put(component->dev);
1938
1939		wm2200->fll_fout = 0;
1940		snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1,
1941				    WM2200_FLL_ENA, 0);
1942		return 0;
1943	}
1944
1945	switch (source) {
1946	case WM2200_FLL_SRC_MCLK1:
1947	case WM2200_FLL_SRC_MCLK2:
1948	case WM2200_FLL_SRC_BCLK:
1949		break;
1950	default:
1951		dev_err(component->dev, "Invalid FLL source %d\n", source);
1952		return -EINVAL;
1953	}
1954
1955	ret = fll_factors(&factors, Fref, Fout);
1956	if (ret < 0)
1957		return ret;
1958
1959	/* Disable the FLL while we reconfigure */
1960	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
1961
1962	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_2,
1963			    WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
1964			    (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
1965			    factors.fll_fratio);
1966	if (factors.theta) {
1967		snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3,
1968				    WM2200_FLL_FRACN_ENA,
1969				    WM2200_FLL_FRACN_ENA);
1970		snd_soc_component_update_bits(component, WM2200_FLL_EFS_2,
1971				    WM2200_FLL_EFS_ENA,
1972				    WM2200_FLL_EFS_ENA);
1973	} else {
1974		snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_3,
1975				    WM2200_FLL_FRACN_ENA, 0);
1976		snd_soc_component_update_bits(component, WM2200_FLL_EFS_2,
1977				    WM2200_FLL_EFS_ENA, 0);
1978	}
1979
1980	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
1981			    factors.theta);
1982	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
1983			    factors.n);
1984	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_7,
1985			    WM2200_FLL_CLK_REF_DIV_MASK |
1986			    WM2200_FLL_CLK_REF_SRC_MASK,
1987			    (factors.fll_refclk_div
1988			     << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
1989	snd_soc_component_update_bits(component, WM2200_FLL_EFS_1,
1990			    WM2200_FLL_LAMBDA_MASK, factors.lambda);
1991
1992	/* Clear any pending completions */
1993	try_wait_for_completion(&wm2200->fll_lock);
1994
1995	pm_runtime_get_sync(component->dev);
1996
1997	snd_soc_component_update_bits(component, WM2200_FLL_CONTROL_1,
1998			    WM2200_FLL_ENA, WM2200_FLL_ENA);
1999
2000	if (i2c->irq)
2001		timeout = 2;
2002	else
2003		timeout = 50;
2004
2005	snd_soc_component_update_bits(component, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
2006			    WM2200_SYSCLK_ENA);
2007
2008	/* Poll for the lock; will use the interrupt to exit quickly */
2009	for (i = 0; i < timeout; i++) {
2010		if (i2c->irq) {
2011			time_left = wait_for_completion_timeout(
2012							&wm2200->fll_lock,
2013							msecs_to_jiffies(25));
2014			if (time_left > 0)
2015				break;
2016		} else {
2017			msleep(1);
2018		}
2019
2020		ret = snd_soc_component_read(component,
2021				   WM2200_INTERRUPT_RAW_STATUS_2);
2022		if (ret < 0) {
2023			dev_err(component->dev,
2024				"Failed to read FLL status: %d\n",
2025				ret);
2026			continue;
2027		}
2028		if (ret & WM2200_FLL_LOCK_STS)
2029			break;
2030	}
2031	if (i == timeout) {
2032		dev_err(component->dev, "FLL lock timed out\n");
2033		pm_runtime_put(component->dev);
2034		return -ETIMEDOUT;
2035	}
2036
2037	wm2200->fll_src = source;
2038	wm2200->fll_fref = Fref;
2039	wm2200->fll_fout = Fout;
2040
2041	dev_dbg(component->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
2042
2043	return 0;
2044}
2045
2046static int wm2200_dai_probe(struct snd_soc_dai *dai)
2047{
2048	struct snd_soc_component *component = dai->component;
2049	struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
2050	unsigned int val = 0;
2051	int ret;
2052
2053	ret = snd_soc_component_read(component, WM2200_GPIO_CTRL_1);
2054	if (ret >= 0) {
2055		if ((ret & WM2200_GP1_FN_MASK) != 0) {
2056			wm2200->symmetric_rates = true;
2057			val = WM2200_AIF1TX_LRCLK_SRC;
2058		}
2059	} else {
2060		dev_err(component->dev, "Failed to read GPIO 1 config: %d\n", ret);
2061	}
2062
2063	snd_soc_component_update_bits(component, WM2200_AUDIO_IF_1_2,
2064			    WM2200_AIF1TX_LRCLK_SRC, val);
2065
2066	return 0;
2067}
2068
2069static const struct snd_soc_dai_ops wm2200_dai_ops = {
2070	.probe = wm2200_dai_probe,
2071	.set_fmt = wm2200_set_fmt,
2072	.hw_params = wm2200_hw_params,
2073};
2074
2075#define WM2200_RATES SNDRV_PCM_RATE_8000_48000
2076
2077#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2078			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2079
2080static struct snd_soc_dai_driver wm2200_dai = {
2081	.name = "wm2200",
 
2082	.playback = {
2083		.stream_name = "Playback",
2084		.channels_min = 2,
2085		.channels_max = 2,
2086		.rates = WM2200_RATES,
2087		.formats = WM2200_FORMATS,
2088	},
2089	.capture = {
2090		 .stream_name = "Capture",
2091		 .channels_min = 2,
2092		 .channels_max = 2,
2093		 .rates = WM2200_RATES,
2094		 .formats = WM2200_FORMATS,
2095	 },
2096	.ops = &wm2200_dai_ops,
2097};
2098
2099static const struct snd_soc_component_driver soc_component_wm2200 = {
2100	.probe			= wm2200_probe,
2101	.set_sysclk		= wm2200_set_sysclk,
2102	.set_pll		= wm2200_set_fll,
2103	.controls		= wm2200_snd_controls,
2104	.num_controls		= ARRAY_SIZE(wm2200_snd_controls),
2105	.dapm_widgets		= wm2200_dapm_widgets,
2106	.num_dapm_widgets	= ARRAY_SIZE(wm2200_dapm_widgets),
2107	.dapm_routes		= wm2200_dapm_routes,
2108	.num_dapm_routes	= ARRAY_SIZE(wm2200_dapm_routes),
2109	.endianness		= 1,
 
 
 
2110};
2111
2112static irqreturn_t wm2200_irq(int irq, void *data)
2113{
2114	struct wm2200_priv *wm2200 = data;
2115	unsigned int val, mask;
2116	int ret;
2117
2118	ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
2119	if (ret != 0) {
2120		dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
2121		return IRQ_NONE;
2122	}
2123
2124	ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
2125			   &mask);
2126	if (ret != 0) {
2127		dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
2128		mask = 0;
2129	}
2130
2131	val &= ~mask;
2132
2133	if (val & WM2200_FLL_LOCK_EINT) {
2134		dev_dbg(wm2200->dev, "FLL locked\n");
2135		complete(&wm2200->fll_lock);
2136	}
2137
2138	if (val) {
2139		regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
2140		
2141		return IRQ_HANDLED;
2142	} else {
2143		return IRQ_NONE;
2144	}
2145}
2146
2147static const struct regmap_config wm2200_regmap = {
2148	.reg_bits = 16,
2149	.val_bits = 16,
2150
2151	.max_register = WM2200_MAX_REGISTER + (ARRAY_SIZE(wm2200_ranges) *
2152					       WM2200_DSP_SPACING),
2153	.reg_defaults = wm2200_reg_defaults,
2154	.num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
2155	.volatile_reg = wm2200_volatile_register,
2156	.readable_reg = wm2200_readable_register,
2157	.cache_type = REGCACHE_MAPLE,
2158	.ranges = wm2200_ranges,
2159	.num_ranges = ARRAY_SIZE(wm2200_ranges),
2160};
2161
2162static const unsigned int wm2200_dig_vu[] = {
2163	WM2200_DAC_DIGITAL_VOLUME_1L,
2164	WM2200_DAC_DIGITAL_VOLUME_1R,
2165	WM2200_DAC_DIGITAL_VOLUME_2L,
2166	WM2200_DAC_DIGITAL_VOLUME_2R,
2167	WM2200_ADC_DIGITAL_VOLUME_1L,
2168	WM2200_ADC_DIGITAL_VOLUME_1R,
2169	WM2200_ADC_DIGITAL_VOLUME_2L,
2170	WM2200_ADC_DIGITAL_VOLUME_2R,
2171	WM2200_ADC_DIGITAL_VOLUME_3L,
2172	WM2200_ADC_DIGITAL_VOLUME_3R,
2173};
2174
2175static const unsigned int wm2200_mic_ctrl_reg[] = {
2176	WM2200_IN1L_CONTROL,
2177	WM2200_IN2L_CONTROL,
2178	WM2200_IN3L_CONTROL,
2179};
2180
2181static int wm2200_i2c_probe(struct i2c_client *i2c)
 
2182{
2183	struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
2184	struct wm2200_priv *wm2200;
2185	unsigned int reg;
2186	int ret, i;
2187	int val;
2188
2189	wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
2190			      GFP_KERNEL);
2191	if (wm2200 == NULL)
2192		return -ENOMEM;
2193
2194	wm2200->dev = &i2c->dev;
2195	init_completion(&wm2200->fll_lock);
2196
2197	wm2200->regmap = devm_regmap_init_i2c(i2c, &wm2200_regmap);
2198	if (IS_ERR(wm2200->regmap)) {
2199		ret = PTR_ERR(wm2200->regmap);
2200		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2201			ret);
2202		return ret;
2203	}
2204
2205	for (i = 0; i < 2; i++) {
2206		wm2200->dsp[i].cs_dsp.type = WMFW_ADSP1;
2207		wm2200->dsp[i].part = "wm2200";
2208		wm2200->dsp[i].cs_dsp.num = i + 1;
2209		wm2200->dsp[i].cs_dsp.dev = &i2c->dev;
2210		wm2200->dsp[i].cs_dsp.regmap = wm2200->regmap;
2211		wm2200->dsp[i].cs_dsp.sysclk_reg = WM2200_CLOCKING_3;
2212		wm2200->dsp[i].cs_dsp.sysclk_mask = WM2200_SYSCLK_FREQ_MASK;
2213		wm2200->dsp[i].cs_dsp.sysclk_shift =  WM2200_SYSCLK_FREQ_SHIFT;
2214	}
2215
2216	wm2200->dsp[0].cs_dsp.base = WM2200_DSP1_CONTROL_1;
2217	wm2200->dsp[0].cs_dsp.mem = wm2200_dsp1_regions;
2218	wm2200->dsp[0].cs_dsp.num_mems = ARRAY_SIZE(wm2200_dsp1_regions);
2219
2220	wm2200->dsp[1].cs_dsp.base = WM2200_DSP2_CONTROL_1;
2221	wm2200->dsp[1].cs_dsp.mem = wm2200_dsp2_regions;
2222	wm2200->dsp[1].cs_dsp.num_mems = ARRAY_SIZE(wm2200_dsp2_regions);
2223
2224	for (i = 0; i < ARRAY_SIZE(wm2200->dsp); i++)
2225		wm_adsp1_init(&wm2200->dsp[i]);
2226
2227	if (pdata)
2228		wm2200->pdata = *pdata;
2229
2230	i2c_set_clientdata(i2c, wm2200);
2231
2232	for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
2233		wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
2234
2235	ret = devm_regulator_bulk_get(&i2c->dev,
2236				      ARRAY_SIZE(wm2200->core_supplies),
2237				      wm2200->core_supplies);
2238	if (ret != 0) {
2239		dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2240			ret);
2241		return ret;
2242	}
2243
2244	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2245				    wm2200->core_supplies);
2246	if (ret != 0) {
2247		dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2248			ret);
2249		return ret;
2250	}
2251
2252	wm2200->ldo_ena = devm_gpiod_get_optional(&i2c->dev, "wlf,ldo1ena",
2253						  GPIOD_OUT_HIGH);
2254	if (IS_ERR(wm2200->ldo_ena)) {
2255		ret = PTR_ERR(wm2200->ldo_ena);
2256		dev_err(&i2c->dev, "Failed to request LDOENA GPIO %d\n",
2257			ret);
2258		goto err_enable;
2259	}
2260	if (wm2200->ldo_ena) {
2261		gpiod_set_consumer_name(wm2200->ldo_ena, "WM2200 LDOENA");
2262		msleep(2);
2263	}
2264
2265	wm2200->reset = devm_gpiod_get_optional(&i2c->dev, "reset",
2266						GPIOD_OUT_LOW);
2267	if (IS_ERR(wm2200->reset)) {
2268		ret = PTR_ERR(wm2200->reset);
2269		dev_err(&i2c->dev, "Failed to request RESET GPIO %d\n",
2270			ret);
2271		goto err_ldo;
 
2272	}
2273	gpiod_set_consumer_name(wm2200->reset, "WM2200 /RESET");
2274
2275	ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
2276	if (ret < 0) {
2277		dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2278		goto err_reset;
2279	}
2280	switch (reg) {
2281	case 0x2200:
2282		break;
2283
2284	default:
2285		dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
2286		ret = -EINVAL;
2287		goto err_reset;
2288	}
2289
2290	ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
2291	if (ret < 0) {
2292		dev_err(&i2c->dev, "Failed to read revision register\n");
2293		goto err_reset;
2294	}
2295
2296	wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
2297
2298	dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
2299
2300	switch (wm2200->rev) {
2301	case 0:
2302	case 1:
2303		ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
2304					    ARRAY_SIZE(wm2200_reva_patch));
2305		if (ret != 0) {
2306			dev_err(&i2c->dev, "Failed to register patch: %d\n",
2307				ret);
2308		}
2309		break;
2310	default:
2311		break;
2312	}
2313
2314	ret = wm2200_reset(wm2200);
2315	if (ret < 0) {
2316		dev_err(&i2c->dev, "Failed to issue reset\n");
2317		goto err_reset;
2318	}
2319
2320	for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
2321		if (!wm2200->pdata.gpio_defaults[i])
2322			continue;
2323
2324		regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
2325			     wm2200->pdata.gpio_defaults[i]);
2326	}
2327
2328	for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
2329		regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
2330				   WM2200_OUT_VU, WM2200_OUT_VU);
2331
2332	/* Assign slots 1-6 to channels 1-6 for both TX and RX */
2333	for (i = 0; i < 6; i++) {
2334		regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
2335		regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
2336	}
2337
2338	for (i = 0; i < WM2200_MAX_MICBIAS; i++) {
2339		if (!wm2200->pdata.micbias[i].mb_lvl &&
2340		    !wm2200->pdata.micbias[i].bypass)
2341			continue;
2342
2343		/* Apply default for bypass mode */
2344		if (!wm2200->pdata.micbias[i].mb_lvl)
2345			wm2200->pdata.micbias[i].mb_lvl
2346					= WM2200_MBIAS_LVL_1V5;
2347
2348		val = (wm2200->pdata.micbias[i].mb_lvl -1)
2349					<< WM2200_MICB1_LVL_SHIFT;
2350
2351		if (wm2200->pdata.micbias[i].discharge)
2352			val |= WM2200_MICB1_DISCH;
2353
2354		if (wm2200->pdata.micbias[i].fast_start)
2355			val |= WM2200_MICB1_RATE;
2356
2357		if (wm2200->pdata.micbias[i].bypass)
2358			val |= WM2200_MICB1_MODE;
2359
2360		regmap_update_bits(wm2200->regmap,
2361				   WM2200_MIC_BIAS_CTRL_1 + i,
2362				   WM2200_MICB1_LVL_MASK |
2363				   WM2200_MICB1_DISCH |
2364				   WM2200_MICB1_MODE |
2365				   WM2200_MICB1_RATE, val);
2366	}
2367
2368	for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
2369		regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
2370				   WM2200_IN1_MODE_MASK |
2371				   WM2200_IN1_DMIC_SUP_MASK,
2372				   (wm2200->pdata.in_mode[i] <<
2373				    WM2200_IN1_MODE_SHIFT) |
2374				   (wm2200->pdata.dmic_sup[i] <<
2375				    WM2200_IN1_DMIC_SUP_SHIFT));
2376	}
2377
2378	if (i2c->irq) {
2379		ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
2380					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
2381					   "wm2200", wm2200);
2382		if (ret == 0)
2383			regmap_update_bits(wm2200->regmap,
2384					   WM2200_INTERRUPT_STATUS_2_MASK,
2385					   WM2200_FLL_LOCK_EINT, 0);
2386		else
2387			dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2388				i2c->irq, ret);
2389	}
2390
2391	pm_runtime_set_active(&i2c->dev);
2392	pm_runtime_enable(&i2c->dev);
2393	pm_request_idle(&i2c->dev);
2394
2395	ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_wm2200,
2396				     &wm2200_dai, 1);
2397	if (ret != 0) {
2398		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
2399		goto err_pm_runtime;
2400	}
2401
2402	return 0;
2403
2404err_pm_runtime:
2405	pm_runtime_disable(&i2c->dev);
2406	if (i2c->irq)
2407		free_irq(i2c->irq, wm2200);
2408err_reset:
2409	gpiod_set_value_cansleep(wm2200->reset, 1);
 
 
 
2410err_ldo:
2411	gpiod_set_value_cansleep(wm2200->ldo_ena, 0);
 
 
 
2412err_enable:
2413	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2414			       wm2200->core_supplies);
 
 
 
 
 
 
2415	return ret;
2416}
2417
2418static void wm2200_i2c_remove(struct i2c_client *i2c)
2419{
2420	struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
2421
2422	pm_runtime_disable(&i2c->dev);
2423	if (i2c->irq)
2424		free_irq(i2c->irq, wm2200);
2425	/* Assert RESET, disable LDO */
2426	gpiod_set_value_cansleep(wm2200->reset, 1);
2427	gpiod_set_value_cansleep(wm2200->ldo_ena, 0);
2428	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2429			       wm2200->core_supplies);
 
 
 
 
 
 
 
 
2430}
2431
2432#ifdef CONFIG_PM
2433static int wm2200_runtime_suspend(struct device *dev)
2434{
2435	struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2436
2437	regcache_cache_only(wm2200->regmap, true);
2438	regcache_mark_dirty(wm2200->regmap);
2439	gpiod_set_value_cansleep(wm2200->ldo_ena, 0);
 
2440	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2441			       wm2200->core_supplies);
2442
2443	return 0;
2444}
2445
2446static int wm2200_runtime_resume(struct device *dev)
2447{
2448	struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2449	int ret;
2450
2451	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2452				    wm2200->core_supplies);
2453	if (ret != 0) {
2454		dev_err(dev, "Failed to enable supplies: %d\n",
2455			ret);
2456		return ret;
2457	}
2458
2459	if (wm2200->ldo_ena) {
2460		gpiod_set_value_cansleep(wm2200->ldo_ena, 1);
2461		msleep(2);
2462	}
2463
2464	regcache_cache_only(wm2200->regmap, false);
2465	regcache_sync(wm2200->regmap);
2466
2467	return 0;
2468}
2469#endif
2470
2471static const struct dev_pm_ops wm2200_pm = {
2472	SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
2473			   NULL)
2474};
2475
2476static const struct i2c_device_id wm2200_i2c_id[] = {
2477	{ "wm2200" },
2478	{ }
2479};
2480MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
2481
2482static struct i2c_driver wm2200_i2c_driver = {
2483	.driver = {
2484		.name = "wm2200",
 
2485		.pm = &wm2200_pm,
2486	},
2487	.probe =    wm2200_i2c_probe,
2488	.remove =   wm2200_i2c_remove,
2489	.id_table = wm2200_i2c_id,
2490};
2491
2492module_i2c_driver(wm2200_i2c_driver);
 
 
 
 
 
 
 
 
 
 
2493
2494MODULE_DESCRIPTION("ASoC WM2200 driver");
2495MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2496MODULE_LICENSE("GPL");
v3.5.6
 
   1/*
   2 * wm2200.c  --  WM2200 ALSA SoC Audio driver
   3 *
   4 * Copyright 2012 Wolfson Microelectronics plc
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/moduleparam.h>
  15#include <linux/init.h>
  16#include <linux/delay.h>
  17#include <linux/pm.h>
 
  18#include <linux/gcd.h>
  19#include <linux/gpio.h>
  20#include <linux/i2c.h>
  21#include <linux/pm_runtime.h>
  22#include <linux/regulator/consumer.h>
  23#include <linux/regulator/fixed.h>
  24#include <linux/slab.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/jack.h>
  30#include <sound/initval.h>
  31#include <sound/tlv.h>
  32#include <sound/wm2200.h>
  33
  34#include "wm2200.h"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  35
  36/* The code assumes DCVDD is generated internally */
  37#define WM2200_NUM_CORE_SUPPLIES 2
  38static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = {
  39	"DBVDD",
  40	"LDOVDD",
  41};
  42
  43struct wm2200_fll {
  44	int fref;
  45	int fout;
  46	int src;
  47	struct completion lock;
  48};
  49
  50/* codec private data */
  51struct wm2200_priv {
 
  52	struct regmap *regmap;
  53	struct device *dev;
  54	struct snd_soc_codec *codec;
  55	struct wm2200_pdata pdata;
  56	struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES];
 
 
  57
  58	struct completion fll_lock;
  59	int fll_fout;
  60	int fll_fref;
  61	int fll_src;
  62
  63	int rev;
  64	int sysclk;
 
 
  65};
  66
  67static struct reg_default wm2200_reg_defaults[] = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  68	{ 0x000B, 0x0000 },   /* R11    - Tone Generator 1 */
  69	{ 0x0102, 0x0000 },   /* R258   - Clocking 3 */
  70	{ 0x0103, 0x0011 },   /* R259   - Clocking 4 */
  71	{ 0x0111, 0x0000 },   /* R273   - FLL Control 1 */
  72	{ 0x0112, 0x0000 },   /* R274   - FLL Control 2 */
  73	{ 0x0113, 0x0000 },   /* R275   - FLL Control 3 */
  74	{ 0x0114, 0x0000 },   /* R276   - FLL Control 4 */
  75	{ 0x0116, 0x0177 },   /* R278   - FLL Control 6 */
  76	{ 0x0117, 0x0004 },   /* R279   - FLL Control 7 */
  77	{ 0x0119, 0x0000 },   /* R281   - FLL EFS 1 */
  78	{ 0x011A, 0x0002 },   /* R282   - FLL EFS 2 */
  79	{ 0x0200, 0x0000 },   /* R512   - Mic Charge Pump 1 */
  80	{ 0x0201, 0x03FF },   /* R513   - Mic Charge Pump 2 */
  81	{ 0x0202, 0x9BDE },   /* R514   - DM Charge Pump 1 */
  82	{ 0x020C, 0x0000 },   /* R524   - Mic Bias Ctrl 1 */
  83	{ 0x020D, 0x0000 },   /* R525   - Mic Bias Ctrl 2 */
  84	{ 0x020F, 0x0000 },   /* R527   - Ear Piece Ctrl 1 */
  85	{ 0x0210, 0x0000 },   /* R528   - Ear Piece Ctrl 2 */
  86	{ 0x0301, 0x0000 },   /* R769   - Input Enables */
  87	{ 0x0302, 0x2240 },   /* R770   - IN1L Control */
  88	{ 0x0303, 0x0040 },   /* R771   - IN1R Control */
  89	{ 0x0304, 0x2240 },   /* R772   - IN2L Control */
  90	{ 0x0305, 0x0040 },   /* R773   - IN2R Control */
  91	{ 0x0306, 0x2240 },   /* R774   - IN3L Control */
  92	{ 0x0307, 0x0040 },   /* R775   - IN3R Control */
  93	{ 0x030A, 0x0000 },   /* R778   - RXANC_SRC */
  94	{ 0x030B, 0x0022 },   /* R779   - Input Volume Ramp */
  95	{ 0x030C, 0x0180 },   /* R780   - ADC Digital Volume 1L */
  96	{ 0x030D, 0x0180 },   /* R781   - ADC Digital Volume 1R */
  97	{ 0x030E, 0x0180 },   /* R782   - ADC Digital Volume 2L */
  98	{ 0x030F, 0x0180 },   /* R783   - ADC Digital Volume 2R */
  99	{ 0x0310, 0x0180 },   /* R784   - ADC Digital Volume 3L */
 100	{ 0x0311, 0x0180 },   /* R785   - ADC Digital Volume 3R */
 101	{ 0x0400, 0x0000 },   /* R1024  - Output Enables */
 102	{ 0x0401, 0x0000 },   /* R1025  - DAC Volume Limit 1L */
 103	{ 0x0402, 0x0000 },   /* R1026  - DAC Volume Limit 1R */
 104	{ 0x0403, 0x0000 },   /* R1027  - DAC Volume Limit 2L */
 105	{ 0x0404, 0x0000 },   /* R1028  - DAC Volume Limit 2R */
 106	{ 0x0409, 0x0000 },   /* R1033  - DAC AEC Control 1 */
 107	{ 0x040A, 0x0022 },   /* R1034  - Output Volume Ramp */
 108	{ 0x040B, 0x0180 },   /* R1035  - DAC Digital Volume 1L */
 109	{ 0x040C, 0x0180 },   /* R1036  - DAC Digital Volume 1R */
 110	{ 0x040D, 0x0180 },   /* R1037  - DAC Digital Volume 2L */
 111	{ 0x040E, 0x0180 },   /* R1038  - DAC Digital Volume 2R */
 112	{ 0x0417, 0x0069 },   /* R1047  - PDM 1 */
 113	{ 0x0418, 0x0000 },   /* R1048  - PDM 2 */
 114	{ 0x0500, 0x0000 },   /* R1280  - Audio IF 1_1 */
 115	{ 0x0501, 0x0008 },   /* R1281  - Audio IF 1_2 */
 116	{ 0x0502, 0x0000 },   /* R1282  - Audio IF 1_3 */
 117	{ 0x0503, 0x0000 },   /* R1283  - Audio IF 1_4 */
 118	{ 0x0504, 0x0000 },   /* R1284  - Audio IF 1_5 */
 119	{ 0x0505, 0x0001 },   /* R1285  - Audio IF 1_6 */
 120	{ 0x0506, 0x0001 },   /* R1286  - Audio IF 1_7 */
 121	{ 0x0507, 0x0000 },   /* R1287  - Audio IF 1_8 */
 122	{ 0x0508, 0x0000 },   /* R1288  - Audio IF 1_9 */
 123	{ 0x0509, 0x0000 },   /* R1289  - Audio IF 1_10 */
 124	{ 0x050A, 0x0000 },   /* R1290  - Audio IF 1_11 */
 125	{ 0x050B, 0x0000 },   /* R1291  - Audio IF 1_12 */
 126	{ 0x050C, 0x0000 },   /* R1292  - Audio IF 1_13 */
 127	{ 0x050D, 0x0000 },   /* R1293  - Audio IF 1_14 */
 128	{ 0x050E, 0x0000 },   /* R1294  - Audio IF 1_15 */
 129	{ 0x050F, 0x0000 },   /* R1295  - Audio IF 1_16 */
 130	{ 0x0510, 0x0000 },   /* R1296  - Audio IF 1_17 */
 131	{ 0x0511, 0x0000 },   /* R1297  - Audio IF 1_18 */
 132	{ 0x0512, 0x0000 },   /* R1298  - Audio IF 1_19 */
 133	{ 0x0513, 0x0000 },   /* R1299  - Audio IF 1_20 */
 134	{ 0x0514, 0x0000 },   /* R1300  - Audio IF 1_21 */
 135	{ 0x0515, 0x0001 },   /* R1301  - Audio IF 1_22 */
 136	{ 0x0600, 0x0000 },   /* R1536  - OUT1LMIX Input 1 Source */
 137	{ 0x0601, 0x0080 },   /* R1537  - OUT1LMIX Input 1 Volume */
 138	{ 0x0602, 0x0000 },   /* R1538  - OUT1LMIX Input 2 Source */
 139	{ 0x0603, 0x0080 },   /* R1539  - OUT1LMIX Input 2 Volume */
 140	{ 0x0604, 0x0000 },   /* R1540  - OUT1LMIX Input 3 Source */
 141	{ 0x0605, 0x0080 },   /* R1541  - OUT1LMIX Input 3 Volume */
 142	{ 0x0606, 0x0000 },   /* R1542  - OUT1LMIX Input 4 Source */
 143	{ 0x0607, 0x0080 },   /* R1543  - OUT1LMIX Input 4 Volume */
 144	{ 0x0608, 0x0000 },   /* R1544  - OUT1RMIX Input 1 Source */
 145	{ 0x0609, 0x0080 },   /* R1545  - OUT1RMIX Input 1 Volume */
 146	{ 0x060A, 0x0000 },   /* R1546  - OUT1RMIX Input 2 Source */
 147	{ 0x060B, 0x0080 },   /* R1547  - OUT1RMIX Input 2 Volume */
 148	{ 0x060C, 0x0000 },   /* R1548  - OUT1RMIX Input 3 Source */
 149	{ 0x060D, 0x0080 },   /* R1549  - OUT1RMIX Input 3 Volume */
 150	{ 0x060E, 0x0000 },   /* R1550  - OUT1RMIX Input 4 Source */
 151	{ 0x060F, 0x0080 },   /* R1551  - OUT1RMIX Input 4 Volume */
 152	{ 0x0610, 0x0000 },   /* R1552  - OUT2LMIX Input 1 Source */
 153	{ 0x0611, 0x0080 },   /* R1553  - OUT2LMIX Input 1 Volume */
 154	{ 0x0612, 0x0000 },   /* R1554  - OUT2LMIX Input 2 Source */
 155	{ 0x0613, 0x0080 },   /* R1555  - OUT2LMIX Input 2 Volume */
 156	{ 0x0614, 0x0000 },   /* R1556  - OUT2LMIX Input 3 Source */
 157	{ 0x0615, 0x0080 },   /* R1557  - OUT2LMIX Input 3 Volume */
 158	{ 0x0616, 0x0000 },   /* R1558  - OUT2LMIX Input 4 Source */
 159	{ 0x0617, 0x0080 },   /* R1559  - OUT2LMIX Input 4 Volume */
 160	{ 0x0618, 0x0000 },   /* R1560  - OUT2RMIX Input 1 Source */
 161	{ 0x0619, 0x0080 },   /* R1561  - OUT2RMIX Input 1 Volume */
 162	{ 0x061A, 0x0000 },   /* R1562  - OUT2RMIX Input 2 Source */
 163	{ 0x061B, 0x0080 },   /* R1563  - OUT2RMIX Input 2 Volume */
 164	{ 0x061C, 0x0000 },   /* R1564  - OUT2RMIX Input 3 Source */
 165	{ 0x061D, 0x0080 },   /* R1565  - OUT2RMIX Input 3 Volume */
 166	{ 0x061E, 0x0000 },   /* R1566  - OUT2RMIX Input 4 Source */
 167	{ 0x061F, 0x0080 },   /* R1567  - OUT2RMIX Input 4 Volume */
 168	{ 0x0620, 0x0000 },   /* R1568  - AIF1TX1MIX Input 1 Source */
 169	{ 0x0621, 0x0080 },   /* R1569  - AIF1TX1MIX Input 1 Volume */
 170	{ 0x0622, 0x0000 },   /* R1570  - AIF1TX1MIX Input 2 Source */
 171	{ 0x0623, 0x0080 },   /* R1571  - AIF1TX1MIX Input 2 Volume */
 172	{ 0x0624, 0x0000 },   /* R1572  - AIF1TX1MIX Input 3 Source */
 173	{ 0x0625, 0x0080 },   /* R1573  - AIF1TX1MIX Input 3 Volume */
 174	{ 0x0626, 0x0000 },   /* R1574  - AIF1TX1MIX Input 4 Source */
 175	{ 0x0627, 0x0080 },   /* R1575  - AIF1TX1MIX Input 4 Volume */
 176	{ 0x0628, 0x0000 },   /* R1576  - AIF1TX2MIX Input 1 Source */
 177	{ 0x0629, 0x0080 },   /* R1577  - AIF1TX2MIX Input 1 Volume */
 178	{ 0x062A, 0x0000 },   /* R1578  - AIF1TX2MIX Input 2 Source */
 179	{ 0x062B, 0x0080 },   /* R1579  - AIF1TX2MIX Input 2 Volume */
 180	{ 0x062C, 0x0000 },   /* R1580  - AIF1TX2MIX Input 3 Source */
 181	{ 0x062D, 0x0080 },   /* R1581  - AIF1TX2MIX Input 3 Volume */
 182	{ 0x062E, 0x0000 },   /* R1582  - AIF1TX2MIX Input 4 Source */
 183	{ 0x062F, 0x0080 },   /* R1583  - AIF1TX2MIX Input 4 Volume */
 184	{ 0x0630, 0x0000 },   /* R1584  - AIF1TX3MIX Input 1 Source */
 185	{ 0x0631, 0x0080 },   /* R1585  - AIF1TX3MIX Input 1 Volume */
 186	{ 0x0632, 0x0000 },   /* R1586  - AIF1TX3MIX Input 2 Source */
 187	{ 0x0633, 0x0080 },   /* R1587  - AIF1TX3MIX Input 2 Volume */
 188	{ 0x0634, 0x0000 },   /* R1588  - AIF1TX3MIX Input 3 Source */
 189	{ 0x0635, 0x0080 },   /* R1589  - AIF1TX3MIX Input 3 Volume */
 190	{ 0x0636, 0x0000 },   /* R1590  - AIF1TX3MIX Input 4 Source */
 191	{ 0x0637, 0x0080 },   /* R1591  - AIF1TX3MIX Input 4 Volume */
 192	{ 0x0638, 0x0000 },   /* R1592  - AIF1TX4MIX Input 1 Source */
 193	{ 0x0639, 0x0080 },   /* R1593  - AIF1TX4MIX Input 1 Volume */
 194	{ 0x063A, 0x0000 },   /* R1594  - AIF1TX4MIX Input 2 Source */
 195	{ 0x063B, 0x0080 },   /* R1595  - AIF1TX4MIX Input 2 Volume */
 196	{ 0x063C, 0x0000 },   /* R1596  - AIF1TX4MIX Input 3 Source */
 197	{ 0x063D, 0x0080 },   /* R1597  - AIF1TX4MIX Input 3 Volume */
 198	{ 0x063E, 0x0000 },   /* R1598  - AIF1TX4MIX Input 4 Source */
 199	{ 0x063F, 0x0080 },   /* R1599  - AIF1TX4MIX Input 4 Volume */
 200	{ 0x0640, 0x0000 },   /* R1600  - AIF1TX5MIX Input 1 Source */
 201	{ 0x0641, 0x0080 },   /* R1601  - AIF1TX5MIX Input 1 Volume */
 202	{ 0x0642, 0x0000 },   /* R1602  - AIF1TX5MIX Input 2 Source */
 203	{ 0x0643, 0x0080 },   /* R1603  - AIF1TX5MIX Input 2 Volume */
 204	{ 0x0644, 0x0000 },   /* R1604  - AIF1TX5MIX Input 3 Source */
 205	{ 0x0645, 0x0080 },   /* R1605  - AIF1TX5MIX Input 3 Volume */
 206	{ 0x0646, 0x0000 },   /* R1606  - AIF1TX5MIX Input 4 Source */
 207	{ 0x0647, 0x0080 },   /* R1607  - AIF1TX5MIX Input 4 Volume */
 208	{ 0x0648, 0x0000 },   /* R1608  - AIF1TX6MIX Input 1 Source */
 209	{ 0x0649, 0x0080 },   /* R1609  - AIF1TX6MIX Input 1 Volume */
 210	{ 0x064A, 0x0000 },   /* R1610  - AIF1TX6MIX Input 2 Source */
 211	{ 0x064B, 0x0080 },   /* R1611  - AIF1TX6MIX Input 2 Volume */
 212	{ 0x064C, 0x0000 },   /* R1612  - AIF1TX6MIX Input 3 Source */
 213	{ 0x064D, 0x0080 },   /* R1613  - AIF1TX6MIX Input 3 Volume */
 214	{ 0x064E, 0x0000 },   /* R1614  - AIF1TX6MIX Input 4 Source */
 215	{ 0x064F, 0x0080 },   /* R1615  - AIF1TX6MIX Input 4 Volume */
 216	{ 0x0650, 0x0000 },   /* R1616  - EQLMIX Input 1 Source */
 217	{ 0x0651, 0x0080 },   /* R1617  - EQLMIX Input 1 Volume */
 218	{ 0x0652, 0x0000 },   /* R1618  - EQLMIX Input 2 Source */
 219	{ 0x0653, 0x0080 },   /* R1619  - EQLMIX Input 2 Volume */
 220	{ 0x0654, 0x0000 },   /* R1620  - EQLMIX Input 3 Source */
 221	{ 0x0655, 0x0080 },   /* R1621  - EQLMIX Input 3 Volume */
 222	{ 0x0656, 0x0000 },   /* R1622  - EQLMIX Input 4 Source */
 223	{ 0x0657, 0x0080 },   /* R1623  - EQLMIX Input 4 Volume */
 224	{ 0x0658, 0x0000 },   /* R1624  - EQRMIX Input 1 Source */
 225	{ 0x0659, 0x0080 },   /* R1625  - EQRMIX Input 1 Volume */
 226	{ 0x065A, 0x0000 },   /* R1626  - EQRMIX Input 2 Source */
 227	{ 0x065B, 0x0080 },   /* R1627  - EQRMIX Input 2 Volume */
 228	{ 0x065C, 0x0000 },   /* R1628  - EQRMIX Input 3 Source */
 229	{ 0x065D, 0x0080 },   /* R1629  - EQRMIX Input 3 Volume */
 230	{ 0x065E, 0x0000 },   /* R1630  - EQRMIX Input 4 Source */
 231	{ 0x065F, 0x0080 },   /* R1631  - EQRMIX Input 4 Volume */
 232	{ 0x0660, 0x0000 },   /* R1632  - LHPF1MIX Input 1 Source */
 233	{ 0x0661, 0x0080 },   /* R1633  - LHPF1MIX Input 1 Volume */
 234	{ 0x0662, 0x0000 },   /* R1634  - LHPF1MIX Input 2 Source */
 235	{ 0x0663, 0x0080 },   /* R1635  - LHPF1MIX Input 2 Volume */
 236	{ 0x0664, 0x0000 },   /* R1636  - LHPF1MIX Input 3 Source */
 237	{ 0x0665, 0x0080 },   /* R1637  - LHPF1MIX Input 3 Volume */
 238	{ 0x0666, 0x0000 },   /* R1638  - LHPF1MIX Input 4 Source */
 239	{ 0x0667, 0x0080 },   /* R1639  - LHPF1MIX Input 4 Volume */
 240	{ 0x0668, 0x0000 },   /* R1640  - LHPF2MIX Input 1 Source */
 241	{ 0x0669, 0x0080 },   /* R1641  - LHPF2MIX Input 1 Volume */
 242	{ 0x066A, 0x0000 },   /* R1642  - LHPF2MIX Input 2 Source */
 243	{ 0x066B, 0x0080 },   /* R1643  - LHPF2MIX Input 2 Volume */
 244	{ 0x066C, 0x0000 },   /* R1644  - LHPF2MIX Input 3 Source */
 245	{ 0x066D, 0x0080 },   /* R1645  - LHPF2MIX Input 3 Volume */
 246	{ 0x066E, 0x0000 },   /* R1646  - LHPF2MIX Input 4 Source */
 247	{ 0x066F, 0x0080 },   /* R1647  - LHPF2MIX Input 4 Volume */
 248	{ 0x0670, 0x0000 },   /* R1648  - DSP1LMIX Input 1 Source */
 249	{ 0x0671, 0x0080 },   /* R1649  - DSP1LMIX Input 1 Volume */
 250	{ 0x0672, 0x0000 },   /* R1650  - DSP1LMIX Input 2 Source */
 251	{ 0x0673, 0x0080 },   /* R1651  - DSP1LMIX Input 2 Volume */
 252	{ 0x0674, 0x0000 },   /* R1652  - DSP1LMIX Input 3 Source */
 253	{ 0x0675, 0x0080 },   /* R1653  - DSP1LMIX Input 3 Volume */
 254	{ 0x0676, 0x0000 },   /* R1654  - DSP1LMIX Input 4 Source */
 255	{ 0x0677, 0x0080 },   /* R1655  - DSP1LMIX Input 4 Volume */
 256	{ 0x0678, 0x0000 },   /* R1656  - DSP1RMIX Input 1 Source */
 257	{ 0x0679, 0x0080 },   /* R1657  - DSP1RMIX Input 1 Volume */
 258	{ 0x067A, 0x0000 },   /* R1658  - DSP1RMIX Input 2 Source */
 259	{ 0x067B, 0x0080 },   /* R1659  - DSP1RMIX Input 2 Volume */
 260	{ 0x067C, 0x0000 },   /* R1660  - DSP1RMIX Input 3 Source */
 261	{ 0x067D, 0x0080 },   /* R1661  - DSP1RMIX Input 3 Volume */
 262	{ 0x067E, 0x0000 },   /* R1662  - DSP1RMIX Input 4 Source */
 263	{ 0x067F, 0x0080 },   /* R1663  - DSP1RMIX Input 4 Volume */
 264	{ 0x0680, 0x0000 },   /* R1664  - DSP1AUX1MIX Input 1 Source */
 265	{ 0x0681, 0x0000 },   /* R1665  - DSP1AUX2MIX Input 1 Source */
 266	{ 0x0682, 0x0000 },   /* R1666  - DSP1AUX3MIX Input 1 Source */
 267	{ 0x0683, 0x0000 },   /* R1667  - DSP1AUX4MIX Input 1 Source */
 268	{ 0x0684, 0x0000 },   /* R1668  - DSP1AUX5MIX Input 1 Source */
 269	{ 0x0685, 0x0000 },   /* R1669  - DSP1AUX6MIX Input 1 Source */
 270	{ 0x0686, 0x0000 },   /* R1670  - DSP2LMIX Input 1 Source */
 271	{ 0x0687, 0x0080 },   /* R1671  - DSP2LMIX Input 1 Volume */
 272	{ 0x0688, 0x0000 },   /* R1672  - DSP2LMIX Input 2 Source */
 273	{ 0x0689, 0x0080 },   /* R1673  - DSP2LMIX Input 2 Volume */
 274	{ 0x068A, 0x0000 },   /* R1674  - DSP2LMIX Input 3 Source */
 275	{ 0x068B, 0x0080 },   /* R1675  - DSP2LMIX Input 3 Volume */
 276	{ 0x068C, 0x0000 },   /* R1676  - DSP2LMIX Input 4 Source */
 277	{ 0x068D, 0x0080 },   /* R1677  - DSP2LMIX Input 4 Volume */
 278	{ 0x068E, 0x0000 },   /* R1678  - DSP2RMIX Input 1 Source */
 279	{ 0x068F, 0x0080 },   /* R1679  - DSP2RMIX Input 1 Volume */
 280	{ 0x0690, 0x0000 },   /* R1680  - DSP2RMIX Input 2 Source */
 281	{ 0x0691, 0x0080 },   /* R1681  - DSP2RMIX Input 2 Volume */
 282	{ 0x0692, 0x0000 },   /* R1682  - DSP2RMIX Input 3 Source */
 283	{ 0x0693, 0x0080 },   /* R1683  - DSP2RMIX Input 3 Volume */
 284	{ 0x0694, 0x0000 },   /* R1684  - DSP2RMIX Input 4 Source */
 285	{ 0x0695, 0x0080 },   /* R1685  - DSP2RMIX Input 4 Volume */
 286	{ 0x0696, 0x0000 },   /* R1686  - DSP2AUX1MIX Input 1 Source */
 287	{ 0x0697, 0x0000 },   /* R1687  - DSP2AUX2MIX Input 1 Source */
 288	{ 0x0698, 0x0000 },   /* R1688  - DSP2AUX3MIX Input 1 Source */
 289	{ 0x0699, 0x0000 },   /* R1689  - DSP2AUX4MIX Input 1 Source */
 290	{ 0x069A, 0x0000 },   /* R1690  - DSP2AUX5MIX Input 1 Source */
 291	{ 0x069B, 0x0000 },   /* R1691  - DSP2AUX6MIX Input 1 Source */
 292	{ 0x0700, 0xA101 },   /* R1792  - GPIO CTRL 1 */
 293	{ 0x0701, 0xA101 },   /* R1793  - GPIO CTRL 2 */
 294	{ 0x0702, 0xA101 },   /* R1794  - GPIO CTRL 3 */
 295	{ 0x0703, 0xA101 },   /* R1795  - GPIO CTRL 4 */
 296	{ 0x0709, 0x0000 },   /* R1801  - Misc Pad Ctrl 1 */
 297	{ 0x0801, 0x00FF },   /* R2049  - Interrupt Status 1 Mask */
 298	{ 0x0804, 0xFFFF },   /* R2052  - Interrupt Status 2 Mask */
 299	{ 0x0808, 0x0000 },   /* R2056  - Interrupt Control */
 300	{ 0x0900, 0x0000 },   /* R2304  - EQL_1 */
 301	{ 0x0901, 0x0000 },   /* R2305  - EQL_2 */
 302	{ 0x0902, 0x0000 },   /* R2306  - EQL_3 */
 303	{ 0x0903, 0x0000 },   /* R2307  - EQL_4 */
 304	{ 0x0904, 0x0000 },   /* R2308  - EQL_5 */
 305	{ 0x0905, 0x0000 },   /* R2309  - EQL_6 */
 306	{ 0x0906, 0x0000 },   /* R2310  - EQL_7 */
 307	{ 0x0907, 0x0000 },   /* R2311  - EQL_8 */
 308	{ 0x0908, 0x0000 },   /* R2312  - EQL_9 */
 309	{ 0x0909, 0x0000 },   /* R2313  - EQL_10 */
 310	{ 0x090A, 0x0000 },   /* R2314  - EQL_11 */
 311	{ 0x090B, 0x0000 },   /* R2315  - EQL_12 */
 312	{ 0x090C, 0x0000 },   /* R2316  - EQL_13 */
 313	{ 0x090D, 0x0000 },   /* R2317  - EQL_14 */
 314	{ 0x090E, 0x0000 },   /* R2318  - EQL_15 */
 315	{ 0x090F, 0x0000 },   /* R2319  - EQL_16 */
 316	{ 0x0910, 0x0000 },   /* R2320  - EQL_17 */
 317	{ 0x0911, 0x0000 },   /* R2321  - EQL_18 */
 318	{ 0x0912, 0x0000 },   /* R2322  - EQL_19 */
 319	{ 0x0913, 0x0000 },   /* R2323  - EQL_20 */
 320	{ 0x0916, 0x0000 },   /* R2326  - EQR_1 */
 321	{ 0x0917, 0x0000 },   /* R2327  - EQR_2 */
 322	{ 0x0918, 0x0000 },   /* R2328  - EQR_3 */
 323	{ 0x0919, 0x0000 },   /* R2329  - EQR_4 */
 324	{ 0x091A, 0x0000 },   /* R2330  - EQR_5 */
 325	{ 0x091B, 0x0000 },   /* R2331  - EQR_6 */
 326	{ 0x091C, 0x0000 },   /* R2332  - EQR_7 */
 327	{ 0x091D, 0x0000 },   /* R2333  - EQR_8 */
 328	{ 0x091E, 0x0000 },   /* R2334  - EQR_9 */
 329	{ 0x091F, 0x0000 },   /* R2335  - EQR_10 */
 330	{ 0x0920, 0x0000 },   /* R2336  - EQR_11 */
 331	{ 0x0921, 0x0000 },   /* R2337  - EQR_12 */
 332	{ 0x0922, 0x0000 },   /* R2338  - EQR_13 */
 333	{ 0x0923, 0x0000 },   /* R2339  - EQR_14 */
 334	{ 0x0924, 0x0000 },   /* R2340  - EQR_15 */
 335	{ 0x0925, 0x0000 },   /* R2341  - EQR_16 */
 336	{ 0x0926, 0x0000 },   /* R2342  - EQR_17 */
 337	{ 0x0927, 0x0000 },   /* R2343  - EQR_18 */
 338	{ 0x0928, 0x0000 },   /* R2344  - EQR_19 */
 339	{ 0x0929, 0x0000 },   /* R2345  - EQR_20 */
 340	{ 0x093E, 0x0000 },   /* R2366  - HPLPF1_1 */
 341	{ 0x093F, 0x0000 },   /* R2367  - HPLPF1_2 */
 342	{ 0x0942, 0x0000 },   /* R2370  - HPLPF2_1 */
 343	{ 0x0943, 0x0000 },   /* R2371  - HPLPF2_2 */
 344	{ 0x0A00, 0x0000 },   /* R2560  - DSP1 Control 1 */
 345	{ 0x0A02, 0x0000 },   /* R2562  - DSP1 Control 2 */
 346	{ 0x0A03, 0x0000 },   /* R2563  - DSP1 Control 3 */
 347	{ 0x0A04, 0x0000 },   /* R2564  - DSP1 Control 4 */
 348	{ 0x0A06, 0x0000 },   /* R2566  - DSP1 Control 5 */
 349	{ 0x0A07, 0x0000 },   /* R2567  - DSP1 Control 6 */
 350	{ 0x0A08, 0x0000 },   /* R2568  - DSP1 Control 7 */
 351	{ 0x0A09, 0x0000 },   /* R2569  - DSP1 Control 8 */
 352	{ 0x0A0A, 0x0000 },   /* R2570  - DSP1 Control 9 */
 353	{ 0x0A0B, 0x0000 },   /* R2571  - DSP1 Control 10 */
 354	{ 0x0A0C, 0x0000 },   /* R2572  - DSP1 Control 11 */
 355	{ 0x0A0D, 0x0000 },   /* R2573  - DSP1 Control 12 */
 356	{ 0x0A0F, 0x0000 },   /* R2575  - DSP1 Control 13 */
 357	{ 0x0A10, 0x0000 },   /* R2576  - DSP1 Control 14 */
 358	{ 0x0A11, 0x0000 },   /* R2577  - DSP1 Control 15 */
 359	{ 0x0A12, 0x0000 },   /* R2578  - DSP1 Control 16 */
 360	{ 0x0A13, 0x0000 },   /* R2579  - DSP1 Control 17 */
 361	{ 0x0A14, 0x0000 },   /* R2580  - DSP1 Control 18 */
 362	{ 0x0A16, 0x0000 },   /* R2582  - DSP1 Control 19 */
 363	{ 0x0A17, 0x0000 },   /* R2583  - DSP1 Control 20 */
 364	{ 0x0A18, 0x0000 },   /* R2584  - DSP1 Control 21 */
 365	{ 0x0A1A, 0x1800 },   /* R2586  - DSP1 Control 22 */
 366	{ 0x0A1B, 0x1000 },   /* R2587  - DSP1 Control 23 */
 367	{ 0x0A1C, 0x0400 },   /* R2588  - DSP1 Control 24 */
 368	{ 0x0A1E, 0x0000 },   /* R2590  - DSP1 Control 25 */
 369	{ 0x0A20, 0x0000 },   /* R2592  - DSP1 Control 26 */
 370	{ 0x0A21, 0x0000 },   /* R2593  - DSP1 Control 27 */
 371	{ 0x0A22, 0x0000 },   /* R2594  - DSP1 Control 28 */
 372	{ 0x0A23, 0x0000 },   /* R2595  - DSP1 Control 29 */
 373	{ 0x0A24, 0x0000 },   /* R2596  - DSP1 Control 30 */
 374	{ 0x0A26, 0x0000 },   /* R2598  - DSP1 Control 31 */
 375	{ 0x0B00, 0x0000 },   /* R2816  - DSP2 Control 1 */
 376	{ 0x0B02, 0x0000 },   /* R2818  - DSP2 Control 2 */
 377	{ 0x0B03, 0x0000 },   /* R2819  - DSP2 Control 3 */
 378	{ 0x0B04, 0x0000 },   /* R2820  - DSP2 Control 4 */
 379	{ 0x0B06, 0x0000 },   /* R2822  - DSP2 Control 5 */
 380	{ 0x0B07, 0x0000 },   /* R2823  - DSP2 Control 6 */
 381	{ 0x0B08, 0x0000 },   /* R2824  - DSP2 Control 7 */
 382	{ 0x0B09, 0x0000 },   /* R2825  - DSP2 Control 8 */
 383	{ 0x0B0A, 0x0000 },   /* R2826  - DSP2 Control 9 */
 384	{ 0x0B0B, 0x0000 },   /* R2827  - DSP2 Control 10 */
 385	{ 0x0B0C, 0x0000 },   /* R2828  - DSP2 Control 11 */
 386	{ 0x0B0D, 0x0000 },   /* R2829  - DSP2 Control 12 */
 387	{ 0x0B0F, 0x0000 },   /* R2831  - DSP2 Control 13 */
 388	{ 0x0B10, 0x0000 },   /* R2832  - DSP2 Control 14 */
 389	{ 0x0B11, 0x0000 },   /* R2833  - DSP2 Control 15 */
 390	{ 0x0B12, 0x0000 },   /* R2834  - DSP2 Control 16 */
 391	{ 0x0B13, 0x0000 },   /* R2835  - DSP2 Control 17 */
 392	{ 0x0B14, 0x0000 },   /* R2836  - DSP2 Control 18 */
 393	{ 0x0B16, 0x0000 },   /* R2838  - DSP2 Control 19 */
 394	{ 0x0B17, 0x0000 },   /* R2839  - DSP2 Control 20 */
 395	{ 0x0B18, 0x0000 },   /* R2840  - DSP2 Control 21 */
 396	{ 0x0B1A, 0x0800 },   /* R2842  - DSP2 Control 22 */
 397	{ 0x0B1B, 0x1000 },   /* R2843  - DSP2 Control 23 */
 398	{ 0x0B1C, 0x0400 },   /* R2844  - DSP2 Control 24 */
 399	{ 0x0B1E, 0x0000 },   /* R2846  - DSP2 Control 25 */
 400	{ 0x0B20, 0x0000 },   /* R2848  - DSP2 Control 26 */
 401	{ 0x0B21, 0x0000 },   /* R2849  - DSP2 Control 27 */
 402	{ 0x0B22, 0x0000 },   /* R2850  - DSP2 Control 28 */
 403	{ 0x0B23, 0x0000 },   /* R2851  - DSP2 Control 29 */
 404	{ 0x0B24, 0x0000 },   /* R2852  - DSP2 Control 30 */
 405	{ 0x0B26, 0x0000 },   /* R2854  - DSP2 Control 31 */
 406};
 407
 408static bool wm2200_volatile_register(struct device *dev, unsigned int reg)
 409{
 
 
 
 
 
 
 
 
 
 
 410	switch (reg) {
 411	case WM2200_SOFTWARE_RESET:
 412	case WM2200_DEVICE_REVISION:
 413	case WM2200_ADPS1_IRQ0:
 414	case WM2200_ADPS1_IRQ1:
 415	case WM2200_INTERRUPT_STATUS_1:
 416	case WM2200_INTERRUPT_STATUS_2:
 417	case WM2200_INTERRUPT_RAW_STATUS_2:
 418		return true;
 419	default:
 420		return false;
 421	}
 422}
 423
 424static bool wm2200_readable_register(struct device *dev, unsigned int reg)
 425{
 
 
 
 
 
 
 
 
 
 
 426	switch (reg) {
 427	case WM2200_SOFTWARE_RESET:
 428	case WM2200_DEVICE_REVISION:
 429	case WM2200_TONE_GENERATOR_1:
 430	case WM2200_CLOCKING_3:
 431	case WM2200_CLOCKING_4:
 432	case WM2200_FLL_CONTROL_1:
 433	case WM2200_FLL_CONTROL_2:
 434	case WM2200_FLL_CONTROL_3:
 435	case WM2200_FLL_CONTROL_4:
 436	case WM2200_FLL_CONTROL_6:
 437	case WM2200_FLL_CONTROL_7:
 438	case WM2200_FLL_EFS_1:
 439	case WM2200_FLL_EFS_2:
 440	case WM2200_MIC_CHARGE_PUMP_1:
 441	case WM2200_MIC_CHARGE_PUMP_2:
 442	case WM2200_DM_CHARGE_PUMP_1:
 443	case WM2200_MIC_BIAS_CTRL_1:
 444	case WM2200_MIC_BIAS_CTRL_2:
 445	case WM2200_EAR_PIECE_CTRL_1:
 446	case WM2200_EAR_PIECE_CTRL_2:
 447	case WM2200_INPUT_ENABLES:
 448	case WM2200_IN1L_CONTROL:
 449	case WM2200_IN1R_CONTROL:
 450	case WM2200_IN2L_CONTROL:
 451	case WM2200_IN2R_CONTROL:
 452	case WM2200_IN3L_CONTROL:
 453	case WM2200_IN3R_CONTROL:
 454	case WM2200_RXANC_SRC:
 455	case WM2200_INPUT_VOLUME_RAMP:
 456	case WM2200_ADC_DIGITAL_VOLUME_1L:
 457	case WM2200_ADC_DIGITAL_VOLUME_1R:
 458	case WM2200_ADC_DIGITAL_VOLUME_2L:
 459	case WM2200_ADC_DIGITAL_VOLUME_2R:
 460	case WM2200_ADC_DIGITAL_VOLUME_3L:
 461	case WM2200_ADC_DIGITAL_VOLUME_3R:
 462	case WM2200_OUTPUT_ENABLES:
 463	case WM2200_DAC_VOLUME_LIMIT_1L:
 464	case WM2200_DAC_VOLUME_LIMIT_1R:
 465	case WM2200_DAC_VOLUME_LIMIT_2L:
 466	case WM2200_DAC_VOLUME_LIMIT_2R:
 467	case WM2200_DAC_AEC_CONTROL_1:
 468	case WM2200_OUTPUT_VOLUME_RAMP:
 469	case WM2200_DAC_DIGITAL_VOLUME_1L:
 470	case WM2200_DAC_DIGITAL_VOLUME_1R:
 471	case WM2200_DAC_DIGITAL_VOLUME_2L:
 472	case WM2200_DAC_DIGITAL_VOLUME_2R:
 473	case WM2200_PDM_1:
 474	case WM2200_PDM_2:
 475	case WM2200_AUDIO_IF_1_1:
 476	case WM2200_AUDIO_IF_1_2:
 477	case WM2200_AUDIO_IF_1_3:
 478	case WM2200_AUDIO_IF_1_4:
 479	case WM2200_AUDIO_IF_1_5:
 480	case WM2200_AUDIO_IF_1_6:
 481	case WM2200_AUDIO_IF_1_7:
 482	case WM2200_AUDIO_IF_1_8:
 483	case WM2200_AUDIO_IF_1_9:
 484	case WM2200_AUDIO_IF_1_10:
 485	case WM2200_AUDIO_IF_1_11:
 486	case WM2200_AUDIO_IF_1_12:
 487	case WM2200_AUDIO_IF_1_13:
 488	case WM2200_AUDIO_IF_1_14:
 489	case WM2200_AUDIO_IF_1_15:
 490	case WM2200_AUDIO_IF_1_16:
 491	case WM2200_AUDIO_IF_1_17:
 492	case WM2200_AUDIO_IF_1_18:
 493	case WM2200_AUDIO_IF_1_19:
 494	case WM2200_AUDIO_IF_1_20:
 495	case WM2200_AUDIO_IF_1_21:
 496	case WM2200_AUDIO_IF_1_22:
 497	case WM2200_OUT1LMIX_INPUT_1_SOURCE:
 498	case WM2200_OUT1LMIX_INPUT_1_VOLUME:
 499	case WM2200_OUT1LMIX_INPUT_2_SOURCE:
 500	case WM2200_OUT1LMIX_INPUT_2_VOLUME:
 501	case WM2200_OUT1LMIX_INPUT_3_SOURCE:
 502	case WM2200_OUT1LMIX_INPUT_3_VOLUME:
 503	case WM2200_OUT1LMIX_INPUT_4_SOURCE:
 504	case WM2200_OUT1LMIX_INPUT_4_VOLUME:
 505	case WM2200_OUT1RMIX_INPUT_1_SOURCE:
 506	case WM2200_OUT1RMIX_INPUT_1_VOLUME:
 507	case WM2200_OUT1RMIX_INPUT_2_SOURCE:
 508	case WM2200_OUT1RMIX_INPUT_2_VOLUME:
 509	case WM2200_OUT1RMIX_INPUT_3_SOURCE:
 510	case WM2200_OUT1RMIX_INPUT_3_VOLUME:
 511	case WM2200_OUT1RMIX_INPUT_4_SOURCE:
 512	case WM2200_OUT1RMIX_INPUT_4_VOLUME:
 513	case WM2200_OUT2LMIX_INPUT_1_SOURCE:
 514	case WM2200_OUT2LMIX_INPUT_1_VOLUME:
 515	case WM2200_OUT2LMIX_INPUT_2_SOURCE:
 516	case WM2200_OUT2LMIX_INPUT_2_VOLUME:
 517	case WM2200_OUT2LMIX_INPUT_3_SOURCE:
 518	case WM2200_OUT2LMIX_INPUT_3_VOLUME:
 519	case WM2200_OUT2LMIX_INPUT_4_SOURCE:
 520	case WM2200_OUT2LMIX_INPUT_4_VOLUME:
 521	case WM2200_OUT2RMIX_INPUT_1_SOURCE:
 522	case WM2200_OUT2RMIX_INPUT_1_VOLUME:
 523	case WM2200_OUT2RMIX_INPUT_2_SOURCE:
 524	case WM2200_OUT2RMIX_INPUT_2_VOLUME:
 525	case WM2200_OUT2RMIX_INPUT_3_SOURCE:
 526	case WM2200_OUT2RMIX_INPUT_3_VOLUME:
 527	case WM2200_OUT2RMIX_INPUT_4_SOURCE:
 528	case WM2200_OUT2RMIX_INPUT_4_VOLUME:
 529	case WM2200_AIF1TX1MIX_INPUT_1_SOURCE:
 530	case WM2200_AIF1TX1MIX_INPUT_1_VOLUME:
 531	case WM2200_AIF1TX1MIX_INPUT_2_SOURCE:
 532	case WM2200_AIF1TX1MIX_INPUT_2_VOLUME:
 533	case WM2200_AIF1TX1MIX_INPUT_3_SOURCE:
 534	case WM2200_AIF1TX1MIX_INPUT_3_VOLUME:
 535	case WM2200_AIF1TX1MIX_INPUT_4_SOURCE:
 536	case WM2200_AIF1TX1MIX_INPUT_4_VOLUME:
 537	case WM2200_AIF1TX2MIX_INPUT_1_SOURCE:
 538	case WM2200_AIF1TX2MIX_INPUT_1_VOLUME:
 539	case WM2200_AIF1TX2MIX_INPUT_2_SOURCE:
 540	case WM2200_AIF1TX2MIX_INPUT_2_VOLUME:
 541	case WM2200_AIF1TX2MIX_INPUT_3_SOURCE:
 542	case WM2200_AIF1TX2MIX_INPUT_3_VOLUME:
 543	case WM2200_AIF1TX2MIX_INPUT_4_SOURCE:
 544	case WM2200_AIF1TX2MIX_INPUT_4_VOLUME:
 545	case WM2200_AIF1TX3MIX_INPUT_1_SOURCE:
 546	case WM2200_AIF1TX3MIX_INPUT_1_VOLUME:
 547	case WM2200_AIF1TX3MIX_INPUT_2_SOURCE:
 548	case WM2200_AIF1TX3MIX_INPUT_2_VOLUME:
 549	case WM2200_AIF1TX3MIX_INPUT_3_SOURCE:
 550	case WM2200_AIF1TX3MIX_INPUT_3_VOLUME:
 551	case WM2200_AIF1TX3MIX_INPUT_4_SOURCE:
 552	case WM2200_AIF1TX3MIX_INPUT_4_VOLUME:
 553	case WM2200_AIF1TX4MIX_INPUT_1_SOURCE:
 554	case WM2200_AIF1TX4MIX_INPUT_1_VOLUME:
 555	case WM2200_AIF1TX4MIX_INPUT_2_SOURCE:
 556	case WM2200_AIF1TX4MIX_INPUT_2_VOLUME:
 557	case WM2200_AIF1TX4MIX_INPUT_3_SOURCE:
 558	case WM2200_AIF1TX4MIX_INPUT_3_VOLUME:
 559	case WM2200_AIF1TX4MIX_INPUT_4_SOURCE:
 560	case WM2200_AIF1TX4MIX_INPUT_4_VOLUME:
 561	case WM2200_AIF1TX5MIX_INPUT_1_SOURCE:
 562	case WM2200_AIF1TX5MIX_INPUT_1_VOLUME:
 563	case WM2200_AIF1TX5MIX_INPUT_2_SOURCE:
 564	case WM2200_AIF1TX5MIX_INPUT_2_VOLUME:
 565	case WM2200_AIF1TX5MIX_INPUT_3_SOURCE:
 566	case WM2200_AIF1TX5MIX_INPUT_3_VOLUME:
 567	case WM2200_AIF1TX5MIX_INPUT_4_SOURCE:
 568	case WM2200_AIF1TX5MIX_INPUT_4_VOLUME:
 569	case WM2200_AIF1TX6MIX_INPUT_1_SOURCE:
 570	case WM2200_AIF1TX6MIX_INPUT_1_VOLUME:
 571	case WM2200_AIF1TX6MIX_INPUT_2_SOURCE:
 572	case WM2200_AIF1TX6MIX_INPUT_2_VOLUME:
 573	case WM2200_AIF1TX6MIX_INPUT_3_SOURCE:
 574	case WM2200_AIF1TX6MIX_INPUT_3_VOLUME:
 575	case WM2200_AIF1TX6MIX_INPUT_4_SOURCE:
 576	case WM2200_AIF1TX6MIX_INPUT_4_VOLUME:
 577	case WM2200_EQLMIX_INPUT_1_SOURCE:
 578	case WM2200_EQLMIX_INPUT_1_VOLUME:
 579	case WM2200_EQLMIX_INPUT_2_SOURCE:
 580	case WM2200_EQLMIX_INPUT_2_VOLUME:
 581	case WM2200_EQLMIX_INPUT_3_SOURCE:
 582	case WM2200_EQLMIX_INPUT_3_VOLUME:
 583	case WM2200_EQLMIX_INPUT_4_SOURCE:
 584	case WM2200_EQLMIX_INPUT_4_VOLUME:
 585	case WM2200_EQRMIX_INPUT_1_SOURCE:
 586	case WM2200_EQRMIX_INPUT_1_VOLUME:
 587	case WM2200_EQRMIX_INPUT_2_SOURCE:
 588	case WM2200_EQRMIX_INPUT_2_VOLUME:
 589	case WM2200_EQRMIX_INPUT_3_SOURCE:
 590	case WM2200_EQRMIX_INPUT_3_VOLUME:
 591	case WM2200_EQRMIX_INPUT_4_SOURCE:
 592	case WM2200_EQRMIX_INPUT_4_VOLUME:
 593	case WM2200_LHPF1MIX_INPUT_1_SOURCE:
 594	case WM2200_LHPF1MIX_INPUT_1_VOLUME:
 595	case WM2200_LHPF1MIX_INPUT_2_SOURCE:
 596	case WM2200_LHPF1MIX_INPUT_2_VOLUME:
 597	case WM2200_LHPF1MIX_INPUT_3_SOURCE:
 598	case WM2200_LHPF1MIX_INPUT_3_VOLUME:
 599	case WM2200_LHPF1MIX_INPUT_4_SOURCE:
 600	case WM2200_LHPF1MIX_INPUT_4_VOLUME:
 601	case WM2200_LHPF2MIX_INPUT_1_SOURCE:
 602	case WM2200_LHPF2MIX_INPUT_1_VOLUME:
 603	case WM2200_LHPF2MIX_INPUT_2_SOURCE:
 604	case WM2200_LHPF2MIX_INPUT_2_VOLUME:
 605	case WM2200_LHPF2MIX_INPUT_3_SOURCE:
 606	case WM2200_LHPF2MIX_INPUT_3_VOLUME:
 607	case WM2200_LHPF2MIX_INPUT_4_SOURCE:
 608	case WM2200_LHPF2MIX_INPUT_4_VOLUME:
 609	case WM2200_DSP1LMIX_INPUT_1_SOURCE:
 610	case WM2200_DSP1LMIX_INPUT_1_VOLUME:
 611	case WM2200_DSP1LMIX_INPUT_2_SOURCE:
 612	case WM2200_DSP1LMIX_INPUT_2_VOLUME:
 613	case WM2200_DSP1LMIX_INPUT_3_SOURCE:
 614	case WM2200_DSP1LMIX_INPUT_3_VOLUME:
 615	case WM2200_DSP1LMIX_INPUT_4_SOURCE:
 616	case WM2200_DSP1LMIX_INPUT_4_VOLUME:
 617	case WM2200_DSP1RMIX_INPUT_1_SOURCE:
 618	case WM2200_DSP1RMIX_INPUT_1_VOLUME:
 619	case WM2200_DSP1RMIX_INPUT_2_SOURCE:
 620	case WM2200_DSP1RMIX_INPUT_2_VOLUME:
 621	case WM2200_DSP1RMIX_INPUT_3_SOURCE:
 622	case WM2200_DSP1RMIX_INPUT_3_VOLUME:
 623	case WM2200_DSP1RMIX_INPUT_4_SOURCE:
 624	case WM2200_DSP1RMIX_INPUT_4_VOLUME:
 625	case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE:
 626	case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE:
 627	case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE:
 628	case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE:
 629	case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE:
 630	case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE:
 631	case WM2200_DSP2LMIX_INPUT_1_SOURCE:
 632	case WM2200_DSP2LMIX_INPUT_1_VOLUME:
 633	case WM2200_DSP2LMIX_INPUT_2_SOURCE:
 634	case WM2200_DSP2LMIX_INPUT_2_VOLUME:
 635	case WM2200_DSP2LMIX_INPUT_3_SOURCE:
 636	case WM2200_DSP2LMIX_INPUT_3_VOLUME:
 637	case WM2200_DSP2LMIX_INPUT_4_SOURCE:
 638	case WM2200_DSP2LMIX_INPUT_4_VOLUME:
 639	case WM2200_DSP2RMIX_INPUT_1_SOURCE:
 640	case WM2200_DSP2RMIX_INPUT_1_VOLUME:
 641	case WM2200_DSP2RMIX_INPUT_2_SOURCE:
 642	case WM2200_DSP2RMIX_INPUT_2_VOLUME:
 643	case WM2200_DSP2RMIX_INPUT_3_SOURCE:
 644	case WM2200_DSP2RMIX_INPUT_3_VOLUME:
 645	case WM2200_DSP2RMIX_INPUT_4_SOURCE:
 646	case WM2200_DSP2RMIX_INPUT_4_VOLUME:
 647	case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE:
 648	case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE:
 649	case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE:
 650	case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE:
 651	case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE:
 652	case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE:
 653	case WM2200_GPIO_CTRL_1:
 654	case WM2200_GPIO_CTRL_2:
 655	case WM2200_GPIO_CTRL_3:
 656	case WM2200_GPIO_CTRL_4:
 657	case WM2200_ADPS1_IRQ0:
 658	case WM2200_ADPS1_IRQ1:
 659	case WM2200_MISC_PAD_CTRL_1:
 660	case WM2200_INTERRUPT_STATUS_1:
 661	case WM2200_INTERRUPT_STATUS_1_MASK:
 662	case WM2200_INTERRUPT_STATUS_2:
 663	case WM2200_INTERRUPT_RAW_STATUS_2:
 664	case WM2200_INTERRUPT_STATUS_2_MASK:
 665	case WM2200_INTERRUPT_CONTROL:
 666	case WM2200_EQL_1:
 667	case WM2200_EQL_2:
 668	case WM2200_EQL_3:
 669	case WM2200_EQL_4:
 670	case WM2200_EQL_5:
 671	case WM2200_EQL_6:
 672	case WM2200_EQL_7:
 673	case WM2200_EQL_8:
 674	case WM2200_EQL_9:
 675	case WM2200_EQL_10:
 676	case WM2200_EQL_11:
 677	case WM2200_EQL_12:
 678	case WM2200_EQL_13:
 679	case WM2200_EQL_14:
 680	case WM2200_EQL_15:
 681	case WM2200_EQL_16:
 682	case WM2200_EQL_17:
 683	case WM2200_EQL_18:
 684	case WM2200_EQL_19:
 685	case WM2200_EQL_20:
 686	case WM2200_EQR_1:
 687	case WM2200_EQR_2:
 688	case WM2200_EQR_3:
 689	case WM2200_EQR_4:
 690	case WM2200_EQR_5:
 691	case WM2200_EQR_6:
 692	case WM2200_EQR_7:
 693	case WM2200_EQR_8:
 694	case WM2200_EQR_9:
 695	case WM2200_EQR_10:
 696	case WM2200_EQR_11:
 697	case WM2200_EQR_12:
 698	case WM2200_EQR_13:
 699	case WM2200_EQR_14:
 700	case WM2200_EQR_15:
 701	case WM2200_EQR_16:
 702	case WM2200_EQR_17:
 703	case WM2200_EQR_18:
 704	case WM2200_EQR_19:
 705	case WM2200_EQR_20:
 706	case WM2200_HPLPF1_1:
 707	case WM2200_HPLPF1_2:
 708	case WM2200_HPLPF2_1:
 709	case WM2200_HPLPF2_2:
 710	case WM2200_DSP1_CONTROL_1:
 711	case WM2200_DSP1_CONTROL_2:
 712	case WM2200_DSP1_CONTROL_3:
 713	case WM2200_DSP1_CONTROL_4:
 714	case WM2200_DSP1_CONTROL_5:
 715	case WM2200_DSP1_CONTROL_6:
 716	case WM2200_DSP1_CONTROL_7:
 717	case WM2200_DSP1_CONTROL_8:
 718	case WM2200_DSP1_CONTROL_9:
 719	case WM2200_DSP1_CONTROL_10:
 720	case WM2200_DSP1_CONTROL_11:
 721	case WM2200_DSP1_CONTROL_12:
 722	case WM2200_DSP1_CONTROL_13:
 723	case WM2200_DSP1_CONTROL_14:
 724	case WM2200_DSP1_CONTROL_15:
 725	case WM2200_DSP1_CONTROL_16:
 726	case WM2200_DSP1_CONTROL_17:
 727	case WM2200_DSP1_CONTROL_18:
 728	case WM2200_DSP1_CONTROL_19:
 729	case WM2200_DSP1_CONTROL_20:
 730	case WM2200_DSP1_CONTROL_21:
 731	case WM2200_DSP1_CONTROL_22:
 732	case WM2200_DSP1_CONTROL_23:
 733	case WM2200_DSP1_CONTROL_24:
 734	case WM2200_DSP1_CONTROL_25:
 735	case WM2200_DSP1_CONTROL_26:
 736	case WM2200_DSP1_CONTROL_27:
 737	case WM2200_DSP1_CONTROL_28:
 738	case WM2200_DSP1_CONTROL_29:
 739	case WM2200_DSP1_CONTROL_30:
 740	case WM2200_DSP1_CONTROL_31:
 741	case WM2200_DSP2_CONTROL_1:
 742	case WM2200_DSP2_CONTROL_2:
 743	case WM2200_DSP2_CONTROL_3:
 744	case WM2200_DSP2_CONTROL_4:
 745	case WM2200_DSP2_CONTROL_5:
 746	case WM2200_DSP2_CONTROL_6:
 747	case WM2200_DSP2_CONTROL_7:
 748	case WM2200_DSP2_CONTROL_8:
 749	case WM2200_DSP2_CONTROL_9:
 750	case WM2200_DSP2_CONTROL_10:
 751	case WM2200_DSP2_CONTROL_11:
 752	case WM2200_DSP2_CONTROL_12:
 753	case WM2200_DSP2_CONTROL_13:
 754	case WM2200_DSP2_CONTROL_14:
 755	case WM2200_DSP2_CONTROL_15:
 756	case WM2200_DSP2_CONTROL_16:
 757	case WM2200_DSP2_CONTROL_17:
 758	case WM2200_DSP2_CONTROL_18:
 759	case WM2200_DSP2_CONTROL_19:
 760	case WM2200_DSP2_CONTROL_20:
 761	case WM2200_DSP2_CONTROL_21:
 762	case WM2200_DSP2_CONTROL_22:
 763	case WM2200_DSP2_CONTROL_23:
 764	case WM2200_DSP2_CONTROL_24:
 765	case WM2200_DSP2_CONTROL_25:
 766	case WM2200_DSP2_CONTROL_26:
 767	case WM2200_DSP2_CONTROL_27:
 768	case WM2200_DSP2_CONTROL_28:
 769	case WM2200_DSP2_CONTROL_29:
 770	case WM2200_DSP2_CONTROL_30:
 771	case WM2200_DSP2_CONTROL_31:
 772		return true;
 773	default:
 774		return false;
 775	}
 776}
 777
 778static const struct reg_default wm2200_reva_patch[] = {
 779	{ 0x07, 0x0003 },
 780	{ 0x102, 0x0200 },
 781	{ 0x203, 0x0084 },
 782	{ 0x201, 0x83FF },
 783	{ 0x20C, 0x0062 },
 784	{ 0x20D, 0x0062 },
 785	{ 0x207, 0x2002 },
 786	{ 0x208, 0x20C0 },
 787	{ 0x21D, 0x01C0 },
 788	{ 0x50A, 0x0001 },
 789	{ 0x50B, 0x0002 },
 790	{ 0x50C, 0x0003 },
 791	{ 0x50D, 0x0004 },
 792	{ 0x50E, 0x0005 },
 793	{ 0x510, 0x0001 },
 794	{ 0x511, 0x0002 },
 795	{ 0x512, 0x0003 },
 796	{ 0x513, 0x0004 },
 797	{ 0x514, 0x0005 },
 798	{ 0x515, 0x0000 },
 799	{ 0x201, 0x8084 },
 800	{ 0x202, 0xBBDE },
 801	{ 0x203, 0x00EC },
 802	{ 0x500, 0x8000 },
 803	{ 0x507, 0x1820 },
 804	{ 0x508, 0x1820 },
 805	{ 0x505, 0x0300 },
 806	{ 0x506, 0x0300 },
 807	{ 0x302, 0x2280 },
 808	{ 0x303, 0x0080 },
 809	{ 0x304, 0x2280 },
 810	{ 0x305, 0x0080 },
 811	{ 0x306, 0x2280 },
 812	{ 0x307, 0x0080 },
 813	{ 0x401, 0x0080 },
 814	{ 0x402, 0x0080 },
 815	{ 0x417, 0x3069 },
 816	{ 0x900, 0x6318 },
 817	{ 0x901, 0x6300 },
 818	{ 0x902, 0x0FC8 },
 819	{ 0x903, 0x03FE },
 820	{ 0x904, 0x00E0 },
 821	{ 0x905, 0x1EC4 },
 822	{ 0x906, 0xF136 },
 823	{ 0x907, 0x0409 },
 824	{ 0x908, 0x04CC },
 825	{ 0x909, 0x1C9B },
 826	{ 0x90A, 0xF337 },
 827	{ 0x90B, 0x040B },
 828	{ 0x90C, 0x0CBB },
 829	{ 0x90D, 0x16F8 },
 830	{ 0x90E, 0xF7D9 },
 831	{ 0x90F, 0x040A },
 832	{ 0x910, 0x1F14 },
 833	{ 0x911, 0x058C },
 834	{ 0x912, 0x0563 },
 835	{ 0x913, 0x4000 },
 836	{ 0x916, 0x6318 },
 837	{ 0x917, 0x6300 },
 838	{ 0x918, 0x0FC8 },
 839	{ 0x919, 0x03FE },
 840	{ 0x91A, 0x00E0 },
 841	{ 0x91B, 0x1EC4 },
 842	{ 0x91C, 0xF136 },
 843	{ 0x91D, 0x0409 },
 844	{ 0x91E, 0x04CC },
 845	{ 0x91F, 0x1C9B },
 846	{ 0x920, 0xF337 },
 847	{ 0x921, 0x040B },
 848	{ 0x922, 0x0CBB },
 849	{ 0x923, 0x16F8 },
 850	{ 0x924, 0xF7D9 },
 851	{ 0x925, 0x040A },
 852	{ 0x926, 0x1F14 },
 853	{ 0x927, 0x058C },
 854	{ 0x928, 0x0563 },
 855	{ 0x929, 0x4000 },
 856	{ 0x709, 0x2000 },
 857	{ 0x207, 0x200E },
 858	{ 0x208, 0x20D4 },
 859	{ 0x20A, 0x0080 },
 860	{ 0x07, 0x0000 },
 861};
 862
 863static int wm2200_reset(struct wm2200_priv *wm2200)
 864{
 865	if (wm2200->pdata.reset) {
 866		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
 867		gpio_set_value_cansleep(wm2200->pdata.reset, 1);
 
 868
 869		return 0;
 870	} else {
 871		return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET,
 872				    0x2200);
 873	}
 874}
 875
 876static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
 877static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
 878static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
 879
 880static const char *wm2200_mixer_texts[] = {
 881	"None",
 882	"Tone Generator",
 883	"AEC loopback",
 884	"IN1L",
 885	"IN1R",
 886	"IN2L",
 887	"IN2R",
 888	"IN3L",
 889	"IN3R",
 890	"AIF1RX1",
 891	"AIF1RX2",
 892	"AIF1RX3",
 893	"AIF1RX4",
 894	"AIF1RX5",
 895	"AIF1RX6",
 896	"EQL",
 897	"EQR",
 898	"LHPF1",
 899	"LHPF2",
 900	"LHPF3",
 901	"LHPF4",
 902	"DSP1.1",
 903	"DSP1.2",
 904	"DSP1.3",
 905	"DSP1.4",
 906	"DSP1.5",
 907	"DSP1.6",
 908	"DSP2.1",
 909	"DSP2.2",
 910	"DSP2.3",
 911	"DSP2.4",
 912	"DSP2.5",
 913	"DSP2.6",
 914};
 915
 916static int wm2200_mixer_values[] = {
 917	0x00,
 918	0x04,   /* Tone */
 919	0x08,   /* AEC */
 920	0x10,   /* Input */
 921	0x11,
 922	0x12,
 923	0x13,
 924	0x14,
 925	0x15,
 926	0x20,   /* AIF */
 927	0x21,
 928	0x22,
 929	0x23,
 930	0x24,
 931	0x25,
 932	0x50,   /* EQ */
 933	0x51,
 934	0x52,
 935	0x60,   /* LHPF1 */
 936	0x61,   /* LHPF2 */
 937	0x68,   /* DSP1 */
 938	0x69,
 939	0x6a,
 940	0x6b,
 941	0x6c,
 942	0x6d,
 943	0x70,   /* DSP2 */
 944	0x71,
 945	0x72,
 946	0x73,
 947	0x74,
 948	0x75,
 949};
 950
 951#define WM2200_MIXER_CONTROLS(name, base) \
 952	SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
 953		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
 954	SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
 955		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
 956	SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
 957		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
 958	SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
 959		       WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
 960
 961#define WM2200_MUX_ENUM_DECL(name, reg) \
 962	SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, 			\
 963				   wm2200_mixer_texts, wm2200_mixer_values)
 964
 965#define WM2200_MUX_CTL_DECL(name) \
 966	const struct snd_kcontrol_new name##_mux =	\
 967		SOC_DAPM_VALUE_ENUM("Route", name##_enum)
 968
 969#define WM2200_MIXER_ENUMS(name, base_reg) \
 970	static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg);	     \
 971	static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2);  \
 972	static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4);  \
 973	static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6);  \
 974	static WM2200_MUX_CTL_DECL(name##_in1); \
 975	static WM2200_MUX_CTL_DECL(name##_in2); \
 976	static WM2200_MUX_CTL_DECL(name##_in3); \
 977	static WM2200_MUX_CTL_DECL(name##_in4)
 978
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 979static const struct snd_kcontrol_new wm2200_snd_controls[] = {
 980SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL,
 981	   WM2200_IN1_OSR_SHIFT, 1, 0),
 982SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL,
 983	   WM2200_IN2_OSR_SHIFT, 1, 0),
 984SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL,
 985	   WM2200_IN3_OSR_SHIFT, 1, 0),
 986
 987SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL,
 988		 WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
 989SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL,
 990		 WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
 991SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL,
 992		 WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv),
 993
 994SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
 995	     WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1),
 996SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
 997	     WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1),
 998SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L,
 999	     WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1),
1000
1001SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L,
1002		 WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT,
1003		 0xbf, 0, digital_tlv),
1004SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L,
1005		 WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT,
1006		 0xbf, 0, digital_tlv),
1007SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L,
1008		 WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT,
1009		 0xbf, 0, digital_tlv),
1010
 
 
 
 
 
 
1011SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1012	   WM2200_OUT1_OSR_SHIFT, 1, 0),
1013SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1014	   WM2200_OUT2_OSR_SHIFT, 1, 0),
1015
1016SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L,
1017	     WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1),
1018SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L,
1019		 WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0,
1020		 digital_tlv),
1021SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L,
1022		 WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT,
1023		 0x46, 0, out_tlv),
1024
1025SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L,
1026	     WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1),
1027SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L,
1028		 WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0,
1029		 digital_tlv),
1030SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
1031	   WM2200_SPK1R_MUTE_SHIFT, 1, 0),
 
 
 
 
1032};
1033
1034WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
1035WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE);
1036WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE);
1037WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE);
1038
1039WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE);
1040WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE);
1041WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE);
1042WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE);
1043WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE);
1044WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE);
1045
1046WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE);
1047WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE);
1048
1049WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE);
1050WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE);
1051WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE);
1052WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE);
1053
 
 
 
1054WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE);
1055WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE);
1056
1057#define WM2200_MUX(name, ctrl) \
1058	SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
1059
1060#define WM2200_MIXER_WIDGETS(name, name_str)	\
1061	WM2200_MUX(name_str " Input 1", &name##_in1_mux), \
1062	WM2200_MUX(name_str " Input 2", &name##_in2_mux), \
1063	WM2200_MUX(name_str " Input 3", &name##_in3_mux), \
1064	WM2200_MUX(name_str " Input 4", &name##_in4_mux), \
1065	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
1066
 
 
 
 
 
 
 
 
 
 
1067#define WM2200_MIXER_INPUT_ROUTES(name)	\
1068	{ name, "Tone Generator", "Tone Generator" }, \
 
1069        { name, "IN1L", "IN1L PGA" }, \
1070        { name, "IN1R", "IN1R PGA" }, \
1071        { name, "IN2L", "IN2L PGA" }, \
1072        { name, "IN2R", "IN2R PGA" }, \
1073        { name, "IN3L", "IN3L PGA" }, \
1074        { name, "IN3R", "IN3R PGA" }, \
1075        { name, "DSP1.1", "DSP1" }, \
1076        { name, "DSP1.2", "DSP1" }, \
1077        { name, "DSP1.3", "DSP1" }, \
1078        { name, "DSP1.4", "DSP1" }, \
1079        { name, "DSP1.5", "DSP1" }, \
1080        { name, "DSP1.6", "DSP1" }, \
1081        { name, "DSP2.1", "DSP2" }, \
1082        { name, "DSP2.2", "DSP2" }, \
1083        { name, "DSP2.3", "DSP2" }, \
1084        { name, "DSP2.4", "DSP2" }, \
1085        { name, "DSP2.5", "DSP2" }, \
1086        { name, "DSP2.6", "DSP2" }, \
1087        { name, "AIF1RX1", "AIF1RX1" }, \
1088        { name, "AIF1RX2", "AIF1RX2" }, \
1089        { name, "AIF1RX3", "AIF1RX3" }, \
1090        { name, "AIF1RX4", "AIF1RX4" }, \
1091        { name, "AIF1RX5", "AIF1RX5" }, \
1092        { name, "AIF1RX6", "AIF1RX6" }, \
1093        { name, "EQL", "EQL" }, \
1094        { name, "EQR", "EQR" }, \
1095        { name, "LHPF1", "LHPF1" }, \
1096        { name, "LHPF2", "LHPF2" }
1097
1098#define WM2200_MIXER_ROUTES(widget, name) \
1099	{ widget, NULL, name " Mixer" },         \
1100	{ name " Mixer", NULL, name " Input 1" }, \
1101	{ name " Mixer", NULL, name " Input 2" }, \
1102	{ name " Mixer", NULL, name " Input 3" }, \
1103	{ name " Mixer", NULL, name " Input 4" }, \
1104	WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \
1105	WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \
1106	WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \
1107	WM2200_MIXER_INPUT_ROUTES(name " Input 4")
1108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1109static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = {
1110SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0,
1111		    NULL, 0),
1112SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0,
1113		    NULL, 0),
1114SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0,
1115		    NULL, 0),
1116SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT,
1117		    0, NULL, 0),
1118SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
1119		    0, NULL, 0),
1120SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
1121SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
1122
1123SND_SOC_DAPM_INPUT("IN1L"),
1124SND_SOC_DAPM_INPUT("IN1R"),
1125SND_SOC_DAPM_INPUT("IN2L"),
1126SND_SOC_DAPM_INPUT("IN2R"),
1127SND_SOC_DAPM_INPUT("IN3L"),
1128SND_SOC_DAPM_INPUT("IN3R"),
1129
1130SND_SOC_DAPM_SIGGEN("TONE"),
1131SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1,
1132		 WM2200_TONE_ENA_SHIFT, 0, NULL, 0),
1133
1134SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0,
1135		 NULL, 0),
1136SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0,
1137		 NULL, 0),
1138SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0,
1139		 NULL, 0),
1140SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0,
1141		 NULL, 0),
1142SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0,
1143		 NULL, 0),
1144SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0,
1145		 NULL, 0),
1146
1147SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0,
1148		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0),
1149SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1,
1150		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0),
1151SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2,
1152		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0),
1153SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3,
1154		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0),
1155SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4,
1156		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0),
1157SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5,
1158		    WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0),
1159
1160SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0),
1161SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0),
1162
1163SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0,
1164		 NULL, 0),
1165SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0,
1166		 NULL, 0),
1167
1168SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0),
1169SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0),
1170
1171SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0,
1172		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0),
1173SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1,
1174		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0),
1175SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2,
1176		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0),
1177SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3,
1178		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0),
1179SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4,
1180		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0),
1181SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5,
1182		    WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0),
1183
 
 
 
1184SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES,
1185		   WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0),
1186SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES,
1187		   WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0),
1188
1189SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1190		   WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0),
1191SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1192		   WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0),
1193SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1,
1194		   WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0),
1195
1196SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1197		   WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0),
1198SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1199		   WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0),
1200SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1,
1201		   WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0),
1202
1203SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1204		   WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0),
1205SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1206		   WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0),
1207SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2,
1208		   WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0),
1209
1210SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1211		   WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0),
1212SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1213		   WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0),
1214SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2,
1215		   WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0),
1216
1217SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT,
1218		 0, NULL, 0),
1219SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT,
1220		 0, NULL, 0),
1221
1222SND_SOC_DAPM_OUTPUT("EPOUTLN"),
1223SND_SOC_DAPM_OUTPUT("EPOUTLP"),
1224SND_SOC_DAPM_OUTPUT("EPOUTRN"),
1225SND_SOC_DAPM_OUTPUT("EPOUTRP"),
1226SND_SOC_DAPM_OUTPUT("SPK"),
1227
1228WM2200_MIXER_WIDGETS(EQL, "EQL"),
1229WM2200_MIXER_WIDGETS(EQR, "EQR"),
1230
1231WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"),
1232WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"),
1233
1234WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"),
1235WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"),
1236WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"),
1237WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"),
1238
1239WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1240WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1241WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1242WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1243WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1244WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1245
1246WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"),
1247WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"),
1248WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"),
1249WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"),
1250};
1251
1252static const struct snd_soc_dapm_route wm2200_dapm_routes[] = {
1253	/* Everything needs SYSCLK but only hook up things on the edge
1254	 * of the chip */
1255	{ "IN1L", NULL, "SYSCLK" },
1256	{ "IN1R", NULL, "SYSCLK" },
1257	{ "IN2L", NULL, "SYSCLK" },
1258	{ "IN2R", NULL, "SYSCLK" },
1259	{ "IN3L", NULL, "SYSCLK" },
1260	{ "IN3R", NULL, "SYSCLK" },
1261	{ "OUT1L", NULL, "SYSCLK" },
1262	{ "OUT1R", NULL, "SYSCLK" },
1263	{ "OUT2L", NULL, "SYSCLK" },
1264	{ "OUT2R", NULL, "SYSCLK" },
1265	{ "AIF1RX1", NULL, "SYSCLK" },
1266	{ "AIF1RX2", NULL, "SYSCLK" },
1267	{ "AIF1RX3", NULL, "SYSCLK" },
1268	{ "AIF1RX4", NULL, "SYSCLK" },
1269	{ "AIF1RX5", NULL, "SYSCLK" },
1270	{ "AIF1RX6", NULL, "SYSCLK" },
1271	{ "AIF1TX1", NULL, "SYSCLK" },
1272	{ "AIF1TX2", NULL, "SYSCLK" },
1273	{ "AIF1TX3", NULL, "SYSCLK" },
1274	{ "AIF1TX4", NULL, "SYSCLK" },
1275	{ "AIF1TX5", NULL, "SYSCLK" },
1276	{ "AIF1TX6", NULL, "SYSCLK" },
1277
1278	{ "IN1L", NULL, "AVDD" },
1279	{ "IN1R", NULL, "AVDD" },
1280	{ "IN2L", NULL, "AVDD" },
1281	{ "IN2R", NULL, "AVDD" },
1282	{ "IN3L", NULL, "AVDD" },
1283	{ "IN3R", NULL, "AVDD" },
1284	{ "OUT1L", NULL, "AVDD" },
1285	{ "OUT1R", NULL, "AVDD" },
1286
1287	{ "IN1L PGA", NULL, "IN1L" },
1288	{ "IN1R PGA", NULL, "IN1R" },
1289	{ "IN2L PGA", NULL, "IN2L" },
1290	{ "IN2R PGA", NULL, "IN2R" },
1291	{ "IN3L PGA", NULL, "IN3L" },
1292	{ "IN3R PGA", NULL, "IN3R" },
1293
1294	{ "Tone Generator", NULL, "TONE" },
1295
1296	{ "CP2", NULL, "CPVDD" },
1297	{ "MICBIAS1", NULL, "CP2" },
1298	{ "MICBIAS2", NULL, "CP2" },
1299
1300	{ "CP1", NULL, "CPVDD" },
1301	{ "EPD_LN", NULL, "CP1" },
1302	{ "EPD_LP", NULL, "CP1" },
1303	{ "EPD_RN", NULL, "CP1" },
1304	{ "EPD_RP", NULL, "CP1" },
1305
1306	{ "EPD_LP", NULL, "OUT1L" },
1307	{ "EPD_OUTP_LP", NULL, "EPD_LP" },
1308	{ "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" },
1309	{ "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" },
1310
1311	{ "EPD_LN", NULL, "OUT1L" },
1312	{ "EPD_OUTP_LN", NULL, "EPD_LN" },
1313	{ "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" },
1314	{ "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" },
1315
1316	{ "EPD_RP", NULL, "OUT1R" },
1317	{ "EPD_OUTP_RP", NULL, "EPD_RP" },
1318	{ "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" },
1319	{ "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" },
1320
1321	{ "EPD_RN", NULL, "OUT1R" },
1322	{ "EPD_OUTP_RN", NULL, "EPD_RN" },
1323	{ "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" },
1324	{ "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" },
1325
1326	{ "SPK", NULL, "OUT2L" },
1327	{ "SPK", NULL, "OUT2R" },
1328
 
 
 
 
 
1329	WM2200_MIXER_ROUTES("DSP1", "DSP1L"),
1330	WM2200_MIXER_ROUTES("DSP1", "DSP1R"),
1331	WM2200_MIXER_ROUTES("DSP2", "DSP2L"),
1332	WM2200_MIXER_ROUTES("DSP2", "DSP2R"),
1333
 
 
 
1334	WM2200_MIXER_ROUTES("OUT1L", "OUT1L"),
1335	WM2200_MIXER_ROUTES("OUT1R", "OUT1R"),
1336	WM2200_MIXER_ROUTES("OUT2L", "OUT2L"),
1337	WM2200_MIXER_ROUTES("OUT2R", "OUT2R"),
1338
1339	WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1340	WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1341	WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1342	WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1343	WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1344	WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1345
1346	WM2200_MIXER_ROUTES("EQL", "EQL"),
1347	WM2200_MIXER_ROUTES("EQR", "EQR"),
1348
1349	WM2200_MIXER_ROUTES("LHPF1", "LHPF1"),
1350	WM2200_MIXER_ROUTES("LHPF2", "LHPF2"),
1351};
1352
1353static int wm2200_probe(struct snd_soc_codec *codec)
1354{
1355	struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev);
1356	int ret;
1357
1358	wm2200->codec = codec;
1359	codec->control_data = wm2200->regmap;
1360	codec->dapm.bias_level = SND_SOC_BIAS_OFF;
1361
1362	ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
1363	if (ret != 0) {
1364		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1365		return ret;
1366	}
1367
1368	return ret;
1369}
1370
1371static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1372{
1373	struct snd_soc_codec *codec = dai->codec;
1374	int lrclk, bclk, fmt_val;
1375
1376	lrclk = 0;
1377	bclk = 0;
1378
1379	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1380	case SND_SOC_DAIFMT_DSP_A:
1381		fmt_val = 0;
1382		break;
1383	case SND_SOC_DAIFMT_DSP_B:
1384		fmt_val = 1;
1385		break;
1386	case SND_SOC_DAIFMT_I2S:
1387		fmt_val = 2;
1388		break;
1389	case SND_SOC_DAIFMT_LEFT_J:
1390		fmt_val = 3;
1391		break;
1392	default:
1393		dev_err(codec->dev, "Unsupported DAI format %d\n",
1394			fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1395		return -EINVAL;
1396	}
1397
1398	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1399	case SND_SOC_DAIFMT_CBS_CFS:
1400		break;
1401	case SND_SOC_DAIFMT_CBS_CFM:
1402		lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1403		break;
1404	case SND_SOC_DAIFMT_CBM_CFS:
1405		bclk |= WM2200_AIF1_BCLK_MSTR;
1406		break;
1407	case SND_SOC_DAIFMT_CBM_CFM:
1408		lrclk |= WM2200_AIF1TX_LRCLK_MSTR;
1409		bclk |= WM2200_AIF1_BCLK_MSTR;
1410		break;
1411	default:
1412		dev_err(codec->dev, "Unsupported master mode %d\n",
1413			fmt & SND_SOC_DAIFMT_MASTER_MASK);
1414		return -EINVAL;
1415	}
1416
1417	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1418	case SND_SOC_DAIFMT_NB_NF:
1419		break;
1420	case SND_SOC_DAIFMT_IB_IF:
1421		bclk |= WM2200_AIF1_BCLK_INV;
1422		lrclk |= WM2200_AIF1TX_LRCLK_INV;
1423		break;
1424	case SND_SOC_DAIFMT_IB_NF:
1425		bclk |= WM2200_AIF1_BCLK_INV;
1426		break;
1427	case SND_SOC_DAIFMT_NB_IF:
1428		lrclk |= WM2200_AIF1TX_LRCLK_INV;
1429		break;
1430	default:
1431		return -EINVAL;
1432	}
1433
1434	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR |
1435			    WM2200_AIF1_BCLK_INV, bclk);
1436	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
1437			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1438			    lrclk);
1439	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3,
1440			    WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV,
1441			    lrclk);
1442	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5,
1443			    WM2200_AIF1_FMT_MASK << 1, fmt_val << 1);
1444
1445	return 0;
1446}
1447
1448static int wm2200_sr_code[] = {
1449	0,
1450	12000,
1451	24000,
1452	48000,
1453	96000,
1454	192000,
1455	384000,
1456	768000,
1457	0,
1458	11025,
1459	22050,
1460	44100,
1461	88200,
1462	176400,
1463	352800,
1464	705600,
1465	4000,
1466	8000,
1467	16000,
1468	32000,
1469	64000,
1470	128000,
1471	256000,
1472	512000,
1473};
1474
1475#define WM2200_NUM_BCLK_RATES 12
1476
1477static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = {
1478	6144000,
1479	3072000,
1480	2048000,
1481	1536000,
1482	768000,
1483	512000,
1484	384000,
1485	256000,
1486	192000,
1487	128000,
1488	96000,
1489	64000,
1490};	
1491
1492static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = {
1493	5644800,
1494	3763200,
1495	2882400,
1496	1881600,
1497	1411200,
1498	705600,
1499	470400,
1500	352800,
1501	176400,
1502	117600,
1503	88200,
1504	58800,
1505};
1506
1507static int wm2200_hw_params(struct snd_pcm_substream *substream,
1508			    struct snd_pcm_hw_params *params,
1509			    struct snd_soc_dai *dai)
1510{
1511	struct snd_soc_codec *codec = dai->codec;
1512	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1513	int i, bclk, lrclk, wl, fl, sr_code;
1514	int *bclk_rates;
1515
1516	/* Data sizes if not using TDM */
1517	wl = snd_pcm_format_width(params_format(params));
1518	if (wl < 0)
1519		return wl;
1520	fl = snd_soc_params_to_frame_size(params);
1521	if (fl < 0)
1522		return fl;
1523
1524	dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1525		wl, fl);
1526
1527	/* Target BCLK rate */
1528	bclk = snd_soc_params_to_bclk(params);
1529	if (bclk < 0)
1530		return bclk;
1531
1532	if (!wm2200->sysclk) {
1533		dev_err(codec->dev, "SYSCLK has no rate set\n");
1534		return -EINVAL;
1535	}
1536
1537	for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++)
1538		if (wm2200_sr_code[i] == params_rate(params))
1539			break;
1540	if (i == ARRAY_SIZE(wm2200_sr_code)) {
1541		dev_err(codec->dev, "Unsupported sample rate: %dHz\n",
1542			params_rate(params));
1543		return -EINVAL;
1544	}
1545	sr_code = i;
1546
1547	dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n",
1548		bclk, wm2200->sysclk);
1549
1550	if (wm2200->sysclk % 4000)
1551		bclk_rates = wm2200_bclk_rates_cd;
1552	else
1553		bclk_rates = wm2200_bclk_rates_dat;
1554
1555	for (i = 0; i < WM2200_NUM_BCLK_RATES; i++)
1556		if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1557			break;
1558	if (i == WM2200_NUM_BCLK_RATES) {
1559		dev_err(codec->dev,
1560			"No valid BCLK for %dHz found from %dHz SYSCLK\n",
1561			bclk, wm2200->sysclk);
1562		return -EINVAL;
1563	}
1564
1565	bclk = i;
1566	dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1567	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1,
1568			    WM2200_AIF1_BCLK_DIV_MASK, bclk);
1569
1570	lrclk = bclk_rates[bclk] / params_rate(params);
1571	dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1572	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1573	    dai->symmetric_rates)
1574		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7,
1575				    WM2200_AIF1RX_BCPF_MASK, lrclk);
1576	else
1577		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6,
1578				    WM2200_AIF1TX_BCPF_MASK, lrclk);
1579
1580	i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl;
1581	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1582		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9,
1583				    WM2200_AIF1RX_WL_MASK |
1584				    WM2200_AIF1RX_SLOT_LEN_MASK, i);
1585	else
1586		snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8,
1587				    WM2200_AIF1TX_WL_MASK |
1588				    WM2200_AIF1TX_SLOT_LEN_MASK, i);
1589
1590	snd_soc_update_bits(codec, WM2200_CLOCKING_4,
1591			    WM2200_SAMPLE_RATE_1_MASK, sr_code);
1592
1593	return 0;
1594}
1595
1596static const struct snd_soc_dai_ops wm2200_dai_ops = {
1597	.set_fmt = wm2200_set_fmt,
1598	.hw_params = wm2200_hw_params,
1599};
1600
1601static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1602			     int source, unsigned int freq, int dir)
1603{
1604	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1605	int fval;
1606
1607	switch (clk_id) {
1608	case WM2200_CLK_SYSCLK:
1609		break;
1610
1611	default:
1612		dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1613		return -EINVAL;
1614	}
1615
1616	switch (source) {
1617	case WM2200_CLKSRC_MCLK1:
1618	case WM2200_CLKSRC_MCLK2:
1619	case WM2200_CLKSRC_FLL:
1620	case WM2200_CLKSRC_BCLK1:
1621		break;
1622	default:
1623		dev_err(codec->dev, "Invalid source %d\n", source);
1624		return -EINVAL;
1625	}
1626
1627	switch (freq) {
1628	case 22579200:
1629	case 24576000:
1630		fval = 2;
1631		break;
1632	default:
1633		dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1634		return -EINVAL;
1635	}
1636
1637	/* TODO: Check if MCLKs are in use and enable/disable pulls to
1638	 * match.
1639	 */
1640
1641	snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK |
1642			    WM2200_SYSCLK_SRC_MASK,
1643			    fval << WM2200_SYSCLK_FREQ_SHIFT | source);
1644
1645	wm2200->sysclk = freq;
1646
1647	return 0;
1648}
1649
1650struct _fll_div {
1651	u16 fll_fratio;
1652	u16 fll_outdiv;
1653	u16 fll_refclk_div;
1654	u16 n;
1655	u16 theta;
1656	u16 lambda;
1657};
1658
1659static struct {
1660	unsigned int min;
1661	unsigned int max;
1662	u16 fll_fratio;
1663	int ratio;
1664} fll_fratios[] = {
1665	{       0,    64000, 4, 16 },
1666	{   64000,   128000, 3,  8 },
1667	{  128000,   256000, 2,  4 },
1668	{  256000,  1000000, 1,  2 },
1669	{ 1000000, 13500000, 0,  1 },
1670};
1671
1672static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1673		       unsigned int Fout)
1674{
1675	unsigned int target;
1676	unsigned int div;
1677	unsigned int fratio, gcd_fll;
1678	int i;
1679
1680	/* Fref must be <=13.5MHz */
1681	div = 1;
1682	fll_div->fll_refclk_div = 0;
1683	while ((Fref / div) > 13500000) {
1684		div *= 2;
1685		fll_div->fll_refclk_div++;
1686
1687		if (div > 8) {
1688			pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1689			       Fref);
1690			return -EINVAL;
1691		}
1692	}
1693
1694	pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1695
1696	/* Apply the division for our remaining calculations */
1697	Fref /= div;
1698
1699	/* Fvco should be 90-100MHz; don't check the upper bound */
1700	div = 2;
1701	while (Fout * div < 90000000) {
1702		div++;
1703		if (div > 64) {
1704			pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1705			       Fout);
1706			return -EINVAL;
1707		}
1708	}
1709	target = Fout * div;
1710	fll_div->fll_outdiv = div - 1;
1711
1712	pr_debug("FLL Fvco=%dHz\n", target);
1713
1714	/* Find an appropraite FLL_FRATIO and factor it out of the target */
1715	for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1716		if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1717			fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1718			fratio = fll_fratios[i].ratio;
1719			break;
1720		}
1721	}
1722	if (i == ARRAY_SIZE(fll_fratios)) {
1723		pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1724		return -EINVAL;
1725	}
1726
1727	fll_div->n = target / (fratio * Fref);
1728
1729	if (target % Fref == 0) {
1730		fll_div->theta = 0;
1731		fll_div->lambda = 0;
1732	} else {
1733		gcd_fll = gcd(target, fratio * Fref);
1734
1735		fll_div->theta = (target - (fll_div->n * fratio * Fref))
1736			/ gcd_fll;
1737		fll_div->lambda = (fratio * Fref) / gcd_fll;
1738	}
1739
1740	pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1741		 fll_div->n, fll_div->theta, fll_div->lambda);
1742	pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1743		 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1744		 fll_div->fll_refclk_div);
1745
1746	return 0;
1747}
1748
1749static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1750			  unsigned int Fref, unsigned int Fout)
1751{
1752	struct i2c_client *i2c = to_i2c_client(codec->dev);
1753	struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec);
1754	struct _fll_div factors;
1755	int ret, i, timeout;
 
1756
1757	if (!Fout) {
1758		dev_dbg(codec->dev, "FLL disabled");
1759
1760		if (wm2200->fll_fout)
1761			pm_runtime_put(codec->dev);
1762
1763		wm2200->fll_fout = 0;
1764		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
1765				    WM2200_FLL_ENA, 0);
1766		return 0;
1767	}
1768
1769	switch (source) {
1770	case WM2200_FLL_SRC_MCLK1:
1771	case WM2200_FLL_SRC_MCLK2:
1772	case WM2200_FLL_SRC_BCLK:
1773		break;
1774	default:
1775		dev_err(codec->dev, "Invalid FLL source %d\n", source);
1776		return -EINVAL;
1777	}
1778
1779	ret = fll_factors(&factors, Fref, Fout);
1780	if (ret < 0)
1781		return ret;
1782
1783	/* Disable the FLL while we reconfigure */
1784	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0);
1785
1786	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2,
1787			    WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK,
1788			    (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) |
1789			    factors.fll_fratio);
1790	if (factors.theta) {
1791		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
1792				    WM2200_FLL_FRACN_ENA,
1793				    WM2200_FLL_FRACN_ENA);
1794		snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
1795				    WM2200_FLL_EFS_ENA,
1796				    WM2200_FLL_EFS_ENA);
1797	} else {
1798		snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3,
1799				    WM2200_FLL_FRACN_ENA, 0);
1800		snd_soc_update_bits(codec, WM2200_FLL_EFS_2,
1801				    WM2200_FLL_EFS_ENA, 0);
1802	}
1803
1804	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK,
1805			    factors.theta);
1806	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK,
1807			    factors.n);
1808	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7,
1809			    WM2200_FLL_CLK_REF_DIV_MASK |
1810			    WM2200_FLL_CLK_REF_SRC_MASK,
1811			    (factors.fll_refclk_div
1812			     << WM2200_FLL_CLK_REF_DIV_SHIFT) | source);
1813	snd_soc_update_bits(codec, WM2200_FLL_EFS_1,
1814			    WM2200_FLL_LAMBDA_MASK, factors.lambda);
1815
1816	/* Clear any pending completions */
1817	try_wait_for_completion(&wm2200->fll_lock);
1818
1819	pm_runtime_get_sync(codec->dev);
1820
1821	snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1,
1822			    WM2200_FLL_ENA, WM2200_FLL_ENA);
1823
1824	if (i2c->irq)
1825		timeout = 2;
1826	else
1827		timeout = 50;
1828
1829	snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA,
1830			    WM2200_SYSCLK_ENA);
1831
1832	/* Poll for the lock; will use the interrupt to exit quickly */
1833	for (i = 0; i < timeout; i++) {
1834		if (i2c->irq) {
1835			ret = wait_for_completion_timeout(&wm2200->fll_lock,
1836							  msecs_to_jiffies(25));
1837			if (ret > 0)
 
1838				break;
1839		} else {
1840			msleep(1);
1841		}
1842
1843		ret = snd_soc_read(codec,
1844				   WM2200_INTERRUPT_RAW_STATUS_2);
1845		if (ret < 0) {
1846			dev_err(codec->dev,
1847				"Failed to read FLL status: %d\n",
1848				ret);
1849			continue;
1850		}
1851		if (ret & WM2200_FLL_LOCK_STS)
1852			break;
1853	}
1854	if (i == timeout) {
1855		dev_err(codec->dev, "FLL lock timed out\n");
1856		pm_runtime_put(codec->dev);
1857		return -ETIMEDOUT;
1858	}
1859
1860	wm2200->fll_src = source;
1861	wm2200->fll_fref = Fref;
1862	wm2200->fll_fout = Fout;
1863
1864	dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout);
1865
1866	return 0;
1867}
1868
1869static int wm2200_dai_probe(struct snd_soc_dai *dai)
1870{
1871	struct snd_soc_codec *codec = dai->codec;
 
1872	unsigned int val = 0;
1873	int ret;
1874
1875	ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1);
1876	if (ret >= 0) {
1877		if ((ret & WM2200_GP1_FN_MASK) != 0) {
1878			dai->symmetric_rates = true;
1879			val = WM2200_AIF1TX_LRCLK_SRC;
1880		}
1881	} else {
1882		dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret);
1883	}
1884
1885	snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2,
1886			    WM2200_AIF1TX_LRCLK_SRC, val);
1887
1888	return 0;
1889}
1890
 
 
 
 
 
 
1891#define WM2200_RATES SNDRV_PCM_RATE_8000_48000
1892
1893#define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1894			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1895
1896static struct snd_soc_dai_driver wm2200_dai = {
1897	.name = "wm2200",
1898	.probe = wm2200_dai_probe,
1899	.playback = {
1900		.stream_name = "Playback",
1901		.channels_min = 2,
1902		.channels_max = 2,
1903		.rates = WM2200_RATES,
1904		.formats = WM2200_FORMATS,
1905	},
1906	.capture = {
1907		 .stream_name = "Capture",
1908		 .channels_min = 2,
1909		 .channels_max = 2,
1910		 .rates = WM2200_RATES,
1911		 .formats = WM2200_FORMATS,
1912	 },
1913	.ops = &wm2200_dai_ops,
1914};
1915
1916static struct snd_soc_codec_driver soc_codec_wm2200 = {
1917	.probe = wm2200_probe,
1918
1919	.idle_bias_off = true,
1920	.ignore_pmdown_time = true,
1921	.set_sysclk = wm2200_set_sysclk,
1922	.set_pll = wm2200_set_fll,
1923
1924	.controls = wm2200_snd_controls,
1925	.num_controls = ARRAY_SIZE(wm2200_snd_controls),
1926	.dapm_widgets = wm2200_dapm_widgets,
1927	.num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets),
1928	.dapm_routes = wm2200_dapm_routes,
1929	.num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes),
1930};
1931
1932static irqreturn_t wm2200_irq(int irq, void *data)
1933{
1934	struct wm2200_priv *wm2200 = data;
1935	unsigned int val, mask;
1936	int ret;
1937
1938	ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val);
1939	if (ret != 0) {
1940		dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret);
1941		return IRQ_NONE;
1942	}
1943
1944	ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK,
1945			   &mask);
1946	if (ret != 0) {
1947		dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret);
1948		mask = 0;
1949	}
1950
1951	val &= ~mask;
1952
1953	if (val & WM2200_FLL_LOCK_EINT) {
1954		dev_dbg(wm2200->dev, "FLL locked\n");
1955		complete(&wm2200->fll_lock);
1956	}
1957
1958	if (val) {
1959		regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val);
1960		
1961		return IRQ_HANDLED;
1962	} else {
1963		return IRQ_NONE;
1964	}
1965}
1966
1967static const struct regmap_config wm2200_regmap = {
1968	.reg_bits = 16,
1969	.val_bits = 16,
1970
1971	.max_register = WM2200_MAX_REGISTER,
 
1972	.reg_defaults = wm2200_reg_defaults,
1973	.num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults),
1974	.volatile_reg = wm2200_volatile_register,
1975	.readable_reg = wm2200_readable_register,
1976	.cache_type = REGCACHE_RBTREE,
 
 
1977};
1978
1979static const unsigned int wm2200_dig_vu[] = {
1980	WM2200_DAC_DIGITAL_VOLUME_1L,
1981	WM2200_DAC_DIGITAL_VOLUME_1R,
1982	WM2200_DAC_DIGITAL_VOLUME_2L,
1983	WM2200_DAC_DIGITAL_VOLUME_2R,
1984	WM2200_ADC_DIGITAL_VOLUME_1L,
1985	WM2200_ADC_DIGITAL_VOLUME_1R,
1986	WM2200_ADC_DIGITAL_VOLUME_2L,
1987	WM2200_ADC_DIGITAL_VOLUME_2R,
1988	WM2200_ADC_DIGITAL_VOLUME_3L,
1989	WM2200_ADC_DIGITAL_VOLUME_3R,
1990};
1991
1992static const unsigned int wm2200_mic_ctrl_reg[] = {
1993	WM2200_IN1L_CONTROL,
1994	WM2200_IN2L_CONTROL,
1995	WM2200_IN3L_CONTROL,
1996};
1997
1998static __devinit int wm2200_i2c_probe(struct i2c_client *i2c,
1999				      const struct i2c_device_id *id)
2000{
2001	struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev);
2002	struct wm2200_priv *wm2200;
2003	unsigned int reg;
2004	int ret, i;
 
2005
2006	wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv),
2007			      GFP_KERNEL);
2008	if (wm2200 == NULL)
2009		return -ENOMEM;
2010
2011	wm2200->dev = &i2c->dev;
2012	init_completion(&wm2200->fll_lock);
2013
2014	wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap);
2015	if (IS_ERR(wm2200->regmap)) {
2016		ret = PTR_ERR(wm2200->regmap);
2017		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2018			ret);
2019		goto err;
2020	}
2021
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2022	if (pdata)
2023		wm2200->pdata = *pdata;
2024
2025	i2c_set_clientdata(i2c, wm2200);
2026
2027	for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++)
2028		wm2200->core_supplies[i].supply = wm2200_core_supply_names[i];
2029
2030	ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies),
2031				 wm2200->core_supplies);
 
2032	if (ret != 0) {
2033		dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2034			ret);
2035		goto err_regmap;
2036	}
2037
2038	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2039				    wm2200->core_supplies);
2040	if (ret != 0) {
2041		dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2042			ret);
2043		goto err_core;
2044	}
2045
2046	if (wm2200->pdata.ldo_ena) {
2047		ret = gpio_request_one(wm2200->pdata.ldo_ena,
2048				       GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA");
2049		if (ret < 0) {
2050			dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2051				wm2200->pdata.ldo_ena, ret);
2052			goto err_enable;
2053		}
 
 
2054		msleep(2);
2055	}
2056
2057	if (wm2200->pdata.reset) {
2058		ret = gpio_request_one(wm2200->pdata.reset,
2059				       GPIOF_OUT_INIT_HIGH, "WM2200 /RESET");
2060		if (ret < 0) {
2061			dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2062				wm2200->pdata.reset, ret);
2063			goto err_ldo;
2064		}
2065	}
 
2066
2067	ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, &reg);
2068	if (ret < 0) {
2069		dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2070		goto err_reset;
2071	}
2072	switch (reg) {
2073	case 0x2200:
2074		break;
2075
2076	default:
2077		dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg);
2078		ret = -EINVAL;
2079		goto err_reset;
2080	}
2081
2082	ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, &reg);
2083	if (ret < 0) {
2084		dev_err(&i2c->dev, "Failed to read revision register\n");
2085		goto err_reset;
2086	}
2087
2088	wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK;
2089
2090	dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A');
2091
2092	switch (wm2200->rev) {
2093	case 0:
 
2094		ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch,
2095					    ARRAY_SIZE(wm2200_reva_patch));
2096		if (ret != 0) {
2097			dev_err(&i2c->dev, "Failed to register patch: %d\n",
2098				ret);
2099		}
2100		break;
2101	default:
2102		break;
2103	}
2104
2105	ret = wm2200_reset(wm2200);
2106	if (ret < 0) {
2107		dev_err(&i2c->dev, "Failed to issue reset\n");
2108		goto err_reset;
2109	}
2110
2111	for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) {
2112		if (!wm2200->pdata.gpio_defaults[i])
2113			continue;
2114
2115		regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i,
2116			     wm2200->pdata.gpio_defaults[i]);
2117	}
2118
2119	for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++)
2120		regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i],
2121				   WM2200_OUT_VU, WM2200_OUT_VU);
2122
2123	/* Assign slots 1-6 to channels 1-6 for both TX and RX */
2124	for (i = 0; i < 6; i++) {
2125		regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i);
2126		regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i);
2127	}
2128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2129	for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) {
2130		regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i],
2131				   WM2200_IN1_MODE_MASK |
2132				   WM2200_IN1_DMIC_SUP_MASK,
2133				   (wm2200->pdata.in_mode[i] <<
2134				    WM2200_IN1_MODE_SHIFT) |
2135				   (wm2200->pdata.dmic_sup[i] <<
2136				    WM2200_IN1_DMIC_SUP_SHIFT));
2137	}
2138
2139	if (i2c->irq) {
2140		ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq,
2141					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
2142					   "wm2200", wm2200);
2143		if (ret == 0)
2144			regmap_update_bits(wm2200->regmap,
2145					   WM2200_INTERRUPT_STATUS_2_MASK,
2146					   WM2200_FLL_LOCK_EINT, 0);
2147		else
2148			dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2149				i2c->irq, ret);
2150	}
2151
2152	pm_runtime_set_active(&i2c->dev);
2153	pm_runtime_enable(&i2c->dev);
2154	pm_request_idle(&i2c->dev);
2155
2156	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200,
2157				     &wm2200_dai, 1);
2158	if (ret != 0) {
2159		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
2160		goto err_pm_runtime;
2161	}
2162
2163	return 0;
2164
2165err_pm_runtime:
2166	pm_runtime_disable(&i2c->dev);
 
 
2167err_reset:
2168	if (wm2200->pdata.reset) {
2169		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2170		gpio_free(wm2200->pdata.reset);
2171	}
2172err_ldo:
2173	if (wm2200->pdata.ldo_ena) {
2174		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2175		gpio_free(wm2200->pdata.ldo_ena);
2176	}
2177err_enable:
2178	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2179			       wm2200->core_supplies);
2180err_core:
2181	regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
2182			    wm2200->core_supplies);
2183err_regmap:
2184	regmap_exit(wm2200->regmap);
2185err:
2186	return ret;
2187}
2188
2189static __devexit int wm2200_i2c_remove(struct i2c_client *i2c)
2190{
2191	struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c);
2192
2193	snd_soc_unregister_codec(&i2c->dev);
2194	if (i2c->irq)
2195		free_irq(i2c->irq, wm2200);
2196	if (wm2200->pdata.reset) {
2197		gpio_set_value_cansleep(wm2200->pdata.reset, 0);
2198		gpio_free(wm2200->pdata.reset);
2199	}
2200	if (wm2200->pdata.ldo_ena) {
2201		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2202		gpio_free(wm2200->pdata.ldo_ena);
2203	}
2204	regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies),
2205			    wm2200->core_supplies);
2206	regmap_exit(wm2200->regmap);
2207
2208	return 0;
2209}
2210
2211#ifdef CONFIG_PM_RUNTIME
2212static int wm2200_runtime_suspend(struct device *dev)
2213{
2214	struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2215
2216	regcache_cache_only(wm2200->regmap, true);
2217	regcache_mark_dirty(wm2200->regmap);
2218	if (wm2200->pdata.ldo_ena)
2219		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0);
2220	regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies),
2221			       wm2200->core_supplies);
2222
2223	return 0;
2224}
2225
2226static int wm2200_runtime_resume(struct device *dev)
2227{
2228	struct wm2200_priv *wm2200 = dev_get_drvdata(dev);
2229	int ret;
2230
2231	ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies),
2232				    wm2200->core_supplies);
2233	if (ret != 0) {
2234		dev_err(dev, "Failed to enable supplies: %d\n",
2235			ret);
2236		return ret;
2237	}
2238
2239	if (wm2200->pdata.ldo_ena) {
2240		gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1);
2241		msleep(2);
2242	}
2243
2244	regcache_cache_only(wm2200->regmap, false);
2245	regcache_sync(wm2200->regmap);
2246
2247	return 0;
2248}
2249#endif
2250
2251static struct dev_pm_ops wm2200_pm = {
2252	SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume,
2253			   NULL)
2254};
2255
2256static const struct i2c_device_id wm2200_i2c_id[] = {
2257	{ "wm2200", 0 },
2258	{ }
2259};
2260MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id);
2261
2262static struct i2c_driver wm2200_i2c_driver = {
2263	.driver = {
2264		.name = "wm2200",
2265		.owner = THIS_MODULE,
2266		.pm = &wm2200_pm,
2267	},
2268	.probe =    wm2200_i2c_probe,
2269	.remove =   __devexit_p(wm2200_i2c_remove),
2270	.id_table = wm2200_i2c_id,
2271};
2272
2273static int __init wm2200_modinit(void)
2274{
2275	return i2c_add_driver(&wm2200_i2c_driver);
2276}
2277module_init(wm2200_modinit);
2278
2279static void __exit wm2200_exit(void)
2280{
2281	i2c_del_driver(&wm2200_i2c_driver);
2282}
2283module_exit(wm2200_exit);
2284
2285MODULE_DESCRIPTION("ASoC WM2200 driver");
2286MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2287MODULE_LICENSE("GPL");