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

Side by Side Diff: sound/soc/codecs/wm8971.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/wm8962.c ('k') | sound/soc/codecs/wm8974.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 * wm8971.c -- WM8971 ALSA SoC Audio driver 2 * wm8971.c -- WM8971 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2005 Lab126, Inc. 4 * Copyright 2005 Lab126, Inc.
5 * 5 *
6 * Author: Kenneth Kiraly <kiraly@lab126.com> 6 * Author: Kenneth Kiraly <kiraly@lab126.com>
7 * 7 *
8 * Based on wm8753.c by Liam Girdwood 8 * Based on wm8753.c by Liam Girdwood
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. 13 * option) any later version.
14 */ 14 */
15 15
16 #include <linux/module.h> 16 #include <linux/module.h>
17 #include <linux/moduleparam.h> 17 #include <linux/moduleparam.h>
18 #include <linux/init.h> 18 #include <linux/init.h>
19 #include <linux/delay.h> 19 #include <linux/delay.h>
20 #include <linux/pm.h> 20 #include <linux/pm.h>
21 #include <linux/i2c.h> 21 #include <linux/i2c.h>
22 #include <linux/platform_device.h> 22 #include <linux/platform_device.h>
23 #include <linux/slab.h> 23 #include <linux/slab.h>
24 #include <sound/core.h> 24 #include <sound/core.h>
25 #include <sound/pcm.h> 25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h> 26 #include <sound/pcm_params.h>
27 #include <sound/soc.h> 27 #include <sound/soc.h>
28 #include <sound/soc-dapm.h>
29 #include <sound/initval.h> 28 #include <sound/initval.h>
30 29
31 #include "wm8971.h" 30 #include "wm8971.h"
32 31
33 #define WM8971_REG_COUNT 43 32 #define WM8971_REG_COUNT 43
34 33
35 static struct workqueue_struct *wm8971_workq = NULL; 34 static struct workqueue_struct *wm8971_workq = NULL;
36 35
37 /* codec private data */ 36 /* codec private data */
38 struct wm8971_priv { 37 struct wm8971_priv {
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"}, 325 {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
327 {"Right ADC Mux", "Digital Mono", "Right PGA Mux"}, 326 {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
328 327
329 /* ADC */ 328 /* ADC */
330 {"Left ADC", NULL, "Left ADC Mux"}, 329 {"Left ADC", NULL, "Left ADC Mux"},
331 {"Right ADC", NULL, "Right ADC Mux"}, 330 {"Right ADC", NULL, "Right ADC Mux"},
332 }; 331 };
333 332
334 static int wm8971_add_widgets(struct snd_soc_codec *codec) 333 static int wm8971_add_widgets(struct snd_soc_codec *codec)
335 { 334 {
336 » snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets, 335 » struct snd_soc_dapm_context *dapm = &codec->dapm;
336
337 » snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
337 ARRAY_SIZE(wm8971_dapm_widgets)); 338 ARRAY_SIZE(wm8971_dapm_widgets));
338 339 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
339 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
340 340
341 return 0; 341 return 0;
342 } 342 }
343 343
344 struct _coeff_div { 344 struct _coeff_div {
345 u32 mclk; 345 u32 mclk;
346 u32 rate; 346 u32 rate;
347 u16 fs; 347 u16 fs;
348 u8 sr:5; 348 u8 sr:5;
349 u8 usb:1; 349 u8 usb:1;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 case SND_SOC_BIAS_PREPARE: 546 case SND_SOC_BIAS_PREPARE:
547 break; 547 break;
548 case SND_SOC_BIAS_STANDBY: 548 case SND_SOC_BIAS_STANDBY:
549 /* mute dac and set vmid to 500k, enable VREF */ 549 /* mute dac and set vmid to 500k, enable VREF */
550 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140); 550 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
551 break; 551 break;
552 case SND_SOC_BIAS_OFF: 552 case SND_SOC_BIAS_OFF:
553 snd_soc_write(codec, WM8971_PWR1, 0x0001); 553 snd_soc_write(codec, WM8971_PWR1, 0x0001);
554 break; 554 break;
555 } 555 }
556 » codec->bias_level = level; 556 » codec->dapm.bias_level = level;
557 return 0; 557 return 0;
558 } 558 }
559 559
560 #define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 560 #define WM8971_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
561 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_441 00 | \ 561 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_441 00 | \
562 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_960 00) 562 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_960 00)
563 563
564 #define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 564 #define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
565 SNDRV_PCM_FMTBIT_S24_LE) 565 SNDRV_PCM_FMTBIT_S24_LE)
566 566
(...skipping 16 matching lines...) Expand all
583 .stream_name = "Capture", 583 .stream_name = "Capture",
584 .channels_min = 1, 584 .channels_min = 1,
585 .channels_max = 2, 585 .channels_max = 2,
586 .rates = WM8971_RATES, 586 .rates = WM8971_RATES,
587 .formats = WM8971_FORMATS,}, 587 .formats = WM8971_FORMATS,},
588 .ops = &wm8971_dai_ops, 588 .ops = &wm8971_dai_ops,
589 }; 589 };
590 590
591 static void wm8971_work(struct work_struct *work) 591 static void wm8971_work(struct work_struct *work)
592 { 592 {
593 » struct snd_soc_codec *codec = 593 » struct snd_soc_dapm_context *dapm =
594 » » container_of(work, struct snd_soc_codec, delayed_work.work); 594 » » container_of(work, struct snd_soc_dapm_context,
595 » wm8971_set_bias_level(codec, codec->bias_level); 595 » » » delayed_work.work);
596 » struct snd_soc_codec *codec = dapm->codec;
597 » wm8971_set_bias_level(codec, codec->dapm.bias_level);
596 } 598 }
597 599
598 static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state) 600 static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
599 { 601 {
600 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); 602 wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF);
601 return 0; 603 return 0;
602 } 604 }
603 605
604 static int wm8971_resume(struct snd_soc_codec *codec) 606 static int wm8971_resume(struct snd_soc_codec *codec)
605 { 607 {
606 int i; 608 int i;
607 u8 data[2]; 609 u8 data[2];
608 u16 *cache = codec->reg_cache; 610 u16 *cache = codec->reg_cache;
609 u16 reg; 611 u16 reg;
610 612
611 /* Sync reg_cache with the hardware */ 613 /* Sync reg_cache with the hardware */
612 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) { 614 for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) {
613 if (i + 1 == WM8971_RESET) 615 if (i + 1 == WM8971_RESET)
614 continue; 616 continue;
615 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 617 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
616 data[1] = cache[i] & 0x00ff; 618 data[1] = cache[i] & 0x00ff;
617 codec->hw_write(codec->control_data, data, 2); 619 codec->hw_write(codec->control_data, data, 2);
618 } 620 }
619 621
620 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 622 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
621 623
622 /* charge wm8971 caps */ 624 /* charge wm8971 caps */
623 » if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 625 » if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
624 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 626 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
625 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); 627 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
626 » » codec->bias_level = SND_SOC_BIAS_ON; 628 » » codec->dapm.bias_level = SND_SOC_BIAS_ON;
627 » » queue_delayed_work(wm8971_workq, &codec->delayed_work, 629 » » queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
628 msecs_to_jiffies(1000)); 630 msecs_to_jiffies(1000));
629 } 631 }
630 632
631 return 0; 633 return 0;
632 } 634 }
633 635
634 static int wm8971_probe(struct snd_soc_codec *codec) 636 static int wm8971_probe(struct snd_soc_codec *codec)
635 { 637 {
636 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec); 638 struct wm8971_priv *wm8971 = snd_soc_codec_get_drvdata(codec);
637 int ret = 0; 639 int ret = 0;
638 u16 reg; 640 u16 reg;
639 641
640 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type); 642 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8971->control_type);
641 if (ret < 0) { 643 if (ret < 0) {
642 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret); 644 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
643 return ret; 645 return ret;
644 } 646 }
645 647
646 » INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work); 648 » INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
647 wm8971_workq = create_workqueue("wm8971"); 649 wm8971_workq = create_workqueue("wm8971");
648 if (wm8971_workq == NULL) 650 if (wm8971_workq == NULL)
649 return -ENOMEM; 651 return -ENOMEM;
650 652
651 wm8971_reset(codec); 653 wm8971_reset(codec);
652 654
653 /* charge output caps - set vmid to 5k for quick power up */ 655 /* charge output caps - set vmid to 5k for quick power up */
654 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 656 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
655 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); 657 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
656 » codec->bias_level = SND_SOC_BIAS_STANDBY; 658 » codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
657 » queue_delayed_work(wm8971_workq, &codec->delayed_work, 659 » queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
658 msecs_to_jiffies(1000)); 660 msecs_to_jiffies(1000));
659 661
660 /* set the update bits */ 662 /* set the update bits */
661 reg = snd_soc_read(codec, WM8971_LDAC); 663 reg = snd_soc_read(codec, WM8971_LDAC);
662 snd_soc_write(codec, WM8971_LDAC, reg | 0x0100); 664 snd_soc_write(codec, WM8971_LDAC, reg | 0x0100);
663 reg = snd_soc_read(codec, WM8971_RDAC); 665 reg = snd_soc_read(codec, WM8971_RDAC);
664 snd_soc_write(codec, WM8971_RDAC, reg | 0x0100); 666 snd_soc_write(codec, WM8971_RDAC, reg | 0x0100);
665 667
666 reg = snd_soc_read(codec, WM8971_LOUT1V); 668 reg = snd_soc_read(codec, WM8971_LOUT1V);
667 snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100); 669 snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 { 772 {
771 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 773 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
772 i2c_del_driver(&wm8971_i2c_driver); 774 i2c_del_driver(&wm8971_i2c_driver);
773 #endif 775 #endif
774 } 776 }
775 module_exit(wm8971_exit); 777 module_exit(wm8971_exit);
776 778
777 MODULE_DESCRIPTION("ASoC WM8971 driver"); 779 MODULE_DESCRIPTION("ASoC WM8971 driver");
778 MODULE_AUTHOR("Lab126"); 780 MODULE_AUTHOR("Lab126");
779 MODULE_LICENSE("GPL"); 781 MODULE_LICENSE("GPL");
OLDNEW
« no previous file with comments | « sound/soc/codecs/wm8962.c ('k') | sound/soc/codecs/wm8974.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698