diff options
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 113 |
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 | ||
993 | struct snd_soc_dai aic3x_dai = { | 992 | struct 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 | */ |
1175 | static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; | ||
1176 | |||
1177 | /* Magic definition of all other variables and things */ | ||
1178 | I2C_CLIENT_INSMOD; | ||
1179 | |||
1180 | static struct i2c_driver aic3x_i2c_driver; | ||
1181 | static 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 | */ |
1187 | static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) | 1179 | static 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 | |||
1222 | err: | ||
1223 | kfree(i2c); | ||
1224 | return ret; | 1192 | return ret; |
1225 | } | 1193 | } |
1226 | 1194 | ||
1227 | static int aic3x_i2c_detach(struct i2c_client *client) | 1195 | static 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 | ||
1236 | static int aic3x_i2c_attach(struct i2c_adapter *adap) | 1202 | static 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 | }; |
1206 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); | ||
1240 | 1207 | ||
1241 | /* machine i2c codec control layer */ | 1208 | /* machine i2c codec control layer */ |
1242 | static struct i2c_driver aic3x_i2c_driver = { | 1209 | static 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 | |||
1251 | static struct i2c_client client_template = { | ||
1252 | .name = "AIC3X", | ||
1253 | .driver = &aic3x_i2c_driver, | ||
1254 | }; | 1217 | }; |
1255 | 1218 | ||
1256 | static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) | 1219 | static 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 | |||
1225 | static 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 | |||
1260 | err_driver: | ||
1261 | i2c_del_driver(&aic3x_i2c_driver); | ||
1262 | return -ENODEV; | ||
1263 | } | ||
1261 | #endif | 1264 | #endif |
1262 | 1265 | ||
1263 | static int aic3x_probe(struct platform_device *pdev) | 1266 | static 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); |