cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wm2200.c (82599B)


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