diff --git a/config/kernel/linux-sunxi-current.config b/config/kernel/linux-sunxi-current.config index 01312bb5c..6c70a775e 100644 --- a/config/kernel/linux-sunxi-current.config +++ b/config/kernel/linux-sunxi-current.config @@ -4,10 +4,10 @@ # # -# Compiler: arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0 +# Compiler: arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025 # CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=80300 +CONFIG_GCC_VERSION=90201 CONFIG_CLANG_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_HAS_ASM_GOTO=y @@ -4721,6 +4721,7 @@ CONFIG_DRM_RCAR_DW_HDMI=m # CONFIG_DRM_RCAR_LVDS is not set CONFIG_DRM_SUN4I=m CONFIG_DRM_SUN4I_HDMI=m +CONFIG_DRM_SUN4I_HDMI_AUDIO=y CONFIG_DRM_SUN4I_HDMI_CEC=y CONFIG_DRM_SUN4I_BACKEND=m CONFIG_DRM_SUN6I_DSI=m diff --git a/config/kernel/linux-sunxi-dev.config b/config/kernel/linux-sunxi-dev.config index a87fc9051..081f82109 100644 --- a/config/kernel/linux-sunxi-dev.config +++ b/config/kernel/linux-sunxi-dev.config @@ -1,14 +1,14 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 5.7.7 Kernel Configuration +# Linux/arm 5.7.8 Kernel Configuration # # -# Compiler: arm-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.3.0 +# Compiler: arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025 # CONFIG_CC_IS_GCC=y -CONFIG_GCC_VERSION=80300 -CONFIG_LD_VERSION=232000000 +CONFIG_GCC_VERSION=90201 +CONFIG_LD_VERSION=233010000 CONFIG_CLANG_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_HAS_ASM_GOTO=y @@ -1798,7 +1798,7 @@ CONFIG_DEV_COREDUMP=y CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y -CONFIG_REGMAP_SPI=m +CONFIG_REGMAP_SPI=y CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y CONFIG_REGMAP_SCCB=m @@ -2735,6 +2735,7 @@ CONFIG_TOUCHSCREEN_ELO=m # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +# CONFIG_TOUCHSCREEN_WM97XX is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC_SERIO is not set @@ -3479,7 +3480,7 @@ CONFIG_MFD_SUN4I_GPADC=m # CONFIG_MFD_ATMEL_HLCDC is not set # CONFIG_MFD_BCM590XX is not set # CONFIG_MFD_BD9571MWV is not set -CONFIG_MFD_AC100=m +CONFIG_MFD_AC100=y CONFIG_MFD_AC200=m CONFIG_MFD_AXP20X=y CONFIG_MFD_AXP20X_I2C=y @@ -3528,6 +3529,7 @@ CONFIG_MFD_CPCAP=m # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set +# CONFIG_UCB1400_CORE is not set # CONFIG_MFD_PM8XXX is not set # CONFIG_MFD_RT5033 is not set # CONFIG_MFD_RC5T583 is not set @@ -3692,7 +3694,7 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_SDR_SUPPORT=y -# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_CEC_SUPPORT=y # CONFIG_MEDIA_CEC_RC is not set # CONFIG_CEC_PIN_ERROR_INJ is not set CONFIG_MEDIA_CONTROLLER=y @@ -3879,6 +3881,12 @@ CONFIG_VIDEO_EM28XX_RC=m CONFIG_USB_AIRSPY=m CONFIG_USB_HACKRF=m CONFIG_USB_MSI2500=m + +# +# USB HDMI CEC adapters +# +# CONFIG_USB_PULSE8_CEC is not set +# CONFIG_USB_RAINSHADOW_CEC is not set CONFIG_V4L_PLATFORM_DRIVERS=y # CONFIG_VIDEO_CADENCE is not set CONFIG_VIDEO_ASPEED=m @@ -3900,7 +3908,8 @@ CONFIG_VIDEO_VIM2M=m CONFIG_VIDEO_VICODEC=m CONFIG_DVB_PLATFORM_DRIVERS=y CONFIG_DVB_C8SECTPFE=m -# CONFIG_SDR_PLATFORM_DRIVERS is not set +CONFIG_CEC_PLATFORM_DRIVERS=y +CONFIG_SDR_PLATFORM_DRIVERS=y # # Supported MMC/SDIO adapters @@ -4360,7 +4369,7 @@ CONFIG_DVB_DUMMY_FE=m # # Graphics support # -# CONFIG_IMX_IPUV3_CORE is not set +CONFIG_IMX_IPUV3_CORE=m CONFIG_DRM=y CONFIG_DRM_MIPI_DBI=m CONFIG_DRM_MIPI_DSI=y @@ -4392,7 +4401,8 @@ CONFIG_DRM_SCHED=m # # ARM devices # -# CONFIG_DRM_HDLCD is not set +CONFIG_DRM_HDLCD=m +# CONFIG_DRM_HDLCD_SHOW_UNDERRUN is not set CONFIG_DRM_MALI_DISPLAY=m CONFIG_DRM_KOMEDA=m # end of ARM devices @@ -4406,6 +4416,7 @@ CONFIG_DRM_RCAR_DW_HDMI=m # CONFIG_DRM_RCAR_LVDS is not set CONFIG_DRM_SUN4I=y CONFIG_DRM_SUN4I_HDMI=y +CONFIG_DRM_SUN4I_HDMI_AUDIO=y CONFIG_DRM_SUN4I_HDMI_CEC=y CONFIG_DRM_SUN4I_BACKEND=y CONFIG_DRM_SUN6I_DSI=y @@ -4509,24 +4520,25 @@ CONFIG_DRM_DW_HDMI_CEC=m # end of Display Interface Bridges # CONFIG_DRM_STI is not set +# CONFIG_DRM_IMX is not set CONFIG_DRM_ETNAVIV=m CONFIG_DRM_ETNAVIV_THERMAL=y # CONFIG_DRM_ARCPGU is not set # CONFIG_DRM_MXSFB is not set CONFIG_DRM_GM12U320=m CONFIG_TINYDRM_HX8357D=m -# CONFIG_TINYDRM_ILI9225 is not set +CONFIG_TINYDRM_ILI9225=m CONFIG_TINYDRM_ILI9341=m CONFIG_TINYDRM_ILI9486=m CONFIG_TINYDRM_MI0283QT=m -# CONFIG_TINYDRM_REPAPER is not set -# CONFIG_TINYDRM_ST7586 is not set -# CONFIG_TINYDRM_ST7735R is not set -# CONFIG_DRM_PL111 is not set -# CONFIG_DRM_TVE200 is not set +CONFIG_TINYDRM_REPAPER=m +CONFIG_TINYDRM_ST7586=m +CONFIG_TINYDRM_ST7735R=m +CONFIG_DRM_PL111=m +CONFIG_DRM_TVE200=m CONFIG_DRM_LIMA=m CONFIG_DRM_PANFROST=m -# CONFIG_DRM_MCDE is not set +CONFIG_DRM_MCDE=m CONFIG_DRM_TIDSS=m # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y @@ -4537,7 +4549,7 @@ CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_FB_CMDLINE=y CONFIG_FB_NOTIFY=y CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set +CONFIG_FIRMWARE_EDID=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -4618,22 +4630,29 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_CLUT224 is not set # end of Graphics support -CONFIG_SOUND=m -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y CONFIG_SND_PCM_ELD=y CONFIG_SND_PCM_IEC958=y -CONFIG_SND_DMAENGINE_PCM=m +CONFIG_SND_DMAENGINE_PCM=y CONFIG_SND_HWDEP=m CONFIG_SND_SEQ_DEVICE=m CONFIG_SND_RAWMIDI=m +CONFIG_SND_COMPRESS_OFFLOAD=y CONFIG_SND_JACK=y CONFIG_SND_JACK_INPUT_DEV=y -# CONFIG_SND_OSSEMUL is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_PCM_TIMER=y -# CONFIG_SND_HRTIMER is not set -# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_HRTIMER=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_PROC_FS=y CONFIG_SND_VERBOSE_PROCFS=y @@ -4641,19 +4660,24 @@ CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SEQUENCER_OSS=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y CONFIG_SND_SEQ_MIDI_EVENT=m CONFIG_SND_SEQ_MIDI=m CONFIG_SND_SEQ_VIRMIDI=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_AC97_CODEC=m CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m CONFIG_SND_ALOOP=m CONFIG_SND_VIRMIDI=m -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_MTS64 is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_PORTMAN2X4 is not set +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +# CONFIG_SND_AC97_POWER_SAVE is not set # # HD-Audio @@ -4661,8 +4685,8 @@ CONFIG_SND_VIRMIDI=m # end of HD-Audio CONFIG_SND_HDA_PREALLOC_SIZE=64 -# CONFIG_SND_ARM is not set -# CONFIG_SND_SPI is not set +CONFIG_SND_ARM=y +CONFIG_SND_SPI=y CONFIG_SND_USB=y CONFIG_SND_USB_AUDIO=m CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER=y @@ -4677,12 +4701,19 @@ CONFIG_SND_USB_POD=m CONFIG_SND_USB_PODHD=m CONFIG_SND_USB_TONEPORT=m CONFIG_SND_USB_VARIAX=m -CONFIG_SND_SOC=m +CONFIG_SND_SOC=y +CONFIG_SND_SOC_AC97_BUS=y CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y -# CONFIG_SND_SOC_AMD_ACP is not set -# CONFIG_SND_ATMEL_SOC is not set +CONFIG_SND_SOC_COMPRESS=y +CONFIG_SND_SOC_TOPOLOGY=y +CONFIG_SND_SOC_AMD_ACP=m +CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH=m +CONFIG_SND_SOC_AMD_CZ_RT5645_MACH=m +CONFIG_SND_ATMEL_SOC=m +CONFIG_SND_SOC_MIKROE_PROTO=m CONFIG_SND_BCM63XX_I2S_WHISTLER=m -# CONFIG_SND_DESIGNWARE_I2S is not set +CONFIG_SND_DESIGNWARE_I2S=m +CONFIG_SND_DESIGNWARE_PCM=y # # SoC Audio for Freescale CPUs @@ -4691,20 +4722,43 @@ CONFIG_SND_BCM63XX_I2S_WHISTLER=m # # Common SoC Audio options for Freescale CPUs: # -# CONFIG_SND_SOC_FSL_ASRC is not set -# CONFIG_SND_SOC_FSL_SAI is not set +CONFIG_SND_SOC_FSL_ASRC=m +CONFIG_SND_SOC_FSL_SAI=m +CONFIG_SND_SOC_FSL_MQS=m CONFIG_SND_SOC_FSL_AUDMIX=m -# CONFIG_SND_SOC_FSL_SSI is not set -# CONFIG_SND_SOC_FSL_SPDIF is not set -# CONFIG_SND_SOC_FSL_ESAI is not set -# CONFIG_SND_SOC_FSL_MICFIL is not set -# CONFIG_SND_SOC_IMX_AUDMUX is not set +CONFIG_SND_SOC_FSL_SSI=m +CONFIG_SND_SOC_FSL_SPDIF=m +CONFIG_SND_SOC_FSL_ESAI=m +CONFIG_SND_SOC_FSL_MICFIL=m +CONFIG_SND_SOC_IMX_AUDMUX=m # end of SoC Audio for Freescale CPUs -# CONFIG_SND_I2S_HI6210_I2S is not set -# CONFIG_SND_SOC_IMG is not set +CONFIG_SND_I2S_HI6210_I2S=m +CONFIG_SND_SOC_IMG=y +CONFIG_SND_SOC_IMG_I2S_IN=m +CONFIG_SND_SOC_IMG_I2S_OUT=m +CONFIG_SND_SOC_IMG_PARALLEL_OUT=m +CONFIG_SND_SOC_IMG_SPDIF_IN=m +CONFIG_SND_SOC_IMG_SPDIF_OUT=m +CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC=m CONFIG_SND_SOC_MTK_BTCVSD=m -# CONFIG_SND_SOC_SOF_TOPLEVEL is not set +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=m +CONFIG_SND_SOC_SOF_DEBUG_PROBES=y +CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT=y +CONFIG_SND_SOC_SOF_NOCODEC=m +CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT=y +CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS=y +CONFIG_SND_SOC_SOF_DEBUG=y +CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE=y +CONFIG_SND_SOC_SOF_DEBUG_XRUN_STOP=y +CONFIG_SND_SOC_SOF_DEBUG_VERBOSE_IPC=y +CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION=y +# CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE is not set +# CONFIG_SND_SOC_SOF_DEBUG_ENABLE_FIRMWARE_TRACE is not set +# CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST is not set +# CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT is not set +CONFIG_SND_SOC_SOF=m # # STMicroelectronics STM32 SOC audio support @@ -4714,174 +4768,193 @@ CONFIG_SND_SOC_MTK_BTCVSD=m # # Allwinner SoC Audio support # -CONFIG_SND_SUN4I_CODEC=m -CONFIG_SND_SUN8I_CODEC=m -CONFIG_SND_AC100_CODEC=m -CONFIG_SND_SUN8I_CODEC_ANALOG=m -CONFIG_SND_SUN4I_I2S=m -CONFIG_SND_SUN4I_SPDIF=m -CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m +CONFIG_SND_SUN4I_CODEC=y +CONFIG_SND_SUN8I_CODEC=y +CONFIG_SND_AC100_CODEC=y +CONFIG_SND_SUN8I_CODEC_ANALOG=y +CONFIG_SND_SUN4I_I2S=y +CONFIG_SND_SUN4I_SPDIF=y +CONFIG_SND_SUN8I_ADDA_PR_REGMAP=y # end of Allwinner SoC Audio support CONFIG_SND_SOC_XILINX_I2S=m CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER=m CONFIG_SND_SOC_XILINX_SPDIF=m -# CONFIG_SND_SOC_XTFPGA_I2S is not set -# CONFIG_ZX_TDM is not set -CONFIG_SND_SOC_I2C_AND_SPI=m +CONFIG_SND_SOC_XTFPGA_I2S=m +CONFIG_ZX_TDM=m +CONFIG_SND_SOC_I2C_AND_SPI=y # # CODEC drivers # -# CONFIG_SND_SOC_AC97_CODEC is not set -# CONFIG_SND_SOC_ADAU1701 is not set -# CONFIG_SND_SOC_ADAU1761_I2C is not set -# CONFIG_SND_SOC_ADAU1761_SPI is not set -# CONFIG_SND_SOC_ADAU7002 is not set +CONFIG_SND_SOC_AC97_CODEC=m +CONFIG_SND_SOC_ADAU_UTILS=m +CONFIG_SND_SOC_ADAU1701=m +CONFIG_SND_SOC_ADAU17X1=m +CONFIG_SND_SOC_ADAU1761=m +CONFIG_SND_SOC_ADAU1761_I2C=m +CONFIG_SND_SOC_ADAU1761_SPI=m +CONFIG_SND_SOC_ADAU7002=m CONFIG_SND_SOC_ADAU7118=m CONFIG_SND_SOC_ADAU7118_HW=m CONFIG_SND_SOC_ADAU7118_I2C=m -# CONFIG_SND_SOC_AK4104 is not set +CONFIG_SND_SOC_AK4104=m CONFIG_SND_SOC_AK4118=m CONFIG_SND_SOC_AK4458=m -# CONFIG_SND_SOC_AK4554 is not set -# CONFIG_SND_SOC_AK4613 is not set -# CONFIG_SND_SOC_AK4642 is not set -# CONFIG_SND_SOC_AK5386 is not set +CONFIG_SND_SOC_AK4554=m +CONFIG_SND_SOC_AK4613=m +CONFIG_SND_SOC_AK4642=m +CONFIG_SND_SOC_AK5386=m CONFIG_SND_SOC_AK5558=m -# CONFIG_SND_SOC_ALC5623 is not set +CONFIG_SND_SOC_ALC5623=m CONFIG_SND_SOC_BD28623=m -# CONFIG_SND_SOC_BT_SCO is not set +CONFIG_SND_SOC_BT_SCO=m CONFIG_SND_SOC_CPCAP=m -# CONFIG_SND_SOC_CS35L32 is not set -# CONFIG_SND_SOC_CS35L33 is not set -# CONFIG_SND_SOC_CS35L34 is not set +CONFIG_SND_SOC_CS35L32=m +CONFIG_SND_SOC_CS35L33=m +CONFIG_SND_SOC_CS35L34=m CONFIG_SND_SOC_CS35L35=m CONFIG_SND_SOC_CS35L36=m -# CONFIG_SND_SOC_CS42L42 is not set -# CONFIG_SND_SOC_CS42L51_I2C is not set -# CONFIG_SND_SOC_CS42L52 is not set -# CONFIG_SND_SOC_CS42L56 is not set -# CONFIG_SND_SOC_CS42L73 is not set -# CONFIG_SND_SOC_CS4265 is not set -# CONFIG_SND_SOC_CS4270 is not set -# CONFIG_SND_SOC_CS4271_I2C is not set -# CONFIG_SND_SOC_CS4271_SPI is not set -# CONFIG_SND_SOC_CS42XX8_I2C is not set -# CONFIG_SND_SOC_CS43130 is not set +CONFIG_SND_SOC_CS42L42=m +CONFIG_SND_SOC_CS42L51=m +CONFIG_SND_SOC_CS42L51_I2C=m +CONFIG_SND_SOC_CS42L52=m +CONFIG_SND_SOC_CS42L56=m +CONFIG_SND_SOC_CS42L73=m +CONFIG_SND_SOC_CS4265=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_CS4271=m +CONFIG_SND_SOC_CS4271_I2C=m +CONFIG_SND_SOC_CS4271_SPI=m +CONFIG_SND_SOC_CS42XX8=m +CONFIG_SND_SOC_CS42XX8_I2C=m +CONFIG_SND_SOC_CS43130=m CONFIG_SND_SOC_CS4341=m -# CONFIG_SND_SOC_CS4349 is not set -# CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_CX2072X is not set +CONFIG_SND_SOC_CS4349=m +CONFIG_SND_SOC_CS53L30=m +CONFIG_SND_SOC_CX2072X=m CONFIG_SND_SOC_DA7213=m +CONFIG_SND_SOC_DA7219=m CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_HDMI_CODEC=m -# CONFIG_SND_SOC_ES7134 is not set +CONFIG_SND_SOC_ES7134=m CONFIG_SND_SOC_ES7241=m -# CONFIG_SND_SOC_ES8316 is not set +CONFIG_SND_SOC_ES8316=m CONFIG_SND_SOC_ES8328=m CONFIG_SND_SOC_ES8328_I2C=m CONFIG_SND_SOC_ES8328_SPI=m -# CONFIG_SND_SOC_GTM601 is not set +CONFIG_SND_SOC_GTM601=m CONFIG_SND_SOC_EC25=m -# CONFIG_SND_SOC_INNO_RK3036 is not set +CONFIG_SND_SOC_INNO_RK3036=m CONFIG_SND_SOC_MAX98088=m -# CONFIG_SND_SOC_MAX98357A is not set -# CONFIG_SND_SOC_MAX98504 is not set +CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_MAX98504=m CONFIG_SND_SOC_MAX9867=m -# CONFIG_SND_SOC_MAX98927 is not set -# CONFIG_SND_SOC_MAX98373 is not set -# CONFIG_SND_SOC_MAX9860 is not set -# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set -# CONFIG_SND_SOC_PCM1681 is not set +CONFIG_SND_SOC_MAX98927=m +CONFIG_SND_SOC_MAX98373=m +CONFIG_SND_SOC_MAX9860=m +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m +CONFIG_SND_SOC_PCM1681=m CONFIG_SND_SOC_PCM1789=m CONFIG_SND_SOC_PCM1789_I2C=m -# CONFIG_SND_SOC_PCM179X_I2C is not set -# CONFIG_SND_SOC_PCM179X_SPI is not set +CONFIG_SND_SOC_PCM179X=m +CONFIG_SND_SOC_PCM179X_I2C=m +CONFIG_SND_SOC_PCM179X_SPI=m CONFIG_SND_SOC_PCM186X=m CONFIG_SND_SOC_PCM186X_I2C=m CONFIG_SND_SOC_PCM186X_SPI=m CONFIG_SND_SOC_PCM3060=m CONFIG_SND_SOC_PCM3060_I2C=m CONFIG_SND_SOC_PCM3060_SPI=m -# CONFIG_SND_SOC_PCM3168A_I2C is not set -# CONFIG_SND_SOC_PCM3168A_SPI is not set +CONFIG_SND_SOC_PCM3168A=m +CONFIG_SND_SOC_PCM3168A_I2C=m +CONFIG_SND_SOC_PCM3168A_SPI=m CONFIG_SND_SOC_PCM5102A=m CONFIG_SND_SOC_PCM512x=m CONFIG_SND_SOC_PCM512x_I2C=m CONFIG_SND_SOC_PCM512x_SPI=m CONFIG_SND_SOC_RK3328=m -# CONFIG_SND_SOC_RT5616 is not set -# CONFIG_SND_SOC_RT5631 is not set -# CONFIG_SND_SOC_SGTL5000 is not set +CONFIG_SND_SOC_RL6231=m +CONFIG_SND_SOC_RT5616=m +CONFIG_SND_SOC_RT5631=m +CONFIG_SND_SOC_RT5645=m +CONFIG_SND_SOC_SGTL5000=m +CONFIG_SND_SOC_SIGMADSP=m +CONFIG_SND_SOC_SIGMADSP_I2C=m +CONFIG_SND_SOC_SIGMADSP_REGMAP=m CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set CONFIG_SND_SOC_SPDIF=m -# CONFIG_SND_SOC_SSM2305 is not set -# CONFIG_SND_SOC_SSM2602_SPI is not set -# CONFIG_SND_SOC_SSM2602_I2C is not set -# CONFIG_SND_SOC_SSM4567 is not set -# CONFIG_SND_SOC_STA32X is not set -# CONFIG_SND_SOC_STA350 is not set -# CONFIG_SND_SOC_STI_SAS is not set -# CONFIG_SND_SOC_TAS2552 is not set +CONFIG_SND_SOC_SSM2305=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_SSM2602_SPI=m +CONFIG_SND_SOC_SSM2602_I2C=m +CONFIG_SND_SOC_SSM4567=m +CONFIG_SND_SOC_STA32X=m +CONFIG_SND_SOC_STA350=m +CONFIG_SND_SOC_STI_SAS=m +CONFIG_SND_SOC_TAS2552=m CONFIG_SND_SOC_TAS2562=m CONFIG_SND_SOC_TAS2770=m -# CONFIG_SND_SOC_TAS5086 is not set -# CONFIG_SND_SOC_TAS571X is not set -# CONFIG_SND_SOC_TAS5720 is not set +CONFIG_SND_SOC_TAS5086=m +CONFIG_SND_SOC_TAS571X=m +CONFIG_SND_SOC_TAS5720=m CONFIG_SND_SOC_TAS6424=m CONFIG_SND_SOC_TDA7419=m -# CONFIG_SND_SOC_TFA9879 is not set -# CONFIG_SND_SOC_TLV320AIC23_I2C is not set -# CONFIG_SND_SOC_TLV320AIC23_SPI is not set -# CONFIG_SND_SOC_TLV320AIC31XX is not set -# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set -# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set -# CONFIG_SND_SOC_TLV320AIC3X is not set +CONFIG_SND_SOC_TFA9879=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC23_I2C=m +CONFIG_SND_SOC_TLV320AIC23_SPI=m +CONFIG_SND_SOC_TLV320AIC31XX=m +CONFIG_SND_SOC_TLV320AIC32X4=m +CONFIG_SND_SOC_TLV320AIC32X4_I2C=m +CONFIG_SND_SOC_TLV320AIC32X4_SPI=m +CONFIG_SND_SOC_TLV320AIC3X=m CONFIG_SND_SOC_TLV320ADCX140=m -# CONFIG_SND_SOC_TS3A227E is not set -# CONFIG_SND_SOC_TSCS42XX is not set -# CONFIG_SND_SOC_TSCS454 is not set +CONFIG_SND_SOC_TS3A227E=m +CONFIG_SND_SOC_TSCS42XX=m +CONFIG_SND_SOC_TSCS454=m CONFIG_SND_SOC_UDA1334=m -# CONFIG_SND_SOC_WM8510 is not set -# CONFIG_SND_SOC_WM8523 is not set -# CONFIG_SND_SOC_WM8524 is not set -# CONFIG_SND_SOC_WM8580 is not set -# CONFIG_SND_SOC_WM8711 is not set -# CONFIG_SND_SOC_WM8728 is not set -# CONFIG_SND_SOC_WM8731 is not set -# CONFIG_SND_SOC_WM8737 is not set -# CONFIG_SND_SOC_WM8741 is not set -# CONFIG_SND_SOC_WM8750 is not set -# CONFIG_SND_SOC_WM8753 is not set -# CONFIG_SND_SOC_WM8770 is not set -# CONFIG_SND_SOC_WM8776 is not set -# CONFIG_SND_SOC_WM8782 is not set -# CONFIG_SND_SOC_WM8804_I2C is not set -# CONFIG_SND_SOC_WM8804_SPI is not set -# CONFIG_SND_SOC_WM8903 is not set +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8523=m +CONFIG_SND_SOC_WM8524=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8711=m +CONFIG_SND_SOC_WM8728=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8737=m +CONFIG_SND_SOC_WM8741=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8770=m +CONFIG_SND_SOC_WM8776=m +CONFIG_SND_SOC_WM8782=m +CONFIG_SND_SOC_WM8804=m +CONFIG_SND_SOC_WM8804_I2C=m +CONFIG_SND_SOC_WM8804_SPI=m +CONFIG_SND_SOC_WM8903=m CONFIG_SND_SOC_WM8904=m -# CONFIG_SND_SOC_WM8960 is not set -# CONFIG_SND_SOC_WM8962 is not set -# CONFIG_SND_SOC_WM8974 is not set -# CONFIG_SND_SOC_WM8978 is not set -# CONFIG_SND_SOC_WM8985 is not set -# CONFIG_SND_SOC_ZX_AUD96P22 is not set +CONFIG_SND_SOC_WM8960=m +CONFIG_SND_SOC_WM8962=m +CONFIG_SND_SOC_WM8974=m +CONFIG_SND_SOC_WM8978=m +CONFIG_SND_SOC_WM8985=m +CONFIG_SND_SOC_ZX_AUD96P22=m CONFIG_SND_SOC_MAX9759=m -# CONFIG_SND_SOC_MT6351 is not set +CONFIG_SND_SOC_MT6351=m CONFIG_SND_SOC_MT6358=m CONFIG_SND_SOC_MT6660=m CONFIG_SND_SOC_NAU8540=m -# CONFIG_SND_SOC_NAU8810 is not set +CONFIG_SND_SOC_NAU8810=m CONFIG_SND_SOC_NAU8822=m CONFIG_SND_SOC_NAU8824=m -# CONFIG_SND_SOC_TPA6130A2 is not set +CONFIG_SND_SOC_TPA6130A2=m # end of CODEC drivers -CONFIG_SND_SIMPLE_CARD_UTILS=m -CONFIG_SND_SIMPLE_CARD=m -# CONFIG_SND_AUDIO_GRAPH_CARD is not set +CONFIG_SND_SIMPLE_CARD_UTILS=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_AUDIO_GRAPH_CARD=y +CONFIG_AC97_BUS=y # # HID support @@ -4901,7 +4974,7 @@ CONFIG_HID_ACRUX=m CONFIG_HID_ACRUX_FF=y CONFIG_HID_APPLE=m CONFIG_HID_APPLEIR=m -# CONFIG_HID_ASUS is not set +CONFIG_HID_ASUS=m CONFIG_HID_AUREAL=m CONFIG_HID_BELKIN=m CONFIG_HID_BETOP_FF=m @@ -4912,7 +4985,7 @@ CONFIG_HID_CORSAIR=m CONFIG_HID_COUGAR=m CONFIG_HID_MACALLY=m CONFIG_HID_PRODIKEYS=m -# CONFIG_HID_CMEDIA is not set +CONFIG_HID_CMEDIA=m CONFIG_HID_CP2112=m CONFIG_HID_CREATIVE_SB0540=m CONFIG_HID_CYPRESS=m @@ -4972,14 +5045,14 @@ CONFIG_HID_PICOLCD_LEDS=y CONFIG_HID_PICOLCD_CIR=y CONFIG_HID_PLANTRONICS=m CONFIG_HID_PRIMAX=m -# CONFIG_HID_RETRODE is not set +CONFIG_HID_RETRODE=m CONFIG_HID_ROCCAT=m CONFIG_HID_SAITEK=m CONFIG_HID_SAMSUNG=m CONFIG_HID_SONY=m CONFIG_SONY_FF=y CONFIG_HID_SPEEDLINK=m -# CONFIG_HID_STEAM is not set +CONFIG_HID_STEAM=m CONFIG_HID_STEELSERIES=m CONFIG_HID_SUNPLUS=m CONFIG_HID_RMI=m @@ -4992,7 +5065,7 @@ CONFIG_HID_TOPSEED=m CONFIG_HID_THINGM=m CONFIG_HID_THRUSTMASTER=m CONFIG_THRUSTMASTER_FF=y -# CONFIG_HID_UDRAW_PS3 is not set +CONFIG_HID_UDRAW_PS3=m CONFIG_HID_U2FZERO=m CONFIG_HID_WACOM=m CONFIG_HID_WIIMOTE=m @@ -5035,7 +5108,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y -# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_OTG=y # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set @@ -5056,16 +5129,18 @@ CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_EHCI_FSL=m CONFIG_USB_EHCI_HCD_PLATFORM=y -# CONFIG_USB_OXU210HP_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_FOTG210_HCD is not set -# CONFIG_USB_MAX3421_HCD is not set +CONFIG_USB_OXU210HP_HCD=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_FOTG210_HCD=m +CONFIG_USB_MAX3421_HCD=m CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HCD_BCMA is not set -# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_U132_HCD is not set +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_HCD_ISO=y +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_HCD_BCMA=m +CONFIG_USB_HCD_SSB=m # CONFIG_USB_HCD_TEST_MODE is not set # @@ -5085,26 +5160,27 @@ CONFIG_USB_TMC=m # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_REALTEK is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set -# CONFIG_USB_STORAGE_ENE_UB6250 is not set +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m CONFIG_USB_UAS=m # # USB Imaging devices # -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m CONFIG_USBIP_CORE=m CONFIG_USBIP_VHCI_HCD=m CONFIG_USBIP_VHCI_HC_PORTS=8 @@ -5121,7 +5197,7 @@ CONFIG_USB_MUSB_DUAL_ROLE=y # # Platform Glue Layer # -CONFIG_USB_MUSB_SUNXI=y +CONFIG_USB_MUSB_SUNXI=m # # MUSB DMA mode @@ -5216,40 +5292,47 @@ CONFIG_USB_SERIAL_DEBUG=m # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_SEVSEG=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m CONFIG_APPLE_MFI_FASTCHARGE=m -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set -# CONFIG_USB_EHSET_TEST_FIXTURE is not set -# CONFIG_USB_ISIGHTFW is not set -# CONFIG_USB_YUREX is not set +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_TEST=m +CONFIG_USB_EHSET_TEST_FIXTURE=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m CONFIG_USB_EZUSB_FX2=m CONFIG_USB_HUB_USB251XB=m -# CONFIG_USB_HSIC_USB3503 is not set -# CONFIG_USB_HSIC_USB4604 is not set -# CONFIG_USB_LINK_LAYER_TEST is not set +CONFIG_USB_HSIC_USB3503=m +CONFIG_USB_HSIC_USB4604=m +CONFIG_USB_LINK_LAYER_TEST=m CONFIG_USB_CHAOSKEY=m -# CONFIG_USB_ATM is not set +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m # # USB Physical Layer drivers # CONFIG_USB_PHY=y -CONFIG_NOP_USB_XCEIV=y -# CONFIG_AM335X_PHY_USB is not set -# CONFIG_USB_GPIO_VBUS is not set -# CONFIG_USB_ISP1301 is not set -# CONFIG_USB_ULPI is not set +CONFIG_NOP_USB_XCEIV=m +CONFIG_AM335X_CONTROL_USB=m +CONFIG_AM335X_PHY_USB=m +CONFIG_USB_GPIO_VBUS=m +CONFIG_USB_ISP1301=m +CONFIG_USB_ULPI=y +CONFIG_USB_ULPI_VIEWPORT=y # end of USB Physical Layer drivers CONFIG_USB_GADGET=y @@ -5281,6 +5364,7 @@ CONFIG_USB_MAX3420_UDC=m CONFIG_USB_LIBCOMPOSITE=m CONFIG_USB_F_ACM=m +CONFIG_USB_F_SS_LB=m CONFIG_USB_U_SERIAL=m CONFIG_USB_U_ETHER=m CONFIG_USB_U_AUDIO=m @@ -5292,11 +5376,35 @@ CONFIG_USB_F_EEM=m CONFIG_USB_F_SUBSET=m CONFIG_USB_F_RNDIS=m CONFIG_USB_F_MASS_STORAGE=m +CONFIG_USB_F_FS=m CONFIG_USB_F_UAC1=m +CONFIG_USB_F_UAC1_LEGACY=m +CONFIG_USB_F_UAC2=m CONFIG_USB_F_UVC=m +CONFIG_USB_F_MIDI=m CONFIG_USB_F_HID=m CONFIG_USB_F_PRINTER=m -# CONFIG_USB_CONFIGFS is not set +CONFIG_USB_F_TCM=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_USB_CONFIGFS_F_PRINTER=y +CONFIG_USB_CONFIGFS_F_TCM=y # # USB Gadget precomposed configurations @@ -5312,7 +5420,7 @@ CONFIG_USB_G_NCM=m CONFIG_USB_GADGETFS=m # CONFIG_USB_FUNCTIONFS is not set CONFIG_USB_MASS_STORAGE=m -# CONFIG_USB_GADGET_TARGET is not set +CONFIG_USB_GADGET_TARGET=m CONFIG_USB_G_SERIAL=m # CONFIG_USB_MIDI_GADGET is not set CONFIG_USB_G_PRINTER=m @@ -5320,14 +5428,37 @@ CONFIG_USB_CDC_COMPOSITE=m CONFIG_USB_G_ACM_MS=m CONFIG_USB_G_MULTI=m CONFIG_USB_G_MULTI_RNDIS=y -# CONFIG_USB_G_MULTI_CDC is not set +CONFIG_USB_G_MULTI_CDC=y CONFIG_USB_G_HID=m # CONFIG_USB_G_DBGP is not set CONFIG_USB_G_WEBCAM=m CONFIG_USB_RAW_GADGET=m # end of USB Gadget precomposed configurations -# CONFIG_TYPEC is not set +CONFIG_TYPEC=m +CONFIG_TYPEC_TCPM=m +CONFIG_TYPEC_TCPCI=m +CONFIG_TYPEC_RT1711H=m +CONFIG_TYPEC_FUSB302=m +CONFIG_TYPEC_UCSI=m +CONFIG_UCSI_CCG=m +CONFIG_TYPEC_ANX7688=m +CONFIG_TYPEC_HD3SS3220=m +CONFIG_TYPEC_TPS6598X=m + +# +# USB Type-C Multiplexer/DeMultiplexer Switch support +# +CONFIG_TYPEC_MUX_PI3USB30532=m +# end of USB Type-C Multiplexer/DeMultiplexer Switch support + +# +# USB Type-C Alternate Mode drivers +# +CONFIG_TYPEC_DP_ALTMODE=m +CONFIG_TYPEC_NVIDIA_ALTMODE=m +# end of USB Type-C Alternate Mode drivers + CONFIG_USB_ROLE_SWITCH=y CONFIG_MMC=y CONFIG_PWRSEQ_EMMC=m @@ -5365,40 +5496,43 @@ CONFIG_LEDS_CLASS_FLASH=m # # CONFIG_LEDS_AAT1290 is not set CONFIG_LEDS_AN30259A=m -# CONFIG_LEDS_AS3645A is not set -# CONFIG_LEDS_BCM6328 is not set -# CONFIG_LEDS_BCM6358 is not set +CONFIG_LEDS_AS3645A=m +CONFIG_LEDS_BCM6328=m +CONFIG_LEDS_BCM6358=m CONFIG_LEDS_CPCAP=m CONFIG_LEDS_CR0014114=m CONFIG_LEDS_EL15203000=m -# CONFIG_LEDS_LM3530 is not set +CONFIG_LEDS_LM3530=m CONFIG_LEDS_LM3532=m -# CONFIG_LEDS_LM3642 is not set +CONFIG_LEDS_LM3642=m CONFIG_LEDS_LM3692X=m -# CONFIG_LEDS_LM3601X is not set -# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_LM3601X=m +CONFIG_LEDS_PCA9532=m +# CONFIG_LEDS_PCA9532_GPIO is not set CONFIG_LEDS_GPIO=y -# CONFIG_LEDS_LP3944 is not set -# CONFIG_LEDS_LP3952 is not set -# CONFIG_LEDS_LP5521 is not set -# CONFIG_LEDS_LP5523 is not set -# CONFIG_LEDS_LP5562 is not set -# CONFIG_LEDS_LP8501 is not set -# CONFIG_LEDS_LP8860 is not set -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_PCA963X is not set -# CONFIG_LEDS_DAC124S085 is not set +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP3952=m +CONFIG_LEDS_LP55XX_COMMON=m +CONFIG_LEDS_LP5521=m +CONFIG_LEDS_LP5523=m +CONFIG_LEDS_LP5562=m +CONFIG_LEDS_LP8501=m +CONFIG_LEDS_LP8860=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_PCA955X_GPIO=y +CONFIG_LEDS_PCA963X=m +CONFIG_LEDS_DAC124S085=m CONFIG_LEDS_PWM=m CONFIG_LEDS_REGULATOR=m -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -# CONFIG_LEDS_TCA6507 is not set -# CONFIG_LEDS_TLC591XX is not set +CONFIG_LEDS_BD2802=m +CONFIG_LEDS_LT3593=m +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_TLC591XX=m CONFIG_LEDS_MAX77650=m -# CONFIG_LEDS_LM355x is not set -# CONFIG_LEDS_KTD2692 is not set -# CONFIG_LEDS_IS31FL319X is not set -# CONFIG_LEDS_IS31FL32XX is not set +CONFIG_LEDS_LM355x=m +CONFIG_LEDS_KTD2692=m +CONFIG_LEDS_IS31FL319X=m +CONFIG_LEDS_IS31FL32XX=m # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) @@ -5407,8 +5541,9 @@ CONFIG_LEDS_MAX77650=m CONFIG_LEDS_SYSCON=y CONFIG_LEDS_MLXREG=m CONFIG_LEDS_USER=y -# CONFIG_LEDS_SPI_BYTE is not set -# CONFIG_LEDS_TI_LMU_COMMON is not set +CONFIG_LEDS_SPI_BYTE=m +CONFIG_LEDS_TI_LMU_COMMON=m +CONFIG_LEDS_LM3697=m CONFIG_LEDS_AXP20X=m # @@ -5440,6 +5575,7 @@ CONFIG_LEDS_TRIGGER_AUDIO=m CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y CONFIG_RTC_LIB=y +CONFIG_RTC_MC146818_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" @@ -5466,24 +5602,26 @@ CONFIG_RTC_DRV_ABEOZ9=m CONFIG_RTC_DRV_AC100=m CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_DS1307_CENTURY is not set -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_HYM8563 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1374_WDT=y +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_HYM8563=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m CONFIG_RTC_DRV_ISL12026=m -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8523 is not set -# CONFIG_RTC_DRV_PCF85063 is not set -# CONFIG_RTC_DRV_PCF85363 is not set +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF85063=m +CONFIG_RTC_DRV_PCF85363=m CONFIG_RTC_DRV_PCF8563=m -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -# CONFIG_RTC_DRV_BQ32K is not set -# CONFIG_RTC_DRV_S35390A is not set -# CONFIG_RTC_DRV_FM3130 is not set +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_BQ32K=y +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_FM3130=m # CONFIG_RTC_DRV_RX8010 is not set # CONFIG_RTC_DRV_RX8581 is not set # CONFIG_RTC_DRV_RX8025 is not set @@ -5495,49 +5633,56 @@ CONFIG_RTC_DRV_SD3078=m # # SPI RTC drivers # -# CONFIG_RTC_DRV_M41T93 is not set -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1302 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1343 is not set -# CONFIG_RTC_DRV_DS1347 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6916 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RX4581 is not set -# CONFIG_RTC_DRV_RX6110 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_PCF2123 is not set -# CONFIG_RTC_DRV_MCP795 is not set +CONFIG_RTC_DRV_M41T93=m +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_DS1302=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1343=m +CONFIG_RTC_DRV_DS1347=m +CONFIG_RTC_DRV_DS1390=m +CONFIG_RTC_DRV_MAX6916=m +CONFIG_RTC_DRV_R9701=m +CONFIG_RTC_DRV_RX4581=m +CONFIG_RTC_DRV_RX6110=m +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF2123=m +CONFIG_RTC_DRV_MCP795=m CONFIG_RTC_I2C_AND_SPI=y # # SPI and I2C RTC drivers # -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_PCF2127 is not set -# CONFIG_RTC_DRV_RV3029C2 is not set +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_DS3232_HWMON=y +CONFIG_RTC_DRV_PCF2127=m +CONFIG_RTC_DRV_RV3029C2=m +CONFIG_RTC_DRV_RV3029_HWMON=y # # Platform RTC drivers # -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1685_FAMILY is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_DS2404 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set -# CONFIG_RTC_DRV_ZYNQMP is not set +CONFIG_RTC_DRV_CMOS=m +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1685_FAMILY=m +CONFIG_RTC_DRV_DS1685=y +# CONFIG_RTC_DRV_DS1689 is not set +# CONFIG_RTC_DRV_DS17285 is not set +# CONFIG_RTC_DRV_DS17485 is not set +# CONFIG_RTC_DRV_DS17885 is not set +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS2404=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_ZYNQMP=m # # on-CPU RTC drivers @@ -5545,14 +5690,14 @@ CONFIG_RTC_I2C_AND_SPI=y CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y CONFIG_RTC_DRV_CADENCE=m -# CONFIG_RTC_DRV_FTRTC010 is not set -# CONFIG_RTC_DRV_R7301 is not set +CONFIG_RTC_DRV_FTRTC010=m +CONFIG_RTC_DRV_R7301=m CONFIG_RTC_DRV_CPCAP=m # # HID Sensor RTC drivers # -# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_RTC_DRV_HID_SENSOR_TIME=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set diff --git a/patch/kernel/sunxi-current/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch b/patch/kernel/sunxi-current/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch new file mode 100644 index 000000000..6967ba0cd --- /dev/null +++ b/patch/kernel/sunxi-current/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch @@ -0,0 +1,637 @@ +Add HDMI audio support for the sun4i-hdmi encoder, used on +the older Allwinner chips - A10, A20, A31. + +Most of the code is based on the BSP implementation. In it +dditional formats are supported (S20_3LE and S24_LE), however +there where some problems with them and only S16_LE is left. + +Signed-off-by: Stefan Mavrodiev +--- +Changes for v3: + - Instead of platfrom_driver dynammicly register/unregister card + - Add Kconfig dependencies + - Restrore drvdata after card unregistering + +Changes for v2: + - Create a new platform driver instead of using the HDMI encoder + - Expose a new kcontrol to the userspace holding the ELD data + - Wrap all macro arguments in parentheses + + drivers/gpu/drm/sun4i/Kconfig | 11 + + drivers/gpu/drm/sun4i/Makefile | 3 + + drivers/gpu/drm/sun4i/sun4i_hdmi.h | 37 ++ + drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c | 450 +++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 14 + + 5 files changed, 515 insertions(+) + create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c + +diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig +index 37e90e42943f..ca2ab5d53dd4 100644 +--- a/drivers/gpu/drm/sun4i/Kconfig ++++ b/drivers/gpu/drm/sun4i/Kconfig +@@ -23,6 +23,17 @@ config DRM_SUN4I_HDMI + Choose this option if you have an Allwinner SoC with an HDMI + controller. + ++config DRM_SUN4I_HDMI_AUDIO ++ bool "Allwinner A10 HDMI Audio Support" ++ default y ++ depends on DRM_SUN4I_HDMI ++ depends on SND_SOC=y || SND_SOC=DRM_SUN4I_HDMI ++ select SND_PCM_ELD ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ help ++ Choose this option if you have an Allwinner SoC with an HDMI ++ controller and want to use audio. ++ + config DRM_SUN4I_HDMI_CEC + bool "Allwinner A10 HDMI CEC Support" + depends on DRM_SUN4I_HDMI +diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile +index 0d04f2447b01..492bfd28ad2e 100644 +--- a/drivers/gpu/drm/sun4i/Makefile ++++ b/drivers/gpu/drm/sun4i/Makefile +@@ -5,6 +5,9 @@ sun4i-frontend-y += sun4i_frontend.o + sun4i-drm-y += sun4i_drv.o + sun4i-drm-y += sun4i_framebuffer.o + ++ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++sun4i-drm-hdmi-y += sun4i_hdmi_audio.o ++endif + sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o + sun4i-drm-hdmi-y += sun4i_hdmi_enc.o + sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h +index 7ad3f06c127e..28621d289655 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h +@@ -42,7 +42,32 @@ + #define SUN4I_HDMI_VID_TIMING_POL_VSYNC BIT(1) + #define SUN4I_HDMI_VID_TIMING_POL_HSYNC BIT(0) + ++#define SUN4I_HDMI_AUDIO_CTRL_REG 0x040 ++#define SUN4I_HDMI_AUDIO_CTRL_ENABLE BIT(31) ++#define SUN4I_HDMI_AUDIO_CTRL_RESET BIT(30) ++ ++#define SUN4I_HDMI_AUDIO_FMT_REG 0x048 ++#define SUN4I_HDMI_AUDIO_FMT_SRC BIT(31) ++#define SUN4I_HDMI_AUDIO_FMT_LAYOUT BIT(3) ++#define SUN4I_HDMI_AUDIO_FMT_CH_CFG(n) ((n) - 1) ++#define SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK GENMASK(2, 0) ++ ++#define SUN4I_HDMI_AUDIO_PCM_REG 0x4c ++#define SUN4I_HDMI_AUDIO_PCM_CH_MAP(n, m) (((m) - 1) << ((n) * 4)) ++#define SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(n) (GENMASK(2, 0) << ((n) * 4)) ++ ++#define SUN4I_HDMI_AUDIO_CTS_REG 0x050 ++#define SUN4I_HDMI_AUDIO_CTS(n) ((n) & GENMASK(19, 0)) ++ ++#define SUN4I_HDMI_AUDIO_N_REG 0x054 ++#define SUN4I_HDMI_AUDIO_N(n) ((n) & GENMASK(19, 0)) ++ ++#define SUN4I_HDMI_AUDIO_STAT0_REG 0x58 ++#define SUN4I_HDMI_AUDIO_STAT0_FREQ(n) ((n) << 24) ++#define SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK GENMASK(27, 24) ++ + #define SUN4I_HDMI_AVI_INFOFRAME_REG(n) (0x080 + (n)) ++#define SUN4I_HDMI_AUDIO_INFOFRAME_REG(n) (0x0a0 + (n)) + + #define SUN4I_HDMI_PAD_CTRL0_REG 0x200 + #define SUN4I_HDMI_PAD_CTRL0_BIASEN BIT(31) +@@ -242,6 +267,11 @@ struct sun4i_hdmi_variant { + bool ddc_fifo_has_dir; + }; + ++struct sun4i_hdmi_audio { ++ struct snd_soc_card *card; ++ u8 channels; ++}; ++ + struct sun4i_hdmi { + struct drm_connector connector; + struct drm_encoder encoder; +@@ -283,9 +313,14 @@ struct sun4i_hdmi { + struct regmap_field *field_ddc_sda_en; + struct regmap_field *field_ddc_sck_en; + ++ + struct sun4i_drv *drv; + + bool hdmi_monitor; ++ bool hdmi_audio; ++ ++ struct sun4i_hdmi_audio audio; ++ + struct cec_adapter *cec_adap; + + const struct sun4i_hdmi_variant *variant; +@@ -294,5 +329,7 @@ struct sun4i_hdmi { + int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk); + int sun4i_tmds_create(struct sun4i_hdmi *hdmi); + int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi); ++int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi); ++void sun4i_hdmi_audio_destroy(struct sun4i_hdmi *hdmi); + + #endif /* _SUN4I_HDMI_H_ */ +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c +new file mode 100644 +index 000000000000..f42f2cea4e9e +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c +@@ -0,0 +1,450 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (C) 2020 Olimex Ltd. ++ * Author: Stefan Mavrodiev ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "sun4i_hdmi.h" ++ ++static int sun4i_hdmi_audio_ctl_eld_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; ++ uinfo->count = MAX_ELD_BYTES; ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_ctl_eld_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct snd_soc_card *card = snd_soc_component_get_drvdata(component); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ ++ memcpy(ucontrol->value.bytes.data, ++ hdmi->connector.eld, ++ MAX_ELD_BYTES); ++ ++ return 0; ++} ++ ++static const struct snd_kcontrol_new sun4i_hdmi_audio_controls[] = { ++ { ++ .access = SNDRV_CTL_ELEM_ACCESS_READ | ++ SNDRV_CTL_ELEM_ACCESS_VOLATILE, ++ .iface = SNDRV_CTL_ELEM_IFACE_PCM, ++ .name = "ELD", ++ .info = sun4i_hdmi_audio_ctl_eld_info, ++ .get = sun4i_hdmi_audio_ctl_eld_get, ++ }, ++}; ++ ++static const struct snd_soc_dapm_widget sun4i_hdmi_audio_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("TX"), ++}; ++ ++static const struct snd_soc_dapm_route sun4i_hdmi_audio_routes[] = { ++ { "TX", NULL, "Playback" }, ++}; ++ ++static const struct snd_soc_component_driver sun4i_hdmi_audio_component = { ++ .controls = sun4i_hdmi_audio_controls, ++ .num_controls = ARRAY_SIZE(sun4i_hdmi_audio_controls), ++ .dapm_widgets = sun4i_hdmi_audio_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(sun4i_hdmi_audio_widgets), ++ .dapm_routes = sun4i_hdmi_audio_routes, ++ .num_dapm_routes = ARRAY_SIZE(sun4i_hdmi_audio_routes), ++}; ++ ++static int sun4i_hdmi_audio_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ u32 reg; ++ int ret; ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ SUN4I_HDMI_AUDIO_CTRL_RESET); ++ ret = regmap_read_poll_timeout(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ reg, !reg, 100, 50000); ++ if (ret < 0) { ++ DRM_ERROR("Failed to reset HDMI Audio\n"); ++ return ret; ++ } ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ SUN4I_HDMI_AUDIO_CTRL_ENABLE); ++ ++ return snd_pcm_hw_constraint_eld(substream->runtime, ++ hdmi->connector.eld); ++} ++ ++static void sun4i_hdmi_audio_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); ++} ++ ++static int sun4i_hdmi_setup_audio_infoframes(struct sun4i_hdmi *hdmi) ++{ ++ union hdmi_infoframe frame; ++ u8 buffer[14]; ++ int i, ret; ++ ++ ret = hdmi_audio_infoframe_init(&frame.audio); ++ if (ret < 0) { ++ DRM_ERROR("Failed to init HDMI audio infoframe\n"); ++ return ret; ++ } ++ ++ frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; ++ frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; ++ frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; ++ frame.audio.channels = hdmi->audio.channels; ++ ++ ret = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); ++ if (ret < 0) { ++ DRM_ERROR("Failed to pack HDMI audio infoframe\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < sizeof(buffer); i++) ++ writeb(buffer[i], ++ hdmi->base + SUN4I_HDMI_AUDIO_INFOFRAME_REG(i)); ++ ++ return 0; ++} ++ ++static void sun4i_hdmi_audio_set_cts_n(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ struct drm_encoder *encoder = &hdmi->encoder; ++ struct drm_crtc *crtc = encoder->crtc; ++ const struct drm_display_mode *mode = &crtc->state->adjusted_mode; ++ u32 rate = params_rate(params); ++ u32 n, cts; ++ u64 tmp; ++ ++ /** ++ * Calculate Cycle Time Stamp (CTS) and Numerator (N): ++ * ++ * N = 128 * Samplerate / 1000 ++ * CTS = (Ftdms * N) / (128 * Samplerate) ++ */ ++ ++ n = 128 * rate / 1000; ++ tmp = (u64)(mode->clock * 1000) * n; ++ do_div(tmp, 128 * rate); ++ cts = tmp; ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTS_REG, ++ SUN4I_HDMI_AUDIO_CTS(cts)); ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_N_REG, ++ SUN4I_HDMI_AUDIO_N(n)); ++} ++ ++static int sun4i_hdmi_audio_set_hw_rate(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ u32 rate = params_rate(params); ++ u32 val; ++ ++ switch (rate) { ++ case 44100: ++ val = 0x0; ++ break; ++ case 48000: ++ val = 0x2; ++ break; ++ case 32000: ++ val = 0x3; ++ break; ++ case 88200: ++ val = 0x8; ++ break; ++ case 96000: ++ val = 0x9; ++ break; ++ case 176400: ++ val = 0xc; ++ break; ++ case 192000: ++ val = 0xe; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_STAT0_REG, ++ SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK, ++ SUN4I_HDMI_AUDIO_STAT0_FREQ(val)); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_set_hw_channels(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ u32 channels = params_channels(params); ++ ++ if (channels > 8) ++ return -EINVAL; ++ ++ hdmi->audio.channels = channels; ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_FMT_REG, ++ SUN4I_HDMI_AUDIO_FMT_LAYOUT, ++ (channels > 2) ? SUN4I_HDMI_AUDIO_FMT_LAYOUT : 0); ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_FMT_REG, ++ SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK, ++ SUN4I_HDMI_AUDIO_FMT_CH_CFG(channels)); ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_PCM_REG, 0x76543210); ++ ++ /** ++ * If only one channel is required, send the same sample ++ * to the sink device as a left and right channel. ++ */ ++ if (channels == 1) ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_PCM_REG, ++ SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(1), ++ SUN4I_HDMI_AUDIO_PCM_CH_MAP(1, 1)); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ int ret; ++ ++ ret = sun4i_hdmi_audio_set_hw_rate(hdmi, params); ++ if (ret < 0) ++ return ret; ++ ++ ret = sun4i_hdmi_audio_set_hw_channels(hdmi, params); ++ if (ret < 0) ++ return ret; ++ ++ sun4i_hdmi_audio_set_cts_n(hdmi, params); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_trigger(struct snd_pcm_substream *substream, ++ int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ int ret = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ ret = sun4i_hdmi_setup_audio_infoframes(hdmi); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct snd_soc_dai_ops sun4i_hdmi_audio_dai_ops = { ++ .startup = sun4i_hdmi_audio_startup, ++ .shutdown = sun4i_hdmi_audio_shutdown, ++ .hw_params = sun4i_hdmi_audio_hw_params, ++ .trigger = sun4i_hdmi_audio_trigger, ++}; ++ ++static int sun4i_hdmi_audio_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct snd_dmaengine_dai_dma_data *dma_data; ++ ++ dma_data = devm_kzalloc(dai->dev, sizeof(*dma_data), GFP_KERNEL); ++ if (!dma_data) ++ return -ENOMEM; ++ ++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dma_data->maxburst = 8; ++ ++ snd_soc_dai_init_dma_data(dai, dma_data, NULL); ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_driver sun4i_hdmi_audio_dai = { ++ .name = "HDMI", ++ .ops = &sun4i_hdmi_audio_dai_ops, ++ .probe = sun4i_hdmi_audio_dai_probe, ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 1, ++ .channels_max = 8, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ }, ++}; ++ ++static const struct snd_pcm_hardware sun4i_hdmi_audio_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE | ++ SNDRV_PCM_INFO_RESUME, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .rate_min = 8000, ++ .rate_max = 192000, ++ .channels_min = 1, ++ .channels_max = 8, ++ .buffer_bytes_max = 128 * 1024, ++ .period_bytes_min = 4 * 1024, ++ .period_bytes_max = 32 * 1024, ++ .periods_min = 2, ++ .periods_max = 8, ++ .fifo_size = 128, ++}; ++ ++static const struct snd_dmaengine_pcm_config sun4i_hdmi_audio_pcm_config = { ++ .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-tx", ++ .pcm_hardware = &sun4i_hdmi_audio_pcm_hardware, ++ .prealloc_buffer_size = 128 * 1024, ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++}; ++ ++struct snd_soc_card sun4i_hdmi_audio_card = { ++ .name = "sun4i-hdmi", ++}; ++ ++int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi) ++{ ++ struct snd_soc_card *card = &sun4i_hdmi_audio_card; ++ struct snd_soc_dai_link_component *comp; ++ struct snd_soc_dai_link *link; ++ int ret; ++ ++ ret = snd_dmaengine_pcm_register(hdmi->dev, ++ &sun4i_hdmi_audio_pcm_config, 0); ++ if (ret < 0) { ++ DRM_ERROR("Could not register PCM\n"); ++ return ret; ++ } ++ ++ ret = snd_soc_register_component(hdmi->dev, ++ &sun4i_hdmi_audio_component, ++ &sun4i_hdmi_audio_dai, 1); ++ if (ret < 0) { ++ DRM_ERROR("Could not register DAI\n"); ++ goto unregister_pcm; ++ } ++ ++ link = devm_kzalloc(hdmi->dev, sizeof(*link), GFP_KERNEL); ++ if (!link) { ++ ret = -ENOMEM; ++ goto unregister_component; ++ } ++ ++ comp = devm_kzalloc(hdmi->dev, sizeof(*comp) * 3, GFP_KERNEL); ++ if (!comp) { ++ ret = -ENOMEM; ++ goto unregister_component; ++ } ++ ++ link->cpus = &comp[0]; ++ link->codecs = &comp[1]; ++ link->platforms = &comp[2]; ++ ++ link->num_cpus = 1; ++ link->num_codecs = 1; ++ link->num_platforms = 1; ++ ++ link->playback_only = 1; ++ ++ link->name = "SUN4I-HDMI"; ++ link->stream_name = "SUN4I-HDMI PCM"; ++ ++ link->codecs->name = dev_name(hdmi->dev); ++ link->codecs->dai_name = sun4i_hdmi_audio_dai.name; ++ ++ link->cpus->dai_name = dev_name(hdmi->dev); ++ ++ link->platforms->name = dev_name(hdmi->dev); ++ ++ link->dai_fmt = SND_SOC_DAIFMT_I2S; ++ ++ card->dai_link = link; ++ card->num_links = 1; ++ card->dev = hdmi->dev; ++ ++ hdmi->audio.card = card; ++ ++ /** ++ * snd_soc_register_card() will overwrite the driver_data pointer. ++ * So before registering the card, store the original pointer in ++ * card->drvdata. ++ */ ++ snd_soc_card_set_drvdata(card, hdmi); ++ ret = snd_soc_register_card(card); ++ if (ret) ++ goto unregister_component; ++ ++ return 0; ++ ++unregister_component: ++ snd_soc_unregister_component(hdmi->dev); ++unregister_pcm: ++ snd_dmaengine_pcm_unregister(hdmi->dev); ++ return ret; ++} ++ ++void sun4i_hdmi_audio_destroy(struct sun4i_hdmi *hdmi) ++{ ++ struct snd_soc_card *card = hdmi->audio.card; ++ void *data; ++ ++ /** ++ * Before removing the card, restore the previously stored driver_data. ++ * This will ensure proper removal of the sun4i-hdmi module, since it ++ * uses dev_get_drvdata() in the unbind function. ++ */ ++ data = snd_soc_card_get_drvdata(card); ++ ++ snd_soc_unregister_card(card); ++ snd_soc_unregister_component(hdmi->dev); ++ snd_dmaengine_pcm_unregister(hdmi->dev); ++ ++ dev_set_drvdata(hdmi->dev, data); ++} +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +index 68d4644ac2dc..4cd35c97c503 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + #include "sun4i_backend.h" + #include "sun4i_crtc.h" + #include "sun4i_drv.h" +@@ -87,6 +89,10 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder) + + DRM_DEBUG_DRIVER("Disabling the HDMI Output\n"); + ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ sun4i_hdmi_audio_destroy(hdmi); ++#endif ++ + val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG); + val &= ~SUN4I_HDMI_VID_CTRL_ENABLE; + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); +@@ -114,6 +120,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder) + val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; + + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); ++ ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ if (hdmi->hdmi_audio && sun4i_hdmi_audio_create(hdmi)) ++ DRM_ERROR("Couldn't create the HDMI audio adapter\n"); ++#endif + } + + static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, +@@ -218,6 +229,9 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector) + if (!edid) + return 0; + ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ hdmi->hdmi_audio = drm_detect_monitor_audio(edid); ++#endif + hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid); + DRM_DEBUG_DRIVER("Monitor is %s monitor\n", + hdmi->hdmi_monitor ? "an HDMI" : "a DVI"); diff --git a/patch/kernel/sunxi-dev/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch b/patch/kernel/sunxi-dev/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch new file mode 100644 index 000000000..6967ba0cd --- /dev/null +++ b/patch/kernel/sunxi-dev/Add_HDMI_audio_support_for_the_sun4i-hdmi.patch @@ -0,0 +1,637 @@ +Add HDMI audio support for the sun4i-hdmi encoder, used on +the older Allwinner chips - A10, A20, A31. + +Most of the code is based on the BSP implementation. In it +dditional formats are supported (S20_3LE and S24_LE), however +there where some problems with them and only S16_LE is left. + +Signed-off-by: Stefan Mavrodiev +--- +Changes for v3: + - Instead of platfrom_driver dynammicly register/unregister card + - Add Kconfig dependencies + - Restrore drvdata after card unregistering + +Changes for v2: + - Create a new platform driver instead of using the HDMI encoder + - Expose a new kcontrol to the userspace holding the ELD data + - Wrap all macro arguments in parentheses + + drivers/gpu/drm/sun4i/Kconfig | 11 + + drivers/gpu/drm/sun4i/Makefile | 3 + + drivers/gpu/drm/sun4i/sun4i_hdmi.h | 37 ++ + drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c | 450 +++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 14 + + 5 files changed, 515 insertions(+) + create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c + +diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig +index 37e90e42943f..ca2ab5d53dd4 100644 +--- a/drivers/gpu/drm/sun4i/Kconfig ++++ b/drivers/gpu/drm/sun4i/Kconfig +@@ -23,6 +23,17 @@ config DRM_SUN4I_HDMI + Choose this option if you have an Allwinner SoC with an HDMI + controller. + ++config DRM_SUN4I_HDMI_AUDIO ++ bool "Allwinner A10 HDMI Audio Support" ++ default y ++ depends on DRM_SUN4I_HDMI ++ depends on SND_SOC=y || SND_SOC=DRM_SUN4I_HDMI ++ select SND_PCM_ELD ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ help ++ Choose this option if you have an Allwinner SoC with an HDMI ++ controller and want to use audio. ++ + config DRM_SUN4I_HDMI_CEC + bool "Allwinner A10 HDMI CEC Support" + depends on DRM_SUN4I_HDMI +diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile +index 0d04f2447b01..492bfd28ad2e 100644 +--- a/drivers/gpu/drm/sun4i/Makefile ++++ b/drivers/gpu/drm/sun4i/Makefile +@@ -5,6 +5,9 @@ sun4i-frontend-y += sun4i_frontend.o + sun4i-drm-y += sun4i_drv.o + sun4i-drm-y += sun4i_framebuffer.o + ++ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++sun4i-drm-hdmi-y += sun4i_hdmi_audio.o ++endif + sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o + sun4i-drm-hdmi-y += sun4i_hdmi_enc.o + sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h +index 7ad3f06c127e..28621d289655 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h +@@ -42,7 +42,32 @@ + #define SUN4I_HDMI_VID_TIMING_POL_VSYNC BIT(1) + #define SUN4I_HDMI_VID_TIMING_POL_HSYNC BIT(0) + ++#define SUN4I_HDMI_AUDIO_CTRL_REG 0x040 ++#define SUN4I_HDMI_AUDIO_CTRL_ENABLE BIT(31) ++#define SUN4I_HDMI_AUDIO_CTRL_RESET BIT(30) ++ ++#define SUN4I_HDMI_AUDIO_FMT_REG 0x048 ++#define SUN4I_HDMI_AUDIO_FMT_SRC BIT(31) ++#define SUN4I_HDMI_AUDIO_FMT_LAYOUT BIT(3) ++#define SUN4I_HDMI_AUDIO_FMT_CH_CFG(n) ((n) - 1) ++#define SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK GENMASK(2, 0) ++ ++#define SUN4I_HDMI_AUDIO_PCM_REG 0x4c ++#define SUN4I_HDMI_AUDIO_PCM_CH_MAP(n, m) (((m) - 1) << ((n) * 4)) ++#define SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(n) (GENMASK(2, 0) << ((n) * 4)) ++ ++#define SUN4I_HDMI_AUDIO_CTS_REG 0x050 ++#define SUN4I_HDMI_AUDIO_CTS(n) ((n) & GENMASK(19, 0)) ++ ++#define SUN4I_HDMI_AUDIO_N_REG 0x054 ++#define SUN4I_HDMI_AUDIO_N(n) ((n) & GENMASK(19, 0)) ++ ++#define SUN4I_HDMI_AUDIO_STAT0_REG 0x58 ++#define SUN4I_HDMI_AUDIO_STAT0_FREQ(n) ((n) << 24) ++#define SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK GENMASK(27, 24) ++ + #define SUN4I_HDMI_AVI_INFOFRAME_REG(n) (0x080 + (n)) ++#define SUN4I_HDMI_AUDIO_INFOFRAME_REG(n) (0x0a0 + (n)) + + #define SUN4I_HDMI_PAD_CTRL0_REG 0x200 + #define SUN4I_HDMI_PAD_CTRL0_BIASEN BIT(31) +@@ -242,6 +267,11 @@ struct sun4i_hdmi_variant { + bool ddc_fifo_has_dir; + }; + ++struct sun4i_hdmi_audio { ++ struct snd_soc_card *card; ++ u8 channels; ++}; ++ + struct sun4i_hdmi { + struct drm_connector connector; + struct drm_encoder encoder; +@@ -283,9 +313,14 @@ struct sun4i_hdmi { + struct regmap_field *field_ddc_sda_en; + struct regmap_field *field_ddc_sck_en; + ++ + struct sun4i_drv *drv; + + bool hdmi_monitor; ++ bool hdmi_audio; ++ ++ struct sun4i_hdmi_audio audio; ++ + struct cec_adapter *cec_adap; + + const struct sun4i_hdmi_variant *variant; +@@ -294,5 +329,7 @@ struct sun4i_hdmi { + int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk); + int sun4i_tmds_create(struct sun4i_hdmi *hdmi); + int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi); ++int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi); ++void sun4i_hdmi_audio_destroy(struct sun4i_hdmi *hdmi); + + #endif /* _SUN4I_HDMI_H_ */ +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c +new file mode 100644 +index 000000000000..f42f2cea4e9e +--- /dev/null ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c +@@ -0,0 +1,450 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (C) 2020 Olimex Ltd. ++ * Author: Stefan Mavrodiev ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "sun4i_hdmi.h" ++ ++static int sun4i_hdmi_audio_ctl_eld_info(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_info *uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; ++ uinfo->count = MAX_ELD_BYTES; ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_ctl_eld_get(struct snd_kcontrol *kcontrol, ++ struct snd_ctl_elem_value *ucontrol) ++{ ++ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); ++ struct snd_soc_card *card = snd_soc_component_get_drvdata(component); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ ++ memcpy(ucontrol->value.bytes.data, ++ hdmi->connector.eld, ++ MAX_ELD_BYTES); ++ ++ return 0; ++} ++ ++static const struct snd_kcontrol_new sun4i_hdmi_audio_controls[] = { ++ { ++ .access = SNDRV_CTL_ELEM_ACCESS_READ | ++ SNDRV_CTL_ELEM_ACCESS_VOLATILE, ++ .iface = SNDRV_CTL_ELEM_IFACE_PCM, ++ .name = "ELD", ++ .info = sun4i_hdmi_audio_ctl_eld_info, ++ .get = sun4i_hdmi_audio_ctl_eld_get, ++ }, ++}; ++ ++static const struct snd_soc_dapm_widget sun4i_hdmi_audio_widgets[] = { ++ SND_SOC_DAPM_OUTPUT("TX"), ++}; ++ ++static const struct snd_soc_dapm_route sun4i_hdmi_audio_routes[] = { ++ { "TX", NULL, "Playback" }, ++}; ++ ++static const struct snd_soc_component_driver sun4i_hdmi_audio_component = { ++ .controls = sun4i_hdmi_audio_controls, ++ .num_controls = ARRAY_SIZE(sun4i_hdmi_audio_controls), ++ .dapm_widgets = sun4i_hdmi_audio_widgets, ++ .num_dapm_widgets = ARRAY_SIZE(sun4i_hdmi_audio_widgets), ++ .dapm_routes = sun4i_hdmi_audio_routes, ++ .num_dapm_routes = ARRAY_SIZE(sun4i_hdmi_audio_routes), ++}; ++ ++static int sun4i_hdmi_audio_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ u32 reg; ++ int ret; ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ SUN4I_HDMI_AUDIO_CTRL_RESET); ++ ret = regmap_read_poll_timeout(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ reg, !reg, 100, 50000); ++ if (ret < 0) { ++ DRM_ERROR("Failed to reset HDMI Audio\n"); ++ return ret; ++ } ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTRL_REG, ++ SUN4I_HDMI_AUDIO_CTRL_ENABLE); ++ ++ return snd_pcm_hw_constraint_eld(substream->runtime, ++ hdmi->connector.eld); ++} ++ ++static void sun4i_hdmi_audio_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); ++} ++ ++static int sun4i_hdmi_setup_audio_infoframes(struct sun4i_hdmi *hdmi) ++{ ++ union hdmi_infoframe frame; ++ u8 buffer[14]; ++ int i, ret; ++ ++ ret = hdmi_audio_infoframe_init(&frame.audio); ++ if (ret < 0) { ++ DRM_ERROR("Failed to init HDMI audio infoframe\n"); ++ return ret; ++ } ++ ++ frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; ++ frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; ++ frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; ++ frame.audio.channels = hdmi->audio.channels; ++ ++ ret = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); ++ if (ret < 0) { ++ DRM_ERROR("Failed to pack HDMI audio infoframe\n"); ++ return ret; ++ } ++ ++ for (i = 0; i < sizeof(buffer); i++) ++ writeb(buffer[i], ++ hdmi->base + SUN4I_HDMI_AUDIO_INFOFRAME_REG(i)); ++ ++ return 0; ++} ++ ++static void sun4i_hdmi_audio_set_cts_n(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ struct drm_encoder *encoder = &hdmi->encoder; ++ struct drm_crtc *crtc = encoder->crtc; ++ const struct drm_display_mode *mode = &crtc->state->adjusted_mode; ++ u32 rate = params_rate(params); ++ u32 n, cts; ++ u64 tmp; ++ ++ /** ++ * Calculate Cycle Time Stamp (CTS) and Numerator (N): ++ * ++ * N = 128 * Samplerate / 1000 ++ * CTS = (Ftdms * N) / (128 * Samplerate) ++ */ ++ ++ n = 128 * rate / 1000; ++ tmp = (u64)(mode->clock * 1000) * n; ++ do_div(tmp, 128 * rate); ++ cts = tmp; ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_CTS_REG, ++ SUN4I_HDMI_AUDIO_CTS(cts)); ++ ++ regmap_write(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_N_REG, ++ SUN4I_HDMI_AUDIO_N(n)); ++} ++ ++static int sun4i_hdmi_audio_set_hw_rate(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ u32 rate = params_rate(params); ++ u32 val; ++ ++ switch (rate) { ++ case 44100: ++ val = 0x0; ++ break; ++ case 48000: ++ val = 0x2; ++ break; ++ case 32000: ++ val = 0x3; ++ break; ++ case 88200: ++ val = 0x8; ++ break; ++ case 96000: ++ val = 0x9; ++ break; ++ case 176400: ++ val = 0xc; ++ break; ++ case 192000: ++ val = 0xe; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_STAT0_REG, ++ SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK, ++ SUN4I_HDMI_AUDIO_STAT0_FREQ(val)); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_set_hw_channels(struct sun4i_hdmi *hdmi, ++ struct snd_pcm_hw_params *params) ++{ ++ u32 channels = params_channels(params); ++ ++ if (channels > 8) ++ return -EINVAL; ++ ++ hdmi->audio.channels = channels; ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_FMT_REG, ++ SUN4I_HDMI_AUDIO_FMT_LAYOUT, ++ (channels > 2) ? SUN4I_HDMI_AUDIO_FMT_LAYOUT : 0); ++ ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_FMT_REG, ++ SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK, ++ SUN4I_HDMI_AUDIO_FMT_CH_CFG(channels)); ++ ++ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_PCM_REG, 0x76543210); ++ ++ /** ++ * If only one channel is required, send the same sample ++ * to the sink device as a left and right channel. ++ */ ++ if (channels == 1) ++ regmap_update_bits(hdmi->regmap, ++ SUN4I_HDMI_AUDIO_PCM_REG, ++ SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(1), ++ SUN4I_HDMI_AUDIO_PCM_CH_MAP(1, 1)); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ int ret; ++ ++ ret = sun4i_hdmi_audio_set_hw_rate(hdmi, params); ++ if (ret < 0) ++ return ret; ++ ++ ret = sun4i_hdmi_audio_set_hw_channels(hdmi, params); ++ if (ret < 0) ++ return ret; ++ ++ sun4i_hdmi_audio_set_cts_n(hdmi, params); ++ ++ return 0; ++} ++ ++static int sun4i_hdmi_audio_trigger(struct snd_pcm_substream *substream, ++ int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); ++ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); ++ int ret = 0; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ ret = sun4i_hdmi_setup_audio_infoframes(hdmi); ++ break; ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ ++static const struct snd_soc_dai_ops sun4i_hdmi_audio_dai_ops = { ++ .startup = sun4i_hdmi_audio_startup, ++ .shutdown = sun4i_hdmi_audio_shutdown, ++ .hw_params = sun4i_hdmi_audio_hw_params, ++ .trigger = sun4i_hdmi_audio_trigger, ++}; ++ ++static int sun4i_hdmi_audio_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct snd_dmaengine_dai_dma_data *dma_data; ++ ++ dma_data = devm_kzalloc(dai->dev, sizeof(*dma_data), GFP_KERNEL); ++ if (!dma_data) ++ return -ENOMEM; ++ ++ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dma_data->maxburst = 8; ++ ++ snd_soc_dai_init_dma_data(dai, dma_data, NULL); ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_driver sun4i_hdmi_audio_dai = { ++ .name = "HDMI", ++ .ops = &sun4i_hdmi_audio_dai_ops, ++ .probe = sun4i_hdmi_audio_dai_probe, ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 1, ++ .channels_max = 8, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ }, ++}; ++ ++static const struct snd_pcm_hardware sun4i_hdmi_audio_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER | ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID | ++ SNDRV_PCM_INFO_PAUSE | ++ SNDRV_PCM_INFO_RESUME, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .rate_min = 8000, ++ .rate_max = 192000, ++ .channels_min = 1, ++ .channels_max = 8, ++ .buffer_bytes_max = 128 * 1024, ++ .period_bytes_min = 4 * 1024, ++ .period_bytes_max = 32 * 1024, ++ .periods_min = 2, ++ .periods_max = 8, ++ .fifo_size = 128, ++}; ++ ++static const struct snd_dmaengine_pcm_config sun4i_hdmi_audio_pcm_config = { ++ .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-tx", ++ .pcm_hardware = &sun4i_hdmi_audio_pcm_hardware, ++ .prealloc_buffer_size = 128 * 1024, ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++}; ++ ++struct snd_soc_card sun4i_hdmi_audio_card = { ++ .name = "sun4i-hdmi", ++}; ++ ++int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi) ++{ ++ struct snd_soc_card *card = &sun4i_hdmi_audio_card; ++ struct snd_soc_dai_link_component *comp; ++ struct snd_soc_dai_link *link; ++ int ret; ++ ++ ret = snd_dmaengine_pcm_register(hdmi->dev, ++ &sun4i_hdmi_audio_pcm_config, 0); ++ if (ret < 0) { ++ DRM_ERROR("Could not register PCM\n"); ++ return ret; ++ } ++ ++ ret = snd_soc_register_component(hdmi->dev, ++ &sun4i_hdmi_audio_component, ++ &sun4i_hdmi_audio_dai, 1); ++ if (ret < 0) { ++ DRM_ERROR("Could not register DAI\n"); ++ goto unregister_pcm; ++ } ++ ++ link = devm_kzalloc(hdmi->dev, sizeof(*link), GFP_KERNEL); ++ if (!link) { ++ ret = -ENOMEM; ++ goto unregister_component; ++ } ++ ++ comp = devm_kzalloc(hdmi->dev, sizeof(*comp) * 3, GFP_KERNEL); ++ if (!comp) { ++ ret = -ENOMEM; ++ goto unregister_component; ++ } ++ ++ link->cpus = &comp[0]; ++ link->codecs = &comp[1]; ++ link->platforms = &comp[2]; ++ ++ link->num_cpus = 1; ++ link->num_codecs = 1; ++ link->num_platforms = 1; ++ ++ link->playback_only = 1; ++ ++ link->name = "SUN4I-HDMI"; ++ link->stream_name = "SUN4I-HDMI PCM"; ++ ++ link->codecs->name = dev_name(hdmi->dev); ++ link->codecs->dai_name = sun4i_hdmi_audio_dai.name; ++ ++ link->cpus->dai_name = dev_name(hdmi->dev); ++ ++ link->platforms->name = dev_name(hdmi->dev); ++ ++ link->dai_fmt = SND_SOC_DAIFMT_I2S; ++ ++ card->dai_link = link; ++ card->num_links = 1; ++ card->dev = hdmi->dev; ++ ++ hdmi->audio.card = card; ++ ++ /** ++ * snd_soc_register_card() will overwrite the driver_data pointer. ++ * So before registering the card, store the original pointer in ++ * card->drvdata. ++ */ ++ snd_soc_card_set_drvdata(card, hdmi); ++ ret = snd_soc_register_card(card); ++ if (ret) ++ goto unregister_component; ++ ++ return 0; ++ ++unregister_component: ++ snd_soc_unregister_component(hdmi->dev); ++unregister_pcm: ++ snd_dmaengine_pcm_unregister(hdmi->dev); ++ return ret; ++} ++ ++void sun4i_hdmi_audio_destroy(struct sun4i_hdmi *hdmi) ++{ ++ struct snd_soc_card *card = hdmi->audio.card; ++ void *data; ++ ++ /** ++ * Before removing the card, restore the previously stored driver_data. ++ * This will ensure proper removal of the sun4i-hdmi module, since it ++ * uses dev_get_drvdata() in the unbind function. ++ */ ++ data = snd_soc_card_get_drvdata(card); ++ ++ snd_soc_unregister_card(card); ++ snd_soc_unregister_component(hdmi->dev); ++ snd_dmaengine_pcm_unregister(hdmi->dev); ++ ++ dev_set_drvdata(hdmi->dev, data); ++} +diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +index 68d4644ac2dc..4cd35c97c503 100644 +--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c ++++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +@@ -23,6 +23,8 @@ + #include + #include + ++#include ++ + #include "sun4i_backend.h" + #include "sun4i_crtc.h" + #include "sun4i_drv.h" +@@ -87,6 +89,10 @@ static void sun4i_hdmi_disable(struct drm_encoder *encoder) + + DRM_DEBUG_DRIVER("Disabling the HDMI Output\n"); + ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ sun4i_hdmi_audio_destroy(hdmi); ++#endif ++ + val = readl(hdmi->base + SUN4I_HDMI_VID_CTRL_REG); + val &= ~SUN4I_HDMI_VID_CTRL_ENABLE; + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); +@@ -114,6 +120,11 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder) + val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; + + writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); ++ ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ if (hdmi->hdmi_audio && sun4i_hdmi_audio_create(hdmi)) ++ DRM_ERROR("Couldn't create the HDMI audio adapter\n"); ++#endif + } + + static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, +@@ -218,6 +229,9 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector) + if (!edid) + return 0; + ++#ifdef CONFIG_DRM_SUN4I_HDMI_AUDIO ++ hdmi->hdmi_audio = drm_detect_monitor_audio(edid); ++#endif + hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid); + DRM_DEBUG_DRIVER("Monitor is %s monitor\n", + hdmi->hdmi_monitor ? "an HDMI" : "a DVI");