linux/sound/soc/codecs/wm8994.c
Mark Brown d1ce6b200c ASoC: Unconditionally enable WM8994 AIF1ADC TDM mode
AIF1ADC TDM mode has no effect other than causing the ADCDAT line to
be tristated rather than driven low on clock cycles where there is no
data to be transmitted. If the clock cycle is idle then there should
be no devices using the data so tristating should have no adverse
effects.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
2010-07-20 10:27:05 +01:00

4156 lines
137 KiB
C

/*
* wm8994.c -- WM8994 ALSA SoC Audio driver
*
* Copyright 2009 Wolfson Microelectronics plc
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include <linux/mfd/wm8994/core.h>
#include <linux/mfd/wm8994/registers.h>
#include <linux/mfd/wm8994/pdata.h>
#include <linux/mfd/wm8994/gpio.h>
#include "wm8994.h"
#include "wm_hubs.h"
static struct snd_soc_codec *wm8994_codec;
struct snd_soc_codec_device soc_codec_dev_wm8994;
struct fll_config {
int src;
int in;
int out;
};
#define WM8994_NUM_DRC 3
#define WM8994_NUM_EQ 3
static int wm8994_drc_base[] = {
WM8994_AIF1_DRC1_1,
WM8994_AIF1_DRC2_1,
WM8994_AIF2_DRC_1,
};
static int wm8994_retune_mobile_base[] = {
WM8994_AIF1_DAC1_EQ_GAINS_1,
WM8994_AIF1_DAC2_EQ_GAINS_1,
WM8994_AIF2_EQ_GAINS_1,
};
#define WM8994_REG_CACHE_SIZE 0x621
struct wm8994_micdet {
struct snd_soc_jack *jack;
int det;
int shrt;
};
/* codec private data */
struct wm8994_priv {
struct wm_hubs_data hubs;
struct snd_soc_codec codec;
u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
int sysclk[2];
int sysclk_rate[2];
int mclk[2];
int aifclk[2];
struct fll_config fll[2], fll_suspend[2];
int dac_rates[2];
int lrclk_shared[2];
/* Platform dependant DRC configuration */
const char **drc_texts;
int drc_cfg[WM8994_NUM_DRC];
struct soc_enum drc_enum;
/* Platform dependant ReTune mobile configuration */
int num_retune_mobile_texts;
const char **retune_mobile_texts;
int retune_mobile_cfg[WM8994_NUM_EQ];
struct soc_enum retune_mobile_enum;
struct wm8994_micdet micdet[2];
struct wm8994_pdata *pdata;
};
static struct {
unsigned short readable; /* Mask of readable bits */
unsigned short writable; /* Mask of writable bits */
unsigned short vol; /* Mask of volatile bits */
} access_masks[] = {
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
{ 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
{ 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
{ 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
{ 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
{ 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
{ 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
{ 0x0000, 0x0000, 0x0000 }, /* R7 */
{ 0x0000, 0x0000, 0x0000 }, /* R8 */
{ 0x0000, 0x0000, 0x0000 }, /* R9 */
{ 0x0000, 0x0000, 0x0000 }, /* R10 */
{ 0x0000, 0x0000, 0x0000 }, /* R11 */
{ 0x0000, 0x0000, 0x0000 }, /* R12 */
{ 0x0000, 0x0000, 0x0000 }, /* R13 */
{ 0x0000, 0x0000, 0x0000 }, /* R14 */
{ 0x0000, 0x0000, 0x0000 }, /* R15 */
{ 0x0000, 0x0000, 0x0000 }, /* R16 */
{ 0x0000, 0x0000, 0x0000 }, /* R17 */
{ 0x0000, 0x0000, 0x0000 }, /* R18 */
{ 0x0000, 0x0000, 0x0000 }, /* R19 */
{ 0x0000, 0x0000, 0x0000 }, /* R20 */
{ 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
{ 0x0000, 0x0000, 0x0000 }, /* R22 */
{ 0x0000, 0x0000, 0x0000 }, /* R23 */
{ 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
{ 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
{ 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
{ 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
{ 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
{ 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
{ 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
{ 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
{ 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
{ 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
{ 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
{ 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
{ 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
{ 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
{ 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
{ 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
{ 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
{ 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
{ 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
{ 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
{ 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
{ 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
{ 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
{ 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
{ 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
{ 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
{ 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
{ 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
{ 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
{ 0x0000, 0x0000, 0x0000 }, /* R61 */
{ 0x0000, 0x0000, 0x0000 }, /* R62 */
{ 0x0000, 0x0000, 0x0000 }, /* R63 */
{ 0x0000, 0x0000, 0x0000 }, /* R64 */
{ 0x0000, 0x0000, 0x0000 }, /* R65 */
{ 0x0000, 0x0000, 0x0000 }, /* R66 */
{ 0x0000, 0x0000, 0x0000 }, /* R67 */
{ 0x0000, 0x0000, 0x0000 }, /* R68 */
{ 0x0000, 0x0000, 0x0000 }, /* R69 */
{ 0x0000, 0x0000, 0x0000 }, /* R70 */
{ 0x0000, 0x0000, 0x0000 }, /* R71 */
{ 0x0000, 0x0000, 0x0000 }, /* R72 */
{ 0x0000, 0x0000, 0x0000 }, /* R73 */
{ 0x0000, 0x0000, 0x0000 }, /* R74 */
{ 0x0000, 0x0000, 0x0000 }, /* R75 */
{ 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
{ 0x0000, 0x0000, 0x0000 }, /* R77 */
{ 0x0000, 0x0000, 0x0000 }, /* R78 */
{ 0x0000, 0x0000, 0x0000 }, /* R79 */
{ 0x0000, 0x0000, 0x0000 }, /* R80 */
{ 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
{ 0x0000, 0x0000, 0x0000 }, /* R82 */
{ 0x0000, 0x0000, 0x0000 }, /* R83 */
{ 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
{ 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R86 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
{ 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
{ 0x0000, 0x0000, 0x0000 }, /* R89 */
{ 0x0000, 0x0000, 0x0000 }, /* R90 */
{ 0x0000, 0x0000, 0x0000 }, /* R91 */
{ 0x0000, 0x0000, 0x0000 }, /* R92 */
{ 0x0000, 0x0000, 0x0000 }, /* R93 */
{ 0x0000, 0x0000, 0x0000 }, /* R94 */
{ 0x0000, 0x0000, 0x0000 }, /* R95 */
{ 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
{ 0x0000, 0x0000, 0x0000 }, /* R97 */
{ 0x0000, 0x0000, 0x0000 }, /* R98 */
{ 0x0000, 0x0000, 0x0000 }, /* R99 */
{ 0x0000, 0x0000, 0x0000 }, /* R100 */
{ 0x0000, 0x0000, 0x0000 }, /* R101 */
{ 0x0000, 0x0000, 0x0000 }, /* R102 */
{ 0x0000, 0x0000, 0x0000 }, /* R103 */
{ 0x0000, 0x0000, 0x0000 }, /* R104 */
{ 0x0000, 0x0000, 0x0000 }, /* R105 */
{ 0x0000, 0x0000, 0x0000 }, /* R106 */
{ 0x0000, 0x0000, 0x0000 }, /* R107 */
{ 0x0000, 0x0000, 0x0000 }, /* R108 */
{ 0x0000, 0x0000, 0x0000 }, /* R109 */
{ 0x0000, 0x0000, 0x0000 }, /* R110 */
{ 0x0000, 0x0000, 0x0000 }, /* R111 */
{ 0x0000, 0x0000, 0x0000 }, /* R112 */
{ 0x0000, 0x0000, 0x0000 }, /* R113 */
{ 0x0000, 0x0000, 0x0000 }, /* R114 */
{ 0x0000, 0x0000, 0x0000 }, /* R115 */
{ 0x0000, 0x0000, 0x0000 }, /* R116 */
{ 0x0000, 0x0000, 0x0000 }, /* R117 */
{ 0x0000, 0x0000, 0x0000 }, /* R118 */
{ 0x0000, 0x0000, 0x0000 }, /* R119 */
{ 0x0000, 0x0000, 0x0000 }, /* R120 */
{ 0x0000, 0x0000, 0x0000 }, /* R121 */
{ 0x0000, 0x0000, 0x0000 }, /* R122 */
{ 0x0000, 0x0000, 0x0000 }, /* R123 */
{ 0x0000, 0x0000, 0x0000 }, /* R124 */
{ 0x0000, 0x0000, 0x0000 }, /* R125 */
{ 0x0000, 0x0000, 0x0000 }, /* R126 */
{ 0x0000, 0x0000, 0x0000 }, /* R127 */
{ 0x0000, 0x0000, 0x0000 }, /* R128 */
{ 0x0000, 0x0000, 0x0000 }, /* R129 */
{ 0x0000, 0x0000, 0x0000 }, /* R130 */
{ 0x0000, 0x0000, 0x0000 }, /* R131 */
{ 0x0000, 0x0000, 0x0000 }, /* R132 */
{ 0x0000, 0x0000, 0x0000 }, /* R133 */
{ 0x0000, 0x0000, 0x0000 }, /* R134 */
{ 0x0000, 0x0000, 0x0000 }, /* R135 */
{ 0x0000, 0x0000, 0x0000 }, /* R136 */
{ 0x0000, 0x0000, 0x0000 }, /* R137 */
{ 0x0000, 0x0000, 0x0000 }, /* R138 */
{ 0x0000, 0x0000, 0x0000 }, /* R139 */
{ 0x0000, 0x0000, 0x0000 }, /* R140 */
{ 0x0000, 0x0000, 0x0000 }, /* R141 */
{ 0x0000, 0x0000, 0x0000 }, /* R142 */
{ 0x0000, 0x0000, 0x0000 }, /* R143 */
{ 0x0000, 0x0000, 0x0000 }, /* R144 */
{ 0x0000, 0x0000, 0x0000 }, /* R145 */
{ 0x0000, 0x0000, 0x0000 }, /* R146 */
{ 0x0000, 0x0000, 0x0000 }, /* R147 */
{ 0x0000, 0x0000, 0x0000 }, /* R148 */
{ 0x0000, 0x0000, 0x0000 }, /* R149 */
{ 0x0000, 0x0000, 0x0000 }, /* R150 */
{ 0x0000, 0x0000, 0x0000 }, /* R151 */
{ 0x0000, 0x0000, 0x0000 }, /* R152 */
{ 0x0000, 0x0000, 0x0000 }, /* R153 */
{ 0x0000, 0x0000, 0x0000 }, /* R154 */
{ 0x0000, 0x0000, 0x0000 }, /* R155 */
{ 0x0000, 0x0000, 0x0000 }, /* R156 */
{ 0x0000, 0x0000, 0x0000 }, /* R157 */
{ 0x0000, 0x0000, 0x0000 }, /* R158 */
{ 0x0000, 0x0000, 0x0000 }, /* R159 */
{ 0x0000, 0x0000, 0x0000 }, /* R160 */
{ 0x0000, 0x0000, 0x0000 }, /* R161 */
{ 0x0000, 0x0000, 0x0000 }, /* R162 */
{ 0x0000, 0x0000, 0x0000 }, /* R163 */
{ 0x0000, 0x0000, 0x0000 }, /* R164 */
{ 0x0000, 0x0000, 0x0000 }, /* R165 */
{ 0x0000, 0x0000, 0x0000 }, /* R166 */
{ 0x0000, 0x0000, 0x0000 }, /* R167 */
{ 0x0000, 0x0000, 0x0000 }, /* R168 */
{ 0x0000, 0x0000, 0x0000 }, /* R169 */
{ 0x0000, 0x0000, 0x0000 }, /* R170 */
{ 0x0000, 0x0000, 0x0000 }, /* R171 */
{ 0x0000, 0x0000, 0x0000 }, /* R172 */
{ 0x0000, 0x0000, 0x0000 }, /* R173 */
{ 0x0000, 0x0000, 0x0000 }, /* R174 */
{ 0x0000, 0x0000, 0x0000 }, /* R175 */
{ 0x0000, 0x0000, 0x0000 }, /* R176 */
{ 0x0000, 0x0000, 0x0000 }, /* R177 */
{ 0x0000, 0x0000, 0x0000 }, /* R178 */
{ 0x0000, 0x0000, 0x0000 }, /* R179 */
{ 0x0000, 0x0000, 0x0000 }, /* R180 */
{ 0x0000, 0x0000, 0x0000 }, /* R181 */
{ 0x0000, 0x0000, 0x0000 }, /* R182 */
{ 0x0000, 0x0000, 0x0000 }, /* R183 */
{ 0x0000, 0x0000, 0x0000 }, /* R184 */
{ 0x0000, 0x0000, 0x0000 }, /* R185 */
{ 0x0000, 0x0000, 0x0000 }, /* R186 */
{ 0x0000, 0x0000, 0x0000 }, /* R187 */
{ 0x0000, 0x0000, 0x0000 }, /* R188 */
{ 0x0000, 0x0000, 0x0000 }, /* R189 */
{ 0x0000, 0x0000, 0x0000 }, /* R190 */
{ 0x0000, 0x0000, 0x0000 }, /* R191 */
{ 0x0000, 0x0000, 0x0000 }, /* R192 */
{ 0x0000, 0x0000, 0x0000 }, /* R193 */
{ 0x0000, 0x0000, 0x0000 }, /* R194 */
{ 0x0000, 0x0000, 0x0000 }, /* R195 */
{ 0x0000, 0x0000, 0x0000 }, /* R196 */
{ 0x0000, 0x0000, 0x0000 }, /* R197 */
{ 0x0000, 0x0000, 0x0000 }, /* R198 */
{ 0x0000, 0x0000, 0x0000 }, /* R199 */
{ 0x0000, 0x0000, 0x0000 }, /* R200 */
{ 0x0000, 0x0000, 0x0000 }, /* R201 */
{ 0x0000, 0x0000, 0x0000 }, /* R202 */
{ 0x0000, 0x0000, 0x0000 }, /* R203 */
{ 0x0000, 0x0000, 0x0000 }, /* R204 */
{ 0x0000, 0x0000, 0x0000 }, /* R205 */
{ 0x0000, 0x0000, 0x0000 }, /* R206 */
{ 0x0000, 0x0000, 0x0000 }, /* R207 */
{ 0x0000, 0x0000, 0x0000 }, /* R208 */
{ 0x0000, 0x0000, 0x0000 }, /* R209 */
{ 0x0000, 0x0000, 0x0000 }, /* R210 */
{ 0x0000, 0x0000, 0x0000 }, /* R211 */
{ 0x0000, 0x0000, 0x0000 }, /* R212 */
{ 0x0000, 0x0000, 0x0000 }, /* R213 */
{ 0x0000, 0x0000, 0x0000 }, /* R214 */
{ 0x0000, 0x0000, 0x0000 }, /* R215 */
{ 0x0000, 0x0000, 0x0000 }, /* R216 */
{ 0x0000, 0x0000, 0x0000 }, /* R217 */
{ 0x0000, 0x0000, 0x0000 }, /* R218 */
{ 0x0000, 0x0000, 0x0000 }, /* R219 */
{ 0x0000, 0x0000, 0x0000 }, /* R220 */
{ 0x0000, 0x0000, 0x0000 }, /* R221 */
{ 0x0000, 0x0000, 0x0000 }, /* R222 */
{ 0x0000, 0x0000, 0x0000 }, /* R223 */
{ 0x0000, 0x0000, 0x0000 }, /* R224 */
{ 0x0000, 0x0000, 0x0000 }, /* R225 */
{ 0x0000, 0x0000, 0x0000 }, /* R226 */
{ 0x0000, 0x0000, 0x0000 }, /* R227 */
{ 0x0000, 0x0000, 0x0000 }, /* R228 */
{ 0x0000, 0x0000, 0x0000 }, /* R229 */
{ 0x0000, 0x0000, 0x0000 }, /* R230 */
{ 0x0000, 0x0000, 0x0000 }, /* R231 */
{ 0x0000, 0x0000, 0x0000 }, /* R232 */
{ 0x0000, 0x0000, 0x0000 }, /* R233 */
{ 0x0000, 0x0000, 0x0000 }, /* R234 */
{ 0x0000, 0x0000, 0x0000 }, /* R235 */
{ 0x0000, 0x0000, 0x0000 }, /* R236 */
{ 0x0000, 0x0000, 0x0000 }, /* R237 */
{ 0x0000, 0x0000, 0x0000 }, /* R238 */
{ 0x0000, 0x0000, 0x0000 }, /* R239 */
{ 0x0000, 0x0000, 0x0000 }, /* R240 */
{ 0x0000, 0x0000, 0x0000 }, /* R241 */
{ 0x0000, 0x0000, 0x0000 }, /* R242 */
{ 0x0000, 0x0000, 0x0000 }, /* R243 */
{ 0x0000, 0x0000, 0x0000 }, /* R244 */
{ 0x0000, 0x0000, 0x0000 }, /* R245 */
{ 0x0000, 0x0000, 0x0000 }, /* R246 */
{ 0x0000, 0x0000, 0x0000 }, /* R247 */
{ 0x0000, 0x0000, 0x0000 }, /* R248 */
{ 0x0000, 0x0000, 0x0000 }, /* R249 */
{ 0x0000, 0x0000, 0x0000 }, /* R250 */
{ 0x0000, 0x0000, 0x0000 }, /* R251 */
{ 0x0000, 0x0000, 0x0000 }, /* R252 */
{ 0x0000, 0x0000, 0x0000 }, /* R253 */
{ 0x0000, 0x0000, 0x0000 }, /* R254 */
{ 0x0000, 0x0000, 0x0000 }, /* R255 */
{ 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
{ 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
{ 0x0000, 0x0000, 0x0000 }, /* R258 */
{ 0x0000, 0x0000, 0x0000 }, /* R259 */
{ 0x0000, 0x0000, 0x0000 }, /* R260 */
{ 0x0000, 0x0000, 0x0000 }, /* R261 */
{ 0x0000, 0x0000, 0x0000 }, /* R262 */
{ 0x0000, 0x0000, 0x0000 }, /* R263 */
{ 0x0000, 0x0000, 0x0000 }, /* R264 */
{ 0x0000, 0x0000, 0x0000 }, /* R265 */
{ 0x0000, 0x0000, 0x0000 }, /* R266 */
{ 0x0000, 0x0000, 0x0000 }, /* R267 */
{ 0x0000, 0x0000, 0x0000 }, /* R268 */
{ 0x0000, 0x0000, 0x0000 }, /* R269 */
{ 0x0000, 0x0000, 0x0000 }, /* R270 */
{ 0x0000, 0x0000, 0x0000 }, /* R271 */
{ 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
{ 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R274 */
{ 0x0000, 0x0000, 0x0000 }, /* R275 */
{ 0x0000, 0x0000, 0x0000 }, /* R276 */
{ 0x0000, 0x0000, 0x0000 }, /* R277 */
{ 0x0000, 0x0000, 0x0000 }, /* R278 */
{ 0x0000, 0x0000, 0x0000 }, /* R279 */
{ 0x0000, 0x0000, 0x0000 }, /* R280 */
{ 0x0000, 0x0000, 0x0000 }, /* R281 */
{ 0x0000, 0x0000, 0x0000 }, /* R282 */
{ 0x0000, 0x0000, 0x0000 }, /* R283 */
{ 0x0000, 0x0000, 0x0000 }, /* R284 */
{ 0x0000, 0x0000, 0x0000 }, /* R285 */
{ 0x0000, 0x0000, 0x0000 }, /* R286 */
{ 0x0000, 0x0000, 0x0000 }, /* R287 */
{ 0x0000, 0x0000, 0x0000 }, /* R288 */
{ 0x0000, 0x0000, 0x0000 }, /* R289 */
{ 0x0000, 0x0000, 0x0000 }, /* R290 */
{ 0x0000, 0x0000, 0x0000 }, /* R291 */
{ 0x0000, 0x0000, 0x0000 }, /* R292 */
{ 0x0000, 0x0000, 0x0000 }, /* R293 */
{ 0x0000, 0x0000, 0x0000 }, /* R294 */
{ 0x0000, 0x0000, 0x0000 }, /* R295 */
{ 0x0000, 0x0000, 0x0000 }, /* R296 */
{ 0x0000, 0x0000, 0x0000 }, /* R297 */
{ 0x0000, 0x0000, 0x0000 }, /* R298 */
{ 0x0000, 0x0000, 0x0000 }, /* R299 */
{ 0x0000, 0x0000, 0x0000 }, /* R300 */
{ 0x0000, 0x0000, 0x0000 }, /* R301 */
{ 0x0000, 0x0000, 0x0000 }, /* R302 */
{ 0x0000, 0x0000, 0x0000 }, /* R303 */
{ 0x0000, 0x0000, 0x0000 }, /* R304 */
{ 0x0000, 0x0000, 0x0000 }, /* R305 */
{ 0x0000, 0x0000, 0x0000 }, /* R306 */
{ 0x0000, 0x0000, 0x0000 }, /* R307 */
{ 0x0000, 0x0000, 0x0000 }, /* R308 */
{ 0x0000, 0x0000, 0x0000 }, /* R309 */
{ 0x0000, 0x0000, 0x0000 }, /* R310 */
{ 0x0000, 0x0000, 0x0000 }, /* R311 */
{ 0x0000, 0x0000, 0x0000 }, /* R312 */
{ 0x0000, 0x0000, 0x0000 }, /* R313 */
{ 0x0000, 0x0000, 0x0000 }, /* R314 */
{ 0x0000, 0x0000, 0x0000 }, /* R315 */
{ 0x0000, 0x0000, 0x0000 }, /* R316 */
{ 0x0000, 0x0000, 0x0000 }, /* R317 */
{ 0x0000, 0x0000, 0x0000 }, /* R318 */
{ 0x0000, 0x0000, 0x0000 }, /* R319 */
{ 0x0000, 0x0000, 0x0000 }, /* R320 */
{ 0x0000, 0x0000, 0x0000 }, /* R321 */
{ 0x0000, 0x0000, 0x0000 }, /* R322 */
{ 0x0000, 0x0000, 0x0000 }, /* R323 */
{ 0x0000, 0x0000, 0x0000 }, /* R324 */
{ 0x0000, 0x0000, 0x0000 }, /* R325 */
{ 0x0000, 0x0000, 0x0000 }, /* R326 */
{ 0x0000, 0x0000, 0x0000 }, /* R327 */
{ 0x0000, 0x0000, 0x0000 }, /* R328 */
{ 0x0000, 0x0000, 0x0000 }, /* R329 */
{ 0x0000, 0x0000, 0x0000 }, /* R330 */
{ 0x0000, 0x0000, 0x0000 }, /* R331 */
{ 0x0000, 0x0000, 0x0000 }, /* R332 */
{ 0x0000, 0x0000, 0x0000 }, /* R333 */
{ 0x0000, 0x0000, 0x0000 }, /* R334 */
{ 0x0000, 0x0000, 0x0000 }, /* R335 */
{ 0x0000, 0x0000, 0x0000 }, /* R336 */
{ 0x0000, 0x0000, 0x0000 }, /* R337 */
{ 0x0000, 0x0000, 0x0000 }, /* R338 */
{ 0x0000, 0x0000, 0x0000 }, /* R339 */
{ 0x0000, 0x0000, 0x0000 }, /* R340 */
{ 0x0000, 0x0000, 0x0000 }, /* R341 */
{ 0x0000, 0x0000, 0x0000 }, /* R342 */
{ 0x0000, 0x0000, 0x0000 }, /* R343 */
{ 0x0000, 0x0000, 0x0000 }, /* R344 */
{ 0x0000, 0x0000, 0x0000 }, /* R345 */
{ 0x0000, 0x0000, 0x0000 }, /* R346 */
{ 0x0000, 0x0000, 0x0000 }, /* R347 */
{ 0x0000, 0x0000, 0x0000 }, /* R348 */
{ 0x0000, 0x0000, 0x0000 }, /* R349 */
{ 0x0000, 0x0000, 0x0000 }, /* R350 */
{ 0x0000, 0x0000, 0x0000 }, /* R351 */
{ 0x0000, 0x0000, 0x0000 }, /* R352 */
{ 0x0000, 0x0000, 0x0000 }, /* R353 */
{ 0x0000, 0x0000, 0x0000 }, /* R354 */
{ 0x0000, 0x0000, 0x0000 }, /* R355 */
{ 0x0000, 0x0000, 0x0000 }, /* R356 */
{ 0x0000, 0x0000, 0x0000 }, /* R357 */
{ 0x0000, 0x0000, 0x0000 }, /* R358 */
{ 0x0000, 0x0000, 0x0000 }, /* R359 */
{ 0x0000, 0x0000, 0x0000 }, /* R360 */
{ 0x0000, 0x0000, 0x0000 }, /* R361 */
{ 0x0000, 0x0000, 0x0000 }, /* R362 */
{ 0x0000, 0x0000, 0x0000 }, /* R363 */
{ 0x0000, 0x0000, 0x0000 }, /* R364 */
{ 0x0000, 0x0000, 0x0000 }, /* R365 */
{ 0x0000, 0x0000, 0x0000 }, /* R366 */
{ 0x0000, 0x0000, 0x0000 }, /* R367 */
{ 0x0000, 0x0000, 0x0000 }, /* R368 */
{ 0x0000, 0x0000, 0x0000 }, /* R369 */
{ 0x0000, 0x0000, 0x0000 }, /* R370 */
{ 0x0000, 0x0000, 0x0000 }, /* R371 */
{ 0x0000, 0x0000, 0x0000 }, /* R372 */
{ 0x0000, 0x0000, 0x0000 }, /* R373 */
{ 0x0000, 0x0000, 0x0000 }, /* R374 */
{ 0x0000, 0x0000, 0x0000 }, /* R375 */
{ 0x0000, 0x0000, 0x0000 }, /* R376 */
{ 0x0000, 0x0000, 0x0000 }, /* R377 */
{ 0x0000, 0x0000, 0x0000 }, /* R378 */
{ 0x0000, 0x0000, 0x0000 }, /* R379 */
{ 0x0000, 0x0000, 0x0000 }, /* R380 */
{ 0x0000, 0x0000, 0x0000 }, /* R381 */
{ 0x0000, 0x0000, 0x0000 }, /* R382 */
{ 0x0000, 0x0000, 0x0000 }, /* R383 */
{ 0x0000, 0x0000, 0x0000 }, /* R384 */
{ 0x0000, 0x0000, 0x0000 }, /* R385 */
{ 0x0000, 0x0000, 0x0000 }, /* R386 */
{ 0x0000, 0x0000, 0x0000 }, /* R387 */
{ 0x0000, 0x0000, 0x0000 }, /* R388 */
{ 0x0000, 0x0000, 0x0000 }, /* R389 */
{ 0x0000, 0x0000, 0x0000 }, /* R390 */
{ 0x0000, 0x0000, 0x0000 }, /* R391 */
{ 0x0000, 0x0000, 0x0000 }, /* R392 */
{ 0x0000, 0x0000, 0x0000 }, /* R393 */
{ 0x0000, 0x0000, 0x0000 }, /* R394 */
{ 0x0000, 0x0000, 0x0000 }, /* R395 */
{ 0x0000, 0x0000, 0x0000 }, /* R396 */
{ 0x0000, 0x0000, 0x0000 }, /* R397 */
{ 0x0000, 0x0000, 0x0000 }, /* R398 */
{ 0x0000, 0x0000, 0x0000 }, /* R399 */
{ 0x0000, 0x0000, 0x0000 }, /* R400 */
{ 0x0000, 0x0000, 0x0000 }, /* R401 */
{ 0x0000, 0x0000, 0x0000 }, /* R402 */
{ 0x0000, 0x0000, 0x0000 }, /* R403 */
{ 0x0000, 0x0000, 0x0000 }, /* R404 */
{ 0x0000, 0x0000, 0x0000 }, /* R405 */
{ 0x0000, 0x0000, 0x0000 }, /* R406 */
{ 0x0000, 0x0000, 0x0000 }, /* R407 */
{ 0x0000, 0x0000, 0x0000 }, /* R408 */
{ 0x0000, 0x0000, 0x0000 }, /* R409 */
{ 0x0000, 0x0000, 0x0000 }, /* R410 */
{ 0x0000, 0x0000, 0x0000 }, /* R411 */
{ 0x0000, 0x0000, 0x0000 }, /* R412 */
{ 0x0000, 0x0000, 0x0000 }, /* R413 */
{ 0x0000, 0x0000, 0x0000 }, /* R414 */
{ 0x0000, 0x0000, 0x0000 }, /* R415 */
{ 0x0000, 0x0000, 0x0000 }, /* R416 */
{ 0x0000, 0x0000, 0x0000 }, /* R417 */
{ 0x0000, 0x0000, 0x0000 }, /* R418 */
{ 0x0000, 0x0000, 0x0000 }, /* R419 */
{ 0x0000, 0x0000, 0x0000 }, /* R420 */
{ 0x0000, 0x0000, 0x0000 }, /* R421 */
{ 0x0000, 0x0000, 0x0000 }, /* R422 */
{ 0x0000, 0x0000, 0x0000 }, /* R423 */
{ 0x0000, 0x0000, 0x0000 }, /* R424 */
{ 0x0000, 0x0000, 0x0000 }, /* R425 */
{ 0x0000, 0x0000, 0x0000 }, /* R426 */
{ 0x0000, 0x0000, 0x0000 }, /* R427 */
{ 0x0000, 0x0000, 0x0000 }, /* R428 */
{ 0x0000, 0x0000, 0x0000 }, /* R429 */
{ 0x0000, 0x0000, 0x0000 }, /* R430 */
{ 0x0000, 0x0000, 0x0000 }, /* R431 */
{ 0x0000, 0x0000, 0x0000 }, /* R432 */
{ 0x0000, 0x0000, 0x0000 }, /* R433 */
{ 0x0000, 0x0000, 0x0000 }, /* R434 */
{ 0x0000, 0x0000, 0x0000 }, /* R435 */
{ 0x0000, 0x0000, 0x0000 }, /* R436 */
{ 0x0000, 0x0000, 0x0000 }, /* R437 */
{ 0x0000, 0x0000, 0x0000 }, /* R438 */
{ 0x0000, 0x0000, 0x0000 }, /* R439 */
{ 0x0000, 0x0000, 0x0000 }, /* R440 */
{ 0x0000, 0x0000, 0x0000 }, /* R441 */
{ 0x0000, 0x0000, 0x0000 }, /* R442 */
{ 0x0000, 0x0000, 0x0000 }, /* R443 */
{ 0x0000, 0x0000, 0x0000 }, /* R444 */
{ 0x0000, 0x0000, 0x0000 }, /* R445 */
{ 0x0000, 0x0000, 0x0000 }, /* R446 */
{ 0x0000, 0x0000, 0x0000 }, /* R447 */
{ 0x0000, 0x0000, 0x0000 }, /* R448 */
{ 0x0000, 0x0000, 0x0000 }, /* R449 */
{ 0x0000, 0x0000, 0x0000 }, /* R450 */
{ 0x0000, 0x0000, 0x0000 }, /* R451 */
{ 0x0000, 0x0000, 0x0000 }, /* R452 */
{ 0x0000, 0x0000, 0x0000 }, /* R453 */
{ 0x0000, 0x0000, 0x0000 }, /* R454 */
{ 0x0000, 0x0000, 0x0000 }, /* R455 */
{ 0x0000, 0x0000, 0x0000 }, /* R456 */
{ 0x0000, 0x0000, 0x0000 }, /* R457 */
{ 0x0000, 0x0000, 0x0000 }, /* R458 */
{ 0x0000, 0x0000, 0x0000 }, /* R459 */
{ 0x0000, 0x0000, 0x0000 }, /* R460 */
{ 0x0000, 0x0000, 0x0000 }, /* R461 */
{ 0x0000, 0x0000, 0x0000 }, /* R462 */
{ 0x0000, 0x0000, 0x0000 }, /* R463 */
{ 0x0000, 0x0000, 0x0000 }, /* R464 */
{ 0x0000, 0x0000, 0x0000 }, /* R465 */
{ 0x0000, 0x0000, 0x0000 }, /* R466 */
{ 0x0000, 0x0000, 0x0000 }, /* R467 */
{ 0x0000, 0x0000, 0x0000 }, /* R468 */
{ 0x0000, 0x0000, 0x0000 }, /* R469 */
{ 0x0000, 0x0000, 0x0000 }, /* R470 */
{ 0x0000, 0x0000, 0x0000 }, /* R471 */
{ 0x0000, 0x0000, 0x0000 }, /* R472 */
{ 0x0000, 0x0000, 0x0000 }, /* R473 */
{ 0x0000, 0x0000, 0x0000 }, /* R474 */
{ 0x0000, 0x0000, 0x0000 }, /* R475 */
{ 0x0000, 0x0000, 0x0000 }, /* R476 */
{ 0x0000, 0x0000, 0x0000 }, /* R477 */
{ 0x0000, 0x0000, 0x0000 }, /* R478 */
{ 0x0000, 0x0000, 0x0000 }, /* R479 */
{ 0x0000, 0x0000, 0x0000 }, /* R480 */
{ 0x0000, 0x0000, 0x0000 }, /* R481 */
{ 0x0000, 0x0000, 0x0000 }, /* R482 */
{ 0x0000, 0x0000, 0x0000 }, /* R483 */
{ 0x0000, 0x0000, 0x0000 }, /* R484 */
{ 0x0000, 0x0000, 0x0000 }, /* R485 */
{ 0x0000, 0x0000, 0x0000 }, /* R486 */
{ 0x0000, 0x0000, 0x0000 }, /* R487 */
{ 0x0000, 0x0000, 0x0000 }, /* R488 */
{ 0x0000, 0x0000, 0x0000 }, /* R489 */
{ 0x0000, 0x0000, 0x0000 }, /* R490 */
{ 0x0000, 0x0000, 0x0000 }, /* R491 */
{ 0x0000, 0x0000, 0x0000 }, /* R492 */
{ 0x0000, 0x0000, 0x0000 }, /* R493 */
{ 0x0000, 0x0000, 0x0000 }, /* R494 */
{ 0x0000, 0x0000, 0x0000 }, /* R495 */
{ 0x0000, 0x0000, 0x0000 }, /* R496 */
{ 0x0000, 0x0000, 0x0000 }, /* R497 */
{ 0x0000, 0x0000, 0x0000 }, /* R498 */
{ 0x0000, 0x0000, 0x0000 }, /* R499 */
{ 0x0000, 0x0000, 0x0000 }, /* R500 */
{ 0x0000, 0x0000, 0x0000 }, /* R501 */
{ 0x0000, 0x0000, 0x0000 }, /* R502 */
{ 0x0000, 0x0000, 0x0000 }, /* R503 */
{ 0x0000, 0x0000, 0x0000 }, /* R504 */
{ 0x0000, 0x0000, 0x0000 }, /* R505 */
{ 0x0000, 0x0000, 0x0000 }, /* R506 */
{ 0x0000, 0x0000, 0x0000 }, /* R507 */
{ 0x0000, 0x0000, 0x0000 }, /* R508 */
{ 0x0000, 0x0000, 0x0000 }, /* R509 */
{ 0x0000, 0x0000, 0x0000 }, /* R510 */
{ 0x0000, 0x0000, 0x0000 }, /* R511 */
{ 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
{ 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R514 */
{ 0x0000, 0x0000, 0x0000 }, /* R515 */
{ 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
{ 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R518 */
{ 0x0000, 0x0000, 0x0000 }, /* R519 */
{ 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
{ 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R522 */
{ 0x0000, 0x0000, 0x0000 }, /* R523 */
{ 0x0000, 0x0000, 0x0000 }, /* R524 */
{ 0x0000, 0x0000, 0x0000 }, /* R525 */
{ 0x0000, 0x0000, 0x0000 }, /* R526 */
{ 0x0000, 0x0000, 0x0000 }, /* R527 */
{ 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
{ 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
{ 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
{ 0x0000, 0x0000, 0x0000 }, /* R531 */
{ 0x0000, 0x0000, 0x0000 }, /* R532 */
{ 0x0000, 0x0000, 0x0000 }, /* R533 */
{ 0x0000, 0x0000, 0x0000 }, /* R534 */
{ 0x0000, 0x0000, 0x0000 }, /* R535 */
{ 0x0000, 0x0000, 0x0000 }, /* R536 */
{ 0x0000, 0x0000, 0x0000 }, /* R537 */
{ 0x0000, 0x0000, 0x0000 }, /* R538 */
{ 0x0000, 0x0000, 0x0000 }, /* R539 */
{ 0x0000, 0x0000, 0x0000 }, /* R540 */
{ 0x0000, 0x0000, 0x0000 }, /* R541 */
{ 0x0000, 0x0000, 0x0000 }, /* R542 */
{ 0x0000, 0x0000, 0x0000 }, /* R543 */
{ 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
{ 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
{ 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
{ 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
{ 0x0000, 0x0000, 0x0000 }, /* R549 */
{ 0x0000, 0x0000, 0x0000 }, /* R550 */
{ 0x0000, 0x0000, 0x0000 }, /* R551 */
{ 0x0000, 0x0000, 0x0000 }, /* R552 */
{ 0x0000, 0x0000, 0x0000 }, /* R553 */
{ 0x0000, 0x0000, 0x0000 }, /* R554 */
{ 0x0000, 0x0000, 0x0000 }, /* R555 */
{ 0x0000, 0x0000, 0x0000 }, /* R556 */
{ 0x0000, 0x0000, 0x0000 }, /* R557 */
{ 0x0000, 0x0000, 0x0000 }, /* R558 */
{ 0x0000, 0x0000, 0x0000 }, /* R559 */
{ 0x0000, 0x0000, 0x0000 }, /* R560 */
{ 0x0000, 0x0000, 0x0000 }, /* R561 */
{ 0x0000, 0x0000, 0x0000 }, /* R562 */
{ 0x0000, 0x0000, 0x0000 }, /* R563 */
{ 0x0000, 0x0000, 0x0000 }, /* R564 */
{ 0x0000, 0x0000, 0x0000 }, /* R565 */
{ 0x0000, 0x0000, 0x0000 }, /* R566 */
{ 0x0000, 0x0000, 0x0000 }, /* R567 */
{ 0x0000, 0x0000, 0x0000 }, /* R568 */
{ 0x0000, 0x0000, 0x0000 }, /* R569 */
{ 0x0000, 0x0000, 0x0000 }, /* R570 */
{ 0x0000, 0x0000, 0x0000 }, /* R571 */
{ 0x0000, 0x0000, 0x0000 }, /* R572 */
{ 0x0000, 0x0000, 0x0000 }, /* R573 */
{ 0x0000, 0x0000, 0x0000 }, /* R574 */
{ 0x0000, 0x0000, 0x0000 }, /* R575 */
{ 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
{ 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
{ 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
{ 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
{ 0x0000, 0x0000, 0x0000 }, /* R581 */
{ 0x0000, 0x0000, 0x0000 }, /* R582 */
{ 0x0000, 0x0000, 0x0000 }, /* R583 */
{ 0x0000, 0x0000, 0x0000 }, /* R584 */
{ 0x0000, 0x0000, 0x0000 }, /* R585 */
{ 0x0000, 0x0000, 0x0000 }, /* R586 */
{ 0x0000, 0x0000, 0x0000 }, /* R587 */
{ 0x0000, 0x0000, 0x0000 }, /* R588 */
{ 0x0000, 0x0000, 0x0000 }, /* R589 */
{ 0x0000, 0x0000, 0x0000 }, /* R590 */
{ 0x0000, 0x0000, 0x0000 }, /* R591 */
{ 0x0000, 0x0000, 0x0000 }, /* R592 */
{ 0x0000, 0x0000, 0x0000 }, /* R593 */
{ 0x0000, 0x0000, 0x0000 }, /* R594 */
{ 0x0000, 0x0000, 0x0000 }, /* R595 */
{ 0x0000, 0x0000, 0x0000 }, /* R596 */
{ 0x0000, 0x0000, 0x0000 }, /* R597 */
{ 0x0000, 0x0000, 0x0000 }, /* R598 */
{ 0x0000, 0x0000, 0x0000 }, /* R599 */
{ 0x0000, 0x0000, 0x0000 }, /* R600 */
{ 0x0000, 0x0000, 0x0000 }, /* R601 */
{ 0x0000, 0x0000, 0x0000 }, /* R602 */
{ 0x0000, 0x0000, 0x0000 }, /* R603 */
{ 0x0000, 0x0000, 0x0000 }, /* R604 */
{ 0x0000, 0x0000, 0x0000 }, /* R605 */
{ 0x0000, 0x0000, 0x0000 }, /* R606 */
{ 0x0000, 0x0000, 0x0000 }, /* R607 */
{ 0x0000, 0x0000, 0x0000 }, /* R608 */
{ 0x0000, 0x0000, 0x0000 }, /* R609 */
{ 0x0000, 0x0000, 0x0000 }, /* R610 */
{ 0x0000, 0x0000, 0x0000 }, /* R611 */
{ 0x0000, 0x0000, 0x0000 }, /* R612 */
{ 0x0000, 0x0000, 0x0000 }, /* R613 */
{ 0x0000, 0x0000, 0x0000 }, /* R614 */
{ 0x0000, 0x0000, 0x0000 }, /* R615 */
{ 0x0000, 0x0000, 0x0000 }, /* R616 */
{ 0x0000, 0x0000, 0x0000 }, /* R617 */
{ 0x0000, 0x0000, 0x0000 }, /* R618 */
{ 0x0000, 0x0000, 0x0000 }, /* R619 */
{ 0x0000, 0x0000, 0x0000 }, /* R620 */
{ 0x0000, 0x0000, 0x0000 }, /* R621 */
{ 0x0000, 0x0000, 0x0000 }, /* R622 */
{ 0x0000, 0x0000, 0x0000 }, /* R623 */
{ 0x0000, 0x0000, 0x0000 }, /* R624 */
{ 0x0000, 0x0000, 0x0000 }, /* R625 */
{ 0x0000, 0x0000, 0x0000 }, /* R626 */
{ 0x0000, 0x0000, 0x0000 }, /* R627 */
{ 0x0000, 0x0000, 0x0000 }, /* R628 */
{ 0x0000, 0x0000, 0x0000 }, /* R629 */
{ 0x0000, 0x0000, 0x0000 }, /* R630 */
{ 0x0000, 0x0000, 0x0000 }, /* R631 */
{ 0x0000, 0x0000, 0x0000 }, /* R632 */
{ 0x0000, 0x0000, 0x0000 }, /* R633 */
{ 0x0000, 0x0000, 0x0000 }, /* R634 */
{ 0x0000, 0x0000, 0x0000 }, /* R635 */
{ 0x0000, 0x0000, 0x0000 }, /* R636 */
{ 0x0000, 0x0000, 0x0000 }, /* R637 */
{ 0x0000, 0x0000, 0x0000 }, /* R638 */
{ 0x0000, 0x0000, 0x0000 }, /* R639 */
{ 0x0000, 0x0000, 0x0000 }, /* R640 */
{ 0x0000, 0x0000, 0x0000 }, /* R641 */
{ 0x0000, 0x0000, 0x0000 }, /* R642 */
{ 0x0000, 0x0000, 0x0000 }, /* R643 */
{ 0x0000, 0x0000, 0x0000 }, /* R644 */
{ 0x0000, 0x0000, 0x0000 }, /* R645 */
{ 0x0000, 0x0000, 0x0000 }, /* R646 */
{ 0x0000, 0x0000, 0x0000 }, /* R647 */
{ 0x0000, 0x0000, 0x0000 }, /* R648 */
{ 0x0000, 0x0000, 0x0000 }, /* R649 */
{ 0x0000, 0x0000, 0x0000 }, /* R650 */
{ 0x0000, 0x0000, 0x0000 }, /* R651 */
{ 0x0000, 0x0000, 0x0000 }, /* R652 */
{ 0x0000, 0x0000, 0x0000 }, /* R653 */
{ 0x0000, 0x0000, 0x0000 }, /* R654 */
{ 0x0000, 0x0000, 0x0000 }, /* R655 */
{ 0x0000, 0x0000, 0x0000 }, /* R656 */
{ 0x0000, 0x0000, 0x0000 }, /* R657 */
{ 0x0000, 0x0000, 0x0000 }, /* R658 */
{ 0x0000, 0x0000, 0x0000 }, /* R659 */
{ 0x0000, 0x0000, 0x0000 }, /* R660 */
{ 0x0000, 0x0000, 0x0000 }, /* R661 */
{ 0x0000, 0x0000, 0x0000 }, /* R662 */
{ 0x0000, 0x0000, 0x0000 }, /* R663 */
{ 0x0000, 0x0000, 0x0000 }, /* R664 */
{ 0x0000, 0x0000, 0x0000 }, /* R665 */
{ 0x0000, 0x0000, 0x0000 }, /* R666 */
{ 0x0000, 0x0000, 0x0000 }, /* R667 */
{ 0x0000, 0x0000, 0x0000 }, /* R668 */
{ 0x0000, 0x0000, 0x0000 }, /* R669 */
{ 0x0000, 0x0000, 0x0000 }, /* R670 */
{ 0x0000, 0x0000, 0x0000 }, /* R671 */
{ 0x0000, 0x0000, 0x0000 }, /* R672 */
{ 0x0000, 0x0000, 0x0000 }, /* R673 */
{ 0x0000, 0x0000, 0x0000 }, /* R674 */
{ 0x0000, 0x0000, 0x0000 }, /* R675 */
{ 0x0000, 0x0000, 0x0000 }, /* R676 */
{ 0x0000, 0x0000, 0x0000 }, /* R677 */
{ 0x0000, 0x0000, 0x0000 }, /* R678 */
{ 0x0000, 0x0000, 0x0000 }, /* R679 */
{ 0x0000, 0x0000, 0x0000 }, /* R680 */
{ 0x0000, 0x0000, 0x0000 }, /* R681 */
{ 0x0000, 0x0000, 0x0000 }, /* R682 */
{ 0x0000, 0x0000, 0x0000 }, /* R683 */
{ 0x0000, 0x0000, 0x0000 }, /* R684 */
{ 0x0000, 0x0000, 0x0000 }, /* R685 */
{ 0x0000, 0x0000, 0x0000 }, /* R686 */
{ 0x0000, 0x0000, 0x0000 }, /* R687 */
{ 0x0000, 0x0000, 0x0000 }, /* R688 */
{ 0x0000, 0x0000, 0x0000 }, /* R689 */
{ 0x0000, 0x0000, 0x0000 }, /* R690 */
{ 0x0000, 0x0000, 0x0000 }, /* R691 */
{ 0x0000, 0x0000, 0x0000 }, /* R692 */
{ 0x0000, 0x0000, 0x0000 }, /* R693 */
{ 0x0000, 0x0000, 0x0000 }, /* R694 */
{ 0x0000, 0x0000, 0x0000 }, /* R695 */
{ 0x0000, 0x0000, 0x0000 }, /* R696 */
{ 0x0000, 0x0000, 0x0000 }, /* R697 */
{ 0x0000, 0x0000, 0x0000 }, /* R698 */
{ 0x0000, 0x0000, 0x0000 }, /* R699 */
{ 0x0000, 0x0000, 0x0000 }, /* R700 */
{ 0x0000, 0x0000, 0x0000 }, /* R701 */
{ 0x0000, 0x0000, 0x0000 }, /* R702 */
{ 0x0000, 0x0000, 0x0000 }, /* R703 */
{ 0x0000, 0x0000, 0x0000 }, /* R704 */
{ 0x0000, 0x0000, 0x0000 }, /* R705 */
{ 0x0000, 0x0000, 0x0000 }, /* R706 */
{ 0x0000, 0x0000, 0x0000 }, /* R707 */
{ 0x0000, 0x0000, 0x0000 }, /* R708 */
{ 0x0000, 0x0000, 0x0000 }, /* R709 */
{ 0x0000, 0x0000, 0x0000 }, /* R710 */
{ 0x0000, 0x0000, 0x0000 }, /* R711 */
{ 0x0000, 0x0000, 0x0000 }, /* R712 */
{ 0x0000, 0x0000, 0x0000 }, /* R713 */
{ 0x0000, 0x0000, 0x0000 }, /* R714 */
{ 0x0000, 0x0000, 0x0000 }, /* R715 */
{ 0x0000, 0x0000, 0x0000 }, /* R716 */
{ 0x0000, 0x0000, 0x0000 }, /* R717 */
{ 0x0000, 0x0000, 0x0000 }, /* R718 */
{ 0x0000, 0x0000, 0x0000 }, /* R719 */
{ 0x0000, 0x0000, 0x0000 }, /* R720 */
{ 0x0000, 0x0000, 0x0000 }, /* R721 */
{ 0x0000, 0x0000, 0x0000 }, /* R722 */
{ 0x0000, 0x0000, 0x0000 }, /* R723 */
{ 0x0000, 0x0000, 0x0000 }, /* R724 */
{ 0x0000, 0x0000, 0x0000 }, /* R725 */
{ 0x0000, 0x0000, 0x0000 }, /* R726 */
{ 0x0000, 0x0000, 0x0000 }, /* R727 */
{ 0x0000, 0x0000, 0x0000 }, /* R728 */
{ 0x0000, 0x0000, 0x0000 }, /* R729 */
{ 0x0000, 0x0000, 0x0000 }, /* R730 */
{ 0x0000, 0x0000, 0x0000 }, /* R731 */
{ 0x0000, 0x0000, 0x0000 }, /* R732 */
{ 0x0000, 0x0000, 0x0000 }, /* R733 */
{ 0x0000, 0x0000, 0x0000 }, /* R734 */
{ 0x0000, 0x0000, 0x0000 }, /* R735 */
{ 0x0000, 0x0000, 0x0000 }, /* R736 */
{ 0x0000, 0x0000, 0x0000 }, /* R737 */
{ 0x0000, 0x0000, 0x0000 }, /* R738 */
{ 0x0000, 0x0000, 0x0000 }, /* R739 */
{ 0x0000, 0x0000, 0x0000 }, /* R740 */
{ 0x0000, 0x0000, 0x0000 }, /* R741 */
{ 0x0000, 0x0000, 0x0000 }, /* R742 */
{ 0x0000, 0x0000, 0x0000 }, /* R743 */
{ 0x0000, 0x0000, 0x0000 }, /* R744 */
{ 0x0000, 0x0000, 0x0000 }, /* R745 */
{ 0x0000, 0x0000, 0x0000 }, /* R746 */
{ 0x0000, 0x0000, 0x0000 }, /* R747 */
{ 0x0000, 0x0000, 0x0000 }, /* R748 */
{ 0x0000, 0x0000, 0x0000 }, /* R749 */
{ 0x0000, 0x0000, 0x0000 }, /* R750 */
{ 0x0000, 0x0000, 0x0000 }, /* R751 */
{ 0x0000, 0x0000, 0x0000 }, /* R752 */
{ 0x0000, 0x0000, 0x0000 }, /* R753 */
{ 0x0000, 0x0000, 0x0000 }, /* R754 */
{ 0x0000, 0x0000, 0x0000 }, /* R755 */
{ 0x0000, 0x0000, 0x0000 }, /* R756 */
{ 0x0000, 0x0000, 0x0000 }, /* R757 */
{ 0x0000, 0x0000, 0x0000 }, /* R758 */
{ 0x0000, 0x0000, 0x0000 }, /* R759 */
{ 0x0000, 0x0000, 0x0000 }, /* R760 */
{ 0x0000, 0x0000, 0x0000 }, /* R761 */
{ 0x0000, 0x0000, 0x0000 }, /* R762 */
{ 0x0000, 0x0000, 0x0000 }, /* R763 */
{ 0x0000, 0x0000, 0x0000 }, /* R764 */
{ 0x0000, 0x0000, 0x0000 }, /* R765 */
{ 0x0000, 0x0000, 0x0000 }, /* R766 */
{ 0x0000, 0x0000, 0x0000 }, /* R767 */
{ 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
{ 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
{ 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
{ 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
{ 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
{ 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
{ 0x0000, 0x0000, 0x0000 }, /* R776 */
{ 0x0000, 0x0000, 0x0000 }, /* R777 */
{ 0x0000, 0x0000, 0x0000 }, /* R778 */
{ 0x0000, 0x0000, 0x0000 }, /* R779 */
{ 0x0000, 0x0000, 0x0000 }, /* R780 */
{ 0x0000, 0x0000, 0x0000 }, /* R781 */
{ 0x0000, 0x0000, 0x0000 }, /* R782 */
{ 0x0000, 0x0000, 0x0000 }, /* R783 */
{ 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
{ 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
{ 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
{ 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
{ 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
{ 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
{ 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
{ 0x0000, 0x0000, 0x0000 }, /* R792 */
{ 0x0000, 0x0000, 0x0000 }, /* R793 */
{ 0x0000, 0x0000, 0x0000 }, /* R794 */
{ 0x0000, 0x0000, 0x0000 }, /* R795 */
{ 0x0000, 0x0000, 0x0000 }, /* R796 */
{ 0x0000, 0x0000, 0x0000 }, /* R797 */
{ 0x0000, 0x0000, 0x0000 }, /* R798 */
{ 0x0000, 0x0000, 0x0000 }, /* R799 */
{ 0x0000, 0x0000, 0x0000 }, /* R800 */
{ 0x0000, 0x0000, 0x0000 }, /* R801 */
{ 0x0000, 0x0000, 0x0000 }, /* R802 */
{ 0x0000, 0x0000, 0x0000 }, /* R803 */
{ 0x0000, 0x0000, 0x0000 }, /* R804 */
{ 0x0000, 0x0000, 0x0000 }, /* R805 */
{ 0x0000, 0x0000, 0x0000 }, /* R806 */
{ 0x0000, 0x0000, 0x0000 }, /* R807 */
{ 0x0000, 0x0000, 0x0000 }, /* R808 */
{ 0x0000, 0x0000, 0x0000 }, /* R809 */
{ 0x0000, 0x0000, 0x0000 }, /* R810 */
{ 0x0000, 0x0000, 0x0000 }, /* R811 */
{ 0x0000, 0x0000, 0x0000 }, /* R812 */
{ 0x0000, 0x0000, 0x0000 }, /* R813 */
{ 0x0000, 0x0000, 0x0000 }, /* R814 */
{ 0x0000, 0x0000, 0x0000 }, /* R815 */
{ 0x0000, 0x0000, 0x0000 }, /* R816 */
{ 0x0000, 0x0000, 0x0000 }, /* R817 */
{ 0x0000, 0x0000, 0x0000 }, /* R818 */
{ 0x0000, 0x0000, 0x0000 }, /* R819 */
{ 0x0000, 0x0000, 0x0000 }, /* R820 */
{ 0x0000, 0x0000, 0x0000 }, /* R821 */
{ 0x0000, 0x0000, 0x0000 }, /* R822 */
{ 0x0000, 0x0000, 0x0000 }, /* R823 */
{ 0x0000, 0x0000, 0x0000 }, /* R824 */
{ 0x0000, 0x0000, 0x0000 }, /* R825 */
{ 0x0000, 0x0000, 0x0000 }, /* R826 */
{ 0x0000, 0x0000, 0x0000 }, /* R827 */
{ 0x0000, 0x0000, 0x0000 }, /* R828 */
{ 0x0000, 0x0000, 0x0000 }, /* R829 */
{ 0x0000, 0x0000, 0x0000 }, /* R830 */
{ 0x0000, 0x0000, 0x0000 }, /* R831 */
{ 0x0000, 0x0000, 0x0000 }, /* R832 */
{ 0x0000, 0x0000, 0x0000 }, /* R833 */
{ 0x0000, 0x0000, 0x0000 }, /* R834 */
{ 0x0000, 0x0000, 0x0000 }, /* R835 */
{ 0x0000, 0x0000, 0x0000 }, /* R836 */
{ 0x0000, 0x0000, 0x0000 }, /* R837 */
{ 0x0000, 0x0000, 0x0000 }, /* R838 */
{ 0x0000, 0x0000, 0x0000 }, /* R839 */
{ 0x0000, 0x0000, 0x0000 }, /* R840 */
{ 0x0000, 0x0000, 0x0000 }, /* R841 */
{ 0x0000, 0x0000, 0x0000 }, /* R842 */
{ 0x0000, 0x0000, 0x0000 }, /* R843 */
{ 0x0000, 0x0000, 0x0000 }, /* R844 */
{ 0x0000, 0x0000, 0x0000 }, /* R845 */
{ 0x0000, 0x0000, 0x0000 }, /* R846 */
{ 0x0000, 0x0000, 0x0000 }, /* R847 */
{ 0x0000, 0x0000, 0x0000 }, /* R848 */
{ 0x0000, 0x0000, 0x0000 }, /* R849 */
{ 0x0000, 0x0000, 0x0000 }, /* R850 */
{ 0x0000, 0x0000, 0x0000 }, /* R851 */
{ 0x0000, 0x0000, 0x0000 }, /* R852 */
{ 0x0000, 0x0000, 0x0000 }, /* R853 */
{ 0x0000, 0x0000, 0x0000 }, /* R854 */
{ 0x0000, 0x0000, 0x0000 }, /* R855 */
{ 0x0000, 0x0000, 0x0000 }, /* R856 */
{ 0x0000, 0x0000, 0x0000 }, /* R857 */
{ 0x0000, 0x0000, 0x0000 }, /* R858 */
{ 0x0000, 0x0000, 0x0000 }, /* R859 */
{ 0x0000, 0x0000, 0x0000 }, /* R860 */
{ 0x0000, 0x0000, 0x0000 }, /* R861 */
{ 0x0000, 0x0000, 0x0000 }, /* R862 */
{ 0x0000, 0x0000, 0x0000 }, /* R863 */
{ 0x0000, 0x0000, 0x0000 }, /* R864 */
{ 0x0000, 0x0000, 0x0000 }, /* R865 */
{ 0x0000, 0x0000, 0x0000 }, /* R866 */
{ 0x0000, 0x0000, 0x0000 }, /* R867 */
{ 0x0000, 0x0000, 0x0000 }, /* R868 */
{ 0x0000, 0x0000, 0x0000 }, /* R869 */
{ 0x0000, 0x0000, 0x0000 }, /* R870 */
{ 0x0000, 0x0000, 0x0000 }, /* R871 */
{ 0x0000, 0x0000, 0x0000 }, /* R872 */
{ 0x0000, 0x0000, 0x0000 }, /* R873 */
{ 0x0000, 0x0000, 0x0000 }, /* R874 */
{ 0x0000, 0x0000, 0x0000 }, /* R875 */
{ 0x0000, 0x0000, 0x0000 }, /* R876 */
{ 0x0000, 0x0000, 0x0000 }, /* R877 */
{ 0x0000, 0x0000, 0x0000 }, /* R878 */
{ 0x0000, 0x0000, 0x0000 }, /* R879 */
{ 0x0000, 0x0000, 0x0000 }, /* R880 */
{ 0x0000, 0x0000, 0x0000 }, /* R881 */
{ 0x0000, 0x0000, 0x0000 }, /* R882 */
{ 0x0000, 0x0000, 0x0000 }, /* R883 */
{ 0x0000, 0x0000, 0x0000 }, /* R884 */
{ 0x0000, 0x0000, 0x0000 }, /* R885 */
{ 0x0000, 0x0000, 0x0000 }, /* R886 */
{ 0x0000, 0x0000, 0x0000 }, /* R887 */
{ 0x0000, 0x0000, 0x0000 }, /* R888 */
{ 0x0000, 0x0000, 0x0000 }, /* R889 */
{ 0x0000, 0x0000, 0x0000 }, /* R890 */
{ 0x0000, 0x0000, 0x0000 }, /* R891 */
{ 0x0000, 0x0000, 0x0000 }, /* R892 */
{ 0x0000, 0x0000, 0x0000 }, /* R893 */
{ 0x0000, 0x0000, 0x0000 }, /* R894 */
{ 0x0000, 0x0000, 0x0000 }, /* R895 */
{ 0x0000, 0x0000, 0x0000 }, /* R896 */
{ 0x0000, 0x0000, 0x0000 }, /* R897 */
{ 0x0000, 0x0000, 0x0000 }, /* R898 */
{ 0x0000, 0x0000, 0x0000 }, /* R899 */
{ 0x0000, 0x0000, 0x0000 }, /* R900 */
{ 0x0000, 0x0000, 0x0000 }, /* R901 */
{ 0x0000, 0x0000, 0x0000 }, /* R902 */
{ 0x0000, 0x0000, 0x0000 }, /* R903 */
{ 0x0000, 0x0000, 0x0000 }, /* R904 */
{ 0x0000, 0x0000, 0x0000 }, /* R905 */
{ 0x0000, 0x0000, 0x0000 }, /* R906 */
{ 0x0000, 0x0000, 0x0000 }, /* R907 */
{ 0x0000, 0x0000, 0x0000 }, /* R908 */
{ 0x0000, 0x0000, 0x0000 }, /* R909 */
{ 0x0000, 0x0000, 0x0000 }, /* R910 */
{ 0x0000, 0x0000, 0x0000 }, /* R911 */
{ 0x0000, 0x0000, 0x0000 }, /* R912 */
{ 0x0000, 0x0000, 0x0000 }, /* R913 */
{ 0x0000, 0x0000, 0x0000 }, /* R914 */
{ 0x0000, 0x0000, 0x0000 }, /* R915 */
{ 0x0000, 0x0000, 0x0000 }, /* R916 */
{ 0x0000, 0x0000, 0x0000 }, /* R917 */
{ 0x0000, 0x0000, 0x0000 }, /* R918 */
{ 0x0000, 0x0000, 0x0000 }, /* R919 */
{ 0x0000, 0x0000, 0x0000 }, /* R920 */
{ 0x0000, 0x0000, 0x0000 }, /* R921 */
{ 0x0000, 0x0000, 0x0000 }, /* R922 */
{ 0x0000, 0x0000, 0x0000 }, /* R923 */
{ 0x0000, 0x0000, 0x0000 }, /* R924 */
{ 0x0000, 0x0000, 0x0000 }, /* R925 */
{ 0x0000, 0x0000, 0x0000 }, /* R926 */
{ 0x0000, 0x0000, 0x0000 }, /* R927 */
{ 0x0000, 0x0000, 0x0000 }, /* R928 */
{ 0x0000, 0x0000, 0x0000 }, /* R929 */
{ 0x0000, 0x0000, 0x0000 }, /* R930 */
{ 0x0000, 0x0000, 0x0000 }, /* R931 */
{ 0x0000, 0x0000, 0x0000 }, /* R932 */
{ 0x0000, 0x0000, 0x0000 }, /* R933 */
{ 0x0000, 0x0000, 0x0000 }, /* R934 */
{ 0x0000, 0x0000, 0x0000 }, /* R935 */
{ 0x0000, 0x0000, 0x0000 }, /* R936 */
{ 0x0000, 0x0000, 0x0000 }, /* R937 */
{ 0x0000, 0x0000, 0x0000 }, /* R938 */
{ 0x0000, 0x0000, 0x0000 }, /* R939 */
{ 0x0000, 0x0000, 0x0000 }, /* R940 */
{ 0x0000, 0x0000, 0x0000 }, /* R941 */
{ 0x0000, 0x0000, 0x0000 }, /* R942 */
{ 0x0000, 0x0000, 0x0000 }, /* R943 */
{ 0x0000, 0x0000, 0x0000 }, /* R944 */
{ 0x0000, 0x0000, 0x0000 }, /* R945 */
{ 0x0000, 0x0000, 0x0000 }, /* R946 */
{ 0x0000, 0x0000, 0x0000 }, /* R947 */
{ 0x0000, 0x0000, 0x0000 }, /* R948 */
{ 0x0000, 0x0000, 0x0000 }, /* R949 */
{ 0x0000, 0x0000, 0x0000 }, /* R950 */
{ 0x0000, 0x0000, 0x0000 }, /* R951 */
{ 0x0000, 0x0000, 0x0000 }, /* R952 */
{ 0x0000, 0x0000, 0x0000 }, /* R953 */
{ 0x0000, 0x0000, 0x0000 }, /* R954 */
{ 0x0000, 0x0000, 0x0000 }, /* R955 */
{ 0x0000, 0x0000, 0x0000 }, /* R956 */
{ 0x0000, 0x0000, 0x0000 }, /* R957 */
{ 0x0000, 0x0000, 0x0000 }, /* R958 */
{ 0x0000, 0x0000, 0x0000 }, /* R959 */
{ 0x0000, 0x0000, 0x0000 }, /* R960 */
{ 0x0000, 0x0000, 0x0000 }, /* R961 */
{ 0x0000, 0x0000, 0x0000 }, /* R962 */
{ 0x0000, 0x0000, 0x0000 }, /* R963 */
{ 0x0000, 0x0000, 0x0000 }, /* R964 */
{ 0x0000, 0x0000, 0x0000 }, /* R965 */
{ 0x0000, 0x0000, 0x0000 }, /* R966 */
{ 0x0000, 0x0000, 0x0000 }, /* R967 */
{ 0x0000, 0x0000, 0x0000 }, /* R968 */
{ 0x0000, 0x0000, 0x0000 }, /* R969 */
{ 0x0000, 0x0000, 0x0000 }, /* R970 */
{ 0x0000, 0x0000, 0x0000 }, /* R971 */
{ 0x0000, 0x0000, 0x0000 }, /* R972 */
{ 0x0000, 0x0000, 0x0000 }, /* R973 */
{ 0x0000, 0x0000, 0x0000 }, /* R974 */
{ 0x0000, 0x0000, 0x0000 }, /* R975 */
{ 0x0000, 0x0000, 0x0000 }, /* R976 */
{ 0x0000, 0x0000, 0x0000 }, /* R977 */
{ 0x0000, 0x0000, 0x0000 }, /* R978 */
{ 0x0000, 0x0000, 0x0000 }, /* R979 */
{ 0x0000, 0x0000, 0x0000 }, /* R980 */
{ 0x0000, 0x0000, 0x0000 }, /* R981 */
{ 0x0000, 0x0000, 0x0000 }, /* R982 */
{ 0x0000, 0x0000, 0x0000 }, /* R983 */
{ 0x0000, 0x0000, 0x0000 }, /* R984 */
{ 0x0000, 0x0000, 0x0000 }, /* R985 */
{ 0x0000, 0x0000, 0x0000 }, /* R986 */
{ 0x0000, 0x0000, 0x0000 }, /* R987 */
{ 0x0000, 0x0000, 0x0000 }, /* R988 */
{ 0x0000, 0x0000, 0x0000 }, /* R989 */
{ 0x0000, 0x0000, 0x0000 }, /* R990 */
{ 0x0000, 0x0000, 0x0000 }, /* R991 */
{ 0x0000, 0x0000, 0x0000 }, /* R992 */
{ 0x0000, 0x0000, 0x0000 }, /* R993 */
{ 0x0000, 0x0000, 0x0000 }, /* R994 */
{ 0x0000, 0x0000, 0x0000 }, /* R995 */
{ 0x0000, 0x0000, 0x0000 }, /* R996 */
{ 0x0000, 0x0000, 0x0000 }, /* R997 */
{ 0x0000, 0x0000, 0x0000 }, /* R998 */
{ 0x0000, 0x0000, 0x0000 }, /* R999 */
{ 0x0000, 0x0000, 0x0000 }, /* R1000 */
{ 0x0000, 0x0000, 0x0000 }, /* R1001 */
{ 0x0000, 0x0000, 0x0000 }, /* R1002 */
{ 0x0000, 0x0000, 0x0000 }, /* R1003 */
{ 0x0000, 0x0000, 0x0000 }, /* R1004 */
{ 0x0000, 0x0000, 0x0000 }, /* R1005 */
{ 0x0000, 0x0000, 0x0000 }, /* R1006 */
{ 0x0000, 0x0000, 0x0000 }, /* R1007 */
{ 0x0000, 0x0000, 0x0000 }, /* R1008 */
{ 0x0000, 0x0000, 0x0000 }, /* R1009 */
{ 0x0000, 0x0000, 0x0000 }, /* R1010 */
{ 0x0000, 0x0000, 0x0000 }, /* R1011 */
{ 0x0000, 0x0000, 0x0000 }, /* R1012 */
{ 0x0000, 0x0000, 0x0000 }, /* R1013 */
{ 0x0000, 0x0000, 0x0000 }, /* R1014 */
{ 0x0000, 0x0000, 0x0000 }, /* R1015 */
{ 0x0000, 0x0000, 0x0000 }, /* R1016 */
{ 0x0000, 0x0000, 0x0000 }, /* R1017 */
{ 0x0000, 0x0000, 0x0000 }, /* R1018 */
{ 0x0000, 0x0000, 0x0000 }, /* R1019 */
{ 0x0000, 0x0000, 0x0000 }, /* R1020 */
{ 0x0000, 0x0000, 0x0000 }, /* R1021 */
{ 0x0000, 0x0000, 0x0000 }, /* R1022 */
{ 0x0000, 0x0000, 0x0000 }, /* R1023 */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
{ 0x0000, 0x0000, 0x0000 }, /* R1032 */
{ 0x0000, 0x0000, 0x0000 }, /* R1033 */
{ 0x0000, 0x0000, 0x0000 }, /* R1034 */
{ 0x0000, 0x0000, 0x0000 }, /* R1035 */
{ 0x0000, 0x0000, 0x0000 }, /* R1036 */
{ 0x0000, 0x0000, 0x0000 }, /* R1037 */
{ 0x0000, 0x0000, 0x0000 }, /* R1038 */
{ 0x0000, 0x0000, 0x0000 }, /* R1039 */
{ 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
{ 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
{ 0x0000, 0x0000, 0x0000 }, /* R1042 */
{ 0x0000, 0x0000, 0x0000 }, /* R1043 */
{ 0x0000, 0x0000, 0x0000 }, /* R1044 */
{ 0x0000, 0x0000, 0x0000 }, /* R1045 */
{ 0x0000, 0x0000, 0x0000 }, /* R1046 */
{ 0x0000, 0x0000, 0x0000 }, /* R1047 */
{ 0x0000, 0x0000, 0x0000 }, /* R1048 */
{ 0x0000, 0x0000, 0x0000 }, /* R1049 */
{ 0x0000, 0x0000, 0x0000 }, /* R1050 */
{ 0x0000, 0x0000, 0x0000 }, /* R1051 */
{ 0x0000, 0x0000, 0x0000 }, /* R1052 */
{ 0x0000, 0x0000, 0x0000 }, /* R1053 */
{ 0x0000, 0x0000, 0x0000 }, /* R1054 */
{ 0x0000, 0x0000, 0x0000 }, /* R1055 */
{ 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
{ 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
{ 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
{ 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R1060 */
{ 0x0000, 0x0000, 0x0000 }, /* R1061 */
{ 0x0000, 0x0000, 0x0000 }, /* R1062 */
{ 0x0000, 0x0000, 0x0000 }, /* R1063 */
{ 0x0000, 0x0000, 0x0000 }, /* R1064 */
{ 0x0000, 0x0000, 0x0000 }, /* R1065 */
{ 0x0000, 0x0000, 0x0000 }, /* R1066 */
{ 0x0000, 0x0000, 0x0000 }, /* R1067 */
{ 0x0000, 0x0000, 0x0000 }, /* R1068 */
{ 0x0000, 0x0000, 0x0000 }, /* R1069 */
{ 0x0000, 0x0000, 0x0000 }, /* R1070 */
{ 0x0000, 0x0000, 0x0000 }, /* R1071 */
{ 0x0000, 0x0000, 0x0000 }, /* R1072 */
{ 0x0000, 0x0000, 0x0000 }, /* R1073 */
{ 0x0000, 0x0000, 0x0000 }, /* R1074 */
{ 0x0000, 0x0000, 0x0000 }, /* R1075 */
{ 0x0000, 0x0000, 0x0000 }, /* R1076 */
{ 0x0000, 0x0000, 0x0000 }, /* R1077 */
{ 0x0000, 0x0000, 0x0000 }, /* R1078 */
{ 0x0000, 0x0000, 0x0000 }, /* R1079 */
{ 0x0000, 0x0000, 0x0000 }, /* R1080 */
{ 0x0000, 0x0000, 0x0000 }, /* R1081 */
{ 0x0000, 0x0000, 0x0000 }, /* R1082 */
{ 0x0000, 0x0000, 0x0000 }, /* R1083 */
{ 0x0000, 0x0000, 0x0000 }, /* R1084 */
{ 0x0000, 0x0000, 0x0000 }, /* R1085 */
{ 0x0000, 0x0000, 0x0000 }, /* R1086 */
{ 0x0000, 0x0000, 0x0000 }, /* R1087 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
{ 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
{ 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
{ 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
{ 0x0000, 0x0000, 0x0000 }, /* R1093 */
{ 0x0000, 0x0000, 0x0000 }, /* R1094 */
{ 0x0000, 0x0000, 0x0000 }, /* R1095 */
{ 0x0000, 0x0000, 0x0000 }, /* R1096 */
{ 0x0000, 0x0000, 0x0000 }, /* R1097 */
{ 0x0000, 0x0000, 0x0000 }, /* R1098 */
{ 0x0000, 0x0000, 0x0000 }, /* R1099 */
{ 0x0000, 0x0000, 0x0000 }, /* R1100 */
{ 0x0000, 0x0000, 0x0000 }, /* R1101 */
{ 0x0000, 0x0000, 0x0000 }, /* R1102 */
{ 0x0000, 0x0000, 0x0000 }, /* R1103 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
{ 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
{ 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
{ 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
{ 0x0000, 0x0000, 0x0000 }, /* R1109 */
{ 0x0000, 0x0000, 0x0000 }, /* R1110 */
{ 0x0000, 0x0000, 0x0000 }, /* R1111 */
{ 0x0000, 0x0000, 0x0000 }, /* R1112 */
{ 0x0000, 0x0000, 0x0000 }, /* R1113 */
{ 0x0000, 0x0000, 0x0000 }, /* R1114 */
{ 0x0000, 0x0000, 0x0000 }, /* R1115 */
{ 0x0000, 0x0000, 0x0000 }, /* R1116 */
{ 0x0000, 0x0000, 0x0000 }, /* R1117 */
{ 0x0000, 0x0000, 0x0000 }, /* R1118 */
{ 0x0000, 0x0000, 0x0000 }, /* R1119 */
{ 0x0000, 0x0000, 0x0000 }, /* R1120 */
{ 0x0000, 0x0000, 0x0000 }, /* R1121 */
{ 0x0000, 0x0000, 0x0000 }, /* R1122 */
{ 0x0000, 0x0000, 0x0000 }, /* R1123 */
{ 0x0000, 0x0000, 0x0000 }, /* R1124 */
{ 0x0000, 0x0000, 0x0000 }, /* R1125 */
{ 0x0000, 0x0000, 0x0000 }, /* R1126 */
{ 0x0000, 0x0000, 0x0000 }, /* R1127 */
{ 0x0000, 0x0000, 0x0000 }, /* R1128 */
{ 0x0000, 0x0000, 0x0000 }, /* R1129 */
{ 0x0000, 0x0000, 0x0000 }, /* R1130 */
{ 0x0000, 0x0000, 0x0000 }, /* R1131 */
{ 0x0000, 0x0000, 0x0000 }, /* R1132 */
{ 0x0000, 0x0000, 0x0000 }, /* R1133 */
{ 0x0000, 0x0000, 0x0000 }, /* R1134 */
{ 0x0000, 0x0000, 0x0000 }, /* R1135 */
{ 0x0000, 0x0000, 0x0000 }, /* R1136 */
{ 0x0000, 0x0000, 0x0000 }, /* R1137 */
{ 0x0000, 0x0000, 0x0000 }, /* R1138 */
{ 0x0000, 0x0000, 0x0000 }, /* R1139 */
{ 0x0000, 0x0000, 0x0000 }, /* R1140 */
{ 0x0000, 0x0000, 0x0000 }, /* R1141 */
{ 0x0000, 0x0000, 0x0000 }, /* R1142 */
{ 0x0000, 0x0000, 0x0000 }, /* R1143 */
{ 0x0000, 0x0000, 0x0000 }, /* R1144 */
{ 0x0000, 0x0000, 0x0000 }, /* R1145 */
{ 0x0000, 0x0000, 0x0000 }, /* R1146 */
{ 0x0000, 0x0000, 0x0000 }, /* R1147 */
{ 0x0000, 0x0000, 0x0000 }, /* R1148 */
{ 0x0000, 0x0000, 0x0000 }, /* R1149 */
{ 0x0000, 0x0000, 0x0000 }, /* R1150 */
{ 0x0000, 0x0000, 0x0000 }, /* R1151 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
{ 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
{ 0x0000, 0x0000, 0x0000 }, /* R1172 */
{ 0x0000, 0x0000, 0x0000 }, /* R1173 */
{ 0x0000, 0x0000, 0x0000 }, /* R1174 */
{ 0x0000, 0x0000, 0x0000 }, /* R1175 */
{ 0x0000, 0x0000, 0x0000 }, /* R1176 */
{ 0x0000, 0x0000, 0x0000 }, /* R1177 */
{ 0x0000, 0x0000, 0x0000 }, /* R1178 */
{ 0x0000, 0x0000, 0x0000 }, /* R1179 */
{ 0x0000, 0x0000, 0x0000 }, /* R1180 */
{ 0x0000, 0x0000, 0x0000 }, /* R1181 */
{ 0x0000, 0x0000, 0x0000 }, /* R1182 */
{ 0x0000, 0x0000, 0x0000 }, /* R1183 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
{ 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
{ 0x0000, 0x0000, 0x0000 }, /* R1204 */
{ 0x0000, 0x0000, 0x0000 }, /* R1205 */
{ 0x0000, 0x0000, 0x0000 }, /* R1206 */
{ 0x0000, 0x0000, 0x0000 }, /* R1207 */
{ 0x0000, 0x0000, 0x0000 }, /* R1208 */
{ 0x0000, 0x0000, 0x0000 }, /* R1209 */
{ 0x0000, 0x0000, 0x0000 }, /* R1210 */
{ 0x0000, 0x0000, 0x0000 }, /* R1211 */
{ 0x0000, 0x0000, 0x0000 }, /* R1212 */
{ 0x0000, 0x0000, 0x0000 }, /* R1213 */
{ 0x0000, 0x0000, 0x0000 }, /* R1214 */
{ 0x0000, 0x0000, 0x0000 }, /* R1215 */
{ 0x0000, 0x0000, 0x0000 }, /* R1216 */
{ 0x0000, 0x0000, 0x0000 }, /* R1217 */
{ 0x0000, 0x0000, 0x0000 }, /* R1218 */
{ 0x0000, 0x0000, 0x0000 }, /* R1219 */
{ 0x0000, 0x0000, 0x0000 }, /* R1220 */
{ 0x0000, 0x0000, 0x0000 }, /* R1221 */
{ 0x0000, 0x0000, 0x0000 }, /* R1222 */
{ 0x0000, 0x0000, 0x0000 }, /* R1223 */
{ 0x0000, 0x0000, 0x0000 }, /* R1224 */
{ 0x0000, 0x0000, 0x0000 }, /* R1225 */
{ 0x0000, 0x0000, 0x0000 }, /* R1226 */
{ 0x0000, 0x0000, 0x0000 }, /* R1227 */
{ 0x0000, 0x0000, 0x0000 }, /* R1228 */
{ 0x0000, 0x0000, 0x0000 }, /* R1229 */
{ 0x0000, 0x0000, 0x0000 }, /* R1230 */
{ 0x0000, 0x0000, 0x0000 }, /* R1231 */
{ 0x0000, 0x0000, 0x0000 }, /* R1232 */
{ 0x0000, 0x0000, 0x0000 }, /* R1233 */
{ 0x0000, 0x0000, 0x0000 }, /* R1234 */
{ 0x0000, 0x0000, 0x0000 }, /* R1235 */
{ 0x0000, 0x0000, 0x0000 }, /* R1236 */
{ 0x0000, 0x0000, 0x0000 }, /* R1237 */
{ 0x0000, 0x0000, 0x0000 }, /* R1238 */
{ 0x0000, 0x0000, 0x0000 }, /* R1239 */
{ 0x0000, 0x0000, 0x0000 }, /* R1240 */
{ 0x0000, 0x0000, 0x0000 }, /* R1241 */
{ 0x0000, 0x0000, 0x0000 }, /* R1242 */
{ 0x0000, 0x0000, 0x0000 }, /* R1243 */
{ 0x0000, 0x0000, 0x0000 }, /* R1244 */
{ 0x0000, 0x0000, 0x0000 }, /* R1245 */
{ 0x0000, 0x0000, 0x0000 }, /* R1246 */
{ 0x0000, 0x0000, 0x0000 }, /* R1247 */
{ 0x0000, 0x0000, 0x0000 }, /* R1248 */
{ 0x0000, 0x0000, 0x0000 }, /* R1249 */
{ 0x0000, 0x0000, 0x0000 }, /* R1250 */
{ 0x0000, 0x0000, 0x0000 }, /* R1251 */
{ 0x0000, 0x0000, 0x0000 }, /* R1252 */
{ 0x0000, 0x0000, 0x0000 }, /* R1253 */
{ 0x0000, 0x0000, 0x0000 }, /* R1254 */
{ 0x0000, 0x0000, 0x0000 }, /* R1255 */
{ 0x0000, 0x0000, 0x0000 }, /* R1256 */
{ 0x0000, 0x0000, 0x0000 }, /* R1257 */
{ 0x0000, 0x0000, 0x0000 }, /* R1258 */
{ 0x0000, 0x0000, 0x0000 }, /* R1259 */
{ 0x0000, 0x0000, 0x0000 }, /* R1260 */
{ 0x0000, 0x0000, 0x0000 }, /* R1261 */
{ 0x0000, 0x0000, 0x0000 }, /* R1262 */
{ 0x0000, 0x0000, 0x0000 }, /* R1263 */
{ 0x0000, 0x0000, 0x0000 }, /* R1264 */
{ 0x0000, 0x0000, 0x0000 }, /* R1265 */
{ 0x0000, 0x0000, 0x0000 }, /* R1266 */
{ 0x0000, 0x0000, 0x0000 }, /* R1267 */
{ 0x0000, 0x0000, 0x0000 }, /* R1268 */
{ 0x0000, 0x0000, 0x0000 }, /* R1269 */
{ 0x0000, 0x0000, 0x0000 }, /* R1270 */
{ 0x0000, 0x0000, 0x0000 }, /* R1271 */
{ 0x0000, 0x0000, 0x0000 }, /* R1272 */
{ 0x0000, 0x0000, 0x0000 }, /* R1273 */
{ 0x0000, 0x0000, 0x0000 }, /* R1274 */
{ 0x0000, 0x0000, 0x0000 }, /* R1275 */
{ 0x0000, 0x0000, 0x0000 }, /* R1276 */
{ 0x0000, 0x0000, 0x0000 }, /* R1277 */
{ 0x0000, 0x0000, 0x0000 }, /* R1278 */
{ 0x0000, 0x0000, 0x0000 }, /* R1279 */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
{ 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
{ 0x0000, 0x0000, 0x0000 }, /* R1284 */
{ 0x0000, 0x0000, 0x0000 }, /* R1285 */
{ 0x0000, 0x0000, 0x0000 }, /* R1286 */
{ 0x0000, 0x0000, 0x0000 }, /* R1287 */
{ 0x0000, 0x0000, 0x0000 }, /* R1288 */
{ 0x0000, 0x0000, 0x0000 }, /* R1289 */
{ 0x0000, 0x0000, 0x0000 }, /* R1290 */
{ 0x0000, 0x0000, 0x0000 }, /* R1291 */
{ 0x0000, 0x0000, 0x0000 }, /* R1292 */
{ 0x0000, 0x0000, 0x0000 }, /* R1293 */
{ 0x0000, 0x0000, 0x0000 }, /* R1294 */
{ 0x0000, 0x0000, 0x0000 }, /* R1295 */
{ 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
{ 0x0000, 0x0000, 0x0000 }, /* R1297 */
{ 0x0000, 0x0000, 0x0000 }, /* R1298 */
{ 0x0000, 0x0000, 0x0000 }, /* R1299 */
{ 0x0000, 0x0000, 0x0000 }, /* R1300 */
{ 0x0000, 0x0000, 0x0000 }, /* R1301 */
{ 0x0000, 0x0000, 0x0000 }, /* R1302 */
{ 0x0000, 0x0000, 0x0000 }, /* R1303 */
{ 0x0000, 0x0000, 0x0000 }, /* R1304 */
{ 0x0000, 0x0000, 0x0000 }, /* R1305 */
{ 0x0000, 0x0000, 0x0000 }, /* R1306 */
{ 0x0000, 0x0000, 0x0000 }, /* R1307 */
{ 0x0000, 0x0000, 0x0000 }, /* R1308 */
{ 0x0000, 0x0000, 0x0000 }, /* R1309 */
{ 0x0000, 0x0000, 0x0000 }, /* R1310 */
{ 0x0000, 0x0000, 0x0000 }, /* R1311 */
{ 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
{ 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
{ 0x0000, 0x0000, 0x0000 }, /* R1314 */
{ 0x0000, 0x0000, 0x0000 }, /* R1315 */
{ 0x0000, 0x0000, 0x0000 }, /* R1316 */
{ 0x0000, 0x0000, 0x0000 }, /* R1317 */
{ 0x0000, 0x0000, 0x0000 }, /* R1318 */
{ 0x0000, 0x0000, 0x0000 }, /* R1319 */
{ 0x0000, 0x0000, 0x0000 }, /* R1320 */
{ 0x0000, 0x0000, 0x0000 }, /* R1321 */
{ 0x0000, 0x0000, 0x0000 }, /* R1322 */
{ 0x0000, 0x0000, 0x0000 }, /* R1323 */
{ 0x0000, 0x0000, 0x0000 }, /* R1324 */
{ 0x0000, 0x0000, 0x0000 }, /* R1325 */
{ 0x0000, 0x0000, 0x0000 }, /* R1326 */
{ 0x0000, 0x0000, 0x0000 }, /* R1327 */
{ 0x0000, 0x0000, 0x0000 }, /* R1328 */
{ 0x0000, 0x0000, 0x0000 }, /* R1329 */
{ 0x0000, 0x0000, 0x0000 }, /* R1330 */
{ 0x0000, 0x0000, 0x0000 }, /* R1331 */
{ 0x0000, 0x0000, 0x0000 }, /* R1332 */
{ 0x0000, 0x0000, 0x0000 }, /* R1333 */
{ 0x0000, 0x0000, 0x0000 }, /* R1334 */
{ 0x0000, 0x0000, 0x0000 }, /* R1335 */
{ 0x0000, 0x0000, 0x0000 }, /* R1336 */
{ 0x0000, 0x0000, 0x0000 }, /* R1337 */
{ 0x0000, 0x0000, 0x0000 }, /* R1338 */
{ 0x0000, 0x0000, 0x0000 }, /* R1339 */
{ 0x0000, 0x0000, 0x0000 }, /* R1340 */
{ 0x0000, 0x0000, 0x0000 }, /* R1341 */
{ 0x0000, 0x0000, 0x0000 }, /* R1342 */
{ 0x0000, 0x0000, 0x0000 }, /* R1343 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
{ 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
{ 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
{ 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
{ 0x0000, 0x0000, 0x0000 }, /* R1349 */
{ 0x0000, 0x0000, 0x0000 }, /* R1350 */
{ 0x0000, 0x0000, 0x0000 }, /* R1351 */
{ 0x0000, 0x0000, 0x0000 }, /* R1352 */
{ 0x0000, 0x0000, 0x0000 }, /* R1353 */
{ 0x0000, 0x0000, 0x0000 }, /* R1354 */
{ 0x0000, 0x0000, 0x0000 }, /* R1355 */
{ 0x0000, 0x0000, 0x0000 }, /* R1356 */
{ 0x0000, 0x0000, 0x0000 }, /* R1357 */
{ 0x0000, 0x0000, 0x0000 }, /* R1358 */
{ 0x0000, 0x0000, 0x0000 }, /* R1359 */
{ 0x0000, 0x0000, 0x0000 }, /* R1360 */
{ 0x0000, 0x0000, 0x0000 }, /* R1361 */
{ 0x0000, 0x0000, 0x0000 }, /* R1362 */
{ 0x0000, 0x0000, 0x0000 }, /* R1363 */
{ 0x0000, 0x0000, 0x0000 }, /* R1364 */
{ 0x0000, 0x0000, 0x0000 }, /* R1365 */
{ 0x0000, 0x0000, 0x0000 }, /* R1366 */
{ 0x0000, 0x0000, 0x0000 }, /* R1367 */
{ 0x0000, 0x0000, 0x0000 }, /* R1368 */
{ 0x0000, 0x0000, 0x0000 }, /* R1369 */
{ 0x0000, 0x0000, 0x0000 }, /* R1370 */
{ 0x0000, 0x0000, 0x0000 }, /* R1371 */
{ 0x0000, 0x0000, 0x0000 }, /* R1372 */
{ 0x0000, 0x0000, 0x0000 }, /* R1373 */
{ 0x0000, 0x0000, 0x0000 }, /* R1374 */
{ 0x0000, 0x0000, 0x0000 }, /* R1375 */
{ 0x0000, 0x0000, 0x0000 }, /* R1376 */
{ 0x0000, 0x0000, 0x0000 }, /* R1377 */
{ 0x0000, 0x0000, 0x0000 }, /* R1378 */
{ 0x0000, 0x0000, 0x0000 }, /* R1379 */
{ 0x0000, 0x0000, 0x0000 }, /* R1380 */
{ 0x0000, 0x0000, 0x0000 }, /* R1381 */
{ 0x0000, 0x0000, 0x0000 }, /* R1382 */
{ 0x0000, 0x0000, 0x0000 }, /* R1383 */
{ 0x0000, 0x0000, 0x0000 }, /* R1384 */
{ 0x0000, 0x0000, 0x0000 }, /* R1385 */
{ 0x0000, 0x0000, 0x0000 }, /* R1386 */
{ 0x0000, 0x0000, 0x0000 }, /* R1387 */
{ 0x0000, 0x0000, 0x0000 }, /* R1388 */
{ 0x0000, 0x0000, 0x0000 }, /* R1389 */
{ 0x0000, 0x0000, 0x0000 }, /* R1390 */
{ 0x0000, 0x0000, 0x0000 }, /* R1391 */
{ 0x0000, 0x0000, 0x0000 }, /* R1392 */
{ 0x0000, 0x0000, 0x0000 }, /* R1393 */
{ 0x0000, 0x0000, 0x0000 }, /* R1394 */
{ 0x0000, 0x0000, 0x0000 }, /* R1395 */
{ 0x0000, 0x0000, 0x0000 }, /* R1396 */
{ 0x0000, 0x0000, 0x0000 }, /* R1397 */
{ 0x0000, 0x0000, 0x0000 }, /* R1398 */
{ 0x0000, 0x0000, 0x0000 }, /* R1399 */
{ 0x0000, 0x0000, 0x0000 }, /* R1400 */
{ 0x0000, 0x0000, 0x0000 }, /* R1401 */
{ 0x0000, 0x0000, 0x0000 }, /* R1402 */
{ 0x0000, 0x0000, 0x0000 }, /* R1403 */
{ 0x0000, 0x0000, 0x0000 }, /* R1404 */
{ 0x0000, 0x0000, 0x0000 }, /* R1405 */
{ 0x0000, 0x0000, 0x0000 }, /* R1406 */
{ 0x0000, 0x0000, 0x0000 }, /* R1407 */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
{ 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
{ 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
{ 0x0000, 0x0000, 0x0000 }, /* R1428 */
{ 0x0000, 0x0000, 0x0000 }, /* R1429 */
{ 0x0000, 0x0000, 0x0000 }, /* R1430 */
{ 0x0000, 0x0000, 0x0000 }, /* R1431 */
{ 0x0000, 0x0000, 0x0000 }, /* R1432 */
{ 0x0000, 0x0000, 0x0000 }, /* R1433 */
{ 0x0000, 0x0000, 0x0000 }, /* R1434 */
{ 0x0000, 0x0000, 0x0000 }, /* R1435 */
{ 0x0000, 0x0000, 0x0000 }, /* R1436 */
{ 0x0000, 0x0000, 0x0000 }, /* R1437 */
{ 0x0000, 0x0000, 0x0000 }, /* R1438 */
{ 0x0000, 0x0000, 0x0000 }, /* R1439 */
{ 0x0000, 0x0000, 0x0000 }, /* R1440 */
{ 0x0000, 0x0000, 0x0000 }, /* R1441 */
{ 0x0000, 0x0000, 0x0000 }, /* R1442 */
{ 0x0000, 0x0000, 0x0000 }, /* R1443 */
{ 0x0000, 0x0000, 0x0000 }, /* R1444 */
{ 0x0000, 0x0000, 0x0000 }, /* R1445 */
{ 0x0000, 0x0000, 0x0000 }, /* R1446 */
{ 0x0000, 0x0000, 0x0000 }, /* R1447 */
{ 0x0000, 0x0000, 0x0000 }, /* R1448 */
{ 0x0000, 0x0000, 0x0000 }, /* R1449 */
{ 0x0000, 0x0000, 0x0000 }, /* R1450 */
{ 0x0000, 0x0000, 0x0000 }, /* R1451 */
{ 0x0000, 0x0000, 0x0000 }, /* R1452 */
{ 0x0000, 0x0000, 0x0000 }, /* R1453 */
{ 0x0000, 0x0000, 0x0000 }, /* R1454 */
{ 0x0000, 0x0000, 0x0000 }, /* R1455 */
{ 0x0000, 0x0000, 0x0000 }, /* R1456 */
{ 0x0000, 0x0000, 0x0000 }, /* R1457 */
{ 0x0000, 0x0000, 0x0000 }, /* R1458 */
{ 0x0000, 0x0000, 0x0000 }, /* R1459 */
{ 0x0000, 0x0000, 0x0000 }, /* R1460 */
{ 0x0000, 0x0000, 0x0000 }, /* R1461 */
{ 0x0000, 0x0000, 0x0000 }, /* R1462 */
{ 0x0000, 0x0000, 0x0000 }, /* R1463 */
{ 0x0000, 0x0000, 0x0000 }, /* R1464 */
{ 0x0000, 0x0000, 0x0000 }, /* R1465 */
{ 0x0000, 0x0000, 0x0000 }, /* R1466 */
{ 0x0000, 0x0000, 0x0000 }, /* R1467 */
{ 0x0000, 0x0000, 0x0000 }, /* R1468 */
{ 0x0000, 0x0000, 0x0000 }, /* R1469 */
{ 0x0000, 0x0000, 0x0000 }, /* R1470 */
{ 0x0000, 0x0000, 0x0000 }, /* R1471 */
{ 0x0000, 0x0000, 0x0000 }, /* R1472 */
{ 0x0000, 0x0000, 0x0000 }, /* R1473 */
{ 0x0000, 0x0000, 0x0000 }, /* R1474 */
{ 0x0000, 0x0000, 0x0000 }, /* R1475 */
{ 0x0000, 0x0000, 0x0000 }, /* R1476 */
{ 0x0000, 0x0000, 0x0000 }, /* R1477 */
{ 0x0000, 0x0000, 0x0000 }, /* R1478 */
{ 0x0000, 0x0000, 0x0000 }, /* R1479 */
{ 0x0000, 0x0000, 0x0000 }, /* R1480 */
{ 0x0000, 0x0000, 0x0000 }, /* R1481 */
{ 0x0000, 0x0000, 0x0000 }, /* R1482 */
{ 0x0000, 0x0000, 0x0000 }, /* R1483 */
{ 0x0000, 0x0000, 0x0000 }, /* R1484 */
{ 0x0000, 0x0000, 0x0000 }, /* R1485 */
{ 0x0000, 0x0000, 0x0000 }, /* R1486 */
{ 0x0000, 0x0000, 0x0000 }, /* R1487 */
{ 0x0000, 0x0000, 0x0000 }, /* R1488 */
{ 0x0000, 0x0000, 0x0000 }, /* R1489 */
{ 0x0000, 0x0000, 0x0000 }, /* R1490 */
{ 0x0000, 0x0000, 0x0000 }, /* R1491 */
{ 0x0000, 0x0000, 0x0000 }, /* R1492 */
{ 0x0000, 0x0000, 0x0000 }, /* R1493 */
{ 0x0000, 0x0000, 0x0000 }, /* R1494 */
{ 0x0000, 0x0000, 0x0000 }, /* R1495 */
{ 0x0000, 0x0000, 0x0000 }, /* R1496 */
{ 0x0000, 0x0000, 0x0000 }, /* R1497 */
{ 0x0000, 0x0000, 0x0000 }, /* R1498 */
{ 0x0000, 0x0000, 0x0000 }, /* R1499 */
{ 0x0000, 0x0000, 0x0000 }, /* R1500 */
{ 0x0000, 0x0000, 0x0000 }, /* R1501 */
{ 0x0000, 0x0000, 0x0000 }, /* R1502 */
{ 0x0000, 0x0000, 0x0000 }, /* R1503 */
{ 0x0000, 0x0000, 0x0000 }, /* R1504 */
{ 0x0000, 0x0000, 0x0000 }, /* R1505 */
{ 0x0000, 0x0000, 0x0000 }, /* R1506 */
{ 0x0000, 0x0000, 0x0000 }, /* R1507 */
{ 0x0000, 0x0000, 0x0000 }, /* R1508 */
{ 0x0000, 0x0000, 0x0000 }, /* R1509 */
{ 0x0000, 0x0000, 0x0000 }, /* R1510 */
{ 0x0000, 0x0000, 0x0000 }, /* R1511 */
{ 0x0000, 0x0000, 0x0000 }, /* R1512 */
{ 0x0000, 0x0000, 0x0000 }, /* R1513 */
{ 0x0000, 0x0000, 0x0000 }, /* R1514 */
{ 0x0000, 0x0000, 0x0000 }, /* R1515 */
{ 0x0000, 0x0000, 0x0000 }, /* R1516 */
{ 0x0000, 0x0000, 0x0000 }, /* R1517 */
{ 0x0000, 0x0000, 0x0000 }, /* R1518 */
{ 0x0000, 0x0000, 0x0000 }, /* R1519 */
{ 0x0000, 0x0000, 0x0000 }, /* R1520 */
{ 0x0000, 0x0000, 0x0000 }, /* R1521 */
{ 0x0000, 0x0000, 0x0000 }, /* R1522 */
{ 0x0000, 0x0000, 0x0000 }, /* R1523 */
{ 0x0000, 0x0000, 0x0000 }, /* R1524 */
{ 0x0000, 0x0000, 0x0000 }, /* R1525 */
{ 0x0000, 0x0000, 0x0000 }, /* R1526 */
{ 0x0000, 0x0000, 0x0000 }, /* R1527 */
{ 0x0000, 0x0000, 0x0000 }, /* R1528 */
{ 0x0000, 0x0000, 0x0000 }, /* R1529 */
{ 0x0000, 0x0000, 0x0000 }, /* R1530 */
{ 0x0000, 0x0000, 0x0000 }, /* R1531 */
{ 0x0000, 0x0000, 0x0000 }, /* R1532 */
{ 0x0000, 0x0000, 0x0000 }, /* R1533 */
{ 0x0000, 0x0000, 0x0000 }, /* R1534 */
{ 0x0000, 0x0000, 0x0000 }, /* R1535 */
{ 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
{ 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
{ 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
{ 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
{ 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
{ 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
{ 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
{ 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
{ 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
{ 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
{ 0x0000, 0x0000, 0x0000 }, /* R1546 */
{ 0x0000, 0x0000, 0x0000 }, /* R1547 */
{ 0x0000, 0x0000, 0x0000 }, /* R1548 */
{ 0x0000, 0x0000, 0x0000 }, /* R1549 */
{ 0x0000, 0x0000, 0x0000 }, /* R1550 */
{ 0x0000, 0x0000, 0x0000 }, /* R1551 */
{ 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
{ 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
{ 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
{ 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
{ 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
{ 0x0000, 0x0000, 0x0000 }, /* R1557 */
{ 0x0000, 0x0000, 0x0000 }, /* R1558 */
{ 0x0000, 0x0000, 0x0000 }, /* R1559 */
{ 0x0000, 0x0000, 0x0000 }, /* R1560 */
{ 0x0000, 0x0000, 0x0000 }, /* R1561 */
{ 0x0000, 0x0000, 0x0000 }, /* R1562 */
{ 0x0000, 0x0000, 0x0000 }, /* R1563 */
{ 0x0000, 0x0000, 0x0000 }, /* R1564 */
{ 0x0000, 0x0000, 0x0000 }, /* R1565 */
{ 0x0000, 0x0000, 0x0000 }, /* R1566 */
{ 0x0000, 0x0000, 0x0000 }, /* R1567 */
{ 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
{ 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
};
static int wm8994_readable(unsigned int reg)
{
switch (reg) {
case WM8994_GPIO_1:
case WM8994_GPIO_2:
case WM8994_GPIO_3:
case WM8994_GPIO_4:
case WM8994_GPIO_5:
case WM8994_GPIO_6:
case WM8994_GPIO_7:
case WM8994_GPIO_8:
case WM8994_GPIO_9:
case WM8994_GPIO_10:
case WM8994_GPIO_11:
case WM8994_INTERRUPT_STATUS_1:
case WM8994_INTERRUPT_STATUS_2:
case WM8994_INTERRUPT_RAW_STATUS_2:
return 1;
default:
break;
}
if (reg >= ARRAY_SIZE(access_masks))
return 0;
return access_masks[reg].readable != 0;
}
static int wm8994_volatile(unsigned int reg)
{
if (reg >= WM8994_REG_CACHE_SIZE)
return 1;
switch (reg) {
case WM8994_SOFTWARE_RESET:
case WM8994_CHIP_REVISION:
case WM8994_DC_SERVO_1:
case WM8994_DC_SERVO_READBACK:
case WM8994_RATE_STATUS:
case WM8994_LDO_1:
case WM8994_LDO_2:
return 1;
default:
return 0;
}
}
static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
BUG_ON(reg > WM8994_MAX_REGISTER);
if (!wm8994_volatile(reg))
wm8994->reg_cache[reg] = value;
dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
return wm8994_reg_write(codec->control_data, reg, value);
}
static unsigned int wm8994_read(struct snd_soc_codec *codec,
unsigned int reg)
{
u16 *reg_cache = codec->reg_cache;
BUG_ON(reg > WM8994_MAX_REGISTER);
if (wm8994_volatile(reg))
return wm8994_reg_read(codec->control_data, reg);
else
return reg_cache[reg];
}
static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int rate;
int reg1 = 0;
int offset;
if (aif)
offset = 4;
else
offset = 0;
switch (wm8994->sysclk[aif]) {
case WM8994_SYSCLK_MCLK1:
rate = wm8994->mclk[0];
break;
case WM8994_SYSCLK_MCLK2:
reg1 |= 0x8;
rate = wm8994->mclk[1];
break;
case WM8994_SYSCLK_FLL1:
reg1 |= 0x10;
rate = wm8994->fll[0].out;
break;
case WM8994_SYSCLK_FLL2:
reg1 |= 0x18;
rate = wm8994->fll[1].out;
break;
default:
return -EINVAL;
}
if (rate >= 13500000) {
rate /= 2;
reg1 |= WM8994_AIF1CLK_DIV;
dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
aif + 1, rate);
}
if (rate && rate < 3000000)
dev_warn(codec->dev, "AIF%dCLK is %dHz, should be >=3MHz for optimal performance\n",
aif + 1, rate);
wm8994->aifclk[aif] = rate;
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
reg1);
return 0;
}
static int configure_clock(struct snd_soc_codec *codec)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int old, new;
/* Bring up the AIF clocks first */
configure_aif_clock(codec, 0);
configure_aif_clock(codec, 1);
/* Then switch CLK_SYS over to the higher of them; a change
* can only happen as a result of a clocking change which can
* only be made outside of DAPM so we can safely redo the
* clocking.
*/
/* If they're equal it doesn't matter which is used */
if (wm8994->aifclk[0] == wm8994->aifclk[1])
return 0;
if (wm8994->aifclk[0] < wm8994->aifclk[1])
new = WM8994_SYSCLK_SRC;
else
new = 0;
old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
/* If there's no change then we're done. */
if (old == new)
return 0;
snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
snd_soc_dapm_sync(codec);
return 0;
}
static int check_clk_sys(struct snd_soc_dapm_widget *source,
struct snd_soc_dapm_widget *sink)
{
int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
const char *clk;
/* Check what we're currently using for CLK_SYS */
if (reg & WM8994_SYSCLK_SRC)
clk = "AIF2CLK";
else
clk = "AIF1CLK";
return strcmp(source->name, clk) == 0;
}
static const char *sidetone_hpf_text[] = {
"2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
};
static const struct soc_enum sidetone_hpf =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
#define WM8994_DRC_SWITCH(xname, reg, shift) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
.put = wm8994_put_drc_sw, \
.private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct soc_mixer_control *mc =
(struct soc_mixer_control *)kcontrol->private_value;
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
int mask, ret;
/* Can't enable both ADC and DAC paths simultaneously */
if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
WM8994_AIF1ADC1R_DRC_ENA_MASK;
else
mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
ret = snd_soc_read(codec, mc->reg);
if (ret < 0)
return ret;
if (ret & mask)
return -EINVAL;
return snd_soc_put_volsw(kcontrol, ucontrol);
}
static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_pdata *pdata = wm8994->pdata;
int base = wm8994_drc_base[drc];
int cfg = wm8994->drc_cfg[drc];
int save, i;
/* Save any enables; the configuration should clear them. */
save = snd_soc_read(codec, base);
save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
WM8994_AIF1ADC1R_DRC_ENA;
for (i = 0; i < WM8994_DRC_REGS; i++)
snd_soc_update_bits(codec, base + i, 0xffff,
pdata->drc_cfgs[cfg].regs[i]);
snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
WM8994_AIF1ADC1L_DRC_ENA |
WM8994_AIF1ADC1R_DRC_ENA, save);
}
/* Icky as hell but saves code duplication */
static int wm8994_get_drc(const char *name)
{
if (strcmp(name, "AIF1DRC1 Mode") == 0)
return 0;
if (strcmp(name, "AIF1DRC2 Mode") == 0)
return 1;
if (strcmp(name, "AIF2DRC Mode") == 0)
return 2;
return -EINVAL;
}
static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_pdata *pdata = wm8994->pdata;
int drc = wm8994_get_drc(kcontrol->id.name);
int value = ucontrol->value.integer.value[0];
if (drc < 0)
return drc;
if (value >= pdata->num_drc_cfgs)
return -EINVAL;
wm8994->drc_cfg[drc] = value;
wm8994_set_drc(codec, drc);
return 0;
}
static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int drc = wm8994_get_drc(kcontrol->id.name);
ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
return 0;
}
static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_pdata *pdata = wm8994->pdata;
int base = wm8994_retune_mobile_base[block];
int iface, best, best_val, save, i, cfg;
if (!pdata || !wm8994->num_retune_mobile_texts)
return;
switch (block) {
case 0:
case 1:
iface = 0;
break;
case 2:
iface = 1;
break;
default:
return;
}
/* Find the version of the currently selected configuration
* with the nearest sample rate. */
cfg = wm8994->retune_mobile_cfg[block];
best = 0;
best_val = INT_MAX;
for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
if (strcmp(pdata->retune_mobile_cfgs[i].name,
wm8994->retune_mobile_texts[cfg]) == 0 &&
abs(pdata->retune_mobile_cfgs[i].rate
- wm8994->dac_rates[iface]) < best_val) {
best = i;
best_val = abs(pdata->retune_mobile_cfgs[i].rate
- wm8994->dac_rates[iface]);
}
}
dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
block,
pdata->retune_mobile_cfgs[best].name,
pdata->retune_mobile_cfgs[best].rate,
wm8994->dac_rates[iface]);
/* The EQ will be disabled while reconfiguring it, remember the
* current configuration.
*/
save = snd_soc_read(codec, base);
save &= WM8994_AIF1DAC1_EQ_ENA;
for (i = 0; i < WM8994_EQ_REGS; i++)
snd_soc_update_bits(codec, base + i, 0xffff,
pdata->retune_mobile_cfgs[best].regs[i]);
snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
}
/* Icky as hell but saves code duplication */
static int wm8994_get_retune_mobile_block(const char *name)
{
if (strcmp(name, "AIF1.1 EQ Mode") == 0)
return 0;
if (strcmp(name, "AIF1.2 EQ Mode") == 0)
return 1;
if (strcmp(name, "AIF2 EQ Mode") == 0)
return 2;
return -EINVAL;
}
static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_pdata *pdata = wm8994->pdata;
int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
int value = ucontrol->value.integer.value[0];
if (block < 0)
return block;
if (value >= pdata->num_retune_mobile_cfgs)
return -EINVAL;
wm8994->retune_mobile_cfg[block] = value;
wm8994_set_retune_mobile(codec, block);
return 0;
}
static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
return 0;
}
static const struct snd_kcontrol_new wm8994_snd_controls[] = {
SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
WM8994_AIF1_ADC1_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
WM8994_AIF1_ADC2_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
WM8994_AIF2_ADC_RIGHT_VOLUME,
1, 119, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
5, 12, 0, st_tlv),
SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
0, 12, 0, st_tlv),
SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
5, 12, 0, st_tlv),
SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
0, 12, 0, st_tlv),
SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
6, 1, 1, wm_hubs_spkmix_tlv),
SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
2, 1, 1, wm_hubs_spkmix_tlv),
SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
6, 1, 1, wm_hubs_spkmix_tlv),
SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2, 1, 1, wm_hubs_spkmix_tlv),
SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
10, 15, 0, wm8994_3d_tlv),
SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
8, 1, 0),
SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
10, 15, 0, wm8994_3d_tlv),
SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
8, 1, 0),
SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
10, 15, 0, wm8994_3d_tlv),
SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
8, 1, 0),
};
static const struct snd_kcontrol_new wm8994_eq_controls[] = {
SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
eq_tlv),
SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
eq_tlv),
};
static int clk_sys_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
return configure_clock(codec);
case SND_SOC_DAPM_POST_PMD:
configure_clock(codec);
break;
}
return 0;
}
static void wm8994_update_class_w(struct snd_soc_codec *codec)
{
int enable = 1;
int source = 0; /* GCC flow analysis can't track enable */
int reg, reg_r;
/* Only support direct DAC->headphone paths */
reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
dev_vdbg(codec->dev, "HPL connected to output mixer\n");
enable = 0;
}
reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
dev_vdbg(codec->dev, "HPR connected to output mixer\n");
enable = 0;
}
/* We also need the same setting for L/R and only one path */
reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
switch (reg) {
case WM8994_AIF2DACL_TO_DAC1L:
dev_vdbg(codec->dev, "Class W source AIF2DAC\n");
source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
break;
case WM8994_AIF1DAC2L_TO_DAC1L:
dev_vdbg(codec->dev, "Class W source AIF1DAC2\n");
source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
break;
case WM8994_AIF1DAC1L_TO_DAC1L:
dev_vdbg(codec->dev, "Class W source AIF1DAC1\n");
source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
break;
default:
dev_vdbg(codec->dev, "DAC mixer setting: %x\n", reg);
enable = 0;
break;
}
reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
if (reg_r != reg) {
dev_vdbg(codec->dev, "Left and right DAC mixers different\n");
enable = 0;
}
if (enable) {
dev_dbg(codec->dev, "Class W enabled\n");
snd_soc_update_bits(codec, WM8994_CLASS_W_1,
WM8994_CP_DYN_PWR |
WM8994_CP_DYN_SRC_SEL_MASK,
source | WM8994_CP_DYN_PWR);
} else {
dev_dbg(codec->dev, "Class W disabled\n");
snd_soc_update_bits(codec, WM8994_CLASS_W_1,
WM8994_CP_DYN_PWR, 0);
}
}
static const char *hp_mux_text[] = {
"Mixer",
"DAC",
};
#define WM8994_HP_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_enum_double, \
.get = snd_soc_dapm_get_enum_double, \
.put = wm8994_put_hp_enum, \
.private_value = (unsigned long)&xenum }
static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
struct snd_soc_codec *codec = w->codec;
int ret;
ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
wm8994_update_class_w(codec);
return ret;
}
static const struct soc_enum hpl_enum =
SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
static const struct snd_kcontrol_new hpl_mux =
WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
static const struct soc_enum hpr_enum =
SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
static const struct snd_kcontrol_new hpr_mux =
WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
static const char *adc_mux_text[] = {
"ADC",
"DMIC",
};
static const struct soc_enum adc_enum =
SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
static const struct snd_kcontrol_new adcl_mux =
SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
static const struct snd_kcontrol_new adcr_mux =
SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
static const struct snd_kcontrol_new left_speaker_mixer[] = {
SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
};
static const struct snd_kcontrol_new right_speaker_mixer[] = {
SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
};
/* Debugging; dump chip status after DAPM transitions */
static int post_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
dev_dbg(codec->dev, "SRC status: %x\n",
snd_soc_read(codec,
WM8994_RATE_STATUS));
return 0;
}
static const struct snd_kcontrol_new aif1adc1l_mix[] = {
SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
1, 1, 0),
SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
0, 1, 0),
};
static const struct snd_kcontrol_new aif1adc1r_mix[] = {
SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
1, 1, 0),
SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
0, 1, 0),
};
static const struct snd_kcontrol_new aif1adc2l_mix[] = {
SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
1, 1, 0),
SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING,
0, 1, 0),
};
static const struct snd_kcontrol_new aif1adc2r_mix[] = {
SOC_DAPM_SINGLE("DMIC Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
1, 1, 0),
SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING,
0, 1, 0),
};
static const struct snd_kcontrol_new aif2dac2l_mix[] = {
SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
5, 1, 0),
SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
4, 1, 0),
SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2, 1, 0),
SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
1, 1, 0),
SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
0, 1, 0),
};
static const struct snd_kcontrol_new aif2dac2r_mix[] = {
SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
5, 1, 0),
SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
4, 1, 0),
SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2, 1, 0),
SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
1, 1, 0),
SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
0, 1, 0),
};
#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_volsw, \
.get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
struct snd_soc_codec *codec = w->codec;
int ret;
ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
wm8994_update_class_w(codec);
return ret;
}
static const struct snd_kcontrol_new dac1l_mix[] = {
WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
5, 1, 0),
WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
4, 1, 0),
WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2, 1, 0),
WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
1, 1, 0),
WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
0, 1, 0),
};
static const struct snd_kcontrol_new dac1r_mix[] = {
WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
5, 1, 0),
WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
4, 1, 0),
WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2, 1, 0),
WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
1, 1, 0),
WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
0, 1, 0),
};
static const char *sidetone_text[] = {
"ADC/DMIC1", "DMIC2",
};
static const struct soc_enum sidetone1_enum =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
static const struct snd_kcontrol_new sidetone1_mux =
SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
static const struct soc_enum sidetone2_enum =
SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
static const struct snd_kcontrol_new sidetone2_mux =
SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
static const char *aif1dac_text[] = {
"AIF1DACDAT", "AIF3DACDAT",
};
static const struct soc_enum aif1dac_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
static const struct snd_kcontrol_new aif1dac_mux =
SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
static const char *aif2dac_text[] = {
"AIF2DACDAT", "AIF3DACDAT",
};
static const struct soc_enum aif2dac_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
static const struct snd_kcontrol_new aif2dac_mux =
SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
static const char *aif2adc_text[] = {
"AIF2ADCDAT", "AIF3DACDAT",
};
static const struct soc_enum aif2adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
static const struct snd_kcontrol_new aif2adc_mux =
SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
static const char *aif3adc_text[] = {
"AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
};
static const struct soc_enum aif3adc_enum =
SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
static const struct snd_kcontrol_new aif3adc_mux =
SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("DMIC1DAT"),
SND_SOC_DAPM_INPUT("DMIC2DAT"),
SND_SOC_DAPM_INPUT("Clock"),
SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 9, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 8, 0),
SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
WM8994_POWER_MANAGEMENT_5, 9, 0),
SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
WM8994_POWER_MANAGEMENT_5, 8, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 11, 0),
SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
0, WM8994_POWER_MANAGEMENT_4, 10, 0),
SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
WM8994_POWER_MANAGEMENT_5, 11, 0),
SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
WM8994_POWER_MANAGEMENT_5, 10, 0),
SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
dac1l_mix, ARRAY_SIZE(dac1l_mix)),
SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
dac1r_mix, ARRAY_SIZE(dac1r_mix)),
SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
WM8994_POWER_MANAGEMENT_4, 13, 0),
SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
WM8994_POWER_MANAGEMENT_4, 12, 0),
SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
WM8994_POWER_MANAGEMENT_5, 13, 0),
SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
WM8994_POWER_MANAGEMENT_5, 12, 0),
SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
/* Power is done with the muxes since the ADC power also controls the
* downsampling chain, the chip will automatically manage the analogue
* specific portions.
*/
SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
SND_SOC_DAPM_POST("Debug log", post_ev),
};
static const struct snd_soc_dapm_route intercon[] = {
{ "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
{ "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
{ "DSP1CLK", NULL, "CLK_SYS" },
{ "DSP2CLK", NULL, "CLK_SYS" },
{ "DSPINTCLK", NULL, "CLK_SYS" },
{ "AIF1ADC1L", NULL, "AIF1CLK" },
{ "AIF1ADC1L", NULL, "DSP1CLK" },
{ "AIF1ADC1R", NULL, "AIF1CLK" },
{ "AIF1ADC1R", NULL, "DSP1CLK" },
{ "AIF1ADC1R", NULL, "DSPINTCLK" },
{ "AIF1DAC1L", NULL, "AIF1CLK" },
{ "AIF1DAC1L", NULL, "DSP1CLK" },
{ "AIF1DAC1R", NULL, "AIF1CLK" },
{ "AIF1DAC1R", NULL, "DSP1CLK" },
{ "AIF1DAC1R", NULL, "DSPINTCLK" },
{ "AIF1ADC2L", NULL, "AIF1CLK" },
{ "AIF1ADC2L", NULL, "DSP1CLK" },
{ "AIF1ADC2R", NULL, "AIF1CLK" },
{ "AIF1ADC2R", NULL, "DSP1CLK" },
{ "AIF1ADC2R", NULL, "DSPINTCLK" },
{ "AIF1DAC2L", NULL, "AIF1CLK" },
{ "AIF1DAC2L", NULL, "DSP1CLK" },
{ "AIF1DAC2R", NULL, "AIF1CLK" },
{ "AIF1DAC2R", NULL, "DSP1CLK" },
{ "AIF1DAC2R", NULL, "DSPINTCLK" },
{ "AIF2ADCL", NULL, "AIF2CLK" },
{ "AIF2ADCL", NULL, "DSP2CLK" },
{ "AIF2ADCR", NULL, "AIF2CLK" },
{ "AIF2ADCR", NULL, "DSP2CLK" },
{ "AIF2ADCR", NULL, "DSPINTCLK" },
{ "AIF2DACL", NULL, "AIF2CLK" },
{ "AIF2DACL", NULL, "DSP2CLK" },
{ "AIF2DACR", NULL, "AIF2CLK" },
{ "AIF2DACR", NULL, "DSP2CLK" },
{ "AIF2DACR", NULL, "DSPINTCLK" },
{ "DMIC1L", NULL, "DMIC1DAT" },
{ "DMIC1L", NULL, "CLK_SYS" },
{ "DMIC1R", NULL, "DMIC1DAT" },
{ "DMIC1R", NULL, "CLK_SYS" },
{ "DMIC2L", NULL, "DMIC2DAT" },
{ "DMIC2L", NULL, "CLK_SYS" },
{ "DMIC2R", NULL, "DMIC2DAT" },
{ "DMIC2R", NULL, "CLK_SYS" },
{ "ADCL", NULL, "AIF1CLK" },
{ "ADCL", NULL, "DSP1CLK" },
{ "ADCL", NULL, "DSPINTCLK" },
{ "ADCR", NULL, "AIF1CLK" },
{ "ADCR", NULL, "DSP1CLK" },
{ "ADCR", NULL, "DSPINTCLK" },
{ "ADCL Mux", "ADC", "ADCL" },
{ "ADCL Mux", "DMIC", "DMIC1L" },
{ "ADCR Mux", "ADC", "ADCR" },
{ "ADCR Mux", "DMIC", "DMIC1R" },
{ "DAC1L", NULL, "AIF1CLK" },
{ "DAC1L", NULL, "DSP1CLK" },
{ "DAC1L", NULL, "DSPINTCLK" },
{ "DAC1R", NULL, "AIF1CLK" },
{ "DAC1R", NULL, "DSP1CLK" },
{ "DAC1R", NULL, "DSPINTCLK" },
{ "DAC2L", NULL, "AIF2CLK" },
{ "DAC2L", NULL, "DSP2CLK" },
{ "DAC2L", NULL, "DSPINTCLK" },
{ "DAC2R", NULL, "AIF2DACR" },
{ "DAC2R", NULL, "AIF2CLK" },
{ "DAC2R", NULL, "DSP2CLK" },
{ "DAC2R", NULL, "DSPINTCLK" },
{ "TOCLK", NULL, "CLK_SYS" },
/* AIF1 outputs */
{ "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
{ "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
{ "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
{ "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
{ "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
{ "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
{ "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
{ "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
{ "AIF1ADC2L Mixer", "AIF2 Switch", "AIF2DACL" },
{ "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
{ "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
{ "AIF1ADC2R Mixer", "AIF2 Switch", "AIF2DACR" },
/* Pin level routing for AIF3 */
{ "AIF1DAC1L", NULL, "AIF1DAC Mux" },
{ "AIF1DAC1R", NULL, "AIF1DAC Mux" },
{ "AIF1DAC2L", NULL, "AIF1DAC Mux" },
{ "AIF1DAC2R", NULL, "AIF1DAC Mux" },
{ "AIF2DACL", NULL, "AIF2DAC Mux" },
{ "AIF2DACR", NULL, "AIF2DAC Mux" },
{ "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
{ "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
{ "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
{ "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
{ "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
{ "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
{ "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
/* DAC1 inputs */
{ "DAC1L", NULL, "DAC1L Mixer" },
{ "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
{ "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
{ "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
{ "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
{ "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
{ "DAC1R", NULL, "DAC1R Mixer" },
{ "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
{ "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
{ "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
{ "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
{ "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
/* DAC2/AIF2 outputs */
{ "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
{ "DAC2L", NULL, "AIF2DAC2L Mixer" },
{ "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
{ "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
{ "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
{ "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
{ "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
{ "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
{ "DAC2R", NULL, "AIF2DAC2R Mixer" },
{ "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
{ "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
{ "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
{ "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
{ "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
{ "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
/* AIF3 output */
{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
{ "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
{ "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
{ "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
{ "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
{ "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
/* Sidetone */
{ "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
{ "Left Sidetone", "DMIC2", "DMIC2L" },
{ "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
{ "Right Sidetone", "DMIC2", "DMIC2R" },
/* Output stages */
{ "Left Output Mixer", "DAC Switch", "DAC1L" },
{ "Right Output Mixer", "DAC Switch", "DAC1R" },
{ "SPKL", "DAC1 Switch", "DAC1L" },
{ "SPKL", "DAC2 Switch", "DAC2L" },
{ "SPKR", "DAC1 Switch", "DAC1R" },
{ "SPKR", "DAC2 Switch", "DAC2R" },
{ "Left Headphone Mux", "DAC", "DAC1L" },
{ "Right Headphone Mux", "DAC", "DAC1R" },
};
/* The size in bits of the FLL divide multiplied by 10
* to allow rounding later */
#define FIXED_FLL_SIZE ((1 << 16) * 10)
struct fll_div {
u16 outdiv;
u16 n;
u16 k;
u16 clk_ref_div;
u16 fll_fratio;
};
static int wm8994_get_fll_config(struct fll_div *fll,
int freq_in, int freq_out)
{
u64 Kpart;
unsigned int K, Ndiv, Nmod;
pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
/* Scale the input frequency down to <= 13.5MHz */
fll->clk_ref_div = 0;
while (freq_in > 13500000) {
fll->clk_ref_div++;
freq_in /= 2;
if (fll->clk_ref_div > 3)
return -EINVAL;
}
pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
/* Scale the output to give 90MHz<=Fvco<=100MHz */
fll->outdiv = 3;
while (freq_out * (fll->outdiv + 1) < 90000000) {
fll->outdiv++;
if (fll->outdiv > 63)
return -EINVAL;
}
freq_out *= fll->outdiv + 1;
pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
if (freq_in > 1000000) {
fll->fll_fratio = 0;
} else if (freq_in > 256000) {
fll->fll_fratio = 1;
freq_in *= 2;
} else if (freq_in > 128000) {
fll->fll_fratio = 2;
freq_in *= 4;
} else if (freq_in > 64000) {
fll->fll_fratio = 3;
freq_in *= 8;
} else {
fll->fll_fratio = 4;
freq_in *= 16;
}
pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
/* Now, calculate N.K */
Ndiv = freq_out / freq_in;
fll->n = Ndiv;
Nmod = freq_out % freq_in;
pr_debug("Nmod=%d\n", Nmod);
/* Calculate fractional part - scale up so we can round. */
Kpart = FIXED_FLL_SIZE * (long long)Nmod;
do_div(Kpart, freq_in);
K = Kpart & 0xFFFFFFFF;
if ((K % 10) >= 5)
K += 5;
/* Move down to proper range now rounding is done */
fll->k = K / 10;
pr_debug("N=%x K=%x\n", fll->n, fll->k);
return 0;
}
static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
unsigned int freq_in, unsigned int freq_out)
{
struct snd_soc_codec *codec = dai->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int reg_offset, ret;
struct fll_div fll;
u16 reg, aif1, aif2;
aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
& WM8994_AIF1CLK_ENA;
aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
& WM8994_AIF2CLK_ENA;
switch (id) {
case WM8994_FLL1:
reg_offset = 0;
id = 0;
break;
case WM8994_FLL2:
reg_offset = 0x20;
id = 1;
break;
default:
return -EINVAL;
}
switch (src) {
case 0:
/* Allow no source specification when stopping */
if (freq_out)
return -EINVAL;
break;
case WM8994_FLL_SRC_MCLK1:
case WM8994_FLL_SRC_MCLK2:
case WM8994_FLL_SRC_LRCLK:
case WM8994_FLL_SRC_BCLK:
break;
default:
return -EINVAL;
}
/* Are we changing anything? */
if (wm8994->fll[id].src == src &&
wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
return 0;
/* If we're stopping the FLL redo the old config - no
* registers will actually be written but we avoid GCC flow
* analysis bugs spewing warnings.
*/
if (freq_out)
ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
else
ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
wm8994->fll[id].out);
if (ret < 0)
return ret;
/* Gate the AIF clocks while we reclock */
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
WM8994_AIF1CLK_ENA, 0);
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
WM8994_AIF2CLK_ENA, 0);
/* We always need to disable the FLL while reconfiguring */
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
WM8994_FLL1_ENA, 0);
reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
(fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
WM8994_FLL1_OUTDIV_MASK |
WM8994_FLL1_FRATIO_MASK, reg);
snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
WM8994_FLL1_N_MASK,
fll.n << WM8994_FLL1_N_SHIFT);
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
WM8994_FLL1_REFCLK_DIV_MASK |
WM8994_FLL1_REFCLK_SRC_MASK,
(fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
(src - 1));
/* Enable (with fractional mode if required) */
if (freq_out) {
if (fll.k)
reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
else
reg = WM8994_FLL1_ENA;
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
reg);
}
wm8994->fll[id].in = freq_in;
wm8994->fll[id].out = freq_out;
wm8994->fll[id].src = src;
/* Enable any gated AIF clocks */
snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
WM8994_AIF1CLK_ENA, aif1);
snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
WM8994_AIF2CLK_ENA, aif2);
configure_clock(codec);
return 0;
}
static int opclk_divs[] = { 10, 20, 30, 40, 55, 60, 80, 120, 160 };
static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_codec *codec = dai->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int i;
switch (dai->id) {
case 1:
case 2:
break;
default:
/* AIF3 shares clocking with AIF1/2 */
return -EINVAL;
}
switch (clk_id) {
case WM8994_SYSCLK_MCLK1:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
wm8994->mclk[0] = freq;
dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
dai->id, freq);
break;
case WM8994_SYSCLK_MCLK2:
/* TODO: Set GPIO AF */
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
wm8994->mclk[1] = freq;
dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
dai->id, freq);
break;
case WM8994_SYSCLK_FLL1:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
break;
case WM8994_SYSCLK_FLL2:
wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
break;
case WM8994_SYSCLK_OPCLK:
/* Special case - a division (times 10) is given and
* no effect on main clocking.
*/
if (freq) {
for (i = 0; i < ARRAY_SIZE(opclk_divs); i++)
if (opclk_divs[i] == freq)
break;
if (i == ARRAY_SIZE(opclk_divs))
return -EINVAL;
snd_soc_update_bits(codec, WM8994_CLOCKING_2,
WM8994_OPCLK_DIV_MASK, i);
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
WM8994_OPCLK_ENA, WM8994_OPCLK_ENA);
} else {
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_2,
WM8994_OPCLK_ENA, 0);
}
default:
return -EINVAL;
}
configure_clock(codec);
return 0;
}
static int wm8994_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
switch (level) {
case SND_SOC_BIAS_ON:
break;
case SND_SOC_BIAS_PREPARE:
/* VMID=2x40k */
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
WM8994_VMID_SEL_MASK, 0x2);
break;
case SND_SOC_BIAS_STANDBY:
if (codec->bias_level == SND_SOC_BIAS_OFF) {
/* Tweak DC servo configuration for improved
* performance. */
snd_soc_write(codec, 0x102, 0x3);
snd_soc_write(codec, 0x56, 0x3);
snd_soc_write(codec, 0x102, 0);
/* Discharge LINEOUT1 & 2 */
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH);
/* Startup bias, VMID ramp & buffer */
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK,
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
(0x11 << WM8994_VMID_RAMP_SHIFT));
/* Main bias enable, VMID=2x40k */
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
WM8994_BIAS_ENA |
WM8994_VMID_SEL_MASK,
WM8994_BIAS_ENA | 0x2);
msleep(20);
}
/* VMID=2x500k */
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
WM8994_VMID_SEL_MASK, 0x4);
break;
case SND_SOC_BIAS_OFF:
if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
/* Switch over to startup biases */
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_BIAS_SRC |
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK,
WM8994_BIAS_SRC |
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
(1 << WM8994_VMID_RAMP_SHIFT));
/* Disable main biases */
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
WM8994_BIAS_ENA |
WM8994_VMID_SEL_MASK, 0);
/* Discharge line */
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH);
msleep(5);
/* Switch off startup biases */
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_BIAS_SRC |
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK, 0);
}
break;
}
codec->bias_level = level;
return 0;
}
static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_codec *codec = dai->codec;
int ms_reg;
int aif1_reg;
int ms = 0;
int aif1 = 0;
switch (dai->id) {
case 1:
ms_reg = WM8994_AIF1_MASTER_SLAVE;
aif1_reg = WM8994_AIF1_CONTROL_1;
break;
case 2:
ms_reg = WM8994_AIF2_MASTER_SLAVE;
aif1_reg = WM8994_AIF2_CONTROL_1;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
break;
case SND_SOC_DAIFMT_CBM_CFM:
ms = WM8994_AIF1_MSTR;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_B:
aif1 |= WM8994_AIF1_LRCLK_INV;
case SND_SOC_DAIFMT_DSP_A:
aif1 |= 0x18;
break;
case SND_SOC_DAIFMT_I2S:
aif1 |= 0x10;
break;
case SND_SOC_DAIFMT_RIGHT_J:
break;
case SND_SOC_DAIFMT_LEFT_J:
aif1 |= 0x8;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_DSP_A:
case SND_SOC_DAIFMT_DSP_B:
/* frame inversion not valid for DSP modes */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_NF:
aif1 |= WM8994_AIF1_BCLK_INV;
break;
default:
return -EINVAL;
}
break;
case SND_SOC_DAIFMT_I2S:
case SND_SOC_DAIFMT_RIGHT_J:
case SND_SOC_DAIFMT_LEFT_J:
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_IF:
aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
break;
case SND_SOC_DAIFMT_IB_NF:
aif1 |= WM8994_AIF1_BCLK_INV;
break;
case SND_SOC_DAIFMT_NB_IF:
aif1 |= WM8994_AIF1_LRCLK_INV;
break;
default:
return -EINVAL;
}
break;
default:
return -EINVAL;
}
snd_soc_update_bits(codec, aif1_reg,
WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
WM8994_AIF1_FMT_MASK,
aif1);
snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
ms);
return 0;
}
static struct {
int val, rate;
} srs[] = {
{ 0, 8000 },
{ 1, 11025 },
{ 2, 12000 },
{ 3, 16000 },
{ 4, 22050 },
{ 5, 24000 },
{ 6, 32000 },
{ 7, 44100 },
{ 8, 48000 },
{ 9, 88200 },
{ 10, 96000 },
};
static int fs_ratios[] = {
64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
};
static int bclk_divs[] = {
10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
640, 880, 960, 1280, 1760, 1920
};
static int wm8994_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct snd_soc_codec *codec = dai->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int aif1_reg;
int bclk_reg;
int lrclk_reg;
int rate_reg;
int aif1 = 0;
int bclk = 0;
int lrclk = 0;
int rate_val = 0;
int id = dai->id - 1;
int i, cur_val, best_val, bclk_rate, best;
switch (dai->id) {
case 1:
aif1_reg = WM8994_AIF1_CONTROL_1;
bclk_reg = WM8994_AIF1_BCLK;
rate_reg = WM8994_AIF1_RATE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
wm8994->lrclk_shared[0])
lrclk_reg = WM8994_AIF1DAC_LRCLK;
else
lrclk_reg = WM8994_AIF1ADC_LRCLK;
break;
case 2:
aif1_reg = WM8994_AIF2_CONTROL_1;
bclk_reg = WM8994_AIF2_BCLK;
rate_reg = WM8994_AIF2_RATE;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
wm8994->lrclk_shared[1])
lrclk_reg = WM8994_AIF2DAC_LRCLK;
else
lrclk_reg = WM8994_AIF2ADC_LRCLK;
break;
default:
return -EINVAL;
}
bclk_rate = params_rate(params) * 2;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
bclk_rate *= 16;
break;
case SNDRV_PCM_FORMAT_S20_3LE:
bclk_rate *= 20;
aif1 |= 0x20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
bclk_rate *= 24;
aif1 |= 0x40;
break;
case SNDRV_PCM_FORMAT_S32_LE:
bclk_rate *= 32;
aif1 |= 0x60;
break;
default:
return -EINVAL;
}
/* Try to find an appropriate sample rate; look for an exact match. */
for (i = 0; i < ARRAY_SIZE(srs); i++)
if (srs[i].rate == params_rate(params))
break;
if (i == ARRAY_SIZE(srs))
return -EINVAL;
rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
dai->id, wm8994->aifclk[id], bclk_rate);
if (wm8994->aifclk[id] == 0) {
dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
return -EINVAL;
}
/* AIFCLK/fs ratio; look for a close match in either direction */
best = 0;
best_val = abs((fs_ratios[0] * params_rate(params))
- wm8994->aifclk[id]);
for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
cur_val = abs((fs_ratios[i] * params_rate(params))
- wm8994->aifclk[id]);
if (cur_val >= best_val)
continue;
best = i;
best_val = cur_val;
}
dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
dai->id, fs_ratios[best]);
rate_val |= best;
/* We may not get quite the right frequency if using
* approximate clocks so look for the closest match that is
* higher than the target (we need to ensure that there enough
* BCLKs to clock out the samples).
*/
best = 0;
for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
if (cur_val < 0) /* BCLK table is sorted */
break;
best = i;
}
bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
bclk_divs[best], bclk_rate);
bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
lrclk = bclk_rate / params_rate(params);
dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
lrclk, bclk_rate / lrclk);
snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
lrclk);
snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
WM8994_AIF1CLK_RATE_MASK, rate_val);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
switch (dai->id) {
case 1:
wm8994->dac_rates[0] = params_rate(params);
wm8994_set_retune_mobile(codec, 0);
wm8994_set_retune_mobile(codec, 1);
break;
case 2:
wm8994->dac_rates[1] = params_rate(params);
wm8994_set_retune_mobile(codec, 2);
break;
}
}
return 0;
}
static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
{
struct snd_soc_codec *codec = codec_dai->codec;
int mute_reg;
int reg;
switch (codec_dai->id) {
case 1:
mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
break;
case 2:
mute_reg = WM8994_AIF2_DAC_FILTERS_1;
break;
default:
return -EINVAL;
}
if (mute)
reg = WM8994_AIF1DAC1_MUTE;
else
reg = 0;
snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
return 0;
}
static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
{
struct snd_soc_codec *codec = codec_dai->codec;
int reg, val, mask;
switch (codec_dai->id) {
case 1:
reg = WM8994_AIF1_MASTER_SLAVE;
mask = WM8994_AIF1_TRI;
break;
case 2:
reg = WM8994_AIF2_MASTER_SLAVE;
mask = WM8994_AIF2_TRI;
break;
case 3:
reg = WM8994_POWER_MANAGEMENT_6;
mask = WM8994_AIF3_TRI;
break;
default:
return -EINVAL;
}
if (tristate)
val = mask;
else
val = 0;
return snd_soc_update_bits(codec, reg, mask, reg);
}
#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
SNDRV_PCM_FMTBIT_S24_LE)
static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
.set_sysclk = wm8994_set_dai_sysclk,
.set_fmt = wm8994_set_dai_fmt,
.hw_params = wm8994_hw_params,
.digital_mute = wm8994_aif_mute,
.set_pll = wm8994_set_fll,
.set_tristate = wm8994_set_tristate,
};
static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
.set_sysclk = wm8994_set_dai_sysclk,
.set_fmt = wm8994_set_dai_fmt,
.hw_params = wm8994_hw_params,
.digital_mute = wm8994_aif_mute,
.set_pll = wm8994_set_fll,
.set_tristate = wm8994_set_tristate,
};
static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
.set_tristate = wm8994_set_tristate,
};
struct snd_soc_dai wm8994_dai[] = {
{
.name = "WM8994 AIF1",
.id = 1,
.playback = {
.stream_name = "AIF1 Playback",
.channels_min = 2,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF1 Capture",
.channels_min = 2,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.ops = &wm8994_aif1_dai_ops,
},
{
.name = "WM8994 AIF2",
.id = 2,
.playback = {
.stream_name = "AIF2 Playback",
.channels_min = 2,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF2 Capture",
.channels_min = 2,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.ops = &wm8994_aif2_dai_ops,
},
{
.name = "WM8994 AIF3",
.id = 3,
.playback = {
.stream_name = "AIF3 Playback",
.channels_min = 2,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.capture = {
.stream_name = "AIF3 Capture",
.channels_min = 2,
.channels_max = 2,
.rates = WM8994_RATES,
.formats = WM8994_FORMATS,
},
.ops = &wm8994_aif3_dai_ops,
}
};
EXPORT_SYMBOL_GPL(wm8994_dai);
#ifdef CONFIG_PM
static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
int i, ret;
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
sizeof(struct fll_config));
ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
if (ret < 0)
dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
i + 1, ret);
}
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
static int wm8994_resume(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = socdev->card->codec;
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
u16 *reg_cache = codec->reg_cache;
int i, ret;
/* Restore the registers */
for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
switch (i) {
case WM8994_LDO_1:
case WM8994_LDO_2:
case WM8994_SOFTWARE_RESET:
/* Handled by other MFD drivers */
continue;
default:
break;
}
if (!access_masks[i].writable)
continue;
wm8994_reg_write(codec->control_data, i, reg_cache[i]);
}
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
if (!wm8994->fll_suspend[i].out)
continue;
ret = wm8994_set_fll(&codec->dai[0], i + 1,
wm8994->fll_suspend[i].src,
wm8994->fll_suspend[i].in,
wm8994->fll_suspend[i].out);
if (ret < 0)
dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
i + 1, ret);
}
return 0;
}
#else
#define wm8994_suspend NULL
#define wm8994_resume NULL
#endif
static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
{
struct snd_soc_codec *codec = &wm8994->codec;
struct wm8994_pdata *pdata = wm8994->pdata;
struct snd_kcontrol_new controls[] = {
SOC_ENUM_EXT("AIF1.1 EQ Mode",
wm8994->retune_mobile_enum,
wm8994_get_retune_mobile_enum,
wm8994_put_retune_mobile_enum),
SOC_ENUM_EXT("AIF1.2 EQ Mode",
wm8994->retune_mobile_enum,
wm8994_get_retune_mobile_enum,
wm8994_put_retune_mobile_enum),
SOC_ENUM_EXT("AIF2 EQ Mode",
wm8994->retune_mobile_enum,
wm8994_get_retune_mobile_enum,
wm8994_put_retune_mobile_enum),
};
int ret, i, j;
const char **t;
/* We need an array of texts for the enum API but the number
* of texts is likely to be less than the number of
* configurations due to the sample rate dependency of the
* configurations. */
wm8994->num_retune_mobile_texts = 0;
wm8994->retune_mobile_texts = NULL;
for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
if (strcmp(pdata->retune_mobile_cfgs[i].name,
wm8994->retune_mobile_texts[j]) == 0)
break;
}
if (j != wm8994->num_retune_mobile_texts)
continue;
/* Expand the array... */
t = krealloc(wm8994->retune_mobile_texts,
sizeof(char *) *
(wm8994->num_retune_mobile_texts + 1),
GFP_KERNEL);
if (t == NULL)
continue;
/* ...store the new entry... */
t[wm8994->num_retune_mobile_texts] =
pdata->retune_mobile_cfgs[i].name;
/* ...and remember the new version. */
wm8994->num_retune_mobile_texts++;
wm8994->retune_mobile_texts = t;
}
dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
wm8994->num_retune_mobile_texts);
wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
ret = snd_soc_add_controls(&wm8994->codec, controls,
ARRAY_SIZE(controls));
if (ret != 0)
dev_err(wm8994->codec.dev,
"Failed to add ReTune Mobile controls: %d\n", ret);
}
static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
{
struct snd_soc_codec *codec = &wm8994->codec;
struct wm8994_pdata *pdata = wm8994->pdata;
int ret, i;
if (!pdata)
return;
wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
pdata->lineout2_diff,
pdata->lineout1fb,
pdata->lineout2fb,
pdata->jd_scthr,
pdata->jd_thr,
pdata->micbias1_lvl,
pdata->micbias2_lvl);
dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
if (pdata->num_drc_cfgs) {
struct snd_kcontrol_new controls[] = {
SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
wm8994_get_drc_enum, wm8994_put_drc_enum),
SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
wm8994_get_drc_enum, wm8994_put_drc_enum),
SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
wm8994_get_drc_enum, wm8994_put_drc_enum),
};
/* We need an array of texts for the enum API */
wm8994->drc_texts = kmalloc(sizeof(char *)
* pdata->num_drc_cfgs, GFP_KERNEL);
if (!wm8994->drc_texts) {
dev_err(wm8994->codec.dev,
"Failed to allocate %d DRC config texts\n",
pdata->num_drc_cfgs);
return;
}
for (i = 0; i < pdata->num_drc_cfgs; i++)
wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
wm8994->drc_enum.max = pdata->num_drc_cfgs;
wm8994->drc_enum.texts = wm8994->drc_texts;
ret = snd_soc_add_controls(&wm8994->codec, controls,
ARRAY_SIZE(controls));
if (ret != 0)
dev_err(wm8994->codec.dev,
"Failed to add DRC mode controls: %d\n", ret);
for (i = 0; i < WM8994_NUM_DRC; i++)
wm8994_set_drc(codec, i);
}
dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
pdata->num_retune_mobile_cfgs);
if (pdata->num_retune_mobile_cfgs)
wm8994_handle_retune_mobile_pdata(wm8994);
else
snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
ARRAY_SIZE(wm8994_eq_controls));
}
static int wm8994_probe(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_codec *codec;
int ret = 0;
if (wm8994_codec == NULL) {
dev_err(&pdev->dev, "Codec device not registered\n");
return -ENODEV;
}
socdev->card->codec = wm8994_codec;
codec = wm8994_codec;
/* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) {
dev_err(codec->dev, "failed to create pcms: %d\n", ret);
return ret;
}
wm8994_handle_pdata(snd_soc_codec_get_drvdata(codec));
wm_hubs_add_analogue_controls(codec);
snd_soc_add_controls(codec, wm8994_snd_controls,
ARRAY_SIZE(wm8994_snd_controls));
snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
ARRAY_SIZE(wm8994_dapm_widgets));
wm_hubs_add_analogue_routes(codec, 0, 0);
snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
return 0;
}
static int wm8994_remove(struct platform_device *pdev)
{
struct snd_soc_device *socdev = platform_get_drvdata(pdev);
snd_soc_free_pcms(socdev);
snd_soc_dapm_free(socdev);
return 0;
}
struct snd_soc_codec_device soc_codec_dev_wm8994 = {
.probe = wm8994_probe,
.remove = wm8994_remove,
.suspend = wm8994_suspend,
.resume = wm8994_resume,
};
EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
/**
* wm8994_mic_detect - Enable microphone detection via the WM8994 IRQ
*
* @codec: WM8994 codec
* @jack: jack to report detection events on
* @micbias: microphone bias to detect on
* @det: value to report for presence detection
* @shrt: value to report for short detection
*
* Enable microphone detection via IRQ on the WM8994. If GPIOs are
* being used to bring out signals to the processor then only platform
* data configuration is needed for WM8903 and processor GPIOs should
* be configured using snd_soc_jack_add_gpios() instead.
*
* Configuration of detection levels is available via the micbias1_lvl
* and micbias2_lvl platform data members.
*/
int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
int micbias, int det, int shrt)
{
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
struct wm8994_micdet *micdet;
int reg;
switch (micbias) {
case 1:
micdet = &wm8994->micdet[0];
break;
case 2:
micdet = &wm8994->micdet[1];
break;
default:
return -EINVAL;
}
dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n",
micbias, det, shrt);
/* Store the configuration */
micdet->jack = jack;
micdet->det = det;
micdet->shrt = shrt;
/* If either of the jacks is set up then enable detection */
if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
reg = WM8994_MICD_ENA;
else
reg = 0;
snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
return 0;
}
EXPORT_SYMBOL_GPL(wm8994_mic_detect);
static irqreturn_t wm8994_mic_irq(int irq, void *data)
{
struct wm8994_priv *priv = data;
struct snd_soc_codec *codec = &priv->codec;
int reg;
int report;
reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
if (reg < 0) {
dev_err(codec->dev, "Failed to read microphone status: %d\n",
reg);
return IRQ_HANDLED;
}
dev_dbg(codec->dev, "Microphone status: %x\n", reg);
report = 0;
if (reg & WM8994_MIC1_DET_STS)
report |= priv->micdet[0].det;
if (reg & WM8994_MIC1_SHRT_STS)
report |= priv->micdet[0].shrt;
snd_soc_jack_report(priv->micdet[0].jack, report,
priv->micdet[0].det | priv->micdet[0].shrt);
report = 0;
if (reg & WM8994_MIC2_DET_STS)
report |= priv->micdet[1].det;
if (reg & WM8994_MIC2_SHRT_STS)
report |= priv->micdet[1].shrt;
snd_soc_jack_report(priv->micdet[1].jack, report,
priv->micdet[1].det | priv->micdet[1].shrt);
return IRQ_HANDLED;
}
static int wm8994_codec_probe(struct platform_device *pdev)
{
int ret;
struct wm8994_priv *wm8994;
struct snd_soc_codec *codec;
int i;
u16 rev;
if (wm8994_codec) {
dev_err(&pdev->dev, "Another WM8994 is registered\n");
return -EINVAL;
}
wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
if (!wm8994) {
dev_err(&pdev->dev, "Failed to allocate private data\n");
return -ENOMEM;
}
codec = &wm8994->codec;
mutex_init(&codec->mutex);
INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths);
snd_soc_codec_set_drvdata(codec, wm8994);
codec->control_data = dev_get_drvdata(pdev->dev.parent);
codec->name = "WM8994";
codec->owner = THIS_MODULE;
codec->read = wm8994_read;
codec->write = wm8994_write;
codec->readable_register = wm8994_readable;
codec->bias_level = SND_SOC_BIAS_OFF;
codec->set_bias_level = wm8994_set_bias_level;
codec->dai = &wm8994_dai[0];
codec->num_dai = 3;
codec->reg_cache_size = WM8994_MAX_REGISTER;
codec->reg_cache = &wm8994->reg_cache;
codec->dev = &pdev->dev;
wm8994->pdata = pdev->dev.parent->platform_data;
/* Fill the cache with physical values we inherited; don't reset */
ret = wm8994_bulk_read(codec->control_data, 0,
ARRAY_SIZE(wm8994->reg_cache) - 1,
codec->reg_cache);
if (ret < 0) {
dev_err(codec->dev, "Failed to fill register cache: %d\n",
ret);
goto err;
}
/* Clear the cached values for unreadable/volatile registers to
* avoid potential confusion.
*/
for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
if (wm8994_volatile(i) || !wm8994_readable(i))
wm8994->reg_cache[i] = 0;
/* Set revision-specific configuration */
rev = snd_soc_read(codec, WM8994_CHIP_REVISION);
switch (rev) {
case 2:
case 3:
wm8994->hubs.dcs_codes = -5;
wm8994->hubs.hp_startup_mode = 1;
wm8994->hubs.dcs_readback_mode = 1;
break;
default:
wm8994->hubs.dcs_readback_mode = 1;
break;
}
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
wm8994_mic_irq, "Mic 1 detect", wm8994);
if (ret != 0)
dev_warn(&pdev->dev,
"Failed to request Mic1 detect IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
wm8994_mic_irq, "Mic 1 short", wm8994);
if (ret != 0)
dev_warn(&pdev->dev,
"Failed to request Mic1 short IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
wm8994_mic_irq, "Mic 2 detect", wm8994);
if (ret != 0)
dev_warn(&pdev->dev,
"Failed to request Mic2 detect IRQ: %d\n", ret);
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
wm8994_mic_irq, "Mic 2 short", wm8994);
if (ret != 0)
dev_warn(&pdev->dev,
"Failed to request Mic2 short IRQ: %d\n", ret);
/* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically
* at runtime we can deal with that then.
*/
ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
if (ret < 0) {
dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
goto err_irq;
}
if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
wm8994->lrclk_shared[0] = 1;
wm8994_dai[0].symmetric_rates = 1;
} else {
wm8994->lrclk_shared[0] = 0;
}
ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
if (ret < 0) {
dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
goto err_irq;
}
if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
wm8994->lrclk_shared[1] = 1;
wm8994_dai[1].symmetric_rates = 1;
} else {
wm8994->lrclk_shared[1] = 0;
}
for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
wm8994_dai[i].dev = codec->dev;
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
wm8994_codec = codec;
/* Latch volume updates (right only; we always do left then right). */
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
WM8994_DAC1_VU, WM8994_DAC1_VU);
snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
WM8994_DAC2_VU, WM8994_DAC2_VU);
/* Set the low bit of the 3D stereo depth so TLV matches */
snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
/* Unconditionally enable AIF1 ADC TDM mode; it only affects
* behaviour on idle TDM clock cycles. */
snd_soc_update_bits(codec, WM8994_AIF1_CONTROL_1,
WM8994_AIF1ADC_TDM, WM8994_AIF1ADC_TDM);
wm8994_update_class_w(codec);
ret = snd_soc_register_codec(codec);
if (ret != 0) {
dev_err(codec->dev, "Failed to register codec: %d\n", ret);
goto err_irq;
}
ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
if (ret != 0) {
dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
goto err_codec;
}
platform_set_drvdata(pdev, wm8994);
return 0;
err_codec:
snd_soc_unregister_codec(codec);
err_irq:
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
err:
kfree(wm8994);
return ret;
}
static int __devexit wm8994_codec_remove(struct platform_device *pdev)
{
struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
struct snd_soc_codec *codec = &wm8994->codec;
wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
snd_soc_unregister_codec(&wm8994->codec);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994);
wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994);
kfree(wm8994);
wm8994_codec = NULL;
return 0;
}
static struct platform_driver wm8994_codec_driver = {
.driver = {
.name = "wm8994-codec",
.owner = THIS_MODULE,
},
.probe = wm8994_codec_probe,
.remove = __devexit_p(wm8994_codec_remove),
};
static __init int wm8994_init(void)
{
return platform_driver_register(&wm8994_codec_driver);
}
module_init(wm8994_init);
static __exit void wm8994_exit(void)
{
platform_driver_unregister(&wm8994_codec_driver);
}
module_exit(wm8994_exit);
MODULE_DESCRIPTION("ASoC WM8994 driver");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:wm8994-codec");