aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/cs4270.c177
1 files changed, 97 insertions, 80 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 21253b48289f..adc1150ddb00 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -490,21 +490,17 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
490}; 490};
491 491
492/* 492/*
493 * Global variable to store socdev for i2c probe function. 493 * Global variable to store codec for the ASoC probe function.
494 * 494 *
495 * If struct i2c_driver had a private_data field, we wouldn't need to use 495 * If struct i2c_driver had a private_data field, we wouldn't need to use
496 * cs4270_socdec. This is the only way to pass the socdev structure to 496 * cs4270_codec. This is the only way to pass the codec structure from
497 * cs4270_i2c_probe(). 497 * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good
498 * 498 * way to synchronize these two functions. cs4270_i2c_probe() can be called
499 * The real solution to cs4270_socdev is to create a mechanism 499 * multiple times before cs4270_probe() is called even once. So for now, we
500 * that maps I2C addresses to snd_soc_device structures. Perhaps the 500 * also only allow cs4270_i2c_probe() to be run once. That means that we do
501 * creation of the snd_soc_device object should be moved out of 501 * not support more than one cs4270 device in the system, at least for now.
502 * cs4270_probe() and into cs4270_i2c_probe(), but that would make this
503 * driver dependent on I2C. The CS4270 supports "stand-alone" mode, whereby
504 * the chip is *not* connected to the I2C bus, but is instead configured via
505 * input pins.
506 */ 502 */
507static struct snd_soc_device *cs4270_socdev; 503static struct snd_soc_codec *cs4270_codec;
508 504
509struct snd_soc_dai cs4270_dai = { 505struct snd_soc_dai cs4270_dai = {
510 .name = "cs4270", 506 .name = "cs4270",
@@ -532,6 +528,70 @@ struct snd_soc_dai cs4270_dai = {
532EXPORT_SYMBOL_GPL(cs4270_dai); 528EXPORT_SYMBOL_GPL(cs4270_dai);
533 529
534/* 530/*
531 * ASoC probe function
532 */
533static int cs4270_probe(struct platform_device *pdev)
534{
535 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
536 struct snd_soc_codec *codec = cs4270_codec;
537 unsigned int i;
538 int ret;
539
540 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
541 socdev->card->codec = codec;
542
543 /* Register PCMs */
544 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
545 if (ret < 0) {
546 printk(KERN_ERR "cs4270: failed to create PCMs\n");
547 return ret;
548 }
549
550 /* Add the non-DAPM controls */
551 for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) {
552 struct snd_kcontrol *kctrl;
553
554 kctrl = snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL);
555 if (!kctrl) {
556 printk(KERN_ERR "cs4270: error creating control '%s'\n",
557 cs4270_snd_controls[i].name);
558 ret = -ENOMEM;
559 goto error_free_pcms;
560 }
561
562 ret = snd_ctl_add(codec->card, kctrl);
563 if (ret < 0) {
564 printk(KERN_ERR "cs4270: error adding control '%s'\n",
565 cs4270_snd_controls[i].name);
566 goto error_free_pcms;
567 }
568 }
569
570 /* And finally, register the socdev */
571 ret = snd_soc_init_card(socdev);
572 if (ret < 0) {
573 printk(KERN_ERR "cs4270: failed to register card\n");
574 goto error_free_pcms;
575 }
576
577 return 0;
578
579error_free_pcms:
580 snd_soc_free_pcms(socdev);
581
582 return ret;
583}
584
585static int cs4270_remove(struct platform_device *pdev)
586{
587 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
588
589 snd_soc_free_pcms(socdev);
590
591 return 0;
592};
593
594/*
535 * Initialize the I2C interface of the CS4270 595 * Initialize the I2C interface of the CS4270
536 * 596 *
537 * This function is called for whenever the I2C subsystem finds a device 597 * This function is called for whenever the I2C subsystem finds a device
@@ -543,17 +603,27 @@ EXPORT_SYMBOL_GPL(cs4270_dai);
543static int cs4270_i2c_probe(struct i2c_client *i2c_client, 603static int cs4270_i2c_probe(struct i2c_client *i2c_client,
544 const struct i2c_device_id *id) 604 const struct i2c_device_id *id)
545{ 605{
546 struct snd_soc_device *socdev = cs4270_socdev;
547 struct snd_soc_codec *codec; 606 struct snd_soc_codec *codec;
548 struct cs4270_private *cs4270; 607 struct cs4270_private *cs4270;
549 int i; 608 int ret;
550 int ret = 0; 609
610 /* For now, we only support one cs4270 device in the system. See the
611 * comment for cs4270_codec.
612 */
613 if (cs4270_codec) {
614 printk(KERN_ERR "cs4270: ignoring CS4270 at addr %X\n",
615 i2c_client->addr);
616 printk(KERN_ERR "cs4270: only one CS4270 per board allowed\n");
617 /* Should we return something other than ENODEV here? */
618 return -ENODEV;
619 }
551 620
552 /* Verify that we have a CS4270 */ 621 /* Verify that we have a CS4270 */
553 622
554 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); 623 ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
555 if (ret < 0) { 624 if (ret < 0) {
556 printk(KERN_ERR "cs4270: failed to read I2C\n"); 625 printk(KERN_ERR "cs4270: failed to read I2C at addr %X\n",
626 i2c_client->addr);
557 return ret; 627 return ret;
558 } 628 }
559 /* The top four bits of the chip ID should be 1100. */ 629 /* The top four bits of the chip ID should be 1100. */
@@ -575,7 +645,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
575 return -ENOMEM; 645 return -ENOMEM;
576 } 646 }
577 codec = &cs4270->codec; 647 codec = &cs4270->codec;
578 socdev->card->codec = codec; 648 cs4270_codec = codec;
579 649
580 mutex_init(&codec->mutex); 650 mutex_init(&codec->mutex);
581 INIT_LIST_HEAD(&codec->dapm_widgets); 651 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -600,50 +670,20 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
600 goto error_free_codec; 670 goto error_free_codec;
601 } 671 }
602 672
603 /* Register PCMs */ 673 /* Register the DAI. If all the other ASoC driver have already
604 674 * registered, then this will call our probe function, so
605 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 675 * cs4270_codec needs to be ready.
676 */
677 ret = snd_soc_register_dai(&cs4270_dai);
606 if (ret < 0) { 678 if (ret < 0) {
607 printk(KERN_ERR "cs4270: failed to create PCMs\n"); 679 printk(KERN_ERR "cs4270: failed to register DAIe\n");
608 goto error_free_codec; 680 goto error_free_codec;
609 } 681 }
610 682
611 /* Add the non-DAPM controls */ 683 i2c_set_clientdata(i2c_client, cs4270);
612
613 for (i = 0; i < ARRAY_SIZE(cs4270_snd_controls); i++) {
614 struct snd_kcontrol *kctrl;
615
616 kctrl = snd_soc_cnew(&cs4270_snd_controls[i], codec, NULL);
617 if (!kctrl) {
618 printk(KERN_ERR "cs4270: error creating control '%s'\n",
619 cs4270_snd_controls[i].name);
620 ret = -ENOMEM;
621 goto error_free_pcms;
622 }
623
624 ret = snd_ctl_add(codec->card, kctrl);
625 if (ret < 0) {
626 printk(KERN_ERR "cs4270: error adding control '%s'\n",
627 cs4270_snd_controls[i].name);
628 goto error_free_pcms;
629 }
630 }
631
632 /* Initialize the SOC device */
633
634 ret = snd_soc_init_card(socdev);
635 if (ret < 0) {
636 printk(KERN_ERR "cs4270: failed to register card\n");
637 goto error_free_pcms;;
638 }
639
640 i2c_set_clientdata(i2c_client, socdev);
641 684
642 return 0; 685 return 0;
643 686
644error_free_pcms:
645 snd_soc_free_pcms(socdev);
646
647error_free_codec: 687error_free_codec:
648 kfree(cs4270); 688 kfree(cs4270);
649 689
@@ -652,11 +692,8 @@ error_free_codec:
652 692
653static int cs4270_i2c_remove(struct i2c_client *i2c_client) 693static int cs4270_i2c_remove(struct i2c_client *i2c_client)
654{ 694{
655 struct snd_soc_device *socdev = i2c_get_clientdata(i2c_client); 695 struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
656 struct snd_soc_codec *codec = socdev->card->codec;
657 struct cs4270_private *cs4270 = codec->private_data;
658 696
659 snd_soc_free_pcms(socdev);
660 kfree(cs4270); 697 kfree(cs4270);
661 698
662 return 0; 699 return 0;
@@ -679,26 +716,6 @@ static struct i2c_driver cs4270_i2c_driver = {
679}; 716};
680 717
681/* 718/*
682 * ASoC probe function
683 *
684 * This function is called when the machine driver calls
685 * platform_device_add().
686 */
687static int cs4270_probe(struct platform_device *pdev)
688{
689 cs4270_socdev = platform_get_drvdata(pdev);;
690
691 return i2c_add_driver(&cs4270_i2c_driver);
692}
693
694static int cs4270_remove(struct platform_device *pdev)
695{
696 i2c_del_driver(&cs4270_i2c_driver);
697
698 return 0;
699}
700
701/*
702 * ASoC codec device structure 719 * ASoC codec device structure
703 * 720 *
704 * Assign this variable to the codec_dev field of the machine driver's 721 * Assign this variable to the codec_dev field of the machine driver's
@@ -714,13 +731,13 @@ static int __init cs4270_init(void)
714{ 731{
715 printk(KERN_INFO "Cirrus Logic CS4270 ALSA SoC Codec Driver\n"); 732 printk(KERN_INFO "Cirrus Logic CS4270 ALSA SoC Codec Driver\n");
716 733
717 return snd_soc_register_dai(&cs4270_dai); 734 return i2c_add_driver(&cs4270_i2c_driver);
718} 735}
719module_init(cs4270_init); 736module_init(cs4270_init);
720 737
721static void __exit cs4270_exit(void) 738static void __exit cs4270_exit(void)
722{ 739{
723 snd_soc_unregister_dai(&cs4270_dai); 740 i2c_del_driver(&cs4270_i2c_driver);
724} 741}
725module_exit(cs4270_exit); 742module_exit(cs4270_exit);
726 743