aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/tlv320aic3x.c106
-rw-r--r--sound/soc/codecs/tlv320aic3x.h1
-rw-r--r--sound/soc/davinci/davinci-evm.c1
-rw-r--r--sound/soc/omap/n810.c1
4 files changed, 57 insertions, 52 deletions
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 5f9abb199435..88428e22a4d3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -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 */
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 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 */
1187static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind) 1180static 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
1222err:
1223 kfree(i2c);
1224 return ret; 1193 return ret;
1225} 1194}
1226 1195
1227static int aic3x_i2c_detach(struct i2c_client *client) 1196static 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
1236static int aic3x_i2c_attach(struct i2c_adapter *adap) 1203static 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};
1207MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1240 1208
1241/* machine i2c codec control layer */ 1209/* machine i2c codec control layer */
1242static struct i2c_driver aic3x_i2c_driver = { 1210static 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
1251static struct i2c_client client_template = {
1252 .name = "AIC3X",
1253 .driver = &aic3x_i2c_driver,
1254}; 1218};
1255 1219
1256static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) 1220static 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
1226static 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
1261err_driver:
1262 i2c_del_driver(&aic3x_i2c_driver);
1263 return -ENODEV;
1264}
1261#endif 1265#endif
1262 1266
1263static int aic3x_probe(struct platform_device *pdev) 1267static 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);
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index d76c079b86e7..afb238ec0b9d 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -224,6 +224,7 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 224int aic3x_headset_detected(struct snd_soc_codec *codec);
225 225
226struct aic3x_setup_data { 226struct aic3x_setup_data {
227 int i2c_bus;
227 unsigned short i2c_address; 228 unsigned short i2c_address;
228 unsigned int gpio_func[2]; 229 unsigned int gpio_func[2];
229}; 230};
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 65fdbd81a379..092202302bd8 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -136,6 +136,7 @@ static struct snd_soc_machine snd_soc_machine_evm = {
136 136
137/* evm audio private data */ 137/* evm audio private data */
138static struct aic3x_setup_data evm_aic3x_setup = { 138static struct aic3x_setup_data evm_aic3x_setup = {
139 .i2c_bus = 0,
139 .i2c_address = 0x1b, 140 .i2c_address = 0x1b,
140}; 141};
141 142
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 87d0ed01f65a..d166b6b2a60d 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -290,6 +290,7 @@ static struct snd_soc_machine snd_soc_machine_n810 = {
290 290
291/* Audio private data */ 291/* Audio private data */
292static struct aic3x_setup_data n810_aic33_setup = { 292static struct aic3x_setup_data n810_aic33_setup = {
293 .i2c_bus = 2,
293 .i2c_address = 0x18, 294 .i2c_address = 0x18,
294 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, 295 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
295 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, 296 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,