| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8903.c -- WM8903 ALSA SoC Audio driver | 2 * wm8903.c -- WM8903 ALSA SoC Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2008 Wolfson Microelectronics | 4 * Copyright 2008 Wolfson Microelectronics |
| 5 * Copyright 2011 NVIDIA, Inc. |
| 5 * | 6 * |
| 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 7 * | 8 * |
| 8 * This program is free software; you can redistribute it and/or modify | 9 * This program is free software; you can redistribute it and/or modify |
| 9 * it under the terms of the GNU General Public License version 2 as | 10 * it under the terms of the GNU General Public License version 2 as |
| 10 * published by the Free Software Foundation. | 11 * published by the Free Software Foundation. |
| 11 * | 12 * |
| 12 * TODO: | 13 * TODO: |
| 13 * - TDM mode configuration. | 14 * - TDM mode configuration. |
| 14 * - Digital microphone support. | 15 * - Digital microphone support. |
| 15 */ | 16 */ |
| 16 | 17 |
| 17 #include <linux/module.h> | 18 #include <linux/module.h> |
| 18 #include <linux/moduleparam.h> | 19 #include <linux/moduleparam.h> |
| 19 #include <linux/init.h> | 20 #include <linux/init.h> |
| 20 #include <linux/completion.h> | 21 #include <linux/completion.h> |
| 21 #include <linux/delay.h> | 22 #include <linux/delay.h> |
| 23 #include <linux/gpio.h> |
| 22 #include <linux/pm.h> | 24 #include <linux/pm.h> |
| 23 #include <linux/i2c.h> | 25 #include <linux/i2c.h> |
| 24 #include <linux/platform_device.h> | 26 #include <linux/platform_device.h> |
| 25 #include <linux/slab.h> | 27 #include <linux/slab.h> |
| 26 #include <sound/core.h> | 28 #include <sound/core.h> |
| 27 #include <sound/jack.h> | 29 #include <sound/jack.h> |
| 28 #include <sound/pcm.h> | 30 #include <sound/pcm.h> |
| 29 #include <sound/pcm_params.h> | 31 #include <sound/pcm_params.h> |
| 30 #include <sound/tlv.h> | 32 #include <sound/tlv.h> |
| 31 #include <sound/soc.h> | 33 #include <sound/soc.h> |
| 32 #include <sound/soc-dapm.h> | |
| 33 #include <sound/initval.h> | 34 #include <sound/initval.h> |
| 34 #include <sound/wm8903.h> | 35 #include <sound/wm8903.h> |
| 36 #include <trace/events/asoc.h> |
| 35 | 37 |
| 36 #include "wm8903.h" | 38 #include "wm8903.h" |
| 37 | 39 |
| 38 /* Register defaults at reset */ | 40 /* Register defaults at reset */ |
| 39 static u16 wm8903_reg_defaults[] = { | 41 static u16 wm8903_reg_defaults[] = { |
| 40 0x8903, /* R0 - SW Reset and ID */ | 42 0x8903, /* R0 - SW Reset and ID */ |
| 41 0x0000, /* R1 - Revision Number */ | 43 0x0000, /* R1 - Revision Number */ |
| 42 0x0000, /* R2 */ | 44 0x0000, /* R2 */ |
| 43 0x0000, /* R3 */ | 45 0x0000, /* R3 */ |
| 44 0x0018, /* R4 - Bias Control 0 */ | 46 0x0018, /* R4 - Bias Control 0 */ |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 0x0000, /* R166 */ | 208 0x0000, /* R166 */ |
| 207 0x0060, /* R167 */ | 209 0x0060, /* R167 */ |
| 208 0x0000, /* R168 */ | 210 0x0000, /* R168 */ |
| 209 0x0000, /* R169 */ | 211 0x0000, /* R169 */ |
| 210 0x0000, /* R170 */ | 212 0x0000, /* R170 */ |
| 211 0x0000, /* R171 */ | 213 0x0000, /* R171 */ |
| 212 0x0000, /* R172 - Analogue Output Bias 0 */ | 214 0x0000, /* R172 - Analogue Output Bias 0 */ |
| 213 }; | 215 }; |
| 214 | 216 |
| 215 struct wm8903_priv { | 217 struct wm8903_priv { |
| 216 | 218 » struct snd_soc_codec *codec; |
| 217 » u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)]; | |
| 218 | 219 |
| 219 int sysclk; | 220 int sysclk; |
| 220 int irq; | 221 int irq; |
| 221 | 222 |
| 222 » /* Reference counts */ | 223 » int fs; |
| 224 » int deemph; |
| 225 |
| 226 » int dcs_pending; |
| 227 » int dcs_cache[4]; |
| 228 |
| 229 » /* Reference count */ |
| 223 int class_w_users; | 230 int class_w_users; |
| 224 int playback_active; | |
| 225 int capture_active; | |
| 226 | |
| 227 struct completion wseq; | |
| 228 | 231 |
| 229 struct snd_soc_jack *mic_jack; | 232 struct snd_soc_jack *mic_jack; |
| 230 int mic_det; | 233 int mic_det; |
| 231 int mic_short; | 234 int mic_short; |
| 232 int mic_last_report; | 235 int mic_last_report; |
| 233 int mic_delay; | 236 int mic_delay; |
| 234 | 237 |
| 235 » struct snd_pcm_substream *master_substream; | 238 #ifdef CONFIG_GPIOLIB |
| 236 » struct snd_pcm_substream *slave_substream; | 239 » struct gpio_chip gpio_chip; |
| 240 #endif |
| 237 }; | 241 }; |
| 238 | 242 |
| 239 static int wm8903_volatile_register(unsigned int reg) | 243 static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int re
g) |
| 240 { | 244 { |
| 241 switch (reg) { | 245 switch (reg) { |
| 242 case WM8903_SW_RESET_AND_ID: | 246 case WM8903_SW_RESET_AND_ID: |
| 243 case WM8903_REVISION_NUMBER: | 247 case WM8903_REVISION_NUMBER: |
| 244 case WM8903_INTERRUPT_STATUS_1: | 248 case WM8903_INTERRUPT_STATUS_1: |
| 245 case WM8903_WRITE_SEQUENCER_4: | 249 case WM8903_WRITE_SEQUENCER_4: |
| 250 case WM8903_POWER_MANAGEMENT_3: |
| 251 case WM8903_POWER_MANAGEMENT_2: |
| 252 case WM8903_DC_SERVO_READBACK_1: |
| 253 case WM8903_DC_SERVO_READBACK_2: |
| 254 case WM8903_DC_SERVO_READBACK_3: |
| 255 case WM8903_DC_SERVO_READBACK_4: |
| 246 return 1; | 256 return 1; |
| 247 | 257 |
| 248 default: | 258 default: |
| 249 return 0; | 259 return 0; |
| 250 } | 260 } |
| 251 } | 261 } |
| 252 | 262 |
| 253 static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) | |
| 254 { | |
| 255 u16 reg[5]; | |
| 256 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | |
| 257 | |
| 258 BUG_ON(start > 48); | |
| 259 | |
| 260 /* Enable the sequencer if it's not already on */ | |
| 261 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0); | |
| 262 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, | |
| 263 reg[0] | WM8903_WSEQ_ENA); | |
| 264 | |
| 265 dev_dbg(codec->dev, "Starting sequence at %d\n", start); | |
| 266 | |
| 267 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3, | |
| 268 start | WM8903_WSEQ_START); | |
| 269 | |
| 270 /* Wait for it to complete. If we have the interrupt wired up then | |
| 271 * that will break us out of the poll early. | |
| 272 */ | |
| 273 do { | |
| 274 wait_for_completion_timeout(&wm8903->wseq, | |
| 275 msecs_to_jiffies(10)); | |
| 276 | |
| 277 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); | |
| 278 } while (reg[4] & WM8903_WSEQ_BUSY); | |
| 279 | |
| 280 dev_dbg(codec->dev, "Sequence complete\n"); | |
| 281 | |
| 282 /* Disable the sequencer again if we enabled it */ | |
| 283 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); | |
| 284 | |
| 285 return 0; | |
| 286 } | |
| 287 | |
| 288 static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache) | |
| 289 { | |
| 290 int i; | |
| 291 | |
| 292 /* There really ought to be something better we can do here :/ */ | |
| 293 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++) | |
| 294 cache[i] = codec->hw_read(codec, i); | |
| 295 } | |
| 296 | |
| 297 static void wm8903_reset(struct snd_soc_codec *codec) | 263 static void wm8903_reset(struct snd_soc_codec *codec) |
| 298 { | 264 { |
| 299 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); | 265 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); |
| 300 memcpy(codec->reg_cache, wm8903_reg_defaults, | 266 memcpy(codec->reg_cache, wm8903_reg_defaults, |
| 301 sizeof(wm8903_reg_defaults)); | 267 sizeof(wm8903_reg_defaults)); |
| 302 } | 268 } |
| 303 | 269 |
| 304 #define WM8903_OUTPUT_SHORT 0x8 | |
| 305 #define WM8903_OUTPUT_OUT 0x4 | |
| 306 #define WM8903_OUTPUT_INT 0x2 | |
| 307 #define WM8903_OUTPUT_IN 0x1 | |
| 308 | |
| 309 static int wm8903_cp_event(struct snd_soc_dapm_widget *w, | 270 static int wm8903_cp_event(struct snd_soc_dapm_widget *w, |
| 310 struct snd_kcontrol *kcontrol, int event) | 271 struct snd_kcontrol *kcontrol, int event) |
| 311 { | 272 { |
| 312 WARN_ON(event != SND_SOC_DAPM_POST_PMU); | 273 WARN_ON(event != SND_SOC_DAPM_POST_PMU); |
| 313 mdelay(4); | 274 mdelay(4); |
| 314 | 275 |
| 315 return 0; | 276 return 0; |
| 316 } | 277 } |
| 317 | 278 |
| 318 /* | 279 static int wm8903_dcs_event(struct snd_soc_dapm_widget *w, |
| 319 * Event for headphone and line out amplifier power changes. Special | 280 » » » struct snd_kcontrol *kcontrol, int event) |
| 320 * power up/down sequences are required in order to maximise pop/click | |
| 321 * performance. | |
| 322 */ | |
| 323 static int wm8903_output_event(struct snd_soc_dapm_widget *w, | |
| 324 » » » struct snd_kcontrol *kcontrol, int event) | |
| 325 { | 281 { |
| 326 struct snd_soc_codec *codec = w->codec; | 282 struct snd_soc_codec *codec = w->codec; |
| 327 » u16 val; | 283 » struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 328 » u16 reg; | |
| 329 » u16 dcs_reg; | |
| 330 » u16 dcs_bit; | |
| 331 » int shift; | |
| 332 | 284 |
| 333 » switch (w->reg) { | 285 » switch (event) { |
| 334 » case WM8903_POWER_MANAGEMENT_2: | 286 » case SND_SOC_DAPM_POST_PMU: |
| 335 » » reg = WM8903_ANALOGUE_HP_0; | 287 » » wm8903->dcs_pending |= 1 << w->shift; |
| 336 » » dcs_bit = 0 + w->shift; | |
| 337 break; | 288 break; |
| 338 » case WM8903_POWER_MANAGEMENT_3: | 289 » case SND_SOC_DAPM_PRE_PMD: |
| 339 » » reg = WM8903_ANALOGUE_LINEOUT_0; | 290 » » snd_soc_update_bits(codec, WM8903_DC_SERVO_0, |
| 340 » » dcs_bit = 2 + w->shift; | 291 » » » » 1 << w->shift, 0); |
| 341 break; | 292 break; |
| 342 default: | |
| 343 BUG(); | |
| 344 return -EINVAL; /* Spurious warning from some compilers */ | |
| 345 } | |
| 346 | |
| 347 switch (w->shift) { | |
| 348 case 0: | |
| 349 shift = 0; | |
| 350 break; | |
| 351 case 1: | |
| 352 shift = 4; | |
| 353 break; | |
| 354 default: | |
| 355 BUG(); | |
| 356 return -EINVAL; /* Spurious warning from some compilers */ | |
| 357 } | |
| 358 | |
| 359 if (event & SND_SOC_DAPM_PRE_PMU) { | |
| 360 val = snd_soc_read(codec, reg); | |
| 361 | |
| 362 /* Short the output */ | |
| 363 val &= ~(WM8903_OUTPUT_SHORT << shift); | |
| 364 snd_soc_write(codec, reg, val); | |
| 365 } | |
| 366 | |
| 367 if (event & SND_SOC_DAPM_POST_PMU) { | |
| 368 val = snd_soc_read(codec, reg); | |
| 369 | |
| 370 val |= (WM8903_OUTPUT_IN << shift); | |
| 371 snd_soc_write(codec, reg, val); | |
| 372 | |
| 373 val |= (WM8903_OUTPUT_INT << shift); | |
| 374 snd_soc_write(codec, reg, val); | |
| 375 | |
| 376 /* Turn on the output ENA_OUTP */ | |
| 377 val |= (WM8903_OUTPUT_OUT << shift); | |
| 378 snd_soc_write(codec, reg, val); | |
| 379 | |
| 380 /* Enable the DC servo */ | |
| 381 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); | |
| 382 dcs_reg |= dcs_bit; | |
| 383 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg); | |
| 384 | |
| 385 /* Remove the short */ | |
| 386 val |= (WM8903_OUTPUT_SHORT << shift); | |
| 387 snd_soc_write(codec, reg, val); | |
| 388 } | |
| 389 | |
| 390 if (event & SND_SOC_DAPM_PRE_PMD) { | |
| 391 val = snd_soc_read(codec, reg); | |
| 392 | |
| 393 /* Short the output */ | |
| 394 val &= ~(WM8903_OUTPUT_SHORT << shift); | |
| 395 snd_soc_write(codec, reg, val); | |
| 396 | |
| 397 /* Disable the DC servo */ | |
| 398 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); | |
| 399 dcs_reg &= ~dcs_bit; | |
| 400 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg); | |
| 401 | |
| 402 /* Then disable the intermediate and output stages */ | |
| 403 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | | |
| 404 WM8903_OUTPUT_IN) << shift); | |
| 405 snd_soc_write(codec, reg, val); | |
| 406 } | 293 } |
| 407 | 294 |
| 408 return 0; | 295 return 0; |
| 409 } | 296 } |
| 410 | 297 |
| 298 #define WM8903_DCS_MODE_WRITE_STOP 0 |
| 299 #define WM8903_DCS_MODE_START_STOP 2 |
| 300 |
| 301 static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm, |
| 302 enum snd_soc_dapm_type event, int subseq) |
| 303 { |
| 304 struct snd_soc_codec *codec = container_of(dapm, |
| 305 struct snd_soc_codec, dapm); |
| 306 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 307 int dcs_mode = WM8903_DCS_MODE_WRITE_STOP; |
| 308 int i, val; |
| 309 |
| 310 /* Complete any pending DC servo starts */ |
| 311 if (wm8903->dcs_pending) { |
| 312 dev_dbg(codec->dev, "Starting DC servo for %x\n", |
| 313 wm8903->dcs_pending); |
| 314 |
| 315 /* If we've no cached values then we need to do startup */ |
| 316 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) { |
| 317 if (!(wm8903->dcs_pending & (1 << i))) |
| 318 continue; |
| 319 |
| 320 if (wm8903->dcs_cache[i]) { |
| 321 dev_dbg(codec->dev, |
| 322 "Restore DC servo %d value %x\n", |
| 323 3 - i, wm8903->dcs_cache[i]); |
| 324 |
| 325 snd_soc_write(codec, WM8903_DC_SERVO_4 + i, |
| 326 wm8903->dcs_cache[i] & 0xff); |
| 327 } else { |
| 328 dev_dbg(codec->dev, |
| 329 "Calibrate DC servo %d\n", 3 - i); |
| 330 dcs_mode = WM8903_DCS_MODE_START_STOP; |
| 331 } |
| 332 } |
| 333 |
| 334 /* Don't trust the cache for analogue */ |
| 335 if (wm8903->class_w_users) |
| 336 dcs_mode = WM8903_DCS_MODE_START_STOP; |
| 337 |
| 338 snd_soc_update_bits(codec, WM8903_DC_SERVO_2, |
| 339 WM8903_DCS_MODE_MASK, dcs_mode); |
| 340 |
| 341 snd_soc_update_bits(codec, WM8903_DC_SERVO_0, |
| 342 WM8903_DCS_ENA_MASK, wm8903->dcs_pending); |
| 343 |
| 344 switch (dcs_mode) { |
| 345 case WM8903_DCS_MODE_WRITE_STOP: |
| 346 break; |
| 347 |
| 348 case WM8903_DCS_MODE_START_STOP: |
| 349 msleep(270); |
| 350 |
| 351 /* Cache the measured offsets for digital */ |
| 352 if (wm8903->class_w_users) |
| 353 break; |
| 354 |
| 355 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) { |
| 356 if (!(wm8903->dcs_pending & (1 << i))) |
| 357 continue; |
| 358 |
| 359 val = snd_soc_read(codec, |
| 360 WM8903_DC_SERVO_READBACK_1 +
i); |
| 361 dev_dbg(codec->dev, "DC servo %d: %x\n", |
| 362 3 - i, val); |
| 363 wm8903->dcs_cache[i] = val; |
| 364 } |
| 365 break; |
| 366 |
| 367 default: |
| 368 pr_warn("DCS mode %d delay not set\n", dcs_mode); |
| 369 break; |
| 370 } |
| 371 |
| 372 wm8903->dcs_pending = 0; |
| 373 } |
| 374 } |
| 375 |
| 411 /* | 376 /* |
| 412 * When used with DAC outputs only the WM8903 charge pump supports | 377 * When used with DAC outputs only the WM8903 charge pump supports |
| 413 * operation in class W mode, providing very low power consumption | 378 * operation in class W mode, providing very low power consumption |
| 414 * when used with digital sources. Enable and disable this mode | 379 * when used with digital sources. Enable and disable this mode |
| 415 * automatically depending on the mixer configuration. | 380 * automatically depending on the mixer configuration. |
| 416 * | 381 * |
| 417 * All the relevant controls are simple switches. | 382 * All the relevant controls are simple switches. |
| 418 */ | 383 */ |
| 419 static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, | 384 static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, |
| 420 struct snd_ctl_elem_value *ucontrol) | 385 struct snd_ctl_elem_value *ucontrol) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 return ret; | 421 return ret; |
| 457 } | 422 } |
| 458 | 423 |
| 459 #define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \ | 424 #define SOC_DAPM_SINGLE_W(xname, reg, shift, max, invert) \ |
| 460 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 425 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
| 461 .info = snd_soc_info_volsw, \ | 426 .info = snd_soc_info_volsw, \ |
| 462 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \ | 427 .get = snd_soc_dapm_get_volsw, .put = wm8903_class_w_put, \ |
| 463 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | 428 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } |
| 464 | 429 |
| 465 | 430 |
| 431 static int wm8903_deemph[] = { 0, 32000, 44100, 48000 }; |
| 432 |
| 433 static int wm8903_set_deemph(struct snd_soc_codec *codec) |
| 434 { |
| 435 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 436 int val, i, best; |
| 437 |
| 438 /* If we're using deemphasis select the nearest available sample |
| 439 * rate. |
| 440 */ |
| 441 if (wm8903->deemph) { |
| 442 best = 1; |
| 443 for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) { |
| 444 if (abs(wm8903_deemph[i] - wm8903->fs) < |
| 445 abs(wm8903_deemph[best] - wm8903->fs)) |
| 446 best = i; |
| 447 } |
| 448 |
| 449 val = best << WM8903_DEEMPH_SHIFT; |
| 450 } else { |
| 451 best = 0; |
| 452 val = 0; |
| 453 } |
| 454 |
| 455 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", |
| 456 best, wm8903_deemph[best]); |
| 457 |
| 458 return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, |
| 459 WM8903_DEEMPH_MASK, val); |
| 460 } |
| 461 |
| 462 static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, |
| 463 struct snd_ctl_elem_value *ucontrol) |
| 464 { |
| 465 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 466 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 467 |
| 468 ucontrol->value.enumerated.item[0] = wm8903->deemph; |
| 469 |
| 470 return 0; |
| 471 } |
| 472 |
| 473 static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, |
| 474 struct snd_ctl_elem_value *ucontrol) |
| 475 { |
| 476 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 477 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 478 int deemph = ucontrol->value.enumerated.item[0]; |
| 479 int ret = 0; |
| 480 |
| 481 if (deemph > 1) |
| 482 return -EINVAL; |
| 483 |
| 484 mutex_lock(&codec->mutex); |
| 485 if (wm8903->deemph != deemph) { |
| 486 wm8903->deemph = deemph; |
| 487 |
| 488 wm8903_set_deemph(codec); |
| 489 |
| 490 ret = 1; |
| 491 } |
| 492 mutex_unlock(&codec->mutex); |
| 493 |
| 494 return ret; |
| 495 } |
| 496 |
| 466 /* ALSA can only do steps of .01dB */ | 497 /* ALSA can only do steps of .01dB */ |
| 467 static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | 498 static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); |
| 468 | 499 |
| 469 static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); | 500 static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); |
| 470 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); | 501 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); |
| 471 | 502 |
| 472 static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0); | 503 static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0); |
| 473 static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0); | 504 static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0); |
| 474 static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0); | 505 static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0); |
| 475 static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); | 506 static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); |
| 476 static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); | 507 static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); |
| 477 | 508 |
| 509 static const char *hpf_mode_text[] = { |
| 510 "Hi-fi", "Voice 1", "Voice 2", "Voice 3" |
| 511 }; |
| 512 |
| 513 static const struct soc_enum hpf_mode = |
| 514 SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text); |
| 515 |
| 516 static const char *osr_text[] = { |
| 517 "Low power", "High performance" |
| 518 }; |
| 519 |
| 520 static const struct soc_enum adc_osr = |
| 521 SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text); |
| 522 |
| 523 static const struct soc_enum dac_osr = |
| 524 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text); |
| 525 |
| 478 static const char *drc_slope_text[] = { | 526 static const char *drc_slope_text[] = { |
| 479 "1", "1/2", "1/4", "1/8", "1/16", "0" | 527 "1", "1/2", "1/4", "1/8", "1/16", "0" |
| 480 }; | 528 }; |
| 481 | 529 |
| 482 static const struct soc_enum drc_slope_r0 = | 530 static const struct soc_enum drc_slope_r0 = |
| 483 SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text); | 531 SOC_ENUM_SINGLE(WM8903_DRC_2, 3, 6, drc_slope_text); |
| 484 | 532 |
| 485 static const struct soc_enum drc_slope_r1 = | 533 static const struct soc_enum drc_slope_r1 = |
| 486 SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text); | 534 SOC_ENUM_SINGLE(WM8903_DRC_2, 0, 6, drc_slope_text); |
| 487 | 535 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 static const struct soc_enum soft_mute = | 578 static const struct soc_enum soft_mute = |
| 531 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text); | 579 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 10, 2, soft_mute_text); |
| 532 | 580 |
| 533 static const char *mute_mode_text[] = { | 581 static const char *mute_mode_text[] = { |
| 534 "Hard", "Soft" | 582 "Hard", "Soft" |
| 535 }; | 583 }; |
| 536 | 584 |
| 537 static const struct soc_enum mute_mode = | 585 static const struct soc_enum mute_mode = |
| 538 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); | 586 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); |
| 539 | 587 |
| 540 static const char *dac_deemphasis_text[] = { | |
| 541 "Disabled", "32kHz", "44.1kHz", "48kHz" | |
| 542 }; | |
| 543 | |
| 544 static const struct soc_enum dac_deemphasis = | |
| 545 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text); | |
| 546 | |
| 547 static const char *companding_text[] = { | 588 static const char *companding_text[] = { |
| 548 "ulaw", "alaw" | 589 "ulaw", "alaw" |
| 549 }; | 590 }; |
| 550 | 591 |
| 551 static const struct soc_enum dac_companding = | 592 static const struct soc_enum dac_companding = |
| 552 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text); | 593 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 0, 2, companding_text); |
| 553 | 594 |
| 554 static const struct soc_enum adc_companding = | 595 static const struct soc_enum adc_companding = |
| 555 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text); | 596 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 2, 2, companding_text); |
| 556 | 597 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 static const char *sidetone_text[] = { | 629 static const char *sidetone_text[] = { |
| 589 "None", "Left", "Right" | 630 "None", "Left", "Right" |
| 590 }; | 631 }; |
| 591 | 632 |
| 592 static const struct soc_enum lsidetone_enum = | 633 static const struct soc_enum lsidetone_enum = |
| 593 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text); | 634 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text); |
| 594 | 635 |
| 595 static const struct soc_enum rsidetone_enum = | 636 static const struct soc_enum rsidetone_enum = |
| 596 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); | 637 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); |
| 597 | 638 |
| 639 static const char *aif_text[] = { |
| 640 "Left", "Right" |
| 641 }; |
| 642 |
| 643 static const struct soc_enum lcapture_enum = |
| 644 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text); |
| 645 |
| 646 static const struct soc_enum rcapture_enum = |
| 647 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text); |
| 648 |
| 649 static const struct soc_enum lplay_enum = |
| 650 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text); |
| 651 |
| 652 static const struct soc_enum rplay_enum = |
| 653 SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text); |
| 654 |
| 598 static const struct snd_kcontrol_new wm8903_snd_controls[] = { | 655 static const struct snd_kcontrol_new wm8903_snd_controls[] = { |
| 599 | 656 |
| 600 /* Input PGAs - No TLV since the scale depends on PGA mode */ | 657 /* Input PGAs - No TLV since the scale depends on PGA mode */ |
| 601 SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0, | 658 SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0, |
| 602 7, 1, 1), | 659 7, 1, 1), |
| 603 SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0, | 660 SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0, |
| 604 0, 31, 0), | 661 0, 31, 0), |
| 605 SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1, | 662 SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1, |
| 606 6, 1, 0), | 663 6, 1, 0), |
| 607 | 664 |
| 608 SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0, | 665 SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0, |
| 609 7, 1, 1), | 666 7, 1, 1), |
| 610 SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0, | 667 SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0, |
| 611 0, 31, 0), | 668 0, 31, 0), |
| 612 SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, | 669 SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, |
| 613 6, 1, 0), | 670 6, 1, 0), |
| 614 | 671 |
| 615 /* ADCs */ | 672 /* ADCs */ |
| 673 SOC_ENUM("ADC OSR", adc_osr), |
| 674 SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0), |
| 675 SOC_ENUM("HPF Mode", hpf_mode), |
| 616 SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), | 676 SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), |
| 617 SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), | 677 SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), |
| 618 SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), | 678 SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), |
| 619 SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1, | 679 SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1, |
| 620 drc_tlv_thresh), | 680 drc_tlv_thresh), |
| 621 SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), | 681 SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), |
| 622 SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), | 682 SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), |
| 623 SOC_SINGLE_TLV("DRC Maximum Gain Volume", WM8903_DRC_1, 0, 3, 0, drc_tlv_max), | 683 SOC_SINGLE_TLV("DRC Maximum Gain Volume", WM8903_DRC_1, 0, 3, 0, drc_tlv_max), |
| 624 SOC_ENUM("DRC Attack Rate", drc_attack), | 684 SOC_ENUM("DRC Attack Rate", drc_attack), |
| 625 SOC_ENUM("DRC Decay Rate", drc_decay), | 685 SOC_ENUM("DRC Decay Rate", drc_decay), |
| 626 SOC_ENUM("DRC FF Delay", drc_ff_delay), | 686 SOC_ENUM("DRC FF Delay", drc_ff_delay), |
| 627 SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), | 687 SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), |
| 628 SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), | 688 SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), |
| 629 SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), | 689 SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), |
| 630 SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), | 690 SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), |
| 631 SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), | 691 SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), |
| 632 SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), | 692 SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), |
| 633 SOC_ENUM("DRC Smoothing Threshold", drc_smoothing), | 693 SOC_ENUM("DRC Smoothing Threshold", drc_smoothing), |
| 634 SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), | 694 SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), |
| 635 | 695 |
| 636 SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, | 696 SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, |
| 637 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), | 697 WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), |
| 638 SOC_ENUM("ADC Companding Mode", adc_companding), | 698 SOC_ENUM("ADC Companding Mode", adc_companding), |
| 639 SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), | 699 SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), |
| 640 | 700 |
| 641 SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8, | 701 SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8, |
| 642 12, 0, digital_sidetone_tlv), | 702 12, 0, digital_sidetone_tlv), |
| 643 | 703 |
| 644 /* DAC */ | 704 /* DAC */ |
| 705 SOC_ENUM("DAC OSR", dac_osr), |
| 645 SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, | 706 SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, |
| 646 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), | 707 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), |
| 647 SOC_ENUM("DAC Soft Mute Rate", soft_mute), | 708 SOC_ENUM("DAC Soft Mute Rate", soft_mute), |
| 648 SOC_ENUM("DAC Mute Mode", mute_mode), | 709 SOC_ENUM("DAC Mute Mode", mute_mode), |
| 649 SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), | 710 SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), |
| 650 SOC_ENUM("DAC De-emphasis", dac_deemphasis), | |
| 651 SOC_ENUM("DAC Companding Mode", dac_companding), | 711 SOC_ENUM("DAC Companding Mode", dac_companding), |
| 652 SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), | 712 SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), |
| 713 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, |
| 714 wm8903_get_deemph, wm8903_put_deemph), |
| 653 | 715 |
| 654 /* Headphones */ | 716 /* Headphones */ |
| 655 SOC_DOUBLE_R("Headphone Switch", | 717 SOC_DOUBLE_R("Headphone Switch", |
| 656 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT, | 718 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT, |
| 657 8, 1, 1), | 719 8, 1, 1), |
| 658 SOC_DOUBLE_R("Headphone ZC Switch", | 720 SOC_DOUBLE_R("Headphone ZC Switch", |
| 659 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT, | 721 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT, |
| 660 6, 1, 0), | 722 6, 1, 0), |
| 661 SOC_DOUBLE_R_TLV("Headphone Volume", | 723 SOC_DOUBLE_R_TLV("Headphone Volume", |
| 662 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT, | 724 WM8903_ANALOGUE_OUT1_LEFT, WM8903_ANALOGUE_OUT1_RIGHT, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 | 762 |
| 701 static const struct snd_kcontrol_new rinput_inv_mux = | 763 static const struct snd_kcontrol_new rinput_inv_mux = |
| 702 SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum); | 764 SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum); |
| 703 | 765 |
| 704 static const struct snd_kcontrol_new lsidetone_mux = | 766 static const struct snd_kcontrol_new lsidetone_mux = |
| 705 SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum); | 767 SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum); |
| 706 | 768 |
| 707 static const struct snd_kcontrol_new rsidetone_mux = | 769 static const struct snd_kcontrol_new rsidetone_mux = |
| 708 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); | 770 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); |
| 709 | 771 |
| 772 static const struct snd_kcontrol_new lcapture_mux = |
| 773 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum); |
| 774 |
| 775 static const struct snd_kcontrol_new rcapture_mux = |
| 776 SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum); |
| 777 |
| 778 static const struct snd_kcontrol_new lplay_mux = |
| 779 SOC_DAPM_ENUM("Left Playback Mux", lplay_enum); |
| 780 |
| 781 static const struct snd_kcontrol_new rplay_mux = |
| 782 SOC_DAPM_ENUM("Right Playback Mux", rplay_enum); |
| 783 |
| 710 static const struct snd_kcontrol_new left_output_mixer[] = { | 784 static const struct snd_kcontrol_new left_output_mixer[] = { |
| 711 SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), | 785 SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), |
| 712 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), | 786 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), |
| 713 SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0), | 787 SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0), |
| 714 SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0), | 788 SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0), |
| 715 }; | 789 }; |
| 716 | 790 |
| 717 static const struct snd_kcontrol_new right_output_mixer[] = { | 791 static const struct snd_kcontrol_new right_output_mixer[] = { |
| 718 SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0), | 792 SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0), |
| 719 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0), | 793 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux), | 837 SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux), |
| 764 | 838 |
| 765 SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux), | 839 SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux), |
| 766 SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0, | 840 SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0, |
| 767 &rinput_inv_mux), | 841 &rinput_inv_mux), |
| 768 SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux), | 842 SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux), |
| 769 | 843 |
| 770 SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), | 844 SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), |
| 771 SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), | 845 SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), |
| 772 | 846 |
| 773 SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), | 847 SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0), |
| 774 SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), | 848 SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0), |
| 849 |
| 850 SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux), |
| 851 SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux), |
| 852 |
| 853 SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0), |
| 854 SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0), |
| 775 | 855 |
| 776 SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), | 856 SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), |
| 777 SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), | 857 SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), |
| 778 | 858 |
| 779 SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), | 859 SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0), |
| 780 SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), | 860 SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0), |
| 861 |
| 862 SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux), |
| 863 SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux), |
| 864 |
| 865 SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0), |
| 866 SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0), |
| 781 | 867 |
| 782 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, | 868 SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, |
| 783 left_output_mixer, ARRAY_SIZE(left_output_mixer)), | 869 left_output_mixer, ARRAY_SIZE(left_output_mixer)), |
| 784 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8903_POWER_MANAGEMENT_1, 0, 0, | 870 SND_SOC_DAPM_MIXER("Right Output Mixer", WM8903_POWER_MANAGEMENT_1, 0, 0, |
| 785 right_output_mixer, ARRAY_SIZE(right_output_mixer)), | 871 right_output_mixer, ARRAY_SIZE(right_output_mixer)), |
| 786 | 872 |
| 787 SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0, | 873 SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0, |
| 788 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), | 874 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), |
| 789 SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, | 875 SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, |
| 790 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), | 876 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), |
| 791 | 877 |
| 792 SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, | 878 SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0, |
| 793 » » 1, 0, NULL, 0, wm8903_output_event, | 879 » » 4, 0, NULL, 0), |
| 794 » » SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 880 SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_ANALOGUE_HP_0, |
| 795 » » SND_SOC_DAPM_PRE_PMD), | 881 » » 0, 0, NULL, 0), |
| 796 SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, | |
| 797 » » 0, 0, NULL, 0, wm8903_output_event, | |
| 798 » » SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | |
| 799 » » SND_SOC_DAPM_PRE_PMD), | |
| 800 | 882 |
| 801 SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, | 883 SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 4, 0, |
| 802 » » NULL, 0, wm8903_output_event, | 884 » » NULL, 0), |
| 803 » » SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 885 SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_ANALOGUE_LINEOUT_0, 0, 0, |
| 804 » » SND_SOC_DAPM_PRE_PMD), | 886 » » NULL, 0), |
| 805 SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, | 887 |
| 806 » » NULL, 0, wm8903_output_event, | 888 SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0), |
| 807 » » SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 889 SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0), |
| 808 » » SND_SOC_DAPM_PRE_PMD), | 890 SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0), |
| 891 SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0), |
| 892 SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0), |
| 893 SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 1, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0), |
| 894 |
| 895 SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0, |
| 896 » » NULL, 0), |
| 897 SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0, |
| 898 » » NULL, 0), |
| 899 SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 5, 0, |
| 900 » » NULL, 0), |
| 901 SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0, |
| 902 » » NULL, 0), |
| 903 SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0, |
| 904 » » NULL, 0), |
| 905 SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 1, WM8903_ANALOGUE_LINEOUT_0, 1, 0, |
| 906 » » NULL, 0), |
| 907 |
| 908 SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0), |
| 909 SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event, |
| 910 » » SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 911 SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event, |
| 912 » » SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 913 SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event, |
| 914 » » SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 915 SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event, |
| 916 » » SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 809 | 917 |
| 810 SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, | 918 SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, |
| 811 NULL, 0), | 919 NULL, 0), |
| 812 SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0, | 920 SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0, |
| 813 NULL, 0), | 921 NULL, 0), |
| 814 | 922 |
| 815 SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, | 923 SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, |
| 816 wm8903_cp_event, SND_SOC_DAPM_POST_PMU), | 924 wm8903_cp_event, SND_SOC_DAPM_POST_PMU), |
| 817 SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), | 925 SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), |
| 926 SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), |
| 818 }; | 927 }; |
| 819 | 928 |
| 820 static const struct snd_soc_dapm_route intercon[] = { | 929 static const struct snd_soc_dapm_route intercon[] = { |
| 821 | 930 |
| 931 { "CLK_DSP", NULL, "CLK_SYS" }, |
| 932 { "Mic Bias", NULL, "CLK_SYS" }, |
| 933 { "HPL_DCS", NULL, "CLK_SYS" }, |
| 934 { "HPR_DCS", NULL, "CLK_SYS" }, |
| 935 { "LINEOUTL_DCS", NULL, "CLK_SYS" }, |
| 936 { "LINEOUTR_DCS", NULL, "CLK_SYS" }, |
| 937 |
| 822 { "Left Input Mux", "IN1L", "IN1L" }, | 938 { "Left Input Mux", "IN1L", "IN1L" }, |
| 823 { "Left Input Mux", "IN2L", "IN2L" }, | 939 { "Left Input Mux", "IN2L", "IN2L" }, |
| 824 { "Left Input Mux", "IN3L", "IN3L" }, | 940 { "Left Input Mux", "IN3L", "IN3L" }, |
| 825 | 941 |
| 826 { "Left Input Inverting Mux", "IN1L", "IN1L" }, | 942 { "Left Input Inverting Mux", "IN1L", "IN1L" }, |
| 827 { "Left Input Inverting Mux", "IN2L", "IN2L" }, | 943 { "Left Input Inverting Mux", "IN2L", "IN2L" }, |
| 828 { "Left Input Inverting Mux", "IN3L", "IN3L" }, | 944 { "Left Input Inverting Mux", "IN3L", "IN3L" }, |
| 829 | 945 |
| 830 { "Right Input Mux", "IN1R", "IN1R" }, | 946 { "Right Input Mux", "IN1R", "IN1R" }, |
| 831 { "Right Input Mux", "IN2R", "IN2R" }, | 947 { "Right Input Mux", "IN2R", "IN2R" }, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 852 { "Right Input Mode Mux", "Differential Line", | 968 { "Right Input Mode Mux", "Differential Line", |
| 853 "Right Input Inverting Mux" }, | 969 "Right Input Inverting Mux" }, |
| 854 { "Right Input Mode Mux", "Differential Mic", | 970 { "Right Input Mode Mux", "Differential Mic", |
| 855 "Right Input Mux" }, | 971 "Right Input Mux" }, |
| 856 { "Right Input Mode Mux", "Differential Mic", | 972 { "Right Input Mode Mux", "Differential Mic", |
| 857 "Right Input Inverting Mux" }, | 973 "Right Input Inverting Mux" }, |
| 858 | 974 |
| 859 { "Left Input PGA", NULL, "Left Input Mode Mux" }, | 975 { "Left Input PGA", NULL, "Left Input Mode Mux" }, |
| 860 { "Right Input PGA", NULL, "Right Input Mode Mux" }, | 976 { "Right Input PGA", NULL, "Right Input Mode Mux" }, |
| 861 | 977 |
| 978 { "Left Capture Mux", "Left", "ADCL" }, |
| 979 { "Left Capture Mux", "Right", "ADCR" }, |
| 980 |
| 981 { "Right Capture Mux", "Left", "ADCL" }, |
| 982 { "Right Capture Mux", "Right", "ADCR" }, |
| 983 |
| 984 { "AIFTXL", NULL, "Left Capture Mux" }, |
| 985 { "AIFTXR", NULL, "Right Capture Mux" }, |
| 986 |
| 862 { "ADCL", NULL, "Left Input PGA" }, | 987 { "ADCL", NULL, "Left Input PGA" }, |
| 863 { "ADCL", NULL, "CLK_DSP" }, | 988 { "ADCL", NULL, "CLK_DSP" }, |
| 864 { "ADCR", NULL, "Right Input PGA" }, | 989 { "ADCR", NULL, "Right Input PGA" }, |
| 865 { "ADCR", NULL, "CLK_DSP" }, | 990 { "ADCR", NULL, "CLK_DSP" }, |
| 866 | 991 |
| 992 { "Left Playback Mux", "Left", "AIFRXL" }, |
| 993 { "Left Playback Mux", "Right", "AIFRXR" }, |
| 994 |
| 995 { "Right Playback Mux", "Left", "AIFRXL" }, |
| 996 { "Right Playback Mux", "Right", "AIFRXR" }, |
| 997 |
| 867 { "DACL Sidetone", "Left", "ADCL" }, | 998 { "DACL Sidetone", "Left", "ADCL" }, |
| 868 { "DACL Sidetone", "Right", "ADCR" }, | 999 { "DACL Sidetone", "Right", "ADCR" }, |
| 869 { "DACR Sidetone", "Left", "ADCL" }, | 1000 { "DACR Sidetone", "Left", "ADCL" }, |
| 870 { "DACR Sidetone", "Right", "ADCR" }, | 1001 { "DACR Sidetone", "Right", "ADCR" }, |
| 871 | 1002 |
| 1003 { "DACL", NULL, "Left Playback Mux" }, |
| 872 { "DACL", NULL, "DACL Sidetone" }, | 1004 { "DACL", NULL, "DACL Sidetone" }, |
| 873 { "DACL", NULL, "CLK_DSP" }, | 1005 { "DACL", NULL, "CLK_DSP" }, |
| 1006 |
| 1007 { "DACR", NULL, "Right Playback Mux" }, |
| 874 { "DACR", NULL, "DACR Sidetone" }, | 1008 { "DACR", NULL, "DACR Sidetone" }, |
| 875 { "DACR", NULL, "CLK_DSP" }, | 1009 { "DACR", NULL, "CLK_DSP" }, |
| 876 | 1010 |
| 877 { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" }, | 1011 { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" }, |
| 878 { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" }, | 1012 { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" }, |
| 879 { "Left Output Mixer", "DACL Switch", "DACL" }, | 1013 { "Left Output Mixer", "DACL Switch", "DACL" }, |
| 880 { "Left Output Mixer", "DACR Switch", "DACR" }, | 1014 { "Left Output Mixer", "DACR Switch", "DACR" }, |
| 881 | 1015 |
| 882 { "Right Output Mixer", "Left Bypass Switch", "Left Input PGA" }, | 1016 { "Right Output Mixer", "Left Bypass Switch", "Left Input PGA" }, |
| 883 { "Right Output Mixer", "Right Bypass Switch", "Right Input PGA" }, | 1017 { "Right Output Mixer", "Right Bypass Switch", "Right Input PGA" }, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 896 | 1030 |
| 897 { "Left Line Output PGA", NULL, "Left Output Mixer" }, | 1031 { "Left Line Output PGA", NULL, "Left Output Mixer" }, |
| 898 { "Right Line Output PGA", NULL, "Right Output Mixer" }, | 1032 { "Right Line Output PGA", NULL, "Right Output Mixer" }, |
| 899 | 1033 |
| 900 { "Left Headphone Output PGA", NULL, "Left Output Mixer" }, | 1034 { "Left Headphone Output PGA", NULL, "Left Output Mixer" }, |
| 901 { "Right Headphone Output PGA", NULL, "Right Output Mixer" }, | 1035 { "Right Headphone Output PGA", NULL, "Right Output Mixer" }, |
| 902 | 1036 |
| 903 { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, | 1037 { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, |
| 904 { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, | 1038 { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, |
| 905 | 1039 |
| 906 » { "HPOUTL", NULL, "Left Headphone Output PGA" }, | 1040 » { "HPL_ENA_DLY", NULL, "Left Headphone Output PGA" }, |
| 907 » { "HPOUTR", NULL, "Right Headphone Output PGA" }, | 1041 » { "HPR_ENA_DLY", NULL, "Right Headphone Output PGA" }, |
| 1042 » { "LINEOUTL_ENA_DLY", NULL, "Left Line Output PGA" }, |
| 1043 » { "LINEOUTR_ENA_DLY", NULL, "Right Line Output PGA" }, |
| 908 | 1044 |
| 909 » { "LINEOUTL", NULL, "Left Line Output PGA" }, | 1045 » { "HPL_DCS", NULL, "DCS Master" }, |
| 910 » { "LINEOUTR", NULL, "Right Line Output PGA" }, | 1046 » { "HPR_DCS", NULL, "DCS Master" }, |
| 1047 » { "LINEOUTL_DCS", NULL, "DCS Master" }, |
| 1048 » { "LINEOUTR_DCS", NULL, "DCS Master" }, |
| 1049 |
| 1050 » { "HPL_DCS", NULL, "HPL_ENA_DLY" }, |
| 1051 » { "HPR_DCS", NULL, "HPR_ENA_DLY" }, |
| 1052 » { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" }, |
| 1053 » { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" }, |
| 1054 |
| 1055 » { "HPL_ENA_OUTP", NULL, "HPL_DCS" }, |
| 1056 » { "HPR_ENA_OUTP", NULL, "HPR_DCS" }, |
| 1057 » { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" }, |
| 1058 » { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" }, |
| 1059 |
| 1060 » { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" }, |
| 1061 » { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" }, |
| 1062 » { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" }, |
| 1063 » { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" }, |
| 1064 |
| 1065 » { "HPOUTL", NULL, "HPL_RMV_SHORT" }, |
| 1066 » { "HPOUTR", NULL, "HPR_RMV_SHORT" }, |
| 1067 » { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" }, |
| 1068 » { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" }, |
| 911 | 1069 |
| 912 { "LOP", NULL, "Left Speaker PGA" }, | 1070 { "LOP", NULL, "Left Speaker PGA" }, |
| 913 { "LON", NULL, "Left Speaker PGA" }, | 1071 { "LON", NULL, "Left Speaker PGA" }, |
| 914 | 1072 |
| 915 { "ROP", NULL, "Right Speaker PGA" }, | 1073 { "ROP", NULL, "Right Speaker PGA" }, |
| 916 { "RON", NULL, "Right Speaker PGA" }, | 1074 { "RON", NULL, "Right Speaker PGA" }, |
| 917 | 1075 |
| 918 { "Left Headphone Output PGA", NULL, "Charge Pump" }, | 1076 { "Left Headphone Output PGA", NULL, "Charge Pump" }, |
| 919 { "Right Headphone Output PGA", NULL, "Charge Pump" }, | 1077 { "Right Headphone Output PGA", NULL, "Charge Pump" }, |
| 920 { "Left Line Output PGA", NULL, "Charge Pump" }, | 1078 { "Left Line Output PGA", NULL, "Charge Pump" }, |
| 921 { "Right Line Output PGA", NULL, "Charge Pump" }, | 1079 { "Right Line Output PGA", NULL, "Charge Pump" }, |
| 922 }; | 1080 }; |
| 923 | 1081 |
| 924 static int wm8903_add_widgets(struct snd_soc_codec *codec) | 1082 static int wm8903_add_widgets(struct snd_soc_codec *codec) |
| 925 { | 1083 { |
| 926 » snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, | 1084 » struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 1085 |
| 1086 » snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets, |
| 927 ARRAY_SIZE(wm8903_dapm_widgets)); | 1087 ARRAY_SIZE(wm8903_dapm_widgets)); |
| 928 | 1088 » snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); |
| 929 » snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); | |
| 930 | 1089 |
| 931 return 0; | 1090 return 0; |
| 932 } | 1091 } |
| 933 | 1092 |
| 934 static int wm8903_set_bias_level(struct snd_soc_codec *codec, | 1093 static int wm8903_set_bias_level(struct snd_soc_codec *codec, |
| 935 enum snd_soc_bias_level level) | 1094 enum snd_soc_bias_level level) |
| 936 { | 1095 { |
| 937 u16 reg, reg2; | |
| 938 | |
| 939 switch (level) { | 1096 switch (level) { |
| 940 case SND_SOC_BIAS_ON: | 1097 case SND_SOC_BIAS_ON: |
| 1098 break; |
| 1099 |
| 941 case SND_SOC_BIAS_PREPARE: | 1100 case SND_SOC_BIAS_PREPARE: |
| 942 » » reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); | 1101 » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 943 » » reg &= ~(WM8903_VMID_RES_MASK); | 1102 » » » » WM8903_VMID_RES_MASK, |
| 944 » » reg |= WM8903_VMID_RES_50K; | 1103 » » » » WM8903_VMID_RES_50K); |
| 945 » » snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg); | |
| 946 break; | 1104 break; |
| 947 | 1105 |
| 948 case SND_SOC_BIAS_STANDBY: | 1106 case SND_SOC_BIAS_STANDBY: |
| 949 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 1107 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 950 » » » snd_soc_write(codec, WM8903_CLOCK_RATES_2, | 1108 » » » snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
| 951 » » » » WM8903_CLK_SYS_ENA); | 1109 » » » » » WM8903_POBCTRL | WM8903_ISEL_MASK | |
| 1110 » » » » » WM8903_STARTUP_BIAS_ENA | |
| 1111 » » » » » WM8903_BIAS_ENA, |
| 1112 » » » » » WM8903_POBCTRL | |
| 1113 » » » » » (2 << WM8903_ISEL_SHIFT) | |
| 1114 » » » » » WM8903_STARTUP_BIAS_ENA); |
| 952 | 1115 |
| 953 » » » /* Change DC servo dither level in startup sequence */ | 1116 » » » snd_soc_update_bits(codec, |
| 954 » » » snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); | 1117 » » » » » WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0
, |
| 955 » » » snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); | 1118 » » » » » WM8903_SPK_DISCHARGE, |
| 956 » » » snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); | 1119 » » » » » WM8903_SPK_DISCHARGE); |
| 957 | 1120 |
| 958 » » » wm8903_run_sequence(codec, 0); | 1121 » » » msleep(33); |
| 959 » » » wm8903_sync_reg_cache(codec, codec->reg_cache); | |
| 960 | 1122 |
| 961 » » » /* Enable low impedence charge pump output */ | 1123 » » » snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5, |
| 962 » » » reg = snd_soc_read(codec, | 1124 » » » » » WM8903_SPKL_ENA | WM8903_SPKR_ENA, |
| 963 » » » » » WM8903_CONTROL_INTERFACE_TEST_1); | 1125 » » » » » WM8903_SPKL_ENA | WM8903_SPKR_ENA); |
| 964 » » » snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, | 1126 |
| 965 » » » » reg | WM8903_TEST_KEY); | 1127 » » » snd_soc_update_bits(codec, |
| 966 » » » reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1); | 1128 » » » » » WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0
, |
| 967 » » » snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1, | 1129 » » » » » WM8903_SPK_DISCHARGE, 0); |
| 968 » » » » reg2 | WM8903_CP_SW_KELVIN_MODE_MASK); | 1130 |
| 969 » » » snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, | 1131 » » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 970 » » » » reg); | 1132 » » » » » WM8903_VMID_TIE_ENA | |
| 1133 » » » » » WM8903_BUFIO_ENA | |
| 1134 » » » » » WM8903_VMID_IO_ENA | |
| 1135 » » » » » WM8903_VMID_SOFT_MASK | |
| 1136 » » » » » WM8903_VMID_RES_MASK | |
| 1137 » » » » » WM8903_VMID_BUF_ENA, |
| 1138 » » » » » WM8903_VMID_TIE_ENA | |
| 1139 » » » » » WM8903_BUFIO_ENA | |
| 1140 » » » » » WM8903_VMID_IO_ENA | |
| 1141 » » » » » (2 << WM8903_VMID_SOFT_SHIFT) | |
| 1142 » » » » » WM8903_VMID_RES_250K | |
| 1143 » » » » » WM8903_VMID_BUF_ENA); |
| 1144 |
| 1145 » » » msleep(129); |
| 1146 |
| 1147 » » » snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5, |
| 1148 » » » » » WM8903_SPKL_ENA | WM8903_SPKR_ENA, |
| 1149 » » » » » 0); |
| 1150 |
| 1151 » » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 1152 » » » » » WM8903_VMID_SOFT_MASK, 0); |
| 1153 |
| 1154 » » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 1155 » » » » » WM8903_VMID_RES_MASK, |
| 1156 » » » » » WM8903_VMID_RES_50K); |
| 1157 |
| 1158 » » » snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
| 1159 » » » » » WM8903_BIAS_ENA | WM8903_POBCTRL, |
| 1160 » » » » » WM8903_BIAS_ENA); |
| 971 | 1161 |
| 972 /* By default no bypass paths are enabled so | 1162 /* By default no bypass paths are enabled so |
| 973 * enable Class W support. | 1163 * enable Class W support. |
| 974 */ | 1164 */ |
| 975 dev_dbg(codec->dev, "Enabling Class W\n"); | 1165 dev_dbg(codec->dev, "Enabling Class W\n"); |
| 976 » » » snd_soc_write(codec, WM8903_CLASS_W_0, reg | | 1166 » » » snd_soc_update_bits(codec, WM8903_CLASS_W_0, |
| 977 » » » » WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); | 1167 » » » » » WM8903_CP_DYN_FREQ | |
| 1168 » » » » » WM8903_CP_DYN_V, |
| 1169 » » » » » WM8903_CP_DYN_FREQ | |
| 1170 » » » » » WM8903_CP_DYN_V); |
| 978 } | 1171 } |
| 979 | 1172 |
| 980 » » reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); | 1173 » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 981 » » reg &= ~(WM8903_VMID_RES_MASK); | 1174 » » » » WM8903_VMID_RES_MASK, |
| 982 » » reg |= WM8903_VMID_RES_250K; | 1175 » » » » WM8903_VMID_RES_250K); |
| 983 » » snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg); | |
| 984 break; | 1176 break; |
| 985 | 1177 |
| 986 case SND_SOC_BIAS_OFF: | 1178 case SND_SOC_BIAS_OFF: |
| 987 » » wm8903_run_sequence(codec, 32); | 1179 » » snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
| 988 » » reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2); | 1180 » » » » WM8903_BIAS_ENA, 0); |
| 989 » » reg &= ~WM8903_CLK_SYS_ENA; | 1181 |
| 990 » » snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg); | 1182 » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 1183 » » » » WM8903_VMID_SOFT_MASK, |
| 1184 » » » » 2 << WM8903_VMID_SOFT_SHIFT); |
| 1185 |
| 1186 » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 1187 » » » » WM8903_VMID_BUF_ENA, 0); |
| 1188 |
| 1189 » » msleep(290); |
| 1190 |
| 1191 » » snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
| 1192 » » » » WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA | |
| 1193 » » » » WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK | |
| 1194 » » » » WM8903_VMID_SOFT_MASK | |
| 1195 » » » » WM8903_VMID_BUF_ENA, 0); |
| 1196 |
| 1197 » » snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
| 1198 » » » » WM8903_STARTUP_BIAS_ENA, 0); |
| 991 break; | 1199 break; |
| 992 } | 1200 } |
| 993 | 1201 |
| 994 » codec->bias_level = level; | 1202 » codec->dapm.bias_level = level; |
| 995 | 1203 |
| 996 return 0; | 1204 return 0; |
| 997 } | 1205 } |
| 998 | 1206 |
| 999 static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai, | 1207 static int wm8903_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
| 1000 int clk_id, unsigned int freq, int dir) | 1208 int clk_id, unsigned int freq, int dir) |
| 1001 { | 1209 { |
| 1002 struct snd_soc_codec *codec = codec_dai->codec; | 1210 struct snd_soc_codec *codec = codec_dai->codec; |
| 1003 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1211 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 1004 | 1212 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 { 22050, 4 }, | 1423 { 22050, 4 }, |
| 1216 { 24000, 5 }, | 1424 { 24000, 5 }, |
| 1217 { 32000, 6 }, | 1425 { 32000, 6 }, |
| 1218 { 44100, 7 }, | 1426 { 44100, 7 }, |
| 1219 { 48000, 8 }, | 1427 { 48000, 8 }, |
| 1220 { 88200, 9 }, | 1428 { 88200, 9 }, |
| 1221 { 96000, 10 }, | 1429 { 96000, 10 }, |
| 1222 { 0, 0 }, | 1430 { 0, 0 }, |
| 1223 }; | 1431 }; |
| 1224 | 1432 |
| 1225 static int wm8903_startup(struct snd_pcm_substream *substream, | |
| 1226 struct snd_soc_dai *dai) | |
| 1227 { | |
| 1228 struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 1229 struct snd_soc_codec *codec = rtd->codec; | |
| 1230 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | |
| 1231 struct snd_pcm_runtime *master_runtime; | |
| 1232 | |
| 1233 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | |
| 1234 wm8903->playback_active++; | |
| 1235 else | |
| 1236 wm8903->capture_active++; | |
| 1237 | |
| 1238 /* The DAI has shared clocks so if we already have a playback or | |
| 1239 * capture going then constrain this substream to match it. | |
| 1240 */ | |
| 1241 if (wm8903->master_substream) { | |
| 1242 master_runtime = wm8903->master_substream->runtime; | |
| 1243 | |
| 1244 dev_dbg(codec->dev, "Constraining to %d bits\n", | |
| 1245 master_runtime->sample_bits); | |
| 1246 | |
| 1247 snd_pcm_hw_constraint_minmax(substream->runtime, | |
| 1248 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | |
| 1249 master_runtime->sample_bits, | |
| 1250 master_runtime->sample_bits); | |
| 1251 | |
| 1252 wm8903->slave_substream = substream; | |
| 1253 } else | |
| 1254 wm8903->master_substream = substream; | |
| 1255 | |
| 1256 return 0; | |
| 1257 } | |
| 1258 | |
| 1259 static void wm8903_shutdown(struct snd_pcm_substream *substream, | |
| 1260 struct snd_soc_dai *dai) | |
| 1261 { | |
| 1262 struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
| 1263 struct snd_soc_codec *codec = rtd->codec; | |
| 1264 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | |
| 1265 | |
| 1266 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | |
| 1267 wm8903->playback_active--; | |
| 1268 else | |
| 1269 wm8903->capture_active--; | |
| 1270 | |
| 1271 if (wm8903->master_substream == substream) | |
| 1272 wm8903->master_substream = wm8903->slave_substream; | |
| 1273 | |
| 1274 wm8903->slave_substream = NULL; | |
| 1275 } | |
| 1276 | |
| 1277 static int wm8903_hw_params(struct snd_pcm_substream *substream, | 1433 static int wm8903_hw_params(struct snd_pcm_substream *substream, |
| 1278 struct snd_pcm_hw_params *params, | 1434 struct snd_pcm_hw_params *params, |
| 1279 struct snd_soc_dai *dai) | 1435 struct snd_soc_dai *dai) |
| 1280 { | 1436 { |
| 1281 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1437 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 1282 struct snd_soc_codec *codec =rtd->codec; | 1438 struct snd_soc_codec *codec =rtd->codec; |
| 1283 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1439 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 1284 int fs = params_rate(params); | 1440 int fs = params_rate(params); |
| 1285 int bclk; | 1441 int bclk; |
| 1286 int bclk_div; | 1442 int bclk_div; |
| 1287 int i; | 1443 int i; |
| 1288 int dsp_config; | 1444 int dsp_config; |
| 1289 int clk_config; | 1445 int clk_config; |
| 1290 int best_val; | 1446 int best_val; |
| 1291 int cur_val; | 1447 int cur_val; |
| 1292 int clk_sys; | 1448 int clk_sys; |
| 1293 | 1449 |
| 1294 u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1); | 1450 u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1); |
| 1295 u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2); | 1451 u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2); |
| 1296 u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3); | 1452 u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3); |
| 1297 u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0); | 1453 u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0); |
| 1298 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); | 1454 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); |
| 1299 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); | 1455 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); |
| 1300 | 1456 |
| 1301 if (substream == wm8903->slave_substream) { | |
| 1302 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n"); | |
| 1303 return 0; | |
| 1304 } | |
| 1305 | |
| 1306 /* Enable sloping stopband filter for low sample rates */ | 1457 /* Enable sloping stopband filter for low sample rates */ |
| 1307 if (fs <= 24000) | 1458 if (fs <= 24000) |
| 1308 dac_digital1 |= WM8903_DAC_SB_FILT; | 1459 dac_digital1 |= WM8903_DAC_SB_FILT; |
| 1309 else | 1460 else |
| 1310 dac_digital1 &= ~WM8903_DAC_SB_FILT; | 1461 dac_digital1 &= ~WM8903_DAC_SB_FILT; |
| 1311 | 1462 |
| 1312 /* Configure sample rate logic for DSP - choose nearest rate */ | 1463 /* Configure sample rate logic for DSP - choose nearest rate */ |
| 1313 dsp_config = 0; | 1464 dsp_config = 0; |
| 1314 best_val = abs(sample_rates[dsp_config].rate - fs); | 1465 best_val = abs(sample_rates[dsp_config].rate - fs); |
| 1315 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) { | 1466 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) { |
| 1316 cur_val = abs(sample_rates[i].rate - fs); | 1467 cur_val = abs(sample_rates[i].rate - fs); |
| 1317 if (cur_val <= best_val) { | 1468 if (cur_val <= best_val) { |
| 1318 dsp_config = i; | 1469 dsp_config = i; |
| 1319 best_val = cur_val; | 1470 best_val = cur_val; |
| 1320 } | 1471 } |
| 1321 } | 1472 } |
| 1322 | 1473 |
| 1323 /* Constraints should stop us hitting this but let's make sure */ | |
| 1324 if (wm8903->capture_active) | |
| 1325 switch (sample_rates[dsp_config].rate) { | |
| 1326 case 88200: | |
| 1327 case 96000: | |
| 1328 dev_err(codec->dev, "%dHz unsupported by ADC\n", | |
| 1329 fs); | |
| 1330 return -EINVAL; | |
| 1331 | |
| 1332 default: | |
| 1333 break; | |
| 1334 } | |
| 1335 | |
| 1336 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); | 1474 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); |
| 1337 clock1 &= ~WM8903_SAMPLE_RATE_MASK; | 1475 clock1 &= ~WM8903_SAMPLE_RATE_MASK; |
| 1338 clock1 |= sample_rates[dsp_config].value; | 1476 clock1 |= sample_rates[dsp_config].value; |
| 1339 | 1477 |
| 1340 aif1 &= ~WM8903_AIF_WL_MASK; | 1478 aif1 &= ~WM8903_AIF_WL_MASK; |
| 1341 bclk = 2 * fs; | 1479 bclk = 2 * fs; |
| 1342 switch (params_format(params)) { | 1480 switch (params_format(params)) { |
| 1343 case SNDRV_PCM_FORMAT_S16_LE: | 1481 case SNDRV_PCM_FORMAT_S16_LE: |
| 1344 bclk *= 16; | 1482 bclk *= 16; |
| 1345 break; | 1483 break; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 aif2 &= ~WM8903_BCLK_DIV_MASK; | 1559 aif2 &= ~WM8903_BCLK_DIV_MASK; |
| 1422 aif3 &= ~WM8903_LRCLK_RATE_MASK; | 1560 aif3 &= ~WM8903_LRCLK_RATE_MASK; |
| 1423 | 1561 |
| 1424 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", | 1562 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", |
| 1425 bclk_divs[bclk_div].ratio / 10, bclk, | 1563 bclk_divs[bclk_div].ratio / 10, bclk, |
| 1426 (clk_sys * 10) / bclk_divs[bclk_div].ratio); | 1564 (clk_sys * 10) / bclk_divs[bclk_div].ratio); |
| 1427 | 1565 |
| 1428 aif2 |= bclk_divs[bclk_div].div; | 1566 aif2 |= bclk_divs[bclk_div].div; |
| 1429 aif3 |= bclk / fs; | 1567 aif3 |= bclk / fs; |
| 1430 | 1568 |
| 1569 wm8903->fs = params_rate(params); |
| 1570 wm8903_set_deemph(codec); |
| 1571 |
| 1431 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); | 1572 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); |
| 1432 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); | 1573 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); |
| 1433 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); | 1574 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); |
| 1434 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2); | 1575 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2); |
| 1435 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3); | 1576 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3); |
| 1436 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1); | 1577 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1); |
| 1437 | 1578 |
| 1438 return 0; | 1579 return 0; |
| 1439 } | 1580 } |
| 1440 | 1581 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 /* Enable interrupts we've got a report configured for */ | 1613 /* Enable interrupts we've got a report configured for */ |
| 1473 if (det) | 1614 if (det) |
| 1474 irq_mask &= ~WM8903_MICDET_EINT; | 1615 irq_mask &= ~WM8903_MICDET_EINT; |
| 1475 if (shrt) | 1616 if (shrt) |
| 1476 irq_mask &= ~WM8903_MICSHRT_EINT; | 1617 irq_mask &= ~WM8903_MICSHRT_EINT; |
| 1477 | 1618 |
| 1478 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK, | 1619 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK, |
| 1479 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, | 1620 WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, |
| 1480 irq_mask); | 1621 irq_mask); |
| 1481 | 1622 |
| 1482 » if (det && shrt) { | 1623 » if (det || shrt) { |
| 1483 /* Enable mic detection, this may not have been set through | 1624 /* Enable mic detection, this may not have been set through |
| 1484 * platform data (eg, if the defaults are OK). */ | 1625 * platform data (eg, if the defaults are OK). */ |
| 1485 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, | 1626 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, |
| 1486 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); | 1627 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); |
| 1487 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0, | 1628 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0, |
| 1488 WM8903_MICDET_ENA, WM8903_MICDET_ENA); | 1629 WM8903_MICDET_ENA, WM8903_MICDET_ENA); |
| 1489 } else { | 1630 } else { |
| 1490 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0, | 1631 snd_soc_update_bits(codec, WM8903_MIC_BIAS_CONTROL_0, |
| 1491 WM8903_MICDET_ENA, 0); | 1632 WM8903_MICDET_ENA, 0); |
| 1492 } | 1633 } |
| 1493 | 1634 |
| 1494 return 0; | 1635 return 0; |
| 1495 } | 1636 } |
| 1496 EXPORT_SYMBOL_GPL(wm8903_mic_detect); | 1637 EXPORT_SYMBOL_GPL(wm8903_mic_detect); |
| 1497 | 1638 |
| 1498 static irqreturn_t wm8903_irq(int irq, void *data) | 1639 static irqreturn_t wm8903_irq(int irq, void *data) |
| 1499 { | 1640 { |
| 1500 struct snd_soc_codec *codec = data; | 1641 struct snd_soc_codec *codec = data; |
| 1501 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1642 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 1502 int mic_report; | 1643 int mic_report; |
| 1503 int int_pol; | 1644 int int_pol; |
| 1504 int int_val = 0; | 1645 int int_val = 0; |
| 1505 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK); | 1646 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK); |
| 1506 | 1647 |
| 1507 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; | 1648 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; |
| 1508 | 1649 |
| 1509 if (int_val & WM8903_WSEQ_BUSY_EINT) { | 1650 if (int_val & WM8903_WSEQ_BUSY_EINT) { |
| 1510 » » dev_dbg(codec->dev, "Write sequencer done\n"); | 1651 » » dev_warn(codec->dev, "Write sequencer done\n"); |
| 1511 » » complete(&wm8903->wseq); | |
| 1512 } | 1652 } |
| 1513 | 1653 |
| 1514 /* | 1654 /* |
| 1515 * The rest is microphone jack detection. We need to manually | 1655 * The rest is microphone jack detection. We need to manually |
| 1516 * invert the polarity of the interrupt after each event - to | 1656 * invert the polarity of the interrupt after each event - to |
| 1517 * simplify the code keep track of the last state we reported | 1657 * simplify the code keep track of the last state we reported |
| 1518 * and just invert the relevant bits in both the report and | 1658 * and just invert the relevant bits in both the report and |
| 1519 * the polarity register. | 1659 * the polarity register. |
| 1520 */ | 1660 */ |
| 1521 mic_report = wm8903->mic_last_report; | 1661 mic_report = wm8903->mic_last_report; |
| 1522 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); | 1662 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); |
| 1523 | 1663 |
| 1664 #ifndef CONFIG_SND_SOC_WM8903_MODULE |
| 1665 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) |
| 1666 trace_snd_soc_jack_irq(dev_name(codec->dev)); |
| 1667 #endif |
| 1668 |
| 1524 if (int_val & WM8903_MICSHRT_EINT) { | 1669 if (int_val & WM8903_MICSHRT_EINT) { |
| 1525 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); | 1670 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); |
| 1526 | 1671 |
| 1527 mic_report ^= wm8903->mic_short; | 1672 mic_report ^= wm8903->mic_short; |
| 1528 int_pol ^= WM8903_MICSHRT_INV; | 1673 int_pol ^= WM8903_MICSHRT_INV; |
| 1529 } | 1674 } |
| 1530 | 1675 |
| 1531 if (int_val & WM8903_MICDET_EINT) { | 1676 if (int_val & WM8903_MICDET_EINT) { |
| 1532 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); | 1677 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); |
| 1533 | 1678 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1564 SNDRV_PCM_RATE_22050 | \ | 1709 SNDRV_PCM_RATE_22050 | \ |
| 1565 SNDRV_PCM_RATE_32000 | \ | 1710 SNDRV_PCM_RATE_32000 | \ |
| 1566 SNDRV_PCM_RATE_44100 | \ | 1711 SNDRV_PCM_RATE_44100 | \ |
| 1567 SNDRV_PCM_RATE_48000) | 1712 SNDRV_PCM_RATE_48000) |
| 1568 | 1713 |
| 1569 #define WM8903_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | 1714 #define WM8903_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ |
| 1570 SNDRV_PCM_FMTBIT_S20_3LE |\ | 1715 SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 1571 SNDRV_PCM_FMTBIT_S24_LE) | 1716 SNDRV_PCM_FMTBIT_S24_LE) |
| 1572 | 1717 |
| 1573 static struct snd_soc_dai_ops wm8903_dai_ops = { | 1718 static struct snd_soc_dai_ops wm8903_dai_ops = { |
| 1574 .startup = wm8903_startup, | |
| 1575 .shutdown = wm8903_shutdown, | |
| 1576 .hw_params = wm8903_hw_params, | 1719 .hw_params = wm8903_hw_params, |
| 1577 .digital_mute = wm8903_digital_mute, | 1720 .digital_mute = wm8903_digital_mute, |
| 1578 .set_fmt = wm8903_set_dai_fmt, | 1721 .set_fmt = wm8903_set_dai_fmt, |
| 1579 .set_sysclk = wm8903_set_dai_sysclk, | 1722 .set_sysclk = wm8903_set_dai_sysclk, |
| 1580 }; | 1723 }; |
| 1581 | 1724 |
| 1582 static struct snd_soc_dai_driver wm8903_dai = { | 1725 static struct snd_soc_dai_driver wm8903_dai = { |
| 1583 .name = "wm8903-hifi", | 1726 .name = "wm8903-hifi", |
| 1584 .playback = { | 1727 .playback = { |
| 1585 .stream_name = "Playback", | 1728 .stream_name = "Playback", |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1622 if (tmp_cache[i] != reg_cache[i]) | 1765 if (tmp_cache[i] != reg_cache[i]) |
| 1623 snd_soc_write(codec, i, tmp_cache[i]); | 1766 snd_soc_write(codec, i, tmp_cache[i]); |
| 1624 kfree(tmp_cache); | 1767 kfree(tmp_cache); |
| 1625 } else { | 1768 } else { |
| 1626 dev_err(codec->dev, "Failed to allocate temporary cache\n"); | 1769 dev_err(codec->dev, "Failed to allocate temporary cache\n"); |
| 1627 } | 1770 } |
| 1628 | 1771 |
| 1629 return 0; | 1772 return 0; |
| 1630 } | 1773 } |
| 1631 | 1774 |
| 1775 #ifdef CONFIG_GPIOLIB |
| 1776 static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip) |
| 1777 { |
| 1778 return container_of(chip, struct wm8903_priv, gpio_chip); |
| 1779 } |
| 1780 |
| 1781 static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset) |
| 1782 { |
| 1783 if (offset >= WM8903_NUM_GPIO) |
| 1784 return -EINVAL; |
| 1785 |
| 1786 return 0; |
| 1787 } |
| 1788 |
| 1789 static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) |
| 1790 { |
| 1791 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
| 1792 struct snd_soc_codec *codec = wm8903->codec; |
| 1793 unsigned int mask, val; |
| 1794 |
| 1795 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK; |
| 1796 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | |
| 1797 WM8903_GP1_DIR; |
| 1798 |
| 1799 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, |
| 1800 mask, val); |
| 1801 } |
| 1802 |
| 1803 static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 1804 { |
| 1805 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
| 1806 struct snd_soc_codec *codec = wm8903->codec; |
| 1807 int reg; |
| 1808 |
| 1809 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset); |
| 1810 |
| 1811 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; |
| 1812 } |
| 1813 |
| 1814 static int wm8903_gpio_direction_out(struct gpio_chip *chip, |
| 1815 unsigned offset, int value) |
| 1816 { |
| 1817 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
| 1818 struct snd_soc_codec *codec = wm8903->codec; |
| 1819 unsigned int mask, val; |
| 1820 |
| 1821 mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK; |
| 1822 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | |
| 1823 (value << WM8903_GP2_LVL_SHIFT); |
| 1824 |
| 1825 return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, |
| 1826 mask, val); |
| 1827 } |
| 1828 |
| 1829 static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| 1830 { |
| 1831 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
| 1832 struct snd_soc_codec *codec = wm8903->codec; |
| 1833 |
| 1834 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, |
| 1835 WM8903_GP1_LVL_MASK, |
| 1836 !!value << WM8903_GP1_LVL_SHIFT); |
| 1837 } |
| 1838 |
| 1839 static struct gpio_chip wm8903_template_chip = { |
| 1840 .label = "wm8903", |
| 1841 .owner = THIS_MODULE, |
| 1842 .request = wm8903_gpio_request, |
| 1843 .direction_input = wm8903_gpio_direction_in, |
| 1844 .get = wm8903_gpio_get, |
| 1845 .direction_output = wm8903_gpio_direction_out, |
| 1846 .set = wm8903_gpio_set, |
| 1847 .can_sleep = 1, |
| 1848 }; |
| 1849 |
| 1850 static void wm8903_init_gpio(struct snd_soc_codec *codec) |
| 1851 { |
| 1852 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 1853 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); |
| 1854 int ret; |
| 1855 |
| 1856 wm8903->gpio_chip = wm8903_template_chip; |
| 1857 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; |
| 1858 wm8903->gpio_chip.dev = codec->dev; |
| 1859 |
| 1860 if (pdata && pdata->gpio_base) |
| 1861 wm8903->gpio_chip.base = pdata->gpio_base; |
| 1862 else |
| 1863 wm8903->gpio_chip.base = -1; |
| 1864 |
| 1865 ret = gpiochip_add(&wm8903->gpio_chip); |
| 1866 if (ret != 0) |
| 1867 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); |
| 1868 } |
| 1869 |
| 1870 static void wm8903_free_gpio(struct snd_soc_codec *codec) |
| 1871 { |
| 1872 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 1873 int ret; |
| 1874 |
| 1875 ret = gpiochip_remove(&wm8903->gpio_chip); |
| 1876 if (ret != 0) |
| 1877 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); |
| 1878 } |
| 1879 #else |
| 1880 static void wm8903_init_gpio(struct snd_soc_codec *codec) |
| 1881 { |
| 1882 } |
| 1883 |
| 1884 static void wm8903_free_gpio(struct snd_soc_codec *codec) |
| 1885 { |
| 1886 } |
| 1887 #endif |
| 1888 |
| 1632 static int wm8903_probe(struct snd_soc_codec *codec) | 1889 static int wm8903_probe(struct snd_soc_codec *codec) |
| 1633 { | 1890 { |
| 1634 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); | 1891 struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); |
| 1635 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1892 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
| 1636 int ret, i; | 1893 int ret, i; |
| 1637 int trigger, irq_pol; | 1894 int trigger, irq_pol; |
| 1638 u16 val; | 1895 u16 val; |
| 1639 | 1896 |
| 1640 » init_completion(&wm8903->wseq); | 1897 » wm8903->codec = codec; |
| 1641 | 1898 |
| 1642 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 1899 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
| 1643 if (ret != 0) { | 1900 if (ret != 0) { |
| 1644 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1901 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| 1645 return ret; | 1902 return ret; |
| 1646 } | 1903 } |
| 1647 | 1904 |
| 1648 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); | 1905 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); |
| 1649 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { | 1906 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { |
| 1650 dev_err(codec->dev, | 1907 dev_err(codec->dev, |
| 1651 "Device with ID register %x is not a WM8903\n", val); | 1908 "Device with ID register %x is not a WM8903\n", val); |
| 1652 return -ENODEV; | 1909 return -ENODEV; |
| 1653 } | 1910 } |
| 1654 | 1911 |
| 1655 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); | 1912 val = snd_soc_read(codec, WM8903_REVISION_NUMBER); |
| 1656 » dev_info(codec->dev, "WM8903 revision %d\n", | 1913 » dev_info(codec->dev, "WM8903 revision %c\n", |
| 1657 » » val & WM8903_CHIP_REV_MASK); | 1914 » » (val & WM8903_CHIP_REV_MASK) + 'A'); |
| 1658 | 1915 |
| 1659 wm8903_reset(codec); | 1916 wm8903_reset(codec); |
| 1660 | 1917 |
| 1661 /* Set up GPIOs and microphone detection */ | 1918 /* Set up GPIOs and microphone detection */ |
| 1662 if (pdata) { | 1919 if (pdata) { |
| 1920 bool mic_gpio = false; |
| 1921 |
| 1663 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { | 1922 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { |
| 1664 » » » if (!pdata->gpio_cfg[i]) | 1923 » » » if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG) |
| 1665 continue; | 1924 continue; |
| 1666 | 1925 |
| 1667 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, | 1926 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, |
| 1668 pdata->gpio_cfg[i] & 0xffff); | 1927 pdata->gpio_cfg[i] & 0xffff); |
| 1928 |
| 1929 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) |
| 1930 >> WM8903_GP1_FN_SHIFT; |
| 1931 |
| 1932 switch (val) { |
| 1933 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: |
| 1934 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: |
| 1935 mic_gpio = true; |
| 1936 break; |
| 1937 default: |
| 1938 break; |
| 1939 } |
| 1669 } | 1940 } |
| 1670 | 1941 |
| 1671 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, | 1942 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, |
| 1672 pdata->micdet_cfg); | 1943 pdata->micdet_cfg); |
| 1673 | 1944 |
| 1674 /* Microphone detection needs the WSEQ clock */ | 1945 /* Microphone detection needs the WSEQ clock */ |
| 1675 if (pdata->micdet_cfg) | 1946 if (pdata->micdet_cfg) |
| 1676 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, | 1947 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, |
| 1677 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); | 1948 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); |
| 1678 | 1949 |
| 1950 /* If microphone detection is enabled by pdata but |
| 1951 * detected via IRQ then interrupts can be lost before |
| 1952 * the machine driver has set up microphone detection |
| 1953 * IRQs as the IRQs are clear on read. The detection |
| 1954 * will be enabled when the machine driver configures. |
| 1955 */ |
| 1956 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); |
| 1957 |
| 1679 wm8903->mic_delay = pdata->micdet_delay; | 1958 wm8903->mic_delay = pdata->micdet_delay; |
| 1680 } | 1959 } |
| 1681 | 1960 |
| 1682 if (wm8903->irq) { | 1961 if (wm8903->irq) { |
| 1683 if (pdata && pdata->irq_active_low) { | 1962 if (pdata && pdata->irq_active_low) { |
| 1684 trigger = IRQF_TRIGGER_LOW; | 1963 trigger = IRQF_TRIGGER_LOW; |
| 1685 irq_pol = WM8903_IRQ_POL; | 1964 irq_pol = WM8903_IRQ_POL; |
| 1686 } else { | 1965 } else { |
| 1687 trigger = IRQF_TRIGGER_HIGH; | 1966 trigger = IRQF_TRIGGER_HIGH; |
| 1688 irq_pol = 0; | 1967 irq_pol = 0; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1728 val |= WM8903_LINEOUTVU; | 2007 val |= WM8903_LINEOUTVU; |
| 1729 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val); | 2008 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val); |
| 1730 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val); | 2009 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val); |
| 1731 | 2010 |
| 1732 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT); | 2011 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT); |
| 1733 val |= WM8903_SPKVU; | 2012 val |= WM8903_SPKVU; |
| 1734 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val); | 2013 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val); |
| 1735 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); | 2014 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); |
| 1736 | 2015 |
| 1737 /* Enable DAC soft mute by default */ | 2016 /* Enable DAC soft mute by default */ |
| 1738 » val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); | 2017 » snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, |
| 1739 » val |= WM8903_DAC_MUTEMODE; | 2018 » » » WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, |
| 1740 » snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); | 2019 » » » WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); |
| 1741 | 2020 |
| 1742 snd_soc_add_controls(codec, wm8903_snd_controls, | 2021 snd_soc_add_controls(codec, wm8903_snd_controls, |
| 1743 ARRAY_SIZE(wm8903_snd_controls)); | 2022 ARRAY_SIZE(wm8903_snd_controls)); |
| 1744 wm8903_add_widgets(codec); | 2023 wm8903_add_widgets(codec); |
| 1745 | 2024 |
| 2025 wm8903_init_gpio(codec); |
| 2026 |
| 1746 return ret; | 2027 return ret; |
| 1747 } | 2028 } |
| 1748 | 2029 |
| 1749 /* power down chip */ | 2030 /* power down chip */ |
| 1750 static int wm8903_remove(struct snd_soc_codec *codec) | 2031 static int wm8903_remove(struct snd_soc_codec *codec) |
| 1751 { | 2032 { |
| 2033 wm8903_free_gpio(codec); |
| 1752 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2034 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); |
| 1753 return 0; | 2035 return 0; |
| 1754 } | 2036 } |
| 1755 | 2037 |
| 1756 static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { | 2038 static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { |
| 1757 .probe = wm8903_probe, | 2039 .probe = wm8903_probe, |
| 1758 .remove = wm8903_remove, | 2040 .remove = wm8903_remove, |
| 1759 .suspend = wm8903_suspend, | 2041 .suspend = wm8903_suspend, |
| 1760 .resume = wm8903_resume, | 2042 .resume = wm8903_resume, |
| 1761 .set_bias_level = wm8903_set_bias_level, | 2043 .set_bias_level = wm8903_set_bias_level, |
| 1762 .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults), | 2044 .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults), |
| 1763 .reg_word_size = sizeof(u16), | 2045 .reg_word_size = sizeof(u16), |
| 1764 .reg_cache_default = wm8903_reg_defaults, | 2046 .reg_cache_default = wm8903_reg_defaults, |
| 1765 .volatile_register = wm8903_volatile_register, | 2047 .volatile_register = wm8903_volatile_register, |
| 2048 .seq_notifier = wm8903_seq_notifier, |
| 1766 }; | 2049 }; |
| 1767 | 2050 |
| 1768 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 2051 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 1769 static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | 2052 static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, |
| 1770 const struct i2c_device_id *id) | 2053 const struct i2c_device_id *id) |
| 1771 { | 2054 { |
| 1772 struct wm8903_priv *wm8903; | 2055 struct wm8903_priv *wm8903; |
| 1773 int ret; | 2056 int ret; |
| 1774 | 2057 |
| 1775 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); | 2058 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1794 } | 2077 } |
| 1795 | 2078 |
| 1796 static const struct i2c_device_id wm8903_i2c_id[] = { | 2079 static const struct i2c_device_id wm8903_i2c_id[] = { |
| 1797 { "wm8903", 0 }, | 2080 { "wm8903", 0 }, |
| 1798 { } | 2081 { } |
| 1799 }; | 2082 }; |
| 1800 MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); | 2083 MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); |
| 1801 | 2084 |
| 1802 static struct i2c_driver wm8903_i2c_driver = { | 2085 static struct i2c_driver wm8903_i2c_driver = { |
| 1803 .driver = { | 2086 .driver = { |
| 1804 » » .name = "wm8903-codec", | 2087 » » .name = "wm8903", |
| 1805 .owner = THIS_MODULE, | 2088 .owner = THIS_MODULE, |
| 1806 }, | 2089 }, |
| 1807 .probe = wm8903_i2c_probe, | 2090 .probe = wm8903_i2c_probe, |
| 1808 .remove = __devexit_p(wm8903_i2c_remove), | 2091 .remove = __devexit_p(wm8903_i2c_remove), |
| 1809 .id_table = wm8903_i2c_id, | 2092 .id_table = wm8903_i2c_id, |
| 1810 }; | 2093 }; |
| 1811 #endif | 2094 #endif |
| 1812 | 2095 |
| 1813 static int __init wm8903_modinit(void) | 2096 static int __init wm8903_modinit(void) |
| 1814 { | 2097 { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1828 { | 2111 { |
| 1829 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 2112 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 1830 i2c_del_driver(&wm8903_i2c_driver); | 2113 i2c_del_driver(&wm8903_i2c_driver); |
| 1831 #endif | 2114 #endif |
| 1832 } | 2115 } |
| 1833 module_exit(wm8903_exit); | 2116 module_exit(wm8903_exit); |
| 1834 | 2117 |
| 1835 MODULE_DESCRIPTION("ASoC WM8903 driver"); | 2118 MODULE_DESCRIPTION("ASoC WM8903 driver"); |
| 1836 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); | 2119 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); |
| 1837 MODULE_LICENSE("GPL"); | 2120 MODULE_LICENSE("GPL"); |
| OLD | NEW |