1*40e0aa64SRichard Purdie /* 2*40e0aa64SRichard Purdie * wm8731.c -- WM8731 ALSA SoC Audio driver 3*40e0aa64SRichard Purdie * 4*40e0aa64SRichard Purdie * Copyright 2005 Openedhand Ltd. 5*40e0aa64SRichard Purdie * 6*40e0aa64SRichard Purdie * Author: Richard Purdie <richard@openedhand.com> 7*40e0aa64SRichard Purdie * 8*40e0aa64SRichard Purdie * Based on wm8753.c by Liam Girdwood 9*40e0aa64SRichard Purdie * 10*40e0aa64SRichard Purdie * This program is free software; you can redistribute it and/or modify 11*40e0aa64SRichard Purdie * it under the terms of the GNU General Public License version 2 as 12*40e0aa64SRichard Purdie * published by the Free Software Foundation. 13*40e0aa64SRichard Purdie */ 14*40e0aa64SRichard Purdie 15*40e0aa64SRichard Purdie #include <linux/module.h> 16*40e0aa64SRichard Purdie #include <linux/moduleparam.h> 17*40e0aa64SRichard Purdie #include <linux/init.h> 18*40e0aa64SRichard Purdie #include <linux/delay.h> 19*40e0aa64SRichard Purdie #include <linux/pm.h> 20*40e0aa64SRichard Purdie #include <linux/i2c.h> 21*40e0aa64SRichard Purdie #include <linux/platform_device.h> 22*40e0aa64SRichard Purdie #include <sound/driver.h> 23*40e0aa64SRichard Purdie #include <sound/core.h> 24*40e0aa64SRichard Purdie #include <sound/pcm.h> 25*40e0aa64SRichard Purdie #include <sound/pcm_params.h> 26*40e0aa64SRichard Purdie #include <sound/soc.h> 27*40e0aa64SRichard Purdie #include <sound/soc-dapm.h> 28*40e0aa64SRichard Purdie #include <sound/initval.h> 29*40e0aa64SRichard Purdie 30*40e0aa64SRichard Purdie #include "wm8731.h" 31*40e0aa64SRichard Purdie 32*40e0aa64SRichard Purdie #define AUDIO_NAME "wm8731" 33*40e0aa64SRichard Purdie #define WM8731_VERSION "0.12" 34*40e0aa64SRichard Purdie 35*40e0aa64SRichard Purdie /* 36*40e0aa64SRichard Purdie * Debug 37*40e0aa64SRichard Purdie */ 38*40e0aa64SRichard Purdie 39*40e0aa64SRichard Purdie #define WM8731_DEBUG 0 40*40e0aa64SRichard Purdie 41*40e0aa64SRichard Purdie #ifdef WM8731_DEBUG 42*40e0aa64SRichard Purdie #define dbg(format, arg...) \ 43*40e0aa64SRichard Purdie printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg) 44*40e0aa64SRichard Purdie #else 45*40e0aa64SRichard Purdie #define dbg(format, arg...) do {} while (0) 46*40e0aa64SRichard Purdie #endif 47*40e0aa64SRichard Purdie #define err(format, arg...) \ 48*40e0aa64SRichard Purdie printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) 49*40e0aa64SRichard Purdie #define info(format, arg...) \ 50*40e0aa64SRichard Purdie printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) 51*40e0aa64SRichard Purdie #define warn(format, arg...) \ 52*40e0aa64SRichard Purdie printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) 53*40e0aa64SRichard Purdie 54*40e0aa64SRichard Purdie struct snd_soc_codec_device soc_codec_dev_wm8731; 55*40e0aa64SRichard Purdie 56*40e0aa64SRichard Purdie /* 57*40e0aa64SRichard Purdie * wm8731 register cache 58*40e0aa64SRichard Purdie * We can't read the WM8731 register space when we are 59*40e0aa64SRichard Purdie * using 2 wire for device control, so we cache them instead. 60*40e0aa64SRichard Purdie * There is no point in caching the reset register 61*40e0aa64SRichard Purdie */ 62*40e0aa64SRichard Purdie static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 63*40e0aa64SRichard Purdie 0x0097, 0x0097, 0x0079, 0x0079, 64*40e0aa64SRichard Purdie 0x000a, 0x0008, 0x009f, 0x000a, 65*40e0aa64SRichard Purdie 0x0000, 0x0000 66*40e0aa64SRichard Purdie }; 67*40e0aa64SRichard Purdie 68*40e0aa64SRichard Purdie #define WM8731_DAIFMT \ 69*40e0aa64SRichard Purdie (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_RIGHT_J | \ 70*40e0aa64SRichard Purdie SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_IB_NF | \ 71*40e0aa64SRichard Purdie SND_SOC_DAIFMT_IB_IF) 72*40e0aa64SRichard Purdie 73*40e0aa64SRichard Purdie #define WM8731_DIR \ 74*40e0aa64SRichard Purdie (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) 75*40e0aa64SRichard Purdie 76*40e0aa64SRichard Purdie #define WM8731_RATES \ 77*40e0aa64SRichard Purdie (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ 78*40e0aa64SRichard Purdie SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 79*40e0aa64SRichard Purdie SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 80*40e0aa64SRichard Purdie 81*40e0aa64SRichard Purdie #define WM8731_HIFI_BITS \ 82*40e0aa64SRichard Purdie (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 83*40e0aa64SRichard Purdie SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 84*40e0aa64SRichard Purdie 85*40e0aa64SRichard Purdie static struct snd_soc_dai_mode wm8731_modes[] = { 86*40e0aa64SRichard Purdie /* codec frame and clock master modes */ 87*40e0aa64SRichard Purdie /* 8k */ 88*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 89*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_8000, WM8731_DIR, 0, 90*40e0aa64SRichard Purdie 1536, SND_SOC_FSB(64)}, 91*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 92*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_8000, WM8731_DIR, 0, 93*40e0aa64SRichard Purdie 2304, SND_SOC_FSB(64)}, 94*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 95*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_8000, WM8731_DIR, 0, 96*40e0aa64SRichard Purdie 1408, SND_SOC_FSB(64)}, 97*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 98*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_8000, WM8731_DIR, 0, 99*40e0aa64SRichard Purdie 2112, SND_SOC_FSB(64)}, 100*40e0aa64SRichard Purdie 101*40e0aa64SRichard Purdie /* 32k */ 102*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 103*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_32000, WM8731_DIR, 0, 104*40e0aa64SRichard Purdie 384, SND_SOC_FSB(64)}, 105*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 106*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_32000, WM8731_DIR, 0, 107*40e0aa64SRichard Purdie 576, SND_SOC_FSB(64)}, 108*40e0aa64SRichard Purdie 109*40e0aa64SRichard Purdie /* 44.1k & 48k */ 110*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 111*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 112*40e0aa64SRichard Purdie WM8731_DIR, 0, 256, SND_SOC_FSB(64)}, 113*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 114*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 115*40e0aa64SRichard Purdie WM8731_DIR, 0, 384, SND_SOC_FSB(64)}, 116*40e0aa64SRichard Purdie 117*40e0aa64SRichard Purdie /* 88.2 & 96k */ 118*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 119*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, 120*40e0aa64SRichard Purdie WM8731_DIR, 0, 128, SND_SOC_FSB(64)}, 121*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 122*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, 123*40e0aa64SRichard Purdie WM8731_DIR, 0, 192, SND_SOC_FSB(64)}, 124*40e0aa64SRichard Purdie 125*40e0aa64SRichard Purdie 126*40e0aa64SRichard Purdie /* USB codec frame and clock master modes */ 127*40e0aa64SRichard Purdie /* 8k */ 128*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 129*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_8000, WM8731_DIR, 130*40e0aa64SRichard Purdie SND_SOC_DAI_BFS_DIV, 1500, SND_SOC_FSBD(1)}, 131*40e0aa64SRichard Purdie 132*40e0aa64SRichard Purdie /* 44.1k */ 133*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 134*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_44100, WM8731_DIR, 135*40e0aa64SRichard Purdie SND_SOC_DAI_BFS_DIV, 272, SND_SOC_FSBD(1)}, 136*40e0aa64SRichard Purdie 137*40e0aa64SRichard Purdie /* 48k */ 138*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 139*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_48000, WM8731_DIR, 140*40e0aa64SRichard Purdie SND_SOC_DAI_BFS_DIV, 250, SND_SOC_FSBD(1)}, 141*40e0aa64SRichard Purdie 142*40e0aa64SRichard Purdie /* 88.2k */ 143*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 144*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_88200, WM8731_DIR, 145*40e0aa64SRichard Purdie SND_SOC_DAI_BFS_DIV, 136, SND_SOC_FSBD(1)}, 146*40e0aa64SRichard Purdie 147*40e0aa64SRichard Purdie /* 96k */ 148*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAITDM_LRDW(0,0), 149*40e0aa64SRichard Purdie WM8731_HIFI_BITS, SNDRV_PCM_RATE_96000, WM8731_DIR, 150*40e0aa64SRichard Purdie SND_SOC_DAI_BFS_DIV, 125, SND_SOC_FSBD(1)}, 151*40e0aa64SRichard Purdie 152*40e0aa64SRichard Purdie /* codec frame and clock slave modes */ 153*40e0aa64SRichard Purdie {WM8731_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAITDM_LRDW(0,0), 154*40e0aa64SRichard Purdie WM8731_HIFI_BITS, WM8731_RATES, WM8731_DIR, SND_SOC_DAI_BFS_DIV, 155*40e0aa64SRichard Purdie SND_SOC_FS_ALL, SND_SOC_FSBD_ALL}, 156*40e0aa64SRichard Purdie }; 157*40e0aa64SRichard Purdie 158*40e0aa64SRichard Purdie /* 159*40e0aa64SRichard Purdie * read wm8731 register cache 160*40e0aa64SRichard Purdie */ 161*40e0aa64SRichard Purdie static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec, 162*40e0aa64SRichard Purdie unsigned int reg) 163*40e0aa64SRichard Purdie { 164*40e0aa64SRichard Purdie u16 *cache = codec->reg_cache; 165*40e0aa64SRichard Purdie if (reg == WM8731_RESET) 166*40e0aa64SRichard Purdie return 0; 167*40e0aa64SRichard Purdie if (reg >= WM8731_CACHEREGNUM) 168*40e0aa64SRichard Purdie return -1; 169*40e0aa64SRichard Purdie return cache[reg]; 170*40e0aa64SRichard Purdie } 171*40e0aa64SRichard Purdie 172*40e0aa64SRichard Purdie /* 173*40e0aa64SRichard Purdie * write wm8731 register cache 174*40e0aa64SRichard Purdie */ 175*40e0aa64SRichard Purdie static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec, 176*40e0aa64SRichard Purdie u16 reg, unsigned int value) 177*40e0aa64SRichard Purdie { 178*40e0aa64SRichard Purdie u16 *cache = codec->reg_cache; 179*40e0aa64SRichard Purdie if (reg >= WM8731_CACHEREGNUM) 180*40e0aa64SRichard Purdie return; 181*40e0aa64SRichard Purdie cache[reg] = value; 182*40e0aa64SRichard Purdie } 183*40e0aa64SRichard Purdie 184*40e0aa64SRichard Purdie /* 185*40e0aa64SRichard Purdie * write to the WM8731 register space 186*40e0aa64SRichard Purdie */ 187*40e0aa64SRichard Purdie static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg, 188*40e0aa64SRichard Purdie unsigned int value) 189*40e0aa64SRichard Purdie { 190*40e0aa64SRichard Purdie u8 data[2]; 191*40e0aa64SRichard Purdie 192*40e0aa64SRichard Purdie /* data is 193*40e0aa64SRichard Purdie * D15..D9 WM8731 register offset 194*40e0aa64SRichard Purdie * D8...D0 register data 195*40e0aa64SRichard Purdie */ 196*40e0aa64SRichard Purdie data[0] = (reg << 1) | ((value >> 8) & 0x0001); 197*40e0aa64SRichard Purdie data[1] = value & 0x00ff; 198*40e0aa64SRichard Purdie 199*40e0aa64SRichard Purdie wm8731_write_reg_cache (codec, reg, value); 200*40e0aa64SRichard Purdie if (codec->hw_write(codec->control_data, data, 2) == 2) 201*40e0aa64SRichard Purdie return 0; 202*40e0aa64SRichard Purdie else 203*40e0aa64SRichard Purdie return -EIO; 204*40e0aa64SRichard Purdie } 205*40e0aa64SRichard Purdie 206*40e0aa64SRichard Purdie #define wm8731_reset(c) wm8731_write(c, WM8731_RESET, 0) 207*40e0aa64SRichard Purdie 208*40e0aa64SRichard Purdie static const char *wm8731_input_select[] = {"Line In", "Mic"}; 209*40e0aa64SRichard Purdie static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 210*40e0aa64SRichard Purdie 211*40e0aa64SRichard Purdie static const struct soc_enum wm8731_enum[] = { 212*40e0aa64SRichard Purdie SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select), 213*40e0aa64SRichard Purdie SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), 214*40e0aa64SRichard Purdie }; 215*40e0aa64SRichard Purdie 216*40e0aa64SRichard Purdie static const struct snd_kcontrol_new wm8731_snd_controls[] = { 217*40e0aa64SRichard Purdie 218*40e0aa64SRichard Purdie SOC_DOUBLE_R("Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, 0, 127, 0), 219*40e0aa64SRichard Purdie SOC_DOUBLE_R("Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V, 7, 1, 0), 220*40e0aa64SRichard Purdie 221*40e0aa64SRichard Purdie SOC_DOUBLE_R("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0), 222*40e0aa64SRichard Purdie SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), 223*40e0aa64SRichard Purdie 224*40e0aa64SRichard Purdie SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), 225*40e0aa64SRichard Purdie SOC_SINGLE("Capture Mic Switch", WM8731_APANA, 1, 1, 1), 226*40e0aa64SRichard Purdie 227*40e0aa64SRichard Purdie SOC_SINGLE("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1), 228*40e0aa64SRichard Purdie 229*40e0aa64SRichard Purdie SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 230*40e0aa64SRichard Purdie SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 231*40e0aa64SRichard Purdie 232*40e0aa64SRichard Purdie SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), 233*40e0aa64SRichard Purdie }; 234*40e0aa64SRichard Purdie 235*40e0aa64SRichard Purdie /* add non dapm controls */ 236*40e0aa64SRichard Purdie static int wm8731_add_controls(struct snd_soc_codec *codec) 237*40e0aa64SRichard Purdie { 238*40e0aa64SRichard Purdie int err, i; 239*40e0aa64SRichard Purdie 240*40e0aa64SRichard Purdie for (i = 0; i < ARRAY_SIZE(wm8731_snd_controls); i++) { 241*40e0aa64SRichard Purdie if ((err = snd_ctl_add(codec->card, 242*40e0aa64SRichard Purdie snd_soc_cnew(&wm8731_snd_controls[i],codec, NULL))) < 0) 243*40e0aa64SRichard Purdie return err; 244*40e0aa64SRichard Purdie } 245*40e0aa64SRichard Purdie 246*40e0aa64SRichard Purdie return 0; 247*40e0aa64SRichard Purdie } 248*40e0aa64SRichard Purdie 249*40e0aa64SRichard Purdie /* Output Mixer */ 250*40e0aa64SRichard Purdie static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { 251*40e0aa64SRichard Purdie SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), 252*40e0aa64SRichard Purdie SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), 253*40e0aa64SRichard Purdie SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), 254*40e0aa64SRichard Purdie }; 255*40e0aa64SRichard Purdie 256*40e0aa64SRichard Purdie /* Input mux */ 257*40e0aa64SRichard Purdie static const struct snd_kcontrol_new wm8731_input_mux_controls = 258*40e0aa64SRichard Purdie SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); 259*40e0aa64SRichard Purdie 260*40e0aa64SRichard Purdie static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { 261*40e0aa64SRichard Purdie SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, 262*40e0aa64SRichard Purdie &wm8731_output_mixer_controls[0], 263*40e0aa64SRichard Purdie ARRAY_SIZE(wm8731_output_mixer_controls)), 264*40e0aa64SRichard Purdie SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1), 265*40e0aa64SRichard Purdie SND_SOC_DAPM_OUTPUT("LOUT"), 266*40e0aa64SRichard Purdie SND_SOC_DAPM_OUTPUT("LHPOUT"), 267*40e0aa64SRichard Purdie SND_SOC_DAPM_OUTPUT("ROUT"), 268*40e0aa64SRichard Purdie SND_SOC_DAPM_OUTPUT("RHPOUT"), 269*40e0aa64SRichard Purdie SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8731_PWR, 2, 1), 270*40e0aa64SRichard Purdie SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &wm8731_input_mux_controls), 271*40e0aa64SRichard Purdie SND_SOC_DAPM_PGA("Line Input", WM8731_PWR, 0, 1, NULL, 0), 272*40e0aa64SRichard Purdie SND_SOC_DAPM_MICBIAS("Mic Bias", WM8731_PWR, 1, 1), 273*40e0aa64SRichard Purdie SND_SOC_DAPM_INPUT("MICIN"), 274*40e0aa64SRichard Purdie SND_SOC_DAPM_INPUT("RLINEIN"), 275*40e0aa64SRichard Purdie SND_SOC_DAPM_INPUT("LLINEIN"), 276*40e0aa64SRichard Purdie }; 277*40e0aa64SRichard Purdie 278*40e0aa64SRichard Purdie static const char *intercon[][3] = { 279*40e0aa64SRichard Purdie /* output mixer */ 280*40e0aa64SRichard Purdie {"Output Mixer", "Line Bypass Switch", "Line Input"}, 281*40e0aa64SRichard Purdie {"Output Mixer", "HiFi Playback Switch", "DAC"}, 282*40e0aa64SRichard Purdie {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, 283*40e0aa64SRichard Purdie 284*40e0aa64SRichard Purdie /* outputs */ 285*40e0aa64SRichard Purdie {"RHPOUT", NULL, "Output Mixer"}, 286*40e0aa64SRichard Purdie {"ROUT", NULL, "Output Mixer"}, 287*40e0aa64SRichard Purdie {"LHPOUT", NULL, "Output Mixer"}, 288*40e0aa64SRichard Purdie {"LOUT", NULL, "Output Mixer"}, 289*40e0aa64SRichard Purdie 290*40e0aa64SRichard Purdie /* input mux */ 291*40e0aa64SRichard Purdie {"Input Mux", "Line In", "Line Input"}, 292*40e0aa64SRichard Purdie {"Input Mux", "Mic", "Mic Bias"}, 293*40e0aa64SRichard Purdie {"ADC", NULL, "Input Mux"}, 294*40e0aa64SRichard Purdie 295*40e0aa64SRichard Purdie /* inputs */ 296*40e0aa64SRichard Purdie {"Line Input", NULL, "LLINEIN"}, 297*40e0aa64SRichard Purdie {"Line Input", NULL, "RLINEIN"}, 298*40e0aa64SRichard Purdie {"Mic Bias", NULL, "MICIN"}, 299*40e0aa64SRichard Purdie 300*40e0aa64SRichard Purdie /* terminator */ 301*40e0aa64SRichard Purdie {NULL, NULL, NULL}, 302*40e0aa64SRichard Purdie }; 303*40e0aa64SRichard Purdie 304*40e0aa64SRichard Purdie static int wm8731_add_widgets(struct snd_soc_codec *codec) 305*40e0aa64SRichard Purdie { 306*40e0aa64SRichard Purdie int i; 307*40e0aa64SRichard Purdie 308*40e0aa64SRichard Purdie for(i = 0; i < ARRAY_SIZE(wm8731_dapm_widgets); i++) { 309*40e0aa64SRichard Purdie snd_soc_dapm_new_control(codec, &wm8731_dapm_widgets[i]); 310*40e0aa64SRichard Purdie } 311*40e0aa64SRichard Purdie 312*40e0aa64SRichard Purdie /* set up audio path interconnects */ 313*40e0aa64SRichard Purdie for(i = 0; intercon[i][0] != NULL; i++) { 314*40e0aa64SRichard Purdie snd_soc_dapm_connect_input(codec, intercon[i][0], 315*40e0aa64SRichard Purdie intercon[i][1], intercon[i][2]); 316*40e0aa64SRichard Purdie } 317*40e0aa64SRichard Purdie 318*40e0aa64SRichard Purdie snd_soc_dapm_new_widgets(codec); 319*40e0aa64SRichard Purdie return 0; 320*40e0aa64SRichard Purdie } 321*40e0aa64SRichard Purdie 322*40e0aa64SRichard Purdie struct _coeff_div { 323*40e0aa64SRichard Purdie u32 mclk; 324*40e0aa64SRichard Purdie u32 rate; 325*40e0aa64SRichard Purdie u16 fs; 326*40e0aa64SRichard Purdie u8 sr:4; 327*40e0aa64SRichard Purdie u8 bosr:1; 328*40e0aa64SRichard Purdie u8 usb:1; 329*40e0aa64SRichard Purdie }; 330*40e0aa64SRichard Purdie 331*40e0aa64SRichard Purdie /* codec mclk clock divider coefficients */ 332*40e0aa64SRichard Purdie static const struct _coeff_div coeff_div[] = { 333*40e0aa64SRichard Purdie /* 48k */ 334*40e0aa64SRichard Purdie {12288000, 48000, 256, 0x0, 0x0, 0x0}, 335*40e0aa64SRichard Purdie {18432000, 48000, 384, 0x0, 0x1, 0x0}, 336*40e0aa64SRichard Purdie {12000000, 48000, 250, 0x0, 0x0, 0x1}, 337*40e0aa64SRichard Purdie 338*40e0aa64SRichard Purdie /* 32k */ 339*40e0aa64SRichard Purdie {12288000, 32000, 384, 0x6, 0x0, 0x0}, 340*40e0aa64SRichard Purdie {18432000, 32000, 576, 0x6, 0x1, 0x0}, 341*40e0aa64SRichard Purdie 342*40e0aa64SRichard Purdie /* 8k */ 343*40e0aa64SRichard Purdie {12288000, 8000, 1536, 0x3, 0x0, 0x0}, 344*40e0aa64SRichard Purdie {18432000, 8000, 2304, 0x3, 0x1, 0x0}, 345*40e0aa64SRichard Purdie {11289600, 8000, 1408, 0xb, 0x0, 0x0}, 346*40e0aa64SRichard Purdie {16934400, 8000, 2112, 0xb, 0x1, 0x0}, 347*40e0aa64SRichard Purdie {12000000, 8000, 1500, 0x3, 0x0, 0x1}, 348*40e0aa64SRichard Purdie 349*40e0aa64SRichard Purdie /* 96k */ 350*40e0aa64SRichard Purdie {12288000, 96000, 128, 0x7, 0x0, 0x0}, 351*40e0aa64SRichard Purdie {18432000, 96000, 192, 0x7, 0x1, 0x0}, 352*40e0aa64SRichard Purdie {12000000, 96000, 125, 0x7, 0x0, 0x1}, 353*40e0aa64SRichard Purdie 354*40e0aa64SRichard Purdie /* 44.1k */ 355*40e0aa64SRichard Purdie {11289600, 44100, 256, 0x8, 0x0, 0x0}, 356*40e0aa64SRichard Purdie {16934400, 44100, 384, 0x8, 0x1, 0x0}, 357*40e0aa64SRichard Purdie {12000000, 44100, 272, 0x8, 0x1, 0x1}, 358*40e0aa64SRichard Purdie 359*40e0aa64SRichard Purdie /* 88.2k */ 360*40e0aa64SRichard Purdie {11289600, 88200, 128, 0xf, 0x0, 0x0}, 361*40e0aa64SRichard Purdie {16934400, 88200, 192, 0xf, 0x1, 0x0}, 362*40e0aa64SRichard Purdie {12000000, 88200, 136, 0xf, 0x1, 0x1}, 363*40e0aa64SRichard Purdie }; 364*40e0aa64SRichard Purdie 365*40e0aa64SRichard Purdie static inline int get_coeff(int mclk, int rate) 366*40e0aa64SRichard Purdie { 367*40e0aa64SRichard Purdie int i; 368*40e0aa64SRichard Purdie 369*40e0aa64SRichard Purdie for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 370*40e0aa64SRichard Purdie if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) 371*40e0aa64SRichard Purdie return i; 372*40e0aa64SRichard Purdie } 373*40e0aa64SRichard Purdie return 0; 374*40e0aa64SRichard Purdie } 375*40e0aa64SRichard Purdie 376*40e0aa64SRichard Purdie /* WM8731 supports numerous clocks per sample rate */ 377*40e0aa64SRichard Purdie static unsigned int wm8731_config_sysclk(struct snd_soc_codec_dai *dai, 378*40e0aa64SRichard Purdie struct snd_soc_clock_info *info, unsigned int clk) 379*40e0aa64SRichard Purdie { 380*40e0aa64SRichard Purdie dai->mclk = 0; 381*40e0aa64SRichard Purdie 382*40e0aa64SRichard Purdie /* check that the calculated FS and rate actually match a clock from 383*40e0aa64SRichard Purdie * the machine driver */ 384*40e0aa64SRichard Purdie if (info->fs * info->rate == clk) 385*40e0aa64SRichard Purdie dai->mclk = clk; 386*40e0aa64SRichard Purdie 387*40e0aa64SRichard Purdie return dai->mclk; 388*40e0aa64SRichard Purdie } 389*40e0aa64SRichard Purdie 390*40e0aa64SRichard Purdie static int wm8731_pcm_prepare(struct snd_pcm_substream *substream) 391*40e0aa64SRichard Purdie { 392*40e0aa64SRichard Purdie struct snd_soc_pcm_runtime *rtd = substream->private_data; 393*40e0aa64SRichard Purdie struct snd_soc_device *socdev = rtd->socdev; 394*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 395*40e0aa64SRichard Purdie u16 iface = 0, srate; 396*40e0aa64SRichard Purdie int i = get_coeff(rtd->codec_dai->mclk, 397*40e0aa64SRichard Purdie snd_soc_get_rate(rtd->codec_dai->dai_runtime.pcmrate)); 398*40e0aa64SRichard Purdie 399*40e0aa64SRichard Purdie /* set master/slave audio interface */ 400*40e0aa64SRichard Purdie switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK) { 401*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_CBM_CFM: 402*40e0aa64SRichard Purdie iface |= 0x0040; 403*40e0aa64SRichard Purdie break; 404*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_CBS_CFS: 405*40e0aa64SRichard Purdie break; 406*40e0aa64SRichard Purdie } 407*40e0aa64SRichard Purdie srate = (coeff_div[i].sr << 2) | 408*40e0aa64SRichard Purdie (coeff_div[i].bosr << 1) | coeff_div[i].usb; 409*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_SRATE, srate); 410*40e0aa64SRichard Purdie 411*40e0aa64SRichard Purdie /* interface format */ 412*40e0aa64SRichard Purdie switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 413*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_I2S: 414*40e0aa64SRichard Purdie iface |= 0x0002; 415*40e0aa64SRichard Purdie break; 416*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_RIGHT_J: 417*40e0aa64SRichard Purdie break; 418*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_LEFT_J: 419*40e0aa64SRichard Purdie iface |= 0x0001; 420*40e0aa64SRichard Purdie break; 421*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_DSP_A: 422*40e0aa64SRichard Purdie iface |= 0x0003; 423*40e0aa64SRichard Purdie break; 424*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_DSP_B: 425*40e0aa64SRichard Purdie iface |= 0x0013; 426*40e0aa64SRichard Purdie break; 427*40e0aa64SRichard Purdie } 428*40e0aa64SRichard Purdie 429*40e0aa64SRichard Purdie /* bit size */ 430*40e0aa64SRichard Purdie switch (rtd->codec_dai->dai_runtime.pcmfmt) { 431*40e0aa64SRichard Purdie case SNDRV_PCM_FMTBIT_S16_LE: 432*40e0aa64SRichard Purdie break; 433*40e0aa64SRichard Purdie case SNDRV_PCM_FMTBIT_S20_3LE: 434*40e0aa64SRichard Purdie iface |= 0x0004; 435*40e0aa64SRichard Purdie break; 436*40e0aa64SRichard Purdie case SNDRV_PCM_FMTBIT_S24_LE: 437*40e0aa64SRichard Purdie iface |= 0x0008; 438*40e0aa64SRichard Purdie break; 439*40e0aa64SRichard Purdie case SNDRV_PCM_FMTBIT_S32_LE: 440*40e0aa64SRichard Purdie iface |= 0x000c; 441*40e0aa64SRichard Purdie break; 442*40e0aa64SRichard Purdie } 443*40e0aa64SRichard Purdie 444*40e0aa64SRichard Purdie /* clock inversion */ 445*40e0aa64SRichard Purdie switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_INV_MASK) { 446*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_NB_NF: 447*40e0aa64SRichard Purdie break; 448*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_IB_IF: 449*40e0aa64SRichard Purdie iface |= 0x0090; 450*40e0aa64SRichard Purdie break; 451*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_IB_NF: 452*40e0aa64SRichard Purdie iface |= 0x0080; 453*40e0aa64SRichard Purdie break; 454*40e0aa64SRichard Purdie case SND_SOC_DAIFMT_NB_IF: 455*40e0aa64SRichard Purdie iface |= 0x0010; 456*40e0aa64SRichard Purdie break; 457*40e0aa64SRichard Purdie } 458*40e0aa64SRichard Purdie 459*40e0aa64SRichard Purdie /* set iface */ 460*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_IFACE, iface); 461*40e0aa64SRichard Purdie 462*40e0aa64SRichard Purdie /* set active */ 463*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_ACTIVE, 0x0001); 464*40e0aa64SRichard Purdie return 0; 465*40e0aa64SRichard Purdie } 466*40e0aa64SRichard Purdie 467*40e0aa64SRichard Purdie static void wm8731_shutdown(struct snd_pcm_substream *substream) 468*40e0aa64SRichard Purdie { 469*40e0aa64SRichard Purdie struct snd_soc_pcm_runtime *rtd = substream->private_data; 470*40e0aa64SRichard Purdie struct snd_soc_device *socdev = rtd->socdev; 471*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 472*40e0aa64SRichard Purdie 473*40e0aa64SRichard Purdie /* deactivate */ 474*40e0aa64SRichard Purdie if (!codec->active) { 475*40e0aa64SRichard Purdie udelay(50); 476*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_ACTIVE, 0x0); 477*40e0aa64SRichard Purdie } 478*40e0aa64SRichard Purdie } 479*40e0aa64SRichard Purdie 480*40e0aa64SRichard Purdie static int wm8731_mute(struct snd_soc_codec *codec, 481*40e0aa64SRichard Purdie struct snd_soc_codec_dai *dai, int mute) 482*40e0aa64SRichard Purdie { 483*40e0aa64SRichard Purdie u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; 484*40e0aa64SRichard Purdie if (mute) 485*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8); 486*40e0aa64SRichard Purdie else 487*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_APDIGI, mute_reg); 488*40e0aa64SRichard Purdie return 0; 489*40e0aa64SRichard Purdie } 490*40e0aa64SRichard Purdie 491*40e0aa64SRichard Purdie static int wm8731_dapm_event(struct snd_soc_codec *codec, int event) 492*40e0aa64SRichard Purdie { 493*40e0aa64SRichard Purdie u16 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; 494*40e0aa64SRichard Purdie 495*40e0aa64SRichard Purdie switch (event) { 496*40e0aa64SRichard Purdie case SNDRV_CTL_POWER_D0: /* full On */ 497*40e0aa64SRichard Purdie /* vref/mid, osc on, dac unmute */ 498*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_PWR, reg); 499*40e0aa64SRichard Purdie break; 500*40e0aa64SRichard Purdie case SNDRV_CTL_POWER_D1: /* partial On */ 501*40e0aa64SRichard Purdie case SNDRV_CTL_POWER_D2: /* partial On */ 502*40e0aa64SRichard Purdie break; 503*40e0aa64SRichard Purdie case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 504*40e0aa64SRichard Purdie /* everything off except vref/vmid, */ 505*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_PWR, reg | 0x0040); 506*40e0aa64SRichard Purdie break; 507*40e0aa64SRichard Purdie case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 508*40e0aa64SRichard Purdie /* everything off, dac mute, inactive */ 509*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_ACTIVE, 0x0); 510*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_PWR, 0xffff); 511*40e0aa64SRichard Purdie break; 512*40e0aa64SRichard Purdie } 513*40e0aa64SRichard Purdie codec->dapm_state = event; 514*40e0aa64SRichard Purdie return 0; 515*40e0aa64SRichard Purdie } 516*40e0aa64SRichard Purdie 517*40e0aa64SRichard Purdie struct snd_soc_codec_dai wm8731_dai = { 518*40e0aa64SRichard Purdie .name = "WM8731", 519*40e0aa64SRichard Purdie .playback = { 520*40e0aa64SRichard Purdie .stream_name = "Playback", 521*40e0aa64SRichard Purdie .channels_min = 1, 522*40e0aa64SRichard Purdie .channels_max = 2, 523*40e0aa64SRichard Purdie }, 524*40e0aa64SRichard Purdie .capture = { 525*40e0aa64SRichard Purdie .stream_name = "Capture", 526*40e0aa64SRichard Purdie .channels_min = 1, 527*40e0aa64SRichard Purdie .channels_max = 2, 528*40e0aa64SRichard Purdie }, 529*40e0aa64SRichard Purdie .config_sysclk = wm8731_config_sysclk, 530*40e0aa64SRichard Purdie .digital_mute = wm8731_mute, 531*40e0aa64SRichard Purdie .ops = { 532*40e0aa64SRichard Purdie .prepare = wm8731_pcm_prepare, 533*40e0aa64SRichard Purdie .shutdown = wm8731_shutdown, 534*40e0aa64SRichard Purdie }, 535*40e0aa64SRichard Purdie .caps = { 536*40e0aa64SRichard Purdie .num_modes = ARRAY_SIZE(wm8731_modes), 537*40e0aa64SRichard Purdie .mode = wm8731_modes, 538*40e0aa64SRichard Purdie }, 539*40e0aa64SRichard Purdie }; 540*40e0aa64SRichard Purdie EXPORT_SYMBOL_GPL(wm8731_dai); 541*40e0aa64SRichard Purdie 542*40e0aa64SRichard Purdie static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 543*40e0aa64SRichard Purdie { 544*40e0aa64SRichard Purdie struct snd_soc_device *socdev = platform_get_drvdata(pdev); 545*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 546*40e0aa64SRichard Purdie 547*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_ACTIVE, 0x0); 548*40e0aa64SRichard Purdie wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 549*40e0aa64SRichard Purdie return 0; 550*40e0aa64SRichard Purdie } 551*40e0aa64SRichard Purdie 552*40e0aa64SRichard Purdie static int wm8731_resume(struct platform_device *pdev) 553*40e0aa64SRichard Purdie { 554*40e0aa64SRichard Purdie struct snd_soc_device *socdev = platform_get_drvdata(pdev); 555*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 556*40e0aa64SRichard Purdie int i; 557*40e0aa64SRichard Purdie u8 data[2]; 558*40e0aa64SRichard Purdie u16 *cache = codec->reg_cache; 559*40e0aa64SRichard Purdie 560*40e0aa64SRichard Purdie /* Sync reg_cache with the hardware */ 561*40e0aa64SRichard Purdie for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 562*40e0aa64SRichard Purdie data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 563*40e0aa64SRichard Purdie data[1] = cache[i] & 0x00ff; 564*40e0aa64SRichard Purdie codec->hw_write(codec->control_data, data, 2); 565*40e0aa64SRichard Purdie } 566*40e0aa64SRichard Purdie wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 567*40e0aa64SRichard Purdie wm8731_dapm_event(codec, codec->suspend_dapm_state); 568*40e0aa64SRichard Purdie return 0; 569*40e0aa64SRichard Purdie } 570*40e0aa64SRichard Purdie 571*40e0aa64SRichard Purdie /* 572*40e0aa64SRichard Purdie * initialise the WM8731 driver 573*40e0aa64SRichard Purdie * register the mixer and dsp interfaces with the kernel 574*40e0aa64SRichard Purdie */ 575*40e0aa64SRichard Purdie static int wm8731_init(struct snd_soc_device *socdev) 576*40e0aa64SRichard Purdie { 577*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 578*40e0aa64SRichard Purdie int reg, ret = 0; 579*40e0aa64SRichard Purdie 580*40e0aa64SRichard Purdie codec->name = "WM8731"; 581*40e0aa64SRichard Purdie codec->owner = THIS_MODULE; 582*40e0aa64SRichard Purdie codec->read = wm8731_read_reg_cache; 583*40e0aa64SRichard Purdie codec->write = wm8731_write; 584*40e0aa64SRichard Purdie codec->dapm_event = wm8731_dapm_event; 585*40e0aa64SRichard Purdie codec->dai = &wm8731_dai; 586*40e0aa64SRichard Purdie codec->num_dai = 1; 587*40e0aa64SRichard Purdie codec->reg_cache_size = ARRAY_SIZE(wm8731_reg); 588*40e0aa64SRichard Purdie 589*40e0aa64SRichard Purdie codec->reg_cache = 590*40e0aa64SRichard Purdie kzalloc(sizeof(u16) * ARRAY_SIZE(wm8731_reg), GFP_KERNEL); 591*40e0aa64SRichard Purdie if (codec->reg_cache == NULL) 592*40e0aa64SRichard Purdie return -ENOMEM; 593*40e0aa64SRichard Purdie memcpy(codec->reg_cache, 594*40e0aa64SRichard Purdie wm8731_reg, sizeof(u16) * ARRAY_SIZE(wm8731_reg)); 595*40e0aa64SRichard Purdie codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm8731_reg); 596*40e0aa64SRichard Purdie 597*40e0aa64SRichard Purdie wm8731_reset(codec); 598*40e0aa64SRichard Purdie 599*40e0aa64SRichard Purdie /* register pcms */ 600*40e0aa64SRichard Purdie ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 601*40e0aa64SRichard Purdie if (ret < 0) { 602*40e0aa64SRichard Purdie kfree(codec->reg_cache); 603*40e0aa64SRichard Purdie return ret; 604*40e0aa64SRichard Purdie } 605*40e0aa64SRichard Purdie 606*40e0aa64SRichard Purdie /* power on device */ 607*40e0aa64SRichard Purdie wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 608*40e0aa64SRichard Purdie 609*40e0aa64SRichard Purdie /* set the update bits */ 610*40e0aa64SRichard Purdie reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); 611*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_LOUT1V, reg | 0x0100); 612*40e0aa64SRichard Purdie reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); 613*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_ROUT1V, reg | 0x0100); 614*40e0aa64SRichard Purdie reg = wm8731_read_reg_cache(codec, WM8731_LINVOL); 615*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_LINVOL, reg | 0x0100); 616*40e0aa64SRichard Purdie reg = wm8731_read_reg_cache(codec, WM8731_RINVOL); 617*40e0aa64SRichard Purdie wm8731_write(codec, WM8731_RINVOL, reg | 0x0100); 618*40e0aa64SRichard Purdie 619*40e0aa64SRichard Purdie wm8731_add_controls(codec); 620*40e0aa64SRichard Purdie wm8731_add_widgets(codec); 621*40e0aa64SRichard Purdie ret = snd_soc_register_card(socdev); 622*40e0aa64SRichard Purdie if (ret < 0) { 623*40e0aa64SRichard Purdie snd_soc_free_pcms(socdev); 624*40e0aa64SRichard Purdie snd_soc_dapm_free(socdev); 625*40e0aa64SRichard Purdie } 626*40e0aa64SRichard Purdie 627*40e0aa64SRichard Purdie return ret; 628*40e0aa64SRichard Purdie } 629*40e0aa64SRichard Purdie 630*40e0aa64SRichard Purdie static struct snd_soc_device *wm8731_socdev; 631*40e0aa64SRichard Purdie 632*40e0aa64SRichard Purdie #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 633*40e0aa64SRichard Purdie 634*40e0aa64SRichard Purdie /* 635*40e0aa64SRichard Purdie * WM8731 2 wire address is determined by GPIO5 636*40e0aa64SRichard Purdie * state during powerup. 637*40e0aa64SRichard Purdie * low = 0x1a 638*40e0aa64SRichard Purdie * high = 0x1b 639*40e0aa64SRichard Purdie */ 640*40e0aa64SRichard Purdie static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 641*40e0aa64SRichard Purdie 642*40e0aa64SRichard Purdie /* Magic definition of all other variables and things */ 643*40e0aa64SRichard Purdie I2C_CLIENT_INSMOD; 644*40e0aa64SRichard Purdie 645*40e0aa64SRichard Purdie static struct i2c_driver wm8731_i2c_driver; 646*40e0aa64SRichard Purdie static struct i2c_client client_template; 647*40e0aa64SRichard Purdie 648*40e0aa64SRichard Purdie /* If the i2c layer weren't so broken, we could pass this kind of data 649*40e0aa64SRichard Purdie around */ 650*40e0aa64SRichard Purdie 651*40e0aa64SRichard Purdie static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind) 652*40e0aa64SRichard Purdie { 653*40e0aa64SRichard Purdie struct snd_soc_device *socdev = wm8731_socdev; 654*40e0aa64SRichard Purdie struct wm8731_setup_data *setup = socdev->codec_data; 655*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 656*40e0aa64SRichard Purdie struct i2c_client *i2c; 657*40e0aa64SRichard Purdie int ret; 658*40e0aa64SRichard Purdie 659*40e0aa64SRichard Purdie if (addr != setup->i2c_address) 660*40e0aa64SRichard Purdie return -ENODEV; 661*40e0aa64SRichard Purdie 662*40e0aa64SRichard Purdie client_template.adapter = adap; 663*40e0aa64SRichard Purdie client_template.addr = addr; 664*40e0aa64SRichard Purdie 665*40e0aa64SRichard Purdie i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 666*40e0aa64SRichard Purdie if (i2c == NULL) { 667*40e0aa64SRichard Purdie kfree(codec); 668*40e0aa64SRichard Purdie return -ENOMEM; 669*40e0aa64SRichard Purdie } 670*40e0aa64SRichard Purdie memcpy(i2c, &client_template, sizeof(struct i2c_client)); 671*40e0aa64SRichard Purdie i2c_set_clientdata(i2c, codec); 672*40e0aa64SRichard Purdie codec->control_data = i2c; 673*40e0aa64SRichard Purdie 674*40e0aa64SRichard Purdie ret = i2c_attach_client(i2c); 675*40e0aa64SRichard Purdie if (ret < 0) { 676*40e0aa64SRichard Purdie err("failed to attach codec at addr %x\n", addr); 677*40e0aa64SRichard Purdie goto err; 678*40e0aa64SRichard Purdie } 679*40e0aa64SRichard Purdie 680*40e0aa64SRichard Purdie ret = wm8731_init(socdev); 681*40e0aa64SRichard Purdie if (ret < 0) { 682*40e0aa64SRichard Purdie err("failed to initialise WM8731\n"); 683*40e0aa64SRichard Purdie goto err; 684*40e0aa64SRichard Purdie } 685*40e0aa64SRichard Purdie return ret; 686*40e0aa64SRichard Purdie 687*40e0aa64SRichard Purdie err: 688*40e0aa64SRichard Purdie kfree(codec); 689*40e0aa64SRichard Purdie kfree(i2c); 690*40e0aa64SRichard Purdie return ret; 691*40e0aa64SRichard Purdie } 692*40e0aa64SRichard Purdie 693*40e0aa64SRichard Purdie static int wm8731_i2c_detach(struct i2c_client *client) 694*40e0aa64SRichard Purdie { 695*40e0aa64SRichard Purdie struct snd_soc_codec* codec = i2c_get_clientdata(client); 696*40e0aa64SRichard Purdie i2c_detach_client(client); 697*40e0aa64SRichard Purdie kfree(codec->reg_cache); 698*40e0aa64SRichard Purdie kfree(client); 699*40e0aa64SRichard Purdie return 0; 700*40e0aa64SRichard Purdie } 701*40e0aa64SRichard Purdie 702*40e0aa64SRichard Purdie static int wm8731_i2c_attach(struct i2c_adapter *adap) 703*40e0aa64SRichard Purdie { 704*40e0aa64SRichard Purdie return i2c_probe(adap, &addr_data, wm8731_codec_probe); 705*40e0aa64SRichard Purdie } 706*40e0aa64SRichard Purdie 707*40e0aa64SRichard Purdie /* corgi i2c codec control layer */ 708*40e0aa64SRichard Purdie static struct i2c_driver wm8731_i2c_driver = { 709*40e0aa64SRichard Purdie .driver = { 710*40e0aa64SRichard Purdie .name = "WM8731 I2C Codec", 711*40e0aa64SRichard Purdie .owner = THIS_MODULE, 712*40e0aa64SRichard Purdie }, 713*40e0aa64SRichard Purdie .id = I2C_DRIVERID_WM8731, 714*40e0aa64SRichard Purdie .attach_adapter = wm8731_i2c_attach, 715*40e0aa64SRichard Purdie .detach_client = wm8731_i2c_detach, 716*40e0aa64SRichard Purdie .command = NULL, 717*40e0aa64SRichard Purdie }; 718*40e0aa64SRichard Purdie 719*40e0aa64SRichard Purdie static struct i2c_client client_template = { 720*40e0aa64SRichard Purdie .name = "WM8731", 721*40e0aa64SRichard Purdie .driver = &wm8731_i2c_driver, 722*40e0aa64SRichard Purdie }; 723*40e0aa64SRichard Purdie #endif 724*40e0aa64SRichard Purdie 725*40e0aa64SRichard Purdie static int wm8731_probe(struct platform_device *pdev) 726*40e0aa64SRichard Purdie { 727*40e0aa64SRichard Purdie struct snd_soc_device *socdev = platform_get_drvdata(pdev); 728*40e0aa64SRichard Purdie struct wm8731_setup_data *setup; 729*40e0aa64SRichard Purdie struct snd_soc_codec *codec; 730*40e0aa64SRichard Purdie int ret = 0; 731*40e0aa64SRichard Purdie 732*40e0aa64SRichard Purdie info("WM8731 Audio Codec %s", WM8731_VERSION); 733*40e0aa64SRichard Purdie 734*40e0aa64SRichard Purdie setup = socdev->codec_data; 735*40e0aa64SRichard Purdie codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 736*40e0aa64SRichard Purdie if (codec == NULL) 737*40e0aa64SRichard Purdie return -ENOMEM; 738*40e0aa64SRichard Purdie 739*40e0aa64SRichard Purdie socdev->codec = codec; 740*40e0aa64SRichard Purdie mutex_init(&codec->mutex); 741*40e0aa64SRichard Purdie INIT_LIST_HEAD(&codec->dapm_widgets); 742*40e0aa64SRichard Purdie INIT_LIST_HEAD(&codec->dapm_paths); 743*40e0aa64SRichard Purdie 744*40e0aa64SRichard Purdie wm8731_socdev = socdev; 745*40e0aa64SRichard Purdie #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 746*40e0aa64SRichard Purdie if (setup->i2c_address) { 747*40e0aa64SRichard Purdie normal_i2c[0] = setup->i2c_address; 748*40e0aa64SRichard Purdie codec->hw_write = (hw_write_t)i2c_master_send; 749*40e0aa64SRichard Purdie ret = i2c_add_driver(&wm8731_i2c_driver); 750*40e0aa64SRichard Purdie if (ret != 0) 751*40e0aa64SRichard Purdie printk(KERN_ERR "can't add i2c driver"); 752*40e0aa64SRichard Purdie } 753*40e0aa64SRichard Purdie #else 754*40e0aa64SRichard Purdie /* Add other interfaces here */ 755*40e0aa64SRichard Purdie #endif 756*40e0aa64SRichard Purdie return ret; 757*40e0aa64SRichard Purdie } 758*40e0aa64SRichard Purdie 759*40e0aa64SRichard Purdie /* power down chip */ 760*40e0aa64SRichard Purdie static int wm8731_remove(struct platform_device *pdev) 761*40e0aa64SRichard Purdie { 762*40e0aa64SRichard Purdie struct snd_soc_device *socdev = platform_get_drvdata(pdev); 763*40e0aa64SRichard Purdie struct snd_soc_codec *codec = socdev->codec; 764*40e0aa64SRichard Purdie 765*40e0aa64SRichard Purdie if (codec->control_data) 766*40e0aa64SRichard Purdie wm8731_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 767*40e0aa64SRichard Purdie 768*40e0aa64SRichard Purdie snd_soc_free_pcms(socdev); 769*40e0aa64SRichard Purdie snd_soc_dapm_free(socdev); 770*40e0aa64SRichard Purdie #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 771*40e0aa64SRichard Purdie i2c_del_driver(&wm8731_i2c_driver); 772*40e0aa64SRichard Purdie #endif 773*40e0aa64SRichard Purdie kfree(codec); 774*40e0aa64SRichard Purdie 775*40e0aa64SRichard Purdie return 0; 776*40e0aa64SRichard Purdie } 777*40e0aa64SRichard Purdie 778*40e0aa64SRichard Purdie struct snd_soc_codec_device soc_codec_dev_wm8731 = { 779*40e0aa64SRichard Purdie .probe = wm8731_probe, 780*40e0aa64SRichard Purdie .remove = wm8731_remove, 781*40e0aa64SRichard Purdie .suspend = wm8731_suspend, 782*40e0aa64SRichard Purdie .resume = wm8731_resume, 783*40e0aa64SRichard Purdie }; 784*40e0aa64SRichard Purdie 785*40e0aa64SRichard Purdie EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 786*40e0aa64SRichard Purdie 787*40e0aa64SRichard Purdie MODULE_DESCRIPTION("ASoC WM8731 driver"); 788*40e0aa64SRichard Purdie MODULE_AUTHOR("Richard Purdie"); 789*40e0aa64SRichard Purdie MODULE_LICENSE("GPL"); 790