Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Axel Lin and committed by
Mark Brown
c973b8a7 f114040e

+168 -142
+2 -1
sound/soc/cirrus/Kconfig
··· 36 36 tristate "SoC Audio support for Cirrus Logic EDB93xx boards" 37 37 depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A) 38 38 select SND_EP93XX_SOC_I2S 39 - select SND_SOC_CS4271 39 + select SND_SOC_CS4271_I2C if I2C 40 + select SND_SOC_CS4271_SPI if SPI_MASTER 40 41 help 41 42 Say Y or M here if you want to add support for I2S audio on the 42 43 Cirrus Logic EDB93xx boards.
+15 -3
sound/soc/codecs/Kconfig
··· 50 50 select SND_SOC_CS42L73 if I2C 51 51 select SND_SOC_CS4265 if I2C 52 52 select SND_SOC_CS4270 if I2C 53 - select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 53 + select SND_SOC_CS4271_I2C if I2C 54 + select SND_SOC_CS4271_SPI if SPI_MASTER 54 55 select SND_SOC_CS42XX8_I2C if I2C 55 56 select SND_SOC_CX20442 if TTY 56 57 select SND_SOC_DA7210 if I2C ··· 371 370 depends on SND_SOC_CS4270 372 371 373 372 config SND_SOC_CS4271 374 - tristate "Cirrus Logic CS4271 CODEC" 375 - depends on SND_SOC_I2C_AND_SPI 373 + tristate 374 + 375 + config SND_SOC_CS4271_I2C 376 + tristate "Cirrus Logic CS4271 CODEC (I2C)" 377 + depends on I2C 378 + select SND_SOC_CS4271 379 + select REGMAP_I2C 380 + 381 + config SND_SOC_CS4271_SPI 382 + tristate "Cirrus Logic CS4271 CODEC (SPI)" 383 + depends on SPI_MASTER 384 + select SND_SOC_CS4271 385 + select REGMAP_SPI 376 386 377 387 config SND_SOC_CS42XX8 378 388 tristate
+4
sound/soc/codecs/Makefile
··· 41 41 snd-soc-cs4265-objs := cs4265.o 42 42 snd-soc-cs4270-objs := cs4270.o 43 43 snd-soc-cs4271-objs := cs4271.o 44 + snd-soc-cs4271-i2c-objs := cs4271-i2c.o 45 + snd-soc-cs4271-spi-objs := cs4271-spi.o 44 46 snd-soc-cs42xx8-objs := cs42xx8.o 45 47 snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o 46 48 snd-soc-cx20442-objs := cx20442.o ··· 219 217 obj-$(CONFIG_SND_SOC_CS4265) += snd-soc-cs4265.o 220 218 obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 221 219 obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 220 + obj-$(CONFIG_SND_SOC_CS4271_I2C) += snd-soc-cs4271-i2c.o 221 + obj-$(CONFIG_SND_SOC_CS4271_SPI) += snd-soc-cs4271-spi.o 222 222 obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o 223 223 obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o 224 224 obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
+62
sound/soc/codecs/cs4271-i2c.c
··· 1 + /* 2 + * CS4271 I2C audio driver 3 + * 4 + * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 2 9 + * of the License, or (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/module.h> 18 + #include <linux/i2c.h> 19 + #include <linux/regmap.h> 20 + #include <sound/soc.h> 21 + #include "cs4271.h" 22 + 23 + static int cs4271_i2c_probe(struct i2c_client *client, 24 + const struct i2c_device_id *id) 25 + { 26 + struct regmap_config config; 27 + 28 + config = cs4271_regmap_config; 29 + config.reg_bits = 8; 30 + config.val_bits = 8; 31 + 32 + return cs4271_probe(&client->dev, 33 + devm_regmap_init_i2c(client, &config)); 34 + } 35 + 36 + static int cs4271_i2c_remove(struct i2c_client *client) 37 + { 38 + snd_soc_unregister_codec(&client->dev); 39 + return 0; 40 + } 41 + 42 + static const struct i2c_device_id cs4271_i2c_id[] = { 43 + { "cs4271", 0 }, 44 + { } 45 + }; 46 + MODULE_DEVICE_TABLE(i2c, cs4271_i2c_id); 47 + 48 + static struct i2c_driver cs4271_i2c_driver = { 49 + .driver = { 50 + .name = "cs4271", 51 + .owner = THIS_MODULE, 52 + .of_match_table = of_match_ptr(cs4271_dt_ids), 53 + }, 54 + .probe = cs4271_i2c_probe, 55 + .remove = cs4271_i2c_remove, 56 + .id_table = cs4271_i2c_id, 57 + }; 58 + module_i2c_driver(cs4271_i2c_driver); 59 + 60 + MODULE_DESCRIPTION("ASoC CS4271 I2C Driver"); 61 + MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); 62 + MODULE_LICENSE("GPL");
+55
sound/soc/codecs/cs4271-spi.c
··· 1 + /* 2 + * CS4271 SPI audio driver 3 + * 4 + * Copyright (c) 2010 Alexander Sverdlin <subaparts@yandex.ru> 5 + * 6 + * This program is free software; you can redistribute it and/or 7 + * modify it under the terms of the GNU General Public License 8 + * as published by the Free Software Foundation; either version 2 9 + * of the License, or (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #include <linux/module.h> 18 + #include <linux/spi/spi.h> 19 + #include <linux/regmap.h> 20 + #include <sound/soc.h> 21 + #include "cs4271.h" 22 + 23 + static int cs4271_spi_probe(struct spi_device *spi) 24 + { 25 + struct regmap_config config; 26 + 27 + config = cs4271_regmap_config; 28 + config.reg_bits = 16; 29 + config.val_bits = 8; 30 + config.read_flag_mask = 0x21; 31 + config.write_flag_mask = 0x20; 32 + 33 + return cs4271_probe(&spi->dev, devm_regmap_init_spi(spi, &config)); 34 + } 35 + 36 + static int cs4271_spi_remove(struct spi_device *spi) 37 + { 38 + snd_soc_unregister_codec(&spi->dev); 39 + return 0; 40 + } 41 + 42 + static struct spi_driver cs4271_spi_driver = { 43 + .driver = { 44 + .name = "cs4271", 45 + .owner = THIS_MODULE, 46 + .of_match_table = of_match_ptr(cs4271_dt_ids), 47 + }, 48 + .probe = cs4271_spi_probe, 49 + .remove = cs4271_spi_remove, 50 + }; 51 + module_spi_driver(cs4271_spi_driver); 52 + 53 + MODULE_DESCRIPTION("ASoC CS4271 SPI Driver"); 54 + MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); 55 + MODULE_LICENSE("GPL");
+19 -138
sound/soc/codecs/cs4271.c
··· 23 23 #include <linux/slab.h> 24 24 #include <linux/delay.h> 25 25 #include <linux/gpio.h> 26 - #include <linux/i2c.h> 27 - #include <linux/spi/spi.h> 28 26 #include <linux/of.h> 29 27 #include <linux/of_device.h> 30 28 #include <linux/of_gpio.h> ··· 30 32 #include <sound/soc.h> 31 33 #include <sound/tlv.h> 32 34 #include <sound/cs4271.h> 35 + #include "cs4271.h" 33 36 34 37 #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 35 38 SNDRV_PCM_FMTBIT_S24_LE | \ ··· 526 527 #endif /* CONFIG_PM */ 527 528 528 529 #ifdef CONFIG_OF 529 - static const struct of_device_id cs4271_dt_ids[] = { 530 + const struct of_device_id cs4271_dt_ids[] = { 530 531 { .compatible = "cirrus,cs4271", }, 531 532 { } 532 533 }; 533 534 MODULE_DEVICE_TABLE(of, cs4271_dt_ids); 535 + EXPORT_SYMBOL_GPL(cs4271_dt_ids); 534 536 #endif 535 537 536 - static int cs4271_probe(struct snd_soc_codec *codec) 538 + static int cs4271_codec_probe(struct snd_soc_codec *codec) 537 539 { 538 540 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 539 541 struct cs4271_platform_data *cs4271plat = codec->dev->platform_data; ··· 587 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 592 struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); 593 593 ··· 599 599 }; 600 600 601 601 static struct snd_soc_codec_driver soc_codec_dev_cs4271 = { 602 - .probe = cs4271_probe, 603 - .remove = cs4271_remove, 602 + .probe = cs4271_codec_probe, 603 + .remove = cs4271_codec_remove, 604 604 .suspend = cs4271_soc_suspend, 605 605 .resume = cs4271_soc_resume, 606 606 ··· 642 642 return 0; 643 643 } 644 644 645 - #if defined(CONFIG_SPI_MASTER) 646 - 647 - static const struct regmap_config cs4271_spi_regmap = { 648 - .reg_bits = 16, 649 - .val_bits = 8, 650 - .max_register = CS4271_LASTREG, 651 - .read_flag_mask = 0x21, 652 - .write_flag_mask = 0x20, 653 - 654 - .reg_defaults = cs4271_reg_defaults, 655 - .num_reg_defaults = ARRAY_SIZE(cs4271_reg_defaults), 656 - .cache_type = REGCACHE_RBTREE, 657 - 658 - .volatile_reg = cs4271_volatile_reg, 659 - }; 660 - 661 - static int cs4271_spi_probe(struct spi_device *spi) 662 - { 663 - struct cs4271_private *cs4271; 664 - int ret; 665 - 666 - ret = cs4271_common_probe(&spi->dev, &cs4271); 667 - if (ret < 0) 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 - 703 - static const struct regmap_config cs4271_i2c_regmap = { 704 - .reg_bits = 8, 705 - .val_bits = 8, 645 + const struct regmap_config cs4271_regmap_config = { 706 646 .max_register = CS4271_LASTREG, 707 647 708 648 .reg_defaults = cs4271_reg_defaults, ··· 651 711 652 712 .volatile_reg = cs4271_volatile_reg, 653 713 }; 714 + EXPORT_SYMBOL_GPL(cs4271_regmap_config); 654 715 655 - static int cs4271_i2c_probe(struct i2c_client *client, 656 - const struct i2c_device_id *id) 716 + int cs4271_probe(struct device *dev, struct regmap *regmap) 657 717 { 658 718 struct cs4271_private *cs4271; 659 719 int ret; 660 720 661 - ret = cs4271_common_probe(&client->dev, &cs4271); 721 + if (IS_ERR(regmap)) 722 + return PTR_ERR(regmap); 723 + 724 + ret = cs4271_common_probe(dev, &cs4271); 662 725 if (ret < 0) 663 726 return ret; 664 727 665 - i2c_set_clientdata(client, cs4271); 666 - cs4271->regmap = devm_regmap_init_i2c(client, &cs4271_i2c_regmap); 667 - if (IS_ERR(cs4271->regmap)) 668 - return PTR_ERR(cs4271->regmap); 728 + dev_set_drvdata(dev, cs4271); 729 + cs4271->regmap = regmap; 669 730 670 - return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, 671 - &cs4271_dai, 1); 731 + return snd_soc_register_codec(dev, &soc_codec_dev_cs4271, &cs4271_dai, 732 + 1); 672 733 } 673 - 674 - static int cs4271_i2c_remove(struct i2c_client *client) 675 - { 676 - snd_soc_unregister_codec(&client->dev); 677 - return 0; 678 - } 679 - 680 - static struct i2c_driver cs4271_i2c_driver = { 681 - .driver = { 682 - .name = "cs4271", 683 - .owner = THIS_MODULE, 684 - .of_match_table = of_match_ptr(cs4271_dt_ids), 685 - }, 686 - .id_table = cs4271_i2c_id, 687 - .probe = cs4271_i2c_probe, 688 - .remove = cs4271_i2c_remove, 689 - }; 690 - #endif /* IS_ENABLED(CONFIG_I2C) */ 691 - 692 - /* 693 - * We only register our serial bus driver here without 694 - * assignment to particular chip. So if any of the below 695 - * fails, there is some problem with I2C or SPI subsystem. 696 - * In most cases this module will be compiled with support 697 - * of only one serial bus. 698 - */ 699 - static int __init cs4271_modinit(void) 700 - { 701 - int ret; 702 - 703 - #if IS_ENABLED(CONFIG_I2C) 704 - ret = i2c_add_driver(&cs4271_i2c_driver); 705 - if (ret) { 706 - pr_err("Failed to register CS4271 I2C driver: %d\n", ret); 707 - return ret; 708 - } 709 - #endif 710 - 711 - #if defined(CONFIG_SPI_MASTER) 712 - ret = spi_register_driver(&cs4271_spi_driver); 713 - if (ret) { 714 - pr_err("Failed to register CS4271 SPI driver: %d\n", ret); 715 - return ret; 716 - } 717 - #endif 718 - 719 - return 0; 720 - } 721 - module_init(cs4271_modinit); 722 - 723 - static void __exit cs4271_modexit(void) 724 - { 725 - #if defined(CONFIG_SPI_MASTER) 726 - spi_unregister_driver(&cs4271_spi_driver); 727 - #endif 728 - 729 - #if IS_ENABLED(CONFIG_I2C) 730 - i2c_del_driver(&cs4271_i2c_driver); 731 - #endif 732 - } 733 - module_exit(cs4271_modexit); 734 + EXPORT_SYMBOL_GPL(cs4271_probe); 734 735 735 736 MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); 736 737 MODULE_DESCRIPTION("Cirrus Logic CS4271 ALSA SoC Codec Driver");
+11
sound/soc/codecs/cs4271.h
··· 1 + #ifndef _CS4271_PRIV_H 2 + #define _CS4271_PRIV_H 3 + 4 + #include <linux/regmap.h> 5 + 6 + extern const struct of_device_id cs4271_dt_ids[]; 7 + extern const struct regmap_config cs4271_regmap_config; 8 + 9 + int cs4271_probe(struct device *dev, struct regmap *regmap); 10 + 11 + #endif