diff options
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 223 |
1 files changed, 71 insertions, 152 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 71a69908ccf6..43fd9c171742 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -63,8 +63,10 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = { | |||
63 | 63 | ||
64 | /* codec private data */ | 64 | /* codec private data */ |
65 | struct aic3x_priv { | 65 | struct aic3x_priv { |
66 | struct snd_soc_codec codec; | ||
67 | struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; | 66 | struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES]; |
67 | enum snd_soc_control_type control_type; | ||
68 | struct aic3x_setup_data *setup; | ||
69 | void *control_data; | ||
68 | unsigned int sysclk; | 70 | unsigned int sysclk; |
69 | int master; | 71 | int master; |
70 | int gpio_reset; | 72 | int gpio_reset; |
@@ -773,8 +775,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, | |||
773 | struct snd_soc_dai *dai) | 775 | struct snd_soc_dai *dai) |
774 | { | 776 | { |
775 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 777 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
776 | struct snd_soc_device *socdev = rtd->socdev; | 778 | struct snd_soc_codec *codec =rtd->codec; |
777 | struct snd_soc_codec *codec = socdev->card->codec; | ||
778 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); | 779 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); |
779 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; | 780 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; |
780 | u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; | 781 | u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; |
@@ -1101,8 +1102,8 @@ static struct snd_soc_dai_ops aic3x_dai_ops = { | |||
1101 | .set_fmt = aic3x_set_dai_fmt, | 1102 | .set_fmt = aic3x_set_dai_fmt, |
1102 | }; | 1103 | }; |
1103 | 1104 | ||
1104 | struct snd_soc_dai aic3x_dai = { | 1105 | static struct snd_soc_dai_driver aic3x_dai = { |
1105 | .name = "tlv320aic3x", | 1106 | .name = "tlv320aic3x-hifi", |
1106 | .playback = { | 1107 | .playback = { |
1107 | .stream_name = "Playback", | 1108 | .stream_name = "Playback", |
1108 | .channels_min = 1, | 1109 | .channels_min = 1, |
@@ -1117,22 +1118,16 @@ struct snd_soc_dai aic3x_dai = { | |||
1117 | .formats = AIC3X_FORMATS,}, | 1118 | .formats = AIC3X_FORMATS,}, |
1118 | .ops = &aic3x_dai_ops, | 1119 | .ops = &aic3x_dai_ops, |
1119 | }; | 1120 | }; |
1120 | EXPORT_SYMBOL_GPL(aic3x_dai); | ||
1121 | 1121 | ||
1122 | static int aic3x_suspend(struct platform_device *pdev, pm_message_t state) | 1122 | static int aic3x_suspend(struct snd_soc_codec *codec, pm_message_t state) |
1123 | { | 1123 | { |
1124 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1125 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1126 | |||
1127 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1124 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1128 | 1125 | ||
1129 | return 0; | 1126 | return 0; |
1130 | } | 1127 | } |
1131 | 1128 | ||
1132 | static int aic3x_resume(struct platform_device *pdev) | 1129 | static int aic3x_resume(struct snd_soc_codec *codec) |
1133 | { | 1130 | { |
1134 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1135 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1136 | int i; | 1131 | int i; |
1137 | u8 data[2]; | 1132 | u8 data[2]; |
1138 | u8 *cache = codec->reg_cache; | 1133 | u8 *cache = codec->reg_cache; |
@@ -1157,22 +1152,6 @@ static int aic3x_init(struct snd_soc_codec *codec) | |||
1157 | { | 1152 | { |
1158 | int reg; | 1153 | int reg; |
1159 | 1154 | ||
1160 | mutex_init(&codec->mutex); | ||
1161 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
1162 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
1163 | |||
1164 | codec->name = "tlv320aic3x"; | ||
1165 | codec->owner = THIS_MODULE; | ||
1166 | codec->read = aic3x_read_reg_cache; | ||
1167 | codec->write = aic3x_write; | ||
1168 | codec->set_bias_level = aic3x_set_bias_level; | ||
1169 | codec->dai = &aic3x_dai; | ||
1170 | codec->num_dai = 1; | ||
1171 | codec->reg_cache_size = ARRAY_SIZE(aic3x_reg); | ||
1172 | codec->reg_cache = kmemdup(aic3x_reg, sizeof(aic3x_reg), GFP_KERNEL); | ||
1173 | if (codec->reg_cache == NULL) | ||
1174 | return -ENOMEM; | ||
1175 | |||
1176 | aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); | 1155 | aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); |
1177 | aic3x_write(codec, AIC3X_RESET, SOFT_RESET); | 1156 | aic3x_write(codec, AIC3X_RESET, SOFT_RESET); |
1178 | 1157 | ||
@@ -1245,56 +1224,50 @@ static int aic3x_init(struct snd_soc_codec *codec) | |||
1245 | return 0; | 1224 | return 0; |
1246 | } | 1225 | } |
1247 | 1226 | ||
1248 | static struct snd_soc_codec *aic3x_codec; | 1227 | static int aic3x_probe(struct snd_soc_codec *codec) |
1249 | |||
1250 | static int aic3x_register(struct snd_soc_codec *codec) | ||
1251 | { | 1228 | { |
1252 | int ret; | 1229 | struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); |
1230 | |||
1231 | codec->hw_write = (hw_write_t) i2c_master_send; | ||
1232 | codec->control_data = aic3x->control_data; | ||
1253 | 1233 | ||
1254 | ret = aic3x_init(codec); | 1234 | if (aic3x->setup) { |
1255 | if (ret < 0) { | 1235 | /* setup GPIO functions */ |
1256 | dev_err(codec->dev, "Failed to initialise device\n"); | 1236 | aic3x_write(codec, AIC3X_GPIO1_REG, |
1257 | return ret; | 1237 | (aic3x->setup->gpio_func[0] & 0xf) << 4); |
1238 | aic3x_write(codec, AIC3X_GPIO2_REG, | ||
1239 | (aic3x->setup->gpio_func[1] & 0xf) << 4); | ||
1258 | } | 1240 | } |
1259 | 1241 | ||
1260 | aic3x_codec = codec; | 1242 | aic3x_init(codec); |
1261 | 1243 | ||
1262 | ret = snd_soc_register_codec(codec); | 1244 | snd_soc_add_controls(codec, aic3x_snd_controls, |
1263 | if (ret) { | 1245 | ARRAY_SIZE(aic3x_snd_controls)); |
1264 | dev_err(codec->dev, "Failed to register codec\n"); | ||
1265 | return ret; | ||
1266 | } | ||
1267 | 1246 | ||
1268 | ret = snd_soc_register_dai(&aic3x_dai); | 1247 | aic3x_add_widgets(codec); |
1269 | if (ret) { | ||
1270 | dev_err(codec->dev, "Failed to register dai\n"); | ||
1271 | snd_soc_unregister_codec(codec); | ||
1272 | return ret; | ||
1273 | } | ||
1274 | 1248 | ||
1275 | return 0; | 1249 | return 0; |
1276 | } | 1250 | } |
1277 | 1251 | ||
1278 | static int aic3x_unregister(struct aic3x_priv *aic3x) | 1252 | static int aic3x_remove(struct snd_soc_codec *codec) |
1279 | { | 1253 | { |
1280 | aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF); | 1254 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1281 | |||
1282 | snd_soc_unregister_dai(&aic3x_dai); | ||
1283 | snd_soc_unregister_codec(&aic3x->codec); | ||
1284 | |||
1285 | if (aic3x->gpio_reset >= 0) { | ||
1286 | gpio_set_value(aic3x->gpio_reset, 0); | ||
1287 | gpio_free(aic3x->gpio_reset); | ||
1288 | } | ||
1289 | regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); | ||
1290 | regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); | ||
1291 | |||
1292 | kfree(aic3x); | ||
1293 | aic3x_codec = NULL; | ||
1294 | |||
1295 | return 0; | 1255 | return 0; |
1296 | } | 1256 | } |
1297 | 1257 | ||
1258 | static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | ||
1259 | .read = aic3x_read_reg_cache, | ||
1260 | .write = aic3x_write, | ||
1261 | .set_bias_level = aic3x_set_bias_level, | ||
1262 | .reg_cache_size = ARRAY_SIZE(aic3x_reg), | ||
1263 | .reg_word_size = sizeof(u8), | ||
1264 | .reg_cache_default = aic3x_reg, | ||
1265 | .probe = aic3x_probe, | ||
1266 | .remove = aic3x_remove, | ||
1267 | .suspend = aic3x_suspend, | ||
1268 | .resume = aic3x_resume, | ||
1269 | }; | ||
1270 | |||
1298 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1271 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1299 | /* | 1272 | /* |
1300 | * AIC3X 2 wire address can be up to 4 devices with device addresses | 1273 | * AIC3X 2 wire address can be up to 4 devices with device addresses |
@@ -1308,9 +1281,9 @@ static int aic3x_unregister(struct aic3x_priv *aic3x) | |||
1308 | static int aic3x_i2c_probe(struct i2c_client *i2c, | 1281 | static int aic3x_i2c_probe(struct i2c_client *i2c, |
1309 | const struct i2c_device_id *id) | 1282 | const struct i2c_device_id *id) |
1310 | { | 1283 | { |
1311 | struct snd_soc_codec *codec; | ||
1312 | struct aic3x_priv *aic3x; | ||
1313 | struct aic3x_pdata *pdata = i2c->dev.platform_data; | 1284 | struct aic3x_pdata *pdata = i2c->dev.platform_data; |
1285 | struct aic3x_setup_data *setup = pdata->setup; | ||
1286 | struct aic3x_priv *aic3x; | ||
1314 | int ret, i; | 1287 | int ret, i; |
1315 | 1288 | ||
1316 | aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); | 1289 | aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); |
@@ -1319,12 +1292,8 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1319 | return -ENOMEM; | 1292 | return -ENOMEM; |
1320 | } | 1293 | } |
1321 | 1294 | ||
1322 | codec = &aic3x->codec; | 1295 | aic3x->control_data = i2c; |
1323 | codec->dev = &i2c->dev; | 1296 | aic3x->setup = setup; |
1324 | snd_soc_codec_set_drvdata(codec, aic3x); | ||
1325 | codec->control_data = i2c; | ||
1326 | codec->hw_write = (hw_write_t) i2c_master_send; | ||
1327 | |||
1328 | i2c_set_clientdata(i2c, aic3x); | 1297 | i2c_set_clientdata(i2c, aic3x); |
1329 | 1298 | ||
1330 | aic3x->gpio_reset = -1; | 1299 | aic3x->gpio_reset = -1; |
@@ -1339,17 +1308,17 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1339 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) | 1308 | for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) |
1340 | aic3x->supplies[i].supply = aic3x_supply_names[i]; | 1309 | aic3x->supplies[i].supply = aic3x_supply_names[i]; |
1341 | 1310 | ||
1342 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies), | 1311 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(aic3x->supplies), |
1343 | aic3x->supplies); | 1312 | aic3x->supplies); |
1344 | if (ret != 0) { | 1313 | if (ret != 0) { |
1345 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 1314 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); |
1346 | goto err_get; | 1315 | goto err_get; |
1347 | } | 1316 | } |
1348 | 1317 | ||
1349 | ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies), | 1318 | ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies), |
1350 | aic3x->supplies); | 1319 | aic3x->supplies); |
1351 | if (ret != 0) { | 1320 | if (ret != 0) { |
1352 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 1321 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); |
1353 | goto err_enable; | 1322 | goto err_enable; |
1354 | } | 1323 | } |
1355 | 1324 | ||
@@ -1358,7 +1327,11 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1358 | gpio_set_value(aic3x->gpio_reset, 1); | 1327 | gpio_set_value(aic3x->gpio_reset, 1); |
1359 | } | 1328 | } |
1360 | 1329 | ||
1361 | return aic3x_register(codec); | 1330 | ret = snd_soc_register_codec(&i2c->dev, |
1331 | &soc_codec_dev_aic3x, &aic3x_dai, 1); | ||
1332 | if (ret < 0) | ||
1333 | goto err_enable; | ||
1334 | return ret; | ||
1362 | 1335 | ||
1363 | err_enable: | 1336 | err_enable: |
1364 | regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); | 1337 | regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); |
@@ -1374,7 +1347,16 @@ static int aic3x_i2c_remove(struct i2c_client *client) | |||
1374 | { | 1347 | { |
1375 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); | 1348 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); |
1376 | 1349 | ||
1377 | return aic3x_unregister(aic3x); | 1350 | if (aic3x->gpio_reset >= 0) { |
1351 | gpio_set_value(aic3x->gpio_reset, 0); | ||
1352 | gpio_free(aic3x->gpio_reset); | ||
1353 | } | ||
1354 | regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); | ||
1355 | regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); | ||
1356 | |||
1357 | snd_soc_unregister_codec(&client->dev); | ||
1358 | kfree(i2c_get_clientdata(client)); | ||
1359 | return 0; | ||
1378 | } | 1360 | } |
1379 | 1361 | ||
1380 | static const struct i2c_device_id aic3x_i2c_id[] = { | 1362 | static const struct i2c_device_id aic3x_i2c_id[] = { |
@@ -1387,7 +1369,7 @@ MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); | |||
1387 | /* machine i2c codec control layer */ | 1369 | /* machine i2c codec control layer */ |
1388 | static struct i2c_driver aic3x_i2c_driver = { | 1370 | static struct i2c_driver aic3x_i2c_driver = { |
1389 | .driver = { | 1371 | .driver = { |
1390 | .name = "aic3x I2C Codec", | 1372 | .name = "tlv320aic3x-codec", |
1391 | .owner = THIS_MODULE, | 1373 | .owner = THIS_MODULE, |
1392 | }, | 1374 | }, |
1393 | .probe = aic3x_i2c_probe, | 1375 | .probe = aic3x_i2c_probe, |
@@ -1409,90 +1391,27 @@ static inline void aic3x_i2c_exit(void) | |||
1409 | { | 1391 | { |
1410 | i2c_del_driver(&aic3x_i2c_driver); | 1392 | i2c_del_driver(&aic3x_i2c_driver); |
1411 | } | 1393 | } |
1412 | #else | ||
1413 | static inline void aic3x_i2c_init(void) { } | ||
1414 | static inline void aic3x_i2c_exit(void) { } | ||
1415 | #endif | 1394 | #endif |
1416 | 1395 | ||
1417 | static int aic3x_probe(struct platform_device *pdev) | 1396 | static int __init aic3x_modinit(void) |
1418 | { | 1397 | { |
1419 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1420 | struct aic3x_setup_data *setup; | ||
1421 | struct snd_soc_codec *codec; | ||
1422 | int ret = 0; | 1398 | int ret = 0; |
1423 | 1399 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | |
1424 | codec = aic3x_codec; | 1400 | ret = i2c_add_driver(&aic3x_i2c_driver); |
1425 | if (!codec) { | 1401 | if (ret != 0) { |
1426 | dev_err(&pdev->dev, "Codec not registered\n"); | 1402 | printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n", |
1427 | return -ENODEV; | 1403 | ret); |
1428 | } | ||
1429 | |||
1430 | socdev->card->codec = codec; | ||
1431 | setup = socdev->codec_data; | ||
1432 | |||
1433 | if (setup) { | ||
1434 | /* setup GPIO functions */ | ||
1435 | aic3x_write(codec, AIC3X_GPIO1_REG, | ||
1436 | (setup->gpio_func[0] & 0xf) << 4); | ||
1437 | aic3x_write(codec, AIC3X_GPIO2_REG, | ||
1438 | (setup->gpio_func[1] & 0xf) << 4); | ||
1439 | } | ||
1440 | |||
1441 | /* register pcms */ | ||
1442 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
1443 | if (ret < 0) { | ||
1444 | printk(KERN_ERR "aic3x: failed to create pcms\n"); | ||
1445 | goto pcm_err; | ||
1446 | } | 1404 | } |
1447 | 1405 | #endif | |
1448 | snd_soc_add_controls(codec, aic3x_snd_controls, | ||
1449 | ARRAY_SIZE(aic3x_snd_controls)); | ||
1450 | |||
1451 | aic3x_add_widgets(codec); | ||
1452 | |||
1453 | return ret; | ||
1454 | |||
1455 | pcm_err: | ||
1456 | kfree(codec->reg_cache); | ||
1457 | return ret; | 1406 | return ret; |
1458 | } | 1407 | } |
1459 | |||
1460 | static int aic3x_remove(struct platform_device *pdev) | ||
1461 | { | ||
1462 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1463 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1464 | |||
1465 | /* power down chip */ | ||
1466 | if (codec->control_data) | ||
1467 | aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1468 | |||
1469 | snd_soc_free_pcms(socdev); | ||
1470 | snd_soc_dapm_free(socdev); | ||
1471 | |||
1472 | kfree(codec->reg_cache); | ||
1473 | |||
1474 | return 0; | ||
1475 | } | ||
1476 | |||
1477 | struct snd_soc_codec_device soc_codec_dev_aic3x = { | ||
1478 | .probe = aic3x_probe, | ||
1479 | .remove = aic3x_remove, | ||
1480 | .suspend = aic3x_suspend, | ||
1481 | .resume = aic3x_resume, | ||
1482 | }; | ||
1483 | EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x); | ||
1484 | |||
1485 | static int __init aic3x_modinit(void) | ||
1486 | { | ||
1487 | aic3x_i2c_init(); | ||
1488 | |||
1489 | return 0; | ||
1490 | } | ||
1491 | module_init(aic3x_modinit); | 1408 | module_init(aic3x_modinit); |
1492 | 1409 | ||
1493 | static void __exit aic3x_exit(void) | 1410 | static void __exit aic3x_exit(void) |
1494 | { | 1411 | { |
1495 | aic3x_i2c_exit(); | 1412 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1413 | i2c_del_driver(&aic3x_i2c_driver); | ||
1414 | #endif | ||
1496 | } | 1415 | } |
1497 | module_exit(aic3x_exit); | 1416 | module_exit(aic3x_exit); |
1498 | 1417 | ||