Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: sound/soc/codecs/wm8960.c

Issue 6577007: CHROMIUM: ASoC: Import entire upstream ASoC tree (Closed)
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sound/soc/codecs/wm8955.c ('k') | sound/soc/codecs/wm8961.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * wm8960.c -- WM8960 ALSA SoC Audio driver 2 * wm8960.c -- WM8960 ALSA SoC Audio driver
3 * 3 *
4 * Author: Liam Girdwood 4 * Author: Liam Girdwood
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11 #include <linux/module.h> 11 #include <linux/module.h>
12 #include <linux/moduleparam.h> 12 #include <linux/moduleparam.h>
13 #include <linux/init.h> 13 #include <linux/init.h>
14 #include <linux/delay.h> 14 #include <linux/delay.h>
15 #include <linux/pm.h> 15 #include <linux/pm.h>
16 #include <linux/i2c.h> 16 #include <linux/i2c.h>
17 #include <linux/platform_device.h> 17 #include <linux/platform_device.h>
18 #include <linux/slab.h> 18 #include <linux/slab.h>
19 #include <sound/core.h> 19 #include <sound/core.h>
20 #include <sound/pcm.h> 20 #include <sound/pcm.h>
21 #include <sound/pcm_params.h> 21 #include <sound/pcm_params.h>
22 #include <sound/soc.h> 22 #include <sound/soc.h>
23 #include <sound/soc-dapm.h>
24 #include <sound/initval.h> 23 #include <sound/initval.h>
25 #include <sound/tlv.h> 24 #include <sound/tlv.h>
26 #include <sound/wm8960.h> 25 #include <sound/wm8960.h>
27 26
28 #include "wm8960.h" 27 #include "wm8960.h"
29 28
30 #define AUDIO_NAME "wm8960" 29 #define AUDIO_NAME "wm8960"
31 30
32 /* R25 - Power 1 */ 31 /* R25 - Power 1 */
33 #define WM8960_VMID_MASK 0x180 32 #define WM8960_VMID_MASK 0x180
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 0x0000, 0x0000, 0x0000, 0x0000, 64 0x0000, 0x0000, 0x0000, 0x0000,
66 0x0100, 0x0100, 0x0050, 0x0050, 65 0x0100, 0x0100, 0x0050, 0x0050,
67 0x0050, 0x0050, 0x0000, 0x0000, 66 0x0050, 0x0050, 0x0000, 0x0000,
68 0x0000, 0x0000, 0x0040, 0x0000, 67 0x0000, 0x0000, 0x0040, 0x0000,
69 0x0000, 0x0050, 0x0050, 0x0000, 68 0x0000, 0x0050, 0x0050, 0x0000,
70 0x0002, 0x0037, 0x004d, 0x0080, 69 0x0002, 0x0037, 0x004d, 0x0080,
71 0x0008, 0x0031, 0x0026, 0x00e9, 70 0x0008, 0x0031, 0x0026, 0x00e9,
72 }; 71 };
73 72
74 struct wm8960_priv { 73 struct wm8960_priv {
75 u16 reg_cache[WM8960_CACHEREGNUM];
76 enum snd_soc_control_type control_type; 74 enum snd_soc_control_type control_type;
77 void *control_data; 75 void *control_data;
78 int (*set_bias_level)(struct snd_soc_codec *, 76 int (*set_bias_level)(struct snd_soc_codec *,
79 enum snd_soc_bias_level level); 77 enum snd_soc_bias_level level);
80 struct snd_soc_dapm_widget *lout1; 78 struct snd_soc_dapm_widget *lout1;
81 struct snd_soc_dapm_widget *rout1; 79 struct snd_soc_dapm_widget *rout1;
82 struct snd_soc_dapm_widget *out3; 80 struct snd_soc_dapm_widget *out3;
83 bool deemph; 81 bool deemph;
84 int playback_fs; 82 int playback_fs;
85 }; 83 };
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 { "HP_R", NULL, "OUT3 VMID" }, 380 { "HP_R", NULL, "OUT3 VMID" },
383 381
384 { "OUT3 VMID", NULL, "Left Output Mixer" }, 382 { "OUT3 VMID", NULL, "Left Output Mixer" },
385 { "OUT3 VMID", NULL, "Right Output Mixer" }, 383 { "OUT3 VMID", NULL, "Right Output Mixer" },
386 }; 384 };
387 385
388 static int wm8960_add_widgets(struct snd_soc_codec *codec) 386 static int wm8960_add_widgets(struct snd_soc_codec *codec)
389 { 387 {
390 struct wm8960_data *pdata = codec->dev->platform_data; 388 struct wm8960_data *pdata = codec->dev->platform_data;
391 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 389 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
390 struct snd_soc_dapm_context *dapm = &codec->dapm;
392 struct snd_soc_dapm_widget *w; 391 struct snd_soc_dapm_widget *w;
393 392
394 » snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, 393 » snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
395 ARRAY_SIZE(wm8960_dapm_widgets)); 394 ARRAY_SIZE(wm8960_dapm_widgets));
396 395
397 » snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 396 » snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
398 397
399 /* In capless mode OUT3 is used to provide VMID for the 398 /* In capless mode OUT3 is used to provide VMID for the
400 * headphone outputs, otherwise it is used as a mono mixer. 399 * headphone outputs, otherwise it is used as a mono mixer.
401 */ 400 */
402 if (pdata && pdata->capless) { 401 if (pdata && pdata->capless) {
403 » » snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless, 402 » » snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
404 ARRAY_SIZE(wm8960_dapm_widgets_capless )); 403 ARRAY_SIZE(wm8960_dapm_widgets_capless ));
405 404
406 » » snd_soc_dapm_add_routes(codec, audio_paths_capless, 405 » » snd_soc_dapm_add_routes(dapm, audio_paths_capless,
407 ARRAY_SIZE(audio_paths_capless)); 406 ARRAY_SIZE(audio_paths_capless));
408 } else { 407 } else {
409 » » snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3, 408 » » snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
410 ARRAY_SIZE(wm8960_dapm_widgets_out3)); 409 ARRAY_SIZE(wm8960_dapm_widgets_out3));
411 410
412 » » snd_soc_dapm_add_routes(codec, audio_paths_out3, 411 » » snd_soc_dapm_add_routes(dapm, audio_paths_out3,
413 ARRAY_SIZE(audio_paths_out3)); 412 ARRAY_SIZE(audio_paths_out3));
414 } 413 }
415 414
416 /* We need to power up the headphone output stage out of 415 /* We need to power up the headphone output stage out of
417 * sequence for capless mode. To save scanning the widget 416 * sequence for capless mode. To save scanning the widget
418 * list each time to find the desired power state do so now 417 * list each time to find the desired power state do so now
419 * and save the result. 418 * and save the result.
420 */ 419 */
421 » list_for_each_entry(w, &codec->dapm_widgets, list) { 420 » list_for_each_entry(w, &codec->card->widgets, list) {
421 » » if (w->dapm != &codec->dapm)
422 » » » continue;
422 if (strcmp(w->name, "LOUT1 PGA") == 0) 423 if (strcmp(w->name, "LOUT1 PGA") == 0)
423 wm8960->lout1 = w; 424 wm8960->lout1 = w;
424 if (strcmp(w->name, "ROUT1 PGA") == 0) 425 if (strcmp(w->name, "ROUT1 PGA") == 0)
425 wm8960->rout1 = w; 426 wm8960->rout1 = w;
426 if (strcmp(w->name, "OUT3 VMID") == 0) 427 if (strcmp(w->name, "OUT3 VMID") == 0)
427 wm8960->out3 = w; 428 wm8960->out3 = w;
428 } 429 }
429 430
430 return 0; 431 return 0;
431 } 432 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 567
567 case SND_SOC_BIAS_PREPARE: 568 case SND_SOC_BIAS_PREPARE:
568 /* Set VMID to 2x50k */ 569 /* Set VMID to 2x50k */
569 reg = snd_soc_read(codec, WM8960_POWER1); 570 reg = snd_soc_read(codec, WM8960_POWER1);
570 reg &= ~0x180; 571 reg &= ~0x180;
571 reg |= 0x80; 572 reg |= 0x80;
572 snd_soc_write(codec, WM8960_POWER1, reg); 573 snd_soc_write(codec, WM8960_POWER1, reg);
573 break; 574 break;
574 575
575 case SND_SOC_BIAS_STANDBY: 576 case SND_SOC_BIAS_STANDBY:
576 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { 577 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
577 /* Enable anti-pop features */ 578 /* Enable anti-pop features */
578 snd_soc_write(codec, WM8960_APOP1, 579 snd_soc_write(codec, WM8960_APOP1,
579 WM8960_POBCTRL | WM8960_SOFT_ST | 580 WM8960_POBCTRL | WM8960_SOFT_ST |
580 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 581 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
581 582
582 /* Enable & ramp VMID at 2x50k */ 583 /* Enable & ramp VMID at 2x50k */
583 reg = snd_soc_read(codec, WM8960_POWER1); 584 reg = snd_soc_read(codec, WM8960_POWER1);
584 reg |= 0x80; 585 reg |= 0x80;
585 snd_soc_write(codec, WM8960_POWER1, reg); 586 snd_soc_write(codec, WM8960_POWER1, reg);
586 msleep(100); 587 msleep(100);
(...skipping 17 matching lines...) Expand all
604 snd_soc_write(codec, WM8960_APOP1, 605 snd_soc_write(codec, WM8960_APOP1,
605 WM8960_POBCTRL | WM8960_SOFT_ST | 606 WM8960_POBCTRL | WM8960_SOFT_ST |
606 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 607 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
607 608
608 /* Disable VMID and VREF, let them discharge */ 609 /* Disable VMID and VREF, let them discharge */
609 snd_soc_write(codec, WM8960_POWER1, 0); 610 snd_soc_write(codec, WM8960_POWER1, 0);
610 msleep(600); 611 msleep(600);
611 break; 612 break;
612 } 613 }
613 614
614 » codec->bias_level = level; 615 » codec->dapm.bias_level = level;
615 616
616 return 0; 617 return 0;
617 } 618 }
618 619
619 static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, 620 static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
620 enum snd_soc_bias_level level) 621 enum snd_soc_bias_level level)
621 { 622 {
622 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 623 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
623 int reg; 624 int reg;
624 625
625 switch (level) { 626 switch (level) {
626 case SND_SOC_BIAS_ON: 627 case SND_SOC_BIAS_ON:
627 break; 628 break;
628 629
629 case SND_SOC_BIAS_PREPARE: 630 case SND_SOC_BIAS_PREPARE:
630 » » switch (codec->bias_level) { 631 » » switch (codec->dapm.bias_level) {
631 case SND_SOC_BIAS_STANDBY: 632 case SND_SOC_BIAS_STANDBY:
632 /* Enable anti pop mode */ 633 /* Enable anti pop mode */
633 snd_soc_update_bits(codec, WM8960_APOP1, 634 snd_soc_update_bits(codec, WM8960_APOP1,
634 WM8960_POBCTRL | WM8960_SOFT_ST | 635 WM8960_POBCTRL | WM8960_SOFT_ST |
635 WM8960_BUFDCOPEN, 636 WM8960_BUFDCOPEN,
636 WM8960_POBCTRL | WM8960_SOFT_ST | 637 WM8960_POBCTRL | WM8960_SOFT_ST |
637 WM8960_BUFDCOPEN); 638 WM8960_BUFDCOPEN);
638 639
639 /* Enable LOUT1, ROUT1 and OUT3 if they're enabled */ 640 /* Enable LOUT1, ROUT1 and OUT3 if they're enabled */
640 reg = 0; 641 reg = 0;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 snd_soc_update_bits(codec, WM8960_POWER1, 676 snd_soc_update_bits(codec, WM8960_POWER1,
676 WM8960_VREF | WM8960_VMID_MASK, 0); 677 WM8960_VREF | WM8960_VMID_MASK, 0);
677 break; 678 break;
678 679
679 default: 680 default:
680 break; 681 break;
681 } 682 }
682 break; 683 break;
683 684
684 case SND_SOC_BIAS_STANDBY: 685 case SND_SOC_BIAS_STANDBY:
685 » » switch (codec->bias_level) { 686 » » switch (codec->dapm.bias_level) {
686 case SND_SOC_BIAS_PREPARE: 687 case SND_SOC_BIAS_PREPARE:
687 /* Disable HP discharge */ 688 /* Disable HP discharge */
688 snd_soc_update_bits(codec, WM8960_APOP2, 689 snd_soc_update_bits(codec, WM8960_APOP2,
689 WM8960_DISOP | WM8960_DRES_MASK, 690 WM8960_DISOP | WM8960_DRES_MASK,
690 0); 691 0);
691 692
692 /* Disable anti-pop features */ 693 /* Disable anti-pop features */
693 snd_soc_update_bits(codec, WM8960_APOP1, 694 snd_soc_update_bits(codec, WM8960_APOP1,
694 WM8960_POBCTRL | WM8960_SOFT_ST | 695 WM8960_POBCTRL | WM8960_SOFT_ST |
695 WM8960_BUFDCOPEN, 696 WM8960_BUFDCOPEN,
696 WM8960_POBCTRL | WM8960_SOFT_ST | 697 WM8960_POBCTRL | WM8960_SOFT_ST |
697 WM8960_BUFDCOPEN); 698 WM8960_BUFDCOPEN);
698 break; 699 break;
699 700
700 default: 701 default:
701 break; 702 break;
702 } 703 }
703 break; 704 break;
704 705
705 case SND_SOC_BIAS_OFF: 706 case SND_SOC_BIAS_OFF:
706 break; 707 break;
707 } 708 }
708 709
709 » codec->bias_level = level; 710 » codec->dapm.bias_level = level;
710 711
711 return 0; 712 return 0;
712 } 713 }
713 714
714 /* PLL divisors */ 715 /* PLL divisors */
715 struct _pll_div { 716 struct _pll_div {
716 u32 pre_div:1; 717 u32 pre_div:1;
717 u32 n:4; 718 u32 n:4;
718 u32 k:24; 719 u32 k:24;
719 }; 720 };
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 { 1066 {
1066 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1067 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1067 i2c_del_driver(&wm8960_i2c_driver); 1068 i2c_del_driver(&wm8960_i2c_driver);
1068 #endif 1069 #endif
1069 } 1070 }
1070 module_exit(wm8960_exit); 1071 module_exit(wm8960_exit);
1071 1072
1072 MODULE_DESCRIPTION("ASoC WM8960 driver"); 1073 MODULE_DESCRIPTION("ASoC WM8960 driver");
1073 MODULE_AUTHOR("Liam Girdwood"); 1074 MODULE_AUTHOR("Liam Girdwood");
1074 MODULE_LICENSE("GPL"); 1075 MODULE_LICENSE("GPL");
OLDNEW
« no previous file with comments | « sound/soc/codecs/wm8955.c ('k') | sound/soc/codecs/wm8961.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698