1 /* 2 * wm8750.c -- WM8750 ALSA SoC audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <richard@openedhand.com> 7 * 8 * Based on WM8753.c 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/module.h> 16 #include <linux/moduleparam.h> 17 #include <linux/init.h> 18 #include <linux/delay.h> 19 #include <linux/pm.h> 20 #include <linux/i2c.h> 21 #include <linux/platform_device.h> 22 #include <sound/driver.h> 23 #include <sound/core.h> 24 #include <sound/pcm.h> 25 #include <sound/pcm_params.h> 26 #include <sound/soc.h> 27 #include <sound/soc-dapm.h> 28 #include <sound/initval.h> 29 30 #include "wm8750.h" 31 32 #define AUDIO_NAME "WM8750" 33 #define WM8750_VERSION "0.11" 34 35 /* 36 * Debug 37 */ 38 39 #define WM8750_DEBUG 0 40 41 #ifdef WM8750_DEBUG 42 #define dbg(format, arg...) \ 43 printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg) 44 #else 45 #define dbg(format, arg...) do {} while (0) 46 #endif 47 #define err(format, arg...) \ 48 printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) 49 #define info(format, arg...) \ 50 printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) 51 #define warn(format, arg...) \ 52 printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) 53 54 static struct workqueue_struct *wm8750_workq = NULL; 55 static struct work_struct wm8750_dapm_work; 56 57 /* 58 * wm8750 register cache 59 * We can't read the WM8750 register space when we 60 * are using 2 wire for device control, so we cache them instead. 61 */ 62 static const u16 wm8750_reg[] = { 63 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 64 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 65 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 66 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 67 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 68 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 69 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 70 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 71 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 72 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 73 0x0079, 0x0079, 0x0079, /* 40 */ 74 }; 75 76 #define WM8750_HIFI_DAIFMT \ 77 (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_RIGHT_J | \ 78 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_IB_NF | \ 79 SND_SOC_DAIFMT_IB_IF) 80 81 #define WM8750_DIR \ 82 (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) 83 84 #define WM8750_HIFI_FSB \ 85 (SND_SOC_FSBD(1) | SND_SOC_FSBD(2) | SND_SOC_FSBD(4) | \ 86 SND_SOC_FSBD(8) | SND_SOC_FSBD(16)) 87 88 #define WM8750_HIFI_RATES \ 89 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ 90 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ 91 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 92 93 #define WM8750_HIFI_BITS \ 94 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 95 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 96 97 static struct snd_soc_dai_mode wm8750_modes[] = { 98 /* common codec frame and clock master modes */ 99 /* 8k */ 100 { 101 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 102 .pcmfmt = WM8750_HIFI_BITS, 103 .pcmrate = SNDRV_PCM_RATE_8000, 104 .pcmdir = WM8750_DIR, 105 .flags = SND_SOC_DAI_BFS_DIV, 106 .fs = 1536, 107 .bfs = WM8750_HIFI_FSB, 108 }, 109 { 110 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 111 .pcmfmt = WM8750_HIFI_BITS, 112 .pcmrate = SNDRV_PCM_RATE_8000, 113 .pcmdir = WM8750_DIR, 114 .flags = SND_SOC_DAI_BFS_DIV, 115 .fs = 1408, 116 .bfs = WM8750_HIFI_FSB, 117 }, 118 { 119 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 120 .pcmfmt = WM8750_HIFI_BITS, 121 .pcmrate = SNDRV_PCM_RATE_8000, 122 .pcmdir = WM8750_DIR, 123 .flags = SND_SOC_DAI_BFS_DIV, 124 .fs = 2304, 125 .bfs = WM8750_HIFI_FSB, 126 }, 127 { 128 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 129 .pcmfmt = WM8750_HIFI_BITS, 130 .pcmrate = SNDRV_PCM_RATE_8000, 131 .pcmdir = WM8750_DIR, 132 .flags = SND_SOC_DAI_BFS_DIV, 133 .fs = 2112, 134 .bfs = WM8750_HIFI_FSB, 135 }, 136 { 137 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 138 .pcmfmt = WM8750_HIFI_BITS, 139 .pcmrate = SNDRV_PCM_RATE_8000, 140 .pcmdir = WM8750_DIR, 141 .flags = SND_SOC_DAI_BFS_DIV, 142 .fs = 1500, 143 .bfs = WM8750_HIFI_FSB, 144 }, 145 146 /* 11.025k */ 147 { 148 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 149 .pcmfmt = WM8750_HIFI_BITS, 150 .pcmrate = SNDRV_PCM_RATE_11025, 151 .pcmdir = WM8750_DIR, 152 .flags = SND_SOC_DAI_BFS_DIV, 153 .fs = 1024, 154 .bfs = WM8750_HIFI_FSB, 155 }, 156 { 157 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 158 .pcmfmt = WM8750_HIFI_BITS, 159 .pcmrate = SNDRV_PCM_RATE_11025, 160 .pcmdir = WM8750_DIR, 161 .flags = SND_SOC_DAI_BFS_DIV, 162 .fs = 1536, 163 .bfs = WM8750_HIFI_FSB, 164 }, 165 { 166 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 167 .pcmfmt = WM8750_HIFI_BITS, 168 .pcmrate = SNDRV_PCM_RATE_11025, 169 .pcmdir = WM8750_DIR, 170 .flags = SND_SOC_DAI_BFS_DIV, 171 .fs = 1088, 172 .bfs = WM8750_HIFI_FSB, 173 }, 174 175 /* 16k */ 176 { 177 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 178 .pcmfmt = WM8750_HIFI_BITS, 179 .pcmrate = SNDRV_PCM_RATE_16000, 180 .pcmdir = WM8750_DIR, 181 .flags = SND_SOC_DAI_BFS_DIV, 182 .fs = 768, 183 .bfs = WM8750_HIFI_FSB, 184 }, 185 { 186 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 187 .pcmfmt = WM8750_HIFI_BITS, 188 .pcmrate = SNDRV_PCM_RATE_16000, 189 .pcmdir = WM8750_DIR, 190 .flags = SND_SOC_DAI_BFS_DIV, 191 .fs = 1152, 192 .bfs = WM8750_HIFI_FSB 193 }, 194 { 195 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 196 .pcmfmt = WM8750_HIFI_BITS, 197 .pcmrate = SNDRV_PCM_RATE_16000, 198 .pcmdir = WM8750_DIR, 199 .flags = SND_SOC_DAI_BFS_DIV, 200 .fs = 750, 201 .bfs = WM8750_HIFI_FSB, 202 }, 203 204 /* 22.05k */ 205 { 206 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 207 .pcmfmt = WM8750_HIFI_BITS, 208 .pcmrate = SNDRV_PCM_RATE_22050, 209 .pcmdir = WM8750_DIR, 210 .flags = SND_SOC_DAI_BFS_DIV, 211 .fs = 512, 212 .bfs = WM8750_HIFI_FSB, 213 }, 214 { 215 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 216 .pcmfmt = WM8750_HIFI_BITS, 217 .pcmrate = SNDRV_PCM_RATE_22050, 218 .pcmdir = WM8750_DIR, 219 .flags = SND_SOC_DAI_BFS_DIV, 220 .fs = 768, 221 .bfs = WM8750_HIFI_FSB, 222 }, 223 { 224 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 225 .pcmfmt = WM8750_HIFI_BITS, 226 .pcmrate = SNDRV_PCM_RATE_22050, 227 .pcmdir = WM8750_DIR, 228 .flags = SND_SOC_DAI_BFS_DIV, 229 .fs = 544, 230 .bfs = WM8750_HIFI_FSB, 231 }, 232 233 /* 32k */ 234 { 235 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 236 .pcmfmt = WM8750_HIFI_BITS, 237 .pcmrate = SNDRV_PCM_RATE_32000, 238 .pcmdir = WM8750_DIR, 239 .flags = SND_SOC_DAI_BFS_DIV, 240 .fs = 384, 241 .bfs = WM8750_HIFI_FSB, 242 }, 243 { 244 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 245 .pcmfmt = WM8750_HIFI_BITS, 246 .pcmrate = SNDRV_PCM_RATE_32000, 247 .pcmdir = WM8750_DIR, 248 .flags = SND_SOC_DAI_BFS_DIV, 249 .fs = 576, 250 .bfs = WM8750_HIFI_FSB, 251 }, 252 { 253 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 254 .pcmfmt = WM8750_HIFI_BITS, 255 .pcmrate = SNDRV_PCM_RATE_32000, 256 .pcmdir = WM8750_DIR, 257 .flags = SND_SOC_DAI_BFS_DIV, 258 .fs = 375, 259 .bfs = WM8750_HIFI_FSB, 260 }, 261 262 /* 44.1k & 48k */ 263 { 264 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 265 .pcmfmt = WM8750_HIFI_BITS, 266 .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 267 .pcmdir = WM8750_DIR, 268 .flags = SND_SOC_DAI_BFS_DIV, 269 .fs = 256, 270 .bfs = WM8750_HIFI_FSB, 271 }, 272 { 273 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 274 .pcmfmt = WM8750_HIFI_BITS, 275 .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 276 .pcmdir = WM8750_DIR, 277 .flags = SND_SOC_DAI_BFS_DIV, 278 .fs = 384, 279 .bfs = WM8750_HIFI_FSB, 280 }, 281 { 282 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 283 .pcmfmt = WM8750_HIFI_BITS, 284 .pcmrate = SNDRV_PCM_RATE_44100, 285 .pcmdir = WM8750_DIR, 286 .flags = SND_SOC_DAI_BFS_DIV, 287 .fs = 272, 288 .bfs = WM8750_HIFI_FSB, 289 }, 290 { 291 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 292 .pcmfmt = WM8750_HIFI_BITS, 293 .pcmrate = SNDRV_PCM_RATE_48000, 294 .pcmdir = WM8750_DIR, 295 .flags = SND_SOC_DAI_BFS_DIV, 296 .fs = 250, 297 .bfs = WM8750_HIFI_FSB, 298 }, 299 300 /* 88.2k & 96k */ 301 { 302 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 303 .pcmfmt = WM8750_HIFI_BITS, 304 .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, 305 .pcmdir = WM8750_DIR, 306 .flags = SND_SOC_DAI_BFS_DIV, 307 .fs = 128, 308 .bfs = WM8750_HIFI_FSB, 309 }, 310 { 311 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 312 .pcmfmt = WM8750_HIFI_BITS, 313 .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, 314 .pcmdir = WM8750_DIR, 315 .flags = SND_SOC_DAI_BFS_DIV, 316 .fs = 192, 317 .bfs = WM8750_HIFI_FSB, 318 }, 319 { 320 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 321 .pcmfmt = WM8750_HIFI_BITS, 322 .pcmrate = SNDRV_PCM_RATE_88200, 323 .pcmdir = WM8750_DIR, 324 .flags = SND_SOC_DAI_BFS_DIV, 325 .fs = 136, 326 .bfs = WM8750_HIFI_FSB, 327 }, 328 { 329 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBM_CFM, 330 .pcmfmt = WM8750_HIFI_BITS, 331 .pcmrate = SNDRV_PCM_RATE_96000, 332 .pcmdir = WM8750_DIR, 333 .flags = SND_SOC_DAI_BFS_DIV, 334 .fs = 125, 335 .bfs = WM8750_HIFI_FSB, 336 }, 337 338 /* codec frame and clock slave modes */ 339 { 340 .fmt = WM8750_HIFI_DAIFMT | SND_SOC_DAIFMT_CBS_CFS, 341 .pcmfmt = WM8750_HIFI_BITS, 342 .pcmrate = WM8750_HIFI_RATES, 343 .pcmdir = WM8750_DIR, 344 .flags = SND_SOC_DAI_BFS_DIV, 345 .fs = SND_SOC_FS_ALL, 346 .bfs = SND_SOC_FSBD_ALL, 347 }, 348 }; 349 350 /* 351 * read wm8750 register cache 352 */ 353 static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec, 354 unsigned int reg) 355 { 356 u16 *cache = codec->reg_cache; 357 if (reg > WM8750_CACHE_REGNUM) 358 return -1; 359 return cache[reg]; 360 } 361 362 /* 363 * write wm8750 register cache 364 */ 365 static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec, 366 unsigned int reg, unsigned int value) 367 { 368 u16 *cache = codec->reg_cache; 369 if (reg > WM8750_CACHE_REGNUM) 370 return; 371 cache[reg] = value; 372 } 373 374 static int wm8750_write(struct snd_soc_codec *codec, unsigned int reg, 375 unsigned int value) 376 { 377 u8 data[2]; 378 379 /* data is 380 * D15..D9 WM8753 register offset 381 * D8...D0 register data 382 */ 383 data[0] = (reg << 1) | ((value >> 8) & 0x0001); 384 data[1] = value & 0x00ff; 385 386 wm8750_write_reg_cache (codec, reg, value); 387 if (codec->hw_write(codec->control_data, data, 2) == 2) 388 return 0; 389 else 390 return -EIO; 391 } 392 393 #define wm8750_reset(c) wm8750_write(c, WM8750_RESET, 0) 394 395 /* 396 * WM8750 Controls 397 */ 398 static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"}; 399 static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; 400 static const char *wm8750_treble[] = {"8kHz", "4kHz"}; 401 static const char *wm8750_3d_lc[] = {"200Hz", "500Hz"}; 402 static const char *wm8750_3d_uc[] = {"2.2kHz", "1.5kHz"}; 403 static const char *wm8750_3d_func[] = {"Capture", "Playback"}; 404 static const char *wm8750_alc_func[] = {"Off", "Right", "Left", "Stereo"}; 405 static const char *wm8750_ng_type[] = {"Constant PGA Gain", 406 "Mute ADC Output"}; 407 static const char *wm8750_line_mux[] = {"Line 1", "Line 2", "Line 3", "PGA", 408 "Differential"}; 409 static const char *wm8750_pga_sel[] = {"Line 1", "Line 2", "Line 3", 410 "Differential"}; 411 static const char *wm8750_out3[] = {"VREF", "ROUT1 + Vol", "MonoOut", 412 "ROUT1"}; 413 static const char *wm8750_diff_sel[] = {"Line 1", "Line 2"}; 414 static const char *wm8750_adcpol[] = {"Normal", "L Invert", "R Invert", 415 "L + R Invert"}; 416 static const char *wm8750_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 417 static const char *wm8750_mono_mux[] = {"Stereo", "Mono (Left)", 418 "Mono (Right)", "Digital Mono"}; 419 420 static const struct soc_enum wm8750_enum[] = { 421 SOC_ENUM_SINGLE(WM8750_BASS, 7, 2, wm8750_bass), 422 SOC_ENUM_SINGLE(WM8750_BASS, 6, 2, wm8750_bass_filter), 423 SOC_ENUM_SINGLE(WM8750_TREBLE, 6, 2, wm8750_treble), 424 SOC_ENUM_SINGLE(WM8750_3D, 5, 2, wm8750_3d_lc), 425 SOC_ENUM_SINGLE(WM8750_3D, 6, 2, wm8750_3d_uc), 426 SOC_ENUM_SINGLE(WM8750_3D, 7, 2, wm8750_3d_func), 427 SOC_ENUM_SINGLE(WM8750_ALC1, 7, 4, wm8750_alc_func), 428 SOC_ENUM_SINGLE(WM8750_NGATE, 1, 2, wm8750_ng_type), 429 SOC_ENUM_SINGLE(WM8750_LOUTM1, 0, 5, wm8750_line_mux), 430 SOC_ENUM_SINGLE(WM8750_ROUTM1, 0, 5, wm8750_line_mux), 431 SOC_ENUM_SINGLE(WM8750_LADCIN, 6, 4, wm8750_pga_sel), /* 10 */ 432 SOC_ENUM_SINGLE(WM8750_RADCIN, 6, 4, wm8750_pga_sel), 433 SOC_ENUM_SINGLE(WM8750_ADCTL2, 7, 4, wm8750_out3), 434 SOC_ENUM_SINGLE(WM8750_ADCIN, 8, 2, wm8750_diff_sel), 435 SOC_ENUM_SINGLE(WM8750_ADCDAC, 5, 4, wm8750_adcpol), 436 SOC_ENUM_SINGLE(WM8750_ADCDAC, 1, 4, wm8750_deemph), 437 SOC_ENUM_SINGLE(WM8750_ADCIN, 6, 4, wm8750_mono_mux), /* 16 */ 438 439 }; 440 441 static const struct snd_kcontrol_new wm8750_snd_controls[] = { 442 443 SOC_DOUBLE_R("Capture Volume", WM8750_LINVOL, WM8750_RINVOL, 0, 63, 0), 444 SOC_DOUBLE_R("Capture ZC Switch", WM8750_LINVOL, WM8750_RINVOL, 6, 1, 0), 445 SOC_DOUBLE_R("Capture Switch", WM8750_LINVOL, WM8750_RINVOL, 7, 1, 1), 446 447 SOC_DOUBLE_R("Out1 Playback ZC Switch", WM8750_LOUT1V, 448 WM8750_ROUT1V, 7, 1, 0), 449 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8750_LOUT2V, 450 WM8750_ROUT2V, 7, 1, 0), 451 452 SOC_ENUM("Playback De-emphasis", wm8750_enum[15]), 453 454 SOC_ENUM("Capture Polarity", wm8750_enum[14]), 455 SOC_SINGLE("Playback 6dB Attenuate", WM8750_ADCDAC, 7, 1, 0), 456 SOC_SINGLE("Capture 6dB Attenuate", WM8750_ADCDAC, 8, 1, 0), 457 458 SOC_DOUBLE_R("PCM Volume", WM8750_LDAC, WM8750_RDAC, 0, 255, 0), 459 460 SOC_ENUM("Bass Boost", wm8750_enum[0]), 461 SOC_ENUM("Bass Filter", wm8750_enum[1]), 462 SOC_SINGLE("Bass Volume", WM8750_BASS, 0, 15, 1), 463 464 SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 0), 465 SOC_ENUM("Treble Cut-off", wm8750_enum[2]), 466 467 SOC_SINGLE("3D Switch", WM8750_3D, 0, 1, 0), 468 SOC_SINGLE("3D Volume", WM8750_3D, 1, 15, 0), 469 SOC_ENUM("3D Lower Cut-off", wm8750_enum[3]), 470 SOC_ENUM("3D Upper Cut-off", wm8750_enum[4]), 471 SOC_ENUM("3D Mode", wm8750_enum[5]), 472 473 SOC_SINGLE("ALC Capture Target Volume", WM8750_ALC1, 0, 7, 0), 474 SOC_SINGLE("ALC Capture Max Volume", WM8750_ALC1, 4, 7, 0), 475 SOC_ENUM("ALC Capture Function", wm8750_enum[6]), 476 SOC_SINGLE("ALC Capture ZC Switch", WM8750_ALC2, 7, 1, 0), 477 SOC_SINGLE("ALC Capture Hold Time", WM8750_ALC2, 0, 15, 0), 478 SOC_SINGLE("ALC Capture Decay Time", WM8750_ALC3, 4, 15, 0), 479 SOC_SINGLE("ALC Capture Attack Time", WM8750_ALC3, 0, 15, 0), 480 SOC_SINGLE("ALC Capture NG Threshold", WM8750_NGATE, 3, 31, 0), 481 SOC_ENUM("ALC Capture NG Type", wm8750_enum[4]), 482 SOC_SINGLE("ALC Capture NG Switch", WM8750_NGATE, 0, 1, 0), 483 484 SOC_SINGLE("Left ADC Capture Volume", WM8750_LADC, 0, 255, 0), 485 SOC_SINGLE("Right ADC Capture Volume", WM8750_RADC, 0, 255, 0), 486 487 SOC_SINGLE("ZC Timeout Switch", WM8750_ADCTL1, 0, 1, 0), 488 SOC_SINGLE("Playback Invert Switch", WM8750_ADCTL1, 1, 1, 0), 489 490 SOC_SINGLE("Right Out2 Playback Invert Switch", WM8750_ADCTL2, 4, 1, 0), 491 492 /* Unimplemented */ 493 /* ADCDAC Bit 0 - ADCHPD */ 494 /* ADCDAC Bit 4 - HPOR */ 495 /* ADCTL1 Bit 2,3 - DATSEL */ 496 /* ADCTL1 Bit 4,5 - DMONOMIX */ 497 /* ADCTL1 Bit 6,7 - VSEL */ 498 /* ADCTL2 Bit 2 - LRCM */ 499 /* ADCTL2 Bit 3 - TRI */ 500 /* ADCTL3 Bit 5 - HPFLREN */ 501 /* ADCTL3 Bit 6 - VROI */ 502 /* ADCTL3 Bit 7,8 - ADCLRM */ 503 /* ADCIN Bit 4 - LDCM */ 504 /* ADCIN Bit 5 - RDCM */ 505 506 SOC_DOUBLE_R("Mic Boost", WM8750_LADCIN, WM8750_RADCIN, 4, 3, 0), 507 508 SOC_DOUBLE_R("Bypass Left Playback Volume", WM8750_LOUTM1, 509 WM8750_LOUTM2, 4, 7, 1), 510 SOC_DOUBLE_R("Bypass Right Playback Volume", WM8750_ROUTM1, 511 WM8750_ROUTM2, 4, 7, 1), 512 SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8750_MOUTM1, 513 WM8750_MOUTM2, 4, 7, 1), 514 515 SOC_SINGLE("Mono Playback ZC Switch", WM8750_MOUTV, 7, 1, 0), 516 517 SOC_DOUBLE_R("Out1 Playback Volume", WM8750_LOUT1V, WM8750_ROUT1V, 0, 127, 0), 518 SOC_DOUBLE_R("Out2 Playback Volume", WM8750_LOUT2V, WM8750_ROUT2V, 0, 127, 0), 519 520 SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0), 521 522 }; 523 524 /* add non dapm controls */ 525 static int wm8750_add_controls(struct snd_soc_codec *codec) 526 { 527 int err, i; 528 529 for (i = 0; i < ARRAY_SIZE(wm8750_snd_controls); i++) { 530 err = snd_ctl_add(codec->card, 531 snd_soc_cnew(&wm8750_snd_controls[i],codec, NULL)); 532 if (err < 0) 533 return err; 534 } 535 return 0; 536 } 537 538 /* 539 * DAPM Controls 540 */ 541 542 /* Left Mixer */ 543 static const struct snd_kcontrol_new wm8750_left_mixer_controls[] = { 544 SOC_DAPM_SINGLE("Playback Switch", WM8750_LOUTM1, 8, 1, 0), 545 SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_LOUTM1, 7, 1, 0), 546 SOC_DAPM_SINGLE("Right Playback Switch", WM8750_LOUTM2, 8, 1, 0), 547 SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_LOUTM2, 7, 1, 0), 548 }; 549 550 /* Right Mixer */ 551 static const struct snd_kcontrol_new wm8750_right_mixer_controls[] = { 552 SOC_DAPM_SINGLE("Left Playback Switch", WM8750_ROUTM1, 8, 1, 0), 553 SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_ROUTM1, 7, 1, 0), 554 SOC_DAPM_SINGLE("Playback Switch", WM8750_ROUTM2, 8, 1, 0), 555 SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_ROUTM2, 7, 1, 0), 556 }; 557 558 /* Mono Mixer */ 559 static const struct snd_kcontrol_new wm8750_mono_mixer_controls[] = { 560 SOC_DAPM_SINGLE("Left Playback Switch", WM8750_MOUTM1, 8, 1, 0), 561 SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_MOUTM1, 7, 1, 0), 562 SOC_DAPM_SINGLE("Right Playback Switch", WM8750_MOUTM2, 8, 1, 0), 563 SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_MOUTM2, 7, 1, 0), 564 }; 565 566 /* Left Line Mux */ 567 static const struct snd_kcontrol_new wm8750_left_line_controls = 568 SOC_DAPM_ENUM("Route", wm8750_enum[8]); 569 570 /* Right Line Mux */ 571 static const struct snd_kcontrol_new wm8750_right_line_controls = 572 SOC_DAPM_ENUM("Route", wm8750_enum[9]); 573 574 /* Left PGA Mux */ 575 static const struct snd_kcontrol_new wm8750_left_pga_controls = 576 SOC_DAPM_ENUM("Route", wm8750_enum[10]); 577 578 /* Right PGA Mux */ 579 static const struct snd_kcontrol_new wm8750_right_pga_controls = 580 SOC_DAPM_ENUM("Route", wm8750_enum[11]); 581 582 /* Out 3 Mux */ 583 static const struct snd_kcontrol_new wm8750_out3_controls = 584 SOC_DAPM_ENUM("Route", wm8750_enum[12]); 585 586 /* Differential Mux */ 587 static const struct snd_kcontrol_new wm8750_diffmux_controls = 588 SOC_DAPM_ENUM("Route", wm8750_enum[13]); 589 590 /* Mono ADC Mux */ 591 static const struct snd_kcontrol_new wm8750_monomux_controls = 592 SOC_DAPM_ENUM("Route", wm8750_enum[16]); 593 594 static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { 595 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, 596 &wm8750_left_mixer_controls[0], 597 ARRAY_SIZE(wm8750_left_mixer_controls)), 598 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, 599 &wm8750_right_mixer_controls[0], 600 ARRAY_SIZE(wm8750_right_mixer_controls)), 601 SND_SOC_DAPM_MIXER("Mono Mixer", WM8750_PWR2, 2, 0, 602 &wm8750_mono_mixer_controls[0], 603 ARRAY_SIZE(wm8750_mono_mixer_controls)), 604 605 SND_SOC_DAPM_PGA("Right Out 2", WM8750_PWR2, 3, 0, NULL, 0), 606 SND_SOC_DAPM_PGA("Left Out 2", WM8750_PWR2, 4, 0, NULL, 0), 607 SND_SOC_DAPM_PGA("Right Out 1", WM8750_PWR2, 5, 0, NULL, 0), 608 SND_SOC_DAPM_PGA("Left Out 1", WM8750_PWR2, 6, 0, NULL, 0), 609 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8750_PWR2, 7, 0), 610 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8750_PWR2, 8, 0), 611 612 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8750_PWR1, 1, 0), 613 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8750_PWR1, 2, 0), 614 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8750_PWR1, 3, 0), 615 616 SND_SOC_DAPM_MUX("Left PGA Mux", WM8750_PWR1, 5, 0, 617 &wm8750_left_pga_controls), 618 SND_SOC_DAPM_MUX("Right PGA Mux", WM8750_PWR1, 4, 0, 619 &wm8750_right_pga_controls), 620 SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, 621 &wm8750_left_line_controls), 622 SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, 623 &wm8750_right_line_controls), 624 625 SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8750_out3_controls), 626 SND_SOC_DAPM_PGA("Out 3", WM8750_PWR2, 1, 0, NULL, 0), 627 SND_SOC_DAPM_PGA("Mono Out 1", WM8750_PWR2, 2, 0, NULL, 0), 628 629 SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, 630 &wm8750_diffmux_controls), 631 SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, 632 &wm8750_monomux_controls), 633 SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, 634 &wm8750_monomux_controls), 635 636 SND_SOC_DAPM_OUTPUT("LOUT1"), 637 SND_SOC_DAPM_OUTPUT("ROUT1"), 638 SND_SOC_DAPM_OUTPUT("LOUT2"), 639 SND_SOC_DAPM_OUTPUT("ROUT2"), 640 SND_SOC_DAPM_OUTPUT("MONO"), 641 SND_SOC_DAPM_OUTPUT("OUT3"), 642 643 SND_SOC_DAPM_INPUT("LINPUT1"), 644 SND_SOC_DAPM_INPUT("LINPUT2"), 645 SND_SOC_DAPM_INPUT("LINPUT3"), 646 SND_SOC_DAPM_INPUT("RINPUT1"), 647 SND_SOC_DAPM_INPUT("RINPUT2"), 648 SND_SOC_DAPM_INPUT("RINPUT3"), 649 }; 650 651 static const char *audio_map[][3] = { 652 /* left mixer */ 653 {"Left Mixer", "Playback Switch", "Left DAC"}, 654 {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, 655 {"Left Mixer", "Right Playback Switch", "Right DAC"}, 656 {"Left Mixer", "Right Bypass Switch", "Right Line Mux"}, 657 658 /* right mixer */ 659 {"Right Mixer", "Left Playback Switch", "Left DAC"}, 660 {"Right Mixer", "Left Bypass Switch", "Left Line Mux"}, 661 {"Right Mixer", "Playback Switch", "Right DAC"}, 662 {"Right Mixer", "Right Bypass Switch", "Right Line Mux"}, 663 664 /* left out 1 */ 665 {"Left Out 1", NULL, "Left Mixer"}, 666 {"LOUT1", NULL, "Left Out 1"}, 667 668 /* left out 2 */ 669 {"Left Out 2", NULL, "Left Mixer"}, 670 {"LOUT2", NULL, "Left Out 2"}, 671 672 /* right out 1 */ 673 {"Right Out 1", NULL, "Right Mixer"}, 674 {"ROUT1", NULL, "Right Out 1"}, 675 676 /* right out 2 */ 677 {"Right Out 2", NULL, "Right Mixer"}, 678 {"ROUT2", NULL, "Right Out 2"}, 679 680 /* mono mixer */ 681 {"Mono Mixer", "Left Playback Switch", "Left DAC"}, 682 {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"}, 683 {"Mono Mixer", "Right Playback Switch", "Right DAC"}, 684 {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"}, 685 686 /* mono out */ 687 {"Mono Out 1", NULL, "Mono Mixer"}, 688 {"MONO1", NULL, "Mono Out 1"}, 689 690 /* out 3 */ 691 {"Out3 Mux", "VREF", "VREF"}, 692 {"Out3 Mux", "ROUT1 + Vol", "ROUT1"}, 693 {"Out3 Mux", "ROUT1", "Right Mixer"}, 694 {"Out3 Mux", "MonoOut", "MONO1"}, 695 {"Out 3", NULL, "Out3 Mux"}, 696 {"OUT3", NULL, "Out 3"}, 697 698 /* Left Line Mux */ 699 {"Left Line Mux", "Line 1", "LINPUT1"}, 700 {"Left Line Mux", "Line 2", "LINPUT2"}, 701 {"Left Line Mux", "Line 3", "LINPUT3"}, 702 {"Left Line Mux", "PGA", "Left PGA Mux"}, 703 {"Left Line Mux", "Differential", "Differential Mux"}, 704 705 /* Right Line Mux */ 706 {"Right Line Mux", "Line 1", "RINPUT1"}, 707 {"Right Line Mux", "Line 2", "RINPUT2"}, 708 {"Right Line Mux", "Line 3", "RINPUT3"}, 709 {"Right Line Mux", "PGA", "Right PGA Mux"}, 710 {"Right Line Mux", "Differential", "Differential Mux"}, 711 712 /* Left PGA Mux */ 713 {"Left PGA Mux", "Line 1", "LINPUT1"}, 714 {"Left PGA Mux", "Line 2", "LINPUT2"}, 715 {"Left PGA Mux", "Line 3", "LINPUT3"}, 716 {"Left PGA Mux", "Differential", "Differential Mux"}, 717 718 /* Right PGA Mux */ 719 {"Right PGA Mux", "Line 1", "RINPUT1"}, 720 {"Right PGA Mux", "Line 2", "RINPUT2"}, 721 {"Right PGA Mux", "Line 3", "RINPUT3"}, 722 {"Right PGA Mux", "Differential", "Differential Mux"}, 723 724 /* Differential Mux */ 725 {"Differential Mux", "Line 1", "LINPUT1"}, 726 {"Differential Mux", "Line 1", "RINPUT1"}, 727 {"Differential Mux", "Line 2", "LINPUT2"}, 728 {"Differential Mux", "Line 2", "RINPUT2"}, 729 730 /* Left ADC Mux */ 731 {"Left ADC Mux", "Stereo", "Left PGA Mux"}, 732 {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"}, 733 {"Left ADC Mux", "Digital Mono", "Left PGA Mux"}, 734 735 /* Right ADC Mux */ 736 {"Right ADC Mux", "Stereo", "Right PGA Mux"}, 737 {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"}, 738 {"Right ADC Mux", "Digital Mono", "Right PGA Mux"}, 739 740 /* ADC */ 741 {"Left ADC", NULL, "Left ADC Mux"}, 742 {"Right ADC", NULL, "Right ADC Mux"}, 743 744 /* terminator */ 745 {NULL, NULL, NULL}, 746 }; 747 748 static int wm8750_add_widgets(struct snd_soc_codec *codec) 749 { 750 int i; 751 752 for(i = 0; i < ARRAY_SIZE(wm8750_dapm_widgets); i++) { 753 snd_soc_dapm_new_control(codec, &wm8750_dapm_widgets[i]); 754 } 755 756 /* set up audio path audio_mapnects */ 757 for(i = 0; audio_map[i][0] != NULL; i++) { 758 snd_soc_dapm_connect_input(codec, audio_map[i][0], 759 audio_map[i][1], audio_map[i][2]); 760 } 761 762 snd_soc_dapm_new_widgets(codec); 763 return 0; 764 } 765 766 struct _coeff_div { 767 u32 mclk; 768 u32 rate; 769 u16 fs; 770 u8 sr:5; 771 u8 usb:1; 772 }; 773 774 /* codec hifi mclk clock divider coefficients */ 775 static const struct _coeff_div coeff_div[] = { 776 /* 8k */ 777 {12288000, 8000, 1536, 0x6, 0x0}, 778 {11289600, 8000, 1408, 0x16, 0x0}, 779 {18432000, 8000, 2304, 0x7, 0x0}, 780 {16934400, 8000, 2112, 0x17, 0x0}, 781 {12000000, 8000, 1500, 0x6, 0x1}, 782 783 /* 11.025k */ 784 {11289600, 11025, 1024, 0x18, 0x0}, 785 {16934400, 11025, 1536, 0x19, 0x0}, 786 {12000000, 11025, 1088, 0x19, 0x1}, 787 788 /* 16k */ 789 {12288000, 16000, 768, 0xa, 0x0}, 790 {18432000, 16000, 1152, 0xb, 0x0}, 791 {12000000, 16000, 750, 0xa, 0x1}, 792 793 /* 22.05k */ 794 {11289600, 22050, 512, 0x1a, 0x0}, 795 {16934400, 22050, 768, 0x1b, 0x0}, 796 {12000000, 22050, 544, 0x1b, 0x1}, 797 798 /* 32k */ 799 {12288000, 32000, 384, 0xc, 0x0}, 800 {18432000, 32000, 576, 0xd, 0x0}, 801 {12000000, 32000, 375, 0xa, 0x1}, 802 803 /* 44.1k */ 804 {11289600, 44100, 256, 0x10, 0x0}, 805 {16934400, 44100, 384, 0x11, 0x0}, 806 {12000000, 44100, 272, 0x11, 0x1}, 807 808 /* 48k */ 809 {12288000, 48000, 256, 0x0, 0x0}, 810 {18432000, 48000, 384, 0x1, 0x0}, 811 {12000000, 48000, 250, 0x0, 0x1}, 812 813 /* 88.2k */ 814 {11289600, 88200, 128, 0x1e, 0x0}, 815 {16934400, 88200, 192, 0x1f, 0x0}, 816 {12000000, 88200, 136, 0x1f, 0x1}, 817 818 /* 96k */ 819 {12288000, 96000, 128, 0xe, 0x0}, 820 {18432000, 96000, 192, 0xf, 0x0}, 821 {12000000, 96000, 125, 0xe, 0x1}, 822 }; 823 824 static inline int get_coeff(int mclk, int rate) 825 { 826 int i; 827 828 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 829 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) 830 return i; 831 } 832 return -EINVAL; 833 } 834 835 /* WM8750 supports numerous input clocks per sample rate */ 836 static unsigned int wm8750_config_sysclk(struct snd_soc_codec_dai *dai, 837 struct snd_soc_clock_info *info, unsigned int clk) 838 { 839 dai->mclk = 0; 840 841 /* check that the calculated FS and rate actually match a clock from 842 * the machine driver */ 843 if (info->fs * info->rate == clk) 844 dai->mclk = clk; 845 846 return dai->mclk; 847 } 848 849 static int wm8750_pcm_prepare(struct snd_pcm_substream *substream) 850 { 851 struct snd_soc_pcm_runtime *rtd = substream->private_data; 852 struct snd_soc_device *socdev = rtd->socdev; 853 struct snd_soc_codec *codec = socdev->codec; 854 u16 iface = 0, bfs, srate = 0; 855 int i = get_coeff(rtd->codec_dai->mclk, 856 snd_soc_get_rate(rtd->codec_dai->dai_runtime.pcmrate)); 857 858 /* is coefficient valid ? */ 859 if (i < 0) 860 return i; 861 862 bfs = SND_SOC_FSB_REAL(rtd->codec_dai->dai_runtime.bfs); 863 864 /* set master/slave audio interface */ 865 switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK) { 866 case SND_SOC_DAIFMT_CBM_CFM: 867 iface = 0x0040; 868 break; 869 case SND_SOC_DAIFMT_CBS_CFS: 870 break; 871 } 872 873 /* interface format */ 874 switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 875 case SND_SOC_DAIFMT_I2S: 876 iface |= 0x0002; 877 break; 878 case SND_SOC_DAIFMT_RIGHT_J: 879 break; 880 case SND_SOC_DAIFMT_LEFT_J: 881 iface |= 0x0001; 882 break; 883 case SND_SOC_DAIFMT_DSP_A: 884 iface |= 0x0003; 885 break; 886 case SND_SOC_DAIFMT_DSP_B: 887 iface |= 0x0013; 888 break; 889 } 890 891 /* bit size */ 892 switch (rtd->codec_dai->dai_runtime.pcmfmt) { 893 case SNDRV_PCM_FMTBIT_S16_LE: 894 break; 895 case SNDRV_PCM_FMTBIT_S20_3LE: 896 iface |= 0x0004; 897 break; 898 case SNDRV_PCM_FMTBIT_S24_LE: 899 iface |= 0x0008; 900 break; 901 case SNDRV_PCM_FMTBIT_S32_LE: 902 iface |= 0x000c; 903 break; 904 } 905 906 /* clock inversion */ 907 switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_INV_MASK) { 908 case SND_SOC_DAIFMT_NB_NF: 909 break; 910 case SND_SOC_DAIFMT_IB_IF: 911 iface |= 0x0090; 912 break; 913 case SND_SOC_DAIFMT_IB_NF: 914 iface |= 0x0080; 915 break; 916 case SND_SOC_DAIFMT_NB_IF: 917 iface |= 0x0010; 918 break; 919 } 920 921 /* set bclk divisor rate */ 922 switch (bfs) { 923 case 1: 924 break; 925 case 4: 926 srate |= (0x1 << 7); 927 break; 928 case 8: 929 srate |= (0x2 << 7); 930 break; 931 case 16: 932 srate |= (0x3 << 7); 933 break; 934 } 935 936 /* set iface & srate */ 937 wm8750_write(codec, WM8750_IFACE, iface); 938 wm8750_write(codec, WM8750_SRATE, srate | 939 (coeff_div[i].sr << 1) | coeff_div[i].usb); 940 941 return 0; 942 } 943 944 static int wm8750_mute(struct snd_soc_codec *codec, 945 struct snd_soc_codec_dai *dai, int mute) 946 { 947 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; 948 if (mute) 949 wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8); 950 else 951 wm8750_write(codec, WM8750_ADCDAC, mute_reg); 952 return 0; 953 } 954 955 static int wm8750_dapm_event(struct snd_soc_codec *codec, int event) 956 { 957 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; 958 959 switch (event) { 960 case SNDRV_CTL_POWER_D0: /* full On */ 961 /* set vmid to 50k and unmute dac */ 962 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 963 break; 964 case SNDRV_CTL_POWER_D1: /* partial On */ 965 case SNDRV_CTL_POWER_D2: /* partial On */ 966 /* set vmid to 5k for quick power up */ 967 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 968 break; 969 case SNDRV_CTL_POWER_D3hot: /* Off, with power */ 970 /* mute dac and set vmid to 500k, enable VREF */ 971 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 972 break; 973 case SNDRV_CTL_POWER_D3cold: /* Off, without power */ 974 wm8750_write(codec, WM8750_PWR1, 0x0001); 975 break; 976 } 977 codec->dapm_state = event; 978 return 0; 979 } 980 981 struct snd_soc_codec_dai wm8750_dai = { 982 .name = "WM8750", 983 .playback = { 984 .stream_name = "Playback", 985 .channels_min = 1, 986 .channels_max = 2, 987 }, 988 .capture = { 989 .stream_name = "Capture", 990 .channels_min = 1, 991 .channels_max = 2, 992 }, 993 .config_sysclk = wm8750_config_sysclk, 994 .digital_mute = wm8750_mute, 995 .ops = { 996 .prepare = wm8750_pcm_prepare, 997 }, 998 .caps = { 999 .num_modes = ARRAY_SIZE(wm8750_modes), 1000 .mode = wm8750_modes, 1001 }, 1002 }; 1003 EXPORT_SYMBOL_GPL(wm8750_dai); 1004 1005 static void wm8750_work(void *data) 1006 { 1007 struct snd_soc_codec *codec = (struct snd_soc_codec *)data; 1008 wm8750_dapm_event(codec, codec->dapm_state); 1009 } 1010 1011 static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 1012 { 1013 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1014 struct snd_soc_codec *codec = socdev->codec; 1015 1016 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 1017 return 0; 1018 } 1019 1020 static int wm8750_resume(struct platform_device *pdev) 1021 { 1022 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1023 struct snd_soc_codec *codec = socdev->codec; 1024 int i; 1025 u8 data[2]; 1026 u16 *cache = codec->reg_cache; 1027 1028 /* Sync reg_cache with the hardware */ 1029 for (i = 0; i < ARRAY_SIZE(wm8750_reg); i++) { 1030 if (i == WM8750_RESET) 1031 continue; 1032 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 1033 data[1] = cache[i] & 0x00ff; 1034 codec->hw_write(codec->control_data, data, 2); 1035 } 1036 1037 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3hot); 1038 1039 /* charge wm8750 caps */ 1040 if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { 1041 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); 1042 codec->dapm_state = SNDRV_CTL_POWER_D0; 1043 queue_delayed_work(wm8750_workq, &wm8750_dapm_work, 1044 msecs_to_jiffies(1000)); 1045 } 1046 1047 return 0; 1048 } 1049 1050 /* 1051 * initialise the WM8750 driver 1052 * register the mixer and dsp interfaces with the kernel 1053 */ 1054 static int wm8750_init(struct snd_soc_device *socdev) 1055 { 1056 struct snd_soc_codec *codec = socdev->codec; 1057 int reg, ret = 0; 1058 1059 codec->name = "WM8750"; 1060 codec->owner = THIS_MODULE; 1061 codec->read = wm8750_read_reg_cache; 1062 codec->write = wm8750_write; 1063 codec->dapm_event = wm8750_dapm_event; 1064 codec->dai = &wm8750_dai; 1065 codec->num_dai = 1; 1066 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg); 1067 1068 codec->reg_cache = 1069 kzalloc(sizeof(u16) * ARRAY_SIZE(wm8750_reg), GFP_KERNEL); 1070 if (codec->reg_cache == NULL) 1071 return -ENOMEM; 1072 memcpy(codec->reg_cache, wm8750_reg, 1073 sizeof(u16) * ARRAY_SIZE(wm8750_reg)); 1074 codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm8750_reg); 1075 1076 wm8750_reset(codec); 1077 1078 /* register pcms */ 1079 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1080 if (ret < 0) { 1081 kfree(codec->reg_cache); 1082 return ret; 1083 } 1084 1085 /* charge output caps */ 1086 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D2); 1087 codec->dapm_state = SNDRV_CTL_POWER_D3hot; 1088 queue_delayed_work(wm8750_workq, &wm8750_dapm_work, 1089 msecs_to_jiffies(1000)); 1090 1091 /* set the update bits */ 1092 reg = wm8750_read_reg_cache(codec, WM8750_LDAC); 1093 wm8750_write(codec, WM8750_LDAC, reg | 0x0100); 1094 reg = wm8750_read_reg_cache(codec, WM8750_RDAC); 1095 wm8750_write(codec, WM8750_RDAC, reg | 0x0100); 1096 reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V); 1097 wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100); 1098 reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V); 1099 wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100); 1100 reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V); 1101 wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100); 1102 reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V); 1103 wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100); 1104 reg = wm8750_read_reg_cache(codec, WM8750_LINVOL); 1105 wm8750_write(codec, WM8750_LINVOL, reg | 0x0100); 1106 reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); 1107 wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); 1108 1109 wm8750_add_controls(codec); 1110 wm8750_add_widgets(codec); 1111 ret = snd_soc_register_card(socdev); 1112 if (ret < 0) { 1113 snd_soc_free_pcms(socdev); 1114 snd_soc_dapm_free(socdev); 1115 } 1116 1117 return ret; 1118 } 1119 1120 /* If the i2c layer weren't so broken, we could pass this kind of data 1121 around */ 1122 static struct snd_soc_device *wm8750_socdev; 1123 1124 #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 1125 1126 /* 1127 * WM8731 2 wire address is determined by GPIO5 1128 * state during powerup. 1129 * low = 0x1a 1130 * high = 0x1b 1131 */ 1132 static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 1133 1134 /* Magic definition of all other variables and things */ 1135 I2C_CLIENT_INSMOD; 1136 1137 static struct i2c_driver wm8750_i2c_driver; 1138 static struct i2c_client client_template; 1139 1140 static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind) 1141 { 1142 struct snd_soc_device *socdev = wm8750_socdev; 1143 struct wm8750_setup_data *setup = socdev->codec_data; 1144 struct snd_soc_codec *codec = socdev->codec; 1145 struct i2c_client *i2c; 1146 int ret; 1147 1148 if (addr != setup->i2c_address) 1149 return -ENODEV; 1150 1151 client_template.adapter = adap; 1152 client_template.addr = addr; 1153 1154 i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 1155 if (i2c == NULL) { 1156 kfree(codec); 1157 return -ENOMEM; 1158 } 1159 memcpy(i2c, &client_template, sizeof(struct i2c_client)); 1160 i2c_set_clientdata(i2c, codec); 1161 codec->control_data = i2c; 1162 1163 ret = i2c_attach_client(i2c); 1164 if (ret < 0) { 1165 err("failed to attach codec at addr %x\n", addr); 1166 goto err; 1167 } 1168 1169 ret = wm8750_init(socdev); 1170 if (ret < 0) { 1171 err("failed to initialise WM8750\n"); 1172 goto err; 1173 } 1174 return ret; 1175 1176 err: 1177 kfree(codec); 1178 kfree(i2c); 1179 return ret; 1180 } 1181 1182 static int wm8750_i2c_detach(struct i2c_client *client) 1183 { 1184 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1185 i2c_detach_client(client); 1186 kfree(codec->reg_cache); 1187 kfree(client); 1188 return 0; 1189 } 1190 1191 static int wm8750_i2c_attach(struct i2c_adapter *adap) 1192 { 1193 return i2c_probe(adap, &addr_data, wm8750_codec_probe); 1194 } 1195 1196 /* corgi i2c codec control layer */ 1197 static struct i2c_driver wm8750_i2c_driver = { 1198 .driver = { 1199 .name = "WM8750 I2C Codec", 1200 .owner = THIS_MODULE, 1201 }, 1202 .id = I2C_DRIVERID_WM8750, 1203 .attach_adapter = wm8750_i2c_attach, 1204 .detach_client = wm8750_i2c_detach, 1205 .command = NULL, 1206 }; 1207 1208 static struct i2c_client client_template = { 1209 .name = "WM8750", 1210 .driver = &wm8750_i2c_driver, 1211 }; 1212 #endif 1213 1214 static int wm8750_probe(struct platform_device *pdev) 1215 { 1216 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1217 struct wm8750_setup_data *setup = socdev->codec_data; 1218 struct snd_soc_codec *codec; 1219 int ret = 0; 1220 1221 info("WM8750 Audio Codec %s", WM8750_VERSION); 1222 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1223 if (codec == NULL) 1224 return -ENOMEM; 1225 1226 socdev->codec = codec; 1227 mutex_init(&codec->mutex); 1228 INIT_LIST_HEAD(&codec->dapm_widgets); 1229 INIT_LIST_HEAD(&codec->dapm_paths); 1230 wm8750_socdev = socdev; 1231 INIT_WORK(&wm8750_dapm_work, wm8750_work, codec); 1232 wm8750_workq = create_workqueue("wm8750"); 1233 if (wm8750_workq == NULL) { 1234 kfree(codec); 1235 return -ENOMEM; 1236 } 1237 #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 1238 if (setup->i2c_address) { 1239 normal_i2c[0] = setup->i2c_address; 1240 codec->hw_write = (hw_write_t)i2c_master_send; 1241 ret = i2c_add_driver(&wm8750_i2c_driver); 1242 if (ret != 0) 1243 printk(KERN_ERR "can't add i2c driver"); 1244 } 1245 #else 1246 /* Add other interfaces here */ 1247 #endif 1248 1249 return ret; 1250 } 1251 1252 /* power down chip */ 1253 static int wm8750_remove(struct platform_device *pdev) 1254 { 1255 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1256 struct snd_soc_codec *codec = socdev->codec; 1257 1258 if (codec->control_data) 1259 wm8750_dapm_event(codec, SNDRV_CTL_POWER_D3cold); 1260 if (wm8750_workq) 1261 destroy_workqueue(wm8750_workq); 1262 snd_soc_free_pcms(socdev); 1263 snd_soc_dapm_free(socdev); 1264 #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 1265 i2c_del_driver(&wm8750_i2c_driver); 1266 #endif 1267 kfree(codec); 1268 1269 return 0; 1270 } 1271 1272 struct snd_soc_codec_device soc_codec_dev_wm8750 = { 1273 .probe = wm8750_probe, 1274 .remove = wm8750_remove, 1275 .suspend = wm8750_suspend, 1276 .resume = wm8750_resume, 1277 }; 1278 1279 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); 1280 1281 MODULE_DESCRIPTION("ASoC WM8750 driver"); 1282 MODULE_AUTHOR("Liam Girdwood"); 1283 MODULE_LICENSE("GPL"); 1284