diff options
author | Ashish Chavan <ashish.chavan@kpitcummins.com> | 2012-03-29 09:36:29 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-04-01 06:28:31 -0400 |
commit | aa0e25caafb7950e839db930649a65e8b7f70e1a (patch) | |
tree | a9467938858bc0f0883dc8a44eb1f0c7756c1f18 /sound/soc/codecs/da7210.c | |
parent | eb794077b8fe343a6fdc0aa94ad1fc5388ddded5 (diff) |
ASoC: da7210: Add support for spi regmap
This patch adds support for spi regmap feature to existing da7210
driver.
Signed-off-by: Ashish Chavan <ashish.chavan@kpitcummins.com>
Signed-off-by: David Dajun Chen <dchen@diasemi.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/da7210.c')
-rw-r--r-- | sound/soc/codecs/da7210.c | 154 |
1 files changed, 133 insertions, 21 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 7843711729bc..8e45aa9cb7b7 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/spi/spi.h> | ||
20 | #include <linux/regmap.h> | 21 | #include <linux/regmap.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -27,6 +28,7 @@ | |||
27 | #include <sound/tlv.h> | 28 | #include <sound/tlv.h> |
28 | 29 | ||
29 | /* DA7210 register space */ | 30 | /* DA7210 register space */ |
31 | #define DA7210_PAGE_CONTROL 0x00 | ||
30 | #define DA7210_CONTROL 0x01 | 32 | #define DA7210_CONTROL 0x01 |
31 | #define DA7210_STATUS 0x02 | 33 | #define DA7210_STATUS 0x02 |
32 | #define DA7210_STARTUP1 0x03 | 34 | #define DA7210_STARTUP1 0x03 |
@@ -631,6 +633,7 @@ struct da7210_priv { | |||
631 | }; | 633 | }; |
632 | 634 | ||
633 | static struct reg_default da7210_reg_defaults[] = { | 635 | static struct reg_default da7210_reg_defaults[] = { |
636 | { 0x00, 0x00 }, | ||
634 | { 0x01, 0x11 }, | 637 | { 0x01, 0x11 }, |
635 | { 0x03, 0x00 }, | 638 | { 0x03, 0x00 }, |
636 | { 0x04, 0x00 }, | 639 | { 0x04, 0x00 }, |
@@ -928,13 +931,6 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
928 | */ | 931 | */ |
929 | 932 | ||
930 | /* | 933 | /* |
931 | * make sure that DA7210 use bypass mode before start up | ||
932 | */ | ||
933 | snd_soc_write(codec, DA7210_STARTUP1, 0); | ||
934 | snd_soc_write(codec, DA7210_PLL_DIV3, | ||
935 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); | ||
936 | |||
937 | /* | ||
938 | * ADC settings | 934 | * ADC settings |
939 | */ | 935 | */ |
940 | 936 | ||
@@ -1025,16 +1021,6 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
1025 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); | 1021 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); |
1026 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); | 1022 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); |
1027 | 1023 | ||
1028 | /* As suggested by Dialog */ | ||
1029 | /* unlock */ | ||
1030 | regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B); | ||
1031 | regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4); | ||
1032 | regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01); | ||
1033 | regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C); | ||
1034 | /* re-lock */ | ||
1035 | regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00); | ||
1036 | regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00); | ||
1037 | |||
1038 | /* Activate all enabled subsystem */ | 1024 | /* Activate all enabled subsystem */ |
1039 | snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); | 1025 | snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); |
1040 | 1026 | ||
@@ -1055,7 +1041,26 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = { | |||
1055 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), | 1041 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), |
1056 | }; | 1042 | }; |
1057 | 1043 | ||
1058 | static struct regmap_config da7210_regmap = { | 1044 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1045 | |||
1046 | static struct reg_default da7210_regmap_i2c_patch[] = { | ||
1047 | |||
1048 | /* System controller master disable */ | ||
1049 | { DA7210_STARTUP1, 0x00 }, | ||
1050 | /* make sure that DA7210 use bypass mode before start up */ | ||
1051 | { DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP }, | ||
1052 | |||
1053 | /* to unlock */ | ||
1054 | { DA7210_A_HID_UNLOCK, 0x8B}, | ||
1055 | { DA7210_A_TEST_UNLOCK, 0xB4}, | ||
1056 | { DA7210_A_PLL1, 0x01}, | ||
1057 | { DA7210_A_CP_MODE, 0x7C}, | ||
1058 | /* to re-lock */ | ||
1059 | { DA7210_A_HID_UNLOCK, 0x00}, | ||
1060 | { DA7210_A_TEST_UNLOCK, 0x00}, | ||
1061 | }; | ||
1062 | |||
1063 | static const struct regmap_config da7210_regmap_config_i2c = { | ||
1059 | .reg_bits = 8, | 1064 | .reg_bits = 8, |
1060 | .val_bits = 8, | 1065 | .val_bits = 8, |
1061 | 1066 | ||
@@ -1066,7 +1071,6 @@ static struct regmap_config da7210_regmap = { | |||
1066 | .cache_type = REGCACHE_RBTREE, | 1071 | .cache_type = REGCACHE_RBTREE, |
1067 | }; | 1072 | }; |
1068 | 1073 | ||
1069 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1070 | static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | 1074 | static int __devinit da7210_i2c_probe(struct i2c_client *i2c, |
1071 | const struct i2c_device_id *id) | 1075 | const struct i2c_device_id *id) |
1072 | { | 1076 | { |
@@ -1080,13 +1084,18 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
1080 | 1084 | ||
1081 | i2c_set_clientdata(i2c, da7210); | 1085 | i2c_set_clientdata(i2c, da7210); |
1082 | 1086 | ||
1083 | da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap); | 1087 | da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap_config_i2c); |
1084 | if (IS_ERR(da7210->regmap)) { | 1088 | if (IS_ERR(da7210->regmap)) { |
1085 | ret = PTR_ERR(da7210->regmap); | 1089 | ret = PTR_ERR(da7210->regmap); |
1086 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | 1090 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
1087 | return ret; | 1091 | return ret; |
1088 | } | 1092 | } |
1089 | 1093 | ||
1094 | ret = regmap_register_patch(da7210->regmap, da7210_regmap_i2c_patch, | ||
1095 | ARRAY_SIZE(da7210_regmap_i2c_patch)); | ||
1096 | if (ret != 0) | ||
1097 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | ||
1098 | |||
1090 | ret = snd_soc_register_codec(&i2c->dev, | 1099 | ret = snd_soc_register_codec(&i2c->dev, |
1091 | &soc_codec_dev_da7210, &da7210_dai, 1); | 1100 | &soc_codec_dev_da7210, &da7210_dai, 1); |
1092 | if (ret < 0) { | 1101 | if (ret < 0) { |
@@ -1119,7 +1128,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id); | |||
1119 | /* I2C codec control layer */ | 1128 | /* I2C codec control layer */ |
1120 | static struct i2c_driver da7210_i2c_driver = { | 1129 | static struct i2c_driver da7210_i2c_driver = { |
1121 | .driver = { | 1130 | .driver = { |
1122 | .name = "da7210-codec", | 1131 | .name = "da7210", |
1123 | .owner = THIS_MODULE, | 1132 | .owner = THIS_MODULE, |
1124 | }, | 1133 | }, |
1125 | .probe = da7210_i2c_probe, | 1134 | .probe = da7210_i2c_probe, |
@@ -1128,12 +1137,112 @@ static struct i2c_driver da7210_i2c_driver = { | |||
1128 | }; | 1137 | }; |
1129 | #endif | 1138 | #endif |
1130 | 1139 | ||
1140 | #if defined(CONFIG_SPI_MASTER) | ||
1141 | |||
1142 | static struct reg_default da7210_regmap_spi_patch[] = { | ||
1143 | /* Dummy read to give two pulses over nCS for SPI */ | ||
1144 | { DA7210_AUX2, 0x00 }, | ||
1145 | { DA7210_AUX2, 0x00 }, | ||
1146 | |||
1147 | /* System controller master disable */ | ||
1148 | { DA7210_STARTUP1, 0x00 }, | ||
1149 | /* make sure that DA7210 use bypass mode before start up */ | ||
1150 | { DA7210_PLL_DIV3, DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP }, | ||
1151 | |||
1152 | /* to set PAGE1 of SPI register space */ | ||
1153 | { DA7210_PAGE_CONTROL, 0x80 }, | ||
1154 | /* to unlock */ | ||
1155 | { DA7210_A_HID_UNLOCK, 0x8B}, | ||
1156 | { DA7210_A_TEST_UNLOCK, 0xB4}, | ||
1157 | { DA7210_A_PLL1, 0x01}, | ||
1158 | { DA7210_A_CP_MODE, 0x7C}, | ||
1159 | /* to re-lock */ | ||
1160 | { DA7210_A_HID_UNLOCK, 0x00}, | ||
1161 | { DA7210_A_TEST_UNLOCK, 0x00}, | ||
1162 | /* to set back PAGE0 of SPI register space */ | ||
1163 | { DA7210_PAGE_CONTROL, 0x00 }, | ||
1164 | }; | ||
1165 | |||
1166 | static const struct regmap_config da7210_regmap_config_spi = { | ||
1167 | .reg_bits = 8, | ||
1168 | .val_bits = 8, | ||
1169 | .read_flag_mask = 0x01, | ||
1170 | .write_flag_mask = 0x00, | ||
1171 | |||
1172 | .reg_defaults = da7210_reg_defaults, | ||
1173 | .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults), | ||
1174 | .volatile_reg = da7210_volatile_register, | ||
1175 | .readable_reg = da7210_readable_register, | ||
1176 | .cache_type = REGCACHE_RBTREE, | ||
1177 | }; | ||
1178 | |||
1179 | static int __devinit da7210_spi_probe(struct spi_device *spi) | ||
1180 | { | ||
1181 | struct da7210_priv *da7210; | ||
1182 | int ret; | ||
1183 | |||
1184 | da7210 = devm_kzalloc(&spi->dev, sizeof(struct da7210_priv), | ||
1185 | GFP_KERNEL); | ||
1186 | if (!da7210) | ||
1187 | return -ENOMEM; | ||
1188 | |||
1189 | spi_set_drvdata(spi, da7210); | ||
1190 | da7210->regmap = devm_regmap_init_spi(spi, &da7210_regmap_config_spi); | ||
1191 | if (IS_ERR(da7210->regmap)) { | ||
1192 | ret = PTR_ERR(da7210->regmap); | ||
1193 | dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); | ||
1194 | return ret; | ||
1195 | } | ||
1196 | |||
1197 | ret = regmap_register_patch(da7210->regmap, da7210_regmap_spi_patch, | ||
1198 | ARRAY_SIZE(da7210_regmap_spi_patch)); | ||
1199 | if (ret != 0) | ||
1200 | dev_warn(&spi->dev, "Failed to apply regmap patch: %d\n", ret); | ||
1201 | |||
1202 | ret = snd_soc_register_codec(&spi->dev, | ||
1203 | &soc_codec_dev_da7210, &da7210_dai, 1); | ||
1204 | if (ret < 0) | ||
1205 | goto err_regmap; | ||
1206 | |||
1207 | return ret; | ||
1208 | |||
1209 | err_regmap: | ||
1210 | regmap_exit(da7210->regmap); | ||
1211 | |||
1212 | return ret; | ||
1213 | } | ||
1214 | |||
1215 | static int __devexit da7210_spi_remove(struct spi_device *spi) | ||
1216 | { | ||
1217 | struct da7210_priv *da7210 = spi_get_drvdata(spi); | ||
1218 | snd_soc_unregister_codec(&spi->dev); | ||
1219 | regmap_exit(da7210->regmap); | ||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | static struct spi_driver da7210_spi_driver = { | ||
1224 | .driver = { | ||
1225 | .name = "da7210", | ||
1226 | .owner = THIS_MODULE, | ||
1227 | }, | ||
1228 | .probe = da7210_spi_probe, | ||
1229 | .remove = __devexit_p(da7210_spi_remove) | ||
1230 | }; | ||
1231 | #endif | ||
1232 | |||
1131 | static int __init da7210_modinit(void) | 1233 | static int __init da7210_modinit(void) |
1132 | { | 1234 | { |
1133 | int ret = 0; | 1235 | int ret = 0; |
1134 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1236 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1135 | ret = i2c_add_driver(&da7210_i2c_driver); | 1237 | ret = i2c_add_driver(&da7210_i2c_driver); |
1136 | #endif | 1238 | #endif |
1239 | #if defined(CONFIG_SPI_MASTER) | ||
1240 | ret = spi_register_driver(&da7210_spi_driver); | ||
1241 | if (ret) { | ||
1242 | printk(KERN_ERR "Failed to register da7210 SPI driver: %d\n", | ||
1243 | ret); | ||
1244 | } | ||
1245 | #endif | ||
1137 | return ret; | 1246 | return ret; |
1138 | } | 1247 | } |
1139 | module_init(da7210_modinit); | 1248 | module_init(da7210_modinit); |
@@ -1143,6 +1252,9 @@ static void __exit da7210_exit(void) | |||
1143 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1252 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1144 | i2c_del_driver(&da7210_i2c_driver); | 1253 | i2c_del_driver(&da7210_i2c_driver); |
1145 | #endif | 1254 | #endif |
1255 | #if defined(CONFIG_SPI_MASTER) | ||
1256 | spi_unregister_driver(&da7210_spi_driver); | ||
1257 | #endif | ||
1146 | } | 1258 | } |
1147 | module_exit(da7210_exit); | 1259 | module_exit(da7210_exit); |
1148 | 1260 | ||