aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/wm8900.c159
-rw-r--r--sound/soc/codecs/wm8900.h7
2 files changed, 81 insertions, 85 deletions
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index ebf58fba1beb..6767de10ded0 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -138,6 +138,10 @@
138struct snd_soc_codec_device soc_codec_dev_wm8900; 138struct snd_soc_codec_device soc_codec_dev_wm8900;
139 139
140struct wm8900_priv { 140struct wm8900_priv {
141 struct snd_soc_codec codec;
142
143 u16 reg_cache[WM8900_MAXREG];
144
141 u32 fll_in; /* FLL input frequency */ 145 u32 fll_in; /* FLL input frequency */
142 u32 fll_out; /* FLL output frequency */ 146 u32 fll_out; /* FLL output frequency */
143}; 147};
@@ -1282,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
1282 return 0; 1286 return 0;
1283} 1287}
1284 1288
1285/* 1289static struct snd_soc_codec *wm8900_codec;
1286 * initialise the WM8900 driver 1290
1287 * register the mixer and dsp interfaces with the kernel 1291static int wm8900_i2c_probe(struct i2c_client *i2c,
1288 */ 1292 const struct i2c_device_id *id)
1289static int wm8900_init(struct snd_soc_device *socdev)
1290{ 1293{
1291 struct snd_soc_codec *codec = socdev->codec; 1294 struct wm8900_priv *wm8900;
1292 int ret = 0; 1295 struct snd_soc_codec *codec;
1293 unsigned int reg; 1296 unsigned int reg;
1294 struct i2c_client *i2c_client = socdev->codec->control_data; 1297 int ret;
1298
1299 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1300 if (wm8900 == NULL)
1301 return -ENOMEM;
1302
1303 codec = &wm8900->codec;
1304 codec->private_data = wm8900;
1305 codec->reg_cache = &wm8900->reg_cache[0];
1306 codec->reg_cache_size = WM8900_MAXREG;
1307
1308 mutex_init(&codec->mutex);
1309 INIT_LIST_HEAD(&codec->dapm_widgets);
1310 INIT_LIST_HEAD(&codec->dapm_paths);
1295 1311
1296 codec->name = "WM8900"; 1312 codec->name = "WM8900";
1297 codec->owner = THIS_MODULE; 1313 codec->owner = THIS_MODULE;
@@ -1299,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
1299 codec->write = wm8900_write; 1315 codec->write = wm8900_write;
1300 codec->dai = &wm8900_dai; 1316 codec->dai = &wm8900_dai;
1301 codec->num_dai = 1; 1317 codec->num_dai = 1;
1302 codec->reg_cache_size = WM8900_MAXREG; 1318 codec->hw_write = (hw_write_t)i2c_master_send;
1303 codec->reg_cache = kmemdup(wm8900_reg_defaults, 1319 codec->control_data = i2c;
1304 sizeof(wm8900_reg_defaults), GFP_KERNEL); 1320 codec->set_bias_level = wm8900_set_bias_level;
1305 1321 codec->dev = &i2c->dev;
1306 if (codec->reg_cache == NULL)
1307 return -ENOMEM;
1308 1322
1309 reg = wm8900_read(codec, WM8900_REG_ID); 1323 reg = wm8900_read(codec, WM8900_REG_ID);
1310 if (reg != 0x8900) { 1324 if (reg != 0x8900) {
1311 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n", 1325 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1312 reg); 1326 ret = -ENODEV;
1313 return -ENODEV; 1327 goto err;
1314 }
1315
1316 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1317 if (codec->private_data == NULL) {
1318 ret = -ENOMEM;
1319 goto priv_err;
1320 } 1328 }
1321 1329
1322 /* Read back from the chip */ 1330 /* Read back from the chip */
1323 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1331 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1324 reg = (reg >> 12) & 0xf; 1332 reg = (reg >> 12) & 0xf;
1325 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg); 1333 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1326 1334
1327 wm8900_reset(codec); 1335 wm8900_reset(codec);
1328 1336
1337 /* Turn the chip on */
1338 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339
1329 /* Latch the volume update bits */ 1340 /* Latch the volume update bits */
1330 wm8900_write(codec, WM8900_REG_LINVOL, 1341 wm8900_write(codec, WM8900_REG_LINVOL,
1331 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1342 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1351,52 +1362,43 @@ static int wm8900_init(struct snd_soc_device *socdev)
1351 /* Set the DAC and mixer output bias */ 1362 /* Set the DAC and mixer output bias */
1352 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1363 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1353 1364
1354 /* Register pcms */ 1365 wm8900_dai.dev = &i2c->dev;
1355 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1356 if (ret < 0) {
1357 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1358 goto pcm_err;
1359 }
1360 1366
1361 /* Turn the chip on */ 1367 wm8900_codec = codec;
1362 codec->bias_level = SND_SOC_BIAS_OFF;
1363 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1364 1368
1365 wm8900_add_controls(codec); 1369 ret = snd_soc_register_codec(codec);
1366 wm8900_add_widgets(codec); 1370 if (ret != 0) {
1371 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1372 goto err;
1373 }
1367 1374
1368 ret = snd_soc_init_card(socdev); 1375 ret = snd_soc_register_dai(&wm8900_dai);
1369 if (ret < 0) { 1376 if (ret != 0) {
1370 dev_err(&i2c_client->dev, "Failed to register card\n"); 1377 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1371 goto card_err; 1378 goto err_codec;
1372 } 1379 }
1373 return ret;
1374 1380
1375card_err:
1376 snd_soc_free_pcms(socdev);
1377 snd_soc_dapm_free(socdev);
1378pcm_err:
1379 kfree(codec->reg_cache);
1380priv_err:
1381 kfree(codec->private_data);
1382 return ret; 1381 return ret;
1383}
1384
1385static struct i2c_client *wm8900_client;
1386 1382
1387static int wm8900_i2c_probe(struct i2c_client *i2c, 1383err_codec:
1388 const struct i2c_device_id *id) 1384 snd_soc_unregister_codec(codec);
1389{ 1385err:
1390 wm8900_client = i2c; 1386 kfree(wm8900);
1391 wm8900_dai.dev = &i2c->dev; 1387 wm8900_codec = NULL;
1392 return snd_soc_register_dai(&wm8900_dai); 1388 return ret;
1393} 1389}
1394 1390
1395static int wm8900_i2c_remove(struct i2c_client *client) 1391static int wm8900_i2c_remove(struct i2c_client *client)
1396{ 1392{
1397 snd_soc_unregister_dai(&wm8900_dai); 1393 snd_soc_unregister_dai(&wm8900_dai);
1394 snd_soc_unregister_codec(wm8900_codec);
1395
1396 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1397
1398 wm8900_dai.dev = NULL; 1398 wm8900_dai.dev = NULL;
1399 wm8900_client = NULL; 1399 kfree(wm8900_codec->private_data);
1400 wm8900_codec = NULL;
1401
1400 return 0; 1402 return 0;
1401} 1403}
1402 1404
@@ -1408,7 +1410,7 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1408 1410
1409static struct i2c_driver wm8900_i2c_driver = { 1411static struct i2c_driver wm8900_i2c_driver = {
1410 .driver = { 1412 .driver = {
1411 .name = "WM8900 I2C codec", 1413 .name = "WM8900",
1412 .owner = THIS_MODULE, 1414 .owner = THIS_MODULE,
1413 }, 1415 },
1414 .probe = wm8900_i2c_probe, 1416 .probe = wm8900_i2c_probe,
@@ -1422,30 +1424,36 @@ static int wm8900_probe(struct platform_device *pdev)
1422 struct snd_soc_codec *codec; 1424 struct snd_soc_codec *codec;
1423 int ret = 0; 1425 int ret = 0;
1424 1426
1425 if (!wm8900_client) { 1427 if (!wm8900_codec) {
1426 dev_err(&pdev->dev, "I2C client not yet instantiated\n"); 1428 dev_err(&pdev->dev, "I2C client not yet instantiated\n");
1427 return -ENODEV; 1429 return -ENODEV;
1428 } 1430 }
1429 1431
1430 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1432 codec = wm8900_codec;
1431 if (codec == NULL)
1432 return -ENOMEM;
1433
1434 mutex_init(&codec->mutex);
1435 INIT_LIST_HEAD(&codec->dapm_widgets);
1436 INIT_LIST_HEAD(&codec->dapm_paths);
1437
1438 socdev->codec = codec; 1433 socdev->codec = codec;
1439 1434
1440 codec->set_bias_level = wm8900_set_bias_level; 1435 /* Register pcms */
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) {
1438 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1439 goto pcm_err;
1440 }
1441 1441
1442 codec->hw_write = (hw_write_t)i2c_master_send; 1442 wm8900_add_controls(codec);
1443 codec->control_data = wm8900_client; 1443 wm8900_add_widgets(codec);
1444
1445 ret = snd_soc_init_card(socdev);
1446 if (ret < 0) {
1447 dev_err(&pdev->dev, "Failed to register card\n");
1448 goto card_err;
1449 }
1444 1450
1445 ret = wm8900_init(socdev); 1451 return ret;
1446 if (ret != 0)
1447 kfree(codec);
1448 1452
1453card_err:
1454 snd_soc_free_pcms(socdev);
1455 snd_soc_dapm_free(socdev);
1456pcm_err:
1449 return ret; 1457 return ret;
1450} 1458}
1451 1459
@@ -1453,14 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
1453static int wm8900_remove(struct platform_device *pdev) 1461static int wm8900_remove(struct platform_device *pdev)
1454{ 1462{
1455 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1456 struct snd_soc_codec *codec = socdev->codec;
1457
1458 if (codec->control_data)
1459 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1460 1464
1461 snd_soc_free_pcms(socdev); 1465 snd_soc_free_pcms(socdev);
1462 snd_soc_dapm_free(socdev); 1466 snd_soc_dapm_free(socdev);
1463 kfree(codec);
1464 1467
1465 return 0; 1468 return 0;
1466} 1469}
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index 2249a446ad37..fd15007d10c7 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,13 +52,6 @@
52#define WM8900_DAC_CLKDIV_5_5 0x14 52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18 53#define WM8900_DAC_CLKDIV_6 0x18
54 54
55#define WM8900_
56
57struct wm8900_setup_data {
58 int i2c_bus;
59 unsigned short i2c_address;
60};
61
62extern struct snd_soc_dai wm8900_dai; 55extern struct snd_soc_dai wm8900_dai;
63extern struct snd_soc_codec_device soc_codec_dev_wm8900; 56extern struct snd_soc_codec_device soc_codec_dev_wm8900;
64 57