diff options
Diffstat (limited to 'sound/soc/codecs/tlv320aic26.c')
-rw-r--r-- | sound/soc/codecs/tlv320aic26.c | 180 |
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 | ||
281 | struct snd_soc_dai aic26_dai = { | 279 | static 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 | }; |
299 | EXPORT_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 | */ | ||
324 | static 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 | |||
363 | static 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 | |||
370 | struct snd_soc_codec_device aic26_soc_codec_dev = { | ||
371 | .probe = aic26_probe, | ||
372 | .remove = aic26_remove, | ||
373 | }; | ||
374 | EXPORT_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, | |||
409 | static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set); | 351 | static 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 | */ |
415 | static int aic26_spi_probe(struct spi_device *spi) | 356 | static 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 | ||
488 | static int aic26_spi_remove(struct spi_device *spi) | 394 | static 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 | */ | ||
406 | static 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 | |||
433 | static 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 | ||
498 | static struct spi_driver aic26_spi = { | 440 | static 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, |