diff options
Diffstat (limited to 'sound/soc/codecs/tlv320aic3x.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 108 |
1 files changed, 55 insertions, 53 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 5f9abb199435..566a427c928f 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 |
@@ -1172,71 +1172,39 @@ static struct snd_soc_device *aic3x_socdev; | |||
1172 | * AIC3X 2 wire address can be up to 4 devices with device addresses | 1172 | * AIC3X 2 wire address can be up to 4 devices with device addresses |
1173 | * 0x18, 0x19, 0x1A, 0x1B | 1173 | * 0x18, 0x19, 0x1A, 0x1B |
1174 | */ | 1174 | */ |
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 | 1175 | ||
1183 | /* | 1176 | /* |
1184 | * If the i2c layer weren't so broken, we could pass this kind of data | 1177 | * If the i2c layer weren't so broken, we could pass this kind of data |
1185 | * around | 1178 | * around |
1186 | */ | 1179 | */ |
1187 | static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) | 1180 | static int aic3x_i2c_probe(struct i2c_client *i2c, |
1181 | const struct i2c_device_id *id) | ||
1188 | { | 1182 | { |
1189 | struct snd_soc_device *socdev = aic3x_socdev; | 1183 | struct snd_soc_device *socdev = aic3x_socdev; |
1190 | struct aic3x_setup_data *setup = socdev->codec_data; | ||
1191 | struct snd_soc_codec *codec = socdev->codec; | 1184 | struct snd_soc_codec *codec = socdev->codec; |
1192 | struct i2c_client *i2c; | ||
1193 | int ret; | 1185 | int ret; |
1194 | 1186 | ||
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); | 1187 | i2c_set_clientdata(i2c, codec); |
1206 | codec->control_data = i2c; | 1188 | codec->control_data = i2c; |
1207 | 1189 | ||
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); | 1190 | ret = aic3x_init(socdev); |
1216 | if (ret < 0) { | 1191 | if (ret < 0) |
1217 | printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); | 1192 | 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; | 1193 | return ret; |
1225 | } | 1194 | } |
1226 | 1195 | ||
1227 | static int aic3x_i2c_detach(struct i2c_client *client) | 1196 | static int aic3x_i2c_remove(struct i2c_client *client) |
1228 | { | 1197 | { |
1229 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 1198 | struct snd_soc_codec *codec = i2c_get_clientdata(client); |
1230 | i2c_detach_client(client); | ||
1231 | kfree(codec->reg_cache); | 1199 | kfree(codec->reg_cache); |
1232 | kfree(client); | ||
1233 | return 0; | 1200 | return 0; |
1234 | } | 1201 | } |
1235 | 1202 | ||
1236 | static int aic3x_i2c_attach(struct i2c_adapter *adap) | 1203 | static const struct i2c_device_id aic3x_i2c_id[] = { |
1237 | { | 1204 | { "tlv320aic3x", 0 }, |
1238 | return i2c_probe(adap, &addr_data, aic3x_codec_probe); | 1205 | { } |
1239 | } | 1206 | }; |
1207 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); | ||
1240 | 1208 | ||
1241 | /* machine i2c codec control layer */ | 1209 | /* machine i2c codec control layer */ |
1242 | static struct i2c_driver aic3x_i2c_driver = { | 1210 | static struct i2c_driver aic3x_i2c_driver = { |
@@ -1244,13 +1212,9 @@ static struct i2c_driver aic3x_i2c_driver = { | |||
1244 | .name = "aic3x I2C Codec", | 1212 | .name = "aic3x I2C Codec", |
1245 | .owner = THIS_MODULE, | 1213 | .owner = THIS_MODULE, |
1246 | }, | 1214 | }, |
1247 | .attach_adapter = aic3x_i2c_attach, | 1215 | .probe = aic3x_i2c_probe, |
1248 | .detach_client = aic3x_i2c_detach, | 1216 | .remove = aic3x_i2c_remove, |
1249 | }; | 1217 | .id_table = aic3x_i2c_id, |
1250 | |||
1251 | static struct i2c_client client_template = { | ||
1252 | .name = "AIC3X", | ||
1253 | .driver = &aic3x_i2c_driver, | ||
1254 | }; | 1218 | }; |
1255 | 1219 | ||
1256 | static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) | 1220 | static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) |
@@ -1258,6 +1222,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]); | 1222 | value[0] = i2c_smbus_read_byte_data(client, value[0]); |
1259 | return (len == 1); | 1223 | return (len == 1); |
1260 | } | 1224 | } |
1225 | |||
1226 | static int aic3x_add_i2c_device(struct platform_device *pdev, | ||
1227 | const struct aic3x_setup_data *setup) | ||
1228 | { | ||
1229 | struct i2c_board_info info; | ||
1230 | struct i2c_adapter *adapter; | ||
1231 | struct i2c_client *client; | ||
1232 | int ret; | ||
1233 | |||
1234 | ret = i2c_add_driver(&aic3x_i2c_driver); | ||
1235 | if (ret != 0) { | ||
1236 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
1237 | return ret; | ||
1238 | } | ||
1239 | |||
1240 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
1241 | info.addr = setup->i2c_address; | ||
1242 | strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE); | ||
1243 | |||
1244 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
1245 | if (!adapter) { | ||
1246 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
1247 | setup->i2c_bus); | ||
1248 | goto err_driver; | ||
1249 | } | ||
1250 | |||
1251 | client = i2c_new_device(adapter, &info); | ||
1252 | i2c_put_adapter(adapter); | ||
1253 | if (!client) { | ||
1254 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
1255 | (unsigned int)info.addr); | ||
1256 | goto err_driver; | ||
1257 | } | ||
1258 | |||
1259 | return 0; | ||
1260 | |||
1261 | err_driver: | ||
1262 | i2c_del_driver(&aic3x_i2c_driver); | ||
1263 | return -ENODEV; | ||
1264 | } | ||
1261 | #endif | 1265 | #endif |
1262 | 1266 | ||
1263 | static int aic3x_probe(struct platform_device *pdev) | 1267 | static int aic3x_probe(struct platform_device *pdev) |
@@ -1290,12 +1294,9 @@ static int aic3x_probe(struct platform_device *pdev) | |||
1290 | aic3x_socdev = socdev; | 1294 | aic3x_socdev = socdev; |
1291 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1295 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1292 | if (setup->i2c_address) { | 1296 | if (setup->i2c_address) { |
1293 | normal_i2c[0] = setup->i2c_address; | ||
1294 | codec->hw_write = (hw_write_t) i2c_master_send; | 1297 | codec->hw_write = (hw_write_t) i2c_master_send; |
1295 | codec->hw_read = (hw_read_t) aic3x_i2c_read; | 1298 | codec->hw_read = (hw_read_t) aic3x_i2c_read; |
1296 | ret = i2c_add_driver(&aic3x_i2c_driver); | 1299 | ret = aic3x_add_i2c_device(pdev, setup); |
1297 | if (ret != 0) | ||
1298 | printk(KERN_ERR "can't add i2c driver"); | ||
1299 | } | 1300 | } |
1300 | #else | 1301 | #else |
1301 | /* Add other interfaces here */ | 1302 | /* Add other interfaces here */ |
@@ -1320,6 +1321,7 @@ static int aic3x_remove(struct platform_device *pdev) | |||
1320 | snd_soc_free_pcms(socdev); | 1321 | snd_soc_free_pcms(socdev); |
1321 | snd_soc_dapm_free(socdev); | 1322 | snd_soc_dapm_free(socdev); |
1322 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1323 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1324 | i2c_unregister_device(codec->control_data); | ||
1323 | i2c_del_driver(&aic3x_i2c_driver); | 1325 | i2c_del_driver(&aic3x_i2c_driver); |
1324 | #endif | 1326 | #endif |
1325 | kfree(codec->private_data); | 1327 | kfree(codec->private_data); |