aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8900.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8900.c')
-rw-r--r--sound/soc/codecs/wm8900.c251
1 files changed, 122 insertions, 129 deletions
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5da17a704e5a..33c3b57f3f66 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/spi/spi.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <sound/core.h> 29#include <sound/core.h>
@@ -137,11 +138,9 @@
137 138
138#define WM8900_LRC_MASK 0xfc00 139#define WM8900_LRC_MASK 0xfc00
139 140
140struct snd_soc_codec_device soc_codec_dev_wm8900;
141
142struct wm8900_priv { 141struct wm8900_priv {
143 struct snd_soc_codec codec; 142 enum snd_soc_control_type control_type;
144 143 void *control_data;
145 u16 reg_cache[WM8900_MAXREG]; 144 u16 reg_cache[WM8900_MAXREG];
146 145
147 u32 fll_in; /* FLL input frequency */ 146 u32 fll_in; /* FLL input frequency */
@@ -627,8 +626,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
627 struct snd_soc_dai *dai) 626 struct snd_soc_dai *dai)
628{ 627{
629 struct snd_soc_pcm_runtime *rtd = substream->private_data; 628 struct snd_soc_pcm_runtime *rtd = substream->private_data;
630 struct snd_soc_device *socdev = rtd->socdev; 629 struct snd_soc_codec *codec = rtd->codec;
631 struct snd_soc_codec *codec = socdev->card->codec;
632 u16 reg; 630 u16 reg;
633 631
634 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60; 632 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
@@ -1015,8 +1013,8 @@ static struct snd_soc_dai_ops wm8900_dai_ops = {
1015 .digital_mute = wm8900_digital_mute, 1013 .digital_mute = wm8900_digital_mute,
1016}; 1014};
1017 1015
1018struct snd_soc_dai wm8900_dai = { 1016static struct snd_soc_dai_driver wm8900_dai = {
1019 .name = "WM8900 HiFi", 1017 .name = "wm8900-hifi",
1020 .playback = { 1018 .playback = {
1021 .stream_name = "HiFi Playback", 1019 .stream_name = "HiFi Playback",
1022 .channels_min = 1, 1020 .channels_min = 1,
@@ -1033,7 +1031,6 @@ struct snd_soc_dai wm8900_dai = {
1033 }, 1031 },
1034 .ops = &wm8900_dai_ops, 1032 .ops = &wm8900_dai_ops,
1035}; 1033};
1036EXPORT_SYMBOL_GPL(wm8900_dai);
1037 1034
1038static int wm8900_set_bias_level(struct snd_soc_codec *codec, 1035static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1039 enum snd_soc_bias_level level) 1036 enum snd_soc_bias_level level)
@@ -1128,10 +1125,8 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1128 return 0; 1125 return 0;
1129} 1126}
1130 1127
1131static int wm8900_suspend(struct platform_device *pdev, pm_message_t state) 1128static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state)
1132{ 1129{
1133 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1134 struct snd_soc_codec *codec = socdev->card->codec;
1135 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 1130 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1136 int fll_out = wm8900->fll_out; 1131 int fll_out = wm8900->fll_out;
1137 int fll_in = wm8900->fll_in; 1132 int fll_in = wm8900->fll_in;
@@ -1140,7 +1135,7 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1140 /* Stop the FLL in an orderly fashion */ 1135 /* Stop the FLL in an orderly fashion */
1141 ret = wm8900_set_fll(codec, 0, 0, 0); 1136 ret = wm8900_set_fll(codec, 0, 0, 0);
1142 if (ret != 0) { 1137 if (ret != 0) {
1143 dev_err(&pdev->dev, "Failed to stop FLL\n"); 1138 dev_err(codec->dev, "Failed to stop FLL\n");
1144 return ret; 1139 return ret;
1145 } 1140 }
1146 1141
@@ -1152,10 +1147,8 @@ static int wm8900_suspend(struct platform_device *pdev, pm_message_t state)
1152 return 0; 1147 return 0;
1153} 1148}
1154 1149
1155static int wm8900_resume(struct platform_device *pdev) 1150static int wm8900_resume(struct snd_soc_codec *codec)
1156{ 1151{
1157 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1158 struct snd_soc_codec *codec = socdev->card->codec;
1159 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); 1152 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1160 u16 *cache; 1153 u16 *cache;
1161 int i, ret; 1154 int i, ret;
@@ -1176,7 +1169,7 @@ static int wm8900_resume(struct platform_device *pdev)
1176 1169
1177 ret = wm8900_set_fll(codec, 0, fll_in, fll_out); 1170 ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
1178 if (ret != 0) { 1171 if (ret != 0) {
1179 dev_err(&pdev->dev, "Failed to restart FLL\n"); 1172 dev_err(codec->dev, "Failed to restart FLL\n");
1180 return ret; 1173 return ret;
1181 } 1174 }
1182 } 1175 }
@@ -1186,60 +1179,33 @@ static int wm8900_resume(struct platform_device *pdev)
1186 snd_soc_write(codec, i, cache[i]); 1179 snd_soc_write(codec, i, cache[i]);
1187 kfree(cache); 1180 kfree(cache);
1188 } else 1181 } else
1189 dev_err(&pdev->dev, "Unable to allocate register cache\n"); 1182 dev_err(codec->dev, "Unable to allocate register cache\n");
1190 1183
1191 return 0; 1184 return 0;
1192} 1185}
1193 1186
1194static struct snd_soc_codec *wm8900_codec; 1187static int wm8900_probe(struct snd_soc_codec *codec)
1195
1196static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1197 const struct i2c_device_id *id)
1198{ 1188{
1199 struct wm8900_priv *wm8900; 1189 struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
1200 struct snd_soc_codec *codec; 1190 int ret = 0, reg;
1201 unsigned int reg;
1202 int ret;
1203
1204 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1205 if (wm8900 == NULL)
1206 return -ENOMEM;
1207 1191
1208 codec = &wm8900->codec; 1192 codec->control_data = wm8900->control_data;
1209 snd_soc_codec_set_drvdata(codec, wm8900); 1193 ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
1210 codec->reg_cache = &wm8900->reg_cache[0];
1211 codec->reg_cache_size = WM8900_MAXREG;
1212
1213 mutex_init(&codec->mutex);
1214 INIT_LIST_HEAD(&codec->dapm_widgets);
1215 INIT_LIST_HEAD(&codec->dapm_paths);
1216
1217 codec->name = "WM8900";
1218 codec->owner = THIS_MODULE;
1219 codec->dai = &wm8900_dai;
1220 codec->num_dai = 1;
1221 codec->control_data = i2c;
1222 codec->set_bias_level = wm8900_set_bias_level;
1223 codec->volatile_register = wm8900_volatile_register;
1224 codec->dev = &i2c->dev;
1225
1226 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1227 if (ret != 0) { 1194 if (ret != 0) {
1228 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); 1195 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1229 goto err; 1196 return ret;
1230 } 1197 }
1231 1198
1232 reg = snd_soc_read(codec, WM8900_REG_ID); 1199 reg = snd_soc_read(codec, WM8900_REG_ID);
1233 if (reg != 0x8900) { 1200 if (reg != 0x8900) {
1234 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg); 1201 dev_err(codec->dev, "Device is not a WM8900 - ID %x\n", reg);
1235 ret = -ENODEV; 1202 return -ENODEV;
1236 goto err;
1237 } 1203 }
1238 1204
1239 /* Read back from the chip */ 1205 /* Read back from the chip */
1240 reg = snd_soc_read(codec, WM8900_REG_POWER1); 1206 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1241 reg = (reg >> 12) & 0xf; 1207 reg = (reg >> 12) & 0xf;
1242 dev_info(&i2c->dev, "WM8900 revision %d\n", reg); 1208 dev_info(codec->dev, "WM8900 revision %d\n", reg);
1243 1209
1244 wm8900_reset(codec); 1210 wm8900_reset(codec);
1245 1211
@@ -1271,43 +1237,97 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1271 /* Set the DAC and mixer output bias */ 1237 /* Set the DAC and mixer output bias */
1272 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1238 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1273 1239
1274 wm8900_dai.dev = &i2c->dev; 1240 snd_soc_add_controls(codec, wm8900_snd_controls,
1241 ARRAY_SIZE(wm8900_snd_controls));
1242 wm8900_add_widgets(codec);
1275 1243
1276 wm8900_codec = codec; 1244 return 0;
1245}
1277 1246
1278 ret = snd_soc_register_codec(codec); 1247/* power down chip */
1279 if (ret != 0) { 1248static int wm8900_remove(struct snd_soc_codec *codec)
1280 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); 1249{
1281 goto err; 1250 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1282 } 1251 return 0;
1252}
1283 1253
1284 ret = snd_soc_register_dai(&wm8900_dai); 1254static struct snd_soc_codec_driver soc_codec_dev_wm8900 = {
1285 if (ret != 0) { 1255 .probe = wm8900_probe,
1286 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret); 1256 .remove = wm8900_remove,
1287 goto err_codec; 1257 .suspend = wm8900_suspend,
1288 } 1258 .resume = wm8900_resume,
1259 .set_bias_level = wm8900_set_bias_level,
1260 .volatile_register = wm8900_volatile_register,
1261 .reg_cache_size = sizeof(wm8900_reg_defaults),
1262 .reg_word_size = sizeof(u16),
1263 .reg_cache_default = wm8900_reg_defaults,
1264};
1289 1265
1290 return ret; 1266#if defined(CONFIG_SPI_MASTER)
1267static int __devinit wm8900_spi_probe(struct spi_device *spi)
1268{
1269 struct wm8900_priv *wm8900;
1270 int ret;
1271
1272 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1273 if (wm8900 == NULL)
1274 return -ENOMEM;
1291 1275
1292err_codec: 1276 wm8900->control_data = spi;
1293 snd_soc_unregister_codec(codec); 1277 wm8900->control_type = SND_SOC_SPI;
1294err: 1278 spi_set_drvdata(spi, wm8900);
1295 kfree(wm8900); 1279
1296 wm8900_codec = NULL; 1280 ret = snd_soc_register_codec(&spi->dev,
1281 &soc_codec_dev_wm8900, &wm8900_dai, 1);
1282 if (ret < 0)
1283 kfree(wm8900);
1297 return ret; 1284 return ret;
1298} 1285}
1299 1286
1300static __devexit int wm8900_i2c_remove(struct i2c_client *client) 1287static int __devexit wm8900_spi_remove(struct spi_device *spi)
1301{ 1288{
1302 snd_soc_unregister_dai(&wm8900_dai); 1289 snd_soc_unregister_codec(&spi->dev);
1303 snd_soc_unregister_codec(wm8900_codec); 1290 kfree(spi_get_drvdata(spi));
1291 return 0;
1292}
1304 1293
1305 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF); 1294static struct spi_driver wm8900_spi_driver = {
1295 .driver = {
1296 .name = "wm8900-codec",
1297 .bus = &spi_bus_type,
1298 .owner = THIS_MODULE,
1299 },
1300 .probe = wm8900_spi_probe,
1301 .remove = __devexit_p(wm8900_spi_remove),
1302};
1303#endif /* CONFIG_SPI_MASTER */
1304
1305#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1306static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1307 const struct i2c_device_id *id)
1308{
1309 struct wm8900_priv *wm8900;
1310 int ret;
1311
1312 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1313 if (wm8900 == NULL)
1314 return -ENOMEM;
1315
1316 i2c_set_clientdata(i2c, wm8900);
1317 wm8900->control_data = i2c;
1318 wm8900->control_type = SND_SOC_I2C;
1306 1319
1307 wm8900_dai.dev = NULL; 1320 ret = snd_soc_register_codec(&i2c->dev,
1308 kfree(snd_soc_codec_get_drvdata(wm8900_codec)); 1321 &soc_codec_dev_wm8900, &wm8900_dai, 1);
1309 wm8900_codec = NULL; 1322 if (ret < 0)
1323 kfree(wm8900);
1324 return ret;
1325}
1310 1326
1327static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1328{
1329 snd_soc_unregister_codec(&client->dev);
1330 kfree(i2c_get_clientdata(client));
1311 return 0; 1331 return 0;
1312} 1332}
1313 1333
@@ -1319,71 +1339,44 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1319 1339
1320static struct i2c_driver wm8900_i2c_driver = { 1340static struct i2c_driver wm8900_i2c_driver = {
1321 .driver = { 1341 .driver = {
1322 .name = "WM8900", 1342 .name = "wm8900-codec",
1323 .owner = THIS_MODULE, 1343 .owner = THIS_MODULE,
1324 }, 1344 },
1325 .probe = wm8900_i2c_probe, 1345 .probe = wm8900_i2c_probe,
1326 .remove = __devexit_p(wm8900_i2c_remove), 1346 .remove = __devexit_p(wm8900_i2c_remove),
1327 .id_table = wm8900_i2c_id, 1347 .id_table = wm8900_i2c_id,
1328}; 1348};
1349#endif
1329 1350
1330static int wm8900_probe(struct platform_device *pdev) 1351static int __init wm8900_modinit(void)
1331{ 1352{
1332 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1333 struct snd_soc_codec *codec;
1334 int ret = 0; 1353 int ret = 0;
1335 1354#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1336 if (!wm8900_codec) { 1355 ret = i2c_add_driver(&wm8900_i2c_driver);
1337 dev_err(&pdev->dev, "I2C client not yet instantiated\n"); 1356 if (ret != 0) {
1338 return -ENODEV; 1357 printk(KERN_ERR "Failed to register wm8900 I2C driver: %d\n",
1358 ret);
1339 } 1359 }
1340 1360#endif
1341 codec = wm8900_codec; 1361#if defined(CONFIG_SPI_MASTER)
1342 socdev->card->codec = codec; 1362 ret = spi_register_driver(&wm8900_spi_driver);
1343 1363 if (ret != 0) {
1344 /* Register pcms */ 1364 printk(KERN_ERR "Failed to register wm8900 SPI driver: %d\n",
1345 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1365 ret);
1346 if (ret < 0) {
1347 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1348 goto pcm_err;
1349 } 1366 }
1350 1367#endif
1351 snd_soc_add_controls(codec, wm8900_snd_controls,
1352 ARRAY_SIZE(wm8900_snd_controls));
1353 wm8900_add_widgets(codec);
1354
1355pcm_err:
1356 return ret; 1368 return ret;
1357} 1369}
1358
1359/* power down chip */
1360static int wm8900_remove(struct platform_device *pdev)
1361{
1362 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1363
1364 snd_soc_free_pcms(socdev);
1365 snd_soc_dapm_free(socdev);
1366
1367 return 0;
1368}
1369
1370struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1371 .probe = wm8900_probe,
1372 .remove = wm8900_remove,
1373 .suspend = wm8900_suspend,
1374 .resume = wm8900_resume,
1375};
1376EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1377
1378static int __init wm8900_modinit(void)
1379{
1380 return i2c_add_driver(&wm8900_i2c_driver);
1381}
1382module_init(wm8900_modinit); 1370module_init(wm8900_modinit);
1383 1371
1384static void __exit wm8900_exit(void) 1372static void __exit wm8900_exit(void)
1385{ 1373{
1374#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1386 i2c_del_driver(&wm8900_i2c_driver); 1375 i2c_del_driver(&wm8900_i2c_driver);
1376#endif
1377#if defined(CONFIG_SPI_MASTER)
1378 spi_unregister_driver(&wm8900_spi_driver);
1379#endif
1387} 1380}
1388module_exit(wm8900_exit); 1381module_exit(wm8900_exit);
1389 1382