aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic3x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r--sound/soc/codecs/tlv320aic3x.c233
1 files changed, 118 insertions, 115 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index cb0d1bf34b57..3395cf945d56 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};
@@ -145,8 +146,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
145 u8 *value) 146 u8 *value)
146{ 147{
147 *value = reg & 0xff; 148 *value = reg & 0xff;
148 if (codec->hw_read(codec->control_data, value, 1) != 1) 149
149 return -EIO; 150 value[0] = i2c_smbus_read_byte_data(codec->control_data, value[0]);
150 151
151 aic3x_write_reg_cache(codec, reg, *value); 152 aic3x_write_reg_cache(codec, reg, *value);
152 return 0; 153 return 0;
@@ -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,56 +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_i2c_read(struct i2c_client *client, u8 *value, int len) 1353static inline void aic3x_i2c_init(void)
1329{ 1354{
1330 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1331 return (len == 1);
1332}
1333
1334static int aic3x_add_i2c_device(struct platform_device *pdev,
1335 const struct aic3x_setup_data *setup)
1336{
1337 struct i2c_board_info info;
1338 struct i2c_adapter *adapter;
1339 struct i2c_client *client;
1340 int ret; 1355 int ret;
1341 1356
1342 ret = i2c_add_driver(&aic3x_i2c_driver); 1357 ret = i2c_add_driver(&aic3x_i2c_driver);
1343 if (ret != 0) { 1358 if (ret)
1344 dev_err(&pdev->dev, "can't add i2c driver\n"); 1359 printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
1345 return ret; 1360 __func__, ret);
1346 } 1361}
1347
1348 memset(&info, 0, sizeof(struct i2c_board_info));
1349 info.addr = setup->i2c_address;
1350 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1351
1352 adapter = i2c_get_adapter(setup->i2c_bus);
1353 if (!adapter) {
1354 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1355 setup->i2c_bus);
1356 goto err_driver;
1357 }
1358
1359 client = i2c_new_device(adapter, &info);
1360 i2c_put_adapter(adapter);
1361 if (!client) {
1362 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1363 (unsigned int)info.addr);
1364 goto err_driver;
1365 }
1366
1367 return 0;
1368 1362
1369err_driver: 1363static inline void aic3x_i2c_exit(void)
1364{
1370 i2c_del_driver(&aic3x_i2c_driver); 1365 i2c_del_driver(&aic3x_i2c_driver);
1371 return -ENODEV;
1372} 1366}
1367#else
1368static inline void aic3x_i2c_init(void) { }
1369static inline void aic3x_i2c_exit(void) { }
1373#endif 1370#endif
1374 1371
1375static int aic3x_probe(struct platform_device *pdev) 1372static int aic3x_probe(struct platform_device *pdev)
@@ -1377,43 +1374,51 @@ static int aic3x_probe(struct platform_device *pdev)
1377 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1374 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1378 struct aic3x_setup_data *setup; 1375 struct aic3x_setup_data *setup;
1379 struct snd_soc_codec *codec; 1376 struct snd_soc_codec *codec;
1380 struct aic3x_priv *aic3x;
1381 int ret = 0; 1377 int ret = 0;
1382 1378
1383 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 }
1384 1384
1385 socdev->card->codec = codec;
1385 setup = socdev->codec_data; 1386 setup = socdev->codec_data;
1386 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1387 if (codec == NULL)
1388 return -ENOMEM;
1389 1387
1390 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1388 if (setup) {
1391 if (aic3x == NULL) { 1389 /* setup GPIO functions */
1392 kfree(codec); 1390 aic3x_write(codec, AIC3X_GPIO1_REG,
1393 return -ENOMEM; 1391 (setup->gpio_func[0] & 0xf) << 4);
1392 aic3x_write(codec, AIC3X_GPIO2_REG,
1393 (setup->gpio_func[1] & 0xf) << 4);
1394 } 1394 }
1395 1395
1396 codec->private_data = aic3x; 1396 /* register pcms */
1397 socdev->card->codec = codec; 1397 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1398 mutex_init(&codec->mutex); 1398 if (ret < 0) {
1399 INIT_LIST_HEAD(&codec->dapm_widgets); 1399 printk(KERN_ERR "aic3x: failed to create pcms\n");
1400 INIT_LIST_HEAD(&codec->dapm_paths); 1400 goto pcm_err;
1401
1402 aic3x_socdev = socdev;
1403#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1404 if (setup->i2c_address) {
1405 codec->hw_write = (hw_write_t) i2c_master_send;
1406 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1407 ret = aic3x_add_i2c_device(pdev, setup);
1408 } 1401 }
1409#else
1410 /* Add other interfaces here */
1411#endif
1412 1402
1413 if (ret != 0) { 1403 snd_soc_add_controls(codec, aic3x_snd_controls,
1414 kfree(codec->private_data); 1404 ARRAY_SIZE(aic3x_snd_controls));
1415 kfree(codec); 1405
1406 aic3x_add_widgets(codec);
1407
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1416 } 1412 }
1413
1414 return ret;
1415
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err:
1421 kfree(codec->reg_cache);
1417 return ret; 1422 return ret;
1418} 1423}
1419 1424
@@ -1428,12 +1433,8 @@ static int aic3x_remove(struct platform_device *pdev)
1428 1433
1429 snd_soc_free_pcms(socdev); 1434 snd_soc_free_pcms(socdev);
1430 snd_soc_dapm_free(socdev); 1435 snd_soc_dapm_free(socdev);
1431#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1436
1432 i2c_unregister_device(codec->control_data); 1437 kfree(codec->reg_cache);
1433 i2c_del_driver(&aic3x_i2c_driver);
1434#endif
1435 kfree(codec->private_data);
1436 kfree(codec);
1437 1438
1438 return 0; 1439 return 0;
1439} 1440}
@@ -1448,13 +1449,15 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1448 1449
1449static int __init aic3x_modinit(void) 1450static int __init aic3x_modinit(void)
1450{ 1451{
1451 return snd_soc_register_dai(&aic3x_dai); 1452 aic3x_i2c_init();
1453
1454 return 0;
1452} 1455}
1453module_init(aic3x_modinit); 1456module_init(aic3x_modinit);
1454 1457
1455static void __exit aic3x_exit(void) 1458static void __exit aic3x_exit(void)
1456{ 1459{
1457 snd_soc_unregister_dai(&aic3x_dai); 1460 aic3x_i2c_exit();
1458} 1461}
1459module_exit(aic3x_exit); 1462module_exit(aic3x_exit);
1460 1463