diff --git a/arch/arm64/configs/bcm2711_defconfig b/arch/arm64/configs/bcm2711_defconfig index edbcc823e23c..41152dfe3177 100644 --- a/arch/arm64/configs/bcm2711_defconfig +++ b/arch/arm64/configs/bcm2711_defconfig @@ -1037,7 +1037,7 @@ CONFIG_SND_USB_6FIRE=m CONFIG_SND_USB_HIFACE=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_SOC=y -CONFIG_SND_BCM2835_SOC_I2S=m +CONFIG_SND_BCM2835_SOC_I2S=y CONFIG_SND_BCM2708_SOC_CHIPDIP_DAC=m CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD=m CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m @@ -1074,6 +1074,7 @@ CONFIG_SND_BCM2708_SOC_ALLO_BOSS2_DAC=m CONFIG_SND_BCM2708_SOC_ALLO_DIGIONE=m CONFIG_SND_BCM2708_SOC_ALLO_KATANA_DAC=m CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m +CONFIG_SND_BCM2708_SOC_I2SMIC_RPI=y CONFIG_SND_PISOUND=m CONFIG_SND_DACBERRY400=m CONFIG_SND_SOC_AD193X_SPI=m @@ -1088,7 +1089,7 @@ CONFIG_SND_SOC_MAX98357A=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_WM8804_I2C=m CONFIG_SND_SOC_WM8960=m -CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_SIMPLE_CARD=y CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HIDRAW=y CONFIG_UHID=m diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig index c865ad6f50b9..82431f43d2af 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -307,6 +307,12 @@ config SND_BCM2708_SOC_FE_PI_AUDIO help Say Y or M if you want to add support for Fe-Pi-Audio. +config SND_BCM2708_SOC_I2SMIC_RPI + tristate "Support for I2S MEMS Microphone" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + help + Say Y or M if you want to add support for I2S MEMS Microphone. + config SND_PISOUND tristate "Support for Blokas Labs pisound" depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile index 46d1ece070a3..4f1853c6ab04 100644 --- a/sound/soc/bcm/Makefile +++ b/sound/soc/bcm/Makefile @@ -49,6 +49,7 @@ snd-soc-rpi-wm8804-soundcard-objs := rpi-wm8804-soundcard.o snd-soc-pifi-40-objs := pifi-40.o snd-soc-chipdip-dac-objs := chipdip-dac.o snd-soc-dacberry400-objs := dacberry400.o +snd-soc-i2smic-rpi-objs := snd-i2smic-rpi.o obj-$(CONFIG_SND_BCM2708_SOC_GOOGLEVOICEHAT_SOUNDCARD) += snd-soc-googlevoicehat-codec.o obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o @@ -82,3 +83,4 @@ obj-$(CONFIG_SND_RPI_WM8804_SOUNDCARD) += snd-soc-rpi-wm8804-soundcard.o obj-$(CONFIG_SND_BCM2708_SOC_PIFI_40) += snd-soc-pifi-40.o obj-$(CONFIG_SND_BCM2708_SOC_CHIPDIP_DAC) += snd-soc-chipdip-dac.o obj-$(CONFIG_SND_DACBERRY400) += snd-soc-dacberry400.o +obj-$(CONFIG_SND_BCM2708_SOC_I2SMIC_RPI) += snd-soc-i2smic-rpi.o diff --git a/sound/soc/bcm/snd-i2smic-rpi.c b/sound/soc/bcm/snd-i2smic-rpi.c new file mode 100644 index 000000000000..bd482053034e --- /dev/null +++ b/sound/soc/bcm/snd-i2smic-rpi.c @@ -0,0 +1,151 @@ +/* + * ===================================================================================== + * + * Filename: snd-i2smic-rpi + * + * Description: I2S microphone kernel module + * + * Version: 0.1.0 + * Created: 2020-04-14 + * Revision: none + * Compiler: gcc + * + * Pi4 Mods: Carter Nelson + * Orig Author: Huan Truong (htruong@tnhh.net), originally written by Paul Creaser + * + * ===================================================================================== + */ +#include +#include +#include +#include +#include +#include +#include +#include "snd-i2smic-rpi.h" + +/* + * modified for linux 4.1.5 + * inspired by https://github.com/msperl/spi-config + * with thanks for https://github.com/notro/rpi-source/wiki + * as well as Florian Meier for the rpi i2s and dma drivers + * + * to use a differant (simple-card compatible) codec + * change the codec name string in two places and the + * codec_dai name string. (see codec's source file) + * + * + * N.B. playback vs capture is determined by the codec choice + * */ + +static struct asoc_simple_card_info card_info; +static struct platform_device card_device; + +/* + * Setup command line parameter + */ +static short rpi_platform_generation = 2; +module_param(rpi_platform_generation, short, 0); +MODULE_PARM_DESC(rpi_platform_generation, "Raspberry Pi generation: 0=Pi0, 1=Pi2/3, 2=Pi4"); + +/* + * Dummy callback for release + */ +void device_release_callback(struct device *dev) { /* do nothing */ }; + +/* + * Setup the card info + */ +static struct asoc_simple_card_info default_card_info = { + .card = "snd_rpi_i2s_card", // -> snd_soc_card.name + .name = "simple-card_codec_link", // -> snd_soc_dai_link.name + .codec = "snd-soc-dummy", // "dmic-codec", // -> snd_soc_dai_link.codec_name + .platform = "not-set.i2s", + .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, + .cpu_dai = { + .name = "not-set.i2s", // -> snd_soc_dai_link.cpu_dai_name + .sysclk = 0 + }, + .codec_dai = { + .name = "snd-soc-dummy-dai", //"dmic-codec", // -> snd_soc_dai_link.codec_dai_name + .sysclk = 0 + }, +}; + +/* + * Setup the card device + */ +static struct platform_device default_card_device = { + .name = "asoc-simple-card", //module alias + .id = 0, + .num_resources = 0, + .dev = { + .release = &device_release_callback, + .platform_data = &default_card_info, // *HACK ALERT* + }, +}; + +/* + * Callback for module initialization + */ +int i2s_mic_rpi_init(void) +{ + const char *dmaengine = "bcm2708-dmaengine"; //module name + static char *card_platform; + int ret; + + printk(KERN_INFO "snd-i2smic-rpi: Version %s\n", SND_I2SMIC_RPI_VERSION); + + // Set platform + switch (rpi_platform_generation) { + case 0: + // Pi Zero + card_platform = "20203000.i2s"; + break; + case 1: + // Pi 2 and 3 + card_platform = "3f203000.i2s"; + break; + case 2: + default: + // Pi 4 + card_platform = "fe203000.i2s"; + break; + } + + printk(KERN_INFO "snd-i2smic-rpi: Setting platform to %s\n", card_platform); + + // request DMA engine module + ret = request_module(dmaengine); + pr_alert("request module load '%s': %d\n",dmaengine, ret); + + // update info + card_info = default_card_info; + card_info.platform = card_platform; + card_info.cpu_dai.name = card_platform; + + card_device = default_card_device; + card_device.dev.platform_data = &card_info; + + // register the card device + ret = platform_device_register(&card_device); + pr_alert("register platform device '%s': %d\n",card_device.name, ret); + + return 0; +} + +/* + * Callback for module exit + */ +void i2s_mic_rpi_exit(void) +{ + platform_device_unregister(&card_device); + pr_alert("i2s mic module unloaded\n"); +} + +// Plumb it up +module_init(i2s_mic_rpi_init); +module_exit(i2s_mic_rpi_exit); +MODULE_DESCRIPTION("ASoC simple-card I2S Microphone"); +MODULE_AUTHOR("Carter Nelson"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/bcm/snd-i2smic-rpi.h b/sound/soc/bcm/snd-i2smic-rpi.h new file mode 100644 index 000000000000..7d8296d91cb9 --- /dev/null +++ b/sound/soc/bcm/snd-i2smic-rpi.h @@ -0,0 +1,6 @@ +#ifndef _SND_I2SMIC_RPI_H_ +#define _SND_I2SMIC_RPI_H_ + +#define SND_I2SMIC_RPI_VERSION "0.1.0" + +#endif