aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
authorBen Dooks <ben@simtec.co.uk>2009-08-20 17:50:41 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-08-21 05:52:49 -0400
commitcb3826f524728a90a47f2f831c3d61851c8091b2 (patch)
tree5150c7c4a6547851fb126c4c9feee75ac4e5d2c1 /sound/soc/codecs
parent14412acde5b57450b8afb3d4b03132419b6abebf (diff)
ASoC: tlv320aic3x: Change to use device model
The tlv320aic3x driver managed its own i2c device, instead of an extant one created by the board support code. Change the code to make it so that the driver binds to an extant (in this case i2c) device. Add explict tlv320aic33 as well as tlv320aic3x to the supported device table and remove the old driver bindings from the users of this code. Signed-off-by: Ben Dooks <ben@simtec.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/tlv320aic3x.c221
-rw-r--r--sound/soc/codecs/tlv320aic3x.h2
2 files changed, 116 insertions, 107 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 126b15b18aeb..5d547675b853 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -53,6 +53,7 @@
53 53
54/* codec private data */ 54/* codec private data */
55struct aic3x_priv { 55struct aic3x_priv {
56 struct snd_soc_codec codec;
56 unsigned int sysclk; 57 unsigned int sysclk;
57 int master; 58 int master;
58}; 59};
@@ -1156,11 +1157,13 @@ static int aic3x_resume(struct platform_device *pdev)
1156 * initialise the AIC3X driver 1157 * initialise the AIC3X driver
1157 * register the mixer and dsp interfaces with the kernel 1158 * register the mixer and dsp interfaces with the kernel
1158 */ 1159 */
1159static int aic3x_init(struct snd_soc_device *socdev) 1160static int aic3x_init(struct snd_soc_codec *codec)
1160{ 1161{
1161 struct snd_soc_codec *codec = socdev->card->codec; 1162 int reg;
1162 struct aic3x_setup_data *setup = socdev->codec_data; 1163
1163 int reg, ret = 0; 1164 mutex_init(&codec->mutex);
1165 INIT_LIST_HEAD(&codec->dapm_widgets);
1166 INIT_LIST_HEAD(&codec->dapm_paths);
1164 1167
1165 codec->name = "tlv320aic3x"; 1168 codec->name = "tlv320aic3x";
1166 codec->owner = THIS_MODULE; 1169 codec->owner = THIS_MODULE;
@@ -1177,13 +1180,6 @@ static int aic3x_init(struct snd_soc_device *socdev)
1177 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); 1180 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
1178 aic3x_write(codec, AIC3X_RESET, SOFT_RESET); 1181 aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
1179 1182
1180 /* register pcms */
1181 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1182 if (ret < 0) {
1183 printk(KERN_ERR "aic3x: failed to create pcms\n");
1184 goto pcm_err;
1185 }
1186
1187 /* DAC default volume and mute */ 1183 /* DAC default volume and mute */
1188 aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON); 1184 aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
1189 aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON); 1185 aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
@@ -1250,30 +1246,51 @@ static int aic3x_init(struct snd_soc_device *socdev)
1250 /* off, with power on */ 1246 /* off, with power on */
1251 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1247 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1252 1248
1253 /* setup GPIO functions */ 1249 return 0;
1254 aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); 1250}
1255 aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
1256 1251
1257 snd_soc_add_controls(codec, aic3x_snd_controls, 1252static struct snd_soc_codec *aic3x_codec;
1258 ARRAY_SIZE(aic3x_snd_controls)); 1253
1259 aic3x_add_widgets(codec); 1254static int aic3x_register(struct snd_soc_codec *codec)
1260 ret = snd_soc_init_card(socdev); 1255{
1256 int ret;
1257
1258 ret = aic3x_init(codec);
1261 if (ret < 0) { 1259 if (ret < 0) {
1262 printk(KERN_ERR "aic3x: failed to register card\n"); 1260 dev_err(codec->dev, "Failed to initialise device\n");
1263 goto card_err; 1261 return ret;
1264 } 1262 }
1265 1263
1266 return ret; 1264 aic3x_codec = codec;
1267 1265
1268card_err: 1266 ret = snd_soc_register_codec(codec);
1269 snd_soc_free_pcms(socdev); 1267 if (ret) {
1270 snd_soc_dapm_free(socdev); 1268 dev_err(codec->dev, "Failed to register codec\n");
1271pcm_err: 1269 return ret;
1272 kfree(codec->reg_cache); 1270 }
1273 return ret; 1271
1272 ret = snd_soc_register_dai(&aic3x_dai);
1273 if (ret) {
1274 dev_err(codec->dev, "Failed to register dai\n");
1275 snd_soc_unregister_codec(codec);
1276 return ret;
1277 }
1278
1279 return 0;
1274} 1280}
1275 1281
1276static struct snd_soc_device *aic3x_socdev; 1282static int aic3x_unregister(struct aic3x_priv *aic3x)
1283{
1284 aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF);
1285
1286 snd_soc_unregister_dai(&aic3x_dai);
1287 snd_soc_unregister_codec(&aic3x->codec);
1288
1289 kfree(aic3x);
1290 aic3x_codec = NULL;
1291
1292 return 0;
1293}
1277 1294
1278#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1295#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1279/* 1296/*
@@ -1288,28 +1305,36 @@ static struct snd_soc_device *aic3x_socdev;
1288static int aic3x_i2c_probe(struct i2c_client *i2c, 1305static int aic3x_i2c_probe(struct i2c_client *i2c,
1289 const struct i2c_device_id *id) 1306 const struct i2c_device_id *id)
1290{ 1307{
1291 struct snd_soc_device *socdev = aic3x_socdev; 1308 struct snd_soc_codec *codec;
1292 struct snd_soc_codec *codec = socdev->card->codec; 1309 struct aic3x_priv *aic3x;
1293 int ret;
1294 1310
1295 i2c_set_clientdata(i2c, codec); 1311 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1312 if (aic3x == NULL) {
1313 dev_err(&i2c->dev, "failed to create private data\n");
1314 return -ENOMEM;
1315 }
1316
1317 codec = &aic3x->codec;
1318 codec->dev = &i2c->dev;
1319 codec->private_data = aic3x;
1296 codec->control_data = i2c; 1320 codec->control_data = i2c;
1321 codec->hw_write = (hw_write_t) i2c_master_send;
1297 1322
1298 ret = aic3x_init(socdev); 1323 i2c_set_clientdata(i2c, aic3x);
1299 if (ret < 0) 1324
1300 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); 1325 return aic3x_register(codec);
1301 return ret;
1302} 1326}
1303 1327
1304static int aic3x_i2c_remove(struct i2c_client *client) 1328static int aic3x_i2c_remove(struct i2c_client *client)
1305{ 1329{
1306 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1330 struct aic3x_priv *aic3x = i2c_get_clientdata(client);
1307 kfree(codec->reg_cache); 1331
1308 return 0; 1332 return aic3x_unregister(aic3x);
1309} 1333}
1310 1334
1311static const struct i2c_device_id aic3x_i2c_id[] = { 1335static const struct i2c_device_id aic3x_i2c_id[] = {
1312 { "tlv320aic3x", 0 }, 1336 { "tlv320aic3x", 0 },
1337 { "tlv320aic33", 0 },
1313 { } 1338 { }
1314}; 1339};
1315MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1340MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
@@ -1320,50 +1345,28 @@ static struct i2c_driver aic3x_i2c_driver = {
1320 .name = "aic3x I2C Codec", 1345 .name = "aic3x I2C Codec",
1321 .owner = THIS_MODULE, 1346 .owner = THIS_MODULE,
1322 }, 1347 },
1323 .probe = aic3x_i2c_probe, 1348 .probe = aic3x_i2c_probe,
1324 .remove = aic3x_i2c_remove, 1349 .remove = aic3x_i2c_remove,
1325 .id_table = aic3x_i2c_id, 1350 .id_table = aic3x_i2c_id,
1326}; 1351};
1327 1352
1328static int aic3x_add_i2c_device(struct platform_device *pdev, 1353static inline void aic3x_i2c_init(void)
1329 const struct aic3x_setup_data *setup)
1330{ 1354{
1331 struct i2c_board_info info;
1332 struct i2c_adapter *adapter;
1333 struct i2c_client *client;
1334 int ret; 1355 int ret;
1335 1356
1336 ret = i2c_add_driver(&aic3x_i2c_driver); 1357 ret = i2c_add_driver(&aic3x_i2c_driver);
1337 if (ret != 0) { 1358 if (ret)
1338 dev_err(&pdev->dev, "can't add i2c driver\n"); 1359 printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
1339 return ret; 1360 __func__, ret);
1340 } 1361}
1341
1342 memset(&info, 0, sizeof(struct i2c_board_info));
1343 info.addr = setup->i2c_address;
1344 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1345
1346 adapter = i2c_get_adapter(setup->i2c_bus);
1347 if (!adapter) {
1348 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1349 setup->i2c_bus);
1350 goto err_driver;
1351 }
1352
1353 client = i2c_new_device(adapter, &info);
1354 i2c_put_adapter(adapter);
1355 if (!client) {
1356 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1357 (unsigned int)info.addr);
1358 goto err_driver;
1359 }
1360
1361 return 0;
1362 1362
1363err_driver: 1363static inline void aic3x_i2c_exit(void)
1364{
1364 i2c_del_driver(&aic3x_i2c_driver); 1365 i2c_del_driver(&aic3x_i2c_driver);
1365 return -ENODEV;
1366} 1366}
1367#else
1368static inline void aic3x_i2c_init(void) { }
1369static inline void aic3x_i2c_exit(void) { }
1367#endif 1370#endif
1368 1371
1369static int aic3x_probe(struct platform_device *pdev) 1372static int aic3x_probe(struct platform_device *pdev)
@@ -1371,42 +1374,52 @@ static int aic3x_probe(struct platform_device *pdev)
1371 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1374 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1372 struct aic3x_setup_data *setup; 1375 struct aic3x_setup_data *setup;
1373 struct snd_soc_codec *codec; 1376 struct snd_soc_codec *codec;
1374 struct aic3x_priv *aic3x;
1375 int ret = 0; 1377 int ret = 0;
1376 1378
1377 printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION); 1379 codec = aic3x_codec;
1380 if (!codec) {
1381 dev_err(&pdev->dev, "Codec not registered\n");
1382 return -ENODEV;
1383 }
1378 1384
1385 socdev->card->codec = codec;
1379 setup = socdev->codec_data; 1386 setup = socdev->codec_data;
1380 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1381 if (codec == NULL)
1382 return -ENOMEM;
1383 1387
1384 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1388 if (!setup) {
1385 if (aic3x == NULL) { 1389 dev_err(&pdev->dev, "No setup data supplied\n");
1386 kfree(codec); 1390 return -EINVAL;
1387 return -ENOMEM;
1388 } 1391 }
1389 1392
1390 codec->private_data = aic3x; 1393 /* setup GPIO functions */
1391 socdev->card->codec = codec; 1394 aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4);
1392 mutex_init(&codec->mutex); 1395 aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
1393 INIT_LIST_HEAD(&codec->dapm_widgets);
1394 INIT_LIST_HEAD(&codec->dapm_paths);
1395 1396
1396 aic3x_socdev = socdev; 1397 /* register pcms */
1397#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1398 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1398 if (setup->i2c_address) { 1399 if (ret < 0) {
1399 codec->hw_write = (hw_write_t) i2c_master_send; 1400 printk(KERN_ERR "aic3x: failed to create pcms\n");
1400 ret = aic3x_add_i2c_device(pdev, setup); 1401 goto pcm_err;
1401 } 1402 }
1402#else
1403 /* Add other interfaces here */
1404#endif
1405 1403
1406 if (ret != 0) { 1404 snd_soc_add_controls(codec, aic3x_snd_controls,
1407 kfree(codec->private_data); 1405 ARRAY_SIZE(aic3x_snd_controls));
1408 kfree(codec); 1406
1407 aic3x_add_widgets(codec);
1408
1409 ret = snd_soc_init_card(socdev);
1410 if (ret < 0) {
1411 printk(KERN_ERR "aic3x: failed to register card\n");
1412 goto card_err;
1409 } 1413 }
1414
1415 return ret;
1416
1417card_err:
1418 snd_soc_free_pcms(socdev);
1419 snd_soc_dapm_free(socdev);
1420
1421pcm_err:
1422 kfree(codec->reg_cache);
1410 return ret; 1423 return ret;
1411} 1424}
1412 1425
@@ -1421,12 +1434,8 @@ static int aic3x_remove(struct platform_device *pdev)
1421 1434
1422 snd_soc_free_pcms(socdev); 1435 snd_soc_free_pcms(socdev);
1423 snd_soc_dapm_free(socdev); 1436 snd_soc_dapm_free(socdev);
1424#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1437
1425 i2c_unregister_device(codec->control_data); 1438 kfree(codec->reg_cache);
1426 i2c_del_driver(&aic3x_i2c_driver);
1427#endif
1428 kfree(codec->private_data);
1429 kfree(codec);
1430 1439
1431 return 0; 1440 return 0;
1432} 1441}
@@ -1441,13 +1450,15 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1441 1450
1442static int __init aic3x_modinit(void) 1451static int __init aic3x_modinit(void)
1443{ 1452{
1444 return snd_soc_register_dai(&aic3x_dai); 1453 aic3x_i2c_init();
1454
1455 return 0;
1445} 1456}
1446module_init(aic3x_modinit); 1457module_init(aic3x_modinit);
1447 1458
1448static void __exit aic3x_exit(void) 1459static void __exit aic3x_exit(void)
1449{ 1460{
1450 snd_soc_unregister_dai(&aic3x_dai); 1461 aic3x_i2c_exit();
1451} 1462}
1452module_exit(aic3x_exit); 1463module_exit(aic3x_exit);
1453 1464
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index ac827e578c4d..9af1c886213c 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -282,8 +282,6 @@ int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec); 282int aic3x_button_pressed(struct snd_soc_codec *codec);
283 283
284struct aic3x_setup_data { 284struct aic3x_setup_data {
285 int i2c_bus;
286 unsigned short i2c_address;
287 unsigned int gpio_func[2]; 285 unsigned int gpio_func[2];
288}; 286};
289 287