aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ad193x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ad193x.c')
-rw-r--r--sound/soc/codecs/ad193x.c217
1 files changed, 77 insertions, 140 deletions
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 1def75e4862f..fa2834c91b9f 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -24,9 +24,10 @@
24 24
25/* codec private data */ 25/* codec private data */
26struct ad193x_priv { 26struct ad193x_priv {
27 unsigned int sysclk;
28 struct snd_soc_codec codec;
29 u8 reg_cache[AD193X_NUM_REGS]; 27 u8 reg_cache[AD193X_NUM_REGS];
28 enum snd_soc_control_type bus_type;
29 void *control_data;
30 int sysclk;
30}; 31};
31 32
32/* ad193x register cache & default register settings */ 33/* ad193x register cache & default register settings */
@@ -34,9 +35,6 @@ static const u8 ad193x_reg[AD193X_NUM_REGS] = {
34 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 35 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
35}; 36};
36 37
37static struct snd_soc_codec *ad193x_codec;
38struct snd_soc_codec_device soc_codec_dev_ad193x;
39
40/* 38/*
41 * AD193X volume/mute/de-emphasis etc. controls 39 * AD193X volume/mute/de-emphasis etc. controls
42 */ 40 */
@@ -275,8 +273,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
275 int word_len = 0, reg = 0, master_rate = 0; 273 int word_len = 0, reg = 0, master_rate = 0;
276 274
277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 275 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_device *socdev = rtd->socdev; 276 struct snd_soc_codec *codec = rtd->codec;
279 struct snd_soc_codec *codec = socdev->card->codec;
280 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 277 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
281 278
282 /* bit size */ 279 /* bit size */
@@ -323,100 +320,6 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream,
323 return 0; 320 return 0;
324} 321}
325 322
326static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type)
327{
328 struct snd_soc_codec *codec;
329 struct ad193x_priv *ad193x;
330 int ret;
331
332 if (ad193x_codec) {
333 dev_err(dev, "Another ad193x is registered\n");
334 return -EINVAL;
335 }
336
337 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
338 if (ad193x == NULL)
339 return -ENOMEM;
340
341 dev_set_drvdata(dev, ad193x);
342
343 codec = &ad193x->codec;
344 mutex_init(&codec->mutex);
345 codec->control_data = ctrl_data;
346 codec->dev = dev;
347 snd_soc_codec_set_drvdata(codec, ad193x);
348 codec->reg_cache = ad193x->reg_cache;
349 codec->reg_cache_size = AD193X_NUM_REGS;
350 codec->name = "AD193X";
351 codec->owner = THIS_MODULE;
352 codec->dai = &ad193x_dai;
353 codec->num_dai = 1;
354 INIT_LIST_HEAD(&codec->dapm_widgets);
355 INIT_LIST_HEAD(&codec->dapm_paths);
356
357 ad193x_dai.dev = codec->dev;
358 ad193x_codec = codec;
359
360 memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS);
361
362 if (bus_type == SND_SOC_I2C)
363 ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type);
364 else
365 ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type);
366 if (ret < 0) {
367 dev_err(codec->dev, "failed to set cache I/O: %d\n",
368 ret);
369 kfree(ad193x);
370 return ret;
371 }
372
373 /* default setting for ad193x */
374
375 /* unmute dac channels */
376 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
377 /* de-emphasis: 48kHz, powedown dac */
378 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
379 /* powerdown dac, dac in tdm mode */
380 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
381 /* high-pass filter enable */
382 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
383 /* sata delay=1, adc aux mode */
384 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
385 /* pll input: mclki/xi */
386 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
387 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
388 ad193x->sysclk = 12288000;
389
390 ret = snd_soc_register_codec(codec);
391 if (ret != 0) {
392 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
393 kfree(ad193x);
394 return ret;
395 }
396
397 ret = snd_soc_register_dai(&ad193x_dai);
398 if (ret != 0) {
399 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
400 snd_soc_unregister_codec(codec);
401 kfree(ad193x);
402 return ret;
403 }
404
405 return 0;
406}
407
408static int ad193x_bus_remove(struct device *dev)
409{
410 struct ad193x_priv *ad193x = dev_get_drvdata(dev);
411
412 snd_soc_unregister_dai(&ad193x_dai);
413 snd_soc_unregister_codec(&ad193x->codec);
414 kfree(ad193x);
415 ad193x_codec = NULL;
416
417 return 0;
418}
419
420static struct snd_soc_dai_ops ad193x_dai_ops = { 323static struct snd_soc_dai_ops ad193x_dai_ops = {
421 .hw_params = ad193x_hw_params, 324 .hw_params = ad193x_hw_params,
422 .digital_mute = ad193x_mute, 325 .digital_mute = ad193x_mute,
@@ -426,8 +329,8 @@ static struct snd_soc_dai_ops ad193x_dai_ops = {
426}; 329};
427 330
428/* codec DAI instance */ 331/* codec DAI instance */
429struct snd_soc_dai ad193x_dai = { 332static struct snd_soc_dai_driver ad193x_dai = {
430 .name = "AD193X", 333 .name = "ad193x-hifi",
431 .playback = { 334 .playback = {
432 .stream_name = "Playback", 335 .stream_name = "Playback",
433 .channels_min = 2, 336 .channels_min = 2,
@@ -446,28 +349,39 @@ struct snd_soc_dai ad193x_dai = {
446 }, 349 },
447 .ops = &ad193x_dai_ops, 350 .ops = &ad193x_dai_ops,
448}; 351};
449EXPORT_SYMBOL_GPL(ad193x_dai);
450 352
451static int ad193x_probe(struct platform_device *pdev) 353static int ad193x_probe(struct snd_soc_codec *codec)
452{ 354{
453 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 355 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
454 struct snd_soc_codec *codec; 356 int ret;
455 int ret = 0;
456 357
457 if (ad193x_codec == NULL) { 358 codec->control_data = ad193x->control_data;
458 dev_err(&pdev->dev, "Codec device not registered\n"); 359 if (ad193x->bus_type == SND_SOC_I2C)
459 return -ENODEV; 360 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->bus_type);
361 else
362 ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->bus_type);
363 if (ret < 0) {
364 dev_err(codec->dev, "failed to set cache I/O: %d\n",
365 ret);
366 kfree(ad193x);
367 return ret;
460 } 368 }
461 369
462 socdev->card->codec = ad193x_codec; 370 /* default setting for ad193x */
463 codec = ad193x_codec;
464 371
465 /* register pcms */ 372 /* unmute dac channels */
466 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 373 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0);
467 if (ret < 0) { 374 /* de-emphasis: 48kHz, powedown dac */
468 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 375 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A);
469 goto pcm_err; 376 /* powerdown dac, dac in tdm mode */
470 } 377 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41);
378 /* high-pass filter enable */
379 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3);
380 /* sata delay=1, adc aux mode */
381 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43);
382 /* pll input: mclki/xi */
383 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
384 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04);
471 385
472 snd_soc_add_controls(codec, ad193x_snd_controls, 386 snd_soc_add_controls(codec, ad193x_snd_controls,
473 ARRAY_SIZE(ad193x_snd_controls)); 387 ARRAY_SIZE(ad193x_snd_controls));
@@ -475,41 +389,47 @@ static int ad193x_probe(struct platform_device *pdev)
475 ARRAY_SIZE(ad193x_dapm_widgets)); 389 ARRAY_SIZE(ad193x_dapm_widgets));
476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 390 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
477 391
478pcm_err:
479 return ret; 392 return ret;
480} 393}
481 394
482/* power down chip */ 395static struct snd_soc_codec_driver soc_codec_dev_ad193x = {
483static int ad193x_remove(struct platform_device *pdev)
484{
485 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
486
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489
490 return 0;
491}
492
493struct snd_soc_codec_device soc_codec_dev_ad193x = {
494 .probe = ad193x_probe, 396 .probe = ad193x_probe,
495 .remove = ad193x_remove, 397 .reg_cache_default = ad193x_reg,
398 .reg_cache_size = AD193X_NUM_REGS,
399 .reg_word_size = sizeof(u16),
496}; 400};
497EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x);
498 401
499#if defined(CONFIG_SPI_MASTER) 402#if defined(CONFIG_SPI_MASTER)
500static int __devinit ad193x_spi_probe(struct spi_device *spi) 403static int __devinit ad193x_spi_probe(struct spi_device *spi)
501{ 404{
502 return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI); 405 struct ad193x_priv *ad193x;
406 int ret;
407
408 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
409 if (ad193x == NULL)
410 return -ENOMEM;
411
412 spi_set_drvdata(spi, ad193x);
413 ad193x->control_data = spi;
414 ad193x->bus_type = SND_SOC_SPI;
415
416 ret = snd_soc_register_codec(&spi->dev,
417 &soc_codec_dev_ad193x, &ad193x_dai, 1);
418 if (ret < 0)
419 kfree(ad193x);
420 return ret;
503} 421}
504 422
505static int __devexit ad193x_spi_remove(struct spi_device *spi) 423static int __devexit ad193x_spi_remove(struct spi_device *spi)
506{ 424{
507 return ad193x_bus_remove(&spi->dev); 425 snd_soc_unregister_codec(&spi->dev);
426 kfree(spi_get_drvdata(spi));
427 return 0;
508} 428}
509 429
510static struct spi_driver ad193x_spi_driver = { 430static struct spi_driver ad193x_spi_driver = {
511 .driver = { 431 .driver = {
512 .name = "ad193x", 432 .name = "ad193x-codec",
513 .owner = THIS_MODULE, 433 .owner = THIS_MODULE,
514 }, 434 },
515 .probe = ad193x_spi_probe, 435 .probe = ad193x_spi_probe,
@@ -528,17 +448,34 @@ MODULE_DEVICE_TABLE(i2c, ad193x_id);
528static int __devinit ad193x_i2c_probe(struct i2c_client *client, 448static int __devinit ad193x_i2c_probe(struct i2c_client *client,
529 const struct i2c_device_id *id) 449 const struct i2c_device_id *id)
530{ 450{
531 return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C); 451 struct ad193x_priv *ad193x;
452 int ret;
453
454 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL);
455 if (ad193x == NULL)
456 return -ENOMEM;
457
458 i2c_set_clientdata(client, ad193x);
459 ad193x->control_data = client;
460 ad193x->bus_type = SND_SOC_I2C;
461
462 ret = snd_soc_register_codec(&client->dev,
463 &soc_codec_dev_ad193x, &ad193x_dai, 1);
464 if (ret < 0)
465 kfree(ad193x);
466 return ret;
532} 467}
533 468
534static int __devexit ad193x_i2c_remove(struct i2c_client *client) 469static int __devexit ad193x_i2c_remove(struct i2c_client *client)
535{ 470{
536 return ad193x_bus_remove(&client->dev); 471 snd_soc_unregister_codec(&client->dev);
472 kfree(i2c_get_clientdata(client));
473 return 0;
537} 474}
538 475
539static struct i2c_driver ad193x_i2c_driver = { 476static struct i2c_driver ad193x_i2c_driver = {
540 .driver = { 477 .driver = {
541 .name = "ad193x", 478 .name = "ad193x-codec",
542 }, 479 },
543 .probe = ad193x_i2c_probe, 480 .probe = ad193x_i2c_probe,
544 .remove = __devexit_p(ad193x_i2c_remove), 481 .remove = __devexit_p(ad193x_i2c_remove),