aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/da7210.c
diff options
context:
space:
mode:
authorLiam Girdwood <lrg@slimlogic.co.uk>2010-03-17 16:15:21 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2010-08-12 09:00:00 -0400
commitf0fba2ad1b6b53d5360125c41953b7afcd6deff0 (patch)
treef6ad50905f8daa616593c978d7ae992e73241180 /sound/soc/codecs/da7210.c
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: multi-component - ASoC Multi-Component Support
This patch extends the ASoC API to allow sound cards to have more than one CODEC and more than one platform DMA controller. This is achieved by dividing some current ASoC structures that contain both driver data and device data into structures that only either contain device data or driver data. i.e. struct snd_soc_codec ---> struct snd_soc_codec (device data) +-> struct snd_soc_codec_driver (driver data) struct snd_soc_platform ---> struct snd_soc_platform (device data) +-> struct snd_soc_platform_driver (driver data) struct snd_soc_dai ---> struct snd_soc_dai (device data) +-> struct snd_soc_dai_driver (driver data) struct snd_soc_device ---> deleted This now allows ASoC to be more tightly aligned with the Linux driver model and also means that every ASoC codec, platform and (platform) DAI is a kernel device. ASoC component private data is now stored as device private data. The ASoC sound card struct snd_soc_card has also been updated to store lists of it's components rather than a pointer to a codec and platform. The PCM runtime struct soc_pcm_runtime now has pointers to all its components. This patch adds DAPM support for ASoC multi-component and removes struct snd_soc_socdev from DAPM core. All DAPM calls are now made on a card, codec or runtime PCM level basis rather than using snd_soc_socdev. Other notable multi-component changes:- * Stream operations now de-reference less structures. * close_delayed work() now runs on a DAI basis rather than looping all DAIs in a card. * PM suspend()/resume() operations can now handle N CODECs and Platforms per sound card. * Added soc_bind_dai_link() to bind the component devices to the sound card. * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove DAI link components. * sysfs entries can now be registered per component per card. * snd_soc_new_pcms() functionailty rolled into dai_link_probe(). * snd_soc_register_codec() now does all the codec list and mutex init. This patch changes the probe() and remove() of the CODEC drivers as follows:- o Make CODEC driver a platform driver o Moved all struct snd_soc_codec list, mutex, etc initialiasation to core. o Removed all static codec pointers (drivers now support > 1 codec dev) o snd_soc_register_pcms() now done by core. o snd_soc_register_dai() folded into snd_soc_register_codec(). CS4270 portions: Acked-by: Timur Tabi <timur@freescale.com> Some TLV320aic23 and Cirrus platform fixes. Signed-off-by: Ryan Mallon <ryan@bluewatersys.com> TI CODEC and OMAP fixes Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Signed-off-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Samsung platform and misc fixes :- Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Reviewed-by: Jassi Brar <jassi.brar@samsung.com> Signed-off-by: Seungwhan Youn <sw.youn@samsung.com> MPC8610 and PPC fixes. Signed-off-by: Timur Tabi <timur@freescale.com> i.MX fixes and some core fixes. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> J4740 platform fixes:- Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> CC: Tony Lindgren <tony@atomide.com> CC: Nicolas Ferre <nicolas.ferre@atmel.com> CC: Kevin Hilman <khilman@deeprootsystems.com> CC: Sascha Hauer <s.hauer@pengutronix.de> CC: Atsushi Nemoto <anemo@mba.ocn.ne.jp> CC: Kuninori Morimoto <morimoto.kuninori@renesas.com> CC: Daniel Gloeckner <dg@emlix.com> CC: Manuel Lauss <mano@roarinelk.homelinux.net> CC: Mike Frysinger <vapier.adi@gmail.com> CC: Arnaud Patard <apatard@mandriva.com> CC: Wan ZongShun <mcuos.com@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/da7210.c')
-rw-r--r--sound/soc/codecs/da7210.c157
1 files changed, 32 insertions, 125 deletions
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 3c51d6a57523..eabf3c062500 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -25,8 +25,6 @@
25#include <sound/initval.h> 25#include <sound/initval.h>
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27 27
28#include "da7210.h"
29
30/* DA7210 register space */ 28/* DA7210 register space */
31#define DA7210_STATUS 0x02 29#define DA7210_STATUS 0x02
32#define DA7210_STARTUP1 0x03 30#define DA7210_STARTUP1 0x03
@@ -162,11 +160,10 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = {
162 160
163/* Codec private data */ 161/* Codec private data */
164struct da7210_priv { 162struct da7210_priv {
165 struct snd_soc_codec codec; 163 enum snd_soc_control_type control_type;
164 void *control_data;
166}; 165};
167 166
168static struct snd_soc_codec *da7210_codec;
169
170/* 167/*
171 * Register cache 168 * Register cache
172 */ 169 */
@@ -209,12 +206,12 @@ static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
209 u8 *cache = codec->reg_cache; 206 u8 *cache = codec->reg_cache;
210 u8 data[2]; 207 u8 data[2];
211 208
212 BUG_ON(codec->volatile_register); 209 BUG_ON(codec->driver->volatile_register);
213 210
214 data[0] = reg & 0xff; 211 data[0] = reg & 0xff;
215 data[1] = value & 0xff; 212 data[1] = value & 0xff;
216 213
217 if (reg >= codec->reg_cache_size) 214 if (reg >= codec->driver->reg_cache_size)
218 return -EIO; 215 return -EIO;
219 216
220 if (2 != codec->hw_write(codec->control_data, data, 2)) 217 if (2 != codec->hw_write(codec->control_data, data, 2))
@@ -267,8 +264,7 @@ static int da7210_hw_params(struct snd_pcm_substream *substream,
267 struct snd_soc_dai *dai) 264 struct snd_soc_dai *dai)
268{ 265{
269 struct snd_soc_pcm_runtime *rtd = substream->private_data; 266 struct snd_soc_pcm_runtime *rtd = substream->private_data;
270 struct snd_soc_device *socdev = rtd->socdev; 267 struct snd_soc_codec *codec = rtd->codec;
271 struct snd_soc_codec *codec = socdev->card->codec;
272 u32 dai_cfg1; 268 u32 dai_cfg1;
273 u32 hpf_reg, hpf_mask, hpf_value; 269 u32 hpf_reg, hpf_mask, hpf_value;
274 u32 fs, bypass; 270 u32 fs, bypass;
@@ -430,9 +426,8 @@ static struct snd_soc_dai_ops da7210_dai_ops = {
430 .set_fmt = da7210_set_dai_fmt, 426 .set_fmt = da7210_set_dai_fmt,
431}; 427};
432 428
433struct snd_soc_dai da7210_dai = { 429static struct snd_soc_dai_driver da7210_dai = {
434 .name = "DA7210 IIS", 430 .name = "da7210-hifi",
435 .id = 0,
436 /* playback capabilities */ 431 /* playback capabilities */
437 .playback = { 432 .playback = {
438 .stream_name = "Playback", 433 .stream_name = "Playback",
@@ -452,55 +447,15 @@ struct snd_soc_dai da7210_dai = {
452 .ops = &da7210_dai_ops, 447 .ops = &da7210_dai_ops,
453 .symmetric_rates = 1, 448 .symmetric_rates = 1,
454}; 449};
455EXPORT_SYMBOL_GPL(da7210_dai);
456 450
457/* 451static int da7210_probe(struct snd_soc_codec *codec)
458 * Initialize the DA7210 driver
459 * register the mixer and dsp interfaces with the kernel
460 */
461static int da7210_init(struct da7210_priv *da7210)
462{ 452{
463 struct snd_soc_codec *codec = &da7210->codec; 453 struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec);
464 int ret = 0;
465 454
466 if (da7210_codec) { 455 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
467 dev_err(codec->dev, "Another da7210 is registered\n");
468 return -EINVAL;
469 }
470 456
471 mutex_init(&codec->mutex); 457 codec->control_data = da7210->control_data;
472 INIT_LIST_HEAD(&codec->dapm_widgets);
473 INIT_LIST_HEAD(&codec->dapm_paths);
474
475 snd_soc_codec_set_drvdata(codec, da7210);
476 codec->name = "DA7210";
477 codec->owner = THIS_MODULE;
478 codec->read = da7210_read;
479 codec->write = da7210_write;
480 codec->dai = &da7210_dai;
481 codec->num_dai = 1;
482 codec->hw_write = (hw_write_t)i2c_master_send; 458 codec->hw_write = (hw_write_t)i2c_master_send;
483 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
484 codec->reg_cache = kmemdup(da7210_reg,
485 sizeof(da7210_reg), GFP_KERNEL);
486
487 if (!codec->reg_cache)
488 return -ENOMEM;
489
490 da7210_dai.dev = codec->dev;
491 da7210_codec = codec;
492
493 ret = snd_soc_register_codec(codec);
494 if (ret) {
495 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
496 goto init_err;
497 }
498
499 ret = snd_soc_register_dai(&da7210_dai);
500 if (ret) {
501 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
502 goto codec_err;
503 }
504 459
505 /* FIXME 460 /* FIXME
506 * 461 *
@@ -583,54 +538,50 @@ static int da7210_init(struct da7210_priv *da7210)
583 /* Activate all enabled subsystem */ 538 /* Activate all enabled subsystem */
584 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); 539 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
585 540
586 return ret; 541 snd_soc_add_controls(codec, da7210_snd_controls,
587 542 ARRAY_SIZE(da7210_snd_controls));
588codec_err:
589 snd_soc_unregister_codec(codec);
590init_err:
591 kfree(codec->reg_cache);
592 codec->reg_cache = NULL;
593 543
594 return ret; 544 dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
595 545
546 return 0;
596} 547}
597 548
549static struct snd_soc_codec_driver soc_codec_dev_da7210 = {
550 .probe = da7210_probe,
551 .read = da7210_read,
552 .write = da7210_write,
553 .reg_cache_size = ARRAY_SIZE(da7210_reg),
554 .reg_word_size = sizeof(u8),
555 .reg_cache_default = da7210_reg,
556};
557
598#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 558#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
599static int __devinit da7210_i2c_probe(struct i2c_client *i2c, 559static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
600 const struct i2c_device_id *id) 560 const struct i2c_device_id *id)
601{ 561{
602 struct da7210_priv *da7210; 562 struct da7210_priv *da7210;
603 struct snd_soc_codec *codec;
604 int ret; 563 int ret;
605 564
606 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL); 565 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
607 if (!da7210) 566 if (!da7210)
608 return -ENOMEM; 567 return -ENOMEM;
609 568
610 codec = &da7210->codec;
611 codec->dev = &i2c->dev;
612
613 i2c_set_clientdata(i2c, da7210); 569 i2c_set_clientdata(i2c, da7210);
614 codec->control_data = i2c; 570 da7210->control_data = i2c;
571 da7210->control_type = SND_SOC_I2C;
615 572
616 ret = da7210_init(da7210); 573 ret = snd_soc_register_codec(&i2c->dev,
617 if (ret < 0) { 574 &soc_codec_dev_da7210, &da7210_dai, 1);
618 pr_err("Failed to initialise da7210 audio codec\n"); 575 if (ret < 0)
619 kfree(da7210); 576 kfree(da7210);
620 }
621 577
622 return ret; 578 return ret;
623} 579}
624 580
625static int __devexit da7210_i2c_remove(struct i2c_client *client) 581static int __devexit da7210_i2c_remove(struct i2c_client *client)
626{ 582{
627 struct da7210_priv *da7210 = i2c_get_clientdata(client); 583 snd_soc_unregister_codec(&client->dev);
628 584 kfree(i2c_get_clientdata(client));
629 snd_soc_unregister_dai(&da7210_dai);
630 kfree(da7210->codec.reg_cache);
631 kfree(da7210);
632 da7210_codec = NULL;
633
634 return 0; 585 return 0;
635} 586}
636 587
@@ -643,7 +594,7 @@ MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
643/* I2C codec control layer */ 594/* I2C codec control layer */
644static struct i2c_driver da7210_i2c_driver = { 595static struct i2c_driver da7210_i2c_driver = {
645 .driver = { 596 .driver = {
646 .name = "DA7210 I2C Codec", 597 .name = "da7210-codec",
647 .owner = THIS_MODULE, 598 .owner = THIS_MODULE,
648 }, 599 },
649 .probe = da7210_i2c_probe, 600 .probe = da7210_i2c_probe,
@@ -652,50 +603,6 @@ static struct i2c_driver da7210_i2c_driver = {
652}; 603};
653#endif 604#endif
654 605
655static int da7210_probe(struct platform_device *pdev)
656{
657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
658 struct snd_soc_codec *codec;
659 int ret;
660
661 if (!da7210_codec) {
662 dev_err(&pdev->dev, "Codec device not registered\n");
663 return -ENODEV;
664 }
665
666 socdev->card->codec = da7210_codec;
667 codec = da7210_codec;
668
669 /* Register pcms */
670 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
671 if (ret < 0)
672 goto pcm_err;
673
674 snd_soc_add_controls(da7210_codec, da7210_snd_controls,
675 ARRAY_SIZE(da7210_snd_controls));
676
677 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
678
679pcm_err:
680 return ret;
681}
682
683static int da7210_remove(struct platform_device *pdev)
684{
685 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
686
687 snd_soc_free_pcms(socdev);
688 snd_soc_dapm_free(socdev);
689
690 return 0;
691}
692
693struct snd_soc_codec_device soc_codec_dev_da7210 = {
694 .probe = da7210_probe,
695 .remove = da7210_remove,
696};
697EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
698
699static int __init da7210_modinit(void) 606static int __init da7210_modinit(void)
700{ 607{
701 int ret = 0; 608 int ret = 0;