diff options
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 244 |
1 files changed, 128 insertions, 116 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index ab099f482487..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 */ |
55 | struct aic3x_priv { | 55 | struct 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; |
@@ -767,6 +768,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, | |||
767 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; | 768 | int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; |
768 | u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; | 769 | u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; |
769 | u16 pll_d = 1; | 770 | u16 pll_d = 1; |
771 | u8 reg; | ||
770 | 772 | ||
771 | /* select data word length */ | 773 | /* select data word length */ |
772 | data = | 774 | data = |
@@ -801,8 +803,16 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, | |||
801 | pll_q &= 0xf; | 803 | pll_q &= 0xf; |
802 | aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT); | 804 | aic3x_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT); |
803 | aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV); | 805 | aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV); |
804 | } else | 806 | /* disable PLL if it is bypassed */ |
807 | reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); | ||
808 | aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE); | ||
809 | |||
810 | } else { | ||
805 | aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV); | 811 | aic3x_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV); |
812 | /* enable PLL when it is used */ | ||
813 | reg = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); | ||
814 | aic3x_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE); | ||
815 | } | ||
806 | 816 | ||
807 | /* Route Left DAC to left channel input and | 817 | /* Route Left DAC to left channel input and |
808 | * right DAC to right channel input */ | 818 | * right DAC to right channel input */ |
@@ -1147,11 +1157,13 @@ static int aic3x_resume(struct platform_device *pdev) | |||
1147 | * initialise the AIC3X driver | 1157 | * initialise the AIC3X driver |
1148 | * register the mixer and dsp interfaces with the kernel | 1158 | * register the mixer and dsp interfaces with the kernel |
1149 | */ | 1159 | */ |
1150 | static int aic3x_init(struct snd_soc_device *socdev) | 1160 | static int aic3x_init(struct snd_soc_codec *codec) |
1151 | { | 1161 | { |
1152 | struct snd_soc_codec *codec = socdev->card->codec; | 1162 | int reg; |
1153 | struct aic3x_setup_data *setup = socdev->codec_data; | 1163 | |
1154 | int reg, ret = 0; | 1164 | mutex_init(&codec->mutex); |
1165 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
1166 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
1155 | 1167 | ||
1156 | codec->name = "tlv320aic3x"; | 1168 | codec->name = "tlv320aic3x"; |
1157 | codec->owner = THIS_MODULE; | 1169 | codec->owner = THIS_MODULE; |
@@ -1168,13 +1180,6 @@ static int aic3x_init(struct snd_soc_device *socdev) | |||
1168 | aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); | 1180 | aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); |
1169 | aic3x_write(codec, AIC3X_RESET, SOFT_RESET); | 1181 | aic3x_write(codec, AIC3X_RESET, SOFT_RESET); |
1170 | 1182 | ||
1171 | /* register pcms */ | ||
1172 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
1173 | if (ret < 0) { | ||
1174 | printk(KERN_ERR "aic3x: failed to create pcms\n"); | ||
1175 | goto pcm_err; | ||
1176 | } | ||
1177 | |||
1178 | /* DAC default volume and mute */ | 1183 | /* DAC default volume and mute */ |
1179 | aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON); | 1184 | aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON); |
1180 | aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON); | 1185 | aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON); |
@@ -1241,30 +1246,51 @@ static int aic3x_init(struct snd_soc_device *socdev) | |||
1241 | /* off, with power on */ | 1246 | /* off, with power on */ |
1242 | aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1247 | aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1243 | 1248 | ||
1244 | /* setup GPIO functions */ | 1249 | return 0; |
1245 | aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); | 1250 | } |
1246 | aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4); | 1251 | |
1252 | static struct snd_soc_codec *aic3x_codec; | ||
1247 | 1253 | ||
1248 | snd_soc_add_controls(codec, aic3x_snd_controls, | 1254 | static int aic3x_register(struct snd_soc_codec *codec) |
1249 | ARRAY_SIZE(aic3x_snd_controls)); | 1255 | { |
1250 | aic3x_add_widgets(codec); | 1256 | int ret; |
1251 | ret = snd_soc_init_card(socdev); | 1257 | |
1258 | ret = aic3x_init(codec); | ||
1252 | if (ret < 0) { | 1259 | if (ret < 0) { |
1253 | printk(KERN_ERR "aic3x: failed to register card\n"); | 1260 | dev_err(codec->dev, "Failed to initialise device\n"); |
1254 | goto card_err; | 1261 | return ret; |
1255 | } | 1262 | } |
1256 | 1263 | ||
1257 | return ret; | 1264 | aic3x_codec = codec; |
1258 | 1265 | ||
1259 | card_err: | 1266 | ret = snd_soc_register_codec(codec); |
1260 | snd_soc_free_pcms(socdev); | 1267 | if (ret) { |
1261 | snd_soc_dapm_free(socdev); | 1268 | dev_err(codec->dev, "Failed to register codec\n"); |
1262 | pcm_err: | 1269 | return ret; |
1263 | kfree(codec->reg_cache); | 1270 | } |
1264 | 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; | ||
1265 | } | 1280 | } |
1266 | 1281 | ||
1267 | static struct snd_soc_device *aic3x_socdev; | 1282 | static 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 | } | ||
1268 | 1294 | ||
1269 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1295 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1270 | /* | 1296 | /* |
@@ -1279,28 +1305,36 @@ static struct snd_soc_device *aic3x_socdev; | |||
1279 | static int aic3x_i2c_probe(struct i2c_client *i2c, | 1305 | static int aic3x_i2c_probe(struct i2c_client *i2c, |
1280 | const struct i2c_device_id *id) | 1306 | const struct i2c_device_id *id) |
1281 | { | 1307 | { |
1282 | struct snd_soc_device *socdev = aic3x_socdev; | 1308 | struct snd_soc_codec *codec; |
1283 | struct snd_soc_codec *codec = socdev->card->codec; | 1309 | struct aic3x_priv *aic3x; |
1284 | int ret; | 1310 | |
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 | } | ||
1285 | 1316 | ||
1286 | i2c_set_clientdata(i2c, codec); | 1317 | codec = &aic3x->codec; |
1318 | codec->dev = &i2c->dev; | ||
1319 | codec->private_data = aic3x; | ||
1287 | codec->control_data = i2c; | 1320 | codec->control_data = i2c; |
1321 | codec->hw_write = (hw_write_t) i2c_master_send; | ||
1288 | 1322 | ||
1289 | ret = aic3x_init(socdev); | 1323 | i2c_set_clientdata(i2c, aic3x); |
1290 | if (ret < 0) | 1324 | |
1291 | printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); | 1325 | return aic3x_register(codec); |
1292 | return ret; | ||
1293 | } | 1326 | } |
1294 | 1327 | ||
1295 | static int aic3x_i2c_remove(struct i2c_client *client) | 1328 | static int aic3x_i2c_remove(struct i2c_client *client) |
1296 | { | 1329 | { |
1297 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 1330 | struct aic3x_priv *aic3x = i2c_get_clientdata(client); |
1298 | kfree(codec->reg_cache); | 1331 | |
1299 | return 0; | 1332 | return aic3x_unregister(aic3x); |
1300 | } | 1333 | } |
1301 | 1334 | ||
1302 | static const struct i2c_device_id aic3x_i2c_id[] = { | 1335 | static const struct i2c_device_id aic3x_i2c_id[] = { |
1303 | { "tlv320aic3x", 0 }, | 1336 | { "tlv320aic3x", 0 }, |
1337 | { "tlv320aic33", 0 }, | ||
1304 | { } | 1338 | { } |
1305 | }; | 1339 | }; |
1306 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); | 1340 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); |
@@ -1311,56 +1345,28 @@ static struct i2c_driver aic3x_i2c_driver = { | |||
1311 | .name = "aic3x I2C Codec", | 1345 | .name = "aic3x I2C Codec", |
1312 | .owner = THIS_MODULE, | 1346 | .owner = THIS_MODULE, |
1313 | }, | 1347 | }, |
1314 | .probe = aic3x_i2c_probe, | 1348 | .probe = aic3x_i2c_probe, |
1315 | .remove = aic3x_i2c_remove, | 1349 | .remove = aic3x_i2c_remove, |
1316 | .id_table = aic3x_i2c_id, | 1350 | .id_table = aic3x_i2c_id, |
1317 | }; | 1351 | }; |
1318 | 1352 | ||
1319 | static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) | 1353 | static inline void aic3x_i2c_init(void) |
1320 | { | ||
1321 | value[0] = i2c_smbus_read_byte_data(client, value[0]); | ||
1322 | return (len == 1); | ||
1323 | } | ||
1324 | |||
1325 | static int aic3x_add_i2c_device(struct platform_device *pdev, | ||
1326 | const struct aic3x_setup_data *setup) | ||
1327 | { | 1354 | { |
1328 | struct i2c_board_info info; | ||
1329 | struct i2c_adapter *adapter; | ||
1330 | struct i2c_client *client; | ||
1331 | int ret; | 1355 | int ret; |
1332 | 1356 | ||
1333 | ret = i2c_add_driver(&aic3x_i2c_driver); | 1357 | ret = i2c_add_driver(&aic3x_i2c_driver); |
1334 | if (ret != 0) { | 1358 | if (ret) |
1335 | dev_err(&pdev->dev, "can't add i2c driver\n"); | 1359 | printk(KERN_ERR "%s: error regsitering i2c driver, %d\n", |
1336 | return ret; | 1360 | __func__, ret); |
1337 | } | 1361 | } |
1338 | |||
1339 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1340 | info.addr = setup->i2c_address; | ||
1341 | strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE); | ||
1342 | |||
1343 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
1344 | if (!adapter) { | ||
1345 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
1346 | setup->i2c_bus); | ||
1347 | goto err_driver; | ||
1348 | } | ||
1349 | |||
1350 | client = i2c_new_device(adapter, &info); | ||
1351 | i2c_put_adapter(adapter); | ||
1352 | if (!client) { | ||
1353 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
1354 | (unsigned int)info.addr); | ||
1355 | goto err_driver; | ||
1356 | } | ||
1357 | |||
1358 | return 0; | ||
1359 | 1362 | ||
1360 | err_driver: | 1363 | static inline void aic3x_i2c_exit(void) |
1364 | { | ||
1361 | i2c_del_driver(&aic3x_i2c_driver); | 1365 | i2c_del_driver(&aic3x_i2c_driver); |
1362 | return -ENODEV; | ||
1363 | } | 1366 | } |
1367 | #else | ||
1368 | static inline void aic3x_i2c_init(void) { } | ||
1369 | static inline void aic3x_i2c_exit(void) { } | ||
1364 | #endif | 1370 | #endif |
1365 | 1371 | ||
1366 | static int aic3x_probe(struct platform_device *pdev) | 1372 | static int aic3x_probe(struct platform_device *pdev) |
@@ -1368,43 +1374,51 @@ static int aic3x_probe(struct platform_device *pdev) | |||
1368 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1374 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1369 | struct aic3x_setup_data *setup; | 1375 | struct aic3x_setup_data *setup; |
1370 | struct snd_soc_codec *codec; | 1376 | struct snd_soc_codec *codec; |
1371 | struct aic3x_priv *aic3x; | ||
1372 | int ret = 0; | 1377 | int ret = 0; |
1373 | 1378 | ||
1374 | 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 | } | ||
1375 | 1384 | ||
1385 | socdev->card->codec = codec; | ||
1376 | setup = socdev->codec_data; | 1386 | setup = socdev->codec_data; |
1377 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
1378 | if (codec == NULL) | ||
1379 | return -ENOMEM; | ||
1380 | 1387 | ||
1381 | aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); | 1388 | if (setup) { |
1382 | if (aic3x == NULL) { | 1389 | /* setup GPIO functions */ |
1383 | kfree(codec); | 1390 | aic3x_write(codec, AIC3X_GPIO1_REG, |
1384 | return -ENOMEM; | 1391 | (setup->gpio_func[0] & 0xf) << 4); |
1392 | aic3x_write(codec, AIC3X_GPIO2_REG, | ||
1393 | (setup->gpio_func[1] & 0xf) << 4); | ||
1385 | } | 1394 | } |
1386 | 1395 | ||
1387 | codec->private_data = aic3x; | 1396 | /* register pcms */ |
1388 | socdev->card->codec = codec; | 1397 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
1389 | mutex_init(&codec->mutex); | 1398 | if (ret < 0) { |
1390 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1399 | printk(KERN_ERR "aic3x: failed to create pcms\n"); |
1391 | INIT_LIST_HEAD(&codec->dapm_paths); | 1400 | goto pcm_err; |
1392 | |||
1393 | aic3x_socdev = socdev; | ||
1394 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1395 | if (setup->i2c_address) { | ||
1396 | codec->hw_write = (hw_write_t) i2c_master_send; | ||
1397 | codec->hw_read = (hw_read_t) aic3x_i2c_read; | ||
1398 | ret = aic3x_add_i2c_device(pdev, setup); | ||
1399 | } | 1401 | } |
1400 | #else | ||
1401 | /* Add other interfaces here */ | ||
1402 | #endif | ||
1403 | 1402 | ||
1404 | if (ret != 0) { | 1403 | snd_soc_add_controls(codec, aic3x_snd_controls, |
1405 | kfree(codec->private_data); | 1404 | ARRAY_SIZE(aic3x_snd_controls)); |
1406 | 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; | ||
1407 | } | 1412 | } |
1413 | |||
1414 | return ret; | ||
1415 | |||
1416 | card_err: | ||
1417 | snd_soc_free_pcms(socdev); | ||
1418 | snd_soc_dapm_free(socdev); | ||
1419 | |||
1420 | pcm_err: | ||
1421 | kfree(codec->reg_cache); | ||
1408 | return ret; | 1422 | return ret; |
1409 | } | 1423 | } |
1410 | 1424 | ||
@@ -1419,12 +1433,8 @@ static int aic3x_remove(struct platform_device *pdev) | |||
1419 | 1433 | ||
1420 | snd_soc_free_pcms(socdev); | 1434 | snd_soc_free_pcms(socdev); |
1421 | snd_soc_dapm_free(socdev); | 1435 | snd_soc_dapm_free(socdev); |
1422 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1436 | |
1423 | i2c_unregister_device(codec->control_data); | 1437 | kfree(codec->reg_cache); |
1424 | i2c_del_driver(&aic3x_i2c_driver); | ||
1425 | #endif | ||
1426 | kfree(codec->private_data); | ||
1427 | kfree(codec); | ||
1428 | 1438 | ||
1429 | return 0; | 1439 | return 0; |
1430 | } | 1440 | } |
@@ -1439,13 +1449,15 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x); | |||
1439 | 1449 | ||
1440 | static int __init aic3x_modinit(void) | 1450 | static int __init aic3x_modinit(void) |
1441 | { | 1451 | { |
1442 | return snd_soc_register_dai(&aic3x_dai); | 1452 | aic3x_i2c_init(); |
1453 | |||
1454 | return 0; | ||
1443 | } | 1455 | } |
1444 | module_init(aic3x_modinit); | 1456 | module_init(aic3x_modinit); |
1445 | 1457 | ||
1446 | static void __exit aic3x_exit(void) | 1458 | static void __exit aic3x_exit(void) |
1447 | { | 1459 | { |
1448 | snd_soc_unregister_dai(&aic3x_dai); | 1460 | aic3x_i2c_exit(); |
1449 | } | 1461 | } |
1450 | module_exit(aic3x_exit); | 1462 | module_exit(aic3x_exit); |
1451 | 1463 | ||