diff options
-rw-r--r-- | sound/soc/codecs/sgtl5000.c | 145 |
1 files changed, 111 insertions, 34 deletions
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 92bbfec9b107..327b4434b4ce 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/pm.h> | 16 | #include <linux/pm.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/driver.h> | 20 | #include <linux/regulator/driver.h> |
20 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
@@ -34,30 +35,30 @@ | |||
34 | #define SGTL5000_MAX_REG_OFFSET 0x013A | 35 | #define SGTL5000_MAX_REG_OFFSET 0x013A |
35 | 36 | ||
36 | /* default value of sgtl5000 registers */ | 37 | /* default value of sgtl5000 registers */ |
37 | static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { | 38 | static const struct reg_default sgtl5000_reg_defaults[] = { |
38 | [SGTL5000_CHIP_CLK_CTRL] = 0x0008, | 39 | { SGTL5000_CHIP_CLK_CTRL, 0x0008 }, |
39 | [SGTL5000_CHIP_I2S_CTRL] = 0x0010, | 40 | { SGTL5000_CHIP_I2S_CTRL, 0x0010 }, |
40 | [SGTL5000_CHIP_SSS_CTRL] = 0x0008, | 41 | { SGTL5000_CHIP_SSS_CTRL, 0x0008 }, |
41 | [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, | 42 | { SGTL5000_CHIP_DAC_VOL, 0x3c3c }, |
42 | [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, | 43 | { SGTL5000_CHIP_PAD_STRENGTH, 0x015f }, |
43 | [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, | 44 | { SGTL5000_CHIP_ANA_HP_CTRL, 0x1818 }, |
44 | [SGTL5000_CHIP_ANA_CTRL] = 0x0111, | 45 | { SGTL5000_CHIP_ANA_CTRL, 0x0111 }, |
45 | [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404, | 46 | { SGTL5000_CHIP_LINE_OUT_VOL, 0x0404 }, |
46 | [SGTL5000_CHIP_ANA_POWER] = 0x7060, | 47 | { SGTL5000_CHIP_ANA_POWER, 0x7060 }, |
47 | [SGTL5000_CHIP_PLL_CTRL] = 0x5000, | 48 | { SGTL5000_CHIP_PLL_CTRL, 0x5000 }, |
48 | [SGTL5000_DAP_BASS_ENHANCE] = 0x0040, | 49 | { SGTL5000_DAP_BASS_ENHANCE, 0x0040 }, |
49 | [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f, | 50 | { SGTL5000_DAP_BASS_ENHANCE_CTRL, 0x051f }, |
50 | [SGTL5000_DAP_SURROUND] = 0x0040, | 51 | { SGTL5000_DAP_SURROUND, 0x0040 }, |
51 | [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f, | 52 | { SGTL5000_DAP_EQ_BASS_BAND0, 0x002f }, |
52 | [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f, | 53 | { SGTL5000_DAP_EQ_BASS_BAND1, 0x002f }, |
53 | [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f, | 54 | { SGTL5000_DAP_EQ_BASS_BAND2, 0x002f }, |
54 | [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f, | 55 | { SGTL5000_DAP_EQ_BASS_BAND3, 0x002f }, |
55 | [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f, | 56 | { SGTL5000_DAP_EQ_BASS_BAND4, 0x002f }, |
56 | [SGTL5000_DAP_MAIN_CHAN] = 0x8000, | 57 | { SGTL5000_DAP_MAIN_CHAN, 0x8000 }, |
57 | [SGTL5000_DAP_AVC_CTRL] = 0x0510, | 58 | { SGTL5000_DAP_AVC_CTRL, 0x0510 }, |
58 | [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473, | 59 | { SGTL5000_DAP_AVC_THRESHOLD, 0x1473 }, |
59 | [SGTL5000_DAP_AVC_ATTACK] = 0x0028, | 60 | { SGTL5000_DAP_AVC_ATTACK, 0x0028 }, |
60 | [SGTL5000_DAP_AVC_DECAY] = 0x0050, | 61 | { SGTL5000_DAP_AVC_DECAY, 0x0050 }, |
61 | }; | 62 | }; |
62 | 63 | ||
63 | /* regulator supplies for sgtl5000, VDDD is an optional external supply */ | 64 | /* regulator supplies for sgtl5000, VDDD is an optional external supply */ |
@@ -112,6 +113,7 @@ struct sgtl5000_priv { | |||
112 | int fmt; /* i2s data format */ | 113 | int fmt; /* i2s data format */ |
113 | struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM]; | 114 | struct regulator_bulk_data supplies[SGTL5000_SUPPLY_NUM]; |
114 | struct ldo_regulator *ldo; | 115 | struct ldo_regulator *ldo; |
116 | struct regmap *regmap; | ||
115 | }; | 117 | }; |
116 | 118 | ||
117 | /* | 119 | /* |
@@ -958,17 +960,76 @@ static struct snd_soc_dai_driver sgtl5000_dai = { | |||
958 | .symmetric_rates = 1, | 960 | .symmetric_rates = 1, |
959 | }; | 961 | }; |
960 | 962 | ||
961 | static int sgtl5000_volatile_register(struct snd_soc_codec *codec, | 963 | static bool sgtl5000_volatile(struct device *dev, unsigned int reg) |
962 | unsigned int reg) | ||
963 | { | 964 | { |
964 | switch (reg) { | 965 | switch (reg) { |
965 | case SGTL5000_CHIP_ID: | 966 | case SGTL5000_CHIP_ID: |
966 | case SGTL5000_CHIP_ADCDAC_CTRL: | 967 | case SGTL5000_CHIP_ADCDAC_CTRL: |
967 | case SGTL5000_CHIP_ANA_STATUS: | 968 | case SGTL5000_CHIP_ANA_STATUS: |
968 | return 1; | 969 | return true; |
969 | } | 970 | } |
970 | 971 | ||
971 | return 0; | 972 | return false; |
973 | } | ||
974 | |||
975 | static bool sgtl5000_readable(struct device *dev, unsigned int reg) | ||
976 | { | ||
977 | switch (reg) { | ||
978 | case SGTL5000_CHIP_ID: | ||
979 | case SGTL5000_CHIP_DIG_POWER: | ||
980 | case SGTL5000_CHIP_CLK_CTRL: | ||
981 | case SGTL5000_CHIP_I2S_CTRL: | ||
982 | case SGTL5000_CHIP_SSS_CTRL: | ||
983 | case SGTL5000_CHIP_ADCDAC_CTRL: | ||
984 | case SGTL5000_CHIP_DAC_VOL: | ||
985 | case SGTL5000_CHIP_PAD_STRENGTH: | ||
986 | case SGTL5000_CHIP_ANA_ADC_CTRL: | ||
987 | case SGTL5000_CHIP_ANA_HP_CTRL: | ||
988 | case SGTL5000_CHIP_ANA_CTRL: | ||
989 | case SGTL5000_CHIP_LINREG_CTRL: | ||
990 | case SGTL5000_CHIP_REF_CTRL: | ||
991 | case SGTL5000_CHIP_MIC_CTRL: | ||
992 | case SGTL5000_CHIP_LINE_OUT_CTRL: | ||
993 | case SGTL5000_CHIP_LINE_OUT_VOL: | ||
994 | case SGTL5000_CHIP_ANA_POWER: | ||
995 | case SGTL5000_CHIP_PLL_CTRL: | ||
996 | case SGTL5000_CHIP_CLK_TOP_CTRL: | ||
997 | case SGTL5000_CHIP_ANA_STATUS: | ||
998 | case SGTL5000_CHIP_SHORT_CTRL: | ||
999 | case SGTL5000_CHIP_ANA_TEST2: | ||
1000 | case SGTL5000_DAP_CTRL: | ||
1001 | case SGTL5000_DAP_PEQ: | ||
1002 | case SGTL5000_DAP_BASS_ENHANCE: | ||
1003 | case SGTL5000_DAP_BASS_ENHANCE_CTRL: | ||
1004 | case SGTL5000_DAP_AUDIO_EQ: | ||
1005 | case SGTL5000_DAP_SURROUND: | ||
1006 | case SGTL5000_DAP_FLT_COEF_ACCESS: | ||
1007 | case SGTL5000_DAP_COEF_WR_B0_MSB: | ||
1008 | case SGTL5000_DAP_COEF_WR_B0_LSB: | ||
1009 | case SGTL5000_DAP_EQ_BASS_BAND0: | ||
1010 | case SGTL5000_DAP_EQ_BASS_BAND1: | ||
1011 | case SGTL5000_DAP_EQ_BASS_BAND2: | ||
1012 | case SGTL5000_DAP_EQ_BASS_BAND3: | ||
1013 | case SGTL5000_DAP_EQ_BASS_BAND4: | ||
1014 | case SGTL5000_DAP_MAIN_CHAN: | ||
1015 | case SGTL5000_DAP_MIX_CHAN: | ||
1016 | case SGTL5000_DAP_AVC_CTRL: | ||
1017 | case SGTL5000_DAP_AVC_THRESHOLD: | ||
1018 | case SGTL5000_DAP_AVC_ATTACK: | ||
1019 | case SGTL5000_DAP_AVC_DECAY: | ||
1020 | case SGTL5000_DAP_COEF_WR_B1_MSB: | ||
1021 | case SGTL5000_DAP_COEF_WR_B1_LSB: | ||
1022 | case SGTL5000_DAP_COEF_WR_B2_MSB: | ||
1023 | case SGTL5000_DAP_COEF_WR_B2_LSB: | ||
1024 | case SGTL5000_DAP_COEF_WR_A1_MSB: | ||
1025 | case SGTL5000_DAP_COEF_WR_A1_LSB: | ||
1026 | case SGTL5000_DAP_COEF_WR_A2_MSB: | ||
1027 | case SGTL5000_DAP_COEF_WR_A2_LSB: | ||
1028 | return true; | ||
1029 | |||
1030 | default: | ||
1031 | return false; | ||
1032 | } | ||
972 | } | 1033 | } |
973 | 1034 | ||
974 | #ifdef CONFIG_SUSPEND | 1035 | #ifdef CONFIG_SUSPEND |
@@ -1300,7 +1361,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1300 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); | 1361 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); |
1301 | 1362 | ||
1302 | /* setup i2c data ops */ | 1363 | /* setup i2c data ops */ |
1303 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); | 1364 | codec->control_data = sgtl5000->regmap; |
1365 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
1304 | if (ret < 0) { | 1366 | if (ret < 0) { |
1305 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1367 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1306 | return ret; | 1368 | return ret; |
@@ -1391,11 +1453,6 @@ static struct snd_soc_codec_driver sgtl5000_driver = { | |||
1391 | .suspend = sgtl5000_suspend, | 1453 | .suspend = sgtl5000_suspend, |
1392 | .resume = sgtl5000_resume, | 1454 | .resume = sgtl5000_resume, |
1393 | .set_bias_level = sgtl5000_set_bias_level, | 1455 | .set_bias_level = sgtl5000_set_bias_level, |
1394 | .reg_cache_size = ARRAY_SIZE(sgtl5000_regs), | ||
1395 | .reg_word_size = sizeof(u16), | ||
1396 | .reg_cache_step = 2, | ||
1397 | .reg_cache_default = sgtl5000_regs, | ||
1398 | .volatile_register = sgtl5000_volatile_register, | ||
1399 | .controls = sgtl5000_snd_controls, | 1456 | .controls = sgtl5000_snd_controls, |
1400 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), | 1457 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), |
1401 | .dapm_widgets = sgtl5000_dapm_widgets, | 1458 | .dapm_widgets = sgtl5000_dapm_widgets, |
@@ -1404,6 +1461,19 @@ static struct snd_soc_codec_driver sgtl5000_driver = { | |||
1404 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), | 1461 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), |
1405 | }; | 1462 | }; |
1406 | 1463 | ||
1464 | static const struct regmap_config sgtl5000_regmap = { | ||
1465 | .reg_bits = 16, | ||
1466 | .val_bits = 16, | ||
1467 | |||
1468 | .max_register = SGTL5000_MAX_REG_OFFSET, | ||
1469 | .volatile_reg = sgtl5000_volatile, | ||
1470 | .readable_reg = sgtl5000_readable, | ||
1471 | |||
1472 | .cache_type = REGCACHE_RBTREE, | ||
1473 | .reg_defaults = sgtl5000_reg_defaults, | ||
1474 | .num_reg_defaults = ARRAY_SIZE(sgtl5000_reg_defaults), | ||
1475 | }; | ||
1476 | |||
1407 | static int sgtl5000_i2c_probe(struct i2c_client *client, | 1477 | static int sgtl5000_i2c_probe(struct i2c_client *client, |
1408 | const struct i2c_device_id *id) | 1478 | const struct i2c_device_id *id) |
1409 | { | 1479 | { |
@@ -1415,6 +1485,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, | |||
1415 | if (!sgtl5000) | 1485 | if (!sgtl5000) |
1416 | return -ENOMEM; | 1486 | return -ENOMEM; |
1417 | 1487 | ||
1488 | sgtl5000->regmap = devm_regmap_init_i2c(client, &sgtl5000_regmap); | ||
1489 | if (IS_ERR(sgtl5000->regmap)) { | ||
1490 | ret = PTR_ERR(sgtl5000->regmap); | ||
1491 | dev_err(&client->dev, "Failed to allocate regmap: %d\n", ret); | ||
1492 | return ret; | ||
1493 | } | ||
1494 | |||
1418 | i2c_set_clientdata(client, sgtl5000); | 1495 | i2c_set_clientdata(client, sgtl5000); |
1419 | 1496 | ||
1420 | ret = snd_soc_register_codec(&client->dev, | 1497 | ret = snd_soc_register_codec(&client->dev, |