aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5631.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt5631.c')
-rw-r--r--sound/soc/codecs/rt5631.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c
index 20c324c7c349..960d0e93cce9 100644
--- a/sound/soc/codecs/rt5631.c
+++ b/sound/soc/codecs/rt5631.c
@@ -18,7 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/spi/spi.h> 21#include <linux/regmap.h>
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -30,6 +30,7 @@
30#include "rt5631.h" 30#include "rt5631.h"
31 31
32struct rt5631_priv { 32struct rt5631_priv {
33 struct regmap *regmap;
33 int codec_version; 34 int codec_version;
34 int master; 35 int master;
35 int sysclk; 36 int sysclk;
@@ -38,33 +39,33 @@ struct rt5631_priv {
38 int dmic_used_flag; 39 int dmic_used_flag;
39}; 40};
40 41
41static const u16 rt5631_reg[RT5631_VENDOR_ID2 + 1] = { 42static const struct reg_default rt5631_reg[] = {
42 [RT5631_SPK_OUT_VOL] = 0x8888, 43 { RT5631_SPK_OUT_VOL, 0x8888 },
43 [RT5631_HP_OUT_VOL] = 0x8080, 44 { RT5631_HP_OUT_VOL, 0x8080 },
44 [RT5631_MONO_AXO_1_2_VOL] = 0xa080, 45 { RT5631_MONO_AXO_1_2_VOL, 0xa080 },
45 [RT5631_AUX_IN_VOL] = 0x0808, 46 { RT5631_AUX_IN_VOL, 0x0808 },
46 [RT5631_ADC_REC_MIXER] = 0xf0f0, 47 { RT5631_ADC_REC_MIXER, 0xf0f0 },
47 [RT5631_VDAC_DIG_VOL] = 0x0010, 48 { RT5631_VDAC_DIG_VOL, 0x0010 },
48 [RT5631_OUTMIXER_L_CTRL] = 0xffc0, 49 { RT5631_OUTMIXER_L_CTRL, 0xffc0 },
49 [RT5631_OUTMIXER_R_CTRL] = 0xffc0, 50 { RT5631_OUTMIXER_R_CTRL, 0xffc0 },
50 [RT5631_AXO1MIXER_CTRL] = 0x88c0, 51 { RT5631_AXO1MIXER_CTRL, 0x88c0 },
51 [RT5631_AXO2MIXER_CTRL] = 0x88c0, 52 { RT5631_AXO2MIXER_CTRL, 0x88c0 },
52 [RT5631_DIG_MIC_CTRL] = 0x3000, 53 { RT5631_DIG_MIC_CTRL, 0x3000 },
53 [RT5631_MONO_INPUT_VOL] = 0x8808, 54 { RT5631_MONO_INPUT_VOL, 0x8808 },
54 [RT5631_SPK_MIXER_CTRL] = 0xf8f8, 55 { RT5631_SPK_MIXER_CTRL, 0xf8f8 },
55 [RT5631_SPK_MONO_OUT_CTRL] = 0xfc00, 56 { RT5631_SPK_MONO_OUT_CTRL, 0xfc00 },
56 [RT5631_SPK_MONO_HP_OUT_CTRL] = 0x4440, 57 { RT5631_SPK_MONO_HP_OUT_CTRL, 0x4440 },
57 [RT5631_SDP_CTRL] = 0x8000, 58 { RT5631_SDP_CTRL, 0x8000 },
58 [RT5631_MONO_SDP_CTRL] = 0x8000, 59 { RT5631_MONO_SDP_CTRL, 0x8000 },
59 [RT5631_STEREO_AD_DA_CLK_CTRL] = 0x2010, 60 { RT5631_STEREO_AD_DA_CLK_CTRL, 0x2010 },
60 [RT5631_GEN_PUR_CTRL_REG] = 0x0e00, 61 { RT5631_GEN_PUR_CTRL_REG, 0x0e00 },
61 [RT5631_INT_ST_IRQ_CTRL_2] = 0x071a, 62 { RT5631_INT_ST_IRQ_CTRL_2, 0x071a },
62 [RT5631_MISC_CTRL] = 0x2040, 63 { RT5631_MISC_CTRL, 0x2040 },
63 [RT5631_DEPOP_FUN_CTRL_2] = 0x8000, 64 { RT5631_DEPOP_FUN_CTRL_2, 0x8000 },
64 [RT5631_SOFT_VOL_CTRL] = 0x07e0, 65 { RT5631_SOFT_VOL_CTRL, 0x07e0 },
65 [RT5631_ALC_CTRL_1] = 0x0206, 66 { RT5631_ALC_CTRL_1, 0x0206 },
66 [RT5631_ALC_CTRL_3] = 0x2000, 67 { RT5631_ALC_CTRL_3, 0x2000 },
67 [RT5631_PSEUDO_SPATL_CTRL] = 0x0553, 68 { RT5631_PSEUDO_SPATL_CTRL, 0x0553 },
68}; 69};
69 70
70/** 71/**
@@ -96,8 +97,7 @@ static int rt5631_reset(struct snd_soc_codec *codec)
96 return snd_soc_write(codec, RT5631_RESET, 0); 97 return snd_soc_write(codec, RT5631_RESET, 0);
97} 98}
98 99
99static int rt5631_volatile_register(struct snd_soc_codec *codec, 100static bool rt5631_volatile_register(struct device *dev, unsigned int reg)
100 unsigned int reg)
101{ 101{
102 switch (reg) { 102 switch (reg) {
103 case RT5631_RESET: 103 case RT5631_RESET:
@@ -111,8 +111,7 @@ static int rt5631_volatile_register(struct snd_soc_codec *codec,
111 } 111 }
112} 112}
113 113
114static int rt5631_readable_register(struct snd_soc_codec *codec, 114static bool rt5631_readable_register(struct device *dev, unsigned int reg)
115 unsigned int reg)
116{ 115{
117 switch (reg) { 116 switch (reg) {
118 case RT5631_RESET: 117 case RT5631_RESET:
@@ -1361,8 +1360,7 @@ static int get_coeff(int mclk, int rate, int timesofbclk)
1361static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream, 1360static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
1362 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 1361 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1363{ 1362{
1364 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1363 struct snd_soc_codec *codec = dai->codec;
1365 struct snd_soc_codec *codec = rtd->codec;
1366 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); 1364 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1367 int timesofbclk = 32, coeff; 1365 int timesofbclk = 32, coeff;
1368 unsigned int iface = 0; 1366 unsigned int iface = 0;
@@ -1544,6 +1542,8 @@ static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1544static int rt5631_set_bias_level(struct snd_soc_codec *codec, 1542static int rt5631_set_bias_level(struct snd_soc_codec *codec,
1545 enum snd_soc_bias_level level) 1543 enum snd_soc_bias_level level)
1546{ 1544{
1545 struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
1546
1547 switch (level) { 1547 switch (level) {
1548 case SND_SOC_BIAS_ON: 1548 case SND_SOC_BIAS_ON:
1549 case SND_SOC_BIAS_PREPARE: 1549 case SND_SOC_BIAS_PREPARE:
@@ -1561,8 +1561,8 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
1561 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, 1561 snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
1562 RT5631_PWR_FAST_VREF_CTRL, 1562 RT5631_PWR_FAST_VREF_CTRL,
1563 RT5631_PWR_FAST_VREF_CTRL); 1563 RT5631_PWR_FAST_VREF_CTRL);
1564 codec->cache_only = false; 1564 regcache_cache_only(rt5631->regmap, false);
1565 snd_soc_cache_sync(codec); 1565 regcache_sync(rt5631->regmap);
1566 } 1566 }
1567 break; 1567 break;
1568 1568
@@ -1587,7 +1587,9 @@ static int rt5631_probe(struct snd_soc_codec *codec)
1587 unsigned int val; 1587 unsigned int val;
1588 int ret; 1588 int ret;
1589 1589
1590 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); 1590 codec->control_data = rt5631->regmap;
1591
1592 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1591 if (ret != 0) { 1593 if (ret != 0) {
1592 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 1594 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1593 return ret; 1595 return ret;
@@ -1698,12 +1700,6 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
1698 .suspend = rt5631_suspend, 1700 .suspend = rt5631_suspend,
1699 .resume = rt5631_resume, 1701 .resume = rt5631_resume,
1700 .set_bias_level = rt5631_set_bias_level, 1702 .set_bias_level = rt5631_set_bias_level,
1701 .reg_cache_size = RT5631_VENDOR_ID2 + 1,
1702 .reg_word_size = sizeof(u16),
1703 .reg_cache_default = rt5631_reg,
1704 .volatile_register = rt5631_volatile_register,
1705 .readable_register = rt5631_readable_register,
1706 .reg_cache_step = 1,
1707 .controls = rt5631_snd_controls, 1703 .controls = rt5631_snd_controls,
1708 .num_controls = ARRAY_SIZE(rt5631_snd_controls), 1704 .num_controls = ARRAY_SIZE(rt5631_snd_controls),
1709 .dapm_widgets = rt5631_dapm_widgets, 1705 .dapm_widgets = rt5631_dapm_widgets,
@@ -1718,6 +1714,18 @@ static const struct i2c_device_id rt5631_i2c_id[] = {
1718}; 1714};
1719MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); 1715MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
1720 1716
1717static const struct regmap_config rt5631_regmap_config = {
1718 .reg_bits = 8,
1719 .val_bits = 16,
1720
1721 .readable_reg = rt5631_readable_register,
1722 .volatile_reg = rt5631_volatile_register,
1723 .max_register = RT5631_VENDOR_ID2,
1724 .reg_defaults = rt5631_reg,
1725 .num_reg_defaults = ARRAY_SIZE(rt5631_reg),
1726 .cache_type = REGCACHE_RBTREE,
1727};
1728
1721static int rt5631_i2c_probe(struct i2c_client *i2c, 1729static int rt5631_i2c_probe(struct i2c_client *i2c,
1722 const struct i2c_device_id *id) 1730 const struct i2c_device_id *id)
1723{ 1731{
@@ -1731,6 +1739,10 @@ static int rt5631_i2c_probe(struct i2c_client *i2c,
1731 1739
1732 i2c_set_clientdata(i2c, rt5631); 1740 i2c_set_clientdata(i2c, rt5631);
1733 1741
1742 rt5631->regmap = devm_regmap_init_i2c(i2c, &rt5631_regmap_config);
1743 if (IS_ERR(rt5631->regmap))
1744 return PTR_ERR(rt5631->regmap);
1745
1734 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631, 1746 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
1735 rt5631_dai, ARRAY_SIZE(rt5631_dai)); 1747 rt5631_dai, ARRAY_SIZE(rt5631_dai));
1736 return ret; 1748 return ret;
@@ -1752,17 +1764,7 @@ static struct i2c_driver rt5631_i2c_driver = {
1752 .id_table = rt5631_i2c_id, 1764 .id_table = rt5631_i2c_id,
1753}; 1765};
1754 1766
1755static int __init rt5631_modinit(void) 1767module_i2c_driver(rt5631_i2c_driver);
1756{
1757 return i2c_add_driver(&rt5631_i2c_driver);
1758}
1759module_init(rt5631_modinit);
1760
1761static void __exit rt5631_modexit(void)
1762{
1763 i2c_del_driver(&rt5631_i2c_driver);
1764}
1765module_exit(rt5631_modexit);
1766 1768
1767MODULE_DESCRIPTION("ASoC RT5631 driver"); 1769MODULE_DESCRIPTION("ASoC RT5631 driver");
1768MODULE_AUTHOR("flove <flove@realtek.com>"); 1770MODULE_AUTHOR("flove <flove@realtek.com>");