wm8988.c (9edd576d89a5b6d3e136d7dcab654d887c0d25b7) | wm8988.c (d2dc0a7782d3f257789e8650b3fa2586b96c6436) |
---|---|
1/* 2 * wm8988.c -- WM8988 ALSA SoC audio driver 3 * 4 * Copyright 2009 Wolfson Microelectronics plc 5 * Copyright 2005 Openedhand Ltd. 6 * 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 * --- 19 unchanged lines hidden (view full) --- 28 29#include "wm8988.h" 30 31/* 32 * wm8988 register cache 33 * We can't read the WM8988 register space when we 34 * are using 2 wire for device control, so we cache them instead. 35 */ | 1/* 2 * wm8988.c -- WM8988 ALSA SoC audio driver 3 * 4 * Copyright 2009 Wolfson Microelectronics plc 5 * Copyright 2005 Openedhand Ltd. 6 * 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 8 * --- 19 unchanged lines hidden (view full) --- 28 29#include "wm8988.h" 30 31/* 32 * wm8988 register cache 33 * We can't read the WM8988 register space when we 34 * are using 2 wire for device control, so we cache them instead. 35 */ |
36static const u16 wm8988_reg[] = { 37 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ 38 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ 39 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ 40 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ 41 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ 42 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ 43 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ 44 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ 45 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ 46 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ 47 0x0079, 0x0079, 0x0079, /* 40 */ | 36static const struct reg_default wm8988_reg_defaults[] = { 37 { 0, 0x0097 }, 38 { 1, 0x0097 }, 39 { 2, 0x0079 }, 40 { 3, 0x0079 }, 41 { 5, 0x0008 }, 42 { 7, 0x000a }, 43 { 8, 0x0000 }, 44 { 10, 0x00ff }, 45 { 11, 0x00ff }, 46 { 12, 0x000f }, 47 { 13, 0x000f }, 48 { 16, 0x0000 }, 49 { 17, 0x007b }, 50 { 18, 0x0000 }, 51 { 19, 0x0032 }, 52 { 20, 0x0000 }, 53 { 21, 0x00c3 }, 54 { 22, 0x00c3 }, 55 { 23, 0x00c0 }, 56 { 24, 0x0000 }, 57 { 25, 0x0000 }, 58 { 26, 0x0000 }, 59 { 27, 0x0000 }, 60 { 31, 0x0000 }, 61 { 32, 0x0000 }, 62 { 33, 0x0000 }, 63 { 34, 0x0050 }, 64 { 35, 0x0050 }, 65 { 36, 0x0050 }, 66 { 37, 0x0050 }, 67 { 40, 0x0079 }, 68 { 41, 0x0079 }, 69 { 42, 0x0079 }, |
48}; 49 | 70}; 71 |
72static bool wm8988_writeable(struct device *dev, unsigned int reg) 73{ 74 switch (reg) { 75 case WM8988_LINVOL: 76 case WM8988_RINVOL: 77 case WM8988_LOUT1V: 78 case WM8988_ROUT1V: 79 case WM8988_ADCDAC: 80 case WM8988_IFACE: 81 case WM8988_SRATE: 82 case WM8988_LDAC: 83 case WM8988_RDAC: 84 case WM8988_BASS: 85 case WM8988_TREBLE: 86 case WM8988_RESET: 87 case WM8988_3D: 88 case WM8988_ALC1: 89 case WM8988_ALC2: 90 case WM8988_ALC3: 91 case WM8988_NGATE: 92 case WM8988_LADC: 93 case WM8988_RADC: 94 case WM8988_ADCTL1: 95 case WM8988_ADCTL2: 96 case WM8988_PWR1: 97 case WM8988_PWR2: 98 case WM8988_ADCTL3: 99 case WM8988_ADCIN: 100 case WM8988_LADCIN: 101 case WM8988_RADCIN: 102 case WM8988_LOUTM1: 103 case WM8988_LOUTM2: 104 case WM8988_ROUTM1: 105 case WM8988_ROUTM2: 106 case WM8988_LOUT2V: 107 case WM8988_ROUT2V: 108 case WM8988_LPPB: 109 return true; 110 default: 111 return false; 112 } 113} 114 |
|
50/* codec private data */ 51struct wm8988_priv { | 115/* codec private data */ 116struct wm8988_priv { |
117 struct regmap *regmap; |
|
52 unsigned int sysclk; | 118 unsigned int sysclk; |
53 enum snd_soc_control_type control_type; | |
54 struct snd_pcm_hw_constraint_list *sysclk_constraints; 55}; 56 57#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) 58 59/* 60 * WM8988 Controls 61 */ --- 250 unchanged lines hidden (view full) --- 312 SND_SOC_DAPM_OUTPUT("VREF"), 313 314 SND_SOC_DAPM_INPUT("LINPUT1"), 315 SND_SOC_DAPM_INPUT("LINPUT2"), 316 SND_SOC_DAPM_INPUT("RINPUT1"), 317 SND_SOC_DAPM_INPUT("RINPUT2"), 318}; 319 | 119 struct snd_pcm_hw_constraint_list *sysclk_constraints; 120}; 121 122#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) 123 124/* 125 * WM8988 Controls 126 */ --- 250 unchanged lines hidden (view full) --- 377 SND_SOC_DAPM_OUTPUT("VREF"), 378 379 SND_SOC_DAPM_INPUT("LINPUT1"), 380 SND_SOC_DAPM_INPUT("LINPUT2"), 381 SND_SOC_DAPM_INPUT("RINPUT1"), 382 SND_SOC_DAPM_INPUT("RINPUT2"), 383}; 384 |
320static const struct snd_soc_dapm_route audio_map[] = { | 385static const struct snd_soc_dapm_route wm8988_dapm_routes[] = { |
321 322 { "Left Line Mux", "Line 1", "LINPUT1" }, 323 { "Left Line Mux", "Line 2", "LINPUT2" }, 324 { "Left Line Mux", "PGA", "Left PGA Mux" }, 325 { "Left Line Mux", "Differential", "Differential Mux" }, 326 327 { "Right Line Mux", "Line 1", "RINPUT1" }, 328 { "Right Line Mux", "Line 2", "RINPUT2" }, --- 327 unchanged lines hidden (view full) --- 656 else 657 snd_soc_write(codec, WM8988_ADCDAC, mute_reg); 658 return 0; 659} 660 661static int wm8988_set_bias_level(struct snd_soc_codec *codec, 662 enum snd_soc_bias_level level) 663{ | 386 387 { "Left Line Mux", "Line 1", "LINPUT1" }, 388 { "Left Line Mux", "Line 2", "LINPUT2" }, 389 { "Left Line Mux", "PGA", "Left PGA Mux" }, 390 { "Left Line Mux", "Differential", "Differential Mux" }, 391 392 { "Right Line Mux", "Line 1", "RINPUT1" }, 393 { "Right Line Mux", "Line 2", "RINPUT2" }, --- 327 unchanged lines hidden (view full) --- 721 else 722 snd_soc_write(codec, WM8988_ADCDAC, mute_reg); 723 return 0; 724} 725 726static int wm8988_set_bias_level(struct snd_soc_codec *codec, 727 enum snd_soc_bias_level level) 728{ |
729 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); |
|
664 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; 665 666 switch (level) { 667 case SND_SOC_BIAS_ON: 668 break; 669 670 case SND_SOC_BIAS_PREPARE: 671 /* VREF, VMID=2x50k, digital enabled */ 672 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0); 673 break; 674 675 case SND_SOC_BIAS_STANDBY: 676 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 730 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; 731 732 switch (level) { 733 case SND_SOC_BIAS_ON: 734 break; 735 736 case SND_SOC_BIAS_PREPARE: 737 /* VREF, VMID=2x50k, digital enabled */ 738 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0); 739 break; 740 741 case SND_SOC_BIAS_STANDBY: 742 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
677 snd_soc_cache_sync(codec); | 743 regcache_sync(wm8988->regmap); |
678 679 /* VREF, VMID=2x5k */ 680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 681 682 /* Charge caps */ 683 msleep(100); 684 } 685 --- 39 unchanged lines hidden (view full) --- 725 .formats = WM8988_FORMATS, 726 }, 727 .ops = &wm8988_ops, 728 .symmetric_rates = 1, 729}; 730 731static int wm8988_suspend(struct snd_soc_codec *codec) 732{ | 744 745 /* VREF, VMID=2x5k */ 746 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 747 748 /* Charge caps */ 749 msleep(100); 750 } 751 --- 39 unchanged lines hidden (view full) --- 791 .formats = WM8988_FORMATS, 792 }, 793 .ops = &wm8988_ops, 794 .symmetric_rates = 1, 795}; 796 797static int wm8988_suspend(struct snd_soc_codec *codec) 798{ |
799 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 800 |
|
733 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); | 801 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); |
802 regcache_mark_dirty(wm8988->regmap); |
|
734 return 0; 735} 736 737static int wm8988_resume(struct snd_soc_codec *codec) 738{ 739 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 740 return 0; 741} 742 743static int wm8988_probe(struct snd_soc_codec *codec) 744{ 745 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); | 803 return 0; 804} 805 806static int wm8988_resume(struct snd_soc_codec *codec) 807{ 808 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 809 return 0; 810} 811 812static int wm8988_probe(struct snd_soc_codec *codec) 813{ 814 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); |
746 struct snd_soc_dapm_context *dapm = &codec->dapm; | |
747 int ret = 0; 748 | 815 int ret = 0; 816 |
749 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); | 817 codec->control_data = wm8988->regmap; 818 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
750 if (ret < 0) { 751 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 752 return ret; 753 } 754 755 ret = wm8988_reset(codec); 756 if (ret < 0) { 757 dev_err(codec->dev, "Failed to issue reset\n"); --- 4 unchanged lines hidden (view full) --- 762 snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100); 763 snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100); 764 snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100); 765 snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100); 766 snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100); 767 768 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 769 | 819 if (ret < 0) { 820 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 821 return ret; 822 } 823 824 ret = wm8988_reset(codec); 825 if (ret < 0) { 826 dev_err(codec->dev, "Failed to issue reset\n"); --- 4 unchanged lines hidden (view full) --- 831 snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100); 832 snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100); 833 snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100); 834 snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100); 835 snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100); 836 837 wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 838 |
770 snd_soc_add_controls(codec, wm8988_snd_controls, 771 ARRAY_SIZE(wm8988_snd_controls)); 772 snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets, 773 ARRAY_SIZE(wm8988_dapm_widgets)); 774 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 775 | |
776 return 0; 777} 778 779static int wm8988_remove(struct snd_soc_codec *codec) 780{ 781 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 782 return 0; 783} 784 785static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { 786 .probe = wm8988_probe, 787 .remove = wm8988_remove, 788 .suspend = wm8988_suspend, 789 .resume = wm8988_resume, 790 .set_bias_level = wm8988_set_bias_level, | 839 return 0; 840} 841 842static int wm8988_remove(struct snd_soc_codec *codec) 843{ 844 wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); 845 return 0; 846} 847 848static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { 849 .probe = wm8988_probe, 850 .remove = wm8988_remove, 851 .suspend = wm8988_suspend, 852 .resume = wm8988_resume, 853 .set_bias_level = wm8988_set_bias_level, |
791 .reg_cache_size = ARRAY_SIZE(wm8988_reg), 792 .reg_word_size = sizeof(u16), 793 .reg_cache_default = wm8988_reg, | 854 855 .controls = wm8988_snd_controls, 856 .num_controls = ARRAY_SIZE(wm8988_snd_controls), 857 .dapm_widgets = wm8988_dapm_widgets, 858 .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), 859 .dapm_routes = wm8988_dapm_routes, 860 .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), |
794}; 795 | 861}; 862 |
863static struct regmap_config wm8988_regmap = { 864 .reg_bits = 7, 865 .val_bits = 9, 866 867 .max_register = WM8988_LPPB, 868 .writeable_reg = wm8988_writeable, 869 870 .cache_type = REGCACHE_RBTREE, 871 .reg_defaults = wm8988_reg_defaults, 872 .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults), 873}; 874 |
|
796#if defined(CONFIG_SPI_MASTER) 797static int __devinit wm8988_spi_probe(struct spi_device *spi) 798{ 799 struct wm8988_priv *wm8988; 800 int ret; 801 | 875#if defined(CONFIG_SPI_MASTER) 876static int __devinit wm8988_spi_probe(struct spi_device *spi) 877{ 878 struct wm8988_priv *wm8988; 879 int ret; 880 |
802 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); | 881 wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv), 882 GFP_KERNEL); |
803 if (wm8988 == NULL) 804 return -ENOMEM; 805 | 883 if (wm8988 == NULL) 884 return -ENOMEM; 885 |
806 wm8988->control_type = SND_SOC_SPI; | 886 wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap); 887 if (IS_ERR(wm8988->regmap)) { 888 ret = PTR_ERR(wm8988->regmap); 889 dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); 890 return ret; 891 } 892 |
807 spi_set_drvdata(spi, wm8988); 808 809 ret = snd_soc_register_codec(&spi->dev, 810 &soc_codec_dev_wm8988, &wm8988_dai, 1); | 893 spi_set_drvdata(spi, wm8988); 894 895 ret = snd_soc_register_codec(&spi->dev, 896 &soc_codec_dev_wm8988, &wm8988_dai, 1); |
811 if (ret < 0) 812 kfree(wm8988); | 897 if (ret != 0) 898 regmap_exit(wm8988->regmap); 899 |
813 return ret; 814} 815 816static int __devexit wm8988_spi_remove(struct spi_device *spi) 817{ | 900 return ret; 901} 902 903static int __devexit wm8988_spi_remove(struct spi_device *spi) 904{ |
905 struct wm8988_priv *wm8988 = spi_get_drvdata(spi); |
|
818 snd_soc_unregister_codec(&spi->dev); | 906 snd_soc_unregister_codec(&spi->dev); |
819 kfree(spi_get_drvdata(spi)); | 907 regmap_exit(wm8988->regmap); |
820 return 0; 821} 822 823static struct spi_driver wm8988_spi_driver = { 824 .driver = { 825 .name = "wm8988", 826 .owner = THIS_MODULE, 827 }, --- 4 unchanged lines hidden (view full) --- 832 833#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 834static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, 835 const struct i2c_device_id *id) 836{ 837 struct wm8988_priv *wm8988; 838 int ret; 839 | 908 return 0; 909} 910 911static struct spi_driver wm8988_spi_driver = { 912 .driver = { 913 .name = "wm8988", 914 .owner = THIS_MODULE, 915 }, --- 4 unchanged lines hidden (view full) --- 920 921#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 922static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, 923 const struct i2c_device_id *id) 924{ 925 struct wm8988_priv *wm8988; 926 int ret; 927 |
840 wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); | 928 wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv), 929 GFP_KERNEL); |
841 if (wm8988 == NULL) 842 return -ENOMEM; 843 844 i2c_set_clientdata(i2c, wm8988); | 930 if (wm8988 == NULL) 931 return -ENOMEM; 932 933 i2c_set_clientdata(i2c, wm8988); |
845 wm8988->control_type = SND_SOC_I2C; | |
846 | 934 |
935 wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap); 936 if (IS_ERR(wm8988->regmap)) { 937 ret = PTR_ERR(wm8988->regmap); 938 dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); 939 return ret; 940 } 941 |
|
847 ret = snd_soc_register_codec(&i2c->dev, 848 &soc_codec_dev_wm8988, &wm8988_dai, 1); | 942 ret = snd_soc_register_codec(&i2c->dev, 943 &soc_codec_dev_wm8988, &wm8988_dai, 1); |
849 if (ret < 0) 850 kfree(wm8988); | 944 if (ret != 0) 945 regmap_exit(wm8988->regmap); 946 |
851 return ret; 852} 853 854static __devexit int wm8988_i2c_remove(struct i2c_client *client) 855{ | 947 return ret; 948} 949 950static __devexit int wm8988_i2c_remove(struct i2c_client *client) 951{ |
952 struct wm8988_priv *wm8988 = i2c_get_clientdata(client); |
|
856 snd_soc_unregister_codec(&client->dev); | 953 snd_soc_unregister_codec(&client->dev); |
857 kfree(i2c_get_clientdata(client)); | 954 regmap_exit(wm8988->regmap); |
858 return 0; 859} 860 861static const struct i2c_device_id wm8988_i2c_id[] = { 862 { "wm8988", 0 }, 863 { } 864}; 865MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); --- 48 unchanged lines hidden --- | 955 return 0; 956} 957 958static const struct i2c_device_id wm8988_i2c_id[] = { 959 { "wm8988", 0 }, 960 { } 961}; 962MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); --- 48 unchanged lines hidden --- |