cachepc-linux

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

wm8400.c (41763B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * wm8400.c  --  WM8400 ALSA Soc Audio driver
      4 *
      5 * Copyright 2008-11 Wolfson Microelectronics PLC.
      6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
      7 */
      8
      9#include <linux/module.h>
     10#include <linux/moduleparam.h>
     11#include <linux/kernel.h>
     12#include <linux/slab.h>
     13#include <linux/init.h>
     14#include <linux/delay.h>
     15#include <linux/pm.h>
     16#include <linux/platform_device.h>
     17#include <linux/regulator/consumer.h>
     18#include <linux/mfd/wm8400-audio.h>
     19#include <linux/mfd/wm8400-private.h>
     20#include <linux/mfd/core.h>
     21#include <sound/core.h>
     22#include <sound/pcm.h>
     23#include <sound/pcm_params.h>
     24#include <sound/soc.h>
     25#include <sound/initval.h>
     26#include <sound/tlv.h>
     27
     28#include "wm8400.h"
     29
     30static struct regulator_bulk_data power[] = {
     31	{
     32		.supply = "I2S1VDD",
     33	},
     34	{
     35		.supply = "I2S2VDD",
     36	},
     37	{
     38		.supply = "DCVDD",
     39	},
     40	{
     41		.supply = "AVDD",
     42	},
     43	{
     44		.supply = "FLLVDD",
     45	},
     46	{
     47		.supply = "HPVDD",
     48	},
     49	{
     50		.supply = "SPKVDD",
     51	},
     52};
     53
     54/* codec private data */
     55struct wm8400_priv {
     56	struct wm8400 *wm8400;
     57	u16 fake_register;
     58	unsigned int sysclk;
     59	unsigned int pcmclk;
     60	int fll_in, fll_out;
     61};
     62
     63static void wm8400_component_reset(struct snd_soc_component *component)
     64{
     65	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
     66
     67	wm8400_reset_codec_reg_cache(wm8400->wm8400);
     68}
     69
     70static const DECLARE_TLV_DB_SCALE(in_pga_tlv, -1650, 3000, 0);
     71
     72static const DECLARE_TLV_DB_SCALE(out_mix_tlv, -2100, 0, 0);
     73
     74static const DECLARE_TLV_DB_SCALE(out_pga_tlv, -7300, 600, 0);
     75
     76static const DECLARE_TLV_DB_SCALE(out_dac_tlv, -7163, 0, 0);
     77
     78static const DECLARE_TLV_DB_SCALE(in_adc_tlv, -7163, 1763, 0);
     79
     80static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0);
     81
     82static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
     83        struct snd_ctl_elem_value *ucontrol)
     84{
     85	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
     86	struct soc_mixer_control *mc =
     87		(struct soc_mixer_control *)kcontrol->private_value;
     88	int reg = mc->reg;
     89        int ret;
     90        u16 val;
     91
     92        ret = snd_soc_put_volsw(kcontrol, ucontrol);
     93        if (ret < 0)
     94                return ret;
     95
     96        /* now hit the volume update bits (always bit 8) */
     97	val = snd_soc_component_read(component, reg);
     98        return snd_soc_component_write(component, reg, val | 0x0100);
     99}
    100
    101#define WM8400_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert, tlv_array) \
    102	SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \
    103		snd_soc_get_volsw, wm8400_outpga_put_volsw_vu, tlv_array)
    104
    105
    106static const char *wm8400_digital_sidetone[] =
    107	{"None", "Left ADC", "Right ADC", "Reserved"};
    108
    109static SOC_ENUM_SINGLE_DECL(wm8400_left_digital_sidetone_enum,
    110			    WM8400_DIGITAL_SIDE_TONE,
    111			    WM8400_ADC_TO_DACL_SHIFT,
    112			    wm8400_digital_sidetone);
    113
    114static SOC_ENUM_SINGLE_DECL(wm8400_right_digital_sidetone_enum,
    115			    WM8400_DIGITAL_SIDE_TONE,
    116			    WM8400_ADC_TO_DACR_SHIFT,
    117			    wm8400_digital_sidetone);
    118
    119static const char *wm8400_adcmode[] =
    120	{"Hi-fi mode", "Voice mode 1", "Voice mode 2", "Voice mode 3"};
    121
    122static SOC_ENUM_SINGLE_DECL(wm8400_right_adcmode_enum,
    123			    WM8400_ADC_CTRL,
    124			    WM8400_ADC_HPF_CUT_SHIFT,
    125			    wm8400_adcmode);
    126
    127static const struct snd_kcontrol_new wm8400_snd_controls[] = {
    128/* INMIXL */
    129SOC_SINGLE("LIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L12MNBST_SHIFT,
    130	   1, 0),
    131SOC_SINGLE("LIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_L34MNBST_SHIFT,
    132	   1, 0),
    133/* INMIXR */
    134SOC_SINGLE("RIN12 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R12MNBST_SHIFT,
    135	   1, 0),
    136SOC_SINGLE("RIN34 PGA Boost", WM8400_INPUT_MIXER3, WM8400_R34MNBST_SHIFT,
    137	   1, 0),
    138
    139/* LOMIX */
    140SOC_SINGLE_TLV("LOMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER3,
    141	WM8400_LLI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
    142SOC_SINGLE_TLV("LOMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
    143	WM8400_LR12LOVOL_SHIFT, 7, 0, out_mix_tlv),
    144SOC_SINGLE_TLV("LOMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER3,
    145	WM8400_LL12LOVOL_SHIFT, 7, 0, out_mix_tlv),
    146SOC_SINGLE_TLV("LOMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER5,
    147	WM8400_LRI3LOVOL_SHIFT, 7, 0, out_mix_tlv),
    148SOC_SINGLE_TLV("LOMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
    149	WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
    150SOC_SINGLE_TLV("LOMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER5,
    151	WM8400_LRBLOVOL_SHIFT, 7, 0, out_mix_tlv),
    152
    153/* ROMIX */
    154SOC_SINGLE_TLV("ROMIX RIN3 Bypass Volume", WM8400_OUTPUT_MIXER4,
    155	WM8400_RRI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
    156SOC_SINGLE_TLV("ROMIX LIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
    157	WM8400_RL12ROVOL_SHIFT, 7, 0, out_mix_tlv),
    158SOC_SINGLE_TLV("ROMIX RIN12 PGA Bypass Volume", WM8400_OUTPUT_MIXER4,
    159	WM8400_RR12ROVOL_SHIFT, 7, 0, out_mix_tlv),
    160SOC_SINGLE_TLV("ROMIX LIN3 Bypass Volume", WM8400_OUTPUT_MIXER6,
    161	WM8400_RLI3ROVOL_SHIFT, 7, 0, out_mix_tlv),
    162SOC_SINGLE_TLV("ROMIX AINLMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
    163	WM8400_RLBROVOL_SHIFT, 7, 0, out_mix_tlv),
    164SOC_SINGLE_TLV("ROMIX AINRMUX Bypass Volume", WM8400_OUTPUT_MIXER6,
    165	WM8400_RRBROVOL_SHIFT, 7, 0, out_mix_tlv),
    166
    167/* LOUT */
    168WM8400_OUTPGA_SINGLE_R_TLV("LOUT Volume", WM8400_LEFT_OUTPUT_VOLUME,
    169	WM8400_LOUTVOL_SHIFT, WM8400_LOUTVOL_MASK, 0, out_pga_tlv),
    170SOC_SINGLE("LOUT ZC", WM8400_LEFT_OUTPUT_VOLUME, WM8400_LOZC_SHIFT, 1, 0),
    171
    172/* ROUT */
    173WM8400_OUTPGA_SINGLE_R_TLV("ROUT Volume", WM8400_RIGHT_OUTPUT_VOLUME,
    174	WM8400_ROUTVOL_SHIFT, WM8400_ROUTVOL_MASK, 0, out_pga_tlv),
    175SOC_SINGLE("ROUT ZC", WM8400_RIGHT_OUTPUT_VOLUME, WM8400_ROZC_SHIFT, 1, 0),
    176
    177/* LOPGA */
    178WM8400_OUTPGA_SINGLE_R_TLV("LOPGA Volume", WM8400_LEFT_OPGA_VOLUME,
    179	WM8400_LOPGAVOL_SHIFT, WM8400_LOPGAVOL_MASK, 0, out_pga_tlv),
    180SOC_SINGLE("LOPGA ZC Switch", WM8400_LEFT_OPGA_VOLUME,
    181	WM8400_LOPGAZC_SHIFT, 1, 0),
    182
    183/* ROPGA */
    184WM8400_OUTPGA_SINGLE_R_TLV("ROPGA Volume", WM8400_RIGHT_OPGA_VOLUME,
    185	WM8400_ROPGAVOL_SHIFT, WM8400_ROPGAVOL_MASK, 0, out_pga_tlv),
    186SOC_SINGLE("ROPGA ZC Switch", WM8400_RIGHT_OPGA_VOLUME,
    187	WM8400_ROPGAZC_SHIFT, 1, 0),
    188
    189SOC_SINGLE("LON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
    190	WM8400_LONMUTE_SHIFT, 1, 0),
    191SOC_SINGLE("LOP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
    192	WM8400_LOPMUTE_SHIFT, 1, 0),
    193SOC_SINGLE("LOP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
    194	WM8400_LOATTN_SHIFT, 1, 0),
    195SOC_SINGLE("RON Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
    196	WM8400_RONMUTE_SHIFT, 1, 0),
    197SOC_SINGLE("ROP Mute Switch", WM8400_LINE_OUTPUTS_VOLUME,
    198	WM8400_ROPMUTE_SHIFT, 1, 0),
    199SOC_SINGLE("ROP Attenuation Switch", WM8400_LINE_OUTPUTS_VOLUME,
    200	WM8400_ROATTN_SHIFT, 1, 0),
    201
    202SOC_SINGLE("OUT3 Mute Switch", WM8400_OUT3_4_VOLUME,
    203	WM8400_OUT3MUTE_SHIFT, 1, 0),
    204SOC_SINGLE("OUT3 Attenuation Switch", WM8400_OUT3_4_VOLUME,
    205	WM8400_OUT3ATTN_SHIFT, 1, 0),
    206
    207SOC_SINGLE("OUT4 Mute Switch", WM8400_OUT3_4_VOLUME,
    208	WM8400_OUT4MUTE_SHIFT, 1, 0),
    209SOC_SINGLE("OUT4 Attenuation Switch", WM8400_OUT3_4_VOLUME,
    210	WM8400_OUT4ATTN_SHIFT, 1, 0),
    211
    212SOC_SINGLE("Speaker Mode Switch", WM8400_CLASSD1,
    213	WM8400_CDMODE_SHIFT, 1, 0),
    214
    215SOC_SINGLE("Speaker Output Attenuation Volume", WM8400_SPEAKER_VOLUME,
    216	WM8400_SPKATTN_SHIFT, WM8400_SPKATTN_MASK, 0),
    217SOC_SINGLE("Speaker DC Boost Volume", WM8400_CLASSD3,
    218	WM8400_DCGAIN_SHIFT, 6, 0),
    219SOC_SINGLE("Speaker AC Boost Volume", WM8400_CLASSD3,
    220	WM8400_ACGAIN_SHIFT, 6, 0),
    221
    222WM8400_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume",
    223	WM8400_LEFT_DAC_DIGITAL_VOLUME, WM8400_DACL_VOL_SHIFT,
    224	127, 0, out_dac_tlv),
    225
    226WM8400_OUTPGA_SINGLE_R_TLV("Right DAC Digital Volume",
    227	WM8400_RIGHT_DAC_DIGITAL_VOLUME, WM8400_DACR_VOL_SHIFT,
    228	127, 0, out_dac_tlv),
    229
    230SOC_ENUM("Left Digital Sidetone", wm8400_left_digital_sidetone_enum),
    231SOC_ENUM("Right Digital Sidetone", wm8400_right_digital_sidetone_enum),
    232
    233SOC_SINGLE_TLV("Left Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
    234	WM8400_ADCL_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
    235SOC_SINGLE_TLV("Right Digital Sidetone Volume", WM8400_DIGITAL_SIDE_TONE,
    236	WM8400_ADCR_DAC_SVOL_SHIFT, 15, 0, out_sidetone_tlv),
    237
    238SOC_SINGLE("ADC Digital High Pass Filter Switch", WM8400_ADC_CTRL,
    239	WM8400_ADC_HPF_ENA_SHIFT, 1, 0),
    240
    241SOC_ENUM("ADC HPF Mode", wm8400_right_adcmode_enum),
    242
    243WM8400_OUTPGA_SINGLE_R_TLV("Left ADC Digital Volume",
    244	WM8400_LEFT_ADC_DIGITAL_VOLUME,
    245	WM8400_ADCL_VOL_SHIFT,
    246	WM8400_ADCL_VOL_MASK,
    247	0,
    248	in_adc_tlv),
    249
    250WM8400_OUTPGA_SINGLE_R_TLV("Right ADC Digital Volume",
    251	WM8400_RIGHT_ADC_DIGITAL_VOLUME,
    252	WM8400_ADCR_VOL_SHIFT,
    253	WM8400_ADCR_VOL_MASK,
    254	0,
    255	in_adc_tlv),
    256
    257WM8400_OUTPGA_SINGLE_R_TLV("LIN12 Volume",
    258	WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
    259	WM8400_LIN12VOL_SHIFT,
    260	WM8400_LIN12VOL_MASK,
    261	0,
    262	in_pga_tlv),
    263
    264SOC_SINGLE("LIN12 ZC Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
    265	WM8400_LI12ZC_SHIFT, 1, 0),
    266
    267SOC_SINGLE("LIN12 Mute Switch", WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
    268	WM8400_LI12MUTE_SHIFT, 1, 0),
    269
    270WM8400_OUTPGA_SINGLE_R_TLV("LIN34 Volume",
    271	WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
    272	WM8400_LIN34VOL_SHIFT,
    273	WM8400_LIN34VOL_MASK,
    274	0,
    275	in_pga_tlv),
    276
    277SOC_SINGLE("LIN34 ZC Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
    278	WM8400_LI34ZC_SHIFT, 1, 0),
    279
    280SOC_SINGLE("LIN34 Mute Switch", WM8400_LEFT_LINE_INPUT_3_4_VOLUME,
    281	WM8400_LI34MUTE_SHIFT, 1, 0),
    282
    283WM8400_OUTPGA_SINGLE_R_TLV("RIN12 Volume",
    284	WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
    285	WM8400_RIN12VOL_SHIFT,
    286	WM8400_RIN12VOL_MASK,
    287	0,
    288	in_pga_tlv),
    289
    290SOC_SINGLE("RIN12 ZC Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
    291	WM8400_RI12ZC_SHIFT, 1, 0),
    292
    293SOC_SINGLE("RIN12 Mute Switch", WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
    294	WM8400_RI12MUTE_SHIFT, 1, 0),
    295
    296WM8400_OUTPGA_SINGLE_R_TLV("RIN34 Volume",
    297	WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
    298	WM8400_RIN34VOL_SHIFT,
    299	WM8400_RIN34VOL_MASK,
    300	0,
    301	in_pga_tlv),
    302
    303SOC_SINGLE("RIN34 ZC Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
    304	WM8400_RI34ZC_SHIFT, 1, 0),
    305
    306SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
    307	WM8400_RI34MUTE_SHIFT, 1, 0),
    308
    309};
    310
    311/*
    312 * _DAPM_ Controls
    313 */
    314
    315static int outmixer_event (struct snd_soc_dapm_widget *w,
    316	struct snd_kcontrol * kcontrol, int event)
    317{
    318	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
    319	struct soc_mixer_control *mc =
    320		(struct soc_mixer_control *)kcontrol->private_value;
    321	u32 reg_shift = mc->shift;
    322	int ret = 0;
    323	u16 reg;
    324
    325	switch (reg_shift) {
    326	case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
    327		reg = snd_soc_component_read(component, WM8400_OUTPUT_MIXER1);
    328		if (reg & WM8400_LDLO) {
    329			printk(KERN_WARNING
    330			"Cannot set as Output Mixer 1 LDLO Set\n");
    331			ret = -1;
    332		}
    333		break;
    334	case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
    335		reg = snd_soc_component_read(component, WM8400_OUTPUT_MIXER2);
    336		if (reg & WM8400_RDRO) {
    337			printk(KERN_WARNING
    338			"Cannot set as Output Mixer 2 RDRO Set\n");
    339			ret = -1;
    340		}
    341		break;
    342	case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
    343		reg = snd_soc_component_read(component, WM8400_SPEAKER_MIXER);
    344		if (reg & WM8400_LDSPK) {
    345			printk(KERN_WARNING
    346			"Cannot set as Speaker Mixer LDSPK Set\n");
    347			ret = -1;
    348		}
    349		break;
    350	case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
    351		reg = snd_soc_component_read(component, WM8400_SPEAKER_MIXER);
    352		if (reg & WM8400_RDSPK) {
    353			printk(KERN_WARNING
    354			"Cannot set as Speaker Mixer RDSPK Set\n");
    355			ret = -1;
    356		}
    357		break;
    358	}
    359
    360	return ret;
    361}
    362
    363/* INMIX dB values */
    364static const DECLARE_TLV_DB_SCALE(in_mix_tlv, -1200, 600, 0);
    365
    366/* Left In PGA Connections */
    367static const struct snd_kcontrol_new wm8400_dapm_lin12_pga_controls[] = {
    368SOC_DAPM_SINGLE("LIN1 Switch", WM8400_INPUT_MIXER2, WM8400_LMN1_SHIFT, 1, 0),
    369SOC_DAPM_SINGLE("LIN2 Switch", WM8400_INPUT_MIXER2, WM8400_LMP2_SHIFT, 1, 0),
    370};
    371
    372static const struct snd_kcontrol_new wm8400_dapm_lin34_pga_controls[] = {
    373SOC_DAPM_SINGLE("LIN3 Switch", WM8400_INPUT_MIXER2, WM8400_LMN3_SHIFT, 1, 0),
    374SOC_DAPM_SINGLE("LIN4 Switch", WM8400_INPUT_MIXER2, WM8400_LMP4_SHIFT, 1, 0),
    375};
    376
    377/* Right In PGA Connections */
    378static const struct snd_kcontrol_new wm8400_dapm_rin12_pga_controls[] = {
    379SOC_DAPM_SINGLE("RIN1 Switch", WM8400_INPUT_MIXER2, WM8400_RMN1_SHIFT, 1, 0),
    380SOC_DAPM_SINGLE("RIN2 Switch", WM8400_INPUT_MIXER2, WM8400_RMP2_SHIFT, 1, 0),
    381};
    382
    383static const struct snd_kcontrol_new wm8400_dapm_rin34_pga_controls[] = {
    384SOC_DAPM_SINGLE("RIN3 Switch", WM8400_INPUT_MIXER2, WM8400_RMN3_SHIFT, 1, 0),
    385SOC_DAPM_SINGLE("RIN4 Switch", WM8400_INPUT_MIXER2, WM8400_RMP4_SHIFT, 1, 0),
    386};
    387
    388/* INMIXL */
    389static const struct snd_kcontrol_new wm8400_dapm_inmixl_controls[] = {
    390SOC_DAPM_SINGLE_TLV("Record Left Volume", WM8400_INPUT_MIXER3,
    391	WM8400_LDBVOL_SHIFT, WM8400_LDBVOL_MASK, 0, in_mix_tlv),
    392SOC_DAPM_SINGLE_TLV("LIN2 Volume", WM8400_INPUT_MIXER5, WM8400_LI2BVOL_SHIFT,
    393	7, 0, in_mix_tlv),
    394SOC_DAPM_SINGLE("LINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
    395		1, 0),
    396SOC_DAPM_SINGLE("LINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
    397		1, 0),
    398};
    399
    400/* INMIXR */
    401static const struct snd_kcontrol_new wm8400_dapm_inmixr_controls[] = {
    402SOC_DAPM_SINGLE_TLV("Record Right Volume", WM8400_INPUT_MIXER4,
    403	WM8400_RDBVOL_SHIFT, WM8400_RDBVOL_MASK, 0, in_mix_tlv),
    404SOC_DAPM_SINGLE_TLV("RIN2 Volume", WM8400_INPUT_MIXER6, WM8400_RI2BVOL_SHIFT,
    405	7, 0, in_mix_tlv),
    406SOC_DAPM_SINGLE("RINPGA12 Switch", WM8400_INPUT_MIXER3, WM8400_L12MNB_SHIFT,
    407	1, 0),
    408SOC_DAPM_SINGLE("RINPGA34 Switch", WM8400_INPUT_MIXER3, WM8400_L34MNB_SHIFT,
    409	1, 0),
    410};
    411
    412/* AINLMUX */
    413static const char *wm8400_ainlmux[] =
    414	{"INMIXL Mix", "RXVOICE Mix", "DIFFINL Mix"};
    415
    416static SOC_ENUM_SINGLE_DECL(wm8400_ainlmux_enum,
    417			    WM8400_INPUT_MIXER1,
    418			    WM8400_AINLMODE_SHIFT,
    419			    wm8400_ainlmux);
    420
    421static const struct snd_kcontrol_new wm8400_dapm_ainlmux_controls =
    422SOC_DAPM_ENUM("Route", wm8400_ainlmux_enum);
    423
    424/* DIFFINL */
    425
    426/* AINRMUX */
    427static const char *wm8400_ainrmux[] =
    428	{"INMIXR Mix", "RXVOICE Mix", "DIFFINR Mix"};
    429
    430static SOC_ENUM_SINGLE_DECL(wm8400_ainrmux_enum,
    431			    WM8400_INPUT_MIXER1,
    432			    WM8400_AINRMODE_SHIFT,
    433			    wm8400_ainrmux);
    434
    435static const struct snd_kcontrol_new wm8400_dapm_ainrmux_controls =
    436SOC_DAPM_ENUM("Route", wm8400_ainrmux_enum);
    437
    438/* LOMIX */
    439static const struct snd_kcontrol_new wm8400_dapm_lomix_controls[] = {
    440SOC_DAPM_SINGLE("LOMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
    441	WM8400_LRBLO_SHIFT, 1, 0),
    442SOC_DAPM_SINGLE("LOMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER1,
    443	WM8400_LLBLO_SHIFT, 1, 0),
    444SOC_DAPM_SINGLE("LOMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
    445	WM8400_LRI3LO_SHIFT, 1, 0),
    446SOC_DAPM_SINGLE("LOMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER1,
    447	WM8400_LLI3LO_SHIFT, 1, 0),
    448SOC_DAPM_SINGLE("LOMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
    449	WM8400_LR12LO_SHIFT, 1, 0),
    450SOC_DAPM_SINGLE("LOMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER1,
    451	WM8400_LL12LO_SHIFT, 1, 0),
    452SOC_DAPM_SINGLE("LOMIX Left DAC Switch", WM8400_OUTPUT_MIXER1,
    453	WM8400_LDLO_SHIFT, 1, 0),
    454};
    455
    456/* ROMIX */
    457static const struct snd_kcontrol_new wm8400_dapm_romix_controls[] = {
    458SOC_DAPM_SINGLE("ROMIX Left ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
    459	WM8400_RLBRO_SHIFT, 1, 0),
    460SOC_DAPM_SINGLE("ROMIX Right ADC Bypass Switch", WM8400_OUTPUT_MIXER2,
    461	WM8400_RRBRO_SHIFT, 1, 0),
    462SOC_DAPM_SINGLE("ROMIX LIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
    463	WM8400_RLI3RO_SHIFT, 1, 0),
    464SOC_DAPM_SINGLE("ROMIX RIN3 Bypass Switch", WM8400_OUTPUT_MIXER2,
    465	WM8400_RRI3RO_SHIFT, 1, 0),
    466SOC_DAPM_SINGLE("ROMIX LIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
    467	WM8400_RL12RO_SHIFT, 1, 0),
    468SOC_DAPM_SINGLE("ROMIX RIN12 PGA Bypass Switch", WM8400_OUTPUT_MIXER2,
    469	WM8400_RR12RO_SHIFT, 1, 0),
    470SOC_DAPM_SINGLE("ROMIX Right DAC Switch", WM8400_OUTPUT_MIXER2,
    471	WM8400_RDRO_SHIFT, 1, 0),
    472};
    473
    474/* LONMIX */
    475static const struct snd_kcontrol_new wm8400_dapm_lonmix_controls[] = {
    476SOC_DAPM_SINGLE("LONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
    477	WM8400_LLOPGALON_SHIFT, 1, 0),
    478SOC_DAPM_SINGLE("LONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER1,
    479	WM8400_LROPGALON_SHIFT, 1, 0),
    480SOC_DAPM_SINGLE("LONMIX Inverted LOP Switch", WM8400_LINE_MIXER1,
    481	WM8400_LOPLON_SHIFT, 1, 0),
    482};
    483
    484/* LOPMIX */
    485static const struct snd_kcontrol_new wm8400_dapm_lopmix_controls[] = {
    486SOC_DAPM_SINGLE("LOPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER1,
    487	WM8400_LR12LOP_SHIFT, 1, 0),
    488SOC_DAPM_SINGLE("LOPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER1,
    489	WM8400_LL12LOP_SHIFT, 1, 0),
    490SOC_DAPM_SINGLE("LOPMIX Left Mixer PGA Switch", WM8400_LINE_MIXER1,
    491	WM8400_LLOPGALOP_SHIFT, 1, 0),
    492};
    493
    494/* RONMIX */
    495static const struct snd_kcontrol_new wm8400_dapm_ronmix_controls[] = {
    496SOC_DAPM_SINGLE("RONMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
    497	WM8400_RROPGARON_SHIFT, 1, 0),
    498SOC_DAPM_SINGLE("RONMIX Left Mixer PGA Switch", WM8400_LINE_MIXER2,
    499	WM8400_RLOPGARON_SHIFT, 1, 0),
    500SOC_DAPM_SINGLE("RONMIX Inverted ROP Switch", WM8400_LINE_MIXER2,
    501	WM8400_ROPRON_SHIFT, 1, 0),
    502};
    503
    504/* ROPMIX */
    505static const struct snd_kcontrol_new wm8400_dapm_ropmix_controls[] = {
    506SOC_DAPM_SINGLE("ROPMIX Left Mic Bypass Switch", WM8400_LINE_MIXER2,
    507	WM8400_RL12ROP_SHIFT, 1, 0),
    508SOC_DAPM_SINGLE("ROPMIX Right Mic Bypass Switch", WM8400_LINE_MIXER2,
    509	WM8400_RR12ROP_SHIFT, 1, 0),
    510SOC_DAPM_SINGLE("ROPMIX Right Mixer PGA Switch", WM8400_LINE_MIXER2,
    511	WM8400_RROPGAROP_SHIFT, 1, 0),
    512};
    513
    514/* OUT3MIX */
    515static const struct snd_kcontrol_new wm8400_dapm_out3mix_controls[] = {
    516SOC_DAPM_SINGLE("OUT3MIX LIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
    517	WM8400_LI4O3_SHIFT, 1, 0),
    518SOC_DAPM_SINGLE("OUT3MIX Left Out PGA Switch", WM8400_OUT3_4_MIXER,
    519	WM8400_LPGAO3_SHIFT, 1, 0),
    520};
    521
    522/* OUT4MIX */
    523static const struct snd_kcontrol_new wm8400_dapm_out4mix_controls[] = {
    524SOC_DAPM_SINGLE("OUT4MIX Right Out PGA Switch", WM8400_OUT3_4_MIXER,
    525	WM8400_RPGAO4_SHIFT, 1, 0),
    526SOC_DAPM_SINGLE("OUT4MIX RIN4/RXP Bypass Switch", WM8400_OUT3_4_MIXER,
    527	WM8400_RI4O4_SHIFT, 1, 0),
    528};
    529
    530/* SPKMIX */
    531static const struct snd_kcontrol_new wm8400_dapm_spkmix_controls[] = {
    532SOC_DAPM_SINGLE("SPKMIX LIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
    533	WM8400_LI2SPK_SHIFT, 1, 0),
    534SOC_DAPM_SINGLE("SPKMIX LADC Bypass Switch", WM8400_SPEAKER_MIXER,
    535	WM8400_LB2SPK_SHIFT, 1, 0),
    536SOC_DAPM_SINGLE("SPKMIX Left Mixer PGA Switch", WM8400_SPEAKER_MIXER,
    537	WM8400_LOPGASPK_SHIFT, 1, 0),
    538SOC_DAPM_SINGLE("SPKMIX Left DAC Switch", WM8400_SPEAKER_MIXER,
    539	WM8400_LDSPK_SHIFT, 1, 0),
    540SOC_DAPM_SINGLE("SPKMIX Right DAC Switch", WM8400_SPEAKER_MIXER,
    541	WM8400_RDSPK_SHIFT, 1, 0),
    542SOC_DAPM_SINGLE("SPKMIX Right Mixer PGA Switch", WM8400_SPEAKER_MIXER,
    543	WM8400_ROPGASPK_SHIFT, 1, 0),
    544SOC_DAPM_SINGLE("SPKMIX RADC Bypass Switch", WM8400_SPEAKER_MIXER,
    545	WM8400_RL12ROP_SHIFT, 1, 0),
    546SOC_DAPM_SINGLE("SPKMIX RIN2 Bypass Switch", WM8400_SPEAKER_MIXER,
    547	WM8400_RI2SPK_SHIFT, 1, 0),
    548};
    549
    550static const struct snd_soc_dapm_widget wm8400_dapm_widgets[] = {
    551/* Input Side */
    552/* Input Lines */
    553SND_SOC_DAPM_INPUT("LIN1"),
    554SND_SOC_DAPM_INPUT("LIN2"),
    555SND_SOC_DAPM_INPUT("LIN3"),
    556SND_SOC_DAPM_INPUT("LIN4/RXN"),
    557SND_SOC_DAPM_INPUT("RIN3"),
    558SND_SOC_DAPM_INPUT("RIN4/RXP"),
    559SND_SOC_DAPM_INPUT("RIN1"),
    560SND_SOC_DAPM_INPUT("RIN2"),
    561SND_SOC_DAPM_INPUT("Internal ADC Source"),
    562
    563/* DACs */
    564SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8400_POWER_MANAGEMENT_2,
    565	WM8400_ADCL_ENA_SHIFT, 0),
    566SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8400_POWER_MANAGEMENT_2,
    567	WM8400_ADCR_ENA_SHIFT, 0),
    568
    569/* Input PGAs */
    570SND_SOC_DAPM_MIXER("LIN12 PGA", WM8400_POWER_MANAGEMENT_2,
    571		   WM8400_LIN12_ENA_SHIFT,
    572		   0, &wm8400_dapm_lin12_pga_controls[0],
    573		   ARRAY_SIZE(wm8400_dapm_lin12_pga_controls)),
    574SND_SOC_DAPM_MIXER("LIN34 PGA", WM8400_POWER_MANAGEMENT_2,
    575		   WM8400_LIN34_ENA_SHIFT,
    576		   0, &wm8400_dapm_lin34_pga_controls[0],
    577		   ARRAY_SIZE(wm8400_dapm_lin34_pga_controls)),
    578SND_SOC_DAPM_MIXER("RIN12 PGA", WM8400_POWER_MANAGEMENT_2,
    579		   WM8400_RIN12_ENA_SHIFT,
    580		   0, &wm8400_dapm_rin12_pga_controls[0],
    581		   ARRAY_SIZE(wm8400_dapm_rin12_pga_controls)),
    582SND_SOC_DAPM_MIXER("RIN34 PGA", WM8400_POWER_MANAGEMENT_2,
    583		   WM8400_RIN34_ENA_SHIFT,
    584		   0, &wm8400_dapm_rin34_pga_controls[0],
    585		   ARRAY_SIZE(wm8400_dapm_rin34_pga_controls)),
    586
    587SND_SOC_DAPM_SUPPLY("INL", WM8400_POWER_MANAGEMENT_2, WM8400_AINL_ENA_SHIFT,
    588		    0, NULL, 0),
    589SND_SOC_DAPM_SUPPLY("INR", WM8400_POWER_MANAGEMENT_2, WM8400_AINR_ENA_SHIFT,
    590		    0, NULL, 0),
    591
    592/* INMIXL */
    593SND_SOC_DAPM_MIXER("INMIXL", SND_SOC_NOPM, 0, 0,
    594	&wm8400_dapm_inmixl_controls[0],
    595	ARRAY_SIZE(wm8400_dapm_inmixl_controls)),
    596
    597/* AINLMUX */
    598SND_SOC_DAPM_MUX("AILNMUX", SND_SOC_NOPM, 0, 0, &wm8400_dapm_ainlmux_controls),
    599
    600/* INMIXR */
    601SND_SOC_DAPM_MIXER("INMIXR", SND_SOC_NOPM, 0, 0,
    602	&wm8400_dapm_inmixr_controls[0],
    603	ARRAY_SIZE(wm8400_dapm_inmixr_controls)),
    604
    605/* AINRMUX */
    606SND_SOC_DAPM_MUX("AIRNMUX", SND_SOC_NOPM, 0, 0, &wm8400_dapm_ainrmux_controls),
    607
    608/* Output Side */
    609/* DACs */
    610SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8400_POWER_MANAGEMENT_3,
    611	WM8400_DACL_ENA_SHIFT, 0),
    612SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8400_POWER_MANAGEMENT_3,
    613	WM8400_DACR_ENA_SHIFT, 0),
    614
    615/* LOMIX */
    616SND_SOC_DAPM_MIXER_E("LOMIX", WM8400_POWER_MANAGEMENT_3,
    617		     WM8400_LOMIX_ENA_SHIFT,
    618		     0, &wm8400_dapm_lomix_controls[0],
    619		     ARRAY_SIZE(wm8400_dapm_lomix_controls),
    620		     outmixer_event, SND_SOC_DAPM_PRE_REG),
    621
    622/* LONMIX */
    623SND_SOC_DAPM_MIXER("LONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LON_ENA_SHIFT,
    624		   0, &wm8400_dapm_lonmix_controls[0],
    625		   ARRAY_SIZE(wm8400_dapm_lonmix_controls)),
    626
    627/* LOPMIX */
    628SND_SOC_DAPM_MIXER("LOPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_LOP_ENA_SHIFT,
    629		   0, &wm8400_dapm_lopmix_controls[0],
    630		   ARRAY_SIZE(wm8400_dapm_lopmix_controls)),
    631
    632/* OUT3MIX */
    633SND_SOC_DAPM_MIXER("OUT3MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT3_ENA_SHIFT,
    634		   0, &wm8400_dapm_out3mix_controls[0],
    635		   ARRAY_SIZE(wm8400_dapm_out3mix_controls)),
    636
    637/* SPKMIX */
    638SND_SOC_DAPM_MIXER_E("SPKMIX", WM8400_POWER_MANAGEMENT_1, WM8400_SPK_ENA_SHIFT,
    639		     0, &wm8400_dapm_spkmix_controls[0],
    640		     ARRAY_SIZE(wm8400_dapm_spkmix_controls), outmixer_event,
    641		     SND_SOC_DAPM_PRE_REG),
    642
    643/* OUT4MIX */
    644SND_SOC_DAPM_MIXER("OUT4MIX", WM8400_POWER_MANAGEMENT_1, WM8400_OUT4_ENA_SHIFT,
    645	0, &wm8400_dapm_out4mix_controls[0],
    646	ARRAY_SIZE(wm8400_dapm_out4mix_controls)),
    647
    648/* ROPMIX */
    649SND_SOC_DAPM_MIXER("ROPMIX", WM8400_POWER_MANAGEMENT_3, WM8400_ROP_ENA_SHIFT,
    650		   0, &wm8400_dapm_ropmix_controls[0],
    651		   ARRAY_SIZE(wm8400_dapm_ropmix_controls)),
    652
    653/* RONMIX */
    654SND_SOC_DAPM_MIXER("RONMIX", WM8400_POWER_MANAGEMENT_3, WM8400_RON_ENA_SHIFT,
    655		   0, &wm8400_dapm_ronmix_controls[0],
    656		   ARRAY_SIZE(wm8400_dapm_ronmix_controls)),
    657
    658/* ROMIX */
    659SND_SOC_DAPM_MIXER_E("ROMIX", WM8400_POWER_MANAGEMENT_3,
    660		     WM8400_ROMIX_ENA_SHIFT,
    661		     0, &wm8400_dapm_romix_controls[0],
    662		     ARRAY_SIZE(wm8400_dapm_romix_controls),
    663		     outmixer_event, SND_SOC_DAPM_PRE_REG),
    664
    665/* LOUT PGA */
    666SND_SOC_DAPM_PGA("LOUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_LOUT_ENA_SHIFT,
    667		 0, NULL, 0),
    668
    669/* ROUT PGA */
    670SND_SOC_DAPM_PGA("ROUT PGA", WM8400_POWER_MANAGEMENT_1, WM8400_ROUT_ENA_SHIFT,
    671		 0, NULL, 0),
    672
    673/* LOPGA */
    674SND_SOC_DAPM_PGA("LOPGA", WM8400_POWER_MANAGEMENT_3, WM8400_LOPGA_ENA_SHIFT, 0,
    675	NULL, 0),
    676
    677/* ROPGA */
    678SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0,
    679	NULL, 0),
    680
    681/* MICBIAS */
    682SND_SOC_DAPM_SUPPLY("MICBIAS", WM8400_POWER_MANAGEMENT_1,
    683		    WM8400_MIC1BIAS_ENA_SHIFT, 0, NULL, 0),
    684
    685SND_SOC_DAPM_OUTPUT("LON"),
    686SND_SOC_DAPM_OUTPUT("LOP"),
    687SND_SOC_DAPM_OUTPUT("OUT3"),
    688SND_SOC_DAPM_OUTPUT("LOUT"),
    689SND_SOC_DAPM_OUTPUT("SPKN"),
    690SND_SOC_DAPM_OUTPUT("SPKP"),
    691SND_SOC_DAPM_OUTPUT("ROUT"),
    692SND_SOC_DAPM_OUTPUT("OUT4"),
    693SND_SOC_DAPM_OUTPUT("ROP"),
    694SND_SOC_DAPM_OUTPUT("RON"),
    695
    696SND_SOC_DAPM_OUTPUT("Internal DAC Sink"),
    697};
    698
    699static const struct snd_soc_dapm_route wm8400_dapm_routes[] = {
    700	/* Make DACs turn on when playing even if not mixed into any outputs */
    701	{"Internal DAC Sink", NULL, "Left DAC"},
    702	{"Internal DAC Sink", NULL, "Right DAC"},
    703
    704	/* Make ADCs turn on when recording
    705	 * even if not mixed from any inputs */
    706	{"Left ADC", NULL, "Internal ADC Source"},
    707	{"Right ADC", NULL, "Internal ADC Source"},
    708
    709	/* Input Side */
    710	/* LIN12 PGA */
    711	{"LIN12 PGA", "LIN1 Switch", "LIN1"},
    712	{"LIN12 PGA", "LIN2 Switch", "LIN2"},
    713	/* LIN34 PGA */
    714	{"LIN34 PGA", "LIN3 Switch", "LIN3"},
    715	{"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
    716	/* INMIXL */
    717	{"INMIXL", NULL, "INL"},
    718	{"INMIXL", "Record Left Volume", "LOMIX"},
    719	{"INMIXL", "LIN2 Volume", "LIN2"},
    720	{"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
    721	{"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
    722	/* AILNMUX */
    723	{"AILNMUX", NULL, "INL"},
    724	{"AILNMUX", "INMIXL Mix", "INMIXL"},
    725	{"AILNMUX", "DIFFINL Mix", "LIN12 PGA"},
    726	{"AILNMUX", "DIFFINL Mix", "LIN34 PGA"},
    727	{"AILNMUX", "RXVOICE Mix", "LIN4/RXN"},
    728	{"AILNMUX", "RXVOICE Mix", "RIN4/RXP"},
    729	/* ADC */
    730	{"Left ADC", NULL, "AILNMUX"},
    731
    732	/* RIN12 PGA */
    733	{"RIN12 PGA", "RIN1 Switch", "RIN1"},
    734	{"RIN12 PGA", "RIN2 Switch", "RIN2"},
    735	/* RIN34 PGA */
    736	{"RIN34 PGA", "RIN3 Switch", "RIN3"},
    737	{"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
    738	/* INMIXR */
    739	{"INMIXR", NULL, "INR"},
    740	{"INMIXR", "Record Right Volume", "ROMIX"},
    741	{"INMIXR", "RIN2 Volume", "RIN2"},
    742	{"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
    743	{"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
    744	/* AIRNMUX */
    745	{"AIRNMUX", NULL, "INR"},
    746	{"AIRNMUX", "INMIXR Mix", "INMIXR"},
    747	{"AIRNMUX", "DIFFINR Mix", "RIN12 PGA"},
    748	{"AIRNMUX", "DIFFINR Mix", "RIN34 PGA"},
    749	{"AIRNMUX", "RXVOICE Mix", "LIN4/RXN"},
    750	{"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"},
    751	/* ADC */
    752	{"Right ADC", NULL, "AIRNMUX"},
    753
    754	/* LOMIX */
    755	{"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
    756	{"LOMIX", "LOMIX LIN3 Bypass Switch", "LIN3"},
    757	{"LOMIX", "LOMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
    758	{"LOMIX", "LOMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
    759	{"LOMIX", "LOMIX Right ADC Bypass Switch", "AIRNMUX"},
    760	{"LOMIX", "LOMIX Left ADC Bypass Switch", "AILNMUX"},
    761	{"LOMIX", "LOMIX Left DAC Switch", "Left DAC"},
    762
    763	/* ROMIX */
    764	{"ROMIX", "ROMIX RIN3 Bypass Switch", "RIN3"},
    765	{"ROMIX", "ROMIX LIN3 Bypass Switch", "LIN3"},
    766	{"ROMIX", "ROMIX LIN12 PGA Bypass Switch", "LIN12 PGA"},
    767	{"ROMIX", "ROMIX RIN12 PGA Bypass Switch", "RIN12 PGA"},
    768	{"ROMIX", "ROMIX Right ADC Bypass Switch", "AIRNMUX"},
    769	{"ROMIX", "ROMIX Left ADC Bypass Switch", "AILNMUX"},
    770	{"ROMIX", "ROMIX Right DAC Switch", "Right DAC"},
    771
    772	/* SPKMIX */
    773	{"SPKMIX", "SPKMIX LIN2 Bypass Switch", "LIN2"},
    774	{"SPKMIX", "SPKMIX RIN2 Bypass Switch", "RIN2"},
    775	{"SPKMIX", "SPKMIX LADC Bypass Switch", "AILNMUX"},
    776	{"SPKMIX", "SPKMIX RADC Bypass Switch", "AIRNMUX"},
    777	{"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"},
    778	{"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"},
    779	{"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"},
    780	{"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"},
    781
    782	/* LONMIX */
    783	{"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"},
    784	{"LONMIX", "LONMIX Right Mixer PGA Switch", "ROPGA"},
    785	{"LONMIX", "LONMIX Inverted LOP Switch", "LOPMIX"},
    786
    787	/* LOPMIX */
    788	{"LOPMIX", "LOPMIX Right Mic Bypass Switch", "RIN12 PGA"},
    789	{"LOPMIX", "LOPMIX Left Mic Bypass Switch", "LIN12 PGA"},
    790	{"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
    791
    792	/* OUT3MIX */
    793	{"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
    794	{"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
    795
    796	/* OUT4MIX */
    797	{"OUT4MIX", "OUT4MIX Right Out PGA Switch", "ROPGA"},
    798	{"OUT4MIX", "OUT4MIX RIN4/RXP Bypass Switch", "RIN4/RXP"},
    799
    800	/* RONMIX */
    801	{"RONMIX", "RONMIX Right Mixer PGA Switch", "ROPGA"},
    802	{"RONMIX", "RONMIX Left Mixer PGA Switch", "LOPGA"},
    803	{"RONMIX", "RONMIX Inverted ROP Switch", "ROPMIX"},
    804
    805	/* ROPMIX */
    806	{"ROPMIX", "ROPMIX Left Mic Bypass Switch", "LIN12 PGA"},
    807	{"ROPMIX", "ROPMIX Right Mic Bypass Switch", "RIN12 PGA"},
    808	{"ROPMIX", "ROPMIX Right Mixer PGA Switch", "ROPGA"},
    809
    810	/* Out Mixer PGAs */
    811	{"LOPGA", NULL, "LOMIX"},
    812	{"ROPGA", NULL, "ROMIX"},
    813
    814	{"LOUT PGA", NULL, "LOMIX"},
    815	{"ROUT PGA", NULL, "ROMIX"},
    816
    817	/* Output Pins */
    818	{"LON", NULL, "LONMIX"},
    819	{"LOP", NULL, "LOPMIX"},
    820	{"OUT3", NULL, "OUT3MIX"},
    821	{"LOUT", NULL, "LOUT PGA"},
    822	{"SPKN", NULL, "SPKMIX"},
    823	{"ROUT", NULL, "ROUT PGA"},
    824	{"OUT4", NULL, "OUT4MIX"},
    825	{"ROP", NULL, "ROPMIX"},
    826	{"RON", NULL, "RONMIX"},
    827};
    828
    829/*
    830 * Clock after FLL and dividers
    831 */
    832static int wm8400_set_dai_sysclk(struct snd_soc_dai *codec_dai,
    833		int clk_id, unsigned int freq, int dir)
    834{
    835	struct snd_soc_component *component = codec_dai->component;
    836	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
    837
    838	wm8400->sysclk = freq;
    839	return 0;
    840}
    841
    842struct fll_factors {
    843	u16 n;
    844	u16 k;
    845	u16 outdiv;
    846	u16 fratio;
    847	u16 freq_ref;
    848};
    849
    850#define FIXED_FLL_SIZE ((1 << 16) * 10)
    851
    852static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
    853		       unsigned int Fref, unsigned int Fout)
    854{
    855	u64 Kpart;
    856	unsigned int K, Nmod, target;
    857
    858	factors->outdiv = 2;
    859	while (Fout * factors->outdiv <  90000000 ||
    860	       Fout * factors->outdiv > 100000000) {
    861		factors->outdiv *= 2;
    862		if (factors->outdiv > 32) {
    863			dev_err(wm8400->wm8400->dev,
    864				"Unsupported FLL output frequency %uHz\n",
    865				Fout);
    866			return -EINVAL;
    867		}
    868	}
    869	target = Fout * factors->outdiv;
    870	factors->outdiv = factors->outdiv >> 2;
    871
    872	if (Fref < 48000)
    873		factors->freq_ref = 1;
    874	else
    875		factors->freq_ref = 0;
    876
    877	if (Fref < 1000000)
    878		factors->fratio = 9;
    879	else
    880		factors->fratio = 0;
    881
    882	/* Ensure we have a fractional part */
    883	do {
    884		if (Fref < 1000000)
    885			factors->fratio--;
    886		else
    887			factors->fratio++;
    888
    889		if (factors->fratio < 1 || factors->fratio > 8) {
    890			dev_err(wm8400->wm8400->dev,
    891				"Unable to calculate FRATIO\n");
    892			return -EINVAL;
    893		}
    894
    895		factors->n = target / (Fref * factors->fratio);
    896		Nmod = target % (Fref * factors->fratio);
    897	} while (Nmod == 0);
    898
    899	/* Calculate fractional part - scale up so we can round. */
    900	Kpart = FIXED_FLL_SIZE * (long long)Nmod;
    901
    902	do_div(Kpart, (Fref * factors->fratio));
    903
    904	K = Kpart & 0xFFFFFFFF;
    905
    906	if ((K % 10) >= 5)
    907		K += 5;
    908
    909	/* Move down to proper range now rounding is done */
    910	factors->k = K / 10;
    911
    912	dev_dbg(wm8400->wm8400->dev,
    913		"FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n",
    914		Fref, Fout,
    915		factors->n, factors->k, factors->fratio, factors->outdiv);
    916
    917	return 0;
    918}
    919
    920static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
    921			      int source, unsigned int freq_in,
    922			      unsigned int freq_out)
    923{
    924	struct snd_soc_component *component = codec_dai->component;
    925	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
    926	struct fll_factors factors;
    927	int ret;
    928	u16 reg;
    929
    930	if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
    931		return 0;
    932
    933	if (freq_out) {
    934		ret = fll_factors(wm8400, &factors, freq_in, freq_out);
    935		if (ret != 0)
    936			return ret;
    937	} else {
    938		/* Bodge GCC 4.4.0 uninitialised variable warning - it
    939		 * doesn't seem capable of working out that we exit if
    940		 * freq_out is 0 before any of the uses. */
    941		memset(&factors, 0, sizeof(factors));
    942	}
    943
    944	wm8400->fll_out = freq_out;
    945	wm8400->fll_in = freq_in;
    946
    947	/* We *must* disable the FLL before any changes */
    948	reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_2);
    949	reg &= ~WM8400_FLL_ENA;
    950	snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_2, reg);
    951
    952	reg = snd_soc_component_read(component, WM8400_FLL_CONTROL_1);
    953	reg &= ~WM8400_FLL_OSC_ENA;
    954	snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
    955
    956	if (!freq_out)
    957		return 0;
    958
    959	reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
    960	reg |= WM8400_FLL_FRAC | factors.fratio;
    961	reg |= factors.freq_ref << WM8400_FLL_REF_FREQ_SHIFT;
    962	snd_soc_component_write(component, WM8400_FLL_CONTROL_1, reg);
    963
    964	snd_soc_component_write(component, WM8400_FLL_CONTROL_2, factors.k);
    965	snd_soc_component_write(component, WM8400_FLL_CONTROL_3, factors.n);
    966
    967	reg = snd_soc_component_read(component, WM8400_FLL_CONTROL_4);
    968	reg &= ~WM8400_FLL_OUTDIV_MASK;
    969	reg |= factors.outdiv;
    970	snd_soc_component_write(component, WM8400_FLL_CONTROL_4, reg);
    971
    972	return 0;
    973}
    974
    975/*
    976 * Sets ADC and Voice DAC format.
    977 */
    978static int wm8400_set_dai_fmt(struct snd_soc_dai *codec_dai,
    979		unsigned int fmt)
    980{
    981	struct snd_soc_component *component = codec_dai->component;
    982	u16 audio1, audio3;
    983
    984	audio1 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_1);
    985	audio3 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_3);
    986
    987	/* set master/slave audio interface */
    988	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    989	case SND_SOC_DAIFMT_CBS_CFS:
    990		audio3 &= ~WM8400_AIF_MSTR1;
    991		break;
    992	case SND_SOC_DAIFMT_CBM_CFM:
    993		audio3 |= WM8400_AIF_MSTR1;
    994		break;
    995	default:
    996		return -EINVAL;
    997	}
    998
    999	audio1 &= ~WM8400_AIF_FMT_MASK;
   1000
   1001	/* interface format */
   1002	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
   1003	case SND_SOC_DAIFMT_I2S:
   1004		audio1 |= WM8400_AIF_FMT_I2S;
   1005		audio1 &= ~WM8400_AIF_LRCLK_INV;
   1006		break;
   1007	case SND_SOC_DAIFMT_RIGHT_J:
   1008		audio1 |= WM8400_AIF_FMT_RIGHTJ;
   1009		audio1 &= ~WM8400_AIF_LRCLK_INV;
   1010		break;
   1011	case SND_SOC_DAIFMT_LEFT_J:
   1012		audio1 |= WM8400_AIF_FMT_LEFTJ;
   1013		audio1 &= ~WM8400_AIF_LRCLK_INV;
   1014		break;
   1015	case SND_SOC_DAIFMT_DSP_A:
   1016		audio1 |= WM8400_AIF_FMT_DSP;
   1017		audio1 &= ~WM8400_AIF_LRCLK_INV;
   1018		break;
   1019	case SND_SOC_DAIFMT_DSP_B:
   1020		audio1 |= WM8400_AIF_FMT_DSP | WM8400_AIF_LRCLK_INV;
   1021		break;
   1022	default:
   1023		return -EINVAL;
   1024	}
   1025
   1026	snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
   1027	snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_3, audio3);
   1028	return 0;
   1029}
   1030
   1031static int wm8400_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
   1032		int div_id, int div)
   1033{
   1034	struct snd_soc_component *component = codec_dai->component;
   1035	u16 reg;
   1036
   1037	switch (div_id) {
   1038	case WM8400_MCLK_DIV:
   1039		reg = snd_soc_component_read(component, WM8400_CLOCKING_2) &
   1040			~WM8400_MCLK_DIV_MASK;
   1041		snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
   1042		break;
   1043	case WM8400_DACCLK_DIV:
   1044		reg = snd_soc_component_read(component, WM8400_CLOCKING_2) &
   1045			~WM8400_DAC_CLKDIV_MASK;
   1046		snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
   1047		break;
   1048	case WM8400_ADCCLK_DIV:
   1049		reg = snd_soc_component_read(component, WM8400_CLOCKING_2) &
   1050			~WM8400_ADC_CLKDIV_MASK;
   1051		snd_soc_component_write(component, WM8400_CLOCKING_2, reg | div);
   1052		break;
   1053	case WM8400_BCLK_DIV:
   1054		reg = snd_soc_component_read(component, WM8400_CLOCKING_1) &
   1055			~WM8400_BCLK_DIV_MASK;
   1056		snd_soc_component_write(component, WM8400_CLOCKING_1, reg | div);
   1057		break;
   1058	default:
   1059		return -EINVAL;
   1060	}
   1061
   1062	return 0;
   1063}
   1064
   1065/*
   1066 * Set PCM DAI bit size and sample rate.
   1067 */
   1068static int wm8400_hw_params(struct snd_pcm_substream *substream,
   1069	struct snd_pcm_hw_params *params,
   1070	struct snd_soc_dai *dai)
   1071{
   1072	struct snd_soc_component *component = dai->component;
   1073	u16 audio1 = snd_soc_component_read(component, WM8400_AUDIO_INTERFACE_1);
   1074
   1075	audio1 &= ~WM8400_AIF_WL_MASK;
   1076	/* bit size */
   1077	switch (params_width(params)) {
   1078	case 16:
   1079		break;
   1080	case 20:
   1081		audio1 |= WM8400_AIF_WL_20BITS;
   1082		break;
   1083	case 24:
   1084		audio1 |= WM8400_AIF_WL_24BITS;
   1085		break;
   1086	case 32:
   1087		audio1 |= WM8400_AIF_WL_32BITS;
   1088		break;
   1089	}
   1090
   1091	snd_soc_component_write(component, WM8400_AUDIO_INTERFACE_1, audio1);
   1092	return 0;
   1093}
   1094
   1095static int wm8400_mute(struct snd_soc_dai *dai, int mute, int direction)
   1096{
   1097	struct snd_soc_component *component = dai->component;
   1098	u16 val = snd_soc_component_read(component, WM8400_DAC_CTRL) & ~WM8400_DAC_MUTE;
   1099
   1100	if (mute)
   1101		snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
   1102	else
   1103		snd_soc_component_write(component, WM8400_DAC_CTRL, val);
   1104
   1105	return 0;
   1106}
   1107
   1108/* TODO: set bias for best performance at standby */
   1109static int wm8400_set_bias_level(struct snd_soc_component *component,
   1110				 enum snd_soc_bias_level level)
   1111{
   1112	struct wm8400_priv *wm8400 = snd_soc_component_get_drvdata(component);
   1113	u16 val;
   1114	int ret;
   1115
   1116	switch (level) {
   1117	case SND_SOC_BIAS_ON:
   1118		break;
   1119
   1120	case SND_SOC_BIAS_PREPARE:
   1121		/* VMID=2*50k */
   1122		val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1) &
   1123			~WM8400_VMID_MODE_MASK;
   1124		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x2);
   1125		break;
   1126
   1127	case SND_SOC_BIAS_STANDBY:
   1128		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
   1129			ret = regulator_bulk_enable(ARRAY_SIZE(power),
   1130						    &power[0]);
   1131			if (ret != 0) {
   1132				dev_err(wm8400->wm8400->dev,
   1133					"Failed to enable regulators: %d\n",
   1134					ret);
   1135				return ret;
   1136			}
   1137
   1138			snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
   1139				     WM8400_CODEC_ENA | WM8400_SYSCLK_ENA);
   1140
   1141			/* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
   1142			snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
   1143				     WM8400_BUFDCOPEN | WM8400_POBCTRL);
   1144
   1145			msleep(50);
   1146
   1147			/* Enable VREF & VMID at 2x50k */
   1148			val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
   1149			val |= 0x2 | WM8400_VREF_ENA;
   1150			snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
   1151
   1152			/* Enable BUFIOEN */
   1153			snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
   1154				     WM8400_BUFDCOPEN | WM8400_POBCTRL |
   1155				     WM8400_BUFIOEN);
   1156
   1157			/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
   1158			snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_BUFIOEN);
   1159		}
   1160
   1161		/* VMID=2*300k */
   1162		val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1) &
   1163			~WM8400_VMID_MODE_MASK;
   1164		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val | 0x4);
   1165		break;
   1166
   1167	case SND_SOC_BIAS_OFF:
   1168		/* Enable POBCTRL and SOFT_ST */
   1169		snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
   1170			WM8400_POBCTRL | WM8400_BUFIOEN);
   1171
   1172		/* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
   1173		snd_soc_component_write(component, WM8400_ANTIPOP2, WM8400_SOFTST |
   1174			WM8400_BUFDCOPEN | WM8400_POBCTRL |
   1175			WM8400_BUFIOEN);
   1176
   1177		/* mute DAC */
   1178		val = snd_soc_component_read(component, WM8400_DAC_CTRL);
   1179		snd_soc_component_write(component, WM8400_DAC_CTRL, val | WM8400_DAC_MUTE);
   1180
   1181		/* Enable any disabled outputs */
   1182		val = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
   1183		val |= WM8400_SPK_ENA | WM8400_OUT3_ENA |
   1184			WM8400_OUT4_ENA | WM8400_LOUT_ENA |
   1185			WM8400_ROUT_ENA;
   1186		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
   1187
   1188		/* Disable VMID */
   1189		val &= ~WM8400_VMID_MODE_MASK;
   1190		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
   1191
   1192		msleep(300);
   1193
   1194		/* Enable all output discharge bits */
   1195		snd_soc_component_write(component, WM8400_ANTIPOP1, WM8400_DIS_LLINE |
   1196			WM8400_DIS_RLINE | WM8400_DIS_OUT3 |
   1197			WM8400_DIS_OUT4 | WM8400_DIS_LOUT |
   1198			WM8400_DIS_ROUT);
   1199
   1200		/* Disable VREF */
   1201		val &= ~WM8400_VREF_ENA;
   1202		snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, val);
   1203
   1204		/* disable POBCTRL, SOFT_ST and BUFDCOPEN */
   1205		snd_soc_component_write(component, WM8400_ANTIPOP2, 0x0);
   1206
   1207		ret = regulator_bulk_disable(ARRAY_SIZE(power),
   1208					     &power[0]);
   1209		if (ret != 0)
   1210			return ret;
   1211
   1212		break;
   1213	}
   1214
   1215	return 0;
   1216}
   1217
   1218#define WM8400_RATES SNDRV_PCM_RATE_8000_96000
   1219
   1220#define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
   1221	SNDRV_PCM_FMTBIT_S24_LE)
   1222
   1223static const struct snd_soc_dai_ops wm8400_dai_ops = {
   1224	.hw_params = wm8400_hw_params,
   1225	.mute_stream = wm8400_mute,
   1226	.set_fmt = wm8400_set_dai_fmt,
   1227	.set_clkdiv = wm8400_set_dai_clkdiv,
   1228	.set_sysclk = wm8400_set_dai_sysclk,
   1229	.set_pll = wm8400_set_dai_pll,
   1230	.no_capture_mute = 1,
   1231};
   1232
   1233/*
   1234 * The WM8400 supports 2 different and mutually exclusive DAI
   1235 * configurations.
   1236 *
   1237 * 1. ADC/DAC on Primary Interface
   1238 * 2. ADC on Primary Interface/DAC on secondary
   1239 */
   1240static struct snd_soc_dai_driver wm8400_dai = {
   1241/* ADC/DAC on primary */
   1242	.name = "wm8400-hifi",
   1243	.playback = {
   1244		.stream_name = "Playback",
   1245		.channels_min = 1,
   1246		.channels_max = 2,
   1247		.rates = WM8400_RATES,
   1248		.formats = WM8400_FORMATS,
   1249	},
   1250	.capture = {
   1251		.stream_name = "Capture",
   1252		.channels_min = 1,
   1253		.channels_max = 2,
   1254		.rates = WM8400_RATES,
   1255		.formats = WM8400_FORMATS,
   1256	},
   1257	.ops = &wm8400_dai_ops,
   1258};
   1259
   1260static int wm8400_component_probe(struct snd_soc_component *component)
   1261{
   1262	struct wm8400 *wm8400 = dev_get_platdata(component->dev);
   1263	struct wm8400_priv *priv;
   1264	int ret;
   1265	u16 reg;
   1266
   1267	priv = devm_kzalloc(component->dev, sizeof(struct wm8400_priv),
   1268			    GFP_KERNEL);
   1269	if (priv == NULL)
   1270		return -ENOMEM;
   1271
   1272	snd_soc_component_init_regmap(component, wm8400->regmap);
   1273	snd_soc_component_set_drvdata(component, priv);
   1274	priv->wm8400 = wm8400;
   1275
   1276	ret = devm_regulator_bulk_get(wm8400->dev,
   1277				 ARRAY_SIZE(power), &power[0]);
   1278	if (ret != 0) {
   1279		dev_err(component->dev, "Failed to get regulators: %d\n", ret);
   1280		return ret;
   1281	}
   1282
   1283	wm8400_component_reset(component);
   1284
   1285	reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
   1286	snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1, reg | WM8400_CODEC_ENA);
   1287
   1288	/* Latch volume update bits */
   1289	reg = snd_soc_component_read(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME);
   1290	snd_soc_component_write(component, WM8400_LEFT_LINE_INPUT_1_2_VOLUME,
   1291		     reg & WM8400_IPVU);
   1292	reg = snd_soc_component_read(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME);
   1293	snd_soc_component_write(component, WM8400_RIGHT_LINE_INPUT_1_2_VOLUME,
   1294		     reg & WM8400_IPVU);
   1295
   1296	snd_soc_component_write(component, WM8400_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
   1297	snd_soc_component_write(component, WM8400_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
   1298
   1299	return 0;
   1300}
   1301
   1302static void  wm8400_component_remove(struct snd_soc_component *component)
   1303{
   1304	u16 reg;
   1305
   1306	reg = snd_soc_component_read(component, WM8400_POWER_MANAGEMENT_1);
   1307	snd_soc_component_write(component, WM8400_POWER_MANAGEMENT_1,
   1308		     reg & (~WM8400_CODEC_ENA));
   1309}
   1310
   1311static const struct snd_soc_component_driver soc_component_dev_wm8400 = {
   1312	.probe			= wm8400_component_probe,
   1313	.remove			= wm8400_component_remove,
   1314	.set_bias_level		= wm8400_set_bias_level,
   1315	.controls		= wm8400_snd_controls,
   1316	.num_controls		= ARRAY_SIZE(wm8400_snd_controls),
   1317	.dapm_widgets		= wm8400_dapm_widgets,
   1318	.num_dapm_widgets	= ARRAY_SIZE(wm8400_dapm_widgets),
   1319	.dapm_routes		= wm8400_dapm_routes,
   1320	.num_dapm_routes	= ARRAY_SIZE(wm8400_dapm_routes),
   1321	.suspend_bias_off	= 1,
   1322	.idle_bias_on		= 1,
   1323	.use_pmdown_time	= 1,
   1324	.endianness		= 1,
   1325	.non_legacy_dai_naming	= 1,
   1326};
   1327
   1328static int wm8400_probe(struct platform_device *pdev)
   1329{
   1330	return devm_snd_soc_register_component(&pdev->dev,
   1331			&soc_component_dev_wm8400,
   1332			&wm8400_dai, 1);
   1333}
   1334
   1335static struct platform_driver wm8400_codec_driver = {
   1336	.driver = {
   1337		   .name = "wm8400-codec",
   1338		   },
   1339	.probe = wm8400_probe,
   1340};
   1341
   1342module_platform_driver(wm8400_codec_driver);
   1343
   1344MODULE_DESCRIPTION("ASoC WM8400 driver");
   1345MODULE_AUTHOR("Mark Brown");
   1346MODULE_LICENSE("GPL");
   1347MODULE_ALIAS("platform:wm8400-codec");