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.c113
1 files changed, 57 insertions, 56 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5f9abb199435..05336ed7e493 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC TLV320AIC3X codec driver 2 * ALSA SoC TLV320AIC3X codec driver
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@ru.mvista.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * 6 *
7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood 7 * Based on sound/soc/codecs/wm8753.c by Liam Girdwood
@@ -48,7 +48,6 @@
48 48
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.2" 51#define AIC3X_VERSION "0.2"
53 52
54/* codec private data */ 53/* codec private data */
@@ -991,7 +990,7 @@ EXPORT_SYMBOL_GPL(aic3x_headset_detected);
991 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 990 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
992 991
993struct snd_soc_dai aic3x_dai = { 992struct snd_soc_dai aic3x_dai = {
994 .name = "aic3x", 993 .name = "tlv320aic3x",
995 .playback = { 994 .playback = {
996 .stream_name = "Playback", 995 .stream_name = "Playback",
997 .channels_min = 1, 996 .channels_min = 1,
@@ -1055,7 +1054,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1055 struct aic3x_setup_data *setup = socdev->codec_data; 1054 struct aic3x_setup_data *setup = socdev->codec_data;
1056 int reg, ret = 0; 1055 int reg, ret = 0;
1057 1056
1058 codec->name = "aic3x"; 1057 codec->name = "tlv320aic3x";
1059 codec->owner = THIS_MODULE; 1058 codec->owner = THIS_MODULE;
1060 codec->read = aic3x_read_reg_cache; 1059 codec->read = aic3x_read_reg_cache;
1061 codec->write = aic3x_write; 1060 codec->write = aic3x_write;
@@ -1172,71 +1171,39 @@ static struct snd_soc_device *aic3x_socdev;
1172 * AIC3X 2 wire address can be up to 4 devices with device addresses 1171 * AIC3X 2 wire address can be up to 4 devices with device addresses
1173 * 0x18, 0x19, 0x1A, 0x1B 1172 * 0x18, 0x19, 0x1A, 0x1B
1174 */ 1173 */
1175static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
1176
1177/* Magic definition of all other variables and things */
1178I2C_CLIENT_INSMOD;
1179
1180static struct i2c_driver aic3x_i2c_driver;
1181static struct i2c_client client_template;
1182 1174
1183/* 1175/*
1184 * If the i2c layer weren't so broken, we could pass this kind of data 1176 * If the i2c layer weren't so broken, we could pass this kind of data
1185 * around 1177 * around
1186 */ 1178 */
1187static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) 1179static int aic3x_i2c_probe(struct i2c_client *i2c,
1180 const struct i2c_device_id *id)
1188{ 1181{
1189 struct snd_soc_device *socdev = aic3x_socdev; 1182 struct snd_soc_device *socdev = aic3x_socdev;
1190 struct aic3x_setup_data *setup = socdev->codec_data;
1191 struct snd_soc_codec *codec = socdev->codec; 1183 struct snd_soc_codec *codec = socdev->codec;
1192 struct i2c_client *i2c;
1193 int ret; 1184 int ret;
1194 1185
1195 if (addr != setup->i2c_address)
1196 return -ENODEV;
1197
1198 client_template.adapter = adap;
1199 client_template.addr = addr;
1200
1201 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1202 if (i2c == NULL)
1203 return -ENOMEM;
1204
1205 i2c_set_clientdata(i2c, codec); 1186 i2c_set_clientdata(i2c, codec);
1206 codec->control_data = i2c; 1187 codec->control_data = i2c;
1207 1188
1208 ret = i2c_attach_client(i2c);
1209 if (ret < 0) {
1210 printk(KERN_ERR "aic3x: failed to attach codec at addr %x\n",
1211 addr);
1212 goto err;
1213 }
1214
1215 ret = aic3x_init(socdev); 1189 ret = aic3x_init(socdev);
1216 if (ret < 0) { 1190 if (ret < 0)
1217 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); 1191 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n");
1218 goto err;
1219 }
1220 return ret;
1221
1222err:
1223 kfree(i2c);
1224 return ret; 1192 return ret;
1225} 1193}
1226 1194
1227static int aic3x_i2c_detach(struct i2c_client *client) 1195static int aic3x_i2c_remove(struct i2c_client *client)
1228{ 1196{
1229 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1197 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1230 i2c_detach_client(client);
1231 kfree(codec->reg_cache); 1198 kfree(codec->reg_cache);
1232 kfree(client);
1233 return 0; 1199 return 0;
1234} 1200}
1235 1201
1236static int aic3x_i2c_attach(struct i2c_adapter *adap) 1202static const struct i2c_device_id aic3x_i2c_id[] = {
1237{ 1203 { "tlv320aic3x", 0 },
1238 return i2c_probe(adap, &addr_data, aic3x_codec_probe); 1204 { }
1239} 1205};
1206MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1240 1207
1241/* machine i2c codec control layer */ 1208/* machine i2c codec control layer */
1242static struct i2c_driver aic3x_i2c_driver = { 1209static struct i2c_driver aic3x_i2c_driver = {
@@ -1244,13 +1211,9 @@ static struct i2c_driver aic3x_i2c_driver = {
1244 .name = "aic3x I2C Codec", 1211 .name = "aic3x I2C Codec",
1245 .owner = THIS_MODULE, 1212 .owner = THIS_MODULE,
1246 }, 1213 },
1247 .attach_adapter = aic3x_i2c_attach, 1214 .probe = aic3x_i2c_probe,
1248 .detach_client = aic3x_i2c_detach, 1215 .remove = aic3x_i2c_remove,
1249}; 1216 .id_table = aic3x_i2c_id,
1250
1251static struct i2c_client client_template = {
1252 .name = "AIC3X",
1253 .driver = &aic3x_i2c_driver,
1254}; 1217};
1255 1218
1256static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) 1219static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
@@ -1258,6 +1221,46 @@ static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len)
1258 value[0] = i2c_smbus_read_byte_data(client, value[0]); 1221 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1259 return (len == 1); 1222 return (len == 1);
1260} 1223}
1224
1225static int aic3x_add_i2c_device(struct platform_device *pdev,
1226 const struct aic3x_setup_data *setup)
1227{
1228 struct i2c_board_info info;
1229 struct i2c_adapter *adapter;
1230 struct i2c_client *client;
1231 int ret;
1232
1233 ret = i2c_add_driver(&aic3x_i2c_driver);
1234 if (ret != 0) {
1235 dev_err(&pdev->dev, "can't add i2c driver\n");
1236 return ret;
1237 }
1238
1239 memset(&info, 0, sizeof(struct i2c_board_info));
1240 info.addr = setup->i2c_address;
1241 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1242
1243 adapter = i2c_get_adapter(setup->i2c_bus);
1244 if (!adapter) {
1245 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1246 setup->i2c_bus);
1247 goto err_driver;
1248 }
1249
1250 client = i2c_new_device(adapter, &info);
1251 i2c_put_adapter(adapter);
1252 if (!client) {
1253 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1254 (unsigned int)info.addr);
1255 goto err_driver;
1256 }
1257
1258 return 0;
1259
1260err_driver:
1261 i2c_del_driver(&aic3x_i2c_driver);
1262 return -ENODEV;
1263}
1261#endif 1264#endif
1262 1265
1263static int aic3x_probe(struct platform_device *pdev) 1266static int aic3x_probe(struct platform_device *pdev)
@@ -1290,12 +1293,9 @@ static int aic3x_probe(struct platform_device *pdev)
1290 aic3x_socdev = socdev; 1293 aic3x_socdev = socdev;
1291#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1294#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1292 if (setup->i2c_address) { 1295 if (setup->i2c_address) {
1293 normal_i2c[0] = setup->i2c_address;
1294 codec->hw_write = (hw_write_t) i2c_master_send; 1296 codec->hw_write = (hw_write_t) i2c_master_send;
1295 codec->hw_read = (hw_read_t) aic3x_i2c_read; 1297 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1296 ret = i2c_add_driver(&aic3x_i2c_driver); 1298 ret = aic3x_add_i2c_device(pdev, setup);
1297 if (ret != 0)
1298 printk(KERN_ERR "can't add i2c driver");
1299 } 1299 }
1300#else 1300#else
1301 /* Add other interfaces here */ 1301 /* Add other interfaces here */
@@ -1320,6 +1320,7 @@ static int aic3x_remove(struct platform_device *pdev)
1320 snd_soc_free_pcms(socdev); 1320 snd_soc_free_pcms(socdev);
1321 snd_soc_dapm_free(socdev); 1321 snd_soc_dapm_free(socdev);
1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1322#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1323 i2c_unregister_device(codec->control_data);
1323 i2c_del_driver(&aic3x_i2c_driver); 1324 i2c_del_driver(&aic3x_i2c_driver);
1324#endif 1325#endif
1325 kfree(codec->private_data); 1326 kfree(codec->private_data);