aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic26.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic26.c')
-rw-r--r--sound/soc/codecs/tlv320aic26.c180
1 files changed, 61 insertions, 119 deletions
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index f0e00fd4b435..6b7d71ec0004 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -19,7 +19,6 @@
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h> 21#include <sound/soc-dapm.h>
22#include <sound/soc-of-simple.h>
23#include <sound/initval.h> 22#include <sound/initval.h>
24 23
25#include "tlv320aic26.h" 24#include "tlv320aic26.h"
@@ -130,8 +129,7 @@ static int aic26_hw_params(struct snd_pcm_substream *substream,
130 struct snd_soc_dai *dai) 129 struct snd_soc_dai *dai)
131{ 130{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_device *socdev = rtd->socdev; 132 struct snd_soc_codec *codec = rtd->codec;
134 struct snd_soc_codec *codec = socdev->card->codec;
135 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec); 133 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
136 int fsref, divisor, wlen, pval, jval, dval, qval; 134 int fsref, divisor, wlen, pval, jval, dval, qval;
137 u16 reg; 135 u16 reg;
@@ -278,8 +276,8 @@ static struct snd_soc_dai_ops aic26_dai_ops = {
278 .set_fmt = aic26_set_fmt, 276 .set_fmt = aic26_set_fmt,
279}; 277};
280 278
281struct snd_soc_dai aic26_dai = { 279static struct snd_soc_dai_driver aic26_dai = {
282 .name = "tlv320aic26", 280 .name = "tlv320aic26-hifi",
283 .playback = { 281 .playback = {
284 .stream_name = "Playback", 282 .stream_name = "Playback",
285 .channels_min = 2, 283 .channels_min = 2,
@@ -296,7 +294,6 @@ struct snd_soc_dai aic26_dai = {
296 }, 294 },
297 .ops = &aic26_dai_ops, 295 .ops = &aic26_dai_ops,
298}; 296};
299EXPORT_SYMBOL_GPL(aic26_dai);
300 297
301/* --------------------------------------------------------------------- 298/* ---------------------------------------------------------------------
302 * ALSA controls 299 * ALSA controls
@@ -319,61 +316,6 @@ static const struct snd_kcontrol_new aic26_snd_controls[] = {
319}; 316};
320 317
321/* --------------------------------------------------------------------- 318/* ---------------------------------------------------------------------
322 * SoC CODEC portion of driver: probe and release routines
323 */
324static int aic26_probe(struct platform_device *pdev)
325{
326 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
327 struct snd_soc_codec *codec;
328 struct aic26 *aic26;
329 int ret, err;
330
331 dev_info(&pdev->dev, "Probing AIC26 SoC CODEC driver\n");
332 dev_dbg(&pdev->dev, "socdev=%p\n", socdev);
333 dev_dbg(&pdev->dev, "codec_data=%p\n", socdev->codec_data);
334
335 /* Fetch the relevant aic26 private data here (it's already been
336 * stored in the .codec pointer) */
337 aic26 = socdev->codec_data;
338 if (aic26 == NULL) {
339 dev_err(&pdev->dev, "aic26: missing codec pointer\n");
340 return -ENODEV;
341 }
342 codec = &aic26->codec;
343 socdev->card->codec = codec;
344
345 dev_dbg(&pdev->dev, "Registering PCMs, dev=%p, socdev->dev=%p\n",
346 &pdev->dev, socdev->dev);
347 /* register pcms */
348 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
349 if (ret < 0) {
350 dev_err(&pdev->dev, "aic26: failed to create pcms\n");
351 return -ENODEV;
352 }
353
354 /* register controls */
355 dev_dbg(&pdev->dev, "Registering controls\n");
356 err = snd_soc_add_controls(codec, aic26_snd_controls,
357 ARRAY_SIZE(aic26_snd_controls));
358 WARN_ON(err < 0);
359
360 return 0;
361}
362
363static int aic26_remove(struct platform_device *pdev)
364{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
366 snd_soc_free_pcms(socdev);
367 return 0;
368}
369
370struct snd_soc_codec_device aic26_soc_codec_dev = {
371 .probe = aic26_probe,
372 .remove = aic26_remove,
373};
374EXPORT_SYMBOL_GPL(aic26_soc_codec_dev);
375
376/* ---------------------------------------------------------------------
377 * SPI device portion of driver: sysfs files for debugging 319 * SPI device portion of driver: sysfs files for debugging
378 */ 320 */
379 321
@@ -409,95 +351,95 @@ static ssize_t aic26_keyclick_set(struct device *dev,
409static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set); 351static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
410 352
411/* --------------------------------------------------------------------- 353/* ---------------------------------------------------------------------
412 * SPI device portion of driver: probe and release routines and SPI 354 * SoC CODEC portion of driver: probe and release routines
413 * driver registration.
414 */ 355 */
415static int aic26_spi_probe(struct spi_device *spi) 356static int aic26_probe(struct snd_soc_codec *codec)
416{ 357{
417 struct aic26 *aic26; 358 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
418 int ret, i, reg; 359 int ret, err, i, reg;
419
420 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
421
422 /* Allocate driver data */
423 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
424 if (!aic26)
425 return -ENOMEM;
426
427 /* Initialize the driver data */
428 aic26->spi = spi;
429 dev_set_drvdata(&spi->dev, aic26);
430 360
431 /* Setup what we can in the codec structure so that the register 361 dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
432 * access functions will work as expected. More will be filled
433 * out when it is probed by the SoC CODEC part of this driver */
434 snd_soc_codec_set_drvdata(&aic26->codec, aic26);
435 aic26->codec.name = "aic26";
436 aic26->codec.owner = THIS_MODULE;
437 aic26->codec.dai = &aic26_dai;
438 aic26->codec.num_dai = 1;
439 aic26->codec.read = aic26_reg_read;
440 aic26->codec.write = aic26_reg_write;
441 aic26->master = 1;
442 mutex_init(&aic26->codec.mutex);
443 INIT_LIST_HEAD(&aic26->codec.dapm_widgets);
444 INIT_LIST_HEAD(&aic26->codec.dapm_paths);
445 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
446 aic26->codec.reg_cache = aic26->reg_cache;
447
448 aic26_dai.dev = &spi->dev;
449 ret = snd_soc_register_dai(&aic26_dai);
450 if (ret != 0) {
451 dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
452 kfree(aic26);
453 return ret;
454 }
455 362
456 /* Reset the codec to power on defaults */ 363 /* Reset the codec to power on defaults */
457 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00); 364 aic26_reg_write(codec, AIC26_REG_RESET, 0xBB00);
458 365
459 /* Power up CODEC */ 366 /* Power up CODEC */
460 aic26_reg_write(&aic26->codec, AIC26_REG_POWER_CTRL, 0); 367 aic26_reg_write(codec, AIC26_REG_POWER_CTRL, 0);
461 368
462 /* Audio Control 3 (master mode, fsref rate) */ 369 /* Audio Control 3 (master mode, fsref rate) */
463 reg = aic26_reg_read(&aic26->codec, AIC26_REG_AUDIO_CTRL3); 370 reg = aic26_reg_read(codec, AIC26_REG_AUDIO_CTRL3);
464 reg &= ~0xf800; 371 reg &= ~0xf800;
465 reg |= 0x0800; /* set master mode */ 372 reg |= 0x0800; /* set master mode */
466 aic26_reg_write(&aic26->codec, AIC26_REG_AUDIO_CTRL3, reg); 373 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
467 374
468 /* Fill register cache */ 375 /* Fill register cache */
469 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++) 376 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++)
470 aic26_reg_read(&aic26->codec, i); 377 aic26_reg_read(codec, i);
471 378
472 /* Register the sysfs files for debugging */ 379 /* Register the sysfs files for debugging */
473 /* Create SysFS files */ 380 /* Create SysFS files */
474 ret = device_create_file(&spi->dev, &dev_attr_keyclick); 381 ret = device_create_file(codec->dev, &dev_attr_keyclick);
475 if (ret) 382 if (ret)
476 dev_info(&spi->dev, "error creating sysfs files\n"); 383 dev_info(codec->dev, "error creating sysfs files\n");
477 384
478#if defined(CONFIG_SND_SOC_OF_SIMPLE) 385 /* register controls */
479 /* Tell the of_soc helper about this codec */ 386 dev_dbg(codec->dev, "Registering controls\n");
480 of_snd_soc_register_codec(&aic26_soc_codec_dev, aic26, &aic26_dai, 387 err = snd_soc_add_controls(codec, aic26_snd_controls,
481 spi->dev.archdata.of_node); 388 ARRAY_SIZE(aic26_snd_controls));
482#endif 389 WARN_ON(err < 0);
483 390
484 dev_dbg(&spi->dev, "SPI device initialized\n");
485 return 0; 391 return 0;
486} 392}
487 393
488static int aic26_spi_remove(struct spi_device *spi) 394static struct snd_soc_codec_driver aic26_soc_codec_dev = {
395 .probe = aic26_probe,
396 .read = aic26_reg_read,
397 .write = aic26_reg_write,
398 .reg_cache_size = AIC26_NUM_REGS,
399 .reg_word_size = sizeof(u16),
400};
401
402/* ---------------------------------------------------------------------
403 * SPI device portion of driver: probe and release routines and SPI
404 * driver registration.
405 */
406static int aic26_spi_probe(struct spi_device *spi)
489{ 407{
490 struct aic26 *aic26 = dev_get_drvdata(&spi->dev); 408 struct aic26 *aic26;
409 int ret;
491 410
492 snd_soc_unregister_dai(&aic26_dai); 411 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
493 kfree(aic26); 412
413 /* Allocate driver data */
414 aic26 = kzalloc(sizeof *aic26, GFP_KERNEL);
415 if (!aic26)
416 return -ENOMEM;
494 417
418 /* Initialize the driver data */
419 aic26->spi = spi;
420 dev_set_drvdata(&spi->dev, aic26);
421 aic26->master = 1;
422
423 ret = snd_soc_register_codec(&spi->dev,
424 &aic26_soc_codec_dev, &aic26_dai, 1);
425 if (ret < 0)
426 kfree(aic26);
427 return ret;
428
429 dev_dbg(&spi->dev, "SPI device initialized\n");
430 return 0;
431}
432
433static int aic26_spi_remove(struct spi_device *spi)
434{
435 snd_soc_unregister_codec(&spi->dev);
436 kfree(spi_get_drvdata(spi));
495 return 0; 437 return 0;
496} 438}
497 439
498static struct spi_driver aic26_spi = { 440static struct spi_driver aic26_spi = {
499 .driver = { 441 .driver = {
500 .name = "tlv320aic26", 442 .name = "tlv320aic26-codec",
501 .owner = THIS_MODULE, 443 .owner = THIS_MODULE,
502 }, 444 },
503 .probe = aic26_spi_probe, 445 .probe = aic26_spi_probe,