diff options
author | Axel Lin <axel.lin@ingics.com> | 2014-10-06 11:09:47 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-10-20 07:20:02 -0400 |
commit | c973b8a7dc50ace86393f209b19aa7fd0bfaf66b (patch) | |
tree | 8f7ff632abab96bc1b20918f2805aa2d8949903c /sound/soc/codecs/cs4271.c | |
parent | f114040e3ea6e07372334ade75d1ee0775c355e1 (diff) |
ASoC: cs4271: Split SPI and I2C code into different modules
Currently the cs4271 driver depends on SND_SOC_I2C_AND_SPI.
So the driver cannot be built as built-in if CONFIG_I2C=m.
Split SPI and I2C code into different modules to avoid this issue.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Acked-by: Brian Austin <brian.austin@cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/cs4271.c')
-rw-r--r-- | sound/soc/codecs/cs4271.c | 155 |
1 files changed, 18 insertions, 137 deletions
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 93cec52f4733..79a4efcb894c 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -23,8 +23,6 @@ | |||
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/i2c.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/of.h> | 26 | #include <linux/of.h> |
29 | #include <linux/of_device.h> | 27 | #include <linux/of_device.h> |
30 | #include <linux/of_gpio.h> | 28 | #include <linux/of_gpio.h> |
@@ -32,6 +30,7 @@ | |||
32 | #include <sound/soc.h> | 30 | #include <sound/soc.h> |
33 | #include <sound/tlv.h> | 31 | #include <sound/tlv.h> |
34 | #include <sound/cs4271.h> | 32 | #include <sound/cs4271.h> |
33 | #include "cs4271.h" | ||
35 | 34 | ||
36 | #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | 35 | #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
37 | SNDRV_PCM_FMTBIT_S24_LE | \ | 36 | SNDRV_PCM_FMTBIT_S24_LE | \ |
@@ -527,14 +526,15 @@ static int cs4271_soc_resume(struct snd_soc_codec *codec) | |||
527 | #endif /* CONFIG_PM */ | 526 | #endif /* CONFIG_PM */ |
528 | 527 | ||
529 | #ifdef CONFIG_OF | 528 | #ifdef CONFIG_OF |
530 | static const struct of_device_id cs4271_dt_ids[] = { | 529 | const struct of_device_id cs4271_dt_ids[] = { |
531 | { .compatible = "cirrus,cs4271", }, | 530 | { .compatible = "cirrus,cs4271", }, |
532 | { } | 531 | { } |
533 | }; | 532 | }; |
534 | MODULE_DEVICE_TABLE(of, cs4271_dt_ids); | 533 | MODULE_DEVICE_TABLE(of, cs4271_dt_ids); |
534 | EXPORT_SYMBOL_GPL(cs4271_dt_ids); | ||
535 | #endif | 535 | #endif |
536 | 536 | ||
537 | static int cs4271_probe(struct snd_soc_codec *codec) | 537 | static int cs4271_codec_probe(struct snd_soc_codec *codec) |
538 | { | 538 | { |
539 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 539 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
540 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; | 540 | struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; |
@@ -587,7 +587,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
587 | return 0; | 587 | return 0; |
588 | } | 588 | } |
589 | 589 | ||
590 | static int cs4271_remove(struct snd_soc_codec *codec) | 590 | static int cs4271_codec_remove(struct snd_soc_codec *codec) |
591 | { | 591 | { |
592 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 592 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
593 | 593 | ||
@@ -599,8 +599,8 @@ static int cs4271_remove(struct snd_soc_codec *codec) | |||
599 | }; | 599 | }; |
600 | 600 | ||
601 | static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { | 601 | static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { |
602 | .probe = cs4271_probe, | 602 | .probe = cs4271_codec_probe, |
603 | .remove = cs4271_remove, | 603 | .remove = cs4271_codec_remove, |
604 | .suspend = cs4271_soc_suspend, | 604 | .suspend = cs4271_soc_suspend, |
605 | .resume = cs4271_soc_resume, | 605 | .resume = cs4271_soc_resume, |
606 | 606 | ||
@@ -642,14 +642,8 @@ static int cs4271_common_probe(struct device *dev, | |||
642 | return 0; | 642 | return 0; |
643 | } | 643 | } |
644 | 644 | ||
645 | #if defined(CONFIG_SPI_MASTER) | 645 | const struct regmap_config cs4271_regmap_config = { |
646 | |||
647 | static const struct regmap_config cs4271_spi_regmap = { | ||
648 | .reg_bits = 16, | ||
649 | .val_bits = 8, | ||
650 | .max_register = CS4271_LASTREG, | 646 | .max_register = CS4271_LASTREG, |
651 | .read_flag_mask = 0x21, | ||
652 | .write_flag_mask = 0x20, | ||
653 | 647 | ||
654 | .reg_defaults = cs4271_reg_defaults, | 648 | .reg_defaults = cs4271_reg_defaults, |
655 | .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), | 649 | .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), |
@@ -657,140 +651,27 @@ static const struct regmap_config cs4271_spi_regmap = { | |||
657 | 651 | ||
658 | .volatile_reg = cs4271_volatile_reg, | 652 | .volatile_reg = cs4271_volatile_reg, |
659 | }; | 653 | }; |
654 | EXPORT_SYMBOL_GPL(cs4271_regmap_config); | ||
660 | 655 | ||
661 | static int cs4271_spi_probe(struct spi_device *spi) | 656 | int cs4271_probe(struct device *dev, struct regmap *regmap) |
662 | { | 657 | { |
663 | struct cs4271_private *cs4271; | 658 | struct cs4271_private *cs4271; |
664 | int ret; | 659 | int ret; |
665 | 660 | ||
666 | ret = cs4271_common_probe(&spi->dev, &cs4271); | 661 | if (IS_ERR(regmap)) |
667 | if (ret < 0) | 662 | return PTR_ERR(regmap); |
668 | return ret; | ||
669 | |||
670 | spi_set_drvdata(spi, cs4271); | ||
671 | cs4271->regmap = devm_regmap_init_spi(spi, &cs4271_spi_regmap); | ||
672 | if (IS_ERR(cs4271->regmap)) | ||
673 | return PTR_ERR(cs4271->regmap); | ||
674 | |||
675 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, | ||
676 | &cs4271_dai, 1); | ||
677 | } | ||
678 | |||
679 | static int cs4271_spi_remove(struct spi_device *spi) | ||
680 | { | ||
681 | snd_soc_unregister_codec(&spi->dev); | ||
682 | return 0; | ||
683 | } | ||
684 | |||
685 | static struct spi_driver cs4271_spi_driver = { | ||
686 | .driver = { | ||
687 | .name = "cs4271", | ||
688 | .owner = THIS_MODULE, | ||
689 | .of_match_table = of_match_ptr(cs4271_dt_ids), | ||
690 | }, | ||
691 | .probe = cs4271_spi_probe, | ||
692 | .remove = cs4271_spi_remove, | ||
693 | }; | ||
694 | #endif /* defined(CONFIG_SPI_MASTER) */ | ||
695 | |||
696 | #if IS_ENABLED(CONFIG_I2C) | ||
697 | static const struct i2c_device_id cs4271_i2c_id[] = { | ||
698 | {"cs4271", 0}, | ||
699 | {} | ||
700 | }; | ||
701 | MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); | ||
702 | 663 | ||
703 | static const struct regmap_config cs4271_i2c_regmap = { | 664 | ret = cs4271_common_probe(dev, &cs4271); |
704 | .reg_bits = 8, | ||
705 | .val_bits = 8, | ||
706 | .max_register = CS4271_LASTREG, | ||
707 | |||
708 | .reg_defaults = cs4271_reg_defaults, | ||
709 | .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), | ||
710 | .cache_type = REGCACHE_RBTREE, | ||
711 | |||
712 | .volatile_reg = cs4271_volatile_reg, | ||
713 | }; | ||
714 | |||
715 | static int cs4271_i2c_probe(struct i2c_client *client, | ||
716 | const struct i2c_device_id *id) | ||
717 | { | ||
718 | struct cs4271_private *cs4271; | ||
719 | int ret; | ||
720 | |||
721 | ret = cs4271_common_probe(&client->dev, &cs4271); | ||
722 | if (ret < 0) | 665 | if (ret < 0) |
723 | return ret; | 666 | return ret; |
724 | 667 | ||
725 | i2c_set_clientdata(client, cs4271); | 668 | dev_set_drvdata(dev, cs4271); |
726 | cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); | 669 | cs4271->regmap = regmap; |
727 | if (IS_ERR(cs4271->regmap)) | ||
728 | return PTR_ERR(cs4271->regmap); | ||
729 | 670 | ||
730 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, | 671 | return snd_soc_register_codec(dev, &soc_codec_dev_cs4271, &cs4271_dai, |
731 | &cs4271_dai, 1); | 672 | 1); |
732 | } | ||
733 | |||
734 | static int cs4271_i2c_remove(struct i2c_client *client) | ||
735 | { | ||
736 | snd_soc_unregister_codec(&client->dev); | ||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static struct i2c_driver cs4271_i2c_driver = { | ||
741 | .driver = { | ||
742 | .name = "cs4271", | ||
743 | .owner = THIS_MODULE, | ||
744 | .of_match_table = of_match_ptr(cs4271_dt_ids), | ||
745 | }, | ||
746 | .id_table = cs4271_i2c_id, | ||
747 | .probe = cs4271_i2c_probe, | ||
748 | .remove = cs4271_i2c_remove, | ||
749 | }; | ||
750 | #endif /* IS_ENABLED(CONFIG_I2C) */ | ||
751 | |||
752 | /* | ||
753 | * We only register our serial bus driver here without | ||
754 | * assignment to particular chip. So if any of the below | ||
755 | * fails, there is some problem with I2C or SPI subsystem. | ||
756 | * In most cases this module will be compiled with support | ||
757 | * of only one serial bus. | ||
758 | */ | ||
759 | static int __init cs4271_modinit(void) | ||
760 | { | ||
761 | int ret; | ||
762 | |||
763 | #if IS_ENABLED(CONFIG_I2C) | ||
764 | ret = i2c_add_driver(&cs4271_i2c_driver); | ||
765 | if (ret) { | ||
766 | pr_err("Failed to register CS4271 I2C driver: %d\n", ret); | ||
767 | return ret; | ||
768 | } | ||
769 | #endif | ||
770 | |||
771 | #if defined(CONFIG_SPI_MASTER) | ||
772 | ret = spi_register_driver(&cs4271_spi_driver); | ||
773 | if (ret) { | ||
774 | pr_err("Failed to register CS4271 SPI driver: %d\n", ret); | ||
775 | return ret; | ||
776 | } | ||
777 | #endif | ||
778 | |||
779 | return 0; | ||
780 | } | ||
781 | module_init(cs4271_modinit); | ||
782 | |||
783 | static void __exit cs4271_modexit(void) | ||
784 | { | ||
785 | #if defined(CONFIG_SPI_MASTER) | ||
786 | spi_unregister_driver(&cs4271_spi_driver); | ||
787 | #endif | ||
788 | |||
789 | #if IS_ENABLED(CONFIG_I2C) | ||
790 | i2c_del_driver(&cs4271_i2c_driver); | ||
791 | #endif | ||
792 | } | 673 | } |
793 | module_exit(cs4271_modexit); | 674 | EXPORT_SYMBOL_GPL(cs4271_probe); |
794 | 675 | ||
795 | MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); | 676 | MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); |
796 | MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver"); | 677 | MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver"); |