summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorJiaojinxing <jiaojinxing1987@gmail.com>2016-04-22 01:23:30 (GMT)
committer Jiaojinxing <jiaojinxing1987@gmail.com>2016-04-22 01:23:30 (GMT)
commit031627317aa335a9b3c1fc068acf8ef2b477b5b3 (patch)
tree31b82160c87788ad30dfb7bb72b8ff13d2f03803
parent6accdcc6eb4e070963ff095efbe0a41323853436 (diff)
downloadbspam335x-031627317aa335a9b3c1fc068acf8ef2b477b5b3.zip
bspam335x-031627317aa335a9b3c1fc068acf8ef2b477b5b3.tar.gz
bspam335x-031627317aa335a9b3c1fc068acf8ef2b477b5b3.tar.bz2
Fixed audio driver bug.
-rw-r--r--Makefile823
-rw-r--r--SylixOS/StarterWare/include/armv7a/am335x/clock.h1432
-rw-r--r--SylixOS/StarterWare/include/edma.h956
-rw-r--r--SylixOS/bsp/beaglebone/config_beaglebone.h152
-rw-r--r--SylixOS/bsp/bspMap.h25
-rw-r--r--SylixOS/bsp/config.h238
-rw-r--r--SylixOS/bsp/forlinx/config_ok335xd.h166
-rw-r--r--SylixOS/bsp/forlinx/config_ok335xs.h170
-rw-r--r--SylixOS/bsp/ti/config_evmAM335x.h152
-rw-r--r--SylixOS/bsp/ti/config_evmskAM335x.h152
-rw-r--r--SylixOS/driver/audio/codec/codecDrv.c69
-rw-r--r--SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c1325
-rw-r--r--SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.h78
-rw-r--r--SylixOS/driver/audio/dsp/dspDrv.c756
-rw-r--r--SylixOS/driver/audio/dsp/dspDrv.h110
-rw-r--r--SylixOS/driver/audio/mixer/mixerDrv.c588
-rw-r--r--SylixOS/driver/audio/oss_test.c292
-rw-r--r--SylixOS/driver/dma/am335x_dma.c1576
-rw-r--r--SylixOS/driver/lcd/am335x_lcd.c1760
-rw-r--r--SylixOS/driver/mcasp/am335x_mcasp.c1797
-rw-r--r--SylixOS/driver/mcasp/davinci-mcasp.h291
-rw-r--r--SylixOS/driver/memory/gpmc/gpmc.c4095
-rw-r--r--SylixOS/driver/memory/gpmc/gpmc.h473
-rw-r--r--SylixOS/driver/netif/cpswif.c6688
-rw-r--r--SylixOS/driver/sio/am335x_sio.c1946
-rw-r--r--U-Boot.txt212
26 files changed, 13318 insertions, 13004 deletions
diff --git a/Makefile b/Makefile
index a9135e1..50b652b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,407 +1,416 @@
-#*********************************************************************************************************
-# bspam335x Makefile
-# target -> bspam335x.elf
-# bspam335x.bin
-#*********************************************************************************************************
-
-#*********************************************************************************************************
-# include config.mk
-#*********************************************************************************************************
-CONFIG_MK_EXIST = $(shell if [ -f ../config.mk ]; then echo exist; else echo notexist; fi;)
-ifeq ($(CONFIG_MK_EXIST), exist)
-include ../config.mk
-else
-CONFIG_MK_EXIST = $(shell if [ -f config.mk ]; then echo exist; else echo notexist; fi;)
-ifeq ($(CONFIG_MK_EXIST), exist)
-include config.mk
-else
-CONFIG_MK_EXIST =
-endif
-endif
-
-#*********************************************************************************************************
-# check configure
-#*********************************************************************************************************
-check_defined = \
- $(foreach 1,$1,$(__check_defined))
-__check_defined = \
- $(if $(value $1),, \
- $(error Undefined $1$(if $(value 2), ($(strip $2)))))
-
-$(call check_defined, CONFIG_MK_EXIST, Please configure this project in RealEvo-IDE or \
-create a config.mk file!)
-$(call check_defined, SYLIXOS_BASE_PATH, SylixOS base project path)
-$(call check_defined, TOOLCHAIN_PREFIX, the prefix name of toolchain)
-$(call check_defined, DEBUG_LEVEL, debug level(debug or release))
-
-#*********************************************************************************************************
-# toolchain select
-#*********************************************************************************************************
-CC = $(TOOLCHAIN_PREFIX)gcc
-CXX = $(TOOLCHAIN_PREFIX)g++
-AS = $(TOOLCHAIN_PREFIX)gcc
-AR = $(TOOLCHAIN_PREFIX)ar
-LD = $(TOOLCHAIN_PREFIX)g++
-OC = $(TOOLCHAIN_PREFIX)objcopy
-SZ = $(TOOLCHAIN_PREFIX)size
-
-#*********************************************************************************************************
-# platform, can use: evmAM335x evmskAM335x beaglebone ok335xd ok335xs ok335xs2
-#*********************************************************************************************************
-PLATFORM = ok335xs
-
-#*********************************************************************************************************
-# symbol.c symbol.h path
-#*********************************************************************************************************
-SYMBOL_PATH = SylixOS/bsp
-
-#*********************************************************************************************************
-# do not change the following code
-# buildin internal application source
-#*********************************************************************************************************
-
-#*********************************************************************************************************
-# symbol.c
-#*********************************************************************************************************
-SYM_SRCS = $(SYMBOL_PATH)/symbol.c
-
-#*********************************************************************************************************
-# bsp src(s) file
-#*********************************************************************************************************
-BSP_SRCS = \
-SylixOS/bsp/bspInit.c \
-SylixOS/bsp/bspLib.c \
-SylixOS/bsp/startup.S
-
-ifeq ($(PLATFORM), ok335xd)
-BSP_SRCS += SylixOS/bsp/forlinx/bspForlinx.c
-endif
-
-ifeq ($(PLATFORM), ok335xs)
-BSP_SRCS += SylixOS/bsp/forlinx/bspForlinx.c
-endif
-
-ifeq ($(PLATFORM), ok335xs2)
-BSP_SRCS += SylixOS/bsp/forlinx/bspForlinx.c
-endif
-
-ifeq ($(PLATFORM), beaglebone)
-BSP_SRCS += SylixOS/bsp/beaglebone/bspBeaglebone.c
-endif
-
-ifeq ($(PLATFORM), evmAM335x)
-BSP_SRCS += SylixOS/bsp/ti/bspEvmAM335x.c
-endif
-
-ifeq ($(PLATFORM), evmskAM335x)
-BSP_SRCS += SylixOS/bsp/ti/bspEvmAM335x.c
-endif
-#*********************************************************************************************************
-# drivers src(s) file
-#*********************************************************************************************************
-DRV_SRCS = \
-SylixOS/driver/tps65217/tps65217.c \
-SylixOS/driver/dvfs/dvfs.c \
-SylixOS/driver/clock/am335x_clock_data.c \
-SylixOS/driver/clock/am335x_clock.c \
-SylixOS/driver/mcasp/am335x_mcasp.c \
-SylixOS/driver/audio/oss_test.c \
-SylixOS/driver/audio/dsp/dspDrv.c \
-SylixOS/driver/audio/mixer/mixerDrv.c \
-SylixOS/driver/audio/queue/queueLib.c \
-SylixOS/driver/audio/codec/codecDrv.c \
-SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c \
-SylixOS/driver/pinmux/mux.c \
-SylixOS/driver/pinmux/mux_port.c \
-SylixOS/driver/pinmux/mux2420.c \
-SylixOS/driver/pinmux/mux2430.c \
-SylixOS/driver/pinmux/mux33xx.c \
-SylixOS/driver/pinmux/mux34xx.c \
-SylixOS/driver/pinmux/mux44xx.c \
-SylixOS/driver/gpio/am335x_gpio.c \
-SylixOS/driver/gpio/am335x_gpio_test.c \
-SylixOS/driver/lcd/am335x_lcd.c \
-SylixOS/driver/lcd/am335x_lcd_touch_test.c \
-SylixOS/driver/sio/am335x_sio.c \
-SylixOS/driver/sio/am335x_sio_test.c \
-SylixOS/driver/rtc/am335x_rtc.c \
-SylixOS/driver/rtc/am335x_rtc_test.c \
-SylixOS/driver/dma/am335x_dma.c \
-SylixOS/driver/dma/am335x_dma_test.c \
-SylixOS/driver/i2c/am335x_i2c.c \
-SylixOS/driver/pwm/am335x_pwm.c \
-SylixOS/driver/ecap/am335x_ecap.c \
-SylixOS/driver/ecap/am335x_ecap_test.c \
-SylixOS/driver/spi/am335x_spi.c \
-SylixOS/driver/spi/am335x_spi_test.c \
-SylixOS/driver/touch/am335x_adc_touch.c \
-SylixOS/driver/adc/am335x_adc.c \
-SylixOS/driver/adc/am335x_adc_test.c \
-SylixOS/driver/can/dcan_frame.c \
-SylixOS/driver/can/am335x_can.c \
-SylixOS/driver/can/am335x_can_test.c \
-SylixOS/driver/sdi/am335x_sdi.c \
-SylixOS/driver/sdi/am335x_sdi_init.c \
-SylixOS/driver/netif/cpswif.c \
-SylixOS/driver/netif/am335x_cpsw.c \
-SylixOS/driver/netif/netio/netio.c \
-SylixOS/driver/watchdog/am335x_watchdog.c \
-SylixOS/driver/memory/memory_port.c \
-SylixOS/driver/memory/elm/elm.c \
-SylixOS/driver/memory/gpmc/gpmc.c \
-SylixOS/driver/memory/gpmc/gpmc-nand.c \
-SylixOS/driver/memory/nand/omap2.c \
-SylixOS/driver/memory/am335x_nand.c \
-SylixOS/driver/usb/am335x_usb_hw_init.c \
-SylixOS/driver/ft5x06/ft5x06.c \
-SylixOS/driver/beep/beep.c \
-SylixOS/driver/beep/beep_test.c \
-SylixOS/driver/ds1337/ds1337.c \
-SylixOS/driver/ds1337/ds1337_test.c
-
-#*********************************************************************************************************
-# StarterWare src(s) file
-#*********************************************************************************************************
-STARTERWARE_DRIVERS_SRCS = \
-SylixOS/StarterWare/drivers/cpsw.c \
-SylixOS/StarterWare/drivers/dcan.c \
-SylixOS/StarterWare/drivers/dmtimer.c \
-SylixOS/StarterWare/drivers/ecap.c \
-SylixOS/StarterWare/drivers/edma.c \
-SylixOS/StarterWare/drivers/ehrpwm.c \
-SylixOS/StarterWare/drivers/elm.c \
-SylixOS/StarterWare/drivers/gpio_v2.c \
-SylixOS/StarterWare/drivers/gpmc.c \
-SylixOS/StarterWare/drivers/hs_mmcsd.c \
-SylixOS/StarterWare/drivers/hsi2c.c \
-SylixOS/StarterWare/drivers/mailbox.c \
-SylixOS/StarterWare/drivers/mcasp.c \
-SylixOS/StarterWare/drivers/mcspi.c \
-SylixOS/StarterWare/drivers/mdio.c \
-SylixOS/StarterWare/drivers/phy.c \
-SylixOS/StarterWare/drivers/raster.c \
-SylixOS/StarterWare/drivers/rtc.c \
-SylixOS/StarterWare/drivers/tsc_adc.c \
-SylixOS/StarterWare/drivers/uart_irda_cir.c \
-SylixOS/StarterWare/drivers/watchdog.c
-
-STARTERWARE_SYSTEM_CONFIG_SRCS = \
-SylixOS/StarterWare/system_config/armv7a/cache.c \
-SylixOS/StarterWare/system_config/armv7a/am335x/clock.c \
-SylixOS/StarterWare/system_config/armv7a/am335x/device.c \
-SylixOS/StarterWare/system_config/armv7a/am335x/interrupt.c
-
-STARTERWARE_UTILS_SRCS = \
-SylixOS/StarterWare/utils/delay.c \
-SylixOS/StarterWare/utils/perf.c
-
-STARTERWARE_PLATFORM_SRCS = \
-SylixOS/StarterWare/platform/platform.c
-
-STARTERWARE_SRCS += $(STARTERWARE_DRIVERS_SRCS)
-STARTERWARE_SRCS += $(STARTERWARE_SYSTEM_CONFIG_SRCS)
-STARTERWARE_SRCS += $(STARTERWARE_UTILS_SRCS)
-STARTERWARE_SRCS += $(STARTERWARE_PLATFORM_SRCS)
-
-#*********************************************************************************************************
-# user src(s) file
-#*********************************************************************************************************
-USR_SRCS = \
-SylixOS/user/main.c \
-
-#*********************************************************************************************************
-# all bspam335x source
-#*********************************************************************************************************
-SRCS = $(BSP_SRCS)
-SRCS += $(DRV_SRCS)
-SRCS += $(USR_SRCS)
-SRCS += $(SYM_SRCS)
-SRCS += $(STARTERWARE_SRCS)
-
-#*********************************************************************************************************
-# build path
-#*********************************************************************************************************
-ifeq ($(DEBUG_LEVEL), debug)
-OUTDIR = Debug
-else
-OUTDIR = Release
-endif
-
-OUTPATH = ./$(OUTDIR)
-OBJPATH = $(OUTPATH)/obj
-DEPPATH = $(OUTPATH)/dep
-
-#*********************************************************************************************************
-# target
-#*********************************************************************************************************
-O_IMG = $(OUTPATH)/bsp$(PLATFORM).elf
-O_BIN = $(OUTPATH)/bsp$(PLATFORM).bin
-O_SIZ = $(OUTPATH)/bsp$(PLATFORM).siz
-
-#*********************************************************************************************************
-# bspam335x objects
-#*********************************************************************************************************
-OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(SRCS))))
-DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(SRCS))))
-
-#*********************************************************************************************************
-# include path
-#*********************************************************************************************************
-INCDIR = -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS"
-INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include"
-INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include/inet"
-
-INCDIR += -I"./SylixOS"
-INCDIR += -I"./SylixOS/bsp"
-INCDIR += -I"./SylixOS/StarterWare/include"
-INCDIR += -I"./SylixOS/StarterWare/include/hw"
-INCDIR += -I"./SylixOS/StarterWare/include/armv7a"
-INCDIR += -I"./SylixOS/StarterWare/include/armv7a/am335x"
-INCDIR += -I"./SylixOS/StarterWare/usblib/include"
-
-#*********************************************************************************************************
-# compiler preprocess
-#*********************************************************************************************************
-DSYMBOL = -DSYLIXOS
-DSYMBOL += -D__BOOT_INRAM=1
-DSYMBOL += -Dam335x
-DSYMBOL += -Dgcc
-DSYMBOL += -DDMA_MODE
-DSYMBOL += -D$(PLATFORM)
-
-#*********************************************************************************************************
-# load script
-#*********************************************************************************************************
-LD_SCRIPT = SylixOSBSP.ld
-
-#*********************************************************************************************************
-# depend dynamic library
-#*********************************************************************************************************
-DEPEND_DLL = -lsylixos
-
-#*********************************************************************************************************
-# depend dynamic library search path
-#*********************************************************************************************************
-DEPEND_DLL_PATH = -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)"
-
-#*********************************************************************************************************
-# compiler optimize
-#*********************************************************************************************************
-ifeq ($(DEBUG_LEVEL), debug)
-OPTIMIZE = -O0 -g3 -gdwarf-2
-else
-OPTIMIZE = -O2 -g1 -gdwarf-2 # Do NOT use -O3 and -Os
-endif # -Os is not align for function
- # loop and jump.
-#*********************************************************************************************************
-# depends and compiler parameter (cplusplus in kernel MUST NOT use exceptions and rtti)
-#*********************************************************************************************************
-DEPENDFLAG = -MM
-CXX_EXCEPT = -fno-exceptions -fno-rtti
-COMMONFLAGS = $(CPUFLAGS) $(OPTIMIZE) -Wall -fmessage-length=0 -fsigned-char -fno-short-enums
-ASFLAGS = -x assembler-with-cpp $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -c
-CFLAGS = $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -c
-CXXFLAGS = $(DSYMBOL) $(INCDIR) $(CXX_EXCEPT) $(COMMONFLAGS) -c
-ARFLAGS = -r
-
-#*********************************************************************************************************
-# define some useful variable
-#*********************************************************************************************************
-DEPEND = $(CC) $(DEPENDFLAG) $(CFLAGS)
-DEPEND.d = $(subst -g ,,$(DEPEND))
-COMPILE.S = $(AS) $(ASFLAGS)
-COMPILE_VFP.S = $(AS) $(ASFLAGS) $(FPUFLAGS)
-COMPILE.c = $(CC) $(CFLAGS)
-COMPILE.cxx = $(CXX) $(CXXFLAGS)
-
-#*********************************************************************************************************
-# target
-#*********************************************************************************************************
-all: $(O_IMG)
- @echo create "$(O_IMG) $(O_BIN)" success.
-
-#*********************************************************************************************************
-# include depends
-#*********************************************************************************************************
-ifneq ($(MAKECMDGOALS), clean)
-ifneq ($(MAKECMDGOALS), clean_project)
-sinclude $(DEPS)
-endif
-endif
-
-#*********************************************************************************************************
-# auto copy symbol.c symbol.h
-#*********************************************************************************************************
-EMPTY=
-SPACE= $(EMPTY) $(EMPTY)
-$(SYMBOL_PATH)/symbol.c:$(subst $(SPACE),\ ,$(SYLIXOS_BASE_PATH))/libsylixos/$(OUTDIR)/symbol.c
- cp "$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)/symbol.c" $(SYMBOL_PATH)/symbol.c
- cp "$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)/symbol.h" $(SYMBOL_PATH)/symbol.h
-
-#*********************************************************************************************************
-# create depends files
-#*********************************************************************************************************
-$(DEPPATH)/%.d: %.c
- @echo creating $@
- @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
- @rm -f $@; \
- echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
- $(DEPEND.d) $< >> $@ || rm -f $@; exit;
-
-$(DEPPATH)/%.d: %.cpp
- @echo creating $@
- @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
- @rm -f $@; \
- echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
- $(DEPEND.d) $< >> $@ || rm -f $@; exit;
-
-#*********************************************************************************************************
-# compile source files
-#*********************************************************************************************************
-$(OBJPATH)/%.o: %.S
- @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
- $(COMPILE.S) $< -o $@
-
-$(OBJPATH)/%.o: %.c
- @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
- $(COMPILE.c) $< -o $@
-
-$(OBJPATH)/%.o: %.cpp
- @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
- $(COMPILE.cxx) $< -o $@
-
-#*********************************************************************************************************
-# link bspam335x.elf object files
-#*********************************************************************************************************
-$(O_IMG): $(OBJS) $(LD_SCRIPT)
- $(LD) $(CPUFLAGS) -nostdlib $(addprefix -T,$(LD_SCRIPT)) -o $(O_IMG) $(OBJS) \
- $(DEPEND_DLL_PATH) $(DEPEND_DLL) -lm -lgcc
- $(OC) -O binary $(O_IMG) $(O_BIN)
- $(SZ) --format=berkeley $(O_IMG) > $(O_SIZ)
-
-#*********************************************************************************************************
-# clean
-#*********************************************************************************************************
-.PHONY: clean
-.PHONY: clean_project
-
-#*********************************************************************************************************
-# clean objects
-#*********************************************************************************************************
-clean:
- -rm -rf $(O_SIZ)
- -rm -rf $(O_IMG)
- -rm -rf $(O_BIN)
- -rm -rf $(SYMBOL_PATH)/symbol.c $(SYMBOL_PATH)/symbol.h
- -rm -rf $(OBJPATH)
- -rm -rf $(DEPPATH)
-
-#*********************************************************************************************************
-# clean project
-#*********************************************************************************************************
-clean_project:
- -rm -rf $(OUTPATH)
-
-#*********************************************************************************************************
-# END
-#*********************************************************************************************************
+#*********************************************************************************************************
+# bspam335x Makefile
+# target -> bspam335x.elf
+# bspam335x.bin
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# include config.mk
+#*********************************************************************************************************
+CONFIG_MK_EXIST = $(shell if [ -f ../config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include ../config.mk
+else
+CONFIG_MK_EXIST = $(shell if [ -f config.mk ]; then echo exist; else echo notexist; fi;)
+ifeq ($(CONFIG_MK_EXIST), exist)
+include config.mk
+else
+CONFIG_MK_EXIST =
+endif
+endif
+
+#*********************************************************************************************************
+# check configure
+#*********************************************************************************************************
+check_defined = \
+ $(foreach 1,$1,$(__check_defined))
+__check_defined = \
+ $(if $(value $1),, \
+ $(error Undefined $1$(if $(value 2), ($(strip $2)))))
+
+$(call check_defined, CONFIG_MK_EXIST, Please configure this project in RealEvo-IDE or \
+create a config.mk file!)
+$(call check_defined, SYLIXOS_BASE_PATH, SylixOS base project path)
+$(call check_defined, TOOLCHAIN_PREFIX, the prefix name of toolchain)
+$(call check_defined, DEBUG_LEVEL, debug level(debug or release))
+
+#*********************************************************************************************************
+# toolchain select
+#*********************************************************************************************************
+CC = $(TOOLCHAIN_PREFIX)gcc
+CXX = $(TOOLCHAIN_PREFIX)g++
+AS = $(TOOLCHAIN_PREFIX)gcc
+AR = $(TOOLCHAIN_PREFIX)ar
+LD = $(TOOLCHAIN_PREFIX)g++
+OC = $(TOOLCHAIN_PREFIX)objcopy
+SZ = $(TOOLCHAIN_PREFIX)size
+
+#*********************************************************************************************************
+# platform, can use: evmAM335x evmskAM335x beaglebone ok335xd ok335xs ok335xs2
+# watertek platform, can use: FK2500 CT3520
+#*********************************************************************************************************
+PLATFORM = ok335xs
+
+#*********************************************************************************************************
+# symbol.c symbol.h path
+#*********************************************************************************************************
+SYMBOL_PATH = SylixOS/bsp
+
+#*********************************************************************************************************
+# do not change the following code
+# buildin internal application source
+#*********************************************************************************************************
+
+#*********************************************************************************************************
+# symbol.c
+#*********************************************************************************************************
+SYM_SRCS = $(SYMBOL_PATH)/symbol.c
+
+#*********************************************************************************************************
+# bsp src(s) file
+#*********************************************************************************************************
+BSP_SRCS = \
+SylixOS/bsp/bspInit.c \
+SylixOS/bsp/bspLib.c \
+SylixOS/bsp/startup.S
+
+ifeq ($(PLATFORM), ok335xd)
+BSP_SRCS += SylixOS/bsp/forlinx/bspForlinx.c
+endif
+
+ifeq ($(PLATFORM), ok335xs)
+BSP_SRCS += SylixOS/bsp/forlinx/bspForlinx.c
+endif
+
+ifeq ($(PLATFORM), ok335xs2)
+BSP_SRCS += SylixOS/bsp/forlinx/bspForlinx.c
+endif
+
+ifeq ($(PLATFORM), beaglebone)
+BSP_SRCS += SylixOS/bsp/beaglebone/bspBeaglebone.c
+endif
+
+ifeq ($(PLATFORM), evmAM335x)
+BSP_SRCS += SylixOS/bsp/ti/bspEvmAM335x.c
+endif
+
+ifeq ($(PLATFORM), evmskAM335x)
+BSP_SRCS += SylixOS/bsp/ti/bspEvmAM335x.c
+endif
+
+ifeq ($(PLATFORM), FK2500)
+BSP_SRCS += SylixOS/bsp/watertek/bspFK2500.c
+endif
+
+ifeq ($(PLATFORM), CT3520)
+BSP_SRCS += SylixOS/bsp/watertek/bspCT3520.c
+endif
+#*********************************************************************************************************
+# drivers src(s) file
+#*********************************************************************************************************
+DRV_SRCS = \
+SylixOS/driver/tps65217/tps65217.c \
+SylixOS/driver/dvfs/dvfs.c \
+SylixOS/driver/clock/am335x_clock_data.c \
+SylixOS/driver/clock/am335x_clock.c \
+SylixOS/driver/mcasp/am335x_mcasp.c \
+SylixOS/driver/audio/oss_test.c \
+SylixOS/driver/audio/dsp/dspDrv.c \
+SylixOS/driver/audio/mixer/mixerDrv.c \
+SylixOS/driver/audio/queue/queueLib.c \
+SylixOS/driver/audio/codec/codecDrv.c \
+SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c \
+SylixOS/driver/pinmux/mux.c \
+SylixOS/driver/pinmux/mux_port.c \
+SylixOS/driver/pinmux/mux2420.c \
+SylixOS/driver/pinmux/mux2430.c \
+SylixOS/driver/pinmux/mux33xx.c \
+SylixOS/driver/pinmux/mux34xx.c \
+SylixOS/driver/pinmux/mux44xx.c \
+SylixOS/driver/gpio/am335x_gpio.c \
+SylixOS/driver/gpio/am335x_gpio_test.c \
+SylixOS/driver/lcd/am335x_lcd.c \
+SylixOS/driver/lcd/am335x_lcd_touch_test.c \
+SylixOS/driver/sio/am335x_sio.c \
+SylixOS/driver/sio/am335x_sio_test.c \
+SylixOS/driver/rtc/am335x_rtc.c \
+SylixOS/driver/rtc/am335x_rtc_test.c \
+SylixOS/driver/dma/am335x_dma.c \
+SylixOS/driver/dma/am335x_dma_test.c \
+SylixOS/driver/i2c/am335x_i2c.c \
+SylixOS/driver/pwm/am335x_pwm.c \
+SylixOS/driver/ecap/am335x_ecap.c \
+SylixOS/driver/ecap/am335x_ecap_test.c \
+SylixOS/driver/spi/am335x_spi.c \
+SylixOS/driver/spi/am335x_spi_test.c \
+SylixOS/driver/touch/am335x_adc_touch.c \
+SylixOS/driver/adc/am335x_adc.c \
+SylixOS/driver/adc/am335x_adc_test.c \
+SylixOS/driver/can/dcan_frame.c \
+SylixOS/driver/can/am335x_can.c \
+SylixOS/driver/can/am335x_can_test.c \
+SylixOS/driver/sdi/am335x_sdi.c \
+SylixOS/driver/sdi/am335x_sdi_init.c \
+SylixOS/driver/netif/cpswif.c \
+SylixOS/driver/netif/am335x_cpsw.c \
+SylixOS/driver/netif/netio/netio.c \
+SylixOS/driver/watchdog/am335x_watchdog.c \
+SylixOS/driver/memory/memory_port.c \
+SylixOS/driver/memory/elm/elm.c \
+SylixOS/driver/memory/gpmc/gpmc.c \
+SylixOS/driver/memory/gpmc/gpmc-nand.c \
+SylixOS/driver/memory/nand/omap2.c \
+SylixOS/driver/memory/am335x_nand.c \
+SylixOS/driver/usb/am335x_usb_hw_init.c \
+SylixOS/driver/ft5x06/ft5x06.c \
+SylixOS/driver/beep/beep.c \
+SylixOS/driver/beep/beep_test.c \
+SylixOS/driver/ds1337/ds1337.c \
+SylixOS/driver/ds1337/ds1337_test.c
+
+#*********************************************************************************************************
+# StarterWare src(s) file
+#*********************************************************************************************************
+STARTERWARE_DRIVERS_SRCS = \
+SylixOS/StarterWare/drivers/cpsw.c \
+SylixOS/StarterWare/drivers/dcan.c \
+SylixOS/StarterWare/drivers/dmtimer.c \
+SylixOS/StarterWare/drivers/ecap.c \
+SylixOS/StarterWare/drivers/edma.c \
+SylixOS/StarterWare/drivers/ehrpwm.c \
+SylixOS/StarterWare/drivers/elm.c \
+SylixOS/StarterWare/drivers/gpio_v2.c \
+SylixOS/StarterWare/drivers/gpmc.c \
+SylixOS/StarterWare/drivers/hs_mmcsd.c \
+SylixOS/StarterWare/drivers/hsi2c.c \
+SylixOS/StarterWare/drivers/mailbox.c \
+SylixOS/StarterWare/drivers/mcasp.c \
+SylixOS/StarterWare/drivers/mcspi.c \
+SylixOS/StarterWare/drivers/mdio.c \
+SylixOS/StarterWare/drivers/phy.c \
+SylixOS/StarterWare/drivers/raster.c \
+SylixOS/StarterWare/drivers/rtc.c \
+SylixOS/StarterWare/drivers/tsc_adc.c \
+SylixOS/StarterWare/drivers/uart_irda_cir.c \
+SylixOS/StarterWare/drivers/watchdog.c
+
+STARTERWARE_SYSTEM_CONFIG_SRCS = \
+SylixOS/StarterWare/system_config/armv7a/cache.c \
+SylixOS/StarterWare/system_config/armv7a/am335x/clock.c \
+SylixOS/StarterWare/system_config/armv7a/am335x/device.c \
+SylixOS/StarterWare/system_config/armv7a/am335x/interrupt.c
+
+STARTERWARE_UTILS_SRCS = \
+SylixOS/StarterWare/utils/delay.c \
+SylixOS/StarterWare/utils/perf.c
+
+STARTERWARE_PLATFORM_SRCS = \
+SylixOS/StarterWare/platform/platform.c
+
+STARTERWARE_SRCS += $(STARTERWARE_DRIVERS_SRCS)
+STARTERWARE_SRCS += $(STARTERWARE_SYSTEM_CONFIG_SRCS)
+STARTERWARE_SRCS += $(STARTERWARE_UTILS_SRCS)
+STARTERWARE_SRCS += $(STARTERWARE_PLATFORM_SRCS)
+
+#*********************************************************************************************************
+# user src(s) file
+#*********************************************************************************************************
+USR_SRCS = \
+SylixOS/user/main.c \
+
+#*********************************************************************************************************
+# all bspam335x source
+#*********************************************************************************************************
+SRCS = $(BSP_SRCS)
+SRCS += $(DRV_SRCS)
+SRCS += $(USR_SRCS)
+SRCS += $(SYM_SRCS)
+SRCS += $(STARTERWARE_SRCS)
+
+#*********************************************************************************************************
+# build path
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OUTDIR = Debug
+else
+OUTDIR = Release
+endif
+
+OUTPATH = ./$(OUTDIR)
+OBJPATH = $(OUTPATH)/obj
+DEPPATH = $(OUTPATH)/dep
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+O_IMG = $(OUTPATH)/bsp$(PLATFORM).elf
+O_BIN = $(OUTPATH)/bsp$(PLATFORM).bin
+O_SIZ = $(OUTPATH)/bsp$(PLATFORM).siz
+
+#*********************************************************************************************************
+# bspam335x objects
+#*********************************************************************************************************
+OBJS = $(addprefix $(OBJPATH)/, $(addsuffix .o, $(basename $(SRCS))))
+DEPS = $(addprefix $(DEPPATH)/, $(addsuffix .d, $(basename $(SRCS))))
+
+#*********************************************************************************************************
+# include path
+#*********************************************************************************************************
+INCDIR = -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include"
+INCDIR += -I"$(SYLIXOS_BASE_PATH)/libsylixos/SylixOS/include/inet"
+
+INCDIR += -I"./SylixOS"
+INCDIR += -I"./SylixOS/bsp"
+INCDIR += -I"./SylixOS/StarterWare/include"
+INCDIR += -I"./SylixOS/StarterWare/include/hw"
+INCDIR += -I"./SylixOS/StarterWare/include/armv7a"
+INCDIR += -I"./SylixOS/StarterWare/include/armv7a/am335x"
+INCDIR += -I"./SylixOS/StarterWare/usblib/include"
+
+#*********************************************************************************************************
+# compiler preprocess
+#*********************************************************************************************************
+DSYMBOL = -DSYLIXOS
+DSYMBOL += -D__BOOT_INRAM=1
+DSYMBOL += -Dam335x
+DSYMBOL += -Dgcc
+DSYMBOL += -DDMA_MODE
+DSYMBOL += -D$(PLATFORM)
+
+#*********************************************************************************************************
+# load script
+#*********************************************************************************************************
+LD_SCRIPT = SylixOSBSP.ld
+
+#*********************************************************************************************************
+# depend dynamic library
+#*********************************************************************************************************
+DEPEND_DLL = -lsylixos
+
+#*********************************************************************************************************
+# depend dynamic library search path
+#*********************************************************************************************************
+DEPEND_DLL_PATH = -L"$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)"
+
+#*********************************************************************************************************
+# compiler optimize
+#*********************************************************************************************************
+ifeq ($(DEBUG_LEVEL), debug)
+OPTIMIZE = -O0 -g3 -gdwarf-2
+else
+OPTIMIZE = -O2 -g1 -gdwarf-2 # Do NOT use -O3 and -Os
+endif # -Os is not align for function
+ # loop and jump.
+#*********************************************************************************************************
+# depends and compiler parameter (cplusplus in kernel MUST NOT use exceptions and rtti)
+#*********************************************************************************************************
+DEPENDFLAG = -MM
+CXX_EXCEPT = -fno-exceptions -fno-rtti
+COMMONFLAGS = $(CPUFLAGS) $(OPTIMIZE) -Wall -fmessage-length=0 -fsigned-char -fno-short-enums
+ASFLAGS = -x assembler-with-cpp $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -c
+CFLAGS = $(DSYMBOL) $(INCDIR) $(COMMONFLAGS) -c
+CXXFLAGS = $(DSYMBOL) $(INCDIR) $(CXX_EXCEPT) $(COMMONFLAGS) -c
+ARFLAGS = -r
+
+#*********************************************************************************************************
+# define some useful variable
+#*********************************************************************************************************
+DEPEND = $(CC) $(DEPENDFLAG) $(CFLAGS)
+DEPEND.d = $(subst -g ,,$(DEPEND))
+COMPILE.S = $(AS) $(ASFLAGS)
+COMPILE_VFP.S = $(AS) $(ASFLAGS) $(FPUFLAGS)
+COMPILE.c = $(CC) $(CFLAGS)
+COMPILE.cxx = $(CXX) $(CXXFLAGS)
+
+#*********************************************************************************************************
+# target
+#*********************************************************************************************************
+all: $(O_IMG)
+ @echo create "$(O_IMG) $(O_BIN)" success.
+
+#*********************************************************************************************************
+# include depends
+#*********************************************************************************************************
+ifneq ($(MAKECMDGOALS), clean)
+ifneq ($(MAKECMDGOALS), clean_project)
+sinclude $(DEPS)
+endif
+endif
+
+#*********************************************************************************************************
+# auto copy symbol.c symbol.h
+#*********************************************************************************************************
+EMPTY=
+SPACE= $(EMPTY) $(EMPTY)
+$(SYMBOL_PATH)/symbol.c:$(subst $(SPACE),\ ,$(SYLIXOS_BASE_PATH))/libsylixos/$(OUTDIR)/symbol.c
+ cp "$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)/symbol.c" $(SYMBOL_PATH)/symbol.c
+ cp "$(SYLIXOS_BASE_PATH)/libsylixos/$(OUTDIR)/symbol.h" $(SYMBOL_PATH)/symbol.h
+
+#*********************************************************************************************************
+# create depends files
+#*********************************************************************************************************
+$(DEPPATH)/%.d: %.c
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+$(DEPPATH)/%.d: %.cpp
+ @echo creating $@
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ @rm -f $@; \
+ echo -n '$@ $(addprefix $(OBJPATH)/, $(dir $<))' > $@; \
+ $(DEPEND.d) $< >> $@ || rm -f $@; exit;
+
+#*********************************************************************************************************
+# compile source files
+#*********************************************************************************************************
+$(OBJPATH)/%.o: %.S
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.S) $< -o $@
+
+$(OBJPATH)/%.o: %.c
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.c) $< -o $@
+
+$(OBJPATH)/%.o: %.cpp
+ @if [ ! -d "$(dir $@)" ]; then mkdir -p "$(dir $@)"; fi
+ $(COMPILE.cxx) $< -o $@
+
+#*********************************************************************************************************
+# link bspam335x.elf object files
+#*********************************************************************************************************
+$(O_IMG): $(OBJS) $(LD_SCRIPT)
+ $(LD) $(CPUFLAGS) -nostdlib $(addprefix -T,$(LD_SCRIPT)) -o $(O_IMG) $(OBJS) \
+ $(DEPEND_DLL_PATH) $(DEPEND_DLL) -lm -lgcc
+ $(OC) -O binary $(O_IMG) $(O_BIN)
+ $(SZ) --format=berkeley $(O_IMG) > $(O_SIZ)
+
+#*********************************************************************************************************
+# clean
+#*********************************************************************************************************
+.PHONY: clean
+.PHONY: clean_project
+
+#*********************************************************************************************************
+# clean objects
+#*********************************************************************************************************
+clean:
+ -rm -rf $(O_SIZ)
+ -rm -rf $(O_IMG)
+ -rm -rf $(O_BIN)
+ -rm -rf $(SYMBOL_PATH)/symbol.c $(SYMBOL_PATH)/symbol.h
+ -rm -rf $(OBJPATH)
+ -rm -rf $(DEPPATH)
+
+#*********************************************************************************************************
+# clean project
+#*********************************************************************************************************
+clean_project:
+ -rm -rf $(OUTPATH)
+
+#*********************************************************************************************************
+# END
+#*********************************************************************************************************
diff --git a/SylixOS/StarterWare/include/armv7a/am335x/clock.h b/SylixOS/StarterWare/include/armv7a/am335x/clock.h
index e411b20..54f67ad 100644
--- a/SylixOS/StarterWare/include/armv7a/am335x/clock.h
+++ b/SylixOS/StarterWare/include/armv7a/am335x/clock.h
@@ -1,716 +1,716 @@
-/**
- * \file clock.h
- *
- * \brief This file contains the function prototypes for PRCM API's.
- *
- */
-
-/*
-* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
-*/
-/*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-*
-* Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the
-* distribution.
-*
-* Neither the name of Texas Instruments Incorporated nor the names of
-* its contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-
-#ifndef __PRCM_H__
-#define __PRCM_H__
-
-#include "hw_control_AM335x.h"
-#include "hw_types.h"
-#include "hw_cm_per.h"
-#include "hw_cm_wkup.h"
-#include "hw_cm_rtc.h"
-#include "hw_cm_mpu.h"
-#include "hw_cm_dpll.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- FAIL = 0,
- SUCCESS = 1
-}result;
-
-
-/********************** MACROS ***************************/
-
-/* Configs */
-/* Maximun number of OPP's supported by the device */
-#define CLK_MAX_OPP_SUPPORTED (0x4)
-#define CLK_OPP_SR_TURBO (0x0)
-#define CLK_OPP_120 (0x1)
-#define CLK_OPP_100 (0x2)
-#define CLK_OPP_50 (0x3)
-
-/* Maximum number of clocks under a clock domain */
-#define CLK_CLOCKDOMAIN_MAX_CLOCKS (0x50)
-
-/* active logic is '1' */
-#define CLK_ACTIVE_HIGH_LOGIC (0x0)
-
-/* active logic is '0' */
-#define CLK_ACTIVE_LOW_LOGIC (0x1)
-
-/* Different clock speeds */
-#define CLK_EXT_CRYSTAL_SPEED (24*1000*1000)
-#define CLK_CLOCK_SPEED_32768_HZ (32768)
-#define CLK_CLOCK_SPEED_192_MHZ (192*1000*1000)
-#define CLK_CLOCK_SPEED_960_MHZ (960*1000*1000)
-#define CLK_CLOCK_SPEED_600_MHZ (600*1000*1000)
-#define CLK_CLOCK_SPEED_550_MHZ (550*1000*1000)
-#define CLK_CLOCK_SPEED_250_MHZ (250*1000*1000)
-#define CLK_CLOCK_SPEED_200_MHZ (200*1000*1000)
-#define CLK_CLOCK_SPEED_100_MHZ (100*1000*1000)
-
-/* Maximum inputs for the Mux */
-#define CLK_MUX_MAX_INPUT_CLOCKS (0x6)
-
-/* Maximum number of interface clocks required for a module */
-#define CLK_MAX_INTERFACE_CLOCK (0x3)
-
-/* Maximum number of functional clocks required for a module */
-#define CLK_MAX_FUNCTIONAL_CLOCK (0x5)
-
-/* Maximum number of optional clocks required for a module */
-#define CLK_MAX_OPT_CLOCK (0x2)
-
-/* Maximum number of interface clock enable required for a module */
-#define CLK_MAX_INTERFACE_LOCK_ENABLE (0x2)
-
-/* Minimum sigma delta divider for a PLL */
-#define CLK_MIN_ADPLL_SIGMA_DELTA_DIVIDER (0x2)
-
-/* List of Modules */
-#define CLK_MPU_CLK (0x0)
-#define CLK_EMIF (0x1)
-#define CLK_TIMER2 (0x2)
-#define CLK_I2C1 (0x3)
-#define CLK_GPIO3 (0x4)
-#define CLK_SPI0 (0x5)
-#define CLK_UART0 (0x6)
-#define CLK_MAILBOX0 (0x7)
-#define CLK_RTC (0x8)
-#define CLK_L4LS (0x9)
-#define CLK_WDT1 (0xA)
-#define CLK_ADC_TSC (0xB)
-#define CLK_LCDC (0xC)
-#define CLK_WKUP_M3 (0xD)
-#define CLK_L4WKUP (0xE)
-#define CLK_MCASP1 (0xF)
-#define CLK_OCMCRAM (0x10)
-#define CLK_L3 (0x11)
-#define CLK_GPMC (0x12)
-#define CLK_USB0 (0x13)
-#define CLK_L4FW (0x14)
-#define CLK_CPGMAC0 (0x15)
-#define CLK_I2C0 (0x16)
-#define CLK_GPIO0 (0x17)
-#define CLK_GPIO1 (0x18)
-#define CLK_TIMER1 (0x19)
-#define CLK_TIMER3 (0x1A)
-#define CLK_TIMER4 (0x1B)
-#define CLK_TIMER7 (0x1C)
-#define CLK_EPWMSS0 (0x1D)
-#define CLK_TPCC (0x1E)
-#define CLK_TPTC0 (0x1F)
-#define CLK_TPTC1 (0x20)
-#define CLK_TPTC2 (0x21)
-#define CLK_TIMER6 (0x22)
-
-/* List of Clock Domains */
-#define CLK_L4LS_CLK_DOMAIN (0x0)
-#define CLK_RTC_CLK_DOMAIN (0x1)
-#define CLK_WKUP_CLK_DOMAIN (0x2)
-#define CLK_PER_L3_CLK_DOMAIN (0x3)
-#define CLK_L4WKUP_AON_CLK_DOMAIN (0x4)
-#define CLK_MPU_CLK_DOMAIN (0x5)
-#define CLK_LCDC_CLK_DOMAIN (0x6)
-#define CLK_L4_FW_CLK_DOMAIN (0x7)
-#define CLK_L3S_CLK_DOMAIN (0x8)
-#define CLK_CPSW_125MHZ_CLK_DOMAIN (0x9)
-#define CLK_L4HS_CLK_DOMAIN (0xA)
-#define CLK_24MHZ_CLK_DOMAIN (0xB)
-
-/* Clock domain sleep transition */
-#define CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP (0x1u)
-#define CM_CLKSTCTRL_CLKTRCTRL_SW_WKUP (0x2u)
-#define CM_CLKSTCTRL_CLKTRCTRL_SHIFT (0x00000000u)
-
-/* PLL low power mode config */
-#define CM_DPLL_LPMODE_EN_ENABLED (0x1u)
-#define CM_DPLL_LPMODE_EN_SHIFT (0x0000000Au)
-
-/* Module */
-#define MODULE_INVALID (0xFFFFFFFFu)
-#define MODULE_NOT_IDLE (0xFFFFFFFEu)
-#define MODULE_NOT_DISABLED (0xFFFFFFFDu)
-#define MODULE_FUNCTIONAL (0x0u)
-#define MODULE_IN_TRANS (0x1u)
-#define MODULE_IDLE (0x2u)
-#define MODULE_DISABLED (0x3u)
-
-#define MODULE_AND_CLOCK_DISABLED (0x0u)
-#define MODULE_AND_CLOCK_NOT_DISABLED (0x1u)
-
-/* Clock */
-#define CLK_INVALID_GCLK (0xFFFFFFFFu)
-#define CLK_INVALID_DIVIDER (0xFFFFFFFFu)
-#define CLK_CLOCK_GATED (0x0u)
-#define CLK_CLOCK_UNGATED (0x1u)
-
-/* ADPLL */
-#define ADPLL_UNLOCKED (0x0u)
-#define ADPLL_LOCKED (0x1u)
-#define ADPLL_INVALID (0xFFFFFFFFu)
-
-#define CLK_NAME_MAX_SIZE (30)
-
-#define CLK_DOMAIN_CLOCK_GATED (0x0)
-
-#define CLK_LP_MODE_NORMAL (0x0)
-#define CLK_LP_MODE_BYPASS (0x1)
-
-
-/********************** Structure definitions ***************************/
-
-typedef struct clkDivider ClockDivider;
-typedef struct clkDomain ClockDomain;
-typedef struct genericClock Clock;
-
-/**
- * \brief Clock divider definition
- *
- * Clock divider for different OPP's
- */
-struct clkDivider{
-
- /**
- * \brief Divider config register
- * This reigster configures the divider, auto clock gating ctrl and status
- */
- unsigned int *dividerConfigReg;
-
- /**
- * \brief Clock divider mask
- */
- unsigned int clkDividerMask;
-
- /**
- * \brief Divider array ptr
- * Pointer to clock divider array for different OPP
- */
- unsigned int clkDividerValue[CLK_MAX_OPP_SUPPORTED];
-
- /**
- * \brief divider updated status mask
- */
- unsigned int clkDivUpdatedStatusMask;
-
- /**
- * \brief divider updated status shift
- */
- unsigned int clkDivUpdatedStatusShift;
-
- /**
- * \brief CLKOUT auto gating Control mask
- */
- unsigned int clkoutAutoGateCtrlMask;
-
- /**
- * \brief CLKOUT auto gating Control
- */
- unsigned int clkoutAutoGateCtrl;
-
- /**
- * \brief CLKOUT gate status mask
- */
- unsigned int clkoutGateStatusMask;
-
- /**
- * \brief CLKOUT gate status shift
- */
- unsigned int clkoutGateStatusShift;
-
- /**
- * \brief divider auto power down validity
- */
- unsigned int isPdCtrlValid;
-
- /**
- * \brief divider auto Power down Control mask
- */
- unsigned int clkAutoPDCtrlMask;
-
- /**
- * \brief divider auto Power down Control
- */
- unsigned int clkAutoPDCtrl;
-
-};
-
-
-/**
- * \brief PLL structure definition. This will be included as a member of clock
- * structure. If a node in clock tree is PLL then that clock will have valid PLL.
- * This is used to configure the PLL to generate required frequency.
- */
-typedef struct {
-
- /**
- * \brief indicated whether the PLL is configured already
- */
- tBoolean isPLLConfigured;
-
- /**
- * \brief Auto idle register
- * Register to be written to configure the automatic control of the
- * DPLL activity
- */
- unsigned int *autoIdleCtrlReg;
-
- /**
- * \brief Auto idle config value
- * Value to be written to configure the automatic control of the
- * DPLL activity
- */
- unsigned int autoIdleCtrlVal;
-
- /**
- * \brief Idle status register
- * This reigster indicates the master clock idle status
- */
- unsigned int *idleStatusReg;
-
- /**
- * \brief DPLL Clock activity status mask
- */
- unsigned int adpllClkStatusMask;
-
- /**
- * \brief DPLL Clock activity status mask shift
- */
- unsigned int adpllClkStatusShift;
-
- /**
- * \brief DPLL Clock MN bypass status mask
- */
- unsigned int adpllClkMNBypassStatusMask;
-
- /**
- * \brief DPLL Clock MN bypass status mask shift
- */
- unsigned int adpllClkMNBypassStatusShift;
-
- /**
- * \brief DPLL config register
- * This reigster configures the multiplier, divider and bypass clock source
- */
- unsigned int *adpllConfigReg;
-
- /**
- * \brief DPLL Bypass clock source mask
- */
- unsigned int adpllBypassClkMask;
-
- /**
- * \brief DPLL Bypass clock source
- */
- unsigned int adpllBypassClkSource;
-
- /**
- * \brief Sigma delta divider mask
- */
- unsigned int adpllSigmaDeltaDividerMask;
-
- /**
- * \brief Sigma delta divider
- * Sigma-Delta divider select (2 -255). This factor must be set by s/w
- * to ensure optimum jitter performance.
- */
- unsigned int adpllSigmaDeltaDivider[CLK_MAX_OPP_SUPPORTED];
-
- /**
- * \brief DPLL Multiplier mask
- */
- unsigned int adpllMultiplierMask;
-
- /**
- * \brief DPLL Multiplier
- */
- unsigned int adpllMultiplier[CLK_MAX_OPP_SUPPORTED];
-
- /**
- * \brief DPLL divider mask
- */
- unsigned int adpllDividerMask;
-
- /**
- * \brief DPLL divider
- */
- unsigned int adpllDivider[CLK_MAX_OPP_SUPPORTED];
-
- /**
- * \brief DPLL mode register
- * This reigster configures low power mode setting and relock ramp setting
- */
- unsigned int *adpllModeReg;
-
- /**
- * \brief DPLL low power mode control Mask
- */
- unsigned int adpllLowPowerMask;
-
- /**
- * \brief DPLL low power mode control setting
- */
- unsigned int adpllLowPowerNormalVal;
-
- /**
- * \brief DPLL low power mode bypass control setting
- */
- unsigned int adpllLowPowerBypassVal;
-
- /**
- * \brief DPLL relock ramp control Mask
- */
- unsigned int adpllRelockRampMask;
-
- /**
- * \brief DPLL relock ramp control setting
- */
- unsigned int adpllRelockRampVal;
-
-}ADPLL;
-
-
-/**
- * \brief clock definition
- *
- * These are set of parameters defining clock of a module
- */
-struct genericClock{
-
- /**
- * \brief Clock Name
- */
- signed char clkName[CLK_NAME_MAX_SIZE];
-
- /**
- * \brief is leaf clock
- * Is this clock the last node in the clock tree
- */
- unsigned int isLeafClock;
-
- /**
- * \brief Parent clock
- * Parent node of this node in the clock tree
- */
- Clock *parentClock;
-
- /**
- * \brief Clock domain
- * clock domain to which the clock belongs
- */
- ClockDomain *clkDomainPtr;
-
- /**
- * \brief clock speed
- * clock speed in Hz. Always specifies the input clock
- */
- unsigned int clockSpeedHz;
-
- /**
- * \brief PLL pointer
- * Pointer to PLL instance if the clock is a PLL
- */
- ADPLL *adpllPtr;
-
- /**
- * \brief OPP's supported
- * Number of OPP's supported
- */
- unsigned int OPPSupported;
-
- /**
- * \brief Divider
- * Pointer to clock divider
- */
- ClockDivider *clkDivider;
-
- /**
- * \brief Mux input select register
- */
- unsigned int *muxInputSelReg;
-
- /**
- * \brief Mux input select mask
- */
- unsigned int muxInputSelMask;
-
- /**
- * \brief Mux input selector
- */
- unsigned int muxInputSelVal;
-
- /**
- * \brief active child count
- * Indiactes the number of dependent active nodes
- */
- unsigned int activeChildCount;
-
- /* to be extracted from Clock domain ctrl reg (gclk (F/I) belongs to a clock domain) */
-
- /**
- * \brief Module clock gate status register
- * Register to read to get the clock gate status
- */
- unsigned int *clkGateStatusReg;
-
- /**
- * \brief Module clock (gate) status mask
- * Mask to be applied to extract the status bit of the clock gate
- */
- unsigned int clockGateStatusMask;
-
- /**
- * \brief Module clock (gate) status shift
- * No of bits to be shifted to get the status of the clock gate
- */
- unsigned int clockGateStatusShift;
-
-};
-
-
-/**
- * \brief Clock dmoain
- *
- * Clock domain combines multiple clocks and controls the sleep transition
- */
-struct clkDomain{
-
-#ifdef SYLIXOS
- const char *name;
-#endif
-
- /**
- * \brief indicated whether the clock domain is initialized already
- */
- tBoolean isCDInitialized;
-
- /**
- * \brief Number of active clocks under the clock domain
- */
- unsigned int activeClockCount;
-
- /**
- * \brief Clock state transition control
- * Register to be written to configure mode of clock transition
- */
- unsigned int *clkStateTransCtrlReg;
-
- /**
- * \brief Clock state transition value
- * Value to be written to configure mode of clock transition
- */
- unsigned int clkStateTransValue;
-
- /**
- * \brief Clock gate status mask
- * Mask for getting the gate status of all the clocks in the clock domain
- */
- unsigned int clkGateStatusMask;
-
- /**
- * \brief List of clocks in the clock domain
- */
- Clock *clkList[CLK_CLOCKDOMAIN_MAX_CLOCKS];
-
-};
-
-
-/**
- * \brief Mux selection struct, to be used by clock during definition
- */
-typedef struct {
- /**
- * \brief Parent clock
- * Parent node of this node in the clock tree
- */
- Clock *parentClock[CLK_MUX_MAX_INPUT_CLOCKS];
-}MuxParentClockSel;
-
-
-/**
- * \brief Module clock
- * This struct defines the interface clock and functional clock.
- */
-typedef struct {
-#ifdef SYLIXOS
- const char *name;
-#endif
-
- /* module specific */
-
- /**
- * \brief clock control register
- * Register to be written to control the clock
- */
- unsigned int *clockCtrlReg;
-
- /**
- * \brief Enable Value
- * Value to be written to enable the clock
- */
- unsigned int enableValue;
-
- /**
- * \brief Disable Value
- * Value to be written to disable the clock
- */
- unsigned int disableValue;
-
- /**
- * \brief Module status register
- * Register to read to get the clock status
- */
- unsigned int *moduleStatusReg;
-
- /**
- * \brief Module idle status mask
- * Mask to be applied to extract the status bit of the clock
- */
- unsigned int idleStatusMask;
-
- /**
- * \brief Module idle status shift
- * No of bits to be shifted to get the status of the clock
- */
- unsigned int idleStatusShift;
-
- /**
- * \brief Module standby status mask
- * Mask to be applied to extract the standby status bit of the clock
- */
- unsigned int stbyStatusMask;
-
- /**
- * \brief Module standby status shift
- * No of bits to be shifted to get the standby status of the clock
- */
- unsigned int stbyStatusShift;
-
- /* Optional functional clock - not considered here */
-
- /**
- * \brief Interface clock
- */
- Clock *iClk[CLK_MAX_INTERFACE_CLOCK];
-
- /**
- * \brief Functional clock
- */
- Clock *fClk[CLK_MAX_FUNCTIONAL_CLOCK];
-
- /**
- * \brief Optional Clock
- */
- Clock *optClk[CLK_MAX_OPT_CLOCK];
-
- /**
- * \brief clock enable
- */
- Clock *clkEnable[CLK_MAX_INTERFACE_LOCK_ENABLE];
-
-}ModuleClock;
-
-/**
- * \brief Associates a flag with modules to include or exclude for PM Mode
- */
-typedef struct mapModule
-{
- unsigned int module;
- unsigned int select;
-} tMapModule;
-
-/*****************************************************************************
-** FUNCTION DECLARATIONS
-*****************************************************************************/
-
-/* Clock management API's */
-
-void deviceClockEnable(unsigned int enableList[], unsigned noOfElements);
-
-// disable all modules & their clocks
-result deviceClockDisable(unsigned int moduleDisableList[], unsigned noOfElements);
-
-void enableModule(unsigned int moduleId);
-
-void disableModule(unsigned int moduleId);
-
-void enableModuleClock(unsigned int moduleId);
-
-unsigned int disableModuleClock(unsigned int moduleId, tBoolean isBlockingCall);
-
-unsigned int getModuleState(unsigned int moduleId);
-
-int getGclockGateState(Clock *clkPtr);
-
-void initClockDomain(ClockDomain *clkDomainptr);
-
-result disableClockDomain(ClockDomain *clkDomainptr);
-
-
-/* PLL config API's */
-void configADPLL(ADPLL *adpllPtr, unsigned int OPPSupported);
-
-unsigned int getADPLLIdleStatus(ADPLL *adpllPtr);
-
-unsigned int getDividerClkGateStatus(Clock *clkPtr);
-
-result clkdomainGateStatus(unsigned int clkDomainId);
-
-result deviceClockGateStatus(unsigned int clockDomainStatusList[], unsigned noOfElements);
-
-void setLPBypassMode(ADPLL *adpllPtr, unsigned int isNormalByp);
-
-void enableADPLLLowPowerMode(ADPLL *adpllPtr);
-
-void enableSelModuleClock(tMapModule enableList[], unsigned noOfElements);
-
-result disableSelModuleClock(tMapModule moduleDisableList[],
- unsigned int noOfElements);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/**
+ * \file clock.h
+ *
+ * \brief This file contains the function prototypes for PRCM API's.
+ *
+ */
+
+/*
+* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+*/
+/*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+
+#ifndef __PRCM_H__
+#define __PRCM_H__
+
+#include "config.h"
+#include "hw_control_AM335x.h"
+#include "hw_types.h"
+#include "hw_cm_per.h"
+#include "hw_cm_wkup.h"
+#include "hw_cm_rtc.h"
+#include "hw_cm_mpu.h"
+#include "hw_cm_dpll.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ FAIL = 0,
+ SUCCESS = 1
+}result;
+
+
+/********************** MACROS ***************************/
+
+/* Configs */
+/* Maximun number of OPP's supported by the device */
+#define CLK_MAX_OPP_SUPPORTED (0x4)
+#define CLK_OPP_SR_TURBO (0x0)
+#define CLK_OPP_120 (0x1)
+#define CLK_OPP_100 (0x2)
+#define CLK_OPP_50 (0x3)
+
+/* Maximum number of clocks under a clock domain */
+#define CLK_CLOCKDOMAIN_MAX_CLOCKS (0x50)
+
+/* active logic is '1' */
+#define CLK_ACTIVE_HIGH_LOGIC (0x0)
+
+/* active logic is '0' */
+#define CLK_ACTIVE_LOW_LOGIC (0x1)
+
+/* Different clock speeds */
+#define CLK_CLOCK_SPEED_32768_HZ (32768)
+#define CLK_CLOCK_SPEED_192_MHZ (192*1000*1000)
+#define CLK_CLOCK_SPEED_960_MHZ (960*1000*1000)
+#define CLK_CLOCK_SPEED_600_MHZ (600*1000*1000)
+#define CLK_CLOCK_SPEED_550_MHZ (550*1000*1000)
+#define CLK_CLOCK_SPEED_250_MHZ (250*1000*1000)
+#define CLK_CLOCK_SPEED_200_MHZ (200*1000*1000)
+#define CLK_CLOCK_SPEED_100_MHZ (100*1000*1000)
+
+/* Maximum inputs for the Mux */
+#define CLK_MUX_MAX_INPUT_CLOCKS (0x6)
+
+/* Maximum number of interface clocks required for a module */
+#define CLK_MAX_INTERFACE_CLOCK (0x3)
+
+/* Maximum number of functional clocks required for a module */
+#define CLK_MAX_FUNCTIONAL_CLOCK (0x5)
+
+/* Maximum number of optional clocks required for a module */
+#define CLK_MAX_OPT_CLOCK (0x2)
+
+/* Maximum number of interface clock enable required for a module */
+#define CLK_MAX_INTERFACE_LOCK_ENABLE (0x2)
+
+/* Minimum sigma delta divider for a PLL */
+#define CLK_MIN_ADPLL_SIGMA_DELTA_DIVIDER (0x2)
+
+/* List of Modules */
+#define CLK_MPU_CLK (0x0)
+#define CLK_EMIF (0x1)
+#define CLK_TIMER2 (0x2)
+#define CLK_I2C1 (0x3)
+#define CLK_GPIO3 (0x4)
+#define CLK_SPI0 (0x5)
+#define CLK_UART0 (0x6)
+#define CLK_MAILBOX0 (0x7)
+#define CLK_RTC (0x8)
+#define CLK_L4LS (0x9)
+#define CLK_WDT1 (0xA)
+#define CLK_ADC_TSC (0xB)
+#define CLK_LCDC (0xC)
+#define CLK_WKUP_M3 (0xD)
+#define CLK_L4WKUP (0xE)
+#define CLK_MCASP1 (0xF)
+#define CLK_OCMCRAM (0x10)
+#define CLK_L3 (0x11)
+#define CLK_GPMC (0x12)
+#define CLK_USB0 (0x13)
+#define CLK_L4FW (0x14)
+#define CLK_CPGMAC0 (0x15)
+#define CLK_I2C0 (0x16)
+#define CLK_GPIO0 (0x17)
+#define CLK_GPIO1 (0x18)
+#define CLK_TIMER1 (0x19)
+#define CLK_TIMER3 (0x1A)
+#define CLK_TIMER4 (0x1B)
+#define CLK_TIMER7 (0x1C)
+#define CLK_EPWMSS0 (0x1D)
+#define CLK_TPCC (0x1E)
+#define CLK_TPTC0 (0x1F)
+#define CLK_TPTC1 (0x20)
+#define CLK_TPTC2 (0x21)
+#define CLK_TIMER6 (0x22)
+
+/* List of Clock Domains */
+#define CLK_L4LS_CLK_DOMAIN (0x0)
+#define CLK_RTC_CLK_DOMAIN (0x1)
+#define CLK_WKUP_CLK_DOMAIN (0x2)
+#define CLK_PER_L3_CLK_DOMAIN (0x3)
+#define CLK_L4WKUP_AON_CLK_DOMAIN (0x4)
+#define CLK_MPU_CLK_DOMAIN (0x5)
+#define CLK_LCDC_CLK_DOMAIN (0x6)
+#define CLK_L4_FW_CLK_DOMAIN (0x7)
+#define CLK_L3S_CLK_DOMAIN (0x8)
+#define CLK_CPSW_125MHZ_CLK_DOMAIN (0x9)
+#define CLK_L4HS_CLK_DOMAIN (0xA)
+#define CLK_24MHZ_CLK_DOMAIN (0xB)
+
+/* Clock domain sleep transition */
+#define CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP (0x1u)
+#define CM_CLKSTCTRL_CLKTRCTRL_SW_WKUP (0x2u)
+#define CM_CLKSTCTRL_CLKTRCTRL_SHIFT (0x00000000u)
+
+/* PLL low power mode config */
+#define CM_DPLL_LPMODE_EN_ENABLED (0x1u)
+#define CM_DPLL_LPMODE_EN_SHIFT (0x0000000Au)
+
+/* Module */
+#define MODULE_INVALID (0xFFFFFFFFu)
+#define MODULE_NOT_IDLE (0xFFFFFFFEu)
+#define MODULE_NOT_DISABLED (0xFFFFFFFDu)
+#define MODULE_FUNCTIONAL (0x0u)
+#define MODULE_IN_TRANS (0x1u)
+#define MODULE_IDLE (0x2u)
+#define MODULE_DISABLED (0x3u)
+
+#define MODULE_AND_CLOCK_DISABLED (0x0u)
+#define MODULE_AND_CLOCK_NOT_DISABLED (0x1u)
+
+/* Clock */
+#define CLK_INVALID_GCLK (0xFFFFFFFFu)
+#define CLK_INVALID_DIVIDER (0xFFFFFFFFu)
+#define CLK_CLOCK_GATED (0x0u)
+#define CLK_CLOCK_UNGATED (0x1u)
+
+/* ADPLL */
+#define ADPLL_UNLOCKED (0x0u)
+#define ADPLL_LOCKED (0x1u)
+#define ADPLL_INVALID (0xFFFFFFFFu)
+
+#define CLK_NAME_MAX_SIZE (30)
+
+#define CLK_DOMAIN_CLOCK_GATED (0x0)
+
+#define CLK_LP_MODE_NORMAL (0x0)
+#define CLK_LP_MODE_BYPASS (0x1)
+
+
+/********************** Structure definitions ***************************/
+
+typedef struct clkDivider ClockDivider;
+typedef struct clkDomain ClockDomain;
+typedef struct genericClock Clock;
+
+/**
+ * \brief Clock divider definition
+ *
+ * Clock divider for different OPP's
+ */
+struct clkDivider{
+
+ /**
+ * \brief Divider config register
+ * This reigster configures the divider, auto clock gating ctrl and status
+ */
+ unsigned int *dividerConfigReg;
+
+ /**
+ * \brief Clock divider mask
+ */
+ unsigned int clkDividerMask;
+
+ /**
+ * \brief Divider array ptr
+ * Pointer to clock divider array for different OPP
+ */
+ unsigned int clkDividerValue[CLK_MAX_OPP_SUPPORTED];
+
+ /**
+ * \brief divider updated status mask
+ */
+ unsigned int clkDivUpdatedStatusMask;
+
+ /**
+ * \brief divider updated status shift
+ */
+ unsigned int clkDivUpdatedStatusShift;
+
+ /**
+ * \brief CLKOUT auto gating Control mask
+ */
+ unsigned int clkoutAutoGateCtrlMask;
+
+ /**
+ * \brief CLKOUT auto gating Control
+ */
+ unsigned int clkoutAutoGateCtrl;
+
+ /**
+ * \brief CLKOUT gate status mask
+ */
+ unsigned int clkoutGateStatusMask;
+
+ /**
+ * \brief CLKOUT gate status shift
+ */
+ unsigned int clkoutGateStatusShift;
+
+ /**
+ * \brief divider auto power down validity
+ */
+ unsigned int isPdCtrlValid;
+
+ /**
+ * \brief divider auto Power down Control mask
+ */
+ unsigned int clkAutoPDCtrlMask;
+
+ /**
+ * \brief divider auto Power down Control
+ */
+ unsigned int clkAutoPDCtrl;
+
+};
+
+
+/**
+ * \brief PLL structure definition. This will be included as a member of clock
+ * structure. If a node in clock tree is PLL then that clock will have valid PLL.
+ * This is used to configure the PLL to generate required frequency.
+ */
+typedef struct {
+
+ /**
+ * \brief indicated whether the PLL is configured already
+ */
+ tBoolean isPLLConfigured;
+
+ /**
+ * \brief Auto idle register
+ * Register to be written to configure the automatic control of the
+ * DPLL activity
+ */
+ unsigned int *autoIdleCtrlReg;
+
+ /**
+ * \brief Auto idle config value
+ * Value to be written to configure the automatic control of the
+ * DPLL activity
+ */
+ unsigned int autoIdleCtrlVal;
+
+ /**
+ * \brief Idle status register
+ * This reigster indicates the master clock idle status
+ */
+ unsigned int *idleStatusReg;
+
+ /**
+ * \brief DPLL Clock activity status mask
+ */
+ unsigned int adpllClkStatusMask;
+
+ /**
+ * \brief DPLL Clock activity status mask shift
+ */
+ unsigned int adpllClkStatusShift;
+
+ /**
+ * \brief DPLL Clock MN bypass status mask
+ */
+ unsigned int adpllClkMNBypassStatusMask;
+
+ /**
+ * \brief DPLL Clock MN bypass status mask shift
+ */
+ unsigned int adpllClkMNBypassStatusShift;
+
+ /**
+ * \brief DPLL config register
+ * This reigster configures the multiplier, divider and bypass clock source
+ */
+ unsigned int *adpllConfigReg;
+
+ /**
+ * \brief DPLL Bypass clock source mask
+ */
+ unsigned int adpllBypassClkMask;
+
+ /**
+ * \brief DPLL Bypass clock source
+ */
+ unsigned int adpllBypassClkSource;
+
+ /**
+ * \brief Sigma delta divider mask
+ */
+ unsigned int adpllSigmaDeltaDividerMask;
+
+ /**
+ * \brief Sigma delta divider
+ * Sigma-Delta divider select (2 -255). This factor must be set by s/w
+ * to ensure optimum jitter performance.
+ */
+ unsigned int adpllSigmaDeltaDivider[CLK_MAX_OPP_SUPPORTED];
+
+ /**
+ * \brief DPLL Multiplier mask
+ */
+ unsigned int adpllMultiplierMask;
+
+ /**
+ * \brief DPLL Multiplier
+ */
+ unsigned int adpllMultiplier[CLK_MAX_OPP_SUPPORTED];
+
+ /**
+ * \brief DPLL divider mask
+ */
+ unsigned int adpllDividerMask;
+
+ /**
+ * \brief DPLL divider
+ */
+ unsigned int adpllDivider[CLK_MAX_OPP_SUPPORTED];
+
+ /**
+ * \brief DPLL mode register
+ * This reigster configures low power mode setting and relock ramp setting
+ */
+ unsigned int *adpllModeReg;
+
+ /**
+ * \brief DPLL low power mode control Mask
+ */
+ unsigned int adpllLowPowerMask;
+
+ /**
+ * \brief DPLL low power mode control setting
+ */
+ unsigned int adpllLowPowerNormalVal;
+
+ /**
+ * \brief DPLL low power mode bypass control setting
+ */
+ unsigned int adpllLowPowerBypassVal;
+
+ /**
+ * \brief DPLL relock ramp control Mask
+ */
+ unsigned int adpllRelockRampMask;
+
+ /**
+ * \brief DPLL relock ramp control setting
+ */
+ unsigned int adpllRelockRampVal;
+
+}ADPLL;
+
+
+/**
+ * \brief clock definition
+ *
+ * These are set of parameters defining clock of a module
+ */
+struct genericClock{
+
+ /**
+ * \brief Clock Name
+ */
+ signed char clkName[CLK_NAME_MAX_SIZE];
+
+ /**
+ * \brief is leaf clock
+ * Is this clock the last node in the clock tree
+ */
+ unsigned int isLeafClock;
+
+ /**
+ * \brief Parent clock
+ * Parent node of this node in the clock tree
+ */
+ Clock *parentClock;
+
+ /**
+ * \brief Clock domain
+ * clock domain to which the clock belongs
+ */
+ ClockDomain *clkDomainPtr;
+
+ /**
+ * \brief clock speed
+ * clock speed in Hz. Always specifies the input clock
+ */
+ unsigned int clockSpeedHz;
+
+ /**
+ * \brief PLL pointer
+ * Pointer to PLL instance if the clock is a PLL
+ */
+ ADPLL *adpllPtr;
+
+ /**
+ * \brief OPP's supported
+ * Number of OPP's supported
+ */
+ unsigned int OPPSupported;
+
+ /**
+ * \brief Divider
+ * Pointer to clock divider
+ */
+ ClockDivider *clkDivider;
+
+ /**
+ * \brief Mux input select register
+ */
+ unsigned int *muxInputSelReg;
+
+ /**
+ * \brief Mux input select mask
+ */
+ unsigned int muxInputSelMask;
+
+ /**
+ * \brief Mux input selector
+ */
+ unsigned int muxInputSelVal;
+
+ /**
+ * \brief active child count
+ * Indiactes the number of dependent active nodes
+ */
+ unsigned int activeChildCount;
+
+ /* to be extracted from Clock domain ctrl reg (gclk (F/I) belongs to a clock domain) */
+
+ /**
+ * \brief Module clock gate status register
+ * Register to read to get the clock gate status
+ */
+ unsigned int *clkGateStatusReg;
+
+ /**
+ * \brief Module clock (gate) status mask
+ * Mask to be applied to extract the status bit of the clock gate
+ */
+ unsigned int clockGateStatusMask;
+
+ /**
+ * \brief Module clock (gate) status shift
+ * No of bits to be shifted to get the status of the clock gate
+ */
+ unsigned int clockGateStatusShift;
+
+};
+
+
+/**
+ * \brief Clock dmoain
+ *
+ * Clock domain combines multiple clocks and controls the sleep transition
+ */
+struct clkDomain{
+
+#ifdef SYLIXOS
+ const char *name;
+#endif
+
+ /**
+ * \brief indicated whether the clock domain is initialized already
+ */
+ tBoolean isCDInitialized;
+
+ /**
+ * \brief Number of active clocks under the clock domain
+ */
+ unsigned int activeClockCount;
+
+ /**
+ * \brief Clock state transition control
+ * Register to be written to configure mode of clock transition
+ */
+ unsigned int *clkStateTransCtrlReg;
+
+ /**
+ * \brief Clock state transition value
+ * Value to be written to configure mode of clock transition
+ */
+ unsigned int clkStateTransValue;
+
+ /**
+ * \brief Clock gate status mask
+ * Mask for getting the gate status of all the clocks in the clock domain
+ */
+ unsigned int clkGateStatusMask;
+
+ /**
+ * \brief List of clocks in the clock domain
+ */
+ Clock *clkList[CLK_CLOCKDOMAIN_MAX_CLOCKS];
+
+};
+
+
+/**
+ * \brief Mux selection struct, to be used by clock during definition
+ */
+typedef struct {
+ /**
+ * \brief Parent clock
+ * Parent node of this node in the clock tree
+ */
+ Clock *parentClock[CLK_MUX_MAX_INPUT_CLOCKS];
+}MuxParentClockSel;
+
+
+/**
+ * \brief Module clock
+ * This struct defines the interface clock and functional clock.
+ */
+typedef struct {
+#ifdef SYLIXOS
+ const char *name;
+#endif
+
+ /* module specific */
+
+ /**
+ * \brief clock control register
+ * Register to be written to control the clock
+ */
+ unsigned int *clockCtrlReg;
+
+ /**
+ * \brief Enable Value
+ * Value to be written to enable the clock
+ */
+ unsigned int enableValue;
+
+ /**
+ * \brief Disable Value
+ * Value to be written to disable the clock
+ */
+ unsigned int disableValue;
+
+ /**
+ * \brief Module status register
+ * Register to read to get the clock status
+ */
+ unsigned int *moduleStatusReg;
+
+ /**
+ * \brief Module idle status mask
+ * Mask to be applied to extract the status bit of the clock
+ */
+ unsigned int idleStatusMask;
+
+ /**
+ * \brief Module idle status shift
+ * No of bits to be shifted to get the status of the clock
+ */
+ unsigned int idleStatusShift;
+
+ /**
+ * \brief Module standby status mask
+ * Mask to be applied to extract the standby status bit of the clock
+ */
+ unsigned int stbyStatusMask;
+
+ /**
+ * \brief Module standby status shift
+ * No of bits to be shifted to get the standby status of the clock
+ */
+ unsigned int stbyStatusShift;
+
+ /* Optional functional clock - not considered here */
+
+ /**
+ * \brief Interface clock
+ */
+ Clock *iClk[CLK_MAX_INTERFACE_CLOCK];
+
+ /**
+ * \brief Functional clock
+ */
+ Clock *fClk[CLK_MAX_FUNCTIONAL_CLOCK];
+
+ /**
+ * \brief Optional Clock
+ */
+ Clock *optClk[CLK_MAX_OPT_CLOCK];
+
+ /**
+ * \brief clock enable
+ */
+ Clock *clkEnable[CLK_MAX_INTERFACE_LOCK_ENABLE];
+
+}ModuleClock;
+
+/**
+ * \brief Associates a flag with modules to include or exclude for PM Mode
+ */
+typedef struct mapModule
+{
+ unsigned int module;
+ unsigned int select;
+} tMapModule;
+
+/*****************************************************************************
+** FUNCTION DECLARATIONS
+*****************************************************************************/
+
+/* Clock management API's */
+
+void deviceClockEnable(unsigned int enableList[], unsigned noOfElements);
+
+// disable all modules & their clocks
+result deviceClockDisable(unsigned int moduleDisableList[], unsigned noOfElements);
+
+void enableModule(unsigned int moduleId);
+
+void disableModule(unsigned int moduleId);
+
+void enableModuleClock(unsigned int moduleId);
+
+unsigned int disableModuleClock(unsigned int moduleId, tBoolean isBlockingCall);
+
+unsigned int getModuleState(unsigned int moduleId);
+
+int getGclockGateState(Clock *clkPtr);
+
+void initClockDomain(ClockDomain *clkDomainptr);
+
+result disableClockDomain(ClockDomain *clkDomainptr);
+
+
+/* PLL config API's */
+void configADPLL(ADPLL *adpllPtr, unsigned int OPPSupported);
+
+unsigned int getADPLLIdleStatus(ADPLL *adpllPtr);
+
+unsigned int getDividerClkGateStatus(Clock *clkPtr);
+
+result clkdomainGateStatus(unsigned int clkDomainId);
+
+result deviceClockGateStatus(unsigned int clockDomainStatusList[], unsigned noOfElements);
+
+void setLPBypassMode(ADPLL *adpllPtr, unsigned int isNormalByp);
+
+void enableADPLLLowPowerMode(ADPLL *adpllPtr);
+
+void enableSelModuleClock(tMapModule enableList[], unsigned noOfElements);
+
+result disableSelModuleClock(tMapModule moduleDisableList[],
+ unsigned int noOfElements);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/SylixOS/StarterWare/include/edma.h b/SylixOS/StarterWare/include/edma.h
index bbfe4af..ea8974f 100644
--- a/SylixOS/StarterWare/include/edma.h
+++ b/SylixOS/StarterWare/include/edma.h
@@ -1,477 +1,479 @@
-/**
- * \file edma.h
- *
- * \brief This file contains the function prototypes for the device
- * abstraction layer for EDMA. It also contains some
- * related macro definitions and some files to be included.
- */
-
-/*
-* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
-*/
-/*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-*
-* Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the
-* distribution.
-*
-* Neither the name of Texas Instruments Incorporated nor the names of
-* its contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*/
-
-
-#ifndef __EDMA_H__
-#define __EDMA_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "hw_edma3cc.h"
-#include "hw_edma3tc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-//***********************************************************************
-// Values that can be used by the application for configuration via APIs
-//***********************************************************************/
-
-/** Maximum number of EDMA Shadow regions available */
-#define EDMA3_MAX_REGIONS (2u)
-
-/** Number of PaRAM Sets available */
-#define EDMA3_NUM_PARAMSET (128u)
-
-/** Number of Event Queues available */
-#define EDMA3_0_NUM_EVTQUE (2u)
-
-/** Number of Transfer Controllers available */
-#define EDMA3_0_NUM_TC (2u)
-
-/** Interrupt no. for Transfer Completion */
-#define EDMA3_0_CC_XFER_COMPLETION_INT (11u)
-
-/** Interrupt no. for CC Error */
-#define EDMA3_0_CC0_ERRINT (12u)
-
-/** Interrupt no. for TCs Error */
-#define EDMA3_0_TC0_ERRINT (13u)
-#define EDMA3_0_TC1_ERRINT (32u)
-
-#define EDMA3CC_DMA_CHANNELS (32u)
-#define EDMA3CC_QDMA_CHANNELS (8u)
-
-/** DMAQNUM bits Clear */
-#define EDMA3CC_DMAQNUM_CLR(chNum) ( ~ (0x7u << (((chNum) % 8u) \
- * 4u)))
-/** DMAQNUM bits Set */
-#define EDMA3CC_DMAQNUM_SET(chNum,queNum) ((0x7u & (queNum)) << \
- (((chNum) % 8u) * 4u))
-/** QDMAQNUM bits Clear */
-#define EDMA3CC_QDMAQNUM_CLR(chNum) ( ~ (0x7u << ((chNum) * 4u)))
-/** QDMAQNUM bits Set */
-#define EDMA3CC_QDMAQNUM_SET(chNum,queNum) ((0x7u & (queNum)) << \
- ((chNum) * 4u))
-
-#define EDMA3CC_QCHMAP_PAENTRY_CLR (~EDMA3CC_QCHMAP_PAENTRY)
-/** QCHMAP-PaRAMEntry bitfield Set */
-#define EDMA3CC_QCHMAP_PAENTRY_SET(paRAMId) (((EDMA3CC_QCHMAP_PAENTRY >> \
- EDMA3CC_QCHMAP_PAENTRY_SHIFT) & \
- (paRAMId)) << \
- EDMA3CC_QCHMAP_PAENTRY_SHIFT)
-/** QCHMAP-TrigWord bitfield Clear */
-#define EDMA3CC_QCHMAP_TRWORD_CLR (~EDMA3CC_QCHMAP_TRWORD)
-/** QCHMAP-TrigWord bitfield Set */
-#define EDMA3CC_QCHMAP_TRWORD_SET(paRAMId) (((EDMA3CC_QCHMAP_TRWORD >> \
- EDMA3CC_QCHMAP_TRWORD_SHIFT) & \
- (paRAMId)) << \
- EDMA3CC_QCHMAP_TRWORD_SHIFT)
-
-/** OPT-TCC bitfield Clear */
-#define EDMA3CC_OPT_TCC_CLR (~EDMA3CC_OPT_TCC)
-
-/** OPT-TCC bitfield Set */
-#define EDMA3CC_OPT_TCC_SET(tcc) (((EDMA3CC_OPT_TCC >> \
- EDMA3CC_OPT_TCC_SHIFT) & \
- (tcc)) << EDMA3CC_OPT_TCC_SHIFT)
-
-#define EDMA3_SET_ALL_BITS (0xFFFFFFFFu)
-#define EDMA3_CLR_ALL_BITS (0x00000000u)
-
-#define EDMA3CC_COMPL_HANDLER_RETRY_COUNT (10u)
-#define EDMA3CC_ERR_HANDLER_RETRY_COUNT (10u)
-
-#define EDMA3_TRIG_MODE_MANUAL (0u)
-#define EDMA3_TRIG_MODE_QDMA (1u)
-#define EDMA3_TRIG_MODE_EVENT (2u)
-
-#define EDMA3_CHANNEL_TYPE_DMA (0u)
-#define EDMA3_CHANNEL_TYPE_QDMA (1u)
-
-
-#define EDMA3_XFER_COMPLETE (0u)
-#define EDMA3_CC_DMA_EVT_MISS (1u)
-#define EDMA3_CC_QDMA_EVT_MISS (2u)
-
-#define EDMA3_SYNC_A (0u)
-#define EDMA3_SYNC_AB (1u)
-
-#define EDMA3CC_CLR_TCCERR EDMA3CC_CCERRCLR_TCCERR
-#define EDMA3CC_CLR_QTHRQ0 EDMA3CC_CCERRCLR_QTHRXCD0
-#define EDMA3CC_CLR_QTHRQ1 EDMA3CC_CCERRCLR_QTHRXCD1
-
-
-/* paRAMEntry Fields*/
- /**
- * The OPT field (Offset Address 0x0 Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_OPT (0x0u)
-
- /**
- * The SRC field (Offset Address 0x4 Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_SRC (0x1u)
-
- /**
- * The (ACNT+BCNT) field (Offset Address 0x8 Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_ACNT_BCNT (0x2u)
-
- /**
- * The DST field (Offset Address 0xC Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_DST (0x3u)
-
- /**
- * The (SRCBIDX+DSTBIDX) field (Offset Address 0x10 Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_SRC_DST_BIDX (0x4u)
-
- /**
- * The (LINK+BCNTRLD) field (Offset Address 0x14 Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_LINK_BCNTRLD (0x5u)
-
- /**
- * The (SRCCIDX+DSTCIDX) field (Offset Address 0x18 Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_SRC_DST_CIDX (0x6u)
-
- /**
- * The (CCNT+RSVD) field (Offset Address 0x1C Bytes)
- */
-#define EDMA3CC_PARAM_ENTRY_CCNT (0x7u)
-
-
-/** The offset for each PaRAM Entry field */
-#define EDMA3CC_PARAM_FIELD_OFFSET (0x4u)
-
-/** Number of PaRAM Entry fields
- * OPT, SRC, A_B_CNT, DST, SRC_DST_BIDX, LINK_BCNTRLD, SRC_DST_CIDX
- * and CCNT
- */
-#define EDMA3CC_PARAM_ENTRY_FIELDS (0x8u)
-
-
-#define EDMA_REVID_AM335X (0x02u)
-
-#if defined(am335x) || defined(am335x_13x13) || defined(am335x_15x15) || \
- defined(c6a811x) || defined(am386x) || defined(c6741x)
-#define SOC_EDMA3_NUM_DMACH 64
-#define SOC_EDMA3_NUM_QDMACH 8
-#define SOC_EDMA3_NUM_PARAMSETS 256
-#define SOC_EDMA3_NUM_EVQUE 4
-#define SOC_EDMA3_CHMAPEXIST 0
-#define SOC_EDMA3_NUM_REGIONS 8
-#define SOC_EDMA3_MEMPROTECT 0
-#endif
-
-#if defined(am1808) || defined(omapl138) || defined(c6748)
-#define SOC_EDMA3_NUM_DMACH 32
-#define SOC_EDMA3_NUM_QDMACH 8
-#define SOC_EDMA3_NUM_PARAMSETS 128
-#define SOC_EDMA3_NUM_EVQUE 2
-#define SOC_EDMA3_CHMAPEXIST 0
-#define SOC_EDMA3_NUM_REGIONS 4
-#define SOC_EDMA3_MEMPROTECT 0
-#endif
-
-/** Number of TCCS available */
-#define EDMA3_NUM_TCC SOC_EDMA3_NUM_DMACH
-
-/**
- * \brief EDMA3 Parameter RAM Set in User Configurable format
- *
- * This is a mapping of the EDMA3 PaRAM set provided to the user
- * for ease of modification of the individual fields
- */
-typedef struct EDMA3CCPaRAMEntry {
- /** OPT field of PaRAM Set */
- unsigned int opt;
-
- /**
- * \brief Starting byte address of Source
- * For FIFO mode, srcAddr must be a 256-bit aligned address.
- */
- unsigned int srcAddr;
-
- /**
- * \brief Number of bytes in each Array (ACNT)
- */
- unsigned short aCnt;
-
- /**
- * \brief Number of Arrays in each Frame (BCNT)
- */
- unsigned short bCnt;
-
- /**
- * \brief Starting byte address of destination
- * For FIFO mode, destAddr must be a 256-bit aligned address.
- * i.e. 5 LSBs should be 0.
- */
- unsigned int destAddr;
-
- /**
- * \brief Index between consec. arrays of a Source Frame (SRCBIDX)
- */
- short srcBIdx;
-
- /**
- * \brief Index between consec. arrays of a Destination Frame (DSTBIDX)
- */
- short destBIdx;
-
- /**
- * \brief Address for linking (AutoReloading of a PaRAM Set)
- * This must point to a valid aligned 32-byte PaRAM set
- * A value of 0xFFFF means no linking
- */
- unsigned short linkAddr;
-
- /**
- * \brief Reload value of the numArrInFrame (BCNT)
- * Relevant only for A-sync transfers
- */
- unsigned short bCntReload;
-
- /**
- * \brief Index between consecutive frames of a Source Block (SRCCIDX)
- */
- short srcCIdx;
-
- /**
- * \brief Index between consecutive frames of a Dest Block (DSTCIDX)
- */
- short destCIdx;
-
- /**
- * \brief Number of Frames in a block (CCNT)
- */
- unsigned short cCnt;
-
- /**
- * \brief This field is Reserved. Write zero to this field.
- */
- unsigned short rsvd;
-
-}EDMA3CCPaRAMEntry;
-
-/*
-** Structure to store the EDMA context
-*/
-typedef struct edmaContext {
- /* Channel mapping reg Val */
- unsigned int dchMap[64];
- /* DMA Queue Number Register Val */
- unsigned int dmaQNum[8];
-
- /* DMA Region Access Enable Register val */
- unsigned int regAccEnableLow;
- unsigned int regAccEnableHigh;
-
- /* Event Set Register value */
- unsigned int eventSetRegLow;
- unsigned int eventSetRegHigh;
-
- /* Enable Event Set Register value */
- unsigned int enableEvtSetRegLow;
- unsigned int enableEvtSetRegHigh;
-
- /* Interrupt Enable Set Register value */
- unsigned int intEnableSetRegLow;
- unsigned int intEnableSetRegHigh;
-
- struct EDMA3CCPaRAMEntry dmaParEntry[512];
-
-} EDMACONTEXT;
-
-/****************************************************************************
-** API FUNCTION PROTOTYPES
-****************************************************************************/
-
-
-void EDMA3Init(unsigned int baseAdd,
- unsigned int queNum);
-
-void EDMA3EnableChInShadowReg(unsigned int baseAdd,
- unsigned int chType,
- unsigned int chNum);
-
-void EDMA3DisableChInShadowReg(unsigned int baseAdd,
- unsigned int chType,
- unsigned int chNum);
-
-void EDMA3MapChToEvtQ(unsigned int baseAdd,
- unsigned int chType,
- unsigned int chNum,
- unsigned int evtQNum);
-
-void EDMA3UnmapChToEvtQ(unsigned int baseAdd,
- unsigned int chType,
- unsigned int chNum);
-
-void EDMA3MapQdmaChToPaRAM(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int *paRAMId);
-
-void EDMA3SetQdmaTrigWord(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int trigWord);
-
-void EDMA3ClrMissEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3QdmaClrMissEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3ClrCCErr(unsigned int baseAdd,
- unsigned int Flags);
-
-void EDMA3SetEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3ClrEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3EnableDmaEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3DisableDmaEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3EnableQdmaEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3DisableQdmaEvt(unsigned int baseAdd,
- unsigned int chNum);
-
-unsigned int EDMA3GetIntrStatus(unsigned int baseAdd);
-
-void EDMA3EnableEvtIntr(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3DisableEvtIntr(unsigned int baseAdd,
- unsigned int chNum);
-
-void EDMA3ClrIntr(unsigned int baseAdd, unsigned int value);
-
-void EDMA3GetPaRAM(unsigned int baseAdd,
- unsigned int chNum,
- EDMA3CCPaRAMEntry* currPaRAM);
-
-void EDMA3QdmaGetPaRAM(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int paRAMId,
- EDMA3CCPaRAMEntry* currPaRAM);
-
-void EDMA3SetPaRAM(unsigned int baseAdd,
- unsigned int chNum,
- EDMA3CCPaRAMEntry* newPaRAM);
-
-void EDMA3QdmaSetPaRAM(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int paRAMId,
- EDMA3CCPaRAMEntry* newPaRAM);
-
-void EDMA3QdmaSetPaRAMEntry(unsigned int baseAdd,
- unsigned int paRAMId,
- unsigned int paRAMEntry,
- unsigned int newPaRAMEntryVal);
-
-unsigned int EDMA3QdmaGetPaRAMEntry(unsigned int baseAdd,
- unsigned int paRAMId,
- unsigned int paRAMEntry);
-
-unsigned int EDMA3RequestChannel(unsigned int baseAdd, unsigned int chType,
- unsigned int chNum, unsigned int tccNum,
- unsigned int evtQNum);
-
-unsigned int EDMA3FreeChannel(unsigned int baseAdd, unsigned int chType,
- unsigned int chNum, unsigned int trigMode,
- unsigned int tccNum, unsigned int evtQNum);
-
-unsigned int EDMA3EnableTransfer(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int trigMode);
-
-unsigned int EDMA3DisableTransfer(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int trigMode);
-
-void EDMA3ClearErrorBits(unsigned int baseAdd,
- unsigned int chNum,
- unsigned int evtQNum);
-
-unsigned int EDMA3GetCCErrStatus(unsigned int baseAdd);
-
-unsigned int EDMA3GetErrIntrStatus(unsigned int baseAdd);
-
-unsigned int EDMA3QdmaGetErrIntrStatus(unsigned int baseAdd);
-
-void EDMA3CCErrorEvaluate(unsigned int baseAddr);
-
-void EDMA3Deinit(unsigned int baseAdd,
- unsigned int queNum);
-
-unsigned int EDMAVersionGet(void);
-
-unsigned int EDMA3PeripheralIdGet(unsigned int baseAdd);
-unsigned int EDMA3IntrStatusHighGet(unsigned int baseAdd);
-unsigned int EDMA3ErrIntrHighStatusGet(unsigned int baseAdd);
-
-void EDMA3ChannelToParamMap(unsigned int baseAdd,
- unsigned int channel,
- unsigned int paramSet);
-
-extern void EDMA3ContextSave(unsigned int baseAddr,
- EDMACONTEXT *edmaCntxPtr);
-extern void EDMA3ContextRestore(unsigned int baseAddr,
- EDMACONTEXT *edmaCntxPtr);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
-/* !! EOF !! */
+/**
+ * \file edma.h
+ *
+ * \brief This file contains the function prototypes for the device
+ * abstraction layer for EDMA. It also contains some
+ * related macro definitions and some files to be included.
+ */
+
+/*
+* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+*/
+/*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+
+#ifndef __EDMA_H__
+#define __EDMA_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "hw_edma3cc.h"
+#include "hw_edma3tc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+//***********************************************************************
+// Values that can be used by the application for configuration via APIs
+//***********************************************************************/
+
+/** Maximum number of EDMA Shadow regions available */
+#define EDMA3_MAX_REGIONS (2u)
+
+/** Number of PaRAM Sets available */
+#define EDMA3_NUM_PARAMSET (128u)
+
+/** Number of Event Queues available */
+#define EDMA3_0_NUM_EVTQUE (2u)
+
+/** Number of Transfer Controllers available */
+#define EDMA3_0_NUM_TC (2u)
+
+/** Interrupt no. for Transfer Completion */
+#define EDMA3_0_CC_XFER_COMPLETION_INT (11u)
+
+/** Interrupt no. for CC Error */
+#define EDMA3_0_CC0_ERRINT (12u)
+
+/** Interrupt no. for TCs Error */
+#define EDMA3_0_TC0_ERRINT (13u)
+#define EDMA3_0_TC1_ERRINT (32u)
+
+#define EDMA3CC_DMA_CHANNELS (32u)
+#define EDMA3CC_QDMA_CHANNELS (8u)
+
+/** DMAQNUM bits Clear */
+#define EDMA3CC_DMAQNUM_CLR(chNum) ( ~ (0x7u << (((chNum) % 8u) \
+ * 4u)))
+/** DMAQNUM bits Set */
+#define EDMA3CC_DMAQNUM_SET(chNum,queNum) ((0x7u & (queNum)) << \
+ (((chNum) % 8u) * 4u))
+/** QDMAQNUM bits Clear */
+#define EDMA3CC_QDMAQNUM_CLR(chNum) ( ~ (0x7u << ((chNum) * 4u)))
+/** QDMAQNUM bits Set */
+#define EDMA3CC_QDMAQNUM_SET(chNum,queNum) ((0x7u & (queNum)) << \
+ ((chNum) * 4u))
+
+#define EDMA3CC_QCHMAP_PAENTRY_CLR (~EDMA3CC_QCHMAP_PAENTRY)
+/** QCHMAP-PaRAMEntry bitfield Set */
+#define EDMA3CC_QCHMAP_PAENTRY_SET(paRAMId) (((EDMA3CC_QCHMAP_PAENTRY >> \
+ EDMA3CC_QCHMAP_PAENTRY_SHIFT) & \
+ (paRAMId)) << \
+ EDMA3CC_QCHMAP_PAENTRY_SHIFT)
+/** QCHMAP-TrigWord bitfield Clear */
+#define EDMA3CC_QCHMAP_TRWORD_CLR (~EDMA3CC_QCHMAP_TRWORD)
+/** QCHMAP-TrigWord bitfield Set */
+#define EDMA3CC_QCHMAP_TRWORD_SET(paRAMId) (((EDMA3CC_QCHMAP_TRWORD >> \
+ EDMA3CC_QCHMAP_TRWORD_SHIFT) & \
+ (paRAMId)) << \
+ EDMA3CC_QCHMAP_TRWORD_SHIFT)
+
+/** OPT-TCC bitfield Clear */
+#define EDMA3CC_OPT_TCC_CLR (~EDMA3CC_OPT_TCC)
+
+/** OPT-TCC bitfield Set */
+#define EDMA3CC_OPT_TCC_SET(tcc) (((EDMA3CC_OPT_TCC >> \
+ EDMA3CC_OPT_TCC_SHIFT) & \
+ (tcc)) << EDMA3CC_OPT_TCC_SHIFT)
+
+#define EDMA3_SET_ALL_BITS (0xFFFFFFFFu)
+#define EDMA3_CLR_ALL_BITS (0x00000000u)
+
+#define EDMA3CC_COMPL_HANDLER_RETRY_COUNT (10u)
+#define EDMA3CC_ERR_HANDLER_RETRY_COUNT (10u)
+
+#define EDMA3_TRIG_MODE_MANUAL (0u)
+#define EDMA3_TRIG_MODE_QDMA (1u)
+#define EDMA3_TRIG_MODE_EVENT (2u)
+
+#define EDMA3_CHANNEL_TYPE_DMA (0u)
+#define EDMA3_CHANNEL_TYPE_QDMA (1u)
+
+
+#define EDMA3_XFER_COMPLETE (0u)
+#define EDMA3_CC_DMA_EVT_MISS (1u)
+#define EDMA3_CC_QDMA_EVT_MISS (2u)
+
+#define EDMA3_SYNC_A (0u)
+#define EDMA3_SYNC_AB (1u)
+
+#define EDMA3CC_CLR_TCCERR EDMA3CC_CCERRCLR_TCCERR
+#define EDMA3CC_CLR_QTHRQ0 EDMA3CC_CCERRCLR_QTHRXCD0
+#define EDMA3CC_CLR_QTHRQ1 EDMA3CC_CCERRCLR_QTHRXCD1
+
+
+/* paRAMEntry Fields*/
+ /**
+ * The OPT field (Offset Address 0x0 Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_OPT (0x0u)
+
+ /**
+ * The SRC field (Offset Address 0x4 Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_SRC (0x1u)
+
+ /**
+ * The (ACNT+BCNT) field (Offset Address 0x8 Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_ACNT_BCNT (0x2u)
+
+ /**
+ * The DST field (Offset Address 0xC Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_DST (0x3u)
+
+ /**
+ * The (SRCBIDX+DSTBIDX) field (Offset Address 0x10 Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_SRC_DST_BIDX (0x4u)
+
+ /**
+ * The (LINK+BCNTRLD) field (Offset Address 0x14 Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_LINK_BCNTRLD (0x5u)
+
+ /**
+ * The (SRCCIDX+DSTCIDX) field (Offset Address 0x18 Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_SRC_DST_CIDX (0x6u)
+
+ /**
+ * The (CCNT+RSVD) field (Offset Address 0x1C Bytes)
+ */
+#define EDMA3CC_PARAM_ENTRY_CCNT (0x7u)
+
+
+/** The offset for each PaRAM Entry field */
+#define EDMA3CC_PARAM_FIELD_OFFSET (0x4u)
+
+/** Number of PaRAM Entry fields
+ * OPT, SRC, A_B_CNT, DST, SRC_DST_BIDX, LINK_BCNTRLD, SRC_DST_CIDX
+ * and CCNT
+ */
+#define EDMA3CC_PARAM_ENTRY_FIELDS (0x8u)
+
+
+#define EDMA_REVID_AM335X (0x02u)
+
+#if defined(am335x) || defined(am335x_13x13) || defined(am335x_15x15) || \
+ defined(c6a811x) || defined(am386x) || defined(c6741x)
+#define SOC_EDMA3_NUM_DMACH 64
+#define SOC_EDMA3_NUM_QDMACH 8
+#define SOC_EDMA3_NUM_PARAMSETS 256
+#define SOC_EDMA3_NUM_EVQUE 4
+#define SOC_EDMA3_CHMAPEXIST 0
+#define SOC_EDMA3_NUM_REGIONS 8
+#define SOC_EDMA3_MEMPROTECT 0
+#endif
+
+#if defined(am1808) || defined(omapl138) || defined(c6748)
+#define SOC_EDMA3_NUM_DMACH 32
+#define SOC_EDMA3_NUM_QDMACH 8
+#define SOC_EDMA3_NUM_PARAMSETS 128
+#define SOC_EDMA3_NUM_EVQUE 2
+#define SOC_EDMA3_CHMAPEXIST 0
+#define SOC_EDMA3_NUM_REGIONS 4
+#define SOC_EDMA3_MEMPROTECT 0
+#endif
+
+/** Number of TCCS available */
+#define EDMA3_NUM_TCC SOC_EDMA3_NUM_DMACH
+
+/**
+ * \brief EDMA3 Parameter RAM Set in User Configurable format
+ *
+ * This is a mapping of the EDMA3 PaRAM set provided to the user
+ * for ease of modification of the individual fields
+ */
+struct EDMA3CCPaRAMEntry {
+ /** OPT field of PaRAM Set */
+ unsigned int opt;
+
+ /**
+ * \brief Starting byte address of Source
+ * For FIFO mode, srcAddr must be a 256-bit aligned address.
+ */
+ unsigned int srcAddr;
+
+ /**
+ * \brief Number of bytes in each Array (ACNT)
+ */
+ unsigned short aCnt;
+
+ /**
+ * \brief Number of Arrays in each Frame (BCNT)
+ */
+ unsigned short bCnt;
+
+ /**
+ * \brief Starting byte address of destination
+ * For FIFO mode, destAddr must be a 256-bit aligned address.
+ * i.e. 5 LSBs should be 0.
+ */
+ unsigned int destAddr;
+
+ /**
+ * \brief Index between consec. arrays of a Source Frame (SRCBIDX)
+ */
+ short srcBIdx;
+
+ /**
+ * \brief Index between consec. arrays of a Destination Frame (DSTBIDX)
+ */
+ short destBIdx;
+
+ /**
+ * \brief Address for linking (AutoReloading of a PaRAM Set)
+ * This must point to a valid aligned 32-byte PaRAM set
+ * A value of 0xFFFF means no linking
+ */
+ unsigned short linkAddr;
+
+ /**
+ * \brief Reload value of the numArrInFrame (BCNT)
+ * Relevant only for A-sync transfers
+ */
+ unsigned short bCntReload;
+
+ /**
+ * \brief Index between consecutive frames of a Source Block (SRCCIDX)
+ */
+ short srcCIdx;
+
+ /**
+ * \brief Index between consecutive frames of a Dest Block (DSTCIDX)
+ */
+ short destCIdx;
+
+ /**
+ * \brief Number of Frames in a block (CCNT)
+ */
+ unsigned short cCnt;
+
+ /**
+ * \brief This field is Reserved. Write zero to this field.
+ */
+ unsigned short rsvd;
+
+} __attribute__ ((packed));
+
+typedef struct EDMA3CCPaRAMEntry EDMA3CCPaRAMEntry;
+
+/*
+** Structure to store the EDMA context
+*/
+typedef struct edmaContext {
+ /* Channel mapping reg Val */
+ unsigned int dchMap[64];
+ /* DMA Queue Number Register Val */
+ unsigned int dmaQNum[8];
+
+ /* DMA Region Access Enable Register val */
+ unsigned int regAccEnableLow;
+ unsigned int regAccEnableHigh;
+
+ /* Event Set Register value */
+ unsigned int eventSetRegLow;
+ unsigned int eventSetRegHigh;
+
+ /* Enable Event Set Register value */
+ unsigned int enableEvtSetRegLow;
+ unsigned int enableEvtSetRegHigh;
+
+ /* Interrupt Enable Set Register value */
+ unsigned int intEnableSetRegLow;
+ unsigned int intEnableSetRegHigh;
+
+ struct EDMA3CCPaRAMEntry dmaParEntry[512];
+
+} EDMACONTEXT;
+
+/****************************************************************************
+** API FUNCTION PROTOTYPES
+****************************************************************************/
+
+
+void EDMA3Init(unsigned int baseAdd,
+ unsigned int queNum);
+
+void EDMA3EnableChInShadowReg(unsigned int baseAdd,
+ unsigned int chType,
+ unsigned int chNum);
+
+void EDMA3DisableChInShadowReg(unsigned int baseAdd,
+ unsigned int chType,
+ unsigned int chNum);
+
+void EDMA3MapChToEvtQ(unsigned int baseAdd,
+ unsigned int chType,
+ unsigned int chNum,
+ unsigned int evtQNum);
+
+void EDMA3UnmapChToEvtQ(unsigned int baseAdd,
+ unsigned int chType,
+ unsigned int chNum);
+
+void EDMA3MapQdmaChToPaRAM(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int *paRAMId);
+
+void EDMA3SetQdmaTrigWord(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int trigWord);
+
+void EDMA3ClrMissEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3QdmaClrMissEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3ClrCCErr(unsigned int baseAdd,
+ unsigned int Flags);
+
+void EDMA3SetEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3ClrEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3EnableDmaEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3DisableDmaEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3EnableQdmaEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3DisableQdmaEvt(unsigned int baseAdd,
+ unsigned int chNum);
+
+unsigned int EDMA3GetIntrStatus(unsigned int baseAdd);
+
+void EDMA3EnableEvtIntr(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3DisableEvtIntr(unsigned int baseAdd,
+ unsigned int chNum);
+
+void EDMA3ClrIntr(unsigned int baseAdd, unsigned int value);
+
+void EDMA3GetPaRAM(unsigned int baseAdd,
+ unsigned int chNum,
+ EDMA3CCPaRAMEntry* currPaRAM);
+
+void EDMA3QdmaGetPaRAM(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int paRAMId,
+ EDMA3CCPaRAMEntry* currPaRAM);
+
+void EDMA3SetPaRAM(unsigned int baseAdd,
+ unsigned int chNum,
+ EDMA3CCPaRAMEntry* newPaRAM);
+
+void EDMA3QdmaSetPaRAM(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int paRAMId,
+ EDMA3CCPaRAMEntry* newPaRAM);
+
+void EDMA3QdmaSetPaRAMEntry(unsigned int baseAdd,
+ unsigned int paRAMId,
+ unsigned int paRAMEntry,
+ unsigned int newPaRAMEntryVal);
+
+unsigned int EDMA3QdmaGetPaRAMEntry(unsigned int baseAdd,
+ unsigned int paRAMId,
+ unsigned int paRAMEntry);
+
+unsigned int EDMA3RequestChannel(unsigned int baseAdd, unsigned int chType,
+ unsigned int chNum, unsigned int tccNum,
+ unsigned int evtQNum);
+
+unsigned int EDMA3FreeChannel(unsigned int baseAdd, unsigned int chType,
+ unsigned int chNum, unsigned int trigMode,
+ unsigned int tccNum, unsigned int evtQNum);
+
+unsigned int EDMA3EnableTransfer(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int trigMode);
+
+unsigned int EDMA3DisableTransfer(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int trigMode);
+
+void EDMA3ClearErrorBits(unsigned int baseAdd,
+ unsigned int chNum,
+ unsigned int evtQNum);
+
+unsigned int EDMA3GetCCErrStatus(unsigned int baseAdd);
+
+unsigned int EDMA3GetErrIntrStatus(unsigned int baseAdd);
+
+unsigned int EDMA3QdmaGetErrIntrStatus(unsigned int baseAdd);
+
+void EDMA3CCErrorEvaluate(unsigned int baseAddr);
+
+void EDMA3Deinit(unsigned int baseAdd,
+ unsigned int queNum);
+
+unsigned int EDMAVersionGet(void);
+
+unsigned int EDMA3PeripheralIdGet(unsigned int baseAdd);
+unsigned int EDMA3IntrStatusHighGet(unsigned int baseAdd);
+unsigned int EDMA3ErrIntrHighStatusGet(unsigned int baseAdd);
+
+void EDMA3ChannelToParamMap(unsigned int baseAdd,
+ unsigned int channel,
+ unsigned int paramSet);
+
+extern void EDMA3ContextSave(unsigned int baseAddr,
+ EDMACONTEXT *edmaCntxPtr);
+extern void EDMA3ContextRestore(unsigned int baseAddr,
+ EDMACONTEXT *edmaCntxPtr);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/* !! EOF !! */
diff --git a/SylixOS/bsp/beaglebone/config_beaglebone.h b/SylixOS/bsp/beaglebone/config_beaglebone.h
index 20a8408..059c815 100644
--- a/SylixOS/bsp/beaglebone/config_beaglebone.h
+++ b/SylixOS/bsp/beaglebone/config_beaglebone.h
@@ -1,74 +1,78 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM) LW : long wing
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: config_beaglebone.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 15 日
-**
-** 描 述: beaglebone 开发板配置.
-*********************************************************************************************************/
-#ifndef CONFIG_BEAGLEBONE_H_
-#define CONFIG_BEAGLEBONE_H_
-/*********************************************************************************************************
- 名字配置
-*********************************************************************************************************/
-#define BSP_CFG_PLATFORM_NAME "beaglebone"
-/*********************************************************************************************************
- ROM RAM 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ROM_BASE 0x40000000
-#define BSP_CFG_ROM_SIZE (176 * 1024)
-
-#define BSP_CFG_RAM_BASE 0x80000000
-#define BSP_CFG_RAM_SIZE (128 * 1024 * 1024)
-
-#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
-#define BSP_CFG_COMMON_MEM_SIZE (48 * 1024 * 1024)
-
-#define BSP_CFG_KERN_HEAP_SIZE (32 * 1024 * 1024)
-/*********************************************************************************************************
- 网口相关配置
-*********************************************************************************************************/
-#define CPSW_DUAL_MAC_MODE
-#undef CPSW_SWITCH_CONFIG
-/*********************************************************************************************************
- ADC 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ADC_TOUCH_EN 1
-
-#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
-
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
-/*********************************************************************************************************
- NAND 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_NAND_EN 0
-
-#define BSP_CFG_NAND_ROOTFS_EN 0
-/*********************************************************************************************************
- SD 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_SD_ROOTFS_EN 1
-/*********************************************************************************************************
- 串口相关配置
-*********************************************************************************************************/
-#define BSP_CFG_STD_FILE "/dev/ttyS0"
-
-#endif /* CONFIG_BEAGLEBONE_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: config_beaglebone.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 15 日
+**
+** 描 述: beaglebone 开发板配置.
+*********************************************************************************************************/
+#ifndef CONFIG_BEAGLEBONE_H_
+#define CONFIG_BEAGLEBONE_H_
+/*********************************************************************************************************
+ 名字配置
+*********************************************************************************************************/
+#define BSP_CFG_PLATFORM_NAME "beaglebone"
+/*********************************************************************************************************
+ 外部晶振时钟配置
+*********************************************************************************************************/
+#define CLK_EXT_CRYSTAL_SPEED (24 * 1000 * 1000)
+/*********************************************************************************************************
+ ROM RAM 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ROM_BASE 0x40000000
+#define BSP_CFG_ROM_SIZE (176 * 1024)
+
+#define BSP_CFG_RAM_BASE 0x80000000
+#define BSP_CFG_RAM_SIZE (128 * 1024 * 1024)
+
+#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
+#define BSP_CFG_COMMON_MEM_SIZE (48 * 1024 * 1024)
+
+#define BSP_CFG_KERN_HEAP_SIZE (32 * 1024 * 1024)
+/*********************************************************************************************************
+ 网口相关配置
+*********************************************************************************************************/
+#define CPSW_DUAL_MAC_MODE
+#undef CPSW_SWITCH_CONFIG
+/*********************************************************************************************************
+ ADC 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ADC_TOUCH_EN 1
+
+#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
+
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
+/*********************************************************************************************************
+ NAND 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_NAND_EN 0
+
+#define BSP_CFG_NAND_ROOTFS_EN 0
+/*********************************************************************************************************
+ SD 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_SD_ROOTFS_EN 1
+/*********************************************************************************************************
+ 串口相关配置
+*********************************************************************************************************/
+#define BSP_CFG_STD_FILE "/dev/ttyS0"
+
+#endif /* CONFIG_BEAGLEBONE_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/bsp/bspMap.h b/SylixOS/bsp/bspMap.h
index 8d1aed7..2d20e9e 100644
--- a/SylixOS/bsp/bspMap.h
+++ b/SylixOS/bsp/bspMap.h
@@ -405,7 +405,7 @@ LW_MMU_GLOBAL_DESC _G_globaldescMap[] = {
(LW_VMM_FLAG_DMA) /* 映射的属性 */
},
-#if 0
+#if 1
{
SOC_EDMA30CC_0_REGS, /* EDMA30CC_0 寄存器的物理地址 */
SOC_EDMA30CC_0_REGS, /* 映射到的虚拟地址 */
@@ -433,7 +433,9 @@ LW_MMU_GLOBAL_DESC _G_globaldescMap[] = {
1 * 1024 * 1024, /* 映射的大小 */
(LW_VMM_FLAG_DMA) /* 映射的属性 */
},
+#endif
+#if 0
{
SOC_DCAN_0_REGS, /* DCAN_0 寄存器的物理地址 */
SOC_DCAN_0_REGS, /* 映射到的虚拟地址 */
@@ -484,27 +486,6 @@ LW_MMU_GLOBAL_DESC _G_globaldescMap[] = {
},
{
- 0x49800000, /* EDMA3TC0 寄存器的物理地址 */
- 0x49800000, /* 映射到的虚拟地址 */
- 4 * 1024, /* 映射的大小 */
- (LW_VMM_FLAG_DMA) /* 映射的属性 */
- },
-
- {
- 0x49900000, /* EDMA3TC1 寄存器的物理地址 */
- 0x49900000, /* 映射到的虚拟地址 */
- 4 * 1024, /* 映射的大小 */
- (LW_VMM_FLAG_DMA) /* 映射的属性 */
- },
-
- {
- 0x49a00000, /* EDMA3TC2 寄存器的物理地址 */
- 0x49a00000, /* 映射到的虚拟地址 */
- 4 * 1024, /* 映射的大小 */
- (LW_VMM_FLAG_DMA) /* 映射的属性 */
- },
-
- {
0x4a102000, /* CPPI_RAM 寄存器的物理地址 */
0x4a102000, /* 映射到的虚拟地址 */
0x4a103FFF - 0x4a102000 + 1, /* 映射的大小 */
diff --git a/SylixOS/bsp/config.h b/SylixOS/bsp/config.h
index df3262a..9c2c104 100644
--- a/SylixOS/bsp/config.h
+++ b/SylixOS/bsp/config.h
@@ -1,117 +1,121 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM) LW : long wing
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: config.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2014 年 12 月 25 日
-**
-** 描 述: BSP 配置.
-*********************************************************************************************************/
-#ifndef __CONFIG_H
-#define __CONFIG_H
-/*********************************************************************************************************
- 中断优先级配置
-*********************************************************************************************************/
-#define BSP_CFG_INT_PREEMPT_EN 1
-
-#define BSP_CFG_LCD_INT_PRIO 5
-
-#define BSP_CFG_TIMER2_INT_PRIO 0
-
-#define BSP_CFG_I2C0_INT_PRIO 2
-#define BSP_CFG_I2C1_INT_PRIO 2
-#define BSP_CFG_I2C2_INT_PRIO 2
-
-#define BSP_CFG_EDMA3_COMP_INT_PRIO 1
-#define BSP_CFG_EDMA3_ERR_INT_PRIO 2
-
-#define BSP_CFG_UART0_INT_PRIO 3
-#define BSP_CFG_UART1_INT_PRIO 3
-#define BSP_CFG_UART2_INT_PRIO 3
-#define BSP_CFG_UART3_INT_PRIO 3
-#define BSP_CFG_UART4_INT_PRIO 3
-#define BSP_CFG_UART5_INT_PRIO 3
-
-#define BSP_CFG_NETIF_TX_INT_PRIO 4
-#define BSP_CFG_NETIF_RX_INT_PRIO 4
-#define BSP_CFG_NETIF_MISC_INT_PRIO 4
-
-#define BSP_CFG_USB0_INT_PRIO 5
-#define BSP_CFG_USB1_INT_PRIO 5
-#define BSP_CFG_USBSS_INT_PRIO 5
-
-#define BSP_CFG_ADC_TOUCH_INT_PRIO 5
-
-#define BSP_CFG_ELM_INT_PRIO 3
-#define BSP_CFG_GPMC_INT_PRIO 3
-
-#define BSP_CFG_GPIO_INT_PRIO 5
-
-#define BSP_CFG_CAN0_INT_PRIO 3
-#define BSP_CFG_CAN1_INT_PRIO 3
-
-#define BSP_CFG_MMCSD0_INT_PRIO 5
-#define BSP_CFG_MMCSD1_INT_PRIO 5
-#define BSP_CFG_MMCSD2_INT_PRIO 5
-/*********************************************************************************************************
- PERF 配置
-*********************************************************************************************************/
-#define BSP_CFG_INT_PERF_EN 1
-#define BSP_CFG_DMA_PERF_EN 0
-#define BSP_CFG_UART_PERF_EN 0
-#define BSP_CFG_NAND_PERF_EN 0
-/*********************************************************************************************************
- IP 地址配置
-*********************************************************************************************************/
-#define BSP_CFG_EN1_IPADDR "192.168.1.11"
-#define BSP_CFG_EN1_NETMASK "255.255.255.0"
-#define BSP_CFG_EN1_GATEWAY "192.168.1.1"
-
-#define BSP_CFG_EN2_IPADDR "192.168.2.11"
-#define BSP_CFG_EN2_NETMASK "255.255.255.0"
-#define BSP_CFG_EN2_GATEWAY "192.168.2.1"
-/*********************************************************************************************************
- CPSW 驱动配置
-
- 如果您的项目使用以太网极频繁地发送小包, 建议配置 BSP_CFG_CPSW_TX_DMA_PBUF 为 1, 否则建议配置为 0
-*********************************************************************************************************/
-#define BSP_CFG_CPSW_TX_DMA_PBUF 0
-#define BSP_CFG_CPSW_CPPI_RAM_SIZE (80 * 1024)
-/*********************************************************************************************************
- 开发板相关配置
-*********************************************************************************************************/
-#if defined(evmAM335x)
-#include "ti/config_evmAM335x.h"
-#elif defined(evmskAM335x)
-#include "ti/config_evmskAM335x.h"
-#elif defined(beaglebone)
-#include "beaglebone/config_beaglebone.h"
-#elif defined(ok335xd)
-#include "forlinx/config_ok335xd.h"
-#elif defined(ok335xs)
-#include "forlinx/config_ok335xs.h"
-#else
-#error "Please define your platform in Makefile PLATFORM variable!"
-#endif
-/*********************************************************************************************************
- 配置检查
-*********************************************************************************************************/
-#if defined(CPSW_DUAL_MAC_MODE) && defined(CPSW_SWITCH_CONFIG)
-#error "Can NOT define CPSW_DUAL_MAC_MODE and CPSW_SWITCH_CONFIG in the same time!"
-#endif
-
-#endif /* __CONFIG_H */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: config.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2014 年 12 月 25 日
+**
+** 描 述: BSP 配置.
+*********************************************************************************************************/
+#ifndef __CONFIG_H
+#define __CONFIG_H
+/*********************************************************************************************************
+ 中断优先级配置
+*********************************************************************************************************/
+#define BSP_CFG_INT_PREEMPT_EN 1
+
+#define BSP_CFG_LCD_INT_PRIO 5
+
+#define BSP_CFG_TIMER2_INT_PRIO 0
+
+#define BSP_CFG_I2C0_INT_PRIO 2
+#define BSP_CFG_I2C1_INT_PRIO 2
+#define BSP_CFG_I2C2_INT_PRIO 2
+
+#define BSP_CFG_EDMA3_COMP_INT_PRIO 1
+#define BSP_CFG_EDMA3_ERR_INT_PRIO 2
+
+#define BSP_CFG_UART0_INT_PRIO 3
+#define BSP_CFG_UART1_INT_PRIO 3
+#define BSP_CFG_UART2_INT_PRIO 3
+#define BSP_CFG_UART3_INT_PRIO 3
+#define BSP_CFG_UART4_INT_PRIO 3
+#define BSP_CFG_UART5_INT_PRIO 3
+
+#define BSP_CFG_NETIF_TX_INT_PRIO 4
+#define BSP_CFG_NETIF_RX_INT_PRIO 4
+#define BSP_CFG_NETIF_MISC_INT_PRIO 4
+
+#define BSP_CFG_USB0_INT_PRIO 5
+#define BSP_CFG_USB1_INT_PRIO 5
+#define BSP_CFG_USBSS_INT_PRIO 5
+
+#define BSP_CFG_ADC_TOUCH_INT_PRIO 5
+
+#define BSP_CFG_ELM_INT_PRIO 3
+#define BSP_CFG_GPMC_INT_PRIO 3
+
+#define BSP_CFG_GPIO_INT_PRIO 5
+
+#define BSP_CFG_CAN0_INT_PRIO 3
+#define BSP_CFG_CAN1_INT_PRIO 3
+
+#define BSP_CFG_MMCSD0_INT_PRIO 5
+#define BSP_CFG_MMCSD1_INT_PRIO 5
+#define BSP_CFG_MMCSD2_INT_PRIO 5
+/*********************************************************************************************************
+ PERF 配置
+*********************************************************************************************************/
+#define BSP_CFG_INT_PERF_EN 1
+#define BSP_CFG_DMA_PERF_EN 1
+#define BSP_CFG_UART_PERF_EN 0
+#define BSP_CFG_NAND_PERF_EN 0
+/*********************************************************************************************************
+ IP 地址配置
+*********************************************************************************************************/
+#define BSP_CFG_EN1_IPADDR "192.168.1.11"
+#define BSP_CFG_EN1_NETMASK "255.255.255.0"
+#define BSP_CFG_EN1_GATEWAY "192.168.1.1"
+
+#define BSP_CFG_EN2_IPADDR "192.168.2.11"
+#define BSP_CFG_EN2_NETMASK "255.255.255.0"
+#define BSP_CFG_EN2_GATEWAY "192.168.2.1"
+/*********************************************************************************************************
+ CPSW 驱动配置
+
+ 如果您的项目使用以太网极频繁地发送小包, 建议配置 BSP_CFG_CPSW_TX_DMA_PBUF 为 1, 否则建议配置为 0
+*********************************************************************************************************/
+#define BSP_CFG_CPSW_TX_DMA_PBUF 0
+#define BSP_CFG_CPSW_CPPI_RAM_SIZE (80 * 1024)
+/*********************************************************************************************************
+ 开发板相关配置
+*********************************************************************************************************/
+#if defined(evmAM335x)
+#include "ti/config_evmAM335x.h"
+#elif defined(evmskAM335x)
+#include "ti/config_evmskAM335x.h"
+#elif defined(beaglebone)
+#include "beaglebone/config_beaglebone.h"
+#elif defined(ok335xd)
+#include "forlinx/config_ok335xd.h"
+#elif defined(ok335xs)
+#include "forlinx/config_ok335xs.h"
+#elif defined(FK2500)
+#include "watertek/config_fk2500.h"
+#elif defined(CT3520)
+#include "watertek/config_ct3520.h"
+#else
+#error "Please define your platform in Makefile PLATFORM variable!"
+#endif
+/*********************************************************************************************************
+ 配置检查
+*********************************************************************************************************/
+#if defined(CPSW_DUAL_MAC_MODE) && defined(CPSW_SWITCH_CONFIG)
+#error "Can NOT define CPSW_DUAL_MAC_MODE and CPSW_SWITCH_CONFIG in the same time!"
+#endif
+
+#endif /* __CONFIG_H */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/bsp/forlinx/config_ok335xd.h b/SylixOS/bsp/forlinx/config_ok335xd.h
index 18d52b5..a0196df 100644
--- a/SylixOS/bsp/forlinx/config_ok335xd.h
+++ b/SylixOS/bsp/forlinx/config_ok335xd.h
@@ -1,81 +1,85 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM) LW : long wing
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: config_ok335xd.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 15 日
-**
-** 描 述: OK335xD 开发板配置.
-*********************************************************************************************************/
-#ifndef CONFIG_OK335XD_H_
-#define CONFIG_OK335XD_H_
-/*********************************************************************************************************
- 名字配置
-*********************************************************************************************************/
-#define BSP_CFG_PLATFORM_NAME "OK335xD"
-/*********************************************************************************************************
- ROM RAM 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ROM_BASE 0x40000000
-#define BSP_CFG_ROM_SIZE (176 * 1024)
-
-#define BSP_CFG_RAM_BASE 0x80000000
-#define BSP_CFG_RAM_SIZE (512 * 1024 * 1024)
-
-#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
-#define BSP_CFG_COMMON_MEM_SIZE (128 * 1024 * 1024)
-
-#define BSP_CFG_KERN_HEAP_SIZE (96 * 1024 * 1024)
-/*********************************************************************************************************
- 网口相关配置
-*********************************************************************************************************/
-#undef CPSW_DUAL_MAC_MODE
-#undef CPSW_SWITCH_CONFIG
-
-#define CPSW0_PORT_1_PHY_ADDR 0
-#define CPSW0_PORT_1_PHY_GIGABIT FALSE
-/*********************************************************************************************************
- 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_FT5X06_TOUCH_EN 1
-/*********************************************************************************************************
- ADC 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ADC_TOUCH_EN 0
-
-#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
-
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
-/*********************************************************************************************************
- NAND 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_NAND_EN 1
-
-#define BSP_CFG_NAND_ROOTFS_EN 1
-/*********************************************************************************************************
- SD 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_SD_ROOTFS_EN 0
-/*********************************************************************************************************
- 串口相关配置
-*********************************************************************************************************/
-#define BSP_CFG_STD_FILE "/dev/ttyS0"
-
-#endif /* CONFIG_OK335XD_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: config_ok335xd.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 15 日
+**
+** 描 述: OK335xD 开发板配置.
+*********************************************************************************************************/
+#ifndef CONFIG_OK335XD_H_
+#define CONFIG_OK335XD_H_
+/*********************************************************************************************************
+ 名字配置
+*********************************************************************************************************/
+#define BSP_CFG_PLATFORM_NAME "OK335xD"
+/*********************************************************************************************************
+ 外部晶振时钟配置
+*********************************************************************************************************/
+#define CLK_EXT_CRYSTAL_SPEED (24 * 1000 * 1000)
+/*********************************************************************************************************
+ ROM RAM 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ROM_BASE 0x40000000
+#define BSP_CFG_ROM_SIZE (176 * 1024)
+
+#define BSP_CFG_RAM_BASE 0x80000000
+#define BSP_CFG_RAM_SIZE (512 * 1024 * 1024)
+
+#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
+#define BSP_CFG_COMMON_MEM_SIZE (128 * 1024 * 1024)
+
+#define BSP_CFG_KERN_HEAP_SIZE (96 * 1024 * 1024)
+/*********************************************************************************************************
+ 网口相关配置
+*********************************************************************************************************/
+#undef CPSW_DUAL_MAC_MODE
+#undef CPSW_SWITCH_CONFIG
+
+#define CPSW0_PORT_1_PHY_ADDR 0
+#define CPSW0_PORT_1_PHY_GIGABIT FALSE
+/*********************************************************************************************************
+ 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_FT5X06_TOUCH_EN 1
+/*********************************************************************************************************
+ ADC 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ADC_TOUCH_EN 0
+
+#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
+
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
+/*********************************************************************************************************
+ NAND 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_NAND_EN 1
+
+#define BSP_CFG_NAND_ROOTFS_EN 1
+/*********************************************************************************************************
+ SD 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_SD_ROOTFS_EN 0
+/*********************************************************************************************************
+ 串口相关配置
+*********************************************************************************************************/
+#define BSP_CFG_STD_FILE "/dev/ttyS0"
+
+#endif /* CONFIG_OK335XD_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/bsp/forlinx/config_ok335xs.h b/SylixOS/bsp/forlinx/config_ok335xs.h
index 405c581..ee0ce58 100644
--- a/SylixOS/bsp/forlinx/config_ok335xs.h
+++ b/SylixOS/bsp/forlinx/config_ok335xs.h
@@ -1,83 +1,87 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM) LW : long wing
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: config_ok335xs.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 15 日
-**
-** 描 述: OK335xS 开发板配置.
-*********************************************************************************************************/
-#ifndef CONFIG_OK335XS_H_
-#define CONFIG_OK335XS_H_
-/*********************************************************************************************************
- 名字配置
-*********************************************************************************************************/
-#define BSP_CFG_PLATFORM_NAME "OK335xS"
-/*********************************************************************************************************
- ROM RAM 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ROM_BASE 0x40000000
-#define BSP_CFG_ROM_SIZE (176 * 1024)
-
-#define BSP_CFG_RAM_BASE 0x80000000
-#define BSP_CFG_RAM_SIZE (512 * 1024 * 1024)
-
-#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
-#define BSP_CFG_COMMON_MEM_SIZE (128 * 1024 * 1024)
-
-#define BSP_CFG_KERN_HEAP_SIZE (96 * 1024 * 1024)
-/*********************************************************************************************************
- 网口相关配置
-*********************************************************************************************************/
-#define CPSW_DUAL_MAC_MODE
-#undef CPSW_SWITCH_CONFIG
-
-#define CPSW0_PORT_1_PHY_ADDR 0
-#define CPSW0_PORT_2_PHY_ADDR 1
-#define CPSW0_PORT_1_PHY_GIGABIT TRUE
-#define CPSW0_PORT_2_PHY_GIGABIT TRUE
-/*********************************************************************************************************
- 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_FT5X06_TOUCH_EN 1
-/*********************************************************************************************************
- ADC 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ADC_TOUCH_EN 0
-
-#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
-
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
-/*********************************************************************************************************
- NAND 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_NAND_EN 1
-
-#define BSP_CFG_NAND_ROOTFS_EN 1
-/*********************************************************************************************************
- SD 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_SD_ROOTFS_EN 0
-/*********************************************************************************************************
- 串口相关配置
-*********************************************************************************************************/
-#define BSP_CFG_STD_FILE "/dev/ttyS0"
-
-#endif /* CONFIG_OK335XS_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: config_ok335xs.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 15 日
+**
+** 描 述: OK335xS 开发板配置.
+*********************************************************************************************************/
+#ifndef CONFIG_OK335XS_H_
+#define CONFIG_OK335XS_H_
+/*********************************************************************************************************
+ 名字配置
+*********************************************************************************************************/
+#define BSP_CFG_PLATFORM_NAME "OK335xS"
+/*********************************************************************************************************
+ 外部晶振时钟配置
+*********************************************************************************************************/
+#define CLK_EXT_CRYSTAL_SPEED (24 * 1000 * 1000)
+/*********************************************************************************************************
+ ROM RAM 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ROM_BASE 0x40000000
+#define BSP_CFG_ROM_SIZE (176 * 1024)
+
+#define BSP_CFG_RAM_BASE 0x80000000
+#define BSP_CFG_RAM_SIZE (512 * 1024 * 1024)
+
+#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
+#define BSP_CFG_COMMON_MEM_SIZE (128 * 1024 * 1024)
+
+#define BSP_CFG_KERN_HEAP_SIZE (96 * 1024 * 1024)
+/*********************************************************************************************************
+ 网口相关配置
+*********************************************************************************************************/
+#define CPSW_DUAL_MAC_MODE
+#undef CPSW_SWITCH_CONFIG
+
+#define CPSW0_PORT_1_PHY_ADDR 0
+#define CPSW0_PORT_2_PHY_ADDR 1
+#define CPSW0_PORT_1_PHY_GIGABIT TRUE
+#define CPSW0_PORT_2_PHY_GIGABIT TRUE
+/*********************************************************************************************************
+ 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_FT5X06_TOUCH_EN 1
+/*********************************************************************************************************
+ ADC 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ADC_TOUCH_EN 0
+
+#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
+
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
+/*********************************************************************************************************
+ NAND 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_NAND_EN 1
+
+#define BSP_CFG_NAND_ROOTFS_EN 1
+/*********************************************************************************************************
+ SD 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_SD_ROOTFS_EN 0
+/*********************************************************************************************************
+ 串口相关配置
+*********************************************************************************************************/
+#define BSP_CFG_STD_FILE "/dev/ttyS0"
+
+#endif /* CONFIG_OK335XS_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/bsp/ti/config_evmAM335x.h b/SylixOS/bsp/ti/config_evmAM335x.h
index fc6c40e..5b365ea 100644
--- a/SylixOS/bsp/ti/config_evmAM335x.h
+++ b/SylixOS/bsp/ti/config_evmAM335x.h
@@ -1,74 +1,78 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM) LW : long wing
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: config_evmAM335x.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 15 日
-**
-** 描 述: evmAM335x 开发板配置.
-*********************************************************************************************************/
-#ifndef CONFIG_EVMAM335X_H_
-#define CONFIG_EVMAM335X_H_
-/*********************************************************************************************************
- 名字配置
-*********************************************************************************************************/
-#define BSP_CFG_PLATFORM_NAME "evmAM335x"
-/*********************************************************************************************************
- ROM RAM 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ROM_BASE 0x40000000
-#define BSP_CFG_ROM_SIZE (176 * 1024)
-
-#define BSP_CFG_RAM_BASE 0x80000000
-#define BSP_CFG_RAM_SIZE (512 * 1024 * 1024)
-
-#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
-#define BSP_CFG_COMMON_MEM_SIZE (128 * 1024 * 1024)
-
-#define BSP_CFG_KERN_HEAP_SIZE (96 * 1024 * 1024)
-/*********************************************************************************************************
- 网口相关配置
-*********************************************************************************************************/
-#undef CPSW_DUAL_MAC_MODE
-#undef CPSW_SWITCH_CONFIG
-/*********************************************************************************************************
- ADC 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ADC_TOUCH_EN 1
-
-#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
-
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
-/*********************************************************************************************************
- NAND 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_NAND_EN 1
-
-#define BSP_CFG_NAND_ROOTFS_EN 1
-/*********************************************************************************************************
- SD 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_SD_ROOTFS_EN 0
-/*********************************************************************************************************
- 串口相关配置
-*********************************************************************************************************/
-#define BSP_CFG_STD_FILE "/dev/ttyS0"
-
-#endif /* CONFIG_EVMAM335X_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: config_evmAM335x.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 15 日
+**
+** 描 述: evmAM335x 开发板配置.
+*********************************************************************************************************/
+#ifndef CONFIG_EVMAM335X_H_
+#define CONFIG_EVMAM335X_H_
+/*********************************************************************************************************
+ 名字配置
+*********************************************************************************************************/
+#define BSP_CFG_PLATFORM_NAME "evmAM335x"
+/*********************************************************************************************************
+ 外部晶振时钟配置
+*********************************************************************************************************/
+#define CLK_EXT_CRYSTAL_SPEED (24 * 1000 * 1000)
+/*********************************************************************************************************
+ ROM RAM 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ROM_BASE 0x40000000
+#define BSP_CFG_ROM_SIZE (176 * 1024)
+
+#define BSP_CFG_RAM_BASE 0x80000000
+#define BSP_CFG_RAM_SIZE (512 * 1024 * 1024)
+
+#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
+#define BSP_CFG_COMMON_MEM_SIZE (128 * 1024 * 1024)
+
+#define BSP_CFG_KERN_HEAP_SIZE (96 * 1024 * 1024)
+/*********************************************************************************************************
+ 网口相关配置
+*********************************************************************************************************/
+#undef CPSW_DUAL_MAC_MODE
+#undef CPSW_SWITCH_CONFIG
+/*********************************************************************************************************
+ ADC 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ADC_TOUCH_EN 1
+
+#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
+
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
+/*********************************************************************************************************
+ NAND 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_NAND_EN 1
+
+#define BSP_CFG_NAND_ROOTFS_EN 1
+/*********************************************************************************************************
+ SD 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_SD_ROOTFS_EN 0
+/*********************************************************************************************************
+ 串口相关配置
+*********************************************************************************************************/
+#define BSP_CFG_STD_FILE "/dev/ttyS0"
+
+#endif /* CONFIG_EVMAM335X_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/bsp/ti/config_evmskAM335x.h b/SylixOS/bsp/ti/config_evmskAM335x.h
index 1f3b086..cdf9484 100644
--- a/SylixOS/bsp/ti/config_evmskAM335x.h
+++ b/SylixOS/bsp/ti/config_evmskAM335x.h
@@ -1,74 +1,78 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM) LW : long wing
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: config_evmskAM335x.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 15 日
-**
-** 描 述: evmskAM335x 开发板配置.
-*********************************************************************************************************/
-#ifndef CONFIG_EVMSKAM335X_H_
-#define CONFIG_EVMSKAM335X_H_
-/*********************************************************************************************************
- 名字配置
-*********************************************************************************************************/
-#define BSP_CFG_PLATFORM_NAME "evmskAM335x"
-/*********************************************************************************************************
- ROM RAM 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ROM_BASE 0x40000000
-#define BSP_CFG_ROM_SIZE (176 * 1024)
-
-#define BSP_CFG_RAM_BASE 0x80000000
-#define BSP_CFG_RAM_SIZE (256 * 1024 * 1024)
-
-#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
-#define BSP_CFG_COMMON_MEM_SIZE (96 * 1024 * 1024)
-
-#define BSP_CFG_KERN_HEAP_SIZE (64 * 1024 * 1024)
-/*********************************************************************************************************
- 网口相关配置
-*********************************************************************************************************/
-#define CPSW_DUAL_MAC_MODE
-#undef CPSW_SWITCH_CONFIG
-/*********************************************************************************************************
- ADC 触摸屏相关配置
-*********************************************************************************************************/
-#define BSP_CFG_ADC_TOUCH_EN 1
-
-#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
-
-#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
-#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
-/*********************************************************************************************************
- NAND 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_NAND_EN 0
-
-#define BSP_CFG_NAND_ROOTFS_EN 0
-/*********************************************************************************************************
- SD 相关配置
-*********************************************************************************************************/
-#define BSP_CFG_SD_ROOTFS_EN 1
-/*********************************************************************************************************
- 串口相关配置
-*********************************************************************************************************/
-#define BSP_CFG_STD_FILE "/dev/ttyS0"
-
-#endif /* CONFIG_EVMSKAM335X_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM) LW : long wing
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: config_evmskAM335x.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 15 日
+**
+** 描 述: evmskAM335x 开发板配置.
+*********************************************************************************************************/
+#ifndef CONFIG_EVMSKAM335X_H_
+#define CONFIG_EVMSKAM335X_H_
+/*********************************************************************************************************
+ 名字配置
+*********************************************************************************************************/
+#define BSP_CFG_PLATFORM_NAME "evmskAM335x"
+/*********************************************************************************************************
+ 外部晶振时钟配置
+*********************************************************************************************************/
+#define CLK_EXT_CRYSTAL_SPEED (24 * 1000 * 1000)
+/*********************************************************************************************************
+ ROM RAM 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ROM_BASE 0x40000000
+#define BSP_CFG_ROM_SIZE (176 * 1024)
+
+#define BSP_CFG_RAM_BASE 0x80000000
+#define BSP_CFG_RAM_SIZE (256 * 1024 * 1024)
+
+#define BSP_CFG_DATA_BASE (BSP_CFG_RAM_BASE + 6 * 1024 * 1024)
+#define BSP_CFG_COMMON_MEM_SIZE (96 * 1024 * 1024)
+
+#define BSP_CFG_KERN_HEAP_SIZE (64 * 1024 * 1024)
+/*********************************************************************************************************
+ 网口相关配置
+*********************************************************************************************************/
+#define CPSW_DUAL_MAC_MODE
+#undef CPSW_SWITCH_CONFIG
+/*********************************************************************************************************
+ ADC 触摸屏相关配置
+*********************************************************************************************************/
+#define BSP_CFG_ADC_TOUCH_EN 1
+
+#define BSP_CFG_ADC_TOUCH_START_SAMPLES_NUM 5
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MAX 300
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MAX 300
+
+#define BSP_CFG_ADC_TOUCH_X_FILTER_MIN 5
+#define BSP_CFG_ADC_TOUCH_Y_FILTER_MIN 5
+/*********************************************************************************************************
+ NAND 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_NAND_EN 0
+
+#define BSP_CFG_NAND_ROOTFS_EN 0
+/*********************************************************************************************************
+ SD 相关配置
+*********************************************************************************************************/
+#define BSP_CFG_SD_ROOTFS_EN 1
+/*********************************************************************************************************
+ 串口相关配置
+*********************************************************************************************************/
+#define BSP_CFG_STD_FILE "/dev/ttyS0"
+
+#endif /* CONFIG_EVMSKAM335X_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/audio/codec/codecDrv.c b/SylixOS/driver/audio/codec/codecDrv.c
index ea7fed3..d8335f7 100644
--- a/SylixOS/driver/audio/codec/codecDrv.c
+++ b/SylixOS/driver/audio/codec/codecDrv.c
@@ -55,7 +55,7 @@ static LONG __audioCodecOpen (PLW_DEV_HDR pDev,
INT iFlags,
INT iMode)
{
- __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
+ __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
if (pcName == LW_NULL) {
_ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);
@@ -105,11 +105,11 @@ static LONG __audioCodecOpen (PLW_DEV_HDR pDev,
*********************************************************************************************************/
static INT __audioCodecClose (PLW_DEV_HDR pDev)
{
- __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
+ __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
if (LW_DEV_DEC_USE_COUNT(pDev) == 0) {
API_SpiDeviceCtl(pCodecDev->CODEC_pSocAudioBusDev, __AUDIO_CODEC_CLOSE, 0);
- API_I2cDeviceCtl(pCodecDev->CODEC_pCodecDev, __AUDIO_CODEC_CLOSE, 0);
+ API_I2cDeviceCtl(pCodecDev->CODEC_pCodecDev, __AUDIO_CODEC_CLOSE, 0);
}
return (ERROR_NONE);
@@ -128,17 +128,17 @@ static INT __audioCodecIoctl (PLW_DEV_HDR pDev,
INT iCmd,
LONG lArg)
{
- __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
- INT *pIntData = (INT *)lArg;
+ __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
+ INT *pIntData = (INT *)lArg;
switch (iCmd) {
case SNDCTL_DSP_SETFMT:
if (API_I2cDeviceCtl(pCodecDev->CODEC_pCodecDev,
- __AUDIO_CODEC_SETFMT, (LONG)pIntData) == ERROR_NONE &&
+ __AUDIO_CODEC_SETFMT, (LONG)pIntData) == ERROR_NONE &&
API_SpiDeviceCtl(pCodecDev->CODEC_pSocAudioBusDev,
- __AUDIO_CODEC_SETFMT, (LONG)pIntData) == ERROR_NONE) {
+ __AUDIO_CODEC_SETFMT, (LONG)pIntData) == ERROR_NONE) {
pCodecDev->CODEC_param.PARAM_iSampleFmt = *pIntData;
}
break;
@@ -149,20 +149,20 @@ static INT __audioCodecIoctl (PLW_DEV_HDR pDev,
case SNDCTL_DSP_CHANNELS:
if (API_I2cDeviceCtl(pCodecDev->CODEC_pCodecDev,
- __AUDIO_CODEC_CHANNELS, (LONG)pIntData) == ERROR_NONE &&
+ __AUDIO_CODEC_CHANNELS, (LONG)pIntData) == ERROR_NONE &&
API_SpiDeviceCtl(pCodecDev->CODEC_pSocAudioBusDev,
- __AUDIO_CODEC_CHANNELS, (LONG)pIntData) == ERROR_NONE) {
+ __AUDIO_CODEC_CHANNELS, (LONG)pIntData) == ERROR_NONE) {
pCodecDev->CODEC_param.PARAM_iChannels = *pIntData;
}
break;
case SNDCTL_DSP_SPEED:
if (API_I2cDeviceCtl(pCodecDev->CODEC_pCodecDev,
- __AUDIO_CODEC_SPEED, (LONG)pIntData) == ERROR_NONE &&
+ __AUDIO_CODEC_SPEED, (LONG)pIntData) == ERROR_NONE &&
API_SpiDeviceCtl(pCodecDev->CODEC_pSocAudioBusDev,
- __AUDIO_CODEC_SPEED, (LONG)pIntData) == ERROR_NONE) {
+ __AUDIO_CODEC_SPEED, (LONG)pIntData) == ERROR_NONE) {
pCodecDev->CODEC_param.PARAM_iSampleRate = *pIntData;
}
break;
@@ -175,7 +175,7 @@ static INT __audioCodecIoctl (PLW_DEV_HDR pDev,
return (ERROR_NONE);
}
/*********************************************************************************************************
-** 函数名称: __audioCodecTransfer
+** 函数名称: __audioSpiDeviceTransfer
** 功能描述: 读取写入 CODEC 设备
** 输 入 : pDev 设备
** pSpiMsg spi 消息
@@ -184,13 +184,52 @@ static INT __audioCodecIoctl (PLW_DEV_HDR pDev,
** 全局变量:
** 调用模块:
*********************************************************************************************************/
+static INT __audioSpiDeviceTransfer (PLW_SPI_DEVICE pspidevice,
+ PLW_SPI_MESSAGE pspimsg,
+ INT iNum)
+{
+ REGISTER PLW_SPI_ADAPTER pspiadapter;
+ INT iError;
+
+ if (!pspidevice || !pspimsg || (iNum < 1)) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+
+ pspiadapter = pspidevice->SPIDEV_pspiadapter;
+ if (pspiadapter == LW_NULL) {
+ _ErrorHandle(ERROR_KERNEL_OBJECT_NULL); /* 未找到适配器 */
+ return (PX_ERROR);
+ }
+
+ if (pspiadapter->SPIADAPTER_pspifunc->SPIFUNC_pfuncMasterXfer) {
+
+ iError = pspiadapter->SPIADAPTER_pspifunc->SPIFUNC_pfuncMasterXfer(pspiadapter, pspimsg, iNum);
+
+ } else {
+ _ErrorHandle(ENOSYS);
+ iError = PX_ERROR;
+ }
+
+ return (iError);
+}
+/*********************************************************************************************************
+** 函数名称: __audioCodecTransfer
+** 功能描述: 使用指定 spi 设备进行一次传输
+** 输 入 : pspidevice 指定的 spi 设备控制块
+** pspimsg 传输消息控制块组
+** iNum 控制消息组中消息的数量
+** 输 出 : 操作的 pspimsg 数量, 错误返回 -1
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
static ssize_t __audioCodecTransfer (PLW_DEV_HDR pDev,
PLW_SPI_MESSAGE pSpiMsg,
INT iNum)
{
- __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
+ __PAUDIO_CODEC_DEV pCodecDev = (__PAUDIO_CODEC_DEV)pDev;
- return (API_SpiDeviceTransfer(pCodecDev->CODEC_pSocAudioBusDev, pSpiMsg, iNum));
+ return (__audioSpiDeviceTransfer(pCodecDev->CODEC_pSocAudioBusDev, pSpiMsg, iNum));
}
/*********************************************************************************************************
** 函数名称: audioCodecDrv
@@ -236,7 +275,7 @@ INT audioCodecDevAdd (CPCHAR pcDspDevName,
CPCHAR pcSocAudioBusName,
CPCHAR pcCodecBusName)
{
- __PAUDIO_CODEC_DEV pCodecDev;
+ __PAUDIO_CODEC_DEV pCodecDev;
pCodecDev = (__PAUDIO_CODEC_DEV)__SHEAP_ZALLOC(sizeof(__AUDIO_CODEC_DEV));
if (pCodecDev == LW_NULL) {
diff --git a/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c b/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c
index 5c19ed0..80429af 100644
--- a/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c
+++ b/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.c
@@ -1,665 +1,660 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: tlv320aic3x.c
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 22 日
-**
-** 描 述: TI tlv320aic3x 音频芯片驱动
-*********************************************************************************************************/
-#define __SYLIXOS_KERNEL
-#include "SylixOS.h"
-#include "system/device/sound/soundcard.h"
-
-#include "driver/audio/codec/codecDrv.h"
-/*********************************************************************************************************
- 定义
-*********************************************************************************************************/
-#define __AIC3X_NR (2)
-/*********************************************************************************************************
- AIC3X Codec 类型定义
-*********************************************************************************************************/
-typedef struct {
- PLW_I2C_DEVICE AIC3X_pI2cDevice;
-} __AIC31_CODEC, *__PAIC31_CODEC;
-
-static __AIC31_CODEC _G_aic3xCodecs[__AIC3X_NR];
-/*********************************************************************************************************
- Register Address for AIC31 Codec
-*********************************************************************************************************/
-#define AIC31_P0_REG0 (0) /* Page Select */
-#define AIC31_P0_REG1 (1) /* Software Reset */
-#define AIC31_P0_REG2 (2) /* Codec Sample Rate Select */
-#define AIC31_P0_REG3 (3) /* PLL Programming A */
-#define AIC31_P0_REG4 (4) /* PLL Programming B */
-#define AIC31_P0_REG5 (5) /* PLL Programming C */
-#define AIC31_P0_REG6 (6) /* PLL Programming D */
-#define AIC31_P0_REG7 (7) /* Codec Datapath Setup */
-#define AIC31_P0_REG8 (8) /* Audio Serial Data I/f Control A */
-#define AIC31_P0_REG9 (9) /* Audio Serial Data I/f Control B */
-#define AIC31_P0_REG10 (10) /* Audio Serial Data I/f Control C */
-#define AIC31_P0_REG11 (11) /* Audio Codec Overflow Flag */
-#define AIC31_P0_REG12 (12) /* Audio Codec Digital Filter Ctrl */
-#define AIC31_P0_REG13 (13) /* Headset / Button Press Detect A */
-#define AIC31_P0_REG14 (14) /* Headset / Button Press Detect B */
-#define AIC31_P0_REG15 (15) /* Left ADC PGA Gain Control */
-#define AIC31_P0_REG16 (16) /* Right ADC PGA Gain Control */
-#define AIC31_P0_REG17 (17) /* MIC3L/R to Left ADC Control */
-#define AIC31_P0_REG18 (18) /* MIC3L/R to Right ADC Control */
-#define AIC31_P0_REG19 (19) /* LINE1L to Left ADC Control */
-#define AIC31_P0_REG20 (20) /* LINE2L to Left ADC Control */
-#define AIC31_P0_REG21 (21) /* LINE1R to Left ADC Control */
-#define AIC31_P0_REG22 (22) /* LINE1R to Right ADC Control */
-#define AIC31_P0_REG23 (23) /* LINE2R to Right ADC Control */
-#define AIC31_P0_REG24 (24) /* LINE1L to Right ADC Control */
-#define AIC31_P0_REG25 (25) /* MICBIAS Control */
-#define AIC31_P0_REG26 (26) /* Left AGC Control A */
-#define AIC31_P0_REG27 (27) /* Left AGC Control B */
-#define AIC31_P0_REG28 (28) /* Left AGC Control C */
-#define AIC31_P0_REG29 (29) /* Right AGC Control A */
-#define AIC31_P0_REG30 (30) /* Right AGC Control B */
-#define AIC31_P0_REG31 (31) /* Right AGC Control C */
-#define AIC31_P0_REG32 (32) /* Left AGC Gain */
-#define AIC31_P0_REG33 (33) /* Right AGC Gain */
-#define AIC31_P0_REG34 (34) /* Left AGC Noise Gate Debounce */
-#define AIC31_P0_REG35 (35) /* Right AGC Noise Gate Debounce */
-#define AIC31_P0_REG36 (36) /* ADC Flag */
-#define AIC31_P0_REG37 (37) /* DAC Power and Output Driver Control */
-#define AIC31_P0_REG38 (38) /* High Power Output Driver Control*/
-#define AIC31_P0_REG40 (40) /* High Power Output Stage Control*/
-#define AIC31_P0_REG41 (41) /* DAC Output Switching Control */
-#define AIC31_P0_REG42 (42) /* Output Driver Pop Reduction */
-#define AIC31_P0_REG43 (43) /* Left DAC Digital Volume Control */
-#define AIC31_P0_REG44 (44) /* Right DAC Digital Volume Control */
-#define AIC31_P0_REG45 (45) /* LINE2L to HPLOUT Volume Control */
-#define AIC31_P0_REG46 (46) /* PGA_L to HPLOUT Volume Control */
-#define AIC31_P0_REG47 (47) /* DAC_L1 to HPLOUT Volume Control */
-#define AIC31_P0_REG48 (48) /* LINE2R to HPLOUT Volume Control */
-#define AIC31_P0_REG49 (49) /* PGA_R to HPLOUT Volume Control */
-#define AIC31_P0_REG50 (50) /* DAC_R1 to HPLOUT Volume Control */
-#define AIC31_P0_REG51 (51) /* HPLOUT Output Level Control */
-#define AIC31_P0_REG52 (52) /* LINE2L to HPLCOM Volume Control */
-#define AIC31_P0_REG53 (53) /* PGA_L to HPLCOM Volume Control */
-#define AIC31_P0_REG54 (54) /* DAC_L1 to HPLCOM Volume Control */
-#define AIC31_P0_REG55 (55) /* LINE2R to HPLCOM Volume Control */
-#define AIC31_P0_REG56 (56) /* PGA_R to HPLCOM Volume Control */
-#define AIC31_P0_REG57 (57) /* DAC_R1 to HPLCOM Volume Control */
-#define AIC31_P0_REG58 (58) /* HPLCOM Output Level Control */
-#define AIC31_P0_REG59 (59) /* LINE2L to HPROUT Volume Control */
-#define AIC31_P0_REG60 (60) /* PGA_L to HPROUT Volume Control */
-#define AIC31_P0_REG61 (61) /* DAC_L1 to HPROUT Volume Control */
-#define AIC31_P0_REG62 (62) /* LINE2R to HPROUT Volume Control */
-#define AIC31_P0_REG63 (63) /* PGA_R to HPROUT Volume Control */
-#define AIC31_P0_REG64 (64) /* DAC_R1 to HPROUT Volume Control */
-#define AIC31_P0_REG65 (65) /* HPROUT Output Level Control */
-#define AIC31_P0_REG66 (66) /* LINE2L to HPRCOM Volume Control */
-#define AIC31_P0_REG67 (67) /* PGA_L to HPRCOM Volume Control */
-#define AIC31_P0_REG68 (68) /* DAC_L1 to HPRCOM Volume Control */
-#define AIC31_P0_REG69 (69) /* LINE2R to HPRCOM Volume Control */
-#define AIC31_P0_REG70 (70) /* PGA_R to HPRCOM Volume Control */
-#define AIC31_P0_REG71 (71) /* DAC_R1 to HPRCOM Volume Control */
-#define AIC31_P0_REG72 (72) /* HPRCOM Output Level Control */
-#define AIC31_P0_REG73 (73) /* LINE2L to MONO_LOP/M Volume Control*/
-#define AIC31_P0_REG74 (74) /* PGA_L to MONO_LOP/M Volume Control */
-#define AIC31_P0_REG75 (75) /* DAC_L1 to MONO_LOP/M Volume Control */
-#define AIC31_P0_REG76 (76) /* LINE2R to MONO_LOP/M Volume Control */
-#define AIC31_P0_REG77 (77) /* PGA_R to MONO_LOP/M Volume Control */
-#define AIC31_P0_REG78 (78) /* DAC_R1 to MONO_LOP/M Volume Control */
-#define AIC31_P0_REG79 (79) /* MONO_LOP/M Output Level Control */
-#define AIC31_P0_REG80 (80) /* LINE2L to LEFT_LOP/M Volume Control */
-#define AIC31_P0_REG81 (81) /* PGA_L to LEFT_LOP/M Volume Control */
-#define AIC31_P0_REG82 (82) /* DAC_L1 to LEFT_LOP/M Volume Control */
-#define AIC31_P0_REG83 (83) /* LINE2R to LEFT_LOP/M Volume Control */
-#define AIC31_P0_REG84 (84) /* PGA_R to LEFT_LOP/M Volume Control */
-#define AIC31_P0_REG85 (85) /* DAC_R1 to LEFT_LOP/M Volume Control */
-#define AIC31_P0_REG86 (86) /* LEFT_LOP/M Output Level Control */
-#define AIC31_P0_REG87 (87) /* LINE2L to RIGHT_LOP/M Volume Control */
-#define AIC31_P0_REG88 (88) /* PGA_L to RIGHT_LOP/M Volume Control */
-#define AIC31_P0_REG89 (89) /* DAC_L1 to RIGHT_LOP/M Volume Control */
-#define AIC31_P0_REG90 (90) /* LINE2R to RIGHT_LOP/M Volume Control */
-#define AIC31_P0_REG91 (91) /* PGA_R to RIGHT_LOP/M Volume Control */
-#define AIC31_P0_REG92 (92) /* DAC_R1 to RIGHT_LOP/M Volume Control*/
-#define AIC31_P0_REG93 (93) /* RIGHT_LOP/M Output Level Control */
-#define AIC31_P0_REG94 (94) /* Module Power Status */
-#define AIC31_P0_REG95 (95) /**< O/P Driver Short Circuit Detection Status*/
-#define AIC31_P0_REG96 (96) /* Sticky Interrupt Flags */
-#define AIC31_P0_REG97 (97) /* Real-time Interrupt Flags */
-#define AIC31_P0_REG98 (98) /* GPIO1 Control */
-#define AIC31_P0_REG99 (99) /* GPIO2 Control */
-#define AIC31_P0_REG100 (100) /* Additional GPIO Control A */
-#define AIC31_P0_REG101 (101) /* Additional GPIO Control B */
-#define AIC31_P0_REG102 (102) /* Clock Generation Control */
-
-#define AIC31_RESET (0x80)
-
-#define AIC31_SLOT_WIDTH_16 (0u << 4u)
-#define AIC31_SLOT_WIDTH_20 (1u << 4u)
-#define AIC31_SLOT_WIDTH_24 (2u << 4u)
-#define AIC31_SLOT_WIDTH_32 (3u << 4u)
-/*********************************************************************************************************
- Macros for the dataType variable to pass to __aic3xDataConfig function
-*********************************************************************************************************/
-#define AIC31_DATATYPE_I2S (0u << 6u) /* I2S Mode */
-#define AIC31_DATATYPE_DSP (1u << 6u) /* DSP Mode */
-#define AIC31_DATATYPE_RIGHTJ (2u << 6u) /* Right Aligned Mode */
-#define AIC31_DATATYPE_LEFTJ (3u << 6u) /* Left Aligned Mode */
-/*********************************************************************************************************
- Macros for the mode variable for the __aic3xSampleRateConfig function
-*********************************************************************************************************/
-#define AIC31_MODE_ADC (0xF0u)
-#define AIC31_MODE_DAC (0x0Fu)
-#define AIC31_MODE_BOTH (0xFFu)
-/*********************************************************************************************************
-** 函数名称: __aic3xCodecRegRead
-** 功能描述: 读 AIC3X 寄存器
-** 输 入 : pI2cDev i2c 设备
-** ucRegAddr 寄存器地址
-** 输 出 : 寄存器值
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-#if 0
-static UINT8 __aic3xCodecRegRead (PLW_I2C_DEVICE pI2cDev,
- UINT8 ucRegAddr)
-{
- CHAR acBuffer[2];
-
- acBuffer[0] = ucRegAddr;
-
- API_I2cDeviceMasterSend(pI2cDev, &acBuffer[0], 1);
-
- API_I2cDeviceMasterRecv(pI2cDev, &acBuffer[1], 1);
-
- return (acBuffer[1]);
-}
-#endif
-/*********************************************************************************************************
-** 函数名称: __aic3xCodecRegWrite
-** 功能描述: 写 AIC3X 寄存器
-** 输 入 : pI2cDev i2c 设备
-** ucRegAddr 寄存器地址
-** uiValue 值
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __aic3xCodecRegWrite (PLW_I2C_DEVICE pI2cDev,
- UINT8 ucRegAddr,
- UINT8 uiValue)
-{
- CHAR acBuffer[2];
-
- acBuffer[0] = ucRegAddr;
- acBuffer[1] = uiValue;
-
- API_I2cDeviceMasterSend(pI2cDev, acBuffer, 2);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3xCodecRegBitSet
-** 功能描述: 设置 AIC3X 寄存器位
-** 输 入 : pI2cDev i2c 设备
-** ucRegAddr 寄存器地址
-** ucBitMask 位掩码
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-#if 0
-static VOID __aic3xCodecRegBitSet (PLW_I2C_DEVICE pI2cDev,
- UINT8 ucRegAddr,
- UINT8 ucBitMask)
-{
- CHAR acBuffer[2];
-
- acBuffer[0] = ucRegAddr;
-
- API_I2cDeviceMasterSend(pI2cDev, &acBuffer[0], 1);
-
- API_I2cDeviceMasterRecv(pI2cDev, &acBuffer[1], 1);
-
- acBuffer[0] = ucRegAddr;
- acBuffer[1] |= ucBitMask;
- API_I2cDeviceMasterSend(pI2cDev, acBuffer, 2);
-}
-#endif
-/*********************************************************************************************************
-** 函数名称: __aic3xCodecRegBitClr
-** 功能描述: 清除 AIC3X 寄存器位
-** 输 入 : pI2cDev i2c 设备
-** ucRegAddr 寄存器地址
-** ucBitMask 位掩码
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __aic3xCodecRegBitClr (PLW_I2C_DEVICE pI2cDev,
- UINT8 ucRegAddr,
- UINT8 ucBitMask)
-{
- CHAR acBuffer[2];
-
- acBuffer[0] = ucRegAddr;
-
- API_I2cDeviceMasterSend(pI2cDev, &acBuffer[0], 1);
-
- API_I2cDeviceMasterRecv(pI2cDev, &acBuffer[1], 1);
-
- acBuffer[0] = ucRegAddr;
- acBuffer[1] &= ~ucBitMask;
- API_I2cDeviceMasterSend(pI2cDev, acBuffer, 2);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3xReset
-** 功能描述: 复位 AIC3X
-** 输 入 : pI2cDev i2c 设备
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __aic3xReset (PLW_I2C_DEVICE pI2cDev)
-{
- /* Select Page 0 */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG0, 0);
-
- /* Reset the codec */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG1, AIC31_RESET);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3xADCInit
-** 功能描述: AIC3X ADC 初始化
-** 输 入 : pI2cDev i2c 设备
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __aic3xADCInit (PLW_I2C_DEVICE pI2cDev)
-{
- /* enable the programmable PGA for left and right ADC */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG15, 0x00);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG16, 0x00);
-
- /* MIC3L/R is not connected to the left ADC PGA */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG17, 0xFF);
-
- /* MIC3L/R is not connected to the right ADC PGA */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG18, 0xFF);
-
- /* power on the Line L1R */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG19, 0x04);
-
- /* power on the Line LIL */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG22, 0x04);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3xDACInit
-** 功能描述: AIC3X DAC 初始化
-** 输 入 : pI2cDev i2c 设备
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __aic3xDACInit (PLW_I2C_DEVICE pI2cDev)
-{
- /* power up the left and right DACs */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG37, 0xE0);
-
- /* select the DAC L1 R1 Paths */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG41, 0x02);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG42, 0x6C);
-
-
- /* DAC L to HPLOUT Is connected */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG47, 0x80);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG51, 0x09);
-
- /* DAC R to HPROUT is connected */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG64, 0x80);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG65, 0x09);
-
- /* DACL1 connected to LINE1 LOUT */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG82, 0x80);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG86, 0x09);
-
- /* DACR1 connected to LINE1 ROUT */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG92, 0x80);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG93, 0x09);
-
- /* unmute the DAC */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG43, 0x00);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG44, 0x00);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3xDataConfig
-** 功能描述: AIC3X 数据类型配置
-** 输 入 : pI2cDev i2c 设备
-** ucDataType 数据类型
-** ucSlotWidth SLOT 宽度
-** ucDataOff
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __aic3xDataConfig (PLW_I2C_DEVICE pI2cDev,
- UINT8 ucDataType,
- UINT8 ucSlotWidth,
- UINT8 ucDataOff)
-{
- UINT8 uiSlot;
-
- switch (ucSlotWidth) {
- case 16:
- uiSlot = AIC31_SLOT_WIDTH_16;
- break;
-
- case 20:
- uiSlot = AIC31_SLOT_WIDTH_20;
- break;
-
- case 24:
- uiSlot = AIC31_SLOT_WIDTH_24;
- break;
-
- case 32:
- uiSlot = AIC31_SLOT_WIDTH_32;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- /* Write the data type and slot width */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG9, (ucDataType | uiSlot));
-
- /* valid data after dataOff number of clock cycles */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG10, ucDataOff);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3xSampleRateConfig
-** 功能描述: AIC3X 采样率配置
-** 输 入 : pI2cDev i2c 设备
-** uiMode 模式
-** uiSampleRate 采样率
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __aic3xSampleRateConfig (PLW_I2C_DEVICE pI2cDev,
- UINT uiMode,
- UINT uiSampleRate)
-{
- UINT8 fs;
- UINT8 ref = 0x0Au;
- UINT8 temp;
- UINT8 pllPval = 1u;
- UINT8 pllRval = 1u;
- UINT8 pllJval = 8u;
- UINT16 pllDval = 1920u;
-
- /* Select the configuration for the given sampling rate */
- switch (uiSampleRate) {
- case 8000:
- fs = 0xAAu;
- break;
-
- case 11025:
- fs = 0x66u;
- ref = 0x8Au;
- pllJval = 7u;
- pllDval = 5264u;
- break;
-
- case 16000:
- fs = 0x44u;
- break;
-
- case 22050:
- fs = 0x22u;
- ref = 0x8Au;
- pllJval = 7u;
- pllDval = 5264u;
- break;
-
- case 24000:
- fs = 0x22u;
- break;
-
- case 32000:
- fs = 0x11u;
- break;
-
- case 44100:
- ref = 0x8Au;
- fs = 0x00u;
- pllJval = 7u;
- pllDval = 5264u;
- break;
-
- case 48000:
- fs = 0x00u;
- break;
-
- case 96000:
- ref = 0x6Au;
- fs = 0x00u;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- temp = (uiMode & fs);
-
- /* Set the sample Rate */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG2, temp);
-
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG3, 0x80 | pllPval);
-
- /* use PLL_CLK_IN as MCLK */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG102, 0x08);
-
- /* Use PLL DIV OUT as codec CLK IN */
- __aic3xCodecRegBitClr(pI2cDev, AIC31_P0_REG101, 0x01);
-
- /* Select GPIO to output the divided PLL IN */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG98, 0x20);
-
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG4, pllJval << 2);
-
- /* Configure the PLL divide registers */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG5, (pllDval >> 6) & 0xFF);
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG6, (pllDval & 0x3F) << 2);
-
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG11, pllRval);
-
- /* Enable the codec to be master for fs and bclk */
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG8, 0xD0);
-
- __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG7, ref);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3x0MasterCtl
-** 功能描述: AIC3X 控制函数
-** 输 入 : pI2cAdapter i2c 适配器
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __aic3xMasterCtl (__PAIC31_CODEC pAic31xCodec,
- INT iCmd,
- LONG lArg)
-{
- __PAUDIO_CODEC_PARAM pCodceParam = (__PAUDIO_CODEC_PARAM)lArg;
- INT *pIntData = (INT *)lArg;
- UINT uiDataSize;
-
- switch (iCmd) {
- case __AUDIO_CODEC_OPEN:
- __aic3xReset(pAic31xCodec->AIC3X_pI2cDevice);
- API_TimeMSleep(100);
-
- if (pCodceParam->PARAM_iSampleFmt == AFMT_S16_LE) {
- uiDataSize = 16;
- } else if (pCodceParam->PARAM_iSampleFmt == AFMT_U8) {
- uiDataSize = 8;
- } else {
- pCodceParam->PARAM_iSampleFmt = AFMT_S16_LE;
- uiDataSize = 16;
- }
-
- /* Configure the data format and sampling rate */
- if (__aic3xDataConfig(pAic31xCodec->AIC3X_pI2cDevice,
- AIC31_DATATYPE_I2S, uiDataSize, 0) != ERROR_NONE) {
- _ErrorHandle(EIO);
- return (PX_ERROR);
- }
-
- if (__aic3xSampleRateConfig(pAic31xCodec->AIC3X_pI2cDevice,
- AIC31_MODE_BOTH, pCodceParam->PARAM_iSampleRate) != ERROR_NONE) {
- _ErrorHandle(EINVAL);
- return (PX_ERROR);
- }
-
- /* Initialize both ADC and DAC */
- __aic3xADCInit(pAic31xCodec->AIC3X_pI2cDevice);
-
- __aic3xDACInit(pAic31xCodec->AIC3X_pI2cDevice);
-
- pCodceParam->PARAM_iSampleFmts = AFMT_S16_LE | AFMT_U8;
- pCodceParam->PARAM_iChannels = 2;
- break;
-
- case __AUDIO_CODEC_CLOSE:
- break;
-
- case __AUDIO_CODEC_SETFMT:
- if (*pIntData == AFMT_S16_LE) {
- uiDataSize = 16;
- } else if (*pIntData == AFMT_U8) {
- uiDataSize = 8;
- } else {
- _ErrorHandle(EINVAL);
- return (PX_ERROR);
- }
-
- if (__aic3xDataConfig(pAic31xCodec->AIC3X_pI2cDevice,
- AIC31_DATATYPE_I2S, uiDataSize, 0) != ERROR_NONE) {
- _ErrorHandle(EIO);
- return (PX_ERROR);
- }
- break;
-
- case __AUDIO_CODEC_CHANNELS:
- if (*pIntData != 2) {
- _ErrorHandle(EINVAL);
- return (PX_ERROR);
- }
- break;
-
- case __AUDIO_CODEC_SPEED:
- if (__aic3xSampleRateConfig(pAic31xCodec->AIC3X_pI2cDevice,
- AIC31_MODE_BOTH, *pIntData) != ERROR_NONE) {
- _ErrorHandle(EINVAL);
- return (PX_ERROR);
- }
- break;
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __aic3x0MasterCtl
-** 功能描述: AIC3X 控制函数
-** 输 入 : pI2cAdapter i2c 适配器
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __aic3x0MasterCtl (PLW_I2C_ADAPTER pI2cAdapter,
- INT iCmd,
- LONG lArg)
-{
- return (__aic3xMasterCtl(&_G_aic3xCodecs[0], iCmd, lArg));
-}
-/*********************************************************************************************************
-** 函数名称: __aic3x1MasterCtl
-** 功能描述: AIC3X 控制函数
-** 输 入 : pI2cAdapter i2c 适配器
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __aic3x1MasterCtl (PLW_I2C_ADAPTER pI2cAdapter,
- INT iCmd,
- LONG lArg)
-{
- return (__aic3xMasterCtl(&_G_aic3xCodecs[1], iCmd, lArg));
-}
-/*********************************************************************************************************
- AIC3X 总线驱动程序
-*********************************************************************************************************/
-static LW_I2C_FUNCS _G_aic3xI2cFuncs[__AIC3X_NR] = {
- {
- LW_NULL,
- __aic3x0MasterCtl,
- },
- {
- LW_NULL,
- __aic3x1MasterCtl,
- }
-};
-/*********************************************************************************************************
-** 函数名称: aic3xBusFuns
-** 功能描述: 初始化 AIC3X 总线并获取驱动程序
-** 输 入 : uiChannel 通道号
-** pcI2cBusName i2c 总线名
-** usAddr AIC3X i2c 从机地址
-** 输 出 : AIC3X 总线驱动程序
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-PLW_I2C_FUNCS aic3xBusFuns (UINT uiChannel, CPCHAR pcI2cBusName, UINT16 usAddr)
-{
- __PAIC31_CODEC pAic31xCodec;
-
- if (uiChannel >= __AIC3X_NR) {
- printk(KERN_ERR "aic3xBusFuns(): AIC31X channel invalid!\n");
- return (LW_NULL);
- }
-
- pAic31xCodec = &_G_aic3xCodecs[uiChannel];
-
- pAic31xCodec->AIC3X_pI2cDevice = API_I2cDeviceCreate(pcI2cBusName,
- "/dev/dsp",
- usAddr,
- 0);
- if (pAic31xCodec->AIC3X_pI2cDevice == LW_NULL) {
- printk(KERN_ERR "aic3xBusFuns(): failed to create i2c device %s.\n", pcI2cBusName);
- return (LW_NULL);
- }
-
- return (&_G_aic3xI2cFuncs[uiChannel]);
-}
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: tlv320aic3x.c
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 22 日
+**
+** 描 述: TI tlv320aic3x 音频芯片驱动
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "SylixOS.h"
+#include "system/device/sound/soundcard.h"
+
+#include "driver/audio/codec/codecDrv.h"
+/*********************************************************************************************************
+ 定义
+*********************************************************************************************************/
+#define __AIC3X_NR (2)
+/*********************************************************************************************************
+ AIC3X Codec 类型定义
+*********************************************************************************************************/
+typedef struct {
+ PLW_I2C_DEVICE AIC3X_pI2cDevice;
+} __AIC31_CODEC, *__PAIC31_CODEC;
+
+static __AIC31_CODEC _G_aic3xCodecs[__AIC3X_NR];
+/*********************************************************************************************************
+ Register Address for AIC31 Codec
+*********************************************************************************************************/
+#define AIC31_P0_REG0 (0) /* Page Select */
+#define AIC31_P0_REG1 (1) /* Software Reset */
+#define AIC31_P0_REG2 (2) /* Codec Sample Rate Select */
+#define AIC31_P0_REG3 (3) /* PLL Programming A */
+#define AIC31_P0_REG4 (4) /* PLL Programming B */
+#define AIC31_P0_REG5 (5) /* PLL Programming C */
+#define AIC31_P0_REG6 (6) /* PLL Programming D */
+#define AIC31_P0_REG7 (7) /* Codec Datapath Setup */
+#define AIC31_P0_REG8 (8) /* Audio Serial Data I/f Control A */
+#define AIC31_P0_REG9 (9) /* Audio Serial Data I/f Control B */
+#define AIC31_P0_REG10 (10) /* Audio Serial Data I/f Control C */
+#define AIC31_P0_REG11 (11) /* Audio Codec Overflow Flag */
+#define AIC31_P0_REG12 (12) /* Audio Codec Digital Filter Ctrl */
+#define AIC31_P0_REG13 (13) /* Headset / Button Press Detect A */
+#define AIC31_P0_REG14 (14) /* Headset / Button Press Detect B */
+#define AIC31_P0_REG15 (15) /* Left ADC PGA Gain Control */
+#define AIC31_P0_REG16 (16) /* Right ADC PGA Gain Control */
+#define AIC31_P0_REG17 (17) /* MIC3L/R to Left ADC Control */
+#define AIC31_P0_REG18 (18) /* MIC3L/R to Right ADC Control */
+#define AIC31_P0_REG19 (19) /* LINE1L to Left ADC Control */
+#define AIC31_P0_REG20 (20) /* LINE2L to Left ADC Control */
+#define AIC31_P0_REG21 (21) /* LINE1R to Left ADC Control */
+#define AIC31_P0_REG22 (22) /* LINE1R to Right ADC Control */
+#define AIC31_P0_REG23 (23) /* LINE2R to Right ADC Control */
+#define AIC31_P0_REG24 (24) /* LINE1L to Right ADC Control */
+#define AIC31_P0_REG25 (25) /* MICBIAS Control */
+#define AIC31_P0_REG26 (26) /* Left AGC Control A */
+#define AIC31_P0_REG27 (27) /* Left AGC Control B */
+#define AIC31_P0_REG28 (28) /* Left AGC Control C */
+#define AIC31_P0_REG29 (29) /* Right AGC Control A */
+#define AIC31_P0_REG30 (30) /* Right AGC Control B */
+#define AIC31_P0_REG31 (31) /* Right AGC Control C */
+#define AIC31_P0_REG32 (32) /* Left AGC Gain */
+#define AIC31_P0_REG33 (33) /* Right AGC Gain */
+#define AIC31_P0_REG34 (34) /* Left AGC Noise Gate Debounce */
+#define AIC31_P0_REG35 (35) /* Right AGC Noise Gate Debounce */
+#define AIC31_P0_REG36 (36) /* ADC Flag */
+#define AIC31_P0_REG37 (37) /* DAC Power and Output Driver Control */
+#define AIC31_P0_REG38 (38) /* High Power Output Driver Control*/
+#define AIC31_P0_REG40 (40) /* High Power Output Stage Control*/
+#define AIC31_P0_REG41 (41) /* DAC Output Switching Control */
+#define AIC31_P0_REG42 (42) /* Output Driver Pop Reduction */
+#define AIC31_P0_REG43 (43) /* Left DAC Digital Volume Control */
+#define AIC31_P0_REG44 (44) /* Right DAC Digital Volume Control */
+#define AIC31_P0_REG45 (45) /* LINE2L to HPLOUT Volume Control */
+#define AIC31_P0_REG46 (46) /* PGA_L to HPLOUT Volume Control */
+#define AIC31_P0_REG47 (47) /* DAC_L1 to HPLOUT Volume Control */
+#define AIC31_P0_REG48 (48) /* LINE2R to HPLOUT Volume Control */
+#define AIC31_P0_REG49 (49) /* PGA_R to HPLOUT Volume Control */
+#define AIC31_P0_REG50 (50) /* DAC_R1 to HPLOUT Volume Control */
+#define AIC31_P0_REG51 (51) /* HPLOUT Output Level Control */
+#define AIC31_P0_REG52 (52) /* LINE2L to HPLCOM Volume Control */
+#define AIC31_P0_REG53 (53) /* PGA_L to HPLCOM Volume Control */
+#define AIC31_P0_REG54 (54) /* DAC_L1 to HPLCOM Volume Control */
+#define AIC31_P0_REG55 (55) /* LINE2R to HPLCOM Volume Control */
+#define AIC31_P0_REG56 (56) /* PGA_R to HPLCOM Volume Control */
+#define AIC31_P0_REG57 (57) /* DAC_R1 to HPLCOM Volume Control */
+#define AIC31_P0_REG58 (58) /* HPLCOM Output Level Control */
+#define AIC31_P0_REG59 (59) /* LINE2L to HPROUT Volume Control */
+#define AIC31_P0_REG60 (60) /* PGA_L to HPROUT Volume Control */
+#define AIC31_P0_REG61 (61) /* DAC_L1 to HPROUT Volume Control */
+#define AIC31_P0_REG62 (62) /* LINE2R to HPROUT Volume Control */
+#define AIC31_P0_REG63 (63) /* PGA_R to HPROUT Volume Control */
+#define AIC31_P0_REG64 (64) /* DAC_R1 to HPROUT Volume Control */
+#define AIC31_P0_REG65 (65) /* HPROUT Output Level Control */
+#define AIC31_P0_REG66 (66) /* LINE2L to HPRCOM Volume Control */
+#define AIC31_P0_REG67 (67) /* PGA_L to HPRCOM Volume Control */
+#define AIC31_P0_REG68 (68) /* DAC_L1 to HPRCOM Volume Control */
+#define AIC31_P0_REG69 (69) /* LINE2R to HPRCOM Volume Control */
+#define AIC31_P0_REG70 (70) /* PGA_R to HPRCOM Volume Control */
+#define AIC31_P0_REG71 (71) /* DAC_R1 to HPRCOM Volume Control */
+#define AIC31_P0_REG72 (72) /* HPRCOM Output Level Control */
+#define AIC31_P0_REG73 (73) /* LINE2L to MONO_LOP/M Volume Control*/
+#define AIC31_P0_REG74 (74) /* PGA_L to MONO_LOP/M Volume Control */
+#define AIC31_P0_REG75 (75) /* DAC_L1 to MONO_LOP/M Volume Control */
+#define AIC31_P0_REG76 (76) /* LINE2R to MONO_LOP/M Volume Control */
+#define AIC31_P0_REG77 (77) /* PGA_R to MONO_LOP/M Volume Control */
+#define AIC31_P0_REG78 (78) /* DAC_R1 to MONO_LOP/M Volume Control */
+#define AIC31_P0_REG79 (79) /* MONO_LOP/M Output Level Control */
+#define AIC31_P0_REG80 (80) /* LINE2L to LEFT_LOP/M Volume Control */
+#define AIC31_P0_REG81 (81) /* PGA_L to LEFT_LOP/M Volume Control */
+#define AIC31_P0_REG82 (82) /* DAC_L1 to LEFT_LOP/M Volume Control */
+#define AIC31_P0_REG83 (83) /* LINE2R to LEFT_LOP/M Volume Control */
+#define AIC31_P0_REG84 (84) /* PGA_R to LEFT_LOP/M Volume Control */
+#define AIC31_P0_REG85 (85) /* DAC_R1 to LEFT_LOP/M Volume Control */
+#define AIC31_P0_REG86 (86) /* LEFT_LOP/M Output Level Control */
+#define AIC31_P0_REG87 (87) /* LINE2L to RIGHT_LOP/M Volume Control */
+#define AIC31_P0_REG88 (88) /* PGA_L to RIGHT_LOP/M Volume Control */
+#define AIC31_P0_REG89 (89) /* DAC_L1 to RIGHT_LOP/M Volume Control */
+#define AIC31_P0_REG90 (90) /* LINE2R to RIGHT_LOP/M Volume Control */
+#define AIC31_P0_REG91 (91) /* PGA_R to RIGHT_LOP/M Volume Control */
+#define AIC31_P0_REG92 (92) /* DAC_R1 to RIGHT_LOP/M Volume Control*/
+#define AIC31_P0_REG93 (93) /* RIGHT_LOP/M Output Level Control */
+#define AIC31_P0_REG94 (94) /* Module Power Status */
+#define AIC31_P0_REG95 (95) /**< O/P Driver Short Circuit Detection Status*/
+#define AIC31_P0_REG96 (96) /* Sticky Interrupt Flags */
+#define AIC31_P0_REG97 (97) /* Real-time Interrupt Flags */
+#define AIC31_P0_REG98 (98) /* GPIO1 Control */
+#define AIC31_P0_REG99 (99) /* GPIO2 Control */
+#define AIC31_P0_REG100 (100) /* Additional GPIO Control A */
+#define AIC31_P0_REG101 (101) /* Additional GPIO Control B */
+#define AIC31_P0_REG102 (102) /* Clock Generation Control */
+
+#define AIC31_RESET (0x80)
+
+#define AIC31_SLOT_WIDTH_16 (0u << 4u)
+#define AIC31_SLOT_WIDTH_20 (1u << 4u)
+#define AIC31_SLOT_WIDTH_24 (2u << 4u)
+#define AIC31_SLOT_WIDTH_32 (3u << 4u)
+/*********************************************************************************************************
+ Macros for the dataType variable to pass to __aic3xDataConfig function
+*********************************************************************************************************/
+#define AIC31_DATATYPE_I2S (0u << 6u) /* I2S Mode */
+#define AIC31_DATATYPE_DSP (1u << 6u) /* DSP Mode */
+#define AIC31_DATATYPE_RIGHTJ (2u << 6u) /* Right Aligned Mode */
+#define AIC31_DATATYPE_LEFTJ (3u << 6u) /* Left Aligned Mode */
+/*********************************************************************************************************
+ Macros for the mode variable for the __aic3xSampleRateConfig function
+*********************************************************************************************************/
+#define AIC31_MODE_ADC (0xF0u)
+#define AIC31_MODE_DAC (0x0Fu)
+#define AIC31_MODE_BOTH (0xFFu)
+/*********************************************************************************************************
+** 函数名称: __aic3xCodecRegRead
+** 功能描述: 读 AIC3X 寄存器
+** 输 入 : pI2cDev i2c 设备
+** ucRegAddr 寄存器地址
+** 输 出 : 寄存器值
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+#if 0
+static UINT8 __aic3xCodecRegRead (PLW_I2C_DEVICE pI2cDev,
+ UINT8 ucRegAddr)
+{
+ CHAR acBuffer[2];
+
+ acBuffer[0] = ucRegAddr;
+
+ API_I2cDeviceMasterSend(pI2cDev, &acBuffer[0], 1);
+
+ API_I2cDeviceMasterRecv(pI2cDev, &acBuffer[1], 1);
+
+ return (acBuffer[1]);
+}
+#endif
+/*********************************************************************************************************
+** 函数名称: __aic3xCodecRegWrite
+** 功能描述: 写 AIC3X 寄存器
+** 输 入 : pI2cDev i2c 设备
+** ucRegAddr 寄存器地址
+** uiValue 值
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __aic3xCodecRegWrite (PLW_I2C_DEVICE pI2cDev,
+ UINT8 ucRegAddr,
+ UINT8 uiValue)
+{
+ CHAR acBuffer[2];
+
+ acBuffer[0] = ucRegAddr;
+ acBuffer[1] = uiValue;
+
+ API_I2cDeviceMasterSend(pI2cDev, acBuffer, 2);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3xCodecRegBitSet
+** 功能描述: 设置 AIC3X 寄存器位
+** 输 入 : pI2cDev i2c 设备
+** ucRegAddr 寄存器地址
+** ucBitMask 位掩码
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+#if 0
+static VOID __aic3xCodecRegBitSet (PLW_I2C_DEVICE pI2cDev,
+ UINT8 ucRegAddr,
+ UINT8 ucBitMask)
+{
+ CHAR acBuffer[2];
+
+ acBuffer[0] = ucRegAddr;
+
+ API_I2cDeviceMasterSend(pI2cDev, &acBuffer[0], 1);
+
+ API_I2cDeviceMasterRecv(pI2cDev, &acBuffer[1], 1);
+
+ acBuffer[0] = ucRegAddr;
+ acBuffer[1] |= ucBitMask;
+ API_I2cDeviceMasterSend(pI2cDev, acBuffer, 2);
+}
+#endif
+/*********************************************************************************************************
+** 函数名称: __aic3xCodecRegBitClr
+** 功能描述: 清除 AIC3X 寄存器位
+** 输 入 : pI2cDev i2c 设备
+** ucRegAddr 寄存器地址
+** ucBitMask 位掩码
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __aic3xCodecRegBitClr (PLW_I2C_DEVICE pI2cDev,
+ UINT8 ucRegAddr,
+ UINT8 ucBitMask)
+{
+ CHAR acBuffer[2];
+
+ acBuffer[0] = ucRegAddr;
+
+ API_I2cDeviceMasterSend(pI2cDev, &acBuffer[0], 1);
+
+ API_I2cDeviceMasterRecv(pI2cDev, &acBuffer[1], 1);
+
+ acBuffer[0] = ucRegAddr;
+ acBuffer[1] &= ~ucBitMask;
+ API_I2cDeviceMasterSend(pI2cDev, acBuffer, 2);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3xReset
+** 功能描述: 复位 AIC3X
+** 输 入 : pI2cDev i2c 设备
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __aic3xReset (PLW_I2C_DEVICE pI2cDev)
+{
+ /* Select Page 0 */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG0, 0);
+
+ /* Reset the codec */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG1, AIC31_RESET);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3xADCInit
+** 功能描述: AIC3X ADC 初始化
+** 输 入 : pI2cDev i2c 设备
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __aic3xADCInit (PLW_I2C_DEVICE pI2cDev)
+{
+ /* enable the programmable PGA for left and right ADC */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG15, 0x00);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG16, 0x00);
+
+ /* MIC3L/R is not connected to the left ADC PGA */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG17, 0xFF);
+
+ /* MIC3L/R is not connected to the right ADC PGA */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG18, 0xFF);
+
+ /* power on the Line L1R */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG19, 0x04);
+
+ /* power on the Line LIL */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG22, 0x04);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3xDACInit
+** 功能描述: AIC3X DAC 初始化
+** 输 入 : pI2cDev i2c 设备
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __aic3xDACInit (PLW_I2C_DEVICE pI2cDev)
+{
+ /* power up the left and right DACs */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG37, 0xE0);
+
+ /* select the DAC L1 R1 Paths */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG41, 0x02);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG42, 0x6C);
+
+ /* DAC L to HPLOUT Is connected */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG47, 0x80);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG51, 0x09);
+
+ /* DAC R to HPROUT is connected */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG64, 0x80);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG65, 0x09);
+
+ /* DACL1 connected to LINE1 LOUT */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG82, 0x80);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG86, 0x09);
+
+ /* DACR1 connected to LINE1 ROUT */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG92, 0x80);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG93, 0x09);
+
+ /* unmute the DAC */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG43, 0x00);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG44, 0x00);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3xDataConfig
+** 功能描述: AIC3X 数据类型配置
+** 输 入 : pI2cDev i2c 设备
+** ucDataType 数据类型
+** ucSlotWidth SLOT 宽度
+** ucDataOff
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __aic3xDataConfig (PLW_I2C_DEVICE pI2cDev,
+ UINT8 ucDataType,
+ UINT8 ucSlotWidth,
+ UINT8 ucDataOff)
+{
+ UINT8 uiSlot;
+
+ switch (ucSlotWidth) {
+ case 16:
+ uiSlot = AIC31_SLOT_WIDTH_16;
+ break;
+
+ case 20:
+ uiSlot = AIC31_SLOT_WIDTH_20;
+ break;
+
+ case 24:
+ uiSlot = AIC31_SLOT_WIDTH_24;
+ break;
+
+ case 32:
+ uiSlot = AIC31_SLOT_WIDTH_32;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ /* Write the data type and slot width */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG9, (ucDataType | uiSlot));
+
+ /* valid data after dataOff number of clock cycles */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG10, ucDataOff);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3xSampleRateConfig
+** 功能描述: AIC3X 采样率配置
+** 输 入 : pI2cDev i2c 设备
+** uiMode 模式
+** uiSampleRate 采样率
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __aic3xSampleRateConfig (PLW_I2C_DEVICE pI2cDev,
+ UINT uiMode,
+ UINT uiSampleRate)
+{
+ UINT8 fs;
+ UINT8 ref = 0x0Au;
+ UINT8 temp;
+ UINT8 pllPval = 1u;
+ UINT8 pllRval = 1u;
+ UINT8 pllJval = 8u;
+ UINT16 pllDval = 1920u;
+
+ /* Select the configuration for the given sampling rate */
+ switch (uiSampleRate / 2) {
+ case 8000:
+ fs = 0xAAu;
+ break;
+
+ case 11025:
+ fs = 0x66u;
+ ref = 0x8Au;
+ pllJval = 7u;
+ pllDval = 5264u;
+ break;
+
+ case 16000:
+ fs = 0x44u;
+ break;
+
+ case 22050:
+ fs = 0x22u;
+ ref = 0x8Au;
+ pllJval = 7u;
+ pllDval = 5264u;
+ break;
+
+ case 24000:
+ fs = 0x22u;
+ break;
+
+ case 32000:
+ fs = 0x11u;
+ break;
+
+ case 44100:
+ ref = 0x8Au;
+ fs = 0x00u;
+ pllJval = 7u;
+ pllDval = 5264u;
+ break;
+
+ case 48000:
+ fs = 0x00u;
+ break;
+
+ case 96000:
+ ref = 0x6Au;
+ fs = 0x00u;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ temp = (uiMode & fs);
+
+ /* Set the sample Rate */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG2, temp);
+
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG3, 0x80 | pllPval);
+
+ /* use PLL_CLK_IN as MCLK */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG102, 0x08);
+
+ /* Use PLL DIV OUT as codec CLK IN */
+ __aic3xCodecRegBitClr(pI2cDev, AIC31_P0_REG101, 0x01);
+
+ /* Select GPIO to output the divided PLL IN */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG98, 0x20);
+
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG4, pllJval << 2);
+
+ /* Configure the PLL divide registers */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG5, (pllDval >> 6) & 0xFF);
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG6, (pllDval & 0x3F) << 2);
+
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG11, pllRval);
+
+ /* Enable the codec to be master for fs and bclk */
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG8, 0xD0);
+
+ __aic3xCodecRegWrite(pI2cDev, AIC31_P0_REG7, ref);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3x0MasterCtl
+** 功能描述: AIC3X 控制函数
+** 输 入 : pI2cAdapter i2c 适配器
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __aic3xMasterCtl (__PAIC31_CODEC pAic31xCodec,
+ INT iCmd,
+ LONG lArg)
+{
+ __PAUDIO_CODEC_PARAM pCodceParam = (__PAUDIO_CODEC_PARAM)lArg;
+ INT *pIntData = (INT *)lArg;
+ UINT uiDataSize;
+
+ switch (iCmd) {
+ case __AUDIO_CODEC_OPEN:
+ __aic3xReset(pAic31xCodec->AIC3X_pI2cDevice);
+ API_TimeMSleep(100);
+
+ if (pCodceParam->PARAM_iSampleFmt == AFMT_S16_LE) {
+ uiDataSize = 16;
+ } else {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+
+ /* Configure the data format and sampling rate */
+ if (__aic3xDataConfig(pAic31xCodec->AIC3X_pI2cDevice,
+ AIC31_DATATYPE_I2S, uiDataSize, 0) != ERROR_NONE) {
+ _ErrorHandle(EIO);
+ return (PX_ERROR);
+ }
+
+ if (__aic3xSampleRateConfig(pAic31xCodec->AIC3X_pI2cDevice,
+ AIC31_MODE_BOTH, pCodceParam->PARAM_iSampleRate) != ERROR_NONE) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+
+ /* Initialize both ADC and DAC */
+ __aic3xADCInit(pAic31xCodec->AIC3X_pI2cDevice);
+
+ __aic3xDACInit(pAic31xCodec->AIC3X_pI2cDevice);
+
+ pCodceParam->PARAM_iSampleFmts = AFMT_S16_LE;
+ pCodceParam->PARAM_iChannels = 2;
+ break;
+
+ case __AUDIO_CODEC_CLOSE:
+ break;
+
+ case __AUDIO_CODEC_SETFMT:
+ if (*pIntData == AFMT_S16_LE) {
+ uiDataSize = 16;
+ } else {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+
+ if (__aic3xDataConfig(pAic31xCodec->AIC3X_pI2cDevice,
+ AIC31_DATATYPE_I2S, uiDataSize, 0) != ERROR_NONE) {
+ _ErrorHandle(EIO);
+ return (PX_ERROR);
+ }
+ break;
+
+ case __AUDIO_CODEC_CHANNELS:
+ if (*pIntData != 2) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+ break;
+
+ case __AUDIO_CODEC_SPEED:
+ if (__aic3xSampleRateConfig(pAic31xCodec->AIC3X_pI2cDevice,
+ AIC31_MODE_BOTH, *pIntData) != ERROR_NONE) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+ break;
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __aic3x0MasterCtl
+** 功能描述: AIC3X 控制函数
+** 输 入 : pI2cAdapter i2c 适配器
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __aic3x0MasterCtl (PLW_I2C_ADAPTER pI2cAdapter,
+ INT iCmd,
+ LONG lArg)
+{
+ return (__aic3xMasterCtl(&_G_aic3xCodecs[0], iCmd, lArg));
+}
+/*********************************************************************************************************
+** 函数名称: __aic3x1MasterCtl
+** 功能描述: AIC3X 控制函数
+** 输 入 : pI2cAdapter i2c 适配器
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __aic3x1MasterCtl (PLW_I2C_ADAPTER pI2cAdapter,
+ INT iCmd,
+ LONG lArg)
+{
+ return (__aic3xMasterCtl(&_G_aic3xCodecs[1], iCmd, lArg));
+}
+/*********************************************************************************************************
+ AIC3X 总线驱动程序
+*********************************************************************************************************/
+static LW_I2C_FUNCS _G_aic3xI2cFuncs[__AIC3X_NR] = {
+ {
+ LW_NULL,
+ __aic3x0MasterCtl,
+ },
+ {
+ LW_NULL,
+ __aic3x1MasterCtl,
+ }
+};
+/*********************************************************************************************************
+** 函数名称: aic3xBusFuns
+** 功能描述: 初始化 AIC3X 总线并获取驱动程序
+** 输 入 : uiChannel 通道号
+** pcI2cBusName i2c 总线名
+** usAddr AIC3X i2c 从机地址
+** 输 出 : AIC3X 总线驱动程序
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+PLW_I2C_FUNCS aic3xBusFuns (UINT uiChannel, CPCHAR pcI2cBusName, UINT16 usAddr)
+{
+ __PAIC31_CODEC pAic31xCodec;
+
+ if (uiChannel >= __AIC3X_NR) {
+ printk(KERN_ERR "aic3xBusFuns(): AIC31X channel invalid!\n");
+ return (LW_NULL);
+ }
+
+ pAic31xCodec = &_G_aic3xCodecs[uiChannel];
+
+ pAic31xCodec->AIC3X_pI2cDevice = API_I2cDeviceCreate(pcI2cBusName,
+ "/dev/dsp",
+ usAddr,
+ 0);
+ if (pAic31xCodec->AIC3X_pI2cDevice == LW_NULL) {
+ printk(KERN_ERR "aic3xBusFuns(): failed to create i2c device %s.\n", pcI2cBusName);
+ return (LW_NULL);
+ }
+
+ return (&_G_aic3xI2cFuncs[uiChannel]);
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.h b/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.h
index ae4c582..60efb74 100644
--- a/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.h
+++ b/SylixOS/driver/audio/codec/tlv320aic3x/tlv320aic3x.h
@@ -1,39 +1,39 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: tlv320aic3x.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 22 日
-**
-** 描 述: TI tlv320aic3x 音频芯片驱动
-*********************************************************************************************************/
-#ifndef TLV320AIC3X_H_
-#define TLV320AIC3X_H_
-
-/*********************************************************************************************************
-** 函数名称: aic3xBusFuns
-** 功能描述: 初始化 AIC3X 总线并获取驱动程序
-** 输 入 : uiChannel 通道号
-** pcI2cBusName i2c 总线名
-** usAddr AIC3X i2c 从机地址
-** 输 出 : AIC3X 总线驱动程序
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-PLW_I2C_FUNCS aic3xBusFuns(UINT uiChannel, CPCHAR pcI2cBusName, UINT16 usAddr);
-
-#endif /* TLV320AIC3X_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: tlv320aic3x.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 22 日
+**
+** 描 述: TI tlv320aic3x 音频芯片驱动
+*********************************************************************************************************/
+#ifndef TLV320AIC3X_H_
+#define TLV320AIC3X_H_
+
+/*********************************************************************************************************
+** 函数名称: aic3xBusFuns
+** 功能描述: 初始化 AIC3X 总线并获取驱动程序
+** 输 入 : uiChannel 通道号
+** pcI2cBusName i2c 总线名
+** usAddr AIC3X i2c 从机地址
+** 输 出 : AIC3X 总线驱动程序
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+PLW_I2C_FUNCS aic3xBusFuns(UINT uiChannel, CPCHAR pcI2cBusName, UINT16 usAddr);
+
+#endif /* TLV320AIC3X_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/audio/dsp/dspDrv.c b/SylixOS/driver/audio/dsp/dspDrv.c
index 4e51176..ac04c65 100644
--- a/SylixOS/driver/audio/dsp/dspDrv.c
+++ b/SylixOS/driver/audio/dsp/dspDrv.c
@@ -55,8 +55,8 @@ typedef struct __DSP_DEV_STRUCT {
LW_HANDLE DSP_hReadBlockSignal;
LW_HANDLE DSP_hWriteBlockSignal;
- LW_QUEUE DSP_queueRead;
- LW_QUEUE DSP_queueWrite;
+ LW_QUEUE DSP_readQueue;
+ LW_QUEUE DSP_writeQueue;
PUCHAR DSP_pucBlockBuffer;
PUCHAR DSP_pucReadBlockBuffer;
@@ -74,8 +74,8 @@ typedef struct __DSP_DEV_STRUCT {
BOOL DSP_bReadMmaped;
BOOL DSP_bWriteMmaped;
- LW_SPI_MESSAGE DSP_aReadSpiMsgs[__DSP_MAX_FRAGMENT_NUM];
- LW_SPI_MESSAGE DSP_aWriteSpiMsgs[__DSP_MAX_FRAGMENT_NUM];
+ LW_SPI_MESSAGE DSP_aReadMsgs[__DSP_MAX_FRAGMENT_NUM];
+ LW_SPI_MESSAGE DSP_aWriteMsgs[__DSP_MAX_FRAGMENT_NUM];
LW_SEL_WAKEUPLIST DSP_selList;
@@ -105,18 +105,18 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
INT iFlags,
INT iMode)
{
- PLW_FD_NODE pFdNode;
- BOOL bIsNew;
- __PDSP_DEV pDspDev = (__PDSP_DEV)pDev;
- UINT uiUseCount;
- LONGFUNCPTR pfuncDevOpen;
+ PLW_FD_NODE pFdNode;
+ BOOL bIsNew;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pDev;
+ UINT uiUseCount;
+ LONGFUNCPTR pfuncDevOpen;
if (pcName == LW_NULL) {
_ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);
return (PX_ERROR);
} else {
- pFdNode = API_IosFdNodeAdd(&pDspDev->DSP_fdNodeHeader,
+ pFdNode = API_IosFdNodeAdd(&pDspDev->DSP_fdNodeHeader, /* 创建 FD 文件节点 */
(dev_t)pDspDev, 0,
iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
if (pFdNode == LW_NULL) {
@@ -124,26 +124,27 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
return (PX_ERROR);
}
- iFlags = iFlags & O_ACCMODE;
+ iFlags = iFlags & O_ACCMODE; /* 获得访问模式 */
- uiUseCount = LW_DEV_INC_USE_COUNT(&pDspDev->DSP_devHdr);
+ uiUseCount = LW_DEV_INC_USE_COUNT(&pDspDev->DSP_devHdr); /* 增加打开计数 */
if (uiUseCount > 2) {
printk(KERN_ERR "__dspOpen(): already open two times!\n");
_ErrorHandle(EBUSY);
goto __error_handle0;
}
- if (__DSP_CAN_READ(iFlags)) {
- if (API_AtomicInc(&pDspDev->DSP_atomicReadOpenNum) != 1) {
- API_AtomicDec(&pDspDev->DSP_atomicReadOpenNum);
+ if (__DSP_CAN_READ(iFlags)) { /* 如果以可读方式打开 */
+ if (API_AtomicInc(&pDspDev->DSP_atomicReadOpenNum) != 1) { /* 如果已经被可读方式打开 */
+ API_AtomicDec(&pDspDev->DSP_atomicReadOpenNum); /* 不能再以可读方式打开 */
printk(KERN_ERR "__dspOpen(): already open with read mode!\n");
_ErrorHandle(EBUSY);
goto __error_handle0;
}
}
- if (__DSP_CAN_WRITE(iFlags)) {
- if (API_AtomicInc(&pDspDev->DSP_atomicWriteOpenNum) != 1) {
+ if (__DSP_CAN_WRITE(iFlags)) { /* 如果以可写方式打开 */
+ if (API_AtomicInc(&pDspDev->DSP_atomicWriteOpenNum) != 1) { /* 如果已经被可写方式打开 */
+ API_AtomicDec(&pDspDev->DSP_atomicWriteOpenNum); /* 不能再以可写方式打开 */
printk(KERN_ERR "__dspOpen(): already open with write mode!\n");
if (__DSP_CAN_READ(iFlags)) {
API_AtomicDec(&pDspDev->DSP_atomicReadOpenNum);
@@ -153,21 +154,28 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
}
}
- if (uiUseCount == 1) {
-
+ if (uiUseCount == 1) { /* 第一次打开 */
+ /*
+ * 打开 Codec
+ */
pfuncDevOpen = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevOpen;
- if (pfuncDevOpen(pDspDev->DSP_pCodecDev, pcName, O_RDWR, iMode) != ERROR_NONE) {
+ if (pfuncDevOpen(pDspDev->DSP_pCodecDev,
+ pcName, O_RDWR, iMode) != ERROR_NONE) { /* 读写方式打开 Codec */
printk(KERN_ERR "__dspOpen(): failed to init!\n");
goto __error_handle1;
}
- SEL_WAKE_UP_LIST_INIT(&pDspDev->DSP_selList);
+ SEL_WAKE_UP_LIST_INIT(&pDspDev->DSP_selList); /* 初始化 select 唤醒等待链 */
- LW_SPIN_INIT(&pDspDev->DSP_splWrite);
+ LW_SPIN_INIT(&pDspDev->DSP_splWrite); /* 初始化读写自旋锁 */
LW_SPIN_INIT(&pDspDev->DSP_splRead);
+ /*
+ * 初始化成员变量
+ */
pDspDev->DSP_uiBatchReadDoneCount = 0;
pDspDev->DSP_uiBatchWriteDoneCount = 0;
+
pDspDev->DSP_bReadMmaped = LW_FALSE;
pDspDev->DSP_bWriteMmaped = LW_FALSE;
pDspDev->DSP_bBatchReadStarted = LW_FALSE;
@@ -176,8 +184,12 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
pDspDev->DSP_ulBlockCounter = __DSP_DEFAULT_FRAGMENT_NUM;
pDspDev->DSP_stBlockSize = __DSP_DEFAULT_FRAGMENT_SIZE;
- pDspDev->DSP_pucBlockBuffer = API_VmmDmaAlloc(pDspDev->DSP_ulBlockCounter *
- pDspDev->DSP_stBlockSize * 2);
+ /*
+ * 分配读写缓冲区
+ */
+ pDspDev->DSP_pucBlockBuffer = API_VmmDmaAllocAlign(pDspDev->DSP_ulBlockCounter *
+ pDspDev->DSP_stBlockSize * 2,
+ LW_CFG_VMM_PAGE_SIZE);
if (pDspDev->DSP_pucBlockBuffer == LW_NULL) {
printk(KERN_ERR "__dspOpen(): failed to alloc block buffer!\n");
goto __error_handle1;
@@ -186,11 +198,17 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
pDspDev->DSP_pucReadBlockBuffer = pDspDev->DSP_pucBlockBuffer;
pDspDev->DSP_pucWriteBlockBuffer = pDspDev->DSP_pucBlockBuffer +
- pDspDev->DSP_ulBlockCounter * pDspDev->DSP_stBlockSize;
+ pDspDev->DSP_ulBlockCounter * pDspDev->DSP_stBlockSize;
- API_QueueInit(&pDspDev->DSP_queueRead, pDspDev->DSP_ulBlockCounter);
- API_QueueInit(&pDspDev->DSP_queueWrite, pDspDev->DSP_ulBlockCounter);
+ /*
+ * 初始化读写队列
+ */
+ API_QueueInit(&pDspDev->DSP_readQueue, pDspDev->DSP_ulBlockCounter);
+ API_QueueInit(&pDspDev->DSP_writeQueue, pDspDev->DSP_ulBlockCounter);
+ /*
+ * 创建读同步信号量
+ */
pDspDev->DSP_hReadSignal = API_SemaphoreBCreate("dsp_rsync",
LW_FALSE,
LW_OPTION_OBJECT_GLOBAL, LW_NULL);
@@ -199,6 +217,9 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
goto __error_handle1;
}
+ /*
+ * 创建读写块同步信号量
+ */
pDspDev->DSP_hReadBlockSignal = API_SemaphoreBCreate("dsp_blk_rsync",
LW_FALSE,
LW_OPTION_OBJECT_GLOBAL, LW_NULL);
@@ -221,6 +242,9 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
__error_handle1:
+ /*
+ * 删除读写块同步信号量
+ */
if (pDspDev->DSP_hWriteBlockSignal) {
API_SemaphoreBDelete(&pDspDev->DSP_hWriteBlockSignal);
pDspDev->DSP_hWriteBlockSignal = 0;
@@ -231,16 +255,22 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
pDspDev->DSP_hReadBlockSignal = 0;
}
+ /*
+ * 删除读同步信号量
+ */
if (pDspDev->DSP_hReadSignal) {
API_SemaphoreBDelete(&pDspDev->DSP_hReadSignal);
pDspDev->DSP_hReadSignal = 0;
}
+ /*
+ * 释放读写缓冲区
+ */
if (pDspDev->DSP_pucBlockBuffer) {
API_VmmDmaFree(pDspDev->DSP_pucBlockBuffer);
- pDspDev->DSP_pucBlockBuffer = 0;
- pDspDev->DSP_ulBlockCounter = 0;
- pDspDev->DSP_stBlockSize = 0;
+ pDspDev->DSP_pucBlockBuffer = 0;
+ pDspDev->DSP_ulBlockCounter = 0;
+ pDspDev->DSP_stBlockSize = 0;
pDspDev->DSP_pucReadBlockBuffer = 0;
pDspDev->DSP_pucWriteBlockBuffer = 0;
}
@@ -254,13 +284,15 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
}
__error_handle0:
-
+ /*
+ * 删除 FD 文件节点
+ */
if (pFdNode) {
API_IosFdNodeDec(&pDspDev->DSP_fdNodeHeader, pFdNode);
pFdNode = LW_NULL;
}
- LW_DEV_DEC_USE_COUNT(&pDspDev->DSP_devHdr);
+ LW_DEV_DEC_USE_COUNT(&pDspDev->DSP_devHdr); /* 减少打开计数 */
return (PX_ERROR);
}
@@ -274,54 +306,70 @@ static LONG __dspOpen (PLW_DEV_HDR pDev,
*********************************************************************************************************/
static INT __dspClose (PLW_FD_ENTRY pFdEntry)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- PLW_FD_NODE pFdNode = (PLW_FD_NODE)pFdEntry->FDENTRY_pfdnode;
- FUNCPTR pfuncDevClose;
- INT iFlags;
- INTREG intReg;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ PLW_FD_NODE pFdNode = (PLW_FD_NODE)pFdEntry->FDENTRY_pfdnode;
+ FUNCPTR pfuncDevClose;
+ INT iFlags;
+ INTREG intReg;
if (pFdEntry && pFdNode) {
- API_IosFdNodeDec(&pDspDev->DSP_fdNodeHeader, pFdNode);
+ API_IosFdNodeDec(&pDspDev->DSP_fdNodeHeader, pFdNode); /* 删除 FD 文件节点 */
- iFlags = pFdEntry->FDENTRY_iFlag & O_ACCMODE;
+ iFlags = pFdEntry->FDENTRY_iFlag & O_ACCMODE; /* 获得访问模式 */
- if (__DSP_CAN_READ(iFlags)) {
- API_AtomicDec(&pDspDev->DSP_atomicReadOpenNum);
+ if (__DSP_CAN_READ(iFlags)) { /* 如果以可读方式打开 */
+ API_AtomicDec(&pDspDev->DSP_atomicReadOpenNum); /* 减少读打开计数 */
+ /*
+ * 等待读队列为空
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- while (API_QueueCount(&pDspDev->DSP_queueRead)) {
+ while (API_QueueCount(&pDspDev->DSP_readQueue)) {
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
API_SemaphoreBPend(pDspDev->DSP_hReadBlockSignal, LW_OPTION_WAIT_INFINITE);
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
}
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
- __dspBatchReadStop(pDspDev);
+ __dspBatchReadStop(pDspDev); /* 停止批量读 DSP 设备 */
}
- if (__DSP_CAN_WRITE(iFlags)) {
- API_AtomicDec(&pDspDev->DSP_atomicWriteOpenNum);
+ if (__DSP_CAN_WRITE(iFlags)) { /* 如果以可写方式打开 */
+ API_AtomicDec(&pDspDev->DSP_atomicWriteOpenNum); /* 减少写打开计数 */
+ /*
+ * 等待写队列为空
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- while (API_QueueCount(&pDspDev->DSP_queueWrite)) {
+ while (API_QueueCount(&pDspDev->DSP_writeQueue)) {
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
API_SemaphoreBPend(pDspDev->DSP_hWriteBlockSignal, LW_OPTION_WAIT_INFINITE);
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
}
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
- __dspBatchWriteStop(pDspDev);
+ __dspBatchWriteStop(pDspDev); /* 停止批量写 DSP 设备 */
}
- if (LW_DEV_DEC_USE_COUNT(&pDspDev->DSP_devHdr) == 0) {
+ if (LW_DEV_DEC_USE_COUNT(&pDspDev->DSP_devHdr) == 0) { /* 减少打开计数, 最后一次关闭 */
+
+ /*
+ * 关闭 Codec
+ */
pfuncDevClose = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevClose;
pfuncDevClose(pDspDev->DSP_pCodecDev);
+ /*
+ * 删除读写块同步信号量
+ */
if (pDspDev->DSP_hWriteBlockSignal) {
API_SemaphoreBDelete(&pDspDev->DSP_hWriteBlockSignal);
pDspDev->DSP_hWriteBlockSignal = 0;
}
+ /*
+ * 删除读同步信号量
+ */
if (pDspDev->DSP_hReadBlockSignal) {
API_SemaphoreBDelete(&pDspDev->DSP_hReadBlockSignal);
pDspDev->DSP_hReadBlockSignal = 0;
@@ -332,8 +380,11 @@ static INT __dspClose (PLW_FD_ENTRY pFdEntry)
pDspDev->DSP_hReadSignal = 0;
}
- SEL_WAKE_UP_LIST_TERM(&pDspDev->DSP_selList);
+ SEL_WAKE_UP_LIST_TERM(&pDspDev->DSP_selList); /* 终止 select 等待任务 */
+ /*
+ * 释放读写缓冲区
+ */
if (pDspDev->DSP_pucBlockBuffer) {
API_VmmDmaFree(pDspDev->DSP_pucBlockBuffer);
pDspDev->DSP_pucBlockBuffer = 0;
@@ -359,24 +410,27 @@ static INT __dspClose (PLW_FD_ENTRY pFdEntry)
*********************************************************************************************************/
static VOID __dspBatchReadDone (PVOID pvArg)
{
- __PDSP_DEV pDspDev = pvArg;
- UINT i;
- SSIZETFUNCPTR pfuncDrvTransfer;
- INT iError;
- INTREG intReg;
-
- LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
+ __PDSP_DEV pDspDev = pvArg;
+ UINT i;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ INT iError;
+
+ /*
+ * 读完成计数++
+ */
i = pDspDev->DSP_uiBatchReadDoneCount;
pDspDev->DSP_uiBatchReadDoneCount++;
pDspDev->DSP_uiBatchReadDoneCount = pDspDev->DSP_uiBatchReadDoneCount % pDspDev->DSP_ulBlockCounter;
- LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
- SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELREAD);
+ SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELREAD); /* 唤醒 select 等待读任务 */
- if (pDspDev->DSP_bBatchReadStarted) {
+ if (pDspDev->DSP_bBatchReadStarted) { /* 如果启动了批量读 */
+ /*
+ * Codec 继续传输该消息
+ */
pfuncDrvTransfer = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevRead;
- iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, &pDspDev->DSP_aReadSpiMsgs[i], 1);
- if (iError != ERROR_NONE) {
+ iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, &pDspDev->DSP_aReadMsgs[i], 1);
+ if (iError != 1) {
printk(KERN_EMERG "__dspBatchReadDone(): failed to transfer!\n");
}
}
@@ -391,43 +445,54 @@ static VOID __dspBatchReadDone (PVOID pvArg)
*********************************************************************************************************/
static INT __dspBatchReadStart (__PDSP_DEV pDspDev)
{
- PLW_SPI_MESSAGE pSpiMsg;
- UINT i;
- PUCHAR pucBlockBuffer;
- SSIZETFUNCPTR pfuncDrvTransfer;
- INT iError;
- INTREG intReg;
-
+ PLW_SPI_MESSAGE pMsg;
+ UINT i;
+ PUCHAR pucBlockBuffer;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ INT iError;
+ INTREG intReg;
+
+ /*
+ * 等待读队列为空
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- while (API_QueueCount(&pDspDev->DSP_queueRead)) {
+ while (API_QueueCount(&pDspDev->DSP_readQueue)) {
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
API_SemaphoreBPend(pDspDev->DSP_hReadBlockSignal, LW_OPTION_WAIT_INFINITE);
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
}
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
+ /*
+ * 启动批量读
+ */
pDspDev->DSP_bBatchReadStarted = LW_TRUE;
pDspDev->DSP_uiBatchReadDoneCount = 0;
+ /*
+ * 初始化所有的消息
+ */
for (i = 0; i < pDspDev->DSP_ulBlockCounter; i++) {
- pSpiMsg = &pDspDev->DSP_aReadSpiMsgs[i];
+ pMsg = &pDspDev->DSP_aReadMsgs[i];
pucBlockBuffer = &pDspDev->DSP_pucReadBlockBuffer[i * pDspDev->DSP_stBlockSize];
- lib_memset(pSpiMsg, 0, sizeof(*pSpiMsg));
+ lib_memset(pMsg, 0, sizeof(*pMsg));
- pSpiMsg->SPIMSG_pucRdBuffer = pucBlockBuffer;
- pSpiMsg->SPIMSG_uiLen = pDspDev->DSP_stBlockSize;
+ pMsg->SPIMSG_pucRdBuffer = pucBlockBuffer;
+ pMsg->SPIMSG_uiLen = pDspDev->DSP_stBlockSize;
- pSpiMsg->SPIMSG_pfuncComplete = __dspBatchReadDone;
- pSpiMsg->SPIMSG_pvContext = pDspDev;
+ pMsg->SPIMSG_pfuncComplete = __dspBatchReadDone;
+ pMsg->SPIMSG_pvContext = pDspDev;
}
+ /*
+ * 传输所有的消息
+ */
pfuncDrvTransfer = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevRead;
iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev,
- pDspDev->DSP_aReadSpiMsgs,
+ pDspDev->DSP_aReadMsgs,
pDspDev->DSP_ulBlockCounter);
-
- if (iError != ERROR_NONE) {
+ if (iError != pDspDev->DSP_ulBlockCounter) {
printk(KERN_EMERG "__dspBatchRead(): failed to transfer!\n");
}
@@ -443,8 +508,11 @@ static INT __dspBatchReadStart (__PDSP_DEV pDspDev)
*********************************************************************************************************/
static INT __dspBatchReadStop (__PDSP_DEV pDspDev)
{
- INTREG intReg;
+ INTREG intReg;
+ /*
+ * 设置停止批量读标志
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
pDspDev->DSP_bBatchReadStarted = LW_FALSE;
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
@@ -461,25 +529,27 @@ static INT __dspBatchReadStop (__PDSP_DEV pDspDev)
*********************************************************************************************************/
static VOID __dspBatchWriteDone (PVOID pvArg)
{
- __PDSP_DEV pDspDev = pvArg;
- UINT i;
- SSIZETFUNCPTR pfuncDrvTransfer;
- INT iError;
- INTREG intReg;
-
- LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
+ __PDSP_DEV pDspDev = pvArg;
+ UINT i;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ INT iError;
+
+ /*
+ * 写完成计数++
+ */
i = pDspDev->DSP_uiBatchWriteDoneCount;
pDspDev->DSP_uiBatchWriteDoneCount++;
pDspDev->DSP_uiBatchWriteDoneCount = pDspDev->DSP_uiBatchWriteDoneCount % pDspDev->DSP_ulBlockCounter;
- LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
- SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELWRITE);
+ SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELWRITE); /* 唤醒 select 等待写任务 */
- if (pDspDev->DSP_bBatchWriteStarted) {
+ if (pDspDev->DSP_bBatchWriteStarted) { /* 如果启动了批量写 */
+ /*
+ * Codec 继续传输该消息
+ */
pfuncDrvTransfer = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevWrite;
- iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, &pDspDev->DSP_aWriteSpiMsgs[i], 1);
-
- if (iError != ERROR_NONE) {
+ iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, &pDspDev->DSP_aWriteMsgs[i], 1);
+ if (iError != 1) {
printk(KERN_EMERG "__dspBatchWriteDone(): failed to transfer!\n");
}
}
@@ -494,42 +564,54 @@ static VOID __dspBatchWriteDone (PVOID pvArg)
*********************************************************************************************************/
static INT __dspBatchWriteStart (__PDSP_DEV pDspDev)
{
- PLW_SPI_MESSAGE pSpiMsg;
- UINT i;
- PUCHAR pucBlockBuffer;
- SSIZETFUNCPTR pfuncDrvTransfer;
- INT iError;
- INTREG intReg;
-
+ PLW_SPI_MESSAGE pMsg;
+ UINT i;
+ PUCHAR pucBlockBuffer;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ INT iError;
+ INTREG intReg;
+
+ /*
+ * 等待写队列为空
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- while (API_QueueCount(&pDspDev->DSP_queueWrite)) {
+ while (API_QueueCount(&pDspDev->DSP_writeQueue)) {
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
API_SemaphoreBPend(pDspDev->DSP_hWriteBlockSignal, LW_OPTION_WAIT_INFINITE);
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
}
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
+ /*
+ * 启动批量写
+ */
pDspDev->DSP_bBatchWriteStarted = LW_TRUE;
pDspDev->DSP_uiBatchWriteDoneCount = 0;
+ /*
+ * 初始化所有的消息
+ */
for (i = 0; i < pDspDev->DSP_ulBlockCounter; i++) {
- pSpiMsg = &pDspDev->DSP_aWriteSpiMsgs[i];
+ pMsg = &pDspDev->DSP_aWriteMsgs[i];
pucBlockBuffer = &pDspDev->DSP_pucWriteBlockBuffer[i * pDspDev->DSP_stBlockSize];
- lib_memset(pSpiMsg, 0, sizeof(*pSpiMsg));
+ lib_memset(pMsg, 0, sizeof(*pMsg));
- pSpiMsg->SPIMSG_pucWrBuffer = pucBlockBuffer;
- pSpiMsg->SPIMSG_uiLen = pDspDev->DSP_stBlockSize;
+ pMsg->SPIMSG_pucWrBuffer = pucBlockBuffer;
+ pMsg->SPIMSG_uiLen = pDspDev->DSP_stBlockSize;
- pSpiMsg->SPIMSG_pfuncComplete = __dspBatchWriteDone;
- pSpiMsg->SPIMSG_pvContext = pDspDev;
+ pMsg->SPIMSG_pfuncComplete = __dspBatchWriteDone;
+ pMsg->SPIMSG_pvContext = pDspDev;
}
+ /*
+ * 传输所有的消息
+ */
pfuncDrvTransfer = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevWrite;
iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev,
- pDspDev->DSP_aWriteSpiMsgs,
+ pDspDev->DSP_aWriteMsgs,
pDspDev->DSP_ulBlockCounter);
- if (iError != ERROR_NONE) {
+ if (iError != pDspDev->DSP_ulBlockCounter) {
printk(KERN_EMERG "__dspBatchWrite(): failed to transfer!\n");
}
@@ -545,8 +627,11 @@ static INT __dspBatchWriteStart (__PDSP_DEV pDspDev)
*********************************************************************************************************/
static INT __dspBatchWriteStop (__PDSP_DEV pDspDev)
{
- INTREG intReg;
+ INTREG intReg;
+ /*
+ * 设置停止批量读标志
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
pDspDev->DSP_bBatchWriteStarted = LW_FALSE;
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
@@ -567,7 +652,7 @@ static INT __dspLstat (PLW_DEV_HDR pDev,
PCHAR pcName,
struct stat *pStat)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pDev;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pDev;
if (pStat) {
pStat->st_dev = (dev_t)pDspDev;
@@ -577,9 +662,10 @@ static INT __dspLstat (PLW_DEV_HDR pDev,
pStat->st_uid = 0;
pStat->st_gid = 0;
pStat->st_rdev = 0;
+ /* 总大小为读写缓冲区大小之和 */
pStat->st_size = pDspDev->DSP_ulBlockCounter * pDspDev->DSP_stBlockSize * 2;
pStat->st_blksize = pDspDev->DSP_stBlockSize;
- pStat->st_blocks = pDspDev->DSP_ulBlockCounter * 2;
+ pStat->st_blocks = pDspDev->DSP_ulBlockCounter * 2; /* 总块数为读写块数之和 */
pStat->st_atime = pDspDev->DSP_time;
pStat->st_mtime = pDspDev->DSP_time;
pStat->st_ctime = pDspDev->DSP_time;
@@ -631,9 +717,10 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
pStat->st_uid = 0;
pStat->st_gid = 0;
pStat->st_rdev = 0;
+ /* 总大小为读写缓冲区大小之和 */
pStat->st_size = pDspDev->DSP_ulBlockCounter * pDspDev->DSP_stBlockSize * 2;
pStat->st_blksize = pDspDev->DSP_stBlockSize;
- pStat->st_blocks = pDspDev->DSP_ulBlockCounter * 2;
+ pStat->st_blocks = pDspDev->DSP_ulBlockCounter * 2; /* 总块数为读写块数之和 */
pStat->st_atime = pDspDev->DSP_time;
pStat->st_mtime = pDspDev->DSP_time;
pStat->st_ctime = pDspDev->DSP_time;
@@ -659,54 +746,53 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
case FIOSELECT:
pSelNode = (PLW_SEL_WAKEUPNODE)lArg;
- SEL_WAKE_NODE_ADD(&pDspDev->DSP_selList, pSelNode);
+ SEL_WAKE_NODE_ADD(&pDspDev->DSP_selList, pSelNode); /* 将任务加入到 select 等待链 */
- if (pSelNode->SELWUN_seltypType == SELREAD) {
+ if (pSelNode->SELWUN_seltypType == SELREAD) { /* select 可读 */
- if (__DSP_CAN_READ(iFlags)) {
- if (!pDspDev->DSP_bReadMmaped) {
+ if (__DSP_CAN_READ(iFlags)) { /* 具有可读权限 */
+ if (!pDspDev->DSP_bReadMmaped) { /* 还没有 mmap read */
+ /*
+ * 读队列没满就可以唤醒任务
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- bReslut = API_QueueIsFull(&pDspDev->DSP_queueRead);
+ bReslut = API_QueueIsFull(&pDspDev->DSP_readQueue);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
-
if (!bReslut) {
SEL_WAKE_UP(pSelNode);
}
} else {
- LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- bReslut = pDspDev->DSP_uiBatchReadDoneCount > 0 ? LW_TRUE : LW_FALSE;
- LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
-
- if (bReslut) {
- SEL_WAKE_UP(pSelNode);
- }
+ /*
+ * 已经 mmap read, 不能 select
+ */
}
} else {
SEL_WAKE_UP(pSelNode);
+ _ErrorHandle(EACCES);
+ return (PX_ERROR);
}
+ } else if (pSelNode->SELWUN_seltypType == SELWRITE) { /* select 可写 */
- } else if (pSelNode->SELWUN_seltypType == SELWRITE) {
-
- if (__DSP_CAN_WRITE(iFlags)) {
- if (!pDspDev->DSP_bWriteMmaped) {
+ if (__DSP_CAN_WRITE(iFlags)) { /* 具有可写权限 */
+ if (!pDspDev->DSP_bWriteMmaped) { /* 还没有 mmap write */
+ /*
+ * 写队列没满就可以唤醒任务
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- bReslut = API_QueueIsFull(&pDspDev->DSP_queueWrite);
+ bReslut = API_QueueIsFull(&pDspDev->DSP_writeQueue);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
-
if (!bReslut) {
SEL_WAKE_UP(pSelNode);
}
} else {
- LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- bReslut = pDspDev->DSP_uiBatchWriteDoneCount > 0 ? LW_TRUE : LW_FALSE;
- LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
-
- if (bReslut) {
- SEL_WAKE_UP(pSelNode);
- }
+ /*
+ * 已经 mmap write, 不能 select
+ */
}
} else {
SEL_WAKE_UP(pSelNode);
+ _ErrorHandle(EACCES);
+ return (PX_ERROR);
}
}
return (ERROR_NONE);
@@ -724,7 +810,7 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
case SNDCTL_DSP_GETCAPS:
pIntData = (INT *)lArg;
if (pIntData) {
- *pIntData = DSP_CAP_MMAP | DSP_CAP_TRIGGER;
+ *pIntData = DSP_CAP_MMAP | DSP_CAP_TRIGGER; /* 可以 mmap 和 trigger */
return (ERROR_NONE);
}
_ErrorHandle(EINVAL);
@@ -737,10 +823,13 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
paudio_buf_info = (audio_buf_info *)lArg;
if (paudio_buf_info) {
- if (__DSP_CAN_READ(iFlags)) {
- if (!pDspDev->DSP_bReadMmaped) {
+ if (__DSP_CAN_READ(iFlags)) { /* 具有可读权限 */
+ if (!pDspDev->DSP_bReadMmaped) { /* 还没有 mmap read */
+ /*
+ * 获得读队列空闲空间大小
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- paudio_buf_info->fragments = API_QueueFreeSpace(&pDspDev->DSP_queueRead);
+ paudio_buf_info->fragments = API_QueueFreeSpace(&pDspDev->DSP_readQueue);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
} else {
paudio_buf_info->fragments = 0;
@@ -764,10 +853,13 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
paudio_buf_info = (audio_buf_info *)lArg;
if (paudio_buf_info) {
- if (__DSP_CAN_WRITE(iFlags)) {
- if (!pDspDev->DSP_bWriteMmaped) {
+ if (__DSP_CAN_WRITE(iFlags)) { /* 具有可写权限 */
+ if (!pDspDev->DSP_bWriteMmaped) { /* 还没有 mmap write */
+ /*
+ * 获得写队列空闲空间大小
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- paudio_buf_info->fragments = API_QueueFreeSpace(&pDspDev->DSP_queueWrite);
+ paudio_buf_info->fragments = API_QueueFreeSpace(&pDspDev->DSP_writeQueue);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
} else {
paudio_buf_info->fragments = 0;
@@ -791,8 +883,12 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
pcount_info = (count_info *)lArg;
if (pcount_info) {
- if (__DSP_CAN_READ(iFlags)) {
- if (pDspDev->DSP_bReadMmaped && pDspDev->DSP_bBatchReadStarted) {
+ if (__DSP_CAN_READ(iFlags)) { /* 具有可读权限 */
+ if (pDspDev->DSP_bReadMmaped && /* 已经 mmap read 并且 */
+ pDspDev->DSP_bBatchReadStarted) { /* 启动了批量读 */
+ /*
+ * 获得传输完成的块数目
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
pcount_info->blocks = pDspDev->DSP_uiBatchReadDoneCount;
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
@@ -817,8 +913,12 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
pcount_info = (count_info *)lArg;
if (pcount_info) {
- if (__DSP_CAN_WRITE(iFlags)) {
- if (pDspDev->DSP_bWriteMmaped && pDspDev->DSP_bBatchWriteStarted) {
+ if (__DSP_CAN_WRITE(iFlags)) { /* 具有可写权限 */
+ if (pDspDev->DSP_bWriteMmaped && /* 已经 mmap write 并且 */
+ pDspDev->DSP_bBatchWriteStarted) { /* 启动了批量写 */
+ /*
+ * 获得传输完成的块数目
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
pcount_info->blocks = pDspDev->DSP_uiBatchWriteDoneCount;
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
@@ -842,43 +942,37 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
case SNDCTL_DSP_SETTRIGGER:
pIntData = (INT *)lArg;
if (pIntData) {
- if (*pIntData & PCM_ENABLE_INPUT) {
- if (__DSP_CAN_READ(iFlags)) {
- if (!pDspDev->DSP_bBatchReadStarted) {
- __dspBatchReadStart(pDspDev);
+ if (*pIntData & PCM_ENABLE_INPUT) { /* 触发输入 */
+ if (__DSP_CAN_READ(iFlags)) { /* 具有可读权限 */
+ if (!pDspDev->DSP_bBatchReadStarted) { /* 如果还没有启动批量读 */
+ __dspBatchReadStart(pDspDev); /* 启动批量读 */
}
} else {
_ErrorHandle(EACCES);
return (PX_ERROR);
}
- } else {
- if (__DSP_CAN_READ(iFlags)) {
- if (pDspDev->DSP_bBatchReadStarted) {
- __dspBatchReadStop(pDspDev);
+ } else { /* 停止输入 */
+ if (__DSP_CAN_READ(iFlags)) { /* 具有可读权限 */
+ if (pDspDev->DSP_bBatchReadStarted) { /* 如果已经启动了批量读 */
+ __dspBatchReadStop(pDspDev); /* 停止批量读 */
}
- } else {
- _ErrorHandle(EACCES);
- return (PX_ERROR);
}
}
- if (*pIntData & PCM_ENABLE_OUTPUT) {
- if (__DSP_CAN_WRITE(iFlags)) {
- if (!pDspDev->DSP_bBatchWriteStarted) {
- __dspBatchWriteStart(pDspDev);
+ if (*pIntData & PCM_ENABLE_OUTPUT) { /* 触发输出 */
+ if (__DSP_CAN_WRITE(iFlags)) { /* 具有可写权限 */
+ if (!pDspDev->DSP_bBatchWriteStarted) { /* 如果还没有启动批量写 */
+ __dspBatchWriteStart(pDspDev); /* 启动批量写 */
}
} else {
_ErrorHandle(EACCES);
return (PX_ERROR);
}
- } else {
- if (__DSP_CAN_WRITE(iFlags)) {
- if (pDspDev->DSP_bBatchWriteStarted) {
- __dspBatchWriteStop(pDspDev);
+ } else { /* 停止输出 */
+ if (__DSP_CAN_WRITE(iFlags)) { /* 具有可写权限 */
+ if (pDspDev->DSP_bBatchWriteStarted) { /* 如果已经启动了批量写 */
+ __dspBatchWriteStop(pDspDev); /* 停止批量写 */
}
- } else {
- _ErrorHandle(EACCES);
- return (PX_ERROR);
}
}
@@ -894,10 +988,10 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
pIntData = (INT *)lArg;
if (pIntData) {
*pIntData = 0;
- if (__DSP_CAN_READ(iFlags)) {
- *pIntData |= pDspDev->DSP_bBatchReadStarted ? PCM_ENABLE_INPUT : 0;
+ if (__DSP_CAN_READ(iFlags)) { /* 具有可读权限 */
+ *pIntData |= pDspDev->DSP_bBatchReadStarted ? PCM_ENABLE_INPUT : 0;
}
- if (__DSP_CAN_WRITE(iFlags)) {
+ if (__DSP_CAN_WRITE(iFlags)) { /* 具有可写权限 */
*pIntData |= pDspDev->DSP_bBatchWriteStarted ? PCM_ENABLE_OUTPUT : 0;
}
return (ERROR_NONE);
@@ -911,34 +1005,49 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
case SNDCTL_DSP_SETFRAGMENT:
pIntData = (INT *)lArg;
if (pIntData) {
- if (LW_DEV_INC_USE_COUNT(&pDspDev->DSP_devHdr) == 2) {
- if (!pDspDev->DSP_bReadMmaped &&
+ if (LW_DEV_INC_USE_COUNT(&pDspDev->DSP_devHdr) == 2) { /* 只打开过一次 */
+ if (!pDspDev->DSP_bReadMmaped && /* 还没有 mmap 和 trigger */
!pDspDev->DSP_bWriteMmaped &&
!pDspDev->DSP_bBatchReadStarted &&
!pDspDev->DSP_bBatchWriteStarted) {
- ulBlockCounter = *pIntData >> 16;
- stBlockSize = *pIntData & 0xFFFF;
- stBlockSize = pow(2, stBlockSize);
+ INT i;
+ ulBlockCounter = *pIntData >> 16; /* 块数目 */
+ stBlockSize = 1; /* 计算块大小 */
+ for (i = 0; i < (*pIntData & 0xFFFF); i++) {
+ stBlockSize *= 2;
+ }
- if (ulBlockCounter && stBlockSize) {
+ if ((ulBlockCounter <= __DSP_MAX_FRAGMENT_NUM) &&
+ (ulBlockCounter >= __DSP_MIN_FRAGMENT_NUM) &&
+ (stBlockSize <= __DSP_MAX_FRAGMENT_SIZE) &&
+ (stBlockSize >= __DSP_MIN_FRAGMENT_SIZE)) {
+ /*
+ * 等待读队列为空
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- while (API_QueueCount(&pDspDev->DSP_queueRead)) {
+ while (API_QueueCount(&pDspDev->DSP_readQueue)) {
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
API_SemaphoreBPend(pDspDev->DSP_hReadBlockSignal, LW_OPTION_WAIT_INFINITE);
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
}
+ /*
+ * 等待写队列为空
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- while (API_QueueCount(&pDspDev->DSP_queueWrite)) {
+ while (API_QueueCount(&pDspDev->DSP_writeQueue)) {
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
API_SemaphoreBPend(pDspDev->DSP_hWriteBlockSignal, LW_OPTION_WAIT_INFINITE);
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
}
-
- pucBlockBuffer = API_VmmDmaAlloc(ulBlockCounter * stBlockSize * 2);
+ /*
+ * 分配读写缓冲区
+ */
+ pucBlockBuffer = API_VmmDmaAllocAlign(ulBlockCounter * stBlockSize * 2,
+ LW_CFG_VMM_PAGE_SIZE);
if (pucBlockBuffer == LW_NULL) {
printk(KERN_ERR "__dspIoctl(): failed to alloc block buffer!\n");
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
@@ -947,11 +1056,20 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
return (PX_ERROR);
}
+ /*
+ * 记录块大小和块数目
+ */
pDspDev->DSP_ulBlockCounter = ulBlockCounter;
pDspDev->DSP_stBlockSize = stBlockSize;
+ /*
+ * 释放原有的读写缓冲区
+ */
API_VmmDmaFree(pDspDev->DSP_pucBlockBuffer);
+ /*
+ * 记录新的读写缓冲区
+ */
pDspDev->DSP_pucBlockBuffer = pucBlockBuffer;
pDspDev->DSP_pucReadBlockBuffer = pDspDev->DSP_pucBlockBuffer;
@@ -959,11 +1077,18 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
pDspDev->DSP_pucWriteBlockBuffer = pDspDev->DSP_pucBlockBuffer +
pDspDev->DSP_ulBlockCounter * pDspDev->DSP_stBlockSize;
- API_QueueInit(&pDspDev->DSP_queueRead, pDspDev->DSP_ulBlockCounter);
- API_QueueInit(&pDspDev->DSP_queueWrite, pDspDev->DSP_ulBlockCounter);
+ /*
+ * 初始化读写队列
+ */
+ API_QueueInit(&pDspDev->DSP_readQueue, pDspDev->DSP_ulBlockCounter);
+ API_QueueInit(&pDspDev->DSP_writeQueue, pDspDev->DSP_ulBlockCounter);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
- LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
+ LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
+
+ /*
+ * 减小打开计数
+ */
LW_DEV_DEC_USE_COUNT(&pDspDev->DSP_devHdr);
return (ERROR_NONE);
@@ -991,6 +1116,9 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
case SNDCTL_DSP_SPEED:
pIntData = (INT *)lArg;
if (pIntData) {
+ /*
+ * 调用 Codec 的 ioctl 函数
+ */
pfuncDrvIoctl = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevIoctl;
return (pfuncDrvIoctl(pDspDev->DSP_pCodecDev, iCmd, lArg));
} else {
@@ -1013,9 +1141,9 @@ static INT __dspIoctl (PLW_FD_ENTRY pFdEntry,
*********************************************************************************************************/
static VOID __dspReadDone (PVOID pvArg)
{
- __PDSP_DEV pDspDev = pvArg;
+ __PDSP_DEV pDspDev = pvArg;
- API_SemaphoreBPost(pDspDev->DSP_hReadSignal);
+ API_SemaphoreBPost(pDspDev->DSP_hReadSignal); /* 发送读同步信号 */
}
/*********************************************************************************************************
** 函数名称: __dspRead
@@ -1031,31 +1159,34 @@ static ssize_t __dspRead (PLW_FD_ENTRY pFdEntry,
PCHAR pcBuffer,
size_t stMaxBytes)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- PUCHAR pucBlockBuffer;
- BOOL bNonBlock;
- INT iError;
- SSIZETFUNCPTR pfuncDrvTransfer;
- PLW_SPI_MESSAGE pSpiMsg;
- INTREG intReg;
- BOOL bSuccess;
- UINT i;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ PUCHAR pucBlockBuffer;
+ BOOL bNonBlock;
+ INT iError;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ PLW_SPI_MESSAGE pMsg;
+ INTREG intReg;
+ BOOL bSuccess;
+ UINT i;
if (!pFdEntry || !pcBuffer) {
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
- if (!__DSP_CAN_READ(pFdEntry->FDENTRY_iFlag)) {
+ if (!__DSP_CAN_READ(pFdEntry->FDENTRY_iFlag)) { /* 不具有可读权限 */
_ErrorHandle(EACCES);
return (PX_ERROR);
}
- if (pDspDev->DSP_bReadMmaped) {
+ if (pDspDev->DSP_bReadMmaped) { /* 已经 mmap 读了 */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
+ /*
+ * 获得 Codec 的传输函数
+ */
pfuncDrvTransfer = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevRead;
if (!pfuncDrvTransfer) {
_ErrorHandle(ENOSYS);
@@ -1066,19 +1197,25 @@ static ssize_t __dspRead (PLW_FD_ENTRY pFdEntry,
return (0);
}
+ /*
+ * 是否非阻塞
+ */
if (pFdEntry->FDENTRY_iFlag & O_NONBLOCK) {
bNonBlock = LW_TRUE;
} else {
bNonBlock = LW_FALSE;
}
+ /*
+ * 等待一个空闲位置
+ */
while (1) {
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- bSuccess = API_QueueIn(&pDspDev->DSP_queueRead, &i);
+ bSuccess = API_QueueIn(&pDspDev->DSP_readQueue, &i);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
if (!bSuccess) {
- if (bNonBlock) {
+ if (bNonBlock) { /* 非阻塞模式直接退出 */
return (0);
} else {
API_SemaphoreBPend(pDspDev->DSP_hReadBlockSignal, LW_OPTION_WAIT_INFINITE);
@@ -1088,28 +1225,42 @@ static ssize_t __dspRead (PLW_FD_ENTRY pFdEntry,
}
}
- pSpiMsg = &pDspDev->DSP_aReadSpiMsgs[i];
+ /*
+ * 获得传输消息和块缓冲区
+ */
+ pMsg = &pDspDev->DSP_aReadMsgs[i];
pucBlockBuffer = &pDspDev->DSP_pucReadBlockBuffer[i * pDspDev->DSP_stBlockSize];
- lib_memset(pSpiMsg, 0, sizeof(*pSpiMsg));
-
- stMaxBytes = stMaxBytes > pDspDev->DSP_stBlockSize ? pDspDev->DSP_stBlockSize : stMaxBytes;
-
- pSpiMsg->SPIMSG_pucRdBuffer = pucBlockBuffer;
- pSpiMsg->SPIMSG_uiLen = stMaxBytes;
-
- pSpiMsg->SPIMSG_pfuncComplete = __dspReadDone;
- pSpiMsg->SPIMSG_pvContext = pDspDev;
- iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, pSpiMsg, 1);
- if (iError != ERROR_NONE) {
+ stMaxBytes = min(stMaxBytes, pDspDev->DSP_stBlockSize);
+
+ /*
+ * 初始化消息
+ */
+ lib_memset(pMsg, 0, sizeof(*pMsg));
+ pMsg->SPIMSG_pucRdBuffer = pucBlockBuffer;
+ pMsg->SPIMSG_uiLen = stMaxBytes;
+ pMsg->SPIMSG_pfuncComplete = __dspReadDone;
+ pMsg->SPIMSG_pvContext = pDspDev;
+
+ /*
+ * 传输消息
+ */
+ iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, pMsg, 1);
+ if (iError != 1) {
printk(KERN_EMERG "__dspRead(): failed to transfer!\n");
_ErrorHandle(EIO);
stMaxBytes = PX_ERROR;
goto __error_handle;
}
+ /*
+ * 等待消息传输完成
+ */
iError = API_SemaphoreBPend(pDspDev->DSP_hReadSignal, LW_OPTION_WAIT_INFINITE);
if (iError == ERROR_NONE) {
+ /*
+ * 从块缓冲区拷贝数据
+ */
lib_memcpy(pcBuffer, pucBlockBuffer, stMaxBytes);
} else {
printk(KERN_EMERG "__dspRead(): failed to pend read_signal!\n");
@@ -1119,7 +1270,7 @@ static ssize_t __dspRead (PLW_FD_ENTRY pFdEntry,
__error_handle:
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splRead, &intReg);
- API_QueueUnIn(&pDspDev->DSP_queueRead);
+ API_QueueUnIn(&pDspDev->DSP_readQueue);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splRead, intReg);
API_SemaphoreBPost(pDspDev->DSP_hReadBlockSignal);
@@ -1138,16 +1289,22 @@ static ssize_t __dspRead (PLW_FD_ENTRY pFdEntry,
*********************************************************************************************************/
static VOID __dspWriteDone (PVOID pvArg)
{
- __PDSP_DEV pDspDev = pvArg;
- INTREG intReg;
- UINT i;
- BOOL bSuccess;
-
+ __PDSP_DEV pDspDev = pvArg;
+ INTREG intReg;
+ UINT i;
+ BOOL bSuccess;
+
+ /*
+ * 获得传输完成的位置
+ */
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- bSuccess = API_QueueOut(&pDspDev->DSP_queueWrite, &i);
+ bSuccess = API_QueueOut(&pDspDev->DSP_writeQueue, &i);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
if (bSuccess) {
+ /*
+ * 发送写块信号和唤醒 select 等待写的任务
+ */
API_SemaphoreBPost(pDspDev->DSP_hWriteBlockSignal);
SEL_WAKE_UP_ALL(&pDspDev->DSP_selList, SELWRITE);
} else {
@@ -1168,31 +1325,34 @@ static ssize_t __dspWrite (PLW_FD_ENTRY pFdEntry,
PCHAR pcBuffer,
size_t stMaxBytes)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- PUCHAR pucBlockBuffer;
- BOOL bNonBlock;
- INT iError;
- SSIZETFUNCPTR pfuncDrvTransfer;
- PLW_SPI_MESSAGE pSpiMsg;
- INTREG intReg;
- BOOL bSuccess;
- UINT i;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ PUCHAR pucBlockBuffer;
+ BOOL bNonBlock;
+ INT iError;
+ SSIZETFUNCPTR pfuncDrvTransfer;
+ PLW_SPI_MESSAGE pMsg;
+ INTREG intReg;
+ BOOL bSuccess;
+ UINT i;
- if (!pFdEntry || !pcBuffer) {
+ if (!pFdEntry || !pcBuffer) { /* 参数无效 */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
- if (!__DSP_CAN_WRITE(pFdEntry->FDENTRY_iFlag)) {
+ if (!__DSP_CAN_WRITE(pFdEntry->FDENTRY_iFlag)) { /* 不具有写权限 */
_ErrorHandle(EACCES);
return (PX_ERROR);
}
- if (pDspDev->DSP_bWriteMmaped) {
+ if (pDspDev->DSP_bWriteMmaped) { /* 已经 mmap read */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
+ /*
+ * 获得 Codec 传输函数
+ */
pfuncDrvTransfer = pDspDev->DSP_pCodecDevEntry->DEVENTRY_pfuncDevWrite;
if (!pfuncDrvTransfer) {
_ErrorHandle(ENOSYS);
@@ -1203,19 +1363,25 @@ static ssize_t __dspWrite (PLW_FD_ENTRY pFdEntry,
return (0);
}
+ /*
+ * 是否非阻塞
+ */
if (pFdEntry->FDENTRY_iFlag & O_NONBLOCK) {
bNonBlock = LW_TRUE;
} else {
bNonBlock = LW_FALSE;
}
+ /*
+ * 等待一个空闲位置
+ */
while (1) {
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- bSuccess = API_QueueIn(&pDspDev->DSP_queueWrite, &i);
+ bSuccess = API_QueueIn(&pDspDev->DSP_writeQueue, &i);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
if (!bSuccess) {
- if (bNonBlock) {
+ if (bNonBlock) { /* 非阻塞模式直接退出 */
return (0);
} else {
API_SemaphoreBPend(pDspDev->DSP_hWriteBlockSignal, LW_OPTION_WAIT_INFINITE);
@@ -1225,26 +1391,36 @@ static ssize_t __dspWrite (PLW_FD_ENTRY pFdEntry,
}
}
- pSpiMsg = &pDspDev->DSP_aWriteSpiMsgs[i];
+ /*
+ * 获得传输消息和块缓冲区
+ */
+ pMsg = &pDspDev->DSP_aWriteMsgs[i];
pucBlockBuffer = &pDspDev->DSP_pucWriteBlockBuffer[i * pDspDev->DSP_stBlockSize];
- lib_memset(pSpiMsg, 0, sizeof(*pSpiMsg));
-
- stMaxBytes = stMaxBytes > pDspDev->DSP_stBlockSize ? pDspDev->DSP_stBlockSize : stMaxBytes;
+ /*
+ * 拷贝数据到块缓冲区
+ */
+ stMaxBytes = min(stMaxBytes, pDspDev->DSP_stBlockSize);
lib_memcpy(pucBlockBuffer, pcBuffer, stMaxBytes);
- pSpiMsg->SPIMSG_pucWrBuffer = pucBlockBuffer;
- pSpiMsg->SPIMSG_uiLen = stMaxBytes;
-
- pSpiMsg->SPIMSG_pfuncComplete = __dspWriteDone;
- pSpiMsg->SPIMSG_pvContext = pDspDev;
-
- iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, pSpiMsg, 1);
- if (iError != ERROR_NONE) {
+ /*
+ * 初始化消息
+ */
+ lib_memset(pMsg, 0, sizeof(*pMsg));
+ pMsg->SPIMSG_pucWrBuffer = pucBlockBuffer;
+ pMsg->SPIMSG_uiLen = stMaxBytes;
+ pMsg->SPIMSG_pfuncComplete = __dspWriteDone;
+ pMsg->SPIMSG_pvContext = pDspDev;
+
+ /*
+ * 传输消息
+ */
+ iError = pfuncDrvTransfer(pDspDev->DSP_pCodecDev, pMsg, 1);
+ if (iError != 1) {
printk(KERN_EMERG "__dspWrite(): failed to transfer!\n");
LW_SPIN_LOCK_QUICK(&pDspDev->DSP_splWrite, &intReg);
- bSuccess = API_QueueUnIn(&pDspDev->DSP_queueWrite);
+ bSuccess = API_QueueUnIn(&pDspDev->DSP_writeQueue);
LW_SPIN_UNLOCK_QUICK(&pDspDev->DSP_splWrite, intReg);
stMaxBytes = PX_ERROR;
@@ -1265,23 +1441,27 @@ static ssize_t __dspWrite (PLW_FD_ENTRY pFdEntry,
static INT __dspMmapRead (PLW_FD_ENTRY pFdEntry,
PLW_DEV_MMAP_AREA pMmapArea)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- if (pDspDev->DSP_bReadMmaped) {
+ if (pDspDev->DSP_bReadMmaped) { /* 如果已经 mmap read */
_ErrorHandle(EBUSY);
return (PX_ERROR);
}
- if (LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag) {
+ if (LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag) { /* 如果请求 mmap write */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
- if (pMmapArea->DMAP_stLen != pDspDev->DSP_stBlockSize * pDspDev->DSP_ulBlockCounter) {
+ if (pMmapArea->DMAP_stLen !=
+ pDspDev->DSP_stBlockSize * pDspDev->DSP_ulBlockCounter) { /* mmap 长度不正确 */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
+ pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_CACHEABLE; /* 取消 Cacheable */
+ pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_BUFFERABLE; /* 取消 Bufferable */
+
if (API_VmmRemapArea(pMmapArea->DMAP_pvAddr,
(PVOID)pDspDev->DSP_pucReadBlockBuffer,
pMmapArea->DMAP_stLen,
@@ -1290,7 +1470,7 @@ static INT __dspMmapRead (PLW_FD_ENTRY pFdEntry,
return (PX_ERROR);
}
- pDspDev->DSP_bReadMmaped = LW_TRUE;
+ pDspDev->DSP_bReadMmaped = LW_TRUE; /* 设置 mmap read 标志 */
return (ERROR_NONE);
}
@@ -1306,23 +1486,27 @@ static INT __dspMmapRead (PLW_FD_ENTRY pFdEntry,
static INT __dspMmapWrite (PLW_FD_ENTRY pFdEntry,
PLW_DEV_MMAP_AREA pMmapArea)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- if (pDspDev->DSP_bWriteMmaped) {
+ if (pDspDev->DSP_bWriteMmaped) { /* 如果已经 mmap write */
_ErrorHandle(EBUSY);
return (PX_ERROR);
}
- if (!(LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag)) {
+ if (!(LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag)) { /* 如果没有请求 mmap write */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
- if (pMmapArea->DMAP_stLen != pDspDev->DSP_stBlockSize * pDspDev->DSP_ulBlockCounter) {
+ if (pMmapArea->DMAP_stLen !=
+ pDspDev->DSP_stBlockSize * pDspDev->DSP_ulBlockCounter) { /* mmap 长度不正确 */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
+ pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_CACHEABLE; /* 取消 Cacheable */
+ pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_BUFFERABLE; /* 取消 Bufferable */
+
if (API_VmmRemapArea(pMmapArea->DMAP_pvAddr,
(PVOID)pDspDev->DSP_pucWriteBlockBuffer,
pMmapArea->DMAP_stLen,
@@ -1331,7 +1515,7 @@ static INT __dspMmapWrite (PLW_FD_ENTRY pFdEntry,
return (PX_ERROR);
}
- pDspDev->DSP_bWriteMmaped = LW_TRUE;
+ pDspDev->DSP_bWriteMmaped = LW_TRUE; /* 设置 mmap write 标志 */
return (ERROR_NONE);
}
@@ -1347,31 +1531,35 @@ static INT __dspMmapWrite (PLW_FD_ENTRY pFdEntry,
static INT __dspMmapReadWrite (PLW_FD_ENTRY pFdEntry,
PLW_DEV_MMAP_AREA pMmapArea)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- if (!(LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag)) {
- return (__dspMmapRead(pFdEntry, pMmapArea));
+ if (!(LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag)) { /* 如果没有请求 mmap write */
+ return (__dspMmapRead(pFdEntry, pMmapArea)); /* mmap read */
}
- if (pDspDev->DSP_bWriteMmaped && pDspDev->DSP_bReadMmaped) {
+ if (pDspDev->DSP_bWriteMmaped && pDspDev->DSP_bReadMmaped) { /* 如果已经 mmap read & write */
_ErrorHandle(EBUSY);
return (PX_ERROR);
}
- if (pDspDev->DSP_bWriteMmaped) {
+ if (pDspDev->DSP_bWriteMmaped) { /* 如果已经 mmap write */
pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_WRITABLE;
- return (__dspMmapRead(pFdEntry, pMmapArea));
+ return (__dspMmapRead(pFdEntry, pMmapArea)); /* mmap read */
}
- if (pDspDev->DSP_bReadMmaped) {
+ if (pDspDev->DSP_bReadMmaped) { /* 如果已经 mmap read */
return (__dspMmapWrite(pFdEntry, pMmapArea));
}
- if (pMmapArea->DMAP_stLen != pDspDev->DSP_stBlockSize * pDspDev->DSP_ulBlockCounter * 2) {
+ if (pMmapArea->DMAP_stLen !=
+ pDspDev->DSP_stBlockSize * pDspDev->DSP_ulBlockCounter * 2) { /* mmap 长度不正确 */
_ErrorHandle(EINVAL);
return (PX_ERROR);
}
+ pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_CACHEABLE; /* 取消 Cacheable */
+ pMmapArea->DMAP_ulFlag &= ~LW_VMM_FLAG_BUFFERABLE; /* 取消 Bufferable */
+
if (API_VmmRemapArea(pMmapArea->DMAP_pvAddr,
(PVOID)pDspDev->DSP_pucBlockBuffer,
pMmapArea->DMAP_stLen,
@@ -1380,8 +1568,8 @@ static INT __dspMmapReadWrite (PLW_FD_ENTRY pFdEntry,
return (PX_ERROR);
}
- pDspDev->DSP_bReadMmaped = LW_TRUE;
- pDspDev->DSP_bWriteMmaped = LW_TRUE;
+ pDspDev->DSP_bReadMmaped = LW_TRUE; /* 设置 mmap read 标志 */
+ pDspDev->DSP_bWriteMmaped = LW_TRUE; /* 设置 mmap write 标志 */
return (ERROR_NONE);
}
@@ -1397,9 +1585,9 @@ static INT __dspMmapReadWrite (PLW_FD_ENTRY pFdEntry,
static INT __dspUnMapRead (PLW_FD_ENTRY pFdEntry,
PLW_DEV_MMAP_AREA pMmapArea)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- pDspDev->DSP_bReadMmaped = LW_FALSE;
+ pDspDev->DSP_bReadMmaped = LW_FALSE; /* 设置 mmap read 标志无效 */
return (ERROR_NONE);
}
@@ -1415,9 +1603,9 @@ static INT __dspUnMapRead (PLW_FD_ENTRY pFdEntry,
static INT __dspUnMapWrite (PLW_FD_ENTRY pFdEntry,
PLW_DEV_MMAP_AREA pMmapArea)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- pDspDev->DSP_bWriteMmaped = LW_FALSE;
+ pDspDev->DSP_bWriteMmaped = LW_FALSE; /* 设置 mmap write 标志无效 */
return (ERROR_NONE);
}
@@ -1433,14 +1621,14 @@ static INT __dspUnMapWrite (PLW_FD_ENTRY pFdEntry,
static INT __dspUnMapReadWrite (PLW_FD_ENTRY pFdEntry,
PLW_DEV_MMAP_AREA pMmapArea)
{
- __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ __PDSP_DEV pDspDev = (__PDSP_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- if (!(LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag)) {
- return (__dspUnMapRead(pFdEntry, pMmapArea));
+ if (!(LW_VMM_FLAG_WRITABLE & pMmapArea->DMAP_ulFlag)) { /* 如果没有请求 mmap write */
+ return (__dspUnMapRead(pFdEntry, pMmapArea)); /* unmap read */
}
- pDspDev->DSP_bReadMmaped = LW_FALSE;
- pDspDev->DSP_bWriteMmaped = LW_FALSE;
+ pDspDev->DSP_bReadMmaped = LW_FALSE; /* 设置 mmap read 标志无效 */
+ pDspDev->DSP_bWriteMmaped = LW_FALSE; /* 设置 mmap write 标志无效 */
return (ERROR_NONE);
}
@@ -1458,6 +1646,9 @@ static INT __dspMmap (PLW_FD_ENTRY pFdEntry,
{
INT iFlags;
+ /*
+ * 参数检查
+ */
if (!pMmapArea) {
_ErrorHandle(EINVAL);
return (PX_ERROR);
@@ -1473,8 +1664,10 @@ static INT __dspMmap (PLW_FD_ENTRY pFdEntry,
return (PX_ERROR);
}
+ /*
+ * 根据读写权限进行映射
+ */
iFlags = pFdEntry->FDENTRY_iFlag & O_ACCMODE;
-
switch (iFlags) {
case O_RDONLY:
return (__dspMmapRead(pFdEntry, pMmapArea));
@@ -1506,6 +1699,9 @@ static INT __dspUnMap (PLW_FD_ENTRY pFdEntry,
{
INT iFlags;
+ /*
+ * 参数检查
+ */
if (!pMmapArea) {
_ErrorHandle(EINVAL);
return (PX_ERROR);
@@ -1521,8 +1717,10 @@ static INT __dspUnMap (PLW_FD_ENTRY pFdEntry,
return (PX_ERROR);
}
+ /*
+ * 根据读写权限进行取消映射
+ */
iFlags = pFdEntry->FDENTRY_iFlag & O_ACCMODE;
-
switch (iFlags) {
case O_RDONLY:
return (__dspUnMapRead(pFdEntry, pMmapArea));
diff --git a/SylixOS/driver/audio/dsp/dspDrv.h b/SylixOS/driver/audio/dsp/dspDrv.h
index 48a51b2..9fc0405 100644
--- a/SylixOS/driver/audio/dsp/dspDrv.h
+++ b/SylixOS/driver/audio/dsp/dspDrv.h
@@ -1,53 +1,57 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: dspDrv.h
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 23 日
-**
-** 描 述: DSP 驱动
-*********************************************************************************************************/
-#ifndef DSPDRV_H_
-#define DSPDRV_H_
-/*********************************************************************************************************
- 定义
-*********************************************************************************************************/
-#define __DSP_DEFAULT_FRAGMENT_NUM 10
-#define __DSP_DEFAULT_FRAGMENT_SIZE (10 * 1024)
-#define __DSP_MAX_FRAGMENT_NUM 100
-/*********************************************************************************************************
-** 函数名称: dspDrv
-** 功能描述: 安装 DSP 驱动
-** 输 入 : NONE
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-INT dspDrv(VOID);
-/*********************************************************************************************************
-** 函数名称: dspDevAdd
-** 功能描述: 创建 DSP 设备
-** 输 入 : pcName 设备名
-** pCodecDev 音频 Codec 设备
-** pCodecDevEntry 音频 Codec 设备驱动
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-INT dspDevAdd(CPCHAR pcName, PLW_DEV_HDR pCodecDev, PLW_DEV_ENTRY pCodecDevEntry);
-
-#endif /* DSPDRV_H_ */
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: dspDrv.h
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 23 日
+**
+** 描 述: DSP 驱动
+*********************************************************************************************************/
+#ifndef DSPDRV_H_
+#define DSPDRV_H_
+/*********************************************************************************************************
+ 定义
+*********************************************************************************************************/
+#define __DSP_MIN_FRAGMENT_NUM (2)
+#define __DSP_DEFAULT_FRAGMENT_NUM (4)
+#define __DSP_MAX_FRAGMENT_NUM (32)
+
+#define __DSP_MIN_FRAGMENT_SIZE (1024)
+#define __DSP_DEFAULT_FRAGMENT_SIZE (8 * 1024)
+#define __DSP_MAX_FRAGMENT_SIZE (64 * 1024)
+/*********************************************************************************************************
+** 函数名称: dspDrv
+** 功能描述: 安装 DSP 驱动
+** 输 入 : NONE
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+INT dspDrv(VOID);
+/*********************************************************************************************************
+** 函数名称: dspDevAdd
+** 功能描述: 创建 DSP 设备
+** 输 入 : pcName 设备名
+** pCodecDev 音频 Codec 设备
+** pCodecDevEntry 音频 Codec 设备驱动
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+INT dspDevAdd(CPCHAR pcName, PLW_DEV_HDR pCodecDev, PLW_DEV_ENTRY pCodecDevEntry);
+
+#endif /* DSPDRV_H_ */
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/audio/mixer/mixerDrv.c b/SylixOS/driver/audio/mixer/mixerDrv.c
index f738abd..ddf751b 100644
--- a/SylixOS/driver/audio/mixer/mixerDrv.c
+++ b/SylixOS/driver/audio/mixer/mixerDrv.c
@@ -1,294 +1,294 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: mixerDrv.c
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 23 日
-**
-** 描 述: MIXER 驱动
-*********************************************************************************************************/
-#define __SYLIXOS_KERNEL
-#include "SylixOS.h"
-#include "string.h"
-#include "system/include/s_class.h"
-/*********************************************************************************************************
- MIXER 设备类型定义
-*********************************************************************************************************/
-typedef struct {
- LW_DEV_HDR MIXER_devHdr;
- LW_LIST_LINE_HEADER MIXER_fdNodeHeader;
- time_t MIXER_time;
- PLW_DEV_HDR MIXER_pCodecDev;
- PLW_DEV_ENTRY MIXER_pCodecDevEntry;
-} __MIXER_DEV, *__PMIXER_DEV;
-/*********************************************************************************************************
- 全局变量
-*********************************************************************************************************/
-static INT _G_iMixerDrvNum = PX_ERROR;
-/*********************************************************************************************************
-** 函数名称: __mixerOpen
-** 功能描述: 打开 MIXER 设备
-** 输 入 : pDev 设备
-** pcName 设备名字
-** iFlags 标志
-** iMode 模式
-** 输 出 : 文件节点
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static LONG __mixerOpen (PLW_DEV_HDR pDev,
- PCHAR pcName,
- INT iFlags,
- INT iMode)
-{
- PLW_FD_NODE pFdNode;
- BOOL bIsNew;
- __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pDev;
-
- if (pcName == LW_NULL) {
- _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);
- return (PX_ERROR);
-
- } else {
- pFdNode = API_IosFdNodeAdd(&pMixerDev->MIXER_fdNodeHeader,
- (dev_t)pMixerDev, 0,
- iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
- if (pFdNode == LW_NULL) {
- printk(KERN_ERR "__mixerOpen(): failed to add fd node!\n");
- return (PX_ERROR);
- }
-
- LW_DEV_INC_USE_COUNT(&pMixerDev->MIXER_devHdr);
-
- return ((LONG)pFdNode);
- }
-}
-/*********************************************************************************************************
-** 函数名称: __mixerClose
-** 功能描述: 关闭 MIXER 设备
-** 输 入 : pFdEntry 文件结构
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __mixerClose (PLW_FD_ENTRY pFdEntry)
-{
- __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- PLW_FD_NODE pFdNode = (PLW_FD_NODE)pFdEntry->FDENTRY_pfdnode;
-
- if (pFdEntry && pFdNode) {
- API_IosFdNodeDec(&pMixerDev->MIXER_fdNodeHeader, pFdNode);
-
- LW_DEV_DEC_USE_COUNT(&pMixerDev->MIXER_devHdr);
-
- return (ERROR_NONE);
- }
-
- return (PX_ERROR);
-}
-/*********************************************************************************************************
-** 函数名称: __mixerLstat
-** 功能描述: 获得 MIXER 设备状态
-** 输 入 : pDev 设备
-** pcName 设备名字
-** pStat stat 结构指针
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __mixerLstat (PLW_DEV_HDR pDev,
- PCHAR pcName,
- struct stat *pStat)
-{
- __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pDev;
-
- if (pStat) {
- pStat->st_dev = (dev_t)pMixerDev;
- pStat->st_ino = (ino_t)0;
- pStat->st_mode = (S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH);
- pStat->st_nlink = 1;
- pStat->st_uid = 0;
- pStat->st_gid = 0;
- pStat->st_rdev = 0;
- pStat->st_size = 0;
- pStat->st_blksize = 0;
- pStat->st_blocks = 0;
- pStat->st_atime = pMixerDev->MIXER_time;
- pStat->st_mtime = pMixerDev->MIXER_time;
- pStat->st_ctime = pMixerDev->MIXER_time;
- return (ERROR_NONE);
- }
-
- return (PX_ERROR);
-}
-/*********************************************************************************************************
-** 函数名称: __mixerIoctl
-** 功能描述: 控制 MIXER 设备
-** 输 入 : pFdEntry 文件结构
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __mixerIoctl (PLW_FD_ENTRY pFdEntry,
- INT iCmd,
- LONG lArg)
-{
- __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
- struct stat *pStat;
- FUNCPTR pfuncDrvIoctl;
-
- switch (iCmd) {
-
- case FIOFSTATGET:
- pStat = (struct stat *)lArg;
- if (pStat) {
- pStat->st_dev = (dev_t)pMixerDev;
- pStat->st_ino = (ino_t)0;
- pStat->st_mode = (S_IRUSR | S_IRGRP | S_IROTH);
- pStat->st_nlink = 1;
- pStat->st_uid = 0;
- pStat->st_gid = 0;
- pStat->st_rdev = 0;
- pStat->st_size = 0;
- pStat->st_blksize = 0;
- pStat->st_blocks = 0;
- pStat->st_atime = pMixerDev->MIXER_time;
- pStat->st_mtime = pMixerDev->MIXER_time;
- pStat->st_ctime = pMixerDev->MIXER_time;
- return (ERROR_NONE);
- }
- return (PX_ERROR);
-
- case FIOSETFL:
- if ((int)lArg & O_NONBLOCK) {
- pFdEntry->FDENTRY_iFlag |= O_NONBLOCK;
- } else {
- pFdEntry->FDENTRY_iFlag &= ~O_NONBLOCK;
- }
- return (ERROR_NONE);
-
- default:
- if (LW_DEV_GET_USE_COUNT(pMixerDev->MIXER_pCodecDev) == 0) {
- printk(KERN_ERR "__mixerIoctl(): codec has NOT initialized!\n");
- return (PX_ERROR);
- }
-
- pfuncDrvIoctl = pMixerDev->MIXER_pCodecDevEntry->DEVENTRY_pfuncDevIoctl;
- if (pfuncDrvIoctl) {
- return (pfuncDrvIoctl(pMixerDev->MIXER_pCodecDev, iCmd, lArg));
- } else {
- _ErrorHandle(ENOSYS);
- return (PX_ERROR);
- }
- break;
- }
-}
-/*********************************************************************************************************
-** 函数名称: mixerDrv
-** 功能描述: 安装 MIXER 驱动
-** 输 入 : NONE
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-INT mixerDrv (VOID)
-{
- struct file_operations fileOper;
-
- if (_G_iMixerDrvNum >= 0) {
- return (ERROR_NONE);
- }
-
- lib_memset(&fileOper, 0, sizeof(struct file_operations));
-
- fileOper.owner = THIS_MODULE;
- fileOper.fo_create = __mixerOpen;
- fileOper.fo_open = __mixerOpen;
- fileOper.fo_close = __mixerClose;
- fileOper.fo_lstat = __mixerLstat;
- fileOper.fo_ioctl = __mixerIoctl;
-
- _G_iMixerDrvNum = iosDrvInstallEx2(&fileOper, LW_DRV_TYPE_NEW_1);
-
- DRIVER_LICENSE(_G_iMixerDrvNum, "Dual BSD/GPL->Ver 1.0");
- DRIVER_AUTHOR(_G_iMixerDrvNum, "Jiao.JinXing");
- DRIVER_DESCRIPTION(_G_iMixerDrvNum, "oss mixer driver.");
-
- return ((_G_iMixerDrvNum > 0) ? (ERROR_NONE) : (PX_ERROR));
-}
-/*********************************************************************************************************
-** 函数名称: mixerDevAdd
-** 功能描述: 创建 MIXER 设备
-** 输 入 : pcName 设备名
-** pCodecDev 音频 Codec 设备
-** pCodecDevEntry 音频 Codec 设备驱动
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-INT mixerDevAdd (CPCHAR pcName, PLW_DEV_HDR pCodecDev, PLW_DEV_ENTRY pCodecDevEntry)
-{
- __PMIXER_DEV pMixerDev = LW_NULL;
-
- if (pcName == LW_NULL) {
- printk(KERN_ERR "mixerDevAdd(): device name invalid.\n");
- goto __error_handle;
- }
-
- if (pCodecDev == LW_NULL) {
- printk(KERN_ERR "mixerDevAdd(): codec device invalid.\n");
- goto __error_handle;
- }
-
- if (pCodecDevEntry == LW_NULL) {
- printk(KERN_ERR "mixerDevAdd(): codec device driver invalid.\n");
- goto __error_handle;
- }
-
- pMixerDev = (__PMIXER_DEV)__SHEAP_ZALLOC(sizeof(__MIXER_DEV));
- if (pMixerDev == LW_NULL) {
- printk(KERN_ERR "mixerDevAdd(): failed to alloc mixer device struct.\n");
- goto __error_handle;
- }
-
- pMixerDev->MIXER_time = time(LW_NULL);
-
- pMixerDev->MIXER_pCodecDev = pCodecDev;
-
- pMixerDev->MIXER_pCodecDevEntry = pCodecDevEntry;
-
- if (API_IosDevAddEx(&pMixerDev->MIXER_devHdr,
- pcName,
- _G_iMixerDrvNum,
- DT_CHR) != ERROR_NONE) {
- printk(KERN_ERR "mixerDevAdd(): can not add device : %s.\n", strerror(errno));
- goto __error_handle;
- }
-
- return (ERROR_NONE);
-
- __error_handle:
-
- if (pMixerDev) {
- __SHEAP_FREE(pMixerDev);
- pMixerDev = LW_NULL;
- }
-
- return (PX_ERROR);
-}
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: mixerDrv.c
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 23 日
+**
+** 描 述: MIXER 驱动
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "SylixOS.h"
+#include "string.h"
+#include "system/include/s_class.h"
+/*********************************************************************************************************
+ MIXER 设备类型定义
+*********************************************************************************************************/
+typedef struct {
+ LW_DEV_HDR MIXER_devHdr;
+ LW_LIST_LINE_HEADER MIXER_fdNodeHeader;
+ time_t MIXER_time;
+ PLW_DEV_HDR MIXER_pCodecDev;
+ PLW_DEV_ENTRY MIXER_pCodecDevEntry;
+} __MIXER_DEV, *__PMIXER_DEV;
+/*********************************************************************************************************
+ 全局变量
+*********************************************************************************************************/
+static INT _G_iMixerDrvNum = PX_ERROR;
+/*********************************************************************************************************
+** 函数名称: __mixerOpen
+** 功能描述: 打开 MIXER 设备
+** 输 入 : pDev 设备
+** pcName 设备名字
+** iFlags 标志
+** iMode 模式
+** 输 出 : 文件节点
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static LONG __mixerOpen (PLW_DEV_HDR pDev,
+ PCHAR pcName,
+ INT iFlags,
+ INT iMode)
+{
+ PLW_FD_NODE pFdNode;
+ BOOL bIsNew;
+ __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pDev;
+
+ if (pcName == LW_NULL) {
+ _ErrorHandle(ERROR_IO_NO_DEVICE_NAME_IN_PATH);
+ return (PX_ERROR);
+
+ } else {
+ pFdNode = API_IosFdNodeAdd(&pMixerDev->MIXER_fdNodeHeader,
+ (dev_t)pMixerDev, 0,
+ iFlags, iMode, 0, 0, 0, LW_NULL, &bIsNew);
+ if (pFdNode == LW_NULL) {
+ printk(KERN_ERR "__mixerOpen(): failed to add fd node!\n");
+ return (PX_ERROR);
+ }
+
+ LW_DEV_INC_USE_COUNT(&pMixerDev->MIXER_devHdr);
+
+ return ((LONG)pFdNode);
+ }
+}
+/*********************************************************************************************************
+** 函数名称: __mixerClose
+** 功能描述: 关闭 MIXER 设备
+** 输 入 : pFdEntry 文件结构
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __mixerClose (PLW_FD_ENTRY pFdEntry)
+{
+ __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ PLW_FD_NODE pFdNode = (PLW_FD_NODE)pFdEntry->FDENTRY_pfdnode;
+
+ if (pFdEntry && pFdNode) {
+ API_IosFdNodeDec(&pMixerDev->MIXER_fdNodeHeader, pFdNode);
+
+ LW_DEV_DEC_USE_COUNT(&pMixerDev->MIXER_devHdr);
+
+ return (ERROR_NONE);
+ }
+
+ return (PX_ERROR);
+}
+/*********************************************************************************************************
+** 函数名称: __mixerLstat
+** 功能描述: 获得 MIXER 设备状态
+** 输 入 : pDev 设备
+** pcName 设备名字
+** pStat stat 结构指针
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __mixerLstat (PLW_DEV_HDR pDev,
+ PCHAR pcName,
+ struct stat *pStat)
+{
+ __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pDev;
+
+ if (pStat) {
+ pStat->st_dev = (dev_t)pMixerDev;
+ pStat->st_ino = (ino_t)0;
+ pStat->st_mode = (S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH);
+ pStat->st_nlink = 1;
+ pStat->st_uid = 0;
+ pStat->st_gid = 0;
+ pStat->st_rdev = 0;
+ pStat->st_size = 0;
+ pStat->st_blksize = 0;
+ pStat->st_blocks = 0;
+ pStat->st_atime = pMixerDev->MIXER_time;
+ pStat->st_mtime = pMixerDev->MIXER_time;
+ pStat->st_ctime = pMixerDev->MIXER_time;
+ return (ERROR_NONE);
+ }
+
+ return (PX_ERROR);
+}
+/*********************************************************************************************************
+** 函数名称: __mixerIoctl
+** 功能描述: 控制 MIXER 设备
+** 输 入 : pFdEntry 文件结构
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __mixerIoctl (PLW_FD_ENTRY pFdEntry,
+ INT iCmd,
+ LONG lArg)
+{
+ __PMIXER_DEV pMixerDev = (__PMIXER_DEV)pFdEntry->FDENTRY_pdevhdrHdr;
+ struct stat *pStat;
+ FUNCPTR pfuncDrvIoctl;
+
+ switch (iCmd) {
+
+ case FIOFSTATGET:
+ pStat = (struct stat *)lArg;
+ if (pStat) {
+ pStat->st_dev = (dev_t)pMixerDev;
+ pStat->st_ino = (ino_t)0;
+ pStat->st_mode = (S_IRUSR | S_IRGRP | S_IROTH);
+ pStat->st_nlink = 1;
+ pStat->st_uid = 0;
+ pStat->st_gid = 0;
+ pStat->st_rdev = 0;
+ pStat->st_size = 0;
+ pStat->st_blksize = 0;
+ pStat->st_blocks = 0;
+ pStat->st_atime = pMixerDev->MIXER_time;
+ pStat->st_mtime = pMixerDev->MIXER_time;
+ pStat->st_ctime = pMixerDev->MIXER_time;
+ return (ERROR_NONE);
+ }
+ return (PX_ERROR);
+
+ case FIOSETFL:
+ if ((int)lArg & O_NONBLOCK) {
+ pFdEntry->FDENTRY_iFlag |= O_NONBLOCK;
+ } else {
+ pFdEntry->FDENTRY_iFlag &= ~O_NONBLOCK;
+ }
+ return (ERROR_NONE);
+
+ default:
+ if (LW_DEV_GET_USE_COUNT(pMixerDev->MIXER_pCodecDev) == 0) {
+ printk(KERN_ERR "__mixerIoctl(): codec has NOT initialized!\n");
+ return (PX_ERROR);
+ }
+
+ pfuncDrvIoctl = pMixerDev->MIXER_pCodecDevEntry->DEVENTRY_pfuncDevIoctl;
+ if (pfuncDrvIoctl) {
+ return (pfuncDrvIoctl(pMixerDev->MIXER_pCodecDev, iCmd, lArg));
+ } else {
+ _ErrorHandle(ENOSYS);
+ return (PX_ERROR);
+ }
+ break;
+ }
+}
+/*********************************************************************************************************
+** 函数名称: mixerDrv
+** 功能描述: 安装 MIXER 驱动
+** 输 入 : NONE
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+INT mixerDrv (VOID)
+{
+ struct file_operations fileOper;
+
+ if (_G_iMixerDrvNum >= 0) {
+ return (ERROR_NONE);
+ }
+
+ lib_memset(&fileOper, 0, sizeof(struct file_operations));
+
+ fileOper.owner = THIS_MODULE;
+ fileOper.fo_create = __mixerOpen;
+ fileOper.fo_open = __mixerOpen;
+ fileOper.fo_close = __mixerClose;
+ fileOper.fo_lstat = __mixerLstat;
+ fileOper.fo_ioctl = __mixerIoctl;
+
+ _G_iMixerDrvNum = iosDrvInstallEx2(&fileOper, LW_DRV_TYPE_NEW_1);
+
+ DRIVER_LICENSE(_G_iMixerDrvNum, "Dual BSD/GPL->Ver 1.0");
+ DRIVER_AUTHOR(_G_iMixerDrvNum, "Jiao.JinXing");
+ DRIVER_DESCRIPTION(_G_iMixerDrvNum, "oss mixer driver.");
+
+ return ((_G_iMixerDrvNum > 0) ? (ERROR_NONE) : (PX_ERROR));
+}
+/*********************************************************************************************************
+** 函数名称: mixerDevAdd
+** 功能描述: 创建 MIXER 设备
+** 输 入 : pcName 设备名
+** pCodecDev 音频 Codec 设备
+** pCodecDevEntry 音频 Codec 设备驱动
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+INT mixerDevAdd (CPCHAR pcName, PLW_DEV_HDR pCodecDev, PLW_DEV_ENTRY pCodecDevEntry)
+{
+ __PMIXER_DEV pMixerDev = LW_NULL;
+
+ if (pcName == LW_NULL) {
+ printk(KERN_ERR "mixerDevAdd(): device name invalid.\n");
+ goto __error_handle;
+ }
+
+ if (pCodecDev == LW_NULL) {
+ printk(KERN_ERR "mixerDevAdd(): codec device invalid.\n");
+ goto __error_handle;
+ }
+
+ if (pCodecDevEntry == LW_NULL) {
+ printk(KERN_ERR "mixerDevAdd(): codec device driver invalid.\n");
+ goto __error_handle;
+ }
+
+ pMixerDev = (__PMIXER_DEV)__SHEAP_ZALLOC(sizeof(__MIXER_DEV));
+ if (pMixerDev == LW_NULL) {
+ printk(KERN_ERR "mixerDevAdd(): failed to alloc mixer device struct.\n");
+ goto __error_handle;
+ }
+
+ pMixerDev->MIXER_time = time(LW_NULL);
+
+ pMixerDev->MIXER_pCodecDev = pCodecDev;
+
+ pMixerDev->MIXER_pCodecDevEntry = pCodecDevEntry;
+
+ if (API_IosDevAddEx(&pMixerDev->MIXER_devHdr,
+ pcName,
+ _G_iMixerDrvNum,
+ DT_CHR) != ERROR_NONE) {
+ printk(KERN_ERR "mixerDevAdd(): can not add device : %s.\n", strerror(errno));
+ goto __error_handle;
+ }
+
+ return (ERROR_NONE);
+
+ __error_handle:
+
+ if (pMixerDev) {
+ __SHEAP_FREE(pMixerDev);
+ pMixerDev = LW_NULL;
+ }
+
+ return (PX_ERROR);
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/audio/oss_test.c b/SylixOS/driver/audio/oss_test.c
index 1cf745e..05564d7 100644
--- a/SylixOS/driver/audio/oss_test.c
+++ b/SylixOS/driver/audio/oss_test.c
@@ -1,146 +1,146 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: oss_test.c
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 02 月 05 日
-**
-** 描 述: OSS 驱动测试程序
-*********************************************************************************************************/
-#include "unistd.h"
-#include "stdlib.h"
-#include "sys/soundcard.h"
-#include "pthread.h"
-/*********************************************************************************************************
- 定义
-*********************************************************************************************************/
-#define __OSS_TEST_BUFFER_LEN 10 * 1024
-#define __OSS_TEST_WAV_FILE "/apps/wo.wav"
-#define __OSS_TEST_SAMPLE_RATE 11025
-#define __OSS_TEST_CHANNELS 2
-#define __OSS_TEST_SAMPLE_FORMAT AFMT_S16_LE
-/*********************************************************************************************************
-** 函数名称: pthread_test
-** 功能描述: OSS 测试 pthread 线程
-** 输 入 : pvArg 线程参数
-** 输 出 : 线程返回值
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID *pthread_test(VOID *pvArg)
-{
- ssize_t stLen;
- ssize_t stRet;
- CHAR *pcBuffer;
- CHAR *pcPtr;
- INT iSampleFmt;
- INT iChannels;
- INT iSampleRate;
- INT iDspFd;
- INT iFileFd;
-
- pthread_setschedprio(pthread_self(), LW_PRIO_LOWEST - 149);
-
- while (1) {
-
- pcBuffer = malloc(__OSS_TEST_BUFFER_LEN);
- if (!pcBuffer) {
- printf("failed to alloc buffer!\n");
- return (NULL);
- }
-
- iDspFd = open("/dev/dsp", O_WRONLY, 0666);
- if (iDspFd < 0) {
- printf("failed to open /dev/dsp device!\n");
- break;
- }
-
- iSampleFmt = __OSS_TEST_SAMPLE_FORMAT;
- stRet = ioctl(iDspFd, SNDCTL_DSP_SETFMT, &iSampleFmt);
- if (stRet < 0) {
- printf("failed to set sample format!\n");
- close(iDspFd);
- break;
- }
-
- iChannels = __OSS_TEST_CHANNELS;
- stRet = ioctl(iDspFd, SNDCTL_DSP_CHANNELS, &iChannels);
- if (stRet < 0) {
- printf("failed to set channels!\n");
- close(iDspFd);
- break;
- }
-
- iSampleRate = __OSS_TEST_SAMPLE_RATE;
- stRet = ioctl(iDspFd, SNDCTL_DSP_SPEED, &iSampleRate);
- if (stRet < 0) {
- printf("failed to set sample rate!\n");
- close(iDspFd);
- break;
- }
-
- iFileFd = open(__OSS_TEST_WAV_FILE, O_RDONLY, 0666);
- if (iFileFd < 0) {
- printf("failed to open test audio file %s!\n", __OSS_TEST_WAV_FILE);
- close(iDspFd);
- break;
- }
-
- read(iFileFd, pcBuffer, 0x2E * 2);
-
- while ((stLen = read(iFileFd, pcBuffer, __OSS_TEST_BUFFER_LEN)) > 0) {
-
- pcPtr = pcBuffer;
-
- while (stLen > 0) {
- stRet = write(iDspFd, pcPtr, stLen);
- if (stRet < 0) {
- break;
- }
- pcPtr += stRet;
- stLen -= stRet;
- }
- }
-
- sleep(3);
-
- close(iFileFd);
-
- close(iDspFd);
-
- free(pcBuffer);
- }
-
- return (NULL);
-}
-/*********************************************************************************************************
-** 函数名称: ossTestStart
-** 功能描述: OSS 测试
-** 输 入 : NONE
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-INT ossTestStart (VOID)
-{
- pthread_t tid;
- INT iError;
-
- iError = pthread_create(&tid, NULL, pthread_test, NULL);
-
- return (iError == 0 ? ERROR_NONE : PX_ERROR);
-}
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: oss_test.c
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 02 月 05 日
+**
+** 描 述: OSS 驱动测试程序
+*********************************************************************************************************/
+#include "unistd.h"
+#include "stdlib.h"
+#include "sys/soundcard.h"
+#include "pthread.h"
+/*********************************************************************************************************
+ 定义
+*********************************************************************************************************/
+#define __OSS_TEST_BUFFER_LEN 10 * 1024
+#define __OSS_TEST_WAV_FILE "/apps/wo.wav"
+#define __OSS_TEST_SAMPLE_RATE 22050
+#define __OSS_TEST_CHANNELS 2
+#define __OSS_TEST_SAMPLE_FORMAT AFMT_S16_LE
+/*********************************************************************************************************
+** 函数名称: pthread_test
+** 功能描述: OSS 测试 pthread 线程
+** 输 入 : pvArg 线程参数
+** 输 出 : 线程返回值
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID *pthread_test(VOID *pvArg)
+{
+ ssize_t stLen;
+ ssize_t stRet;
+ CHAR *pcBuffer;
+ CHAR *pcPtr;
+ INT iSampleFmt;
+ INT iChannels;
+ INT iSampleRate;
+ INT iDspFd;
+ INT iFileFd;
+
+ pthread_setschedprio(pthread_self(), LW_PRIO_LOWEST - 149);
+
+ while (1) {
+
+ pcBuffer = malloc(__OSS_TEST_BUFFER_LEN);
+ if (!pcBuffer) {
+ printf("failed to alloc buffer!\n");
+ return (NULL);
+ }
+
+ iDspFd = open("/dev/dsp", O_WRONLY, 0666);
+ if (iDspFd < 0) {
+ printf("failed to open /dev/dsp device!\n");
+ break;
+ }
+
+ iSampleFmt = __OSS_TEST_SAMPLE_FORMAT;
+ stRet = ioctl(iDspFd, SNDCTL_DSP_SETFMT, &iSampleFmt);
+ if (stRet < 0) {
+ printf("failed to set sample format!\n");
+ close(iDspFd);
+ break;
+ }
+
+ iChannels = __OSS_TEST_CHANNELS;
+ stRet = ioctl(iDspFd, SNDCTL_DSP_CHANNELS, &iChannels);
+ if (stRet < 0) {
+ printf("failed to set channels!\n");
+ close(iDspFd);
+ break;
+ }
+
+ iSampleRate = __OSS_TEST_SAMPLE_RATE;
+ stRet = ioctl(iDspFd, SNDCTL_DSP_SPEED, &iSampleRate);
+ if (stRet < 0) {
+ printf("failed to set sample rate!\n");
+ close(iDspFd);
+ break;
+ }
+
+ iFileFd = open(__OSS_TEST_WAV_FILE, O_RDONLY, 0666);
+ if (iFileFd < 0) {
+ printf("failed to open test audio file %s!\n", __OSS_TEST_WAV_FILE);
+ close(iDspFd);
+ break;
+ }
+
+ read(iFileFd, pcBuffer, 0x2E * 2);
+
+ while ((stLen = read(iFileFd, pcBuffer, __OSS_TEST_BUFFER_LEN)) > 0) {
+
+ pcPtr = pcBuffer;
+
+ while (stLen > 0) {
+ stRet = write(iDspFd, pcPtr, stLen);
+ if (stRet < 0) {
+ break;
+ }
+ pcPtr += stRet;
+ stLen -= stRet;
+ }
+ }
+
+ sleep(3);
+
+ close(iFileFd);
+
+ close(iDspFd);
+
+ free(pcBuffer);
+ }
+
+ return (NULL);
+}
+/*********************************************************************************************************
+** 函数名称: ossTestStart
+** 功能描述: OSS 测试
+** 输 入 : NONE
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+INT ossTestStart (VOID)
+{
+ pthread_t tid;
+ INT iError;
+
+ iError = pthread_create(&tid, NULL, pthread_test, NULL);
+
+ return (iError == 0 ? ERROR_NONE : PX_ERROR);
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/dma/am335x_dma.c b/SylixOS/driver/dma/am335x_dma.c
index e721428..245b660 100644
--- a/SylixOS/driver/dma/am335x_dma.c
+++ b/SylixOS/driver/dma/am335x_dma.c
@@ -1,795 +1,781 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: am335x_dma.c
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 17 日
-**
-** 描 述: AM335X 处理器 DMA 驱动
-*********************************************************************************************************/
-#define __SYLIXOS_KERNEL
-#include "config.h"
-#include "SylixOS.h"
-
-#include "driver/am335x_common.h"
-#include "edma.h"
-#include "am335x_dma.h"
-
-#if SOC_EDMA3_NUM_DMACH != DMA_CHANNEL_NR
-#error DMA_CHANNEL_NR != SOC_EDMA3_NUM_DMACH
-#endif
-/*********************************************************************************************************
- 定义
-*********************************************************************************************************/
-#define __EDMA3_CONTROLER_NR (1) /* DMA 控制器数目 */
-#define __EDMA3_CHANNEL_NR SOC_EDMA3_NUM_DMACH /* DMA 通道数目 */
-#define __EDMA3_DEFAULT_EVTQ (1) /* EDMA3 Event queue number */
-#define __EDMA3_DUMMY_CH_NUM (5) /* DMA 伪通道号 */
-/*********************************************************************************************************
- DMA 控制器类型定义
-*********************************************************************************************************/
-typedef struct {
- addr_t DMAC_ulPhyAddrBase; /* 物理地址基地址 */
- size_t DMAC_stPhyAddrSize; /* 物理地址空间大小 */
- ULONG DMAC_ulCompVector; /* DMA 完成中断向量 */
- UINT DMAC_uiCompIntPriority; /* DMA 完成中断优先级 */
- ULONG DMAC_ulErrorVector; /* DMA 出错中断向量 */
- UINT DMAC_uiErrorIntPriority; /* DMA 出错中断优先级 */
-
- addr_t DMAC_ulVirtAddrBase; /* 虚拟地址基地址 */
- UINT DMAC_uiTrigMode[__EDMA3_CHANNEL_NR]; /* 各通道触发模式 */
-#if BSP_CFG_DMA_PERF_EN > 0
- atomic_t DMAC_atomicIntCounter[__EDMA3_CHANNEL_NR]; /* 各通道中断次数 */
-#endif
- BOOL DMAC_bIsInit; /* 是否已经初始化 */
- LW_SPINLOCK_DEFINE(DMAC_splLock);
-} __AM335X_DMA_CONTROLER, *__PAM335X_DMA_CONTROLER;
-/*********************************************************************************************************
- 全局变量
-*********************************************************************************************************/
-static __AM335X_DMA_CONTROLER _G_am335xDmaControlers[__EDMA3_CONTROLER_NR] = {
- {
- SOC_EDMA30CC_0_REGS,
- 11 * LW_CFG_MB_SIZE,
- SYS_INT_EDMACOMPINT,
- BSP_CFG_EDMA3_COMP_INT_PRIO,
- SYS_INT_EDMAERRINT,
- BSP_CFG_EDMA3_ERR_INT_PRIO,
- }
-};
-/*********************************************************************************************************
-** 函数名称: __am335xEdmaEventQueue
-** 功能描述: 根据 DMA 通道号获得事件队列号
-** 输 入 : uiChannel DMA 通道号
-** 输 出 : 事件队列号
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static UINT __am335xEdmaEventQueue (UINT uiChannel)
-{
- switch (uiChannel) {
- case EDMA3_CHA_MCASP0_TX:
- case EDMA3_CHA_MCASP1_TX:
- case EDMA3_CHA_MCASP0_RX:
- case EDMA3_CHA_MCASP1_RX:
- return (0);
-
- default:
- return (__EDMA3_DEFAULT_EVTQ);
- }
-}
-/*********************************************************************************************************
-** 函数名称: __am335xEdma3Done
-** 功能描述: DMA 完成
-** 输 入 : pDmaControler DMA 控制器
-** uiChannel DMA 通道号
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xEdma3Done (__PAM335X_DMA_CONTROLER pDmaControler, UINT uiChannel)
-{
- EDMA3CCPaRAMEntry paramSet;
-
- EDMA3GetPaRAM(pDmaControler->DMAC_ulVirtAddrBase, uiChannel, &paramSet);
-
- if (paramSet.cCnt || paramSet.bCnt || paramSet.aCnt || paramSet.bCntReload) {
- if (pDmaControler->DMAC_uiTrigMode[uiChannel] == EDMA3_TRIG_MODE_MANUAL) {
- EDMA3EnableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
- uiChannel,
- pDmaControler->DMAC_uiTrigMode[uiChannel]);
- }
- } else {
- if (pDmaControler->DMAC_uiTrigMode[uiChannel] == EDMA3_TRIG_MODE_EVENT) {
- EDMA3DisableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
- uiChannel,
- pDmaControler->DMAC_uiTrigMode[uiChannel]);
- }
- API_DmaContext(uiChannel);
- }
-
-#if BSP_CFG_DMA_PERF_EN > 0
- API_AtomicInc(&pDmaControler->DMAC_atomicIntCounter[uiChannel]);
-#endif
-}
-/*********************************************************************************************************
-** 函数名称: __am335xEdma3Error
-** 功能描述: DMA 出错
-** 输 入 : pDmaControler DMA 控制器
-** uiChannel DMA 通道号
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xEdma3Error (__PAM335X_DMA_CONTROLER pDmaControler, UINT uiChannel)
-{
- INT iNum;
-
- printk(KERN_ERR "__am335xEdma3CCErrorIsr(): channel=%d\n", uiChannel);
-
- if (pDmaControler->DMAC_uiTrigMode[uiChannel] == EDMA3_TRIG_MODE_EVENT) {
- EDMA3DisableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
- uiChannel,
- pDmaControler->DMAC_uiTrigMode[uiChannel]);
- }
-
- EDMA3FreeChannel(pDmaControler->DMAC_ulVirtAddrBase,
- EDMA3_CHANNEL_TYPE_DMA,
- uiChannel,
- pDmaControler->DMAC_uiTrigMode[uiChannel],
- uiChannel,
- __am335xEdmaEventQueue(uiChannel));
-
- while ((API_DmaJobNodeNum(uiChannel, &iNum) == ERROR_NONE) && (iNum > 0)) {
- API_DmaContext(uiChannel);
- }
-
- EDMA3RequestChannel(pDmaControler->DMAC_ulVirtAddrBase,
- EDMA3_CHANNEL_TYPE_DMA,
- uiChannel,
- uiChannel,
- __am335xEdmaEventQueue(uiChannel));
-}
-/*********************************************************************************************************
-** 函数名称: __am335xEdma3CompletionIsr
-** 功能描述: DMA 完成中断服务例程
-** 输 入 : pDmaControler DMA 控制器
-** ulVector 中断向量
-** 输 出 : 中断返回值
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static irqreturn_t __am335xEdma3CompletionIsr (__PAM335X_DMA_CONTROLER pDmaControler, ULONG ulVector)
-{
- volatile UINT uiPendingIrqs;
- volatile UINT uiIsIntrPending = 0u;
- volatile UINT uiIsHighIntrPending = 0u;
- UINT uiIndex;
- UINT uiCount = 0u;
-
- uiIndex = 1u;
- uiIsIntrPending = EDMA3GetIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
- uiIsHighIntrPending = EDMA3IntrStatusHighGet(pDmaControler->DMAC_ulVirtAddrBase);
-
- if (uiIsIntrPending | uiIsHighIntrPending) {
- while ((uiCount < EDMA3CC_COMPL_HANDLER_RETRY_COUNT) && (uiIndex != 0u)) {
- uiIndex = 0u;
-
- if (uiIsIntrPending) {
- uiPendingIrqs = EDMA3GetIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
- } else {
- uiPendingIrqs = EDMA3IntrStatusHighGet(pDmaControler->DMAC_ulVirtAddrBase);
- }
-
- while (uiPendingIrqs) {
- if (TRUE == (uiPendingIrqs & 1u)) {
- /*
- * If the user has not given any Callback function
- * while requesting the TCC, its TCC specific bit
- * in the IPR register will NOT be cleared.
- */
- if (uiIsIntrPending) {
- /*
- * Here write to ICR to clear the corresponding
- * IPR bits
- */
- __am335xEdma3Done(pDmaControler, uiIndex);
-
- EDMA3ClrIntr(pDmaControler->DMAC_ulVirtAddrBase, uiIndex);
-
- } else {
- /*
- * Here write to ICR to clear the corresponding
- * IPR bits
- */
- __am335xEdma3Done(pDmaControler, uiIndex + 32);
-
- EDMA3ClrIntr(pDmaControler->DMAC_ulVirtAddrBase, uiIndex + 32u);
- }
- }
- ++uiIndex;
- uiPendingIrqs >>= 1u;
- }
- uiCount++;
- }
- }
-
- return (LW_IRQ_HANDLED);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xEdma3CCErrorIsr
-** 功能描述: DMA 出错中断服务例程
-** 输 入 : pDmaControler DMA 控制器
-** ulVector 中断向量
-** 输 出 : 中断返回值
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static irqreturn_t __am335xEdma3CCErrorIsr (__PAM335X_DMA_CONTROLER pDmaControler, ULONG ulVector)
-{
- volatile UINT uiPendingIrqs;
- volatile UINT uiEvtQueNum = 0u; /* Event Queue Num */
- volatile UINT uiIsHighIntrPending = 0u;
- volatile UINT uiIsIntrPending = 0u;
- volatile UINT uiCount = 0u;
- volatile UINT uiIndex;
-
- uiPendingIrqs = 0u;
- uiIndex = 1u;
-
- uiIsIntrPending = EDMA3GetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
- uiIsHighIntrPending = EDMA3ErrIntrHighStatusGet(pDmaControler->DMAC_ulVirtAddrBase);
-
- if ((uiIsIntrPending | uiIsHighIntrPending)
- || (EDMA3QdmaGetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase) != 0u)
- || (EDMA3GetCCErrStatus(pDmaControler->DMAC_ulVirtAddrBase) != 0u)) {
-
- /*
- * Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time,
- * breaks when no pending interrupt is found
- */
- while ((uiCount < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (uiIndex != 0u)) {
- uiIndex = 0u;
-
- if (uiIsIntrPending) {
- uiPendingIrqs = EDMA3GetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
- } else {
- uiPendingIrqs = EDMA3ErrIntrHighStatusGet(pDmaControler->DMAC_ulVirtAddrBase);
- }
-
- while (uiPendingIrqs) {
- /*
- * Process all the pending interrupts
- */
- if (TRUE == (uiPendingIrqs & 1u)) {
- /*
- * Write to EMCR to clear the corresponding EMR bits.
- * Clear any SER
- */
- if (uiIsIntrPending) {
- EDMA3ClrMissEvt(pDmaControler->DMAC_ulVirtAddrBase, uiIndex);
-
- __am335xEdma3Error(pDmaControler, uiIndex);
- } else {
- EDMA3ClrMissEvt(pDmaControler->DMAC_ulVirtAddrBase, uiIndex + 32u);
-
- __am335xEdma3Error(pDmaControler, uiIndex + 32u);
- }
- }
-
- ++uiIndex;
- uiPendingIrqs >>= 1u;
- }
-
- uiIndex = 0u;
- uiPendingIrqs = EDMA3QdmaGetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
-
- while (uiPendingIrqs) {
- /*
- * Process all the pending interrupts
- */
- if (TRUE == (uiPendingIrqs & 1u)) {
- /*
- * Here write to QEMCR to clear the corresponding QEMR bits
- * Clear any QSER
- */
- EDMA3QdmaClrMissEvt(pDmaControler->DMAC_ulVirtAddrBase, uiIndex);
- }
-
- ++uiIndex;
- uiPendingIrqs >>= 1u;
- }
-
- uiIndex = 0u;
-
- uiPendingIrqs = EDMA3GetCCErrStatus(pDmaControler->DMAC_ulVirtAddrBase);
-
- if (uiPendingIrqs != 0u) {
- /*
- * Process all the pending CC error interrupts.
- * Queue threshold error for different event queues.
- */
- for (uiEvtQueNum = 0u; uiEvtQueNum < SOC_EDMA3_NUM_EVQUE; uiEvtQueNum++) {
- if ((uiPendingIrqs & (1u << uiEvtQueNum)) != 0u) {
- /*
- * Clear the error interrupt.
- */
- EDMA3ClrCCErr(pDmaControler->DMAC_ulVirtAddrBase, (1u << uiEvtQueNum));
- }
- }
-
- /*
- * Transfer completion code error.
- */
- if ((uiPendingIrqs & (1u << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u) {
- EDMA3ClrCCErr(pDmaControler->DMAC_ulVirtAddrBase,
- (1u << EDMA3CC_CCERR_TCCERR_SHIFT));
- }
- ++uiIndex;
- }
- uiCount++;
- }
- } else {
- printk(KERN_EMERG "__am335xEdma3CCErrorIsr(): No Error Found!\n");
-
- return (LW_IRQ_HANDLED_DISV);
- }
-
- return (LW_IRQ_HANDLED);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xDmaReset
-** 功能描述: 初始化 DMA 并停止
-** 输 入 : uiChannel DMA 通道号
-** pDmaFuncs DMA 驱动程序
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xDmaReset (UINT uiChannel, PLW_DMA_FUNCS pDmaFuncs)
-{
- __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
-
- if (uiChannel >= __EDMA3_CHANNEL_NR) {
- return;
- }
-
-#if 0
- EDMA3FreeChannel(pDmaControler->DMAC_ulVirtAddrBase,
- EDMA3_CHANNEL_TYPE_DMA,
- uiChannel,
- pDmaControler->DMAC_uiTrigMode[uiChannel],
- uiChannel,
- __am335xEdmaEventQueue(uiChannel));
-#endif
-
- EDMA3RequestChannel(pDmaControler->DMAC_ulVirtAddrBase,
- EDMA3_CHANNEL_TYPE_DMA,
- uiChannel,
- uiChannel,
- __am335xEdmaEventQueue(uiChannel));
-}
-/*********************************************************************************************************
-** 函数名称: __am335xDmaGetStatus
-** 功能描述: 获得 DMA 当前状态
-** 输 入 : uiChannel DMA 通道号
-** pDmaFuncs DMA 驱动程序
-** 输 出 : 0:空闲 1:忙 PX_ERROR:错误
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xDmaGetStatus (UINT uiChannel, PLW_DMA_FUNCS pDmaFuncs)
-{
- __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
-
- (VOID)pDmaControler;
-
- if (uiChannel >= __EDMA3_CHANNEL_NR) {
- return (PX_ERROR);
- }
-
- if (0) { /* 检测状态 */
- return (LW_DMA_STATUS_BUSY);
- } else {
- return (LW_DMA_STATUS_IDLE);
- }
-}
-/*********************************************************************************************************
-** 函数名称: __am335xDmaTxDummyPaRAMConfEnable
-** 功能描述: 初始化一次伪发送 DMA 传输
-** 输 入 : NONE
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xDmaTxDummyPaRAMConfEnable (__PAM335X_DMA_CONTROLER pDmaControler)
-{
- EDMA3CCPaRAMEntry dummyPaRAMSet;
-
- dummyPaRAMSet.aCnt = 1;
- dummyPaRAMSet.bCnt = 0;
- dummyPaRAMSet.cCnt = 0;
- dummyPaRAMSet.srcAddr = 0;
- dummyPaRAMSet.destAddr = 0;
- dummyPaRAMSet.srcBIdx = 0;
- dummyPaRAMSet.destBIdx = 0;
- dummyPaRAMSet.srcCIdx = 0;
- dummyPaRAMSet.destCIdx = 0;
- dummyPaRAMSet.linkAddr = 0xFFFF;
- dummyPaRAMSet.bCntReload = 0;
- dummyPaRAMSet.opt = 0;
-
- EDMA3SetPaRAM(pDmaControler->DMAC_ulVirtAddrBase, __EDMA3_DUMMY_CH_NUM, &dummyPaRAMSet);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xDmaTransact
-** 功能描述: 初始化一次 DMA 传输
-** 输 入 : uiChannel DMA 通道号
-** pDmaFuncs DMA 驱动程序
-** pDmaTrans DMA 传输参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xDmaTransact (UINT uiChannel,
- PLW_DMA_FUNCS pDmaFuncs,
- PLW_DMA_TRANSACTION pDmaTrans)
-{
- __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
- EDMA3CCPaRAMEntry paramSet;
- size_t stRemainBytes;
- INTREG intReg;
-
- if (uiChannel >= __EDMA3_CHANNEL_NR) {
- return (PX_ERROR);
- }
-
- if (!pDmaTrans) {
- return (PX_ERROR);
- }
-
- /*
- * 保存地址信息
- */
- paramSet.srcAddr = (unsigned int)pDmaTrans->DMAT_pucSrcAddress;
- paramSet.destAddr = (unsigned int)pDmaTrans->DMAT_pucDestAddress;
-
- paramSet.aCnt = (unsigned short)(pDmaTrans->DMAT_ulOption & 0xFFFF);
- paramSet.bCnt = (unsigned short)((pDmaTrans->DMAT_ulOption >> 16) & 0xFFFF);
- paramSet.cCnt = (unsigned short)(pDmaTrans->DMAT_stDataBytes /
- ((size_t)paramSet.bCnt * (size_t)paramSet.aCnt));
-
- if (paramSet.aCnt == 0 ||
- paramSet.bCnt == 0 ||
- paramSet.cCnt == 0 ||
- paramSet.aCnt > INT16_MAX ||
- paramSet.bCnt > INT16_MAX ||
- paramSet.cCnt > INT16_MAX) {
- printk(KERN_ERR "__am335xDmaTransact(): DMAT_stDataBytes is invalid!\n");
- return (PX_ERROR);
- }
-
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
- if (((size_t)paramSet.bCnt * (size_t)paramSet.aCnt) > INT16_MAX) {
- printk(KERN_ERR "__am335xDmaTransact(): DMAT_stDataBytes is invalid!\n");
- return (PX_ERROR);
- }
- } else {
- if (paramSet.cCnt != 1) {
- printk(KERN_ERR "__am335xDmaTransact(): DMAT_stDataBytes is invalid!\n");
- return (PX_ERROR);
- }
- }
-
- stRemainBytes = pDmaTrans->DMAT_stDataBytes -
- (size_t)paramSet.aCnt * (size_t)paramSet.bCnt * (size_t)paramSet.cCnt;
-
- if (stRemainBytes) {
- printk(KERN_WARNING "__am335xDmaTransact(): DMAT_stDataBytes is NOT align!\n");
- }
-
- paramSet.bCntReload = 0;
-
- /*
- * 设置源端地址控制信息
- */
- switch (pDmaTrans->DMAT_iSrcAddrCtl) {
- case LW_DMA_ADDR_INC:
- paramSet.srcBIdx = paramSet.aCnt;
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
- paramSet.srcCIdx = ((size_t)paramSet.aCnt * (size_t)paramSet.bCnt);
- } else {
- paramSet.srcCIdx = paramSet.aCnt;
- }
- break;
-
- case LW_DMA_ADDR_FIX:
- paramSet.srcBIdx = 0;
- paramSet.srcCIdx = 0;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- /*
- * 设置源端地址控制信息
- */
- switch (pDmaTrans->DMAT_iDestAddrCtl) {
- case LW_DMA_ADDR_INC:
- paramSet.destBIdx = paramSet.aCnt;
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
- paramSet.destCIdx = ((size_t)paramSet.aCnt * (size_t)paramSet.bCnt);
- } else {
- paramSet.destCIdx = paramSet.aCnt;
- }
- break;
-
- case LW_DMA_ADDR_FIX:
- paramSet.destBIdx = 0;
- paramSet.destCIdx = 0;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- paramSet.opt = 0;
-
- /*
- * FIFO mode.
- */
- paramSet.opt |= ((pDmaTrans->DMAT_iTransMode >> EDMA3_TARNS_MODE_FIFO_SHIFT) & 0x07) << 8;
-
- /*
- * AB Synchronized Transfer.
- */
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_TRIG_MODE_MANUAL) {
- paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
- }
- }
-
- /*
- * Setting the Transfer Complete Code(TCC).
- */
- paramSet.opt |= ((uiChannel << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
-
- /*
- * Enabling the Completion Interrupt.
- */
- paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
-
- /*
- * Trigger mode.
- */
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_TRIG_MODE_MANUAL) {
-
- pDmaControler->DMAC_uiTrigMode[uiChannel] = EDMA3_TRIG_MODE_MANUAL;
-
- paramSet.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT);
- } else {
- pDmaControler->DMAC_uiTrigMode[uiChannel] = EDMA3_TRIG_MODE_EVENT;
- }
-
- /*
- * Link address.
- */
- if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_TX_DUMMY_ENABLE) {
-
- paramSet.linkAddr = EDMA3CC_OPT(__EDMA3_DUMMY_CH_NUM);
-
- __am335xDmaTxDummyPaRAMConfEnable(pDmaControler);
- } else {
- paramSet.linkAddr = (unsigned short)(pDmaTrans->DMAT_iTransMode & 0xFFFF);
- }
-
- /*
- * Enable EDMA Transfer
- */
- LW_SPIN_LOCK_QUICK(&pDmaControler->DMAC_splLock, &intReg);
-
- /*
- * Now, write the PaRAM Set.
- */
- EDMA3SetPaRAM(pDmaControler->DMAC_ulVirtAddrBase, uiChannel, &paramSet);
-
- EDMA3EnableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
- uiChannel,
- pDmaControler->DMAC_uiTrigMode[uiChannel]);
-
- LW_SPIN_UNLOCK_QUICK(&pDmaControler->DMAC_splLock, intReg);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xDmaCmdDmaShow
-** 功能描述: DMA 命令 "dmas"
-** 输 入 : iArgC 参数个数
-** ppcArgV 参数表
-** 输 出 : 0
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-#if BSP_CFG_DMA_PERF_EN > 0
-static INT __am335xDmaCmdDmaShow (INT iArgC, PCHAR ppcArgV[])
-{
- __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
- INT i;
-
- for (i = 0; i < __EDMA3_CHANNEL_NR; i++) {
- if (API_AtomicGet(&pDmaControler->DMAC_atomicIntCounter[i])) {
- printf("DMA channel %d: interrupt count = %d\n", i,
- API_AtomicGet(&pDmaControler->DMAC_atomicIntCounter[i]));
- }
- }
-
- return (ERROR_NONE);
-}
-#endif
-/*********************************************************************************************************
-** 函数名称: __am335xEdma3HwInit
-** 功能描述: 初始化 DMA 硬件控制器
-** 输 入 : pDmaControler DMA 控制器
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xEdma3HwInit(__PAM335X_DMA_CONTROLER pDmaControler)
-{
- /*
- * Configuring the system clocks for EDMA.
- */
- am335xEnableModuleClock(am335xModuleIdGet("TPCC"));
- am335xEnableModuleClock(am335xModuleIdGet("TPTC0"));
- am335xEnableModuleClock(am335xModuleIdGet("TPTC1"));
- am335xEnableModuleClock(am335xModuleIdGet("TPTC2"));
-
- /*
- * Initialization of EDMA3
- */
- EDMA3Init(pDmaControler->DMAC_ulVirtAddrBase, __EDMA3_DEFAULT_EVTQ);
-
- write32((0 << 0) |
- (1 << 4) |
- (2 << 8) |
- (3 << 12),
- pDmaControler->DMAC_ulVirtAddrBase + EDMA3CC_QUEPRI);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xEdma3Init
-** 功能描述: 初始化 DMA 控制器
-** 输 入 : pDmaControler DMA 控制器
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xEdma3Init(__PAM335X_DMA_CONTROLER pDmaControler)
-{
- if (!pDmaControler->DMAC_bIsInit) {
-
- pDmaControler->DMAC_ulVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
- (PVOID)pDmaControler->DMAC_ulPhyAddrBase,
- pDmaControler->DMAC_stPhyAddrSize);
- if (!pDmaControler->DMAC_ulVirtAddrBase) {
- printk(KERN_ERR "__am335xEdma3Init(): failed to remap!\n");
- goto __error_handle;
- }
-
- LW_SPIN_INIT(&pDmaControler->DMAC_splLock);
-
- if (__am335xEdma3HwInit(pDmaControler) != ERROR_NONE) {
- printk(KERN_ERR "__am335xEdma3Init(): failed to init!\n");
- goto __error_handle;
- }
-
- /*
- * Registering EDMA3 Channel Controller 0 transfer completion interrupt.
- */
- API_InterVectorConnect(pDmaControler->DMAC_ulCompVector,
- (PINT_SVR_ROUTINE)__am335xEdma3CompletionIsr,
- pDmaControler,
- "edma3_comp_isr");
-
- /*
- * Setting the priority for EDMA3CC0 completion interrupt in AINTC.
- */
- IntPrioritySet(pDmaControler->DMAC_ulCompVector,
- pDmaControler->DMAC_uiCompIntPriority,
- AINTC_HOSTINT_ROUTE_IRQ);
-
- /*
- * Registering EDMA3 Channel Controller 0 Error Interrupt.
- */
- API_InterVectorConnect(pDmaControler->DMAC_ulErrorVector,
- (PINT_SVR_ROUTINE)__am335xEdma3CCErrorIsr,
- pDmaControler,
- "edma3_err_isr");
-
- /*
- * Setting the priority for EDMA3CC0 Error interrupt in AINTC.
- */
- IntPrioritySet(pDmaControler->DMAC_ulErrorVector,
- pDmaControler->DMAC_uiErrorIntPriority,
- AINTC_HOSTINT_ROUTE_IRQ);
-
- /*
- * Enabling the EDMA3CC0 completion interrupt in AINTC.
- */
- API_InterVectorEnable(pDmaControler->DMAC_ulCompVector);
-
- /*
- * Enabling the EDMA3CC0 Error interrupt in AINTC.
- */
- API_InterVectorEnable(pDmaControler->DMAC_ulErrorVector);
-
-#if BSP_CFG_DMA_PERF_EN > 0
- API_TShellKeywordAdd("dmas", __am335xDmaCmdDmaShow);
-#endif
-
- pDmaControler->DMAC_bIsInit = LW_TRUE;
- }
-
- return (ERROR_NONE);
-
- __error_handle:
-
- if (pDmaControler->DMAC_ulVirtAddrBase) {
- API_VmmIoUnmap((PVOID)pDmaControler->DMAC_ulVirtAddrBase);
- pDmaControler->DMAC_ulVirtAddrBase = 0;
- }
-
- return (PX_ERROR);
-}
-/*********************************************************************************************************
- AM335X 处理器 DMA 驱动程序
-*********************************************************************************************************/
-static LW_DMA_FUNCS _G_am335xDmaFuncs = {
- __am335xDmaReset,
- __am335xDmaTransact,
- __am335xDmaGetStatus,
-};
-/*********************************************************************************************************
-** 函数名称: dmaGetFuncs
-** 功能描述: 获取 DMA 驱动程序
-** 输 入 : uiChannel DMA 通道号
-** pulMaxBytes 最大传输字节数
-** 输 出 : 指定 DMA 通道的驱动程序
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-PLW_DMA_FUNCS dmaGetFuncs (UINT uiChannel, ULONG *pulMaxBytes)
-{
- __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
-
- if (uiChannel >= __EDMA3_CHANNEL_NR) {
- printk(KERN_ERR "dmaGetFuncs(): DMA channel invalid!\n");
- return (LW_NULL);
- }
-
- if (__am335xEdma3Init(pDmaControler) != ERROR_NONE) {
- return (LW_NULL);
- }
-
- if (pulMaxBytes) {
- *pulMaxBytes = (1 * LW_CFG_GB_SIZE);
- }
-
- return (&_G_am335xDmaFuncs);
-}
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: am335x_dma.c
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 17 日
+**
+** 描 述: AM335X 处理器 DMA 驱动
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "config.h"
+#include "SylixOS.h"
+
+#include "driver/am335x_common.h"
+#include "edma.h"
+#include "am335x_dma.h"
+
+#if SOC_EDMA3_NUM_DMACH != DMA_CHANNEL_NR
+#error DMA_CHANNEL_NR != SOC_EDMA3_NUM_DMACH
+#endif
+/*********************************************************************************************************
+ 定义
+*********************************************************************************************************/
+#define __EDMA3_CONTROLER_NR (1) /* DMA 控制器数目 */
+#define __EDMA3_CHANNEL_NR SOC_EDMA3_NUM_DMACH /* DMA 通道数目 */
+#define __EDMA3_DEFAULT_EVTQ (1) /* EDMA3 Event queue number */
+#define __EDMA3_DUMMY_CH_NUM (5) /* DMA 伪通道号 */
+/*********************************************************************************************************
+ DMA 控制器类型定义
+*********************************************************************************************************/
+typedef struct {
+ addr_t DMAC_ulPhyAddrBase; /* 物理地址基地址 */
+ size_t DMAC_stPhyAddrSize; /* 物理地址空间大小 */
+ ULONG DMAC_ulCompVector; /* DMA 完成中断向量 */
+ UINT DMAC_uiCompIntPriority; /* DMA 完成中断优先级 */
+ ULONG DMAC_ulErrorVector; /* DMA 出错中断向量 */
+ UINT DMAC_uiErrorIntPriority; /* DMA 出错中断优先级 */
+
+ addr_t DMAC_ulVirtAddrBase; /* 虚拟地址基地址 */
+ UINT DMAC_uiTrigMode[__EDMA3_CHANNEL_NR]; /* 各通道触发模式 */
+#if BSP_CFG_DMA_PERF_EN > 0
+ atomic_t DMAC_atomicIntCounter[__EDMA3_CHANNEL_NR]; /* 各通道中断次数 */
+#endif
+ BOOL DMAC_bIsInit; /* 是否已经初始化 */
+ LW_SPINLOCK_DEFINE(DMAC_splLock);
+} __AM335X_DMA_CONTROLER, *__PAM335X_DMA_CONTROLER;
+/*********************************************************************************************************
+ 外部函数声明
+*********************************************************************************************************/
+extern VOID am335xMcaspEdma3Done(UINT uiChannel);
+/*********************************************************************************************************
+ 全局变量
+*********************************************************************************************************/
+static __AM335X_DMA_CONTROLER _G_am335xDmaControlers[__EDMA3_CONTROLER_NR] = {
+ {
+ SOC_EDMA30CC_0_REGS,
+ 11 * LW_CFG_MB_SIZE,
+ SYS_INT_EDMACOMPINT,
+ BSP_CFG_EDMA3_COMP_INT_PRIO,
+ SYS_INT_EDMAERRINT,
+ BSP_CFG_EDMA3_ERR_INT_PRIO,
+ }
+};
+/*********************************************************************************************************
+** 函数名称: __am335xEdma3Done
+** 功能描述: DMA 完成
+** 输 入 : pDmaControler DMA 控制器
+** uiChannel DMA 通道号
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xEdma3Done (__PAM335X_DMA_CONTROLER pDmaControler, UINT uiChannel)
+{
+ EDMA3CCPaRAMEntry paramSet;
+
+#if BSP_CFG_DMA_PERF_EN > 0
+ API_AtomicInc(&pDmaControler->DMAC_atomicIntCounter[uiChannel]);
+#endif
+
+ switch (uiChannel) {
+ case EDMA3_CHA_MCASP0_TX:
+ case EDMA3_CHA_MCASP1_TX:
+ case EDMA3_CHA_MCASP0_RX:
+ case EDMA3_CHA_MCASP1_RX:
+ am335xMcaspEdma3Done(uiChannel);
+ break;
+
+ default:
+ break;
+ }
+
+ EDMA3GetPaRAM(pDmaControler->DMAC_ulVirtAddrBase, uiChannel, &paramSet);
+
+ if (paramSet.cCnt || paramSet.bCnt || paramSet.aCnt || paramSet.bCntReload) {
+ if (pDmaControler->DMAC_uiTrigMode[uiChannel] == EDMA3_TRIG_MODE_MANUAL) {
+ EDMA3EnableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
+ uiChannel,
+ pDmaControler->DMAC_uiTrigMode[uiChannel]);
+ }
+ } else {
+ if (pDmaControler->DMAC_uiTrigMode[uiChannel] == EDMA3_TRIG_MODE_EVENT) {
+ EDMA3DisableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
+ uiChannel,
+ pDmaControler->DMAC_uiTrigMode[uiChannel]);
+ }
+ API_DmaContext(uiChannel);
+ }
+}
+/*********************************************************************************************************
+** 函数名称: __am335xEdma3Error
+** 功能描述: DMA 出错
+** 输 入 : pDmaControler DMA 控制器
+** uiChannel DMA 通道号
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xEdma3Error (__PAM335X_DMA_CONTROLER pDmaControler, UINT uiChannel)
+{
+ INT iNum;
+
+ printk(KERN_ERR "__am335xEdma3CCErrorIsr(): channel=%d\n", uiChannel);
+
+ if (pDmaControler->DMAC_uiTrigMode[uiChannel] == EDMA3_TRIG_MODE_EVENT) {
+ EDMA3DisableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
+ uiChannel,
+ pDmaControler->DMAC_uiTrigMode[uiChannel]);
+ }
+
+ EDMA3FreeChannel(pDmaControler->DMAC_ulVirtAddrBase,
+ EDMA3_CHANNEL_TYPE_DMA,
+ uiChannel,
+ pDmaControler->DMAC_uiTrigMode[uiChannel],
+ uiChannel,
+ __EDMA3_DEFAULT_EVTQ);
+
+ while ((API_DmaJobNodeNum(uiChannel, &iNum) == ERROR_NONE) && (iNum > 0)) {
+ API_DmaContext(uiChannel);
+ }
+
+ EDMA3RequestChannel(pDmaControler->DMAC_ulVirtAddrBase,
+ EDMA3_CHANNEL_TYPE_DMA,
+ uiChannel,
+ uiChannel,
+ __EDMA3_DEFAULT_EVTQ);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xEdma3CompletionIsr
+** 功能描述: DMA 完成中断服务例程
+** 输 入 : pDmaControler DMA 控制器
+** ulVector 中断向量
+** 输 出 : 中断返回值
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static irqreturn_t __am335xEdma3CompletionIsr (__PAM335X_DMA_CONTROLER pDmaControler, ULONG ulVector)
+{
+ volatile UINT uiPendingIrqs;
+ volatile UINT uiIsIntrPending = 0u;
+ volatile UINT uiIsHighIntrPending = 0u;
+ UINT uiIndex;
+ UINT uiCount = 0u;
+
+ uiIndex = 1u;
+ uiIsIntrPending = EDMA3GetIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
+ uiIsHighIntrPending = EDMA3IntrStatusHighGet(pDmaControler->DMAC_ulVirtAddrBase);
+
+ if (uiIsIntrPending | uiIsHighIntrPending) {
+ while ((uiCount < EDMA3CC_COMPL_HANDLER_RETRY_COUNT) && (uiIndex != 0u)) {
+ uiIndex = 0u;
+
+ if (uiIsIntrPending) {
+ uiPendingIrqs = EDMA3GetIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
+ } else {
+ uiPendingIrqs = EDMA3IntrStatusHighGet(pDmaControler->DMAC_ulVirtAddrBase);
+ }
+
+ while (uiPendingIrqs) {
+ if (TRUE == (uiPendingIrqs & 1u)) {
+ /*
+ * If the user has not given any Callback function
+ * while requesting the TCC, its TCC specific bit
+ * in the IPR register will NOT be cleared.
+ */
+ if (uiIsIntrPending) {
+ /*
+ * Here write to ICR to clear the corresponding
+ * IPR bits
+ */
+ __am335xEdma3Done(pDmaControler, uiIndex);
+
+ EDMA3ClrIntr(pDmaControler->DMAC_ulVirtAddrBase, uiIndex);
+
+ } else {
+ /*
+ * Here write to ICR to clear the corresponding
+ * IPR bits
+ */
+ __am335xEdma3Done(pDmaControler, uiIndex + 32);
+
+ EDMA3ClrIntr(pDmaControler->DMAC_ulVirtAddrBase, uiIndex + 32u);
+ }
+ }
+ ++uiIndex;
+ uiPendingIrqs >>= 1u;
+ }
+ uiCount++;
+ }
+ }
+
+ return (LW_IRQ_HANDLED);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xEdma3CCErrorIsr
+** 功能描述: DMA 出错中断服务例程
+** 输 入 : pDmaControler DMA 控制器
+** ulVector 中断向量
+** 输 出 : 中断返回值
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static irqreturn_t __am335xEdma3CCErrorIsr (__PAM335X_DMA_CONTROLER pDmaControler, ULONG ulVector)
+{
+ volatile UINT uiPendingIrqs;
+ volatile UINT uiEvtQueNum = 0u; /* Event Queue Num */
+ volatile UINT uiIsHighIntrPending = 0u;
+ volatile UINT uiIsIntrPending = 0u;
+ volatile UINT uiCount = 0u;
+ volatile UINT uiIndex;
+
+ uiPendingIrqs = 0u;
+ uiIndex = 1u;
+
+ uiIsIntrPending = EDMA3GetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
+ uiIsHighIntrPending = EDMA3ErrIntrHighStatusGet(pDmaControler->DMAC_ulVirtAddrBase);
+
+ if ((uiIsIntrPending | uiIsHighIntrPending)
+ || (EDMA3QdmaGetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase) != 0u)
+ || (EDMA3GetCCErrStatus(pDmaControler->DMAC_ulVirtAddrBase) != 0u)) {
+
+ /*
+ * Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time,
+ * breaks when no pending interrupt is found
+ */
+ while ((uiCount < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (uiIndex != 0u)) {
+ uiIndex = 0u;
+
+ if (uiIsIntrPending) {
+ uiPendingIrqs = EDMA3GetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
+ } else {
+ uiPendingIrqs = EDMA3ErrIntrHighStatusGet(pDmaControler->DMAC_ulVirtAddrBase);
+ }
+
+ while (uiPendingIrqs) {
+ /*
+ * Process all the pending interrupts
+ */
+ if (TRUE == (uiPendingIrqs & 1u)) {
+ /*
+ * Write to EMCR to clear the corresponding EMR bits.
+ * Clear any SER
+ */
+ if (uiIsIntrPending) {
+ EDMA3ClrMissEvt(pDmaControler->DMAC_ulVirtAddrBase, uiIndex);
+
+ __am335xEdma3Error(pDmaControler, uiIndex);
+ } else {
+ EDMA3ClrMissEvt(pDmaControler->DMAC_ulVirtAddrBase, uiIndex + 32u);
+
+ __am335xEdma3Error(pDmaControler, uiIndex + 32u);
+ }
+ }
+
+ ++uiIndex;
+ uiPendingIrqs >>= 1u;
+ }
+
+ uiIndex = 0u;
+ uiPendingIrqs = EDMA3QdmaGetErrIntrStatus(pDmaControler->DMAC_ulVirtAddrBase);
+
+ while (uiPendingIrqs) {
+ /*
+ * Process all the pending interrupts
+ */
+ if (TRUE == (uiPendingIrqs & 1u)) {
+ /*
+ * Here write to QEMCR to clear the corresponding QEMR bits
+ * Clear any QSER
+ */
+ EDMA3QdmaClrMissEvt(pDmaControler->DMAC_ulVirtAddrBase, uiIndex);
+ }
+
+ ++uiIndex;
+ uiPendingIrqs >>= 1u;
+ }
+
+ uiIndex = 0u;
+
+ uiPendingIrqs = EDMA3GetCCErrStatus(pDmaControler->DMAC_ulVirtAddrBase);
+
+ if (uiPendingIrqs != 0u) {
+ /*
+ * Process all the pending CC error interrupts.
+ * Queue threshold error for different event queues.
+ */
+ for (uiEvtQueNum = 0u; uiEvtQueNum < SOC_EDMA3_NUM_EVQUE; uiEvtQueNum++) {
+ if ((uiPendingIrqs & (1u << uiEvtQueNum)) != 0u) {
+ /*
+ * Clear the error interrupt.
+ */
+ EDMA3ClrCCErr(pDmaControler->DMAC_ulVirtAddrBase, (1u << uiEvtQueNum));
+ }
+ }
+
+ /*
+ * Transfer completion code error.
+ */
+ if ((uiPendingIrqs & (1u << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u) {
+ EDMA3ClrCCErr(pDmaControler->DMAC_ulVirtAddrBase,
+ (1u << EDMA3CC_CCERR_TCCERR_SHIFT));
+ }
+ ++uiIndex;
+ }
+ uiCount++;
+ }
+ } else {
+ printk(KERN_ERR "__am335xEdma3CCErrorIsr(): No Error Found!\n");
+
+ return (LW_IRQ_HANDLED_DISV);
+ }
+
+ return (LW_IRQ_HANDLED);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xDmaReset
+** 功能描述: 初始化 DMA 并停止
+** 输 入 : uiChannel DMA 通道号
+** pDmaFuncs DMA 驱动程序
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xDmaReset (UINT uiChannel, PLW_DMA_FUNCS pDmaFuncs)
+{
+ __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
+
+ if (uiChannel >= __EDMA3_CHANNEL_NR) {
+ return;
+ }
+
+ EDMA3RequestChannel(pDmaControler->DMAC_ulVirtAddrBase,
+ EDMA3_CHANNEL_TYPE_DMA,
+ uiChannel,
+ uiChannel,
+ __EDMA3_DEFAULT_EVTQ);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xDmaGetStatus
+** 功能描述: 获得 DMA 当前状态
+** 输 入 : uiChannel DMA 通道号
+** pDmaFuncs DMA 驱动程序
+** 输 出 : 0:空闲 1:忙 PX_ERROR:错误
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xDmaGetStatus (UINT uiChannel, PLW_DMA_FUNCS pDmaFuncs)
+{
+ __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
+
+ (VOID)pDmaControler;
+
+ if (uiChannel >= __EDMA3_CHANNEL_NR) {
+ return (PX_ERROR);
+ }
+
+ if (0) { /* 检测状态 */
+ return (LW_DMA_STATUS_BUSY);
+ } else {
+ return (LW_DMA_STATUS_IDLE);
+ }
+}
+/*********************************************************************************************************
+** 函数名称: __am335xDmaTxDummyPaRAMConfEnable
+** 功能描述: 初始化一次伪发送 DMA 传输
+** 输 入 : NONE
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xDmaTxDummyPaRAMConfEnable (__PAM335X_DMA_CONTROLER pDmaControler)
+{
+ EDMA3CCPaRAMEntry dummyPaRAMSet;
+
+ dummyPaRAMSet.aCnt = 1;
+ dummyPaRAMSet.bCnt = 0;
+ dummyPaRAMSet.cCnt = 0;
+ dummyPaRAMSet.srcAddr = 0;
+ dummyPaRAMSet.destAddr = 0;
+ dummyPaRAMSet.srcBIdx = 0;
+ dummyPaRAMSet.destBIdx = 0;
+ dummyPaRAMSet.srcCIdx = 0;
+ dummyPaRAMSet.destCIdx = 0;
+ dummyPaRAMSet.linkAddr = 0xFFFF;
+ dummyPaRAMSet.bCntReload = 0;
+ dummyPaRAMSet.opt = 0;
+
+ EDMA3SetPaRAM(pDmaControler->DMAC_ulVirtAddrBase, __EDMA3_DUMMY_CH_NUM, &dummyPaRAMSet);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xDmaTransact
+** 功能描述: 初始化一次 DMA 传输
+** 输 入 : uiChannel DMA 通道号
+** pDmaFuncs DMA 驱动程序
+** pDmaTrans DMA 传输参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xDmaTransact (UINT uiChannel,
+ PLW_DMA_FUNCS pDmaFuncs,
+ PLW_DMA_TRANSACTION pDmaTrans)
+{
+ __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
+ EDMA3CCPaRAMEntry paramSet = { 0 };
+ size_t stRemainBytes;
+ INTREG intReg;
+
+ if (uiChannel >= __EDMA3_CHANNEL_NR) {
+ return (PX_ERROR);
+ }
+
+ if (!pDmaTrans) {
+ return (PX_ERROR);
+ }
+
+ /*
+ * 保存地址信息
+ */
+ paramSet.srcAddr = (unsigned int)pDmaTrans->DMAT_pucSrcAddress;
+ paramSet.destAddr = (unsigned int)pDmaTrans->DMAT_pucDestAddress;
+
+ paramSet.aCnt = (unsigned short)(pDmaTrans->DMAT_ulOption & 0xFFFF);
+ paramSet.bCnt = (unsigned short)((pDmaTrans->DMAT_ulOption >> 16) & 0xFFFF);
+ paramSet.cCnt = (unsigned short)(pDmaTrans->DMAT_stDataBytes /
+ ((size_t)paramSet.bCnt * (size_t)paramSet.aCnt));
+
+ if (paramSet.aCnt == 0 ||
+ paramSet.bCnt == 0 ||
+ paramSet.cCnt == 0 ||
+ paramSet.aCnt > INT16_MAX ||
+ paramSet.bCnt > INT16_MAX ||
+ paramSet.cCnt > INT16_MAX) {
+ printk(KERN_ERR "__am335xDmaTransact(): DMAT_stDataBytes is invalid!\n");
+ return (PX_ERROR);
+ }
+
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
+ if (((size_t)paramSet.bCnt * (size_t)paramSet.aCnt) > INT16_MAX) {
+ printk(KERN_ERR "__am335xDmaTransact(): DMAT_stDataBytes is invalid!\n");
+ return (PX_ERROR);
+ }
+ } else {
+ if (paramSet.cCnt != 1) {
+ printk(KERN_ERR "__am335xDmaTransact(): DMAT_stDataBytes is invalid!\n");
+ return (PX_ERROR);
+ }
+ }
+
+ stRemainBytes = pDmaTrans->DMAT_stDataBytes -
+ (size_t)paramSet.aCnt * (size_t)paramSet.bCnt * (size_t)paramSet.cCnt;
+
+ if (stRemainBytes) {
+ printk(KERN_WARNING "__am335xDmaTransact(): DMAT_stDataBytes is NOT align!\n");
+ }
+
+ paramSet.bCntReload = 0;
+
+ /*
+ * 设置源端地址控制信息
+ */
+ switch (pDmaTrans->DMAT_iSrcAddrCtl) {
+ case LW_DMA_ADDR_INC:
+ paramSet.srcBIdx = paramSet.aCnt;
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
+ paramSet.srcCIdx = ((size_t)paramSet.aCnt * (size_t)paramSet.bCnt);
+ } else {
+ paramSet.srcCIdx = paramSet.aCnt;
+ }
+ break;
+
+ case LW_DMA_ADDR_FIX:
+ paramSet.srcBIdx = 0;
+ paramSet.srcCIdx = 0;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ /*
+ * 设置源端地址控制信息
+ */
+ switch (pDmaTrans->DMAT_iDestAddrCtl) {
+ case LW_DMA_ADDR_INC:
+ paramSet.destBIdx = paramSet.aCnt;
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
+ paramSet.destCIdx = ((size_t)paramSet.aCnt * (size_t)paramSet.bCnt);
+ } else {
+ paramSet.destCIdx = paramSet.aCnt;
+ }
+ break;
+
+ case LW_DMA_ADDR_FIX:
+ paramSet.destBIdx = 0;
+ paramSet.destCIdx = 0;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ paramSet.opt = 0;
+
+ /*
+ * FIFO mode.
+ */
+ paramSet.opt |= ((pDmaTrans->DMAT_iTransMode >> EDMA3_TARNS_MODE_FIFO_SHIFT) & 0x07) << 8;
+
+ /*
+ * AB Synchronized Transfer.
+ */
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_AB_SYNC) {
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_TRIG_MODE_MANUAL) {
+ paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
+ }
+ }
+
+ /*
+ * Setting the Transfer Complete Code(TCC).
+ */
+ paramSet.opt |= ((uiChannel << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
+
+ /*
+ * Enabling the Completion Interrupt.
+ */
+ paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
+
+ /*
+ * Trigger mode.
+ */
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_TRIG_MODE_MANUAL) {
+
+ pDmaControler->DMAC_uiTrigMode[uiChannel] = EDMA3_TRIG_MODE_MANUAL;
+
+ paramSet.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT);
+ } else {
+ pDmaControler->DMAC_uiTrigMode[uiChannel] = EDMA3_TRIG_MODE_EVENT;
+ }
+
+ /*
+ * Link address.
+ */
+ if (pDmaTrans->DMAT_iTransMode & EDMA3_TARNS_MODE_TX_DUMMY_ENABLE) {
+
+ paramSet.linkAddr = EDMA3CC_OPT(__EDMA3_DUMMY_CH_NUM);
+
+ __am335xDmaTxDummyPaRAMConfEnable(pDmaControler);
+ } else {
+ paramSet.linkAddr = (unsigned short)(pDmaTrans->DMAT_iTransMode & 0xFFFF);
+ }
+
+ /*
+ * Enable EDMA Transfer
+ */
+ LW_SPIN_LOCK_QUICK(&pDmaControler->DMAC_splLock, &intReg);
+
+ /*
+ * Now, write the PaRAM Set.
+ */
+ EDMA3SetPaRAM(pDmaControler->DMAC_ulVirtAddrBase, uiChannel, &paramSet);
+
+ EDMA3EnableTransfer(pDmaControler->DMAC_ulVirtAddrBase,
+ uiChannel,
+ pDmaControler->DMAC_uiTrigMode[uiChannel]);
+
+ LW_SPIN_UNLOCK_QUICK(&pDmaControler->DMAC_splLock, intReg);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xDmaCmdDmaShow
+** 功能描述: DMA 命令 "dmas"
+** 输 入 : iArgC 参数个数
+** ppcArgV 参数表
+** 输 出 : 0
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+#if BSP_CFG_DMA_PERF_EN > 0
+static INT __am335xDmaCmdDmaShow (INT iArgC, PCHAR ppcArgV[])
+{
+ __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
+ INT i;
+
+ for (i = 0; i < __EDMA3_CHANNEL_NR; i++) {
+ if (API_AtomicGet(&pDmaControler->DMAC_atomicIntCounter[i])) {
+ printf("DMA channel %d: interrupt count = %d\n", i,
+ API_AtomicGet(&pDmaControler->DMAC_atomicIntCounter[i]));
+ }
+ }
+
+ return (ERROR_NONE);
+}
+#endif
+/*********************************************************************************************************
+** 函数名称: __am335xEdma3HwInit
+** 功能描述: 初始化 DMA 硬件控制器
+** 输 入 : pDmaControler DMA 控制器
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xEdma3HwInit(__PAM335X_DMA_CONTROLER pDmaControler)
+{
+ /*
+ * Configuring the system clocks for EDMA.
+ */
+ am335xEnableModuleClock(am335xModuleIdGet("TPCC"));
+ am335xEnableModuleClock(am335xModuleIdGet("TPTC0"));
+ am335xEnableModuleClock(am335xModuleIdGet("TPTC1"));
+ am335xEnableModuleClock(am335xModuleIdGet("TPTC2"));
+
+ /*
+ * Initialization of EDMA3
+ */
+ EDMA3Init(pDmaControler->DMAC_ulVirtAddrBase, __EDMA3_DEFAULT_EVTQ);
+
+ write32((0 << 0) |
+ (1 << 4) |
+ (2 << 8) |
+ (3 << 12),
+ pDmaControler->DMAC_ulVirtAddrBase + EDMA3CC_QUEPRI);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xEdma3Init
+** 功能描述: 初始化 DMA 控制器
+** 输 入 : pDmaControler DMA 控制器
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xEdma3Init(__PAM335X_DMA_CONTROLER pDmaControler)
+{
+ if (!pDmaControler->DMAC_bIsInit) {
+
+ pDmaControler->DMAC_ulVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
+ (PVOID)pDmaControler->DMAC_ulPhyAddrBase,
+ pDmaControler->DMAC_stPhyAddrSize);
+ if (!pDmaControler->DMAC_ulVirtAddrBase) {
+ printk(KERN_ERR "__am335xEdma3Init(): failed to remap!\n");
+ goto __error_handle;
+ }
+
+ LW_SPIN_INIT(&pDmaControler->DMAC_splLock);
+
+ if (__am335xEdma3HwInit(pDmaControler) != ERROR_NONE) {
+ printk(KERN_ERR "__am335xEdma3Init(): failed to init!\n");
+ goto __error_handle;
+ }
+
+ /*
+ * Registering EDMA3 Channel Controller 0 transfer completion interrupt.
+ */
+ API_InterVectorConnect(pDmaControler->DMAC_ulCompVector,
+ (PINT_SVR_ROUTINE)__am335xEdma3CompletionIsr,
+ pDmaControler,
+ "edma3_comp_isr");
+
+ /*
+ * Setting the priority for EDMA3CC0 completion interrupt in AINTC.
+ */
+ IntPrioritySet(pDmaControler->DMAC_ulCompVector,
+ pDmaControler->DMAC_uiCompIntPriority,
+ AINTC_HOSTINT_ROUTE_IRQ);
+
+ /*
+ * Registering EDMA3 Channel Controller 0 Error Interrupt.
+ */
+ API_InterVectorConnect(pDmaControler->DMAC_ulErrorVector,
+ (PINT_SVR_ROUTINE)__am335xEdma3CCErrorIsr,
+ pDmaControler,
+ "edma3_err_isr");
+
+ /*
+ * Setting the priority for EDMA3CC0 Error interrupt in AINTC.
+ */
+ IntPrioritySet(pDmaControler->DMAC_ulErrorVector,
+ pDmaControler->DMAC_uiErrorIntPriority,
+ AINTC_HOSTINT_ROUTE_IRQ);
+
+ /*
+ * Enabling the EDMA3CC0 completion interrupt in AINTC.
+ */
+ API_InterVectorEnable(pDmaControler->DMAC_ulCompVector);
+
+ /*
+ * Enabling the EDMA3CC0 Error interrupt in AINTC.
+ */
+ API_InterVectorEnable(pDmaControler->DMAC_ulErrorVector);
+
+#if BSP_CFG_DMA_PERF_EN > 0
+ API_TShellKeywordAdd("dmas", __am335xDmaCmdDmaShow);
+#endif
+
+ pDmaControler->DMAC_bIsInit = LW_TRUE;
+ }
+
+ return (ERROR_NONE);
+
+ __error_handle:
+
+ if (pDmaControler->DMAC_ulVirtAddrBase) {
+ API_VmmIoUnmap((PVOID)pDmaControler->DMAC_ulVirtAddrBase);
+ pDmaControler->DMAC_ulVirtAddrBase = 0;
+ }
+
+ return (PX_ERROR);
+}
+/*********************************************************************************************************
+ AM335X 处理器 DMA 驱动程序
+*********************************************************************************************************/
+static LW_DMA_FUNCS _G_am335xDmaFuncs = {
+ __am335xDmaReset,
+ __am335xDmaTransact,
+ __am335xDmaGetStatus,
+};
+/*********************************************************************************************************
+** 函数名称: dmaGetFuncs
+** 功能描述: 获取 DMA 驱动程序
+** 输 入 : uiChannel DMA 通道号
+** pulMaxBytes 最大传输字节数
+** 输 出 : 指定 DMA 通道的驱动程序
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+PLW_DMA_FUNCS dmaGetFuncs (UINT uiChannel, ULONG *pulMaxBytes)
+{
+ __PAM335X_DMA_CONTROLER pDmaControler = &_G_am335xDmaControlers[0];
+
+ if (uiChannel >= __EDMA3_CHANNEL_NR) {
+ printk(KERN_ERR "dmaGetFuncs(): DMA channel invalid!\n");
+ return (LW_NULL);
+ }
+
+ if (__am335xEdma3Init(pDmaControler) != ERROR_NONE) {
+ return (LW_NULL);
+ }
+
+ if (pulMaxBytes) {
+ *pulMaxBytes = (1 * LW_CFG_GB_SIZE);
+ }
+
+ return (&_G_am335xDmaFuncs);
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/lcd/am335x_lcd.c b/SylixOS/driver/lcd/am335x_lcd.c
index 66706a9..ce82b63 100644
--- a/SylixOS/driver/lcd/am335x_lcd.c
+++ b/SylixOS/driver/lcd/am335x_lcd.c
@@ -1,873 +1,887 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: am335x_lcd.c
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 08 日
-**
-** 描 述: AM335X 处理器 LCD 驱动
-*********************************************************************************************************/
-#define __SYLIXOS_KERNEL
-#include "config.h"
-#include "SylixOS.h"
-#include "string.h"
-
-#include "driver/am335x_common.h"
-#include "raster.h"
-#include "am335x_lcd.h"
-/*********************************************************************************************************
- LCD 面板定义
-*********************************************************************************************************/
-typedef struct {
- const CHAR acName[25]; /* Full name <vendor>_<model> */
- INT iWidth;
- INT iHeight;
- INT iHfp; /* Horizontal front porch */
- INT iHbp; /* Horizontal back porch */
- INT iHsw; /* Horizontal Sync Pulse Width */
- INT iVfp; /* Vertical front porch */
- INT iVbp; /* Vertical back porch */
- INT iVsw; /* Vertical Sync Pulse Width */
- UINT uiPixelClk; /* Pixel clock */
- BOOL bInvertPixelClk; /* Invert Pixel clock */
-} __AM335X_LCD_PANEL, *__PAM335X_LCD_PANEL;
-/*********************************************************************************************************
- LCD 控制器类型定义
-*********************************************************************************************************/
-typedef struct {
- addr_t LCDC_ulPhyAddrBase; /* 物理地址基地址 */
- size_t LCDC_stPhyAddrSize; /* 物理地址空间大小 */
- ULONG LCDC_ulVector; /* 中断向量 */
- UINT LCDC_uiIntPriority; /* 中断优先级 */
- BOOL LCDC_bDoubleFrameBufferEn; /* 是否使用双缓冲区 */
- BOOL LCDC_bInterruptEn; /* 是否使用中断 */
- CPCHAR LCDC_pcName; /* 设备名 */
-
- PAM335X_PINMUX LCDC_pPinMux;
- addr_t LCDC_ulVirtAddrBase; /* 虚拟地址基地址 */
- VOID *LCDC_pvLcdMemBase; /* LCD 内存基地址 */
- BOOL LCDC_bIsInit; /* 是否已经初始化 */
- LW_GM_DEVICE LCDC_gmDev; /* 图形设备 */
- __PAM335X_LCD_PANEL LCDC_pPanel;
- PAM335X_LCD_DATA LCDC_pData;
- PAM335X_LCD_CTRL_CONFIG LCDC_pCtrlConfig;
-} __AM335X_LCD_CONTROLER, *__PAM335X_LCD_CONTROLER;
-/*********************************************************************************************************
- LCD 控制器
-*********************************************************************************************************/
-static __AM335X_LCD_CONTROLER _G_am335xLcdControler = {
- SOC_LCDC_0_REGS,
- LW_CFG_VMM_PAGE_SIZE,
- SYS_INT_LCDCINT,
- BSP_CFG_LCD_INT_PRIO,
- LW_FALSE,
- LW_FALSE,
-};
-/*********************************************************************************************************
- 已知的 LCD 面板
-*********************************************************************************************************/
-static __AM335X_LCD_PANEL __G_am335xKnownLcdPanels[] = {
- /* Sharp LCD035Q3DG01 */
- [0] = {
- .acName = "Sharp_LCD035Q3DG01",
- .iWidth = 320,
- .iHeight = 240,
- .iHfp = 8,
- .iHbp = 6,
- .iHsw = 0,
- .iVfp = 2,
- .iVbp = 2,
- .iVsw = 0,
- .uiPixelClk = 4608000,
- .bInvertPixelClk = 1,
- },
- /* Sharp LK043T1DG01 */
- [1] = {
- .acName = "Sharp_LK043T1DG01",
- .iWidth = 480,
- .iHeight = 272,
- .iHfp = 2,
- .iHbp = 2,
- .iHsw = 41,
- .iVfp = 3,
- .iVbp = 3,
- .iVsw = 10,
- .uiPixelClk = 7833600,
- .bInvertPixelClk = 0,
- },
- /* ThreeFive S9700RTWV35TR */
- [2] = {
- .acName = "TFC_S9700RTWV35TR_01B",
- .iWidth = 800,
- .iHeight = 480,
- .iHfp = 39,
- .iHbp = 39,
- .iHsw = 47,
- .iVfp = 13,
- .iVbp = 29,
- .iVsw = 2,
- .uiPixelClk = 30000000,
- .bInvertPixelClk = 0,
- },
- [3] = {
- .acName = "NHD-5.0-ATXI#-T-1",
- .iWidth = 800,
- .iHeight = 480,
- .iHfp = 8,
- .iHbp = 43,
- .iHsw = 40,
- .iVfp = 4,
- .iVbp = 12,
- .iVsw = 3,
- .uiPixelClk = 30000000,
- .bInvertPixelClk = 0,
- },
- /* Newhaven Display */
- [4] = {
- .acName = "NHD-7.0-ATXI#-T-1",
- .iWidth = 800,
- .iHeight = 480,
- .iHfp = 112,
- .iHbp = 88,
- .iHsw = 48,
- .iVfp = 21,
- .iVbp = 39,
- .iVsw = 3,
- .uiPixelClk = 40000000,
- .bInvertPixelClk = 0,
- },
- [5] = {
- .acName = "NHD-8.0-ATXI#-T-1",
- .iWidth = 800,
- .iHeight = 600,
- .iHfp = 112,
- .iHbp = 88,
- .iHsw = 48,
- .iVfp = 21,
- .iVbp = 39,
- .iVsw = 3,
- .uiPixelClk = 40000000,
- .bInvertPixelClk = 0,
- },
- [6] = {
- /* 720 x 480 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "nxp-720x480@60",
- .iWidth = 720,
- .iHeight = 480,
- .iHfp = 15,
- .iHbp = 59,
- .iHsw = 61,
- .iVfp = 9,
- .iVbp = 30,
- .iVsw = 5,
- .uiPixelClk = 27027000,
- .bInvertPixelClk = 0,
- },
- [7] = {
- /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "nxp-1280x720@60",
- .iWidth = 1280,
- .iHeight = 720,
- .iHfp = 95,
- .iHbp =190,
- .iHsw = 34,
- .iVfp = 5,
- .iVbp = 20,
- .iVsw = 5,
- .uiPixelClk = 64000000,
- .bInvertPixelClk = 0,
- },
- [8] = {
- /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "nxp-1024x768@60",
- .iWidth = 1024,
- .iHeight = 768,
- .iHfp = 28,
- .iHbp = 158,
- .iHsw = 136,
- .iVfp = 3,
- .iVbp = 28,
- .iVsw = 5,
- .uiPixelClk = 64000000,
- .bInvertPixelClk = 0,
- },
- [9] = {
- /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "nxp-800x600@60",
- .iWidth = 800,
- .iHeight = 600,
- .iHfp = 42,
- .iHbp = 144,
- .iHsw = 58,
- .iVfp = 1,
- .iVbp = 25,
- .iVsw = 3,
- .uiPixelClk = 41000000,
- .bInvertPixelClk = 0,
- },
- [10] = {
- /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "nxp-640x480@60",
- .iWidth = 640,
- .iHeight = 480,
- .iHfp = 19,
- .iHbp = 79,
- .iHsw = 59,
- .iVfp = 9,
- .iVbp = 30,
- .iVsw = 6,
- .uiPixelClk = 25200000,
- .bInvertPixelClk = 0,
- },
- [11] = {
- /* 1920 x 1080 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "nxp-1920x1080@24",
- .iWidth = 1920,
- .iHeight = 1080,
- .iHfp = 103,
- .iHbp = 311,
- .iHsw = 31,
- .iVfp = 37,
- .iVbp = 60,
- .iVsw = 8,
- .uiPixelClk = 96000000,
- .bInvertPixelClk = 0,
- },
- [12] = {
- /* 1920 x 1080 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "NHD-4.3-ATXI#-T-1",
- .iWidth = 480,
- .iHeight = 272,
- .iHfp = 1,
- .iHbp = 1,
- .iHsw = 40,
- .iVfp = 2,
- .iVbp = 2,
- .iVsw = 10,
- .uiPixelClk = 9000000,
- .bInvertPixelClk = 0,
- },
- [13] = {
- /* 1920 x 1080 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
- .acName = "NHD-10.4-ATXI#-T-1",
- .iWidth = 800,
- .iHeight = 600,
- .iHfp = 112,
- .iHbp = 88,
- .iHsw = 48,
- .iVfp = 21,
- .iVbp = 39,
- .iVsw = 3,
- .uiPixelClk = 40000000,
- .bInvertPixelClk = 0,
- },
-};
-/*********************************************************************************************************
- FrameBuffer 相关定义
-*********************************************************************************************************/
-#define __LCD_XSIZE pLcdControler->LCDC_pPanel->iWidth
-#define __LCD_YSIZE pLcdControler->LCDC_pPanel->iHeight
-#define __LCD_BITS_PER_PIXEL pLcdControler->LCDC_pCtrlConfig->iBitsPerPixel
-#define __LCD_BYTES_PER_PIXEL (__LCD_BITS_PER_PIXEL / 8)
-
-#define __LCD_MEM_BASE ((ULONG)pLcdControler->LCDC_pvLcdMemBase)
-#define __LCD_MEM_HDR_SIZE 32
-#define __LCD_MEM_HDR_OFFSET (LW_CFG_VMM_PAGE_SIZE - __LCD_MEM_HDR_SIZE)
-#define __LCD_MEM_HDR_BASE (__LCD_MEM_BASE + __LCD_MEM_HDR_OFFSET)
-#define __LCD_FRAMEBUFFER_BASE (__LCD_MEM_BASE + LW_CFG_VMM_PAGE_SIZE)
-#define __LCD_FRAMEBUFFER_SIZE (__LCD_XSIZE * __LCD_YSIZE * __LCD_BYTES_PER_PIXEL)
-#define __LCD_FRAMEBUFFER_END (__LCD_FRAMEBUFFER_BASE + __LCD_FRAMEBUFFER_SIZE - \
- __LCD_BYTES_PER_PIXEL)
-#define __LCD_FRAMEBUFFER_TOTAL_SIZE (LW_CFG_VMM_PAGE_SIZE + __LCD_FRAMEBUFFER_SIZE)
-/*********************************************************************************************************
-** 函数名称: __am335xLcdHwInit
-** 功能描述: 初始化 LCD 硬件
-** 输 入 : pLcdControler LCD 控制器
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xLcdHwInit (__PAM335X_LCD_CONTROLER pLcdControler)
-{
- __PAM335X_LCD_PANEL pPanel = pLcdControler->LCDC_pPanel;
- PAM335X_LCD_CTRL_CONFIG pCtrlConfig = pLcdControler->LCDC_pCtrlConfig;
- UINT32 uiValue;
- UINT32 uiBurstSize;
- UINT32 uiFifoThreshold;
-
- /*
- * Enable clock for LCD Module
- */
- am335xEnableModuleClock(am335xModuleIdGet("LCDC"));
-
- am335xPinMuxSetup(pLcdControler->LCDC_pPinMux);
-
- /*
- * Clock for DMA,LIDD and for Core(which encompasses
- * Raster Active Matrix and Passive Matrix logic)
- * enabled.
- */
- RasterClocksEnable(pLcdControler->LCDC_ulVirtAddrBase);
-
- /*
- * Disable raster
- */
- RasterDisable(pLcdControler->LCDC_ulVirtAddrBase);
-
- /*
- * Configure the pclk
- */
- RasterClkConfig(pLcdControler->LCDC_ulVirtAddrBase,
- pPanel->uiPixelClk,
- 192000000);
-
- /*
- * Configuring DMA of LCD controller
- */
- switch (pCtrlConfig->iDmaBurstSize) {
- case 1:
- uiBurstSize = RASTER_BURST_SIZE_1;
- break;
-
- case 2:
- uiBurstSize = RASTER_BURST_SIZE_2;
- break;
-
- case 4:
- uiBurstSize = RASTER_BURST_SIZE_4;
- break;
-
- case 8:
- uiBurstSize = RASTER_BURST_SIZE_8;
- break;
-
- case 16:
- uiBurstSize = RASTER_BURST_SIZE_16;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- switch (pCtrlConfig->iFifoThreshold) {
- case 8:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_8;
- break;
-
- case 16:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_16;
- break;
-
- case 32:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_32;
- break;
-
- case 64:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_64;
- break;
-
- case 128:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_128;
- break;
-
- case 256:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_256;
- break;
-
- case 512:
- uiFifoThreshold = RASTER_FIFO_THRESHOLD_512;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
- RasterDMAConfig(pLcdControler->LCDC_ulVirtAddrBase,
- RASTER_DOUBLE_FRAME_BUFFER,
- uiBurstSize,
- uiFifoThreshold,
- RASTER_BIG_ENDIAN_DISABLE);
- } else {
- RasterDMAConfig(pLcdControler->LCDC_ulVirtAddrBase,
- RASTER_SINGLE_FRAME_BUFFER,
- uiBurstSize,
- uiFifoThreshold,
- RASTER_BIG_ENDIAN_DISABLE);
- }
-
- /*
- * Configuring modes(ex:tft or stn,color or monochrome etc) for raster controller
- */
- switch (__LCD_BITS_PER_PIXEL) {
- case 16:
- RasterModeConfig(pLcdControler->LCDC_ulVirtAddrBase,
- RASTER_DISPLAY_MODE_TFT,
- RASTER_PALETTE_DATA,
- RASTER_COLOR,
- RASTER_RIGHT_ALIGNED);
- break;
-
- case 24:
- case 32:
- RasterModeConfig(pLcdControler->LCDC_ulVirtAddrBase,
- RASTER_DISPLAY_MODE_TFT_UNPACKED,
- RASTER_PALETTE_DATA,
- RASTER_COLOR,
- RASTER_RIGHT_ALIGNED);
- break;
-
- default:
- return (PX_ERROR);
- }
-
- /*
- * Configuring the polarity of timing parameters of raster controller
- */
- uiValue = 0;
-
- if (pCtrlConfig->bInvertFrameClock) {
- uiValue |= RASTER_FRAME_CLOCK_LOW;
- } else {
- uiValue |= RASTER_FRAME_CLOCK_HIGH;
- }
-
- if (pCtrlConfig->bInvertLineClock) {
- uiValue |= RASTER_LINE_CLOCK_LOW;
- } else {
- uiValue |= RASTER_LINE_CLOCK_HIGH;
- }
-
- if (pPanel->bInvertPixelClk) {
- uiValue |= RASTER_PIXEL_CLOCK_LOW;
- } else {
- uiValue |= RASTER_PIXEL_CLOCK_HIGH;
- }
-
- if (pCtrlConfig->bSyncEdge) {
- uiValue |= RASTER_SYNC_EDGE_FALLING;
- } else {
- uiValue |= RASTER_SYNC_EDGE_RISING;
- }
-
- if (pCtrlConfig->bSyncCtrl) {
- uiValue |= RASTER_SYNC_CTRL_ACTIVE;
- } else {
- uiValue |= RASTER_SYNC_CTRL_INACTIVE;
- }
-
- uiValue |= RASTER_AC_BIAS_HIGH;
-
- RasterTiming2Configure(pLcdControler->LCDC_ulVirtAddrBase,
- uiValue,
- pCtrlConfig->iAcBiasInterrupt,
- pCtrlConfig->iAcBias);
-
- /*
- * Configuring horizontal timing parameter
- */
- RasterHparamConfig(pLcdControler->LCDC_ulVirtAddrBase,
- __LCD_XSIZE,
- pPanel->iHsw,
- pPanel->iHfp,
- pPanel->iHbp);
-
- /*
- * Configuring vertical timing parameters
- */
- RasterVparamConfig(pLcdControler->LCDC_ulVirtAddrBase,
- __LCD_YSIZE,
- pPanel->iVsw,
- pPanel->iVfp,
- pPanel->iVbp);
-
- RasterFIFODMADelayConfig(pLcdControler->LCDC_ulVirtAddrBase,
- pCtrlConfig->iFifoDmaDelay);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdIsr
-** 功能描述: LCD 中断服务例程
-** 输 入 : pLcdControler LCD 控制器
-** ulVector 中断向量
-** 输 出 : 中断返回值
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static irqreturn_t __am335xLcdIsr (__PAM335X_LCD_CONTROLER pLcdControler, ULONG ulVector)
-{
- UINT uiStatus;
-
- uiStatus = RasterIntStatus(pLcdControler->LCDC_ulVirtAddrBase,
- RASTER_END_OF_FRAME0_INT_STAT |
- RASTER_END_OF_FRAME1_INT_STAT);
-
- uiStatus = RasterClearGetIntStatus(pLcdControler->LCDC_ulVirtAddrBase, uiStatus);
-
- if (uiStatus & RASTER_END_OF_FRAME0_INT_STAT) {
- RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
- (UINT)__LCD_MEM_HDR_BASE,
- (UINT)__LCD_FRAMEBUFFER_END,
- 0);
- }
-
- if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
- if (uiStatus & RASTER_END_OF_FRAME1_INT_STAT) {
- RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
- (UINT)__LCD_MEM_HDR_BASE,
- (UINT)__LCD_FRAMEBUFFER_END,
- 1);
- }
- }
-
- return (LW_IRQ_HANDLED);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdOn
-** 功能描述: 打开 LCD 控制器
-** 输 入 : pLcdControler LCD 控制器
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xLcdOn (__PAM335X_LCD_CONTROLER pLcdControler)
-{
- RasterEnable(pLcdControler->LCDC_ulVirtAddrBase); /* Enable raster */
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdOff
-** 功能描述: 关闭 LCD 控制器
-** 输 入 : pLcdControler LCD 控制器
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xLcdOff (__PAM335X_LCD_CONTROLER pLcdControler)
-{
- RasterEnable(pLcdControler->LCDC_ulVirtAddrBase); /* Enable raster */
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdInit
-** 功能描述: 初始化 LCD
-** 输 入 : pLcdControler LCD 控制器
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xLcdInit (__PAM335X_LCD_CONTROLER pLcdControler)
-{
- static UINT32 uiHdr[] = {0x4000u, 0x0000u, 0x0000u, 0x0000u,
- 0x0000u, 0x0000u, 0x0000u, 0x0000u};
- PVOID pvVirtAddr;
-
- if (!pLcdControler->LCDC_bIsInit) {
-
- pLcdControler->LCDC_ulVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
- (PVOID)pLcdControler->LCDC_ulPhyAddrBase,
- pLcdControler->LCDC_stPhyAddrSize);
- if (!pLcdControler->LCDC_ulVirtAddrBase) {
- printk(KERN_ERR "__am335xLcdInit(): failed to remap!\n");
- goto __error_handle;
- }
-
- pLcdControler->LCDC_pvLcdMemBase = API_VmmPhyAllocAlign(__LCD_FRAMEBUFFER_TOTAL_SIZE,
- LW_CFG_VMM_PAGE_SIZE,
- LW_ZONE_ATTR_DMA);
- if (pLcdControler->LCDC_pvLcdMemBase == LW_NULL) {
- printk(KERN_ERR "__am335xLcdInit(): low vmm memory!\n");
- goto __error_handle;
- }
-
- pvVirtAddr = API_VmmIoRemapNocache((PVOID)__LCD_MEM_BASE, LW_CFG_VMM_PAGE_SIZE);
- if (pvVirtAddr == LW_NULL) {
- printk(KERN_ERR "__am335xLcdInit(): failed to remap lcd mem!\n");
- goto __error_handle;
- }
-
- lib_memcpy((PVOID)((ULONG)pvVirtAddr + __LCD_MEM_HDR_OFFSET), (CPVOID)uiHdr, sizeof(uiHdr));
-
- API_VmmIoUnmap((PVOID)pvVirtAddr);
- pvVirtAddr = LW_NULL;
-
- if (__am335xLcdHwInit(pLcdControler) != ERROR_NONE) {
- printk(KERN_ERR "__am335xLcdInit(): failed to remap lcd mem!\n");
- goto __error_handle;
- }
-
- /*
- * Configuring the base ceiling
- */
- RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
- (UINT)__LCD_MEM_HDR_BASE,
- (UINT)__LCD_FRAMEBUFFER_END,
- 0);
-
- if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
- RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
- (UINT)__LCD_MEM_HDR_BASE,
- (UINT)__LCD_FRAMEBUFFER_END,
- 1);
- }
-
- if (pLcdControler->LCDC_bInterruptEn > 0) {
- API_InterVectorConnect(pLcdControler->LCDC_ulVector,
- (PINT_SVR_ROUTINE)__am335xLcdIsr,
- pLcdControler,
- "lcd_isr"); /* 安装操作系统中断向量表 */
-
- IntPrioritySet(pLcdControler->LCDC_ulVector,
- pLcdControler->LCDC_uiIntPriority,
- AINTC_HOSTINT_ROUTE_IRQ);
- }
-
- if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
- /*
- * Enable End of frame0/frame1 interrupt
- */
- RasterIntEnable(pLcdControler->LCDC_ulVirtAddrBase,
- RASTER_END_OF_FRAME0_INT | RASTER_END_OF_FRAME1_INT);
- } else {
- /*
- * Enable End of frame0 interrupt
- */
- RasterIntEnable(pLcdControler->LCDC_ulVirtAddrBase, RASTER_END_OF_FRAME0_INT);
- }
-
- pLcdControler->LCDC_bIsInit = LW_TRUE;
- }
-
- return (ERROR_NONE);
-
- __error_handle:
-
- if (pvVirtAddr) {
- API_VmmIoUnmap(pvVirtAddr);
- pvVirtAddr = 0;
- }
-
- if (pLcdControler->LCDC_pvLcdMemBase) {
- API_VmmPhyFree(pLcdControler->LCDC_pvLcdMemBase);
- pLcdControler->LCDC_pvLcdMemBase = LW_NULL;
- }
-
- if (pLcdControler->LCDC_ulVirtAddrBase) {
- API_VmmIoUnmap((PVOID)pLcdControler->LCDC_ulVirtAddrBase);
- pLcdControler->LCDC_ulVirtAddrBase = 0;
- }
-
- return (PX_ERROR);
-}
-/*********************************************************************************************************
- 全局变量
-*********************************************************************************************************/
-static LW_GM_FILEOPERATIONS _G_am335xGmFileOper;
-/*********************************************************************************************************
- 驱动函数
-*********************************************************************************************************/
-static INT __am335xLcdOpen(PLW_GM_DEVICE pGmDev, INT iFlag, INT iMode);
-static INT __am335xLcdClose(PLW_GM_DEVICE pGmDev);
-static INT __am335xLcdGetVarInfo(PLW_GM_DEVICE pGmDev, PLW_GM_VARINFO pGmVi);
-static INT __am335xLcdGetScrInfo(PLW_GM_DEVICE pGmDev, PLW_GM_SCRINFO pGmSi);
-/*********************************************************************************************************
-** 函数名称: __am335xLcdOpen
-** 功能描述: 打开 LCD 设备
-** 输 入 : pGmDev 图形设备
-** iFlag 标志
-** iMode 模式
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xLcdOpen (PLW_GM_DEVICE pGmDev, INT iFlag, INT iMode)
-{
- __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
-
- if (__am335xLcdInit(pLcdControler) != ERROR_NONE) {
- printk(KERN_ERR "__am335xLcdOpen(): failed to init!\n");
- return (PX_ERROR);
- }
-
- __am335xLcdOn(pLcdControler);
-
- if (pLcdControler->LCDC_bInterruptEn > 0) {
- API_InterVectorEnable(pLcdControler->LCDC_ulVector);
- }
-
- if (pLcdControler->LCDC_pData->pfuncPanelPowerCtrl) {
- pLcdControler->LCDC_pData->pfuncPanelPowerCtrl(LW_TRUE);
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdClose
-** 功能描述: 关闭 LCD 设备
-** 输 入 : pGmDev 图形设备
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xLcdClose (PLW_GM_DEVICE pGmDev)
-{
- __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
-
- if (pLcdControler->LCDC_pData->pfuncPanelPowerCtrl) {
- pLcdControler->LCDC_pData->pfuncPanelPowerCtrl(LW_FALSE);
- }
-
- if (pLcdControler->LCDC_bInterruptEn > 0) {
- API_InterVectorDisable(pLcdControler->LCDC_ulVector);
- }
-
- __am335xLcdOff(pLcdControler);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdGetVarInfo
-** 功能描述: 获得 LCD 设备 LW_GM_VARINFO 参数
-** 输 入 : pGmDev 图形设备
-** pGmVi LW_GM_VARINFO 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xLcdGetVarInfo (PLW_GM_DEVICE pGmDev, PLW_GM_VARINFO pGmVi)
-{
- __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
-
- if (pGmVi) {
- pGmVi->GMVI_ulXRes = __LCD_XSIZE;
- pGmVi->GMVI_ulYRes = __LCD_YSIZE;
-
- pGmVi->GMVI_ulXResVirtual = __LCD_XSIZE;
- pGmVi->GMVI_ulYResVirtual = __LCD_YSIZE;
-
- pGmVi->GMVI_ulXOffset = 0;
- pGmVi->GMVI_ulYOffset = 0;
-
- pGmVi->GMVI_ulBitsPerPixel = __LCD_BITS_PER_PIXEL;
- pGmVi->GMVI_ulBytesPerPixel = __LCD_BYTES_PER_PIXEL;
-
- switch (__LCD_BITS_PER_PIXEL) {
- case 16:
- pGmVi->GMVI_ulGrayscale = (1 << __LCD_BITS_PER_PIXEL);
- pGmVi->GMVI_ulRedMask = 0xF800;
- pGmVi->GMVI_ulGreenMask = 0x07E0;
- pGmVi->GMVI_ulBlueMask = 0x001F;
- pGmVi->GMVI_ulTransMask = 0;
- break;
-
- case 24:
- pGmVi->GMVI_ulGrayscale = (1 << __LCD_BITS_PER_PIXEL);
- pGmVi->GMVI_ulRedMask = 0xFF0000;
- pGmVi->GMVI_ulGreenMask = 0x00FF00;
- pGmVi->GMVI_ulBlueMask = 0x0000FF;
- pGmVi->GMVI_ulTransMask = 0;
- break;
-
- case 32:
- pGmVi->GMVI_ulGrayscale = (1 << __LCD_BITS_PER_PIXEL);
- pGmVi->GMVI_ulRedMask = 0x00FF0000;
- pGmVi->GMVI_ulGreenMask = 0x0000FF00;
- pGmVi->GMVI_ulBlueMask = 0x000000FF;
- pGmVi->GMVI_ulTransMask = 0xFF000000;
- break;
-
- default:
- return (PX_ERROR);
- }
-
- pGmVi->GMVI_bHardwareAccelerate = LW_FALSE;
- pGmVi->GMVI_ulMode = LW_GM_SET_MODE;
- pGmVi->GMVI_ulStatus = 0;
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xLcdGetScrInfo
-** 功能描述: 获得 LCD 设备 PLW_GM_SCRINFO 参数
-** 输 入 : pGmDev 图形设备
-** pGmSi PLW_GM_SCRINFO 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xLcdGetScrInfo (PLW_GM_DEVICE pGmDev, PLW_GM_SCRINFO pGmSi)
-{
- __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
-
- if (pGmSi) {
- pGmSi->GMSI_pcName = (PCHAR)pLcdControler->LCDC_pcName;
- pGmSi->GMSI_ulId = 0;
- pGmSi->GMSI_stMemSize = __LCD_FRAMEBUFFER_SIZE;
- pGmSi->GMSI_stMemSizePerLine = __LCD_XSIZE * __LCD_BYTES_PER_PIXEL;
- pGmSi->GMSI_pcMem = (caddr_t)__LCD_FRAMEBUFFER_BASE;
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: lcdDevCreate
-** 功能描述: 创建 LCD 设备
-** 输 入 : cpcName 设备名
-** pPinMux 管脚复用
-** pData LCD 驱动数据
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-INT lcdDevCreate (CPCHAR cpcName, PAM335X_PINMUX pPinMux, PAM335X_LCD_DATA pData)
-{
- __PAM335X_LCD_CONTROLER pLcdControler = &_G_am335xLcdControler;
- INT i;
-
- if (cpcName == LW_NULL || pData == LW_NULL) {
- return (PX_ERROR);
- }
-
- for (i = 0; i < sizeof(__G_am335xKnownLcdPanels)/sizeof(__G_am335xKnownLcdPanels[0]); i++) {
- if (strcmp(__G_am335xKnownLcdPanels[i].acName, pData->acType) == 0) {
- break;
- }
- }
-
- if (i == sizeof(__G_am335xKnownLcdPanels)/sizeof(__G_am335xKnownLcdPanels[0])) {
- return (PX_ERROR);
- }
-
- /*
- * 仅支持 framebuffer 模式.
- */
- _G_am335xGmFileOper.GMFO_pfuncOpen = __am335xLcdOpen;
- _G_am335xGmFileOper.GMFO_pfuncClose = __am335xLcdClose;
- _G_am335xGmFileOper.GMFO_pfuncGetVarInfo = (INT (*)(LONG, PLW_GM_VARINFO))__am335xLcdGetVarInfo;
- _G_am335xGmFileOper.GMFO_pfuncGetScrInfo = (INT (*)(LONG, PLW_GM_SCRINFO))__am335xLcdGetScrInfo;
-
- pLcdControler->LCDC_gmDev.GMDEV_gmfileop = &_G_am335xGmFileOper;
- pLcdControler->LCDC_gmDev.GMDEV_ulMapFlags = LW_VMM_FLAG_DMA | LW_VMM_FLAG_BUFFERABLE;
-
- pLcdControler->LCDC_pPinMux = pPinMux;
- pLcdControler->LCDC_pcName = cpcName;
- pLcdControler->LCDC_pData = pData;
- pLcdControler->LCDC_pCtrlConfig = pData->pCtrlConfig;
- pLcdControler->LCDC_pPanel = &__G_am335xKnownLcdPanels[i];
-
- return (gmemDevAdd(pLcdControler->LCDC_pcName, &pLcdControler->LCDC_gmDev));
-}
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: am335x_lcd.c
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 08 日
+**
+** 描 述: AM335X 处理器 LCD 驱动
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "config.h"
+#include "SylixOS.h"
+#include "string.h"
+
+#include "driver/am335x_common.h"
+#include "raster.h"
+#include "am335x_lcd.h"
+/*********************************************************************************************************
+ LCD 面板定义
+*********************************************************************************************************/
+typedef struct {
+ const CHAR acName[25]; /* Full name <vendor>_<model> */
+ INT iWidth;
+ INT iHeight;
+ INT iHfp; /* Horizontal front porch */
+ INT iHbp; /* Horizontal back porch */
+ INT iHsw; /* Horizontal Sync Pulse Width */
+ INT iVfp; /* Vertical front porch */
+ INT iVbp; /* Vertical back porch */
+ INT iVsw; /* Vertical Sync Pulse Width */
+ UINT uiPixelClk; /* Pixel clock */
+ BOOL bInvertPixelClk; /* Invert Pixel clock */
+} __AM335X_LCD_PANEL, *__PAM335X_LCD_PANEL;
+/*********************************************************************************************************
+ LCD 控制器类型定义
+*********************************************************************************************************/
+typedef struct {
+ addr_t LCDC_ulPhyAddrBase; /* 物理地址基地址 */
+ size_t LCDC_stPhyAddrSize; /* 物理地址空间大小 */
+ ULONG LCDC_ulVector; /* 中断向量 */
+ UINT LCDC_uiIntPriority; /* 中断优先级 */
+ BOOL LCDC_bDoubleFrameBufferEn; /* 是否使用双缓冲区 */
+ BOOL LCDC_bInterruptEn; /* 是否使用中断 */
+ CPCHAR LCDC_pcName; /* 设备名 */
+
+ PAM335X_PINMUX LCDC_pPinMux;
+ addr_t LCDC_ulVirtAddrBase; /* 虚拟地址基地址 */
+ VOID *LCDC_pvLcdMemBase; /* LCD 内存基地址 */
+ BOOL LCDC_bIsInit; /* 是否已经初始化 */
+ LW_GM_DEVICE LCDC_gmDev; /* 图形设备 */
+ __PAM335X_LCD_PANEL LCDC_pPanel;
+ PAM335X_LCD_DATA LCDC_pData;
+ PAM335X_LCD_CTRL_CONFIG LCDC_pCtrlConfig;
+} __AM335X_LCD_CONTROLER, *__PAM335X_LCD_CONTROLER;
+/*********************************************************************************************************
+ LCD 控制器
+*********************************************************************************************************/
+static __AM335X_LCD_CONTROLER _G_am335xLcdControler = {
+ SOC_LCDC_0_REGS,
+ LW_CFG_VMM_PAGE_SIZE,
+ SYS_INT_LCDCINT,
+ BSP_CFG_LCD_INT_PRIO,
+ LW_FALSE,
+ LW_FALSE,
+};
+/*********************************************************************************************************
+ 已知的 LCD 面板
+*********************************************************************************************************/
+static __AM335X_LCD_PANEL __G_am335xKnownLcdPanels[] = {
+ /* Sharp LCD035Q3DG01 */
+ [0] = {
+ .acName = "Sharp_LCD035Q3DG01",
+ .iWidth = 320,
+ .iHeight = 240,
+ .iHfp = 8,
+ .iHbp = 6,
+ .iHsw = 0,
+ .iVfp = 2,
+ .iVbp = 2,
+ .iVsw = 0,
+ .uiPixelClk = 4608000,
+ .bInvertPixelClk = 1,
+ },
+ /* Sharp LK043T1DG01 */
+ [1] = {
+ .acName = "Sharp_LK043T1DG01",
+ .iWidth = 480,
+ .iHeight = 272,
+ .iHfp = 2,
+ .iHbp = 2,
+ .iHsw = 41,
+ .iVfp = 3,
+ .iVbp = 3,
+ .iVsw = 10,
+ .uiPixelClk = 7833600,
+ .bInvertPixelClk = 0,
+ },
+ /* ThreeFive S9700RTWV35TR */
+ [2] = {
+ .acName = "TFC_S9700RTWV35TR_01B",
+ .iWidth = 800,
+ .iHeight = 480,
+ .iHfp = 39,
+ .iHbp = 39,
+ .iHsw = 47,
+ .iVfp = 13,
+ .iVbp = 29,
+ .iVsw = 2,
+ .uiPixelClk = 30000000,
+ .bInvertPixelClk = 0,
+ },
+ [3] = {
+ .acName = "NHD-5.0-ATXI#-T-1",
+ .iWidth = 800,
+ .iHeight = 480,
+ .iHfp = 8,
+ .iHbp = 43,
+ .iHsw = 40,
+ .iVfp = 4,
+ .iVbp = 12,
+ .iVsw = 3,
+ .uiPixelClk = 30000000,
+ .bInvertPixelClk = 0,
+ },
+ /* Newhaven Display */
+ [4] = {
+ .acName = "NHD-7.0-ATXI#-T-1",
+ .iWidth = 800,
+ .iHeight = 480,
+ .iHfp = 112,
+ .iHbp = 88,
+ .iHsw = 48,
+ .iVfp = 21,
+ .iVbp = 39,
+ .iVsw = 3,
+ .uiPixelClk = 40000000,
+ .bInvertPixelClk = 0,
+ },
+ [5] = {
+ .acName = "NHD-8.0-ATXI#-T-1",
+ .iWidth = 800,
+ .iHeight = 600,
+ .iHfp = 112,
+ .iHbp = 88,
+ .iHsw = 48,
+ .iVfp = 21,
+ .iVbp = 39,
+ .iVsw = 3,
+ .uiPixelClk = 40000000,
+ .bInvertPixelClk = 0,
+ },
+ [6] = {
+ /* 720 x 480 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "nxp-720x480@60",
+ .iWidth = 720,
+ .iHeight = 480,
+ .iHfp = 15,
+ .iHbp = 59,
+ .iHsw = 61,
+ .iVfp = 9,
+ .iVbp = 30,
+ .iVsw = 5,
+ .uiPixelClk = 27027000,
+ .bInvertPixelClk = 0,
+ },
+ [7] = {
+ /* 1280 x 720 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "nxp-1280x720@60",
+ .iWidth = 1280,
+ .iHeight = 720,
+ .iHfp = 95,
+ .iHbp =190,
+ .iHsw = 34,
+ .iVfp = 5,
+ .iVbp = 20,
+ .iVsw = 5,
+ .uiPixelClk = 64000000,
+ .bInvertPixelClk = 0,
+ },
+ [8] = {
+ /* 1024 x 768 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "nxp-1024x768@60",
+ .iWidth = 1024,
+ .iHeight = 768,
+ .iHfp = 28,
+ .iHbp = 158,
+ .iHsw = 136,
+ .iVfp = 3,
+ .iVbp = 28,
+ .iVsw = 5,
+ .uiPixelClk = 64000000,
+ .bInvertPixelClk = 0,
+ },
+ [9] = {
+ /* 800 x 600 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "nxp-800x600@60",
+ .iWidth = 800,
+ .iHeight = 600,
+ .iHfp = 42,
+ .iHbp = 144,
+ .iHsw = 58,
+ .iVfp = 1,
+ .iVbp = 25,
+ .iVsw = 3,
+ .uiPixelClk = 41000000,
+ .bInvertPixelClk = 0,
+ },
+ [10] = {
+ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "nxp-640x480@60",
+ .iWidth = 640,
+ .iHeight = 480,
+ .iHfp = 19,
+ .iHbp = 79,
+ .iHsw = 59,
+ .iVfp = 9,
+ .iVbp = 30,
+ .iVsw = 6,
+ .uiPixelClk = 25200000,
+ .bInvertPixelClk = 0,
+ },
+ [11] = {
+ /* 1920 x 1080 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "nxp-1920x1080@24",
+ .iWidth = 1920,
+ .iHeight = 1080,
+ .iHfp = 103,
+ .iHbp = 311,
+ .iHsw = 31,
+ .iVfp = 37,
+ .iVbp = 60,
+ .iVsw = 8,
+ .uiPixelClk = 96000000,
+ .bInvertPixelClk = 0,
+ },
+ [12] = {
+ /* 1920 x 1080 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "NHD-4.3-ATXI#-T-1",
+ .iWidth = 480,
+ .iHeight = 272,
+ .iHfp = 1,
+ .iHbp = 1,
+ .iHsw = 40,
+ .iVfp = 2,
+ .iVbp = 2,
+ .iVsw = 10,
+ .uiPixelClk = 9000000,
+ .bInvertPixelClk = 0,
+ },
+ [13] = {
+ /* 1920 x 1080 @ 60 Hz Reduced blanking VESA CVT 0.79M3-R */
+ .acName = "NHD-10.4-ATXI#-T-1",
+ .iWidth = 800,
+ .iHeight = 600,
+ .iHfp = 112,
+ .iHbp = 88,
+ .iHsw = 48,
+ .iVfp = 21,
+ .iVbp = 39,
+ .iVsw = 3,
+ .uiPixelClk = 40000000,
+ .bInvertPixelClk = 0,
+ },
+ [14] = {
+ /* 1024 x 768 @ 60 Hz Reduced blanking ADV7123 */
+ .acName = "ADV7123",
+ .iWidth = 1024,
+ .iHeight = 768,
+ .iHfp = 112,
+ .iHbp = 88,
+ .iHsw = 48,
+ .iVfp = 21,
+ .iVbp = 39,
+ .iVsw = 3,
+ .uiPixelClk = 58982400,
+ .bInvertPixelClk = 0,
+ },
+};
+/*********************************************************************************************************
+ FrameBuffer 相关定义
+*********************************************************************************************************/
+#define __LCD_XSIZE pLcdControler->LCDC_pPanel->iWidth
+#define __LCD_YSIZE pLcdControler->LCDC_pPanel->iHeight
+#define __LCD_BITS_PER_PIXEL pLcdControler->LCDC_pCtrlConfig->iBitsPerPixel
+#define __LCD_BYTES_PER_PIXEL (__LCD_BITS_PER_PIXEL / 8)
+
+#define __LCD_MEM_BASE ((ULONG)pLcdControler->LCDC_pvLcdMemBase)
+#define __LCD_MEM_HDR_SIZE 32
+#define __LCD_MEM_HDR_OFFSET (LW_CFG_VMM_PAGE_SIZE - __LCD_MEM_HDR_SIZE)
+#define __LCD_MEM_HDR_BASE (__LCD_MEM_BASE + __LCD_MEM_HDR_OFFSET)
+#define __LCD_FRAMEBUFFER_BASE (__LCD_MEM_BASE + LW_CFG_VMM_PAGE_SIZE)
+#define __LCD_FRAMEBUFFER_SIZE (__LCD_XSIZE * __LCD_YSIZE * __LCD_BYTES_PER_PIXEL)
+#define __LCD_FRAMEBUFFER_END (__LCD_FRAMEBUFFER_BASE + __LCD_FRAMEBUFFER_SIZE - \
+ __LCD_BYTES_PER_PIXEL)
+#define __LCD_FRAMEBUFFER_TOTAL_SIZE (LW_CFG_VMM_PAGE_SIZE + __LCD_FRAMEBUFFER_SIZE)
+/*********************************************************************************************************
+** 函数名称: __am335xLcdHwInit
+** 功能描述: 初始化 LCD 硬件
+** 输 入 : pLcdControler LCD 控制器
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xLcdHwInit (__PAM335X_LCD_CONTROLER pLcdControler)
+{
+ __PAM335X_LCD_PANEL pPanel = pLcdControler->LCDC_pPanel;
+ PAM335X_LCD_CTRL_CONFIG pCtrlConfig = pLcdControler->LCDC_pCtrlConfig;
+ UINT32 uiValue;
+ UINT32 uiBurstSize;
+ UINT32 uiFifoThreshold;
+
+ /*
+ * Enable clock for LCD Module
+ */
+ am335xEnableModuleClock(am335xModuleIdGet("LCDC"));
+
+ am335xPinMuxSetup(pLcdControler->LCDC_pPinMux);
+
+ /*
+ * Clock for DMA,LIDD and for Core(which encompasses
+ * Raster Active Matrix and Passive Matrix logic)
+ * enabled.
+ */
+ RasterClocksEnable(pLcdControler->LCDC_ulVirtAddrBase);
+
+ /*
+ * Disable raster
+ */
+ RasterDisable(pLcdControler->LCDC_ulVirtAddrBase);
+
+ /*
+ * Configure the pclk
+ */
+ RasterClkConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ pPanel->uiPixelClk,
+ 192000000);
+
+ /*
+ * Configuring DMA of LCD controller
+ */
+ switch (pCtrlConfig->iDmaBurstSize) {
+ case 1:
+ uiBurstSize = RASTER_BURST_SIZE_1;
+ break;
+
+ case 2:
+ uiBurstSize = RASTER_BURST_SIZE_2;
+ break;
+
+ case 4:
+ uiBurstSize = RASTER_BURST_SIZE_4;
+ break;
+
+ case 8:
+ uiBurstSize = RASTER_BURST_SIZE_8;
+ break;
+
+ case 16:
+ uiBurstSize = RASTER_BURST_SIZE_16;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ switch (pCtrlConfig->iFifoThreshold) {
+ case 8:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_8;
+ break;
+
+ case 16:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_16;
+ break;
+
+ case 32:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_32;
+ break;
+
+ case 64:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_64;
+ break;
+
+ case 128:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_128;
+ break;
+
+ case 256:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_256;
+ break;
+
+ case 512:
+ uiFifoThreshold = RASTER_FIFO_THRESHOLD_512;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
+ RasterDMAConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ RASTER_DOUBLE_FRAME_BUFFER,
+ uiBurstSize,
+ uiFifoThreshold,
+ RASTER_BIG_ENDIAN_DISABLE);
+ } else {
+ RasterDMAConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ RASTER_SINGLE_FRAME_BUFFER,
+ uiBurstSize,
+ uiFifoThreshold,
+ RASTER_BIG_ENDIAN_DISABLE);
+ }
+
+ /*
+ * Configuring modes(ex:tft or stn,color or monochrome etc) for raster controller
+ */
+ switch (__LCD_BITS_PER_PIXEL) {
+ case 16:
+ RasterModeConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ RASTER_DISPLAY_MODE_TFT,
+ RASTER_PALETTE_DATA,
+ RASTER_COLOR,
+ RASTER_RIGHT_ALIGNED);
+ break;
+
+ case 24:
+ case 32:
+ RasterModeConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ RASTER_DISPLAY_MODE_TFT_UNPACKED,
+ RASTER_PALETTE_DATA,
+ RASTER_COLOR,
+ RASTER_RIGHT_ALIGNED);
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ /*
+ * Configuring the polarity of timing parameters of raster controller
+ */
+ uiValue = 0;
+
+ if (pCtrlConfig->bInvertFrameClock) {
+ uiValue |= RASTER_FRAME_CLOCK_LOW;
+ } else {
+ uiValue |= RASTER_FRAME_CLOCK_HIGH;
+ }
+
+ if (pCtrlConfig->bInvertLineClock) {
+ uiValue |= RASTER_LINE_CLOCK_LOW;
+ } else {
+ uiValue |= RASTER_LINE_CLOCK_HIGH;
+ }
+
+ if (pPanel->bInvertPixelClk) {
+ uiValue |= RASTER_PIXEL_CLOCK_LOW;
+ } else {
+ uiValue |= RASTER_PIXEL_CLOCK_HIGH;
+ }
+
+ if (pCtrlConfig->bSyncEdge) {
+ uiValue |= RASTER_SYNC_EDGE_FALLING;
+ } else {
+ uiValue |= RASTER_SYNC_EDGE_RISING;
+ }
+
+ if (pCtrlConfig->bSyncCtrl) {
+ uiValue |= RASTER_SYNC_CTRL_ACTIVE;
+ } else {
+ uiValue |= RASTER_SYNC_CTRL_INACTIVE;
+ }
+
+ uiValue |= RASTER_AC_BIAS_HIGH;
+
+ RasterTiming2Configure(pLcdControler->LCDC_ulVirtAddrBase,
+ uiValue,
+ pCtrlConfig->iAcBiasInterrupt,
+ pCtrlConfig->iAcBias);
+
+ /*
+ * Configuring horizontal timing parameter
+ */
+ RasterHparamConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ __LCD_XSIZE,
+ pPanel->iHsw,
+ pPanel->iHfp,
+ pPanel->iHbp);
+
+ /*
+ * Configuring vertical timing parameters
+ */
+ RasterVparamConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ __LCD_YSIZE,
+ pPanel->iVsw,
+ pPanel->iVfp,
+ pPanel->iVbp);
+
+ RasterFIFODMADelayConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ pCtrlConfig->iFifoDmaDelay);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdIsr
+** 功能描述: LCD 中断服务例程
+** 输 入 : pLcdControler LCD 控制器
+** ulVector 中断向量
+** 输 出 : 中断返回值
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static irqreturn_t __am335xLcdIsr (__PAM335X_LCD_CONTROLER pLcdControler, ULONG ulVector)
+{
+ UINT uiStatus;
+
+ uiStatus = RasterIntStatus(pLcdControler->LCDC_ulVirtAddrBase,
+ RASTER_END_OF_FRAME0_INT_STAT |
+ RASTER_END_OF_FRAME1_INT_STAT);
+
+ uiStatus = RasterClearGetIntStatus(pLcdControler->LCDC_ulVirtAddrBase, uiStatus);
+
+ if (uiStatus & RASTER_END_OF_FRAME0_INT_STAT) {
+ RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ (UINT)__LCD_MEM_HDR_BASE,
+ (UINT)__LCD_FRAMEBUFFER_END,
+ 0);
+ }
+
+ if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
+ if (uiStatus & RASTER_END_OF_FRAME1_INT_STAT) {
+ RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ (UINT)__LCD_MEM_HDR_BASE,
+ (UINT)__LCD_FRAMEBUFFER_END,
+ 1);
+ }
+ }
+
+ return (LW_IRQ_HANDLED);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdOn
+** 功能描述: 打开 LCD 控制器
+** 输 入 : pLcdControler LCD 控制器
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xLcdOn (__PAM335X_LCD_CONTROLER pLcdControler)
+{
+ RasterEnable(pLcdControler->LCDC_ulVirtAddrBase); /* Enable raster */
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdOff
+** 功能描述: 关闭 LCD 控制器
+** 输 入 : pLcdControler LCD 控制器
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xLcdOff (__PAM335X_LCD_CONTROLER pLcdControler)
+{
+ RasterEnable(pLcdControler->LCDC_ulVirtAddrBase); /* Enable raster */
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdInit
+** 功能描述: 初始化 LCD
+** 输 入 : pLcdControler LCD 控制器
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xLcdInit (__PAM335X_LCD_CONTROLER pLcdControler)
+{
+ static UINT32 uiHdr[] = {0x4000u, 0x0000u, 0x0000u, 0x0000u,
+ 0x0000u, 0x0000u, 0x0000u, 0x0000u};
+ PVOID pvVirtAddr;
+
+ if (!pLcdControler->LCDC_bIsInit) {
+
+ pLcdControler->LCDC_ulVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
+ (PVOID)pLcdControler->LCDC_ulPhyAddrBase,
+ pLcdControler->LCDC_stPhyAddrSize);
+ if (!pLcdControler->LCDC_ulVirtAddrBase) {
+ printk(KERN_ERR "__am335xLcdInit(): failed to remap!\n");
+ goto __error_handle;
+ }
+
+ pLcdControler->LCDC_pvLcdMemBase = API_VmmPhyAllocAlign(__LCD_FRAMEBUFFER_TOTAL_SIZE,
+ LW_CFG_VMM_PAGE_SIZE,
+ LW_ZONE_ATTR_DMA);
+ if (pLcdControler->LCDC_pvLcdMemBase == LW_NULL) {
+ printk(KERN_ERR "__am335xLcdInit(): low vmm memory!\n");
+ goto __error_handle;
+ }
+
+ pvVirtAddr = API_VmmIoRemapNocache((PVOID)__LCD_MEM_BASE, LW_CFG_VMM_PAGE_SIZE);
+ if (pvVirtAddr == LW_NULL) {
+ printk(KERN_ERR "__am335xLcdInit(): failed to remap lcd mem!\n");
+ goto __error_handle;
+ }
+
+ lib_memcpy((PVOID)((ULONG)pvVirtAddr + __LCD_MEM_HDR_OFFSET), (CPVOID)uiHdr, sizeof(uiHdr));
+
+ API_VmmIoUnmap((PVOID)pvVirtAddr);
+ pvVirtAddr = LW_NULL;
+
+ if (__am335xLcdHwInit(pLcdControler) != ERROR_NONE) {
+ printk(KERN_ERR "__am335xLcdInit(): failed to remap lcd mem!\n");
+ goto __error_handle;
+ }
+
+ /*
+ * Configuring the base ceiling
+ */
+ RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ (UINT)__LCD_MEM_HDR_BASE,
+ (UINT)__LCD_FRAMEBUFFER_END,
+ 0);
+
+ if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
+ RasterDMAFBConfig(pLcdControler->LCDC_ulVirtAddrBase,
+ (UINT)__LCD_MEM_HDR_BASE,
+ (UINT)__LCD_FRAMEBUFFER_END,
+ 1);
+ }
+
+ if (pLcdControler->LCDC_bInterruptEn > 0) {
+ API_InterVectorConnect(pLcdControler->LCDC_ulVector,
+ (PINT_SVR_ROUTINE)__am335xLcdIsr,
+ pLcdControler,
+ "lcd_isr"); /* 安装操作系统中断向量表 */
+
+ IntPrioritySet(pLcdControler->LCDC_ulVector,
+ pLcdControler->LCDC_uiIntPriority,
+ AINTC_HOSTINT_ROUTE_IRQ);
+ }
+
+ if (pLcdControler->LCDC_bDoubleFrameBufferEn > 0) {
+ /*
+ * Enable End of frame0/frame1 interrupt
+ */
+ RasterIntEnable(pLcdControler->LCDC_ulVirtAddrBase,
+ RASTER_END_OF_FRAME0_INT | RASTER_END_OF_FRAME1_INT);
+ } else {
+ /*
+ * Enable End of frame0 interrupt
+ */
+ RasterIntEnable(pLcdControler->LCDC_ulVirtAddrBase, RASTER_END_OF_FRAME0_INT);
+ }
+
+ pLcdControler->LCDC_bIsInit = LW_TRUE;
+ }
+
+ return (ERROR_NONE);
+
+ __error_handle:
+
+ if (pvVirtAddr) {
+ API_VmmIoUnmap(pvVirtAddr);
+ pvVirtAddr = 0;
+ }
+
+ if (pLcdControler->LCDC_pvLcdMemBase) {
+ API_VmmPhyFree(pLcdControler->LCDC_pvLcdMemBase);
+ pLcdControler->LCDC_pvLcdMemBase = LW_NULL;
+ }
+
+ if (pLcdControler->LCDC_ulVirtAddrBase) {
+ API_VmmIoUnmap((PVOID)pLcdControler->LCDC_ulVirtAddrBase);
+ pLcdControler->LCDC_ulVirtAddrBase = 0;
+ }
+
+ return (PX_ERROR);
+}
+/*********************************************************************************************************
+ 全局变量
+*********************************************************************************************************/
+static LW_GM_FILEOPERATIONS _G_am335xGmFileOper;
+/*********************************************************************************************************
+ 驱动函数
+*********************************************************************************************************/
+static INT __am335xLcdOpen(PLW_GM_DEVICE pGmDev, INT iFlag, INT iMode);
+static INT __am335xLcdClose(PLW_GM_DEVICE pGmDev);
+static INT __am335xLcdGetVarInfo(PLW_GM_DEVICE pGmDev, PLW_GM_VARINFO pGmVi);
+static INT __am335xLcdGetScrInfo(PLW_GM_DEVICE pGmDev, PLW_GM_SCRINFO pGmSi);
+/*********************************************************************************************************
+** 函数名称: __am335xLcdOpen
+** 功能描述: 打开 LCD 设备
+** 输 入 : pGmDev 图形设备
+** iFlag 标志
+** iMode 模式
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xLcdOpen (PLW_GM_DEVICE pGmDev, INT iFlag, INT iMode)
+{
+ __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
+
+ if (__am335xLcdInit(pLcdControler) != ERROR_NONE) {
+ printk(KERN_ERR "__am335xLcdOpen(): failed to init!\n");
+ return (PX_ERROR);
+ }
+
+ __am335xLcdOn(pLcdControler);
+
+ if (pLcdControler->LCDC_bInterruptEn > 0) {
+ API_InterVectorEnable(pLcdControler->LCDC_ulVector);
+ }
+
+ if (pLcdControler->LCDC_pData->pfuncPanelPowerCtrl) {
+ pLcdControler->LCDC_pData->pfuncPanelPowerCtrl(LW_TRUE);
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdClose
+** 功能描述: 关闭 LCD 设备
+** 输 入 : pGmDev 图形设备
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xLcdClose (PLW_GM_DEVICE pGmDev)
+{
+ __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
+
+ if (pLcdControler->LCDC_pData->pfuncPanelPowerCtrl) {
+ pLcdControler->LCDC_pData->pfuncPanelPowerCtrl(LW_FALSE);
+ }
+
+ if (pLcdControler->LCDC_bInterruptEn > 0) {
+ API_InterVectorDisable(pLcdControler->LCDC_ulVector);
+ }
+
+ __am335xLcdOff(pLcdControler);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdGetVarInfo
+** 功能描述: 获得 LCD 设备 LW_GM_VARINFO 参数
+** 输 入 : pGmDev 图形设备
+** pGmVi LW_GM_VARINFO 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xLcdGetVarInfo (PLW_GM_DEVICE pGmDev, PLW_GM_VARINFO pGmVi)
+{
+ __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
+
+ if (pGmVi) {
+ pGmVi->GMVI_ulXRes = __LCD_XSIZE;
+ pGmVi->GMVI_ulYRes = __LCD_YSIZE;
+
+ pGmVi->GMVI_ulXResVirtual = __LCD_XSIZE;
+ pGmVi->GMVI_ulYResVirtual = __LCD_YSIZE;
+
+ pGmVi->GMVI_ulXOffset = 0;
+ pGmVi->GMVI_ulYOffset = 0;
+
+ pGmVi->GMVI_ulBitsPerPixel = __LCD_BITS_PER_PIXEL;
+ pGmVi->GMVI_ulBytesPerPixel = __LCD_BYTES_PER_PIXEL;
+
+ switch (__LCD_BITS_PER_PIXEL) {
+ case 16:
+ pGmVi->GMVI_ulGrayscale = (1 << __LCD_BITS_PER_PIXEL);
+ pGmVi->GMVI_ulRedMask = 0xF800;
+ pGmVi->GMVI_ulGreenMask = 0x07E0;
+ pGmVi->GMVI_ulBlueMask = 0x001F;
+ pGmVi->GMVI_ulTransMask = 0;
+ break;
+
+ case 24:
+ pGmVi->GMVI_ulGrayscale = (1 << __LCD_BITS_PER_PIXEL);
+ pGmVi->GMVI_ulRedMask = 0xFF0000;
+ pGmVi->GMVI_ulGreenMask = 0x00FF00;
+ pGmVi->GMVI_ulBlueMask = 0x0000FF;
+ pGmVi->GMVI_ulTransMask = 0;
+ break;
+
+ case 32:
+ pGmVi->GMVI_ulGrayscale = (1 << __LCD_BITS_PER_PIXEL);
+ pGmVi->GMVI_ulRedMask = 0x00FF0000;
+ pGmVi->GMVI_ulGreenMask = 0x0000FF00;
+ pGmVi->GMVI_ulBlueMask = 0x000000FF;
+ pGmVi->GMVI_ulTransMask = 0xFF000000;
+ break;
+
+ default:
+ return (PX_ERROR);
+ }
+
+ pGmVi->GMVI_bHardwareAccelerate = LW_FALSE;
+ pGmVi->GMVI_ulMode = LW_GM_SET_MODE;
+ pGmVi->GMVI_ulStatus = 0;
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xLcdGetScrInfo
+** 功能描述: 获得 LCD 设备 PLW_GM_SCRINFO 参数
+** 输 入 : pGmDev 图形设备
+** pGmSi PLW_GM_SCRINFO 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xLcdGetScrInfo (PLW_GM_DEVICE pGmDev, PLW_GM_SCRINFO pGmSi)
+{
+ __PAM335X_LCD_CONTROLER pLcdControler = container_of(pGmDev, __AM335X_LCD_CONTROLER, LCDC_gmDev);
+
+ if (pGmSi) {
+ pGmSi->GMSI_pcName = (PCHAR)pLcdControler->LCDC_pcName;
+ pGmSi->GMSI_ulId = 0;
+ pGmSi->GMSI_stMemSize = __LCD_FRAMEBUFFER_SIZE;
+ pGmSi->GMSI_stMemSizePerLine = __LCD_XSIZE * __LCD_BYTES_PER_PIXEL;
+ pGmSi->GMSI_pcMem = (caddr_t)__LCD_FRAMEBUFFER_BASE;
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: lcdDevCreate
+** 功能描述: 创建 LCD 设备
+** 输 入 : cpcName 设备名
+** pPinMux 管脚复用
+** pData LCD 驱动数据
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+INT lcdDevCreate (CPCHAR cpcName, PAM335X_PINMUX pPinMux, PAM335X_LCD_DATA pData)
+{
+ __PAM335X_LCD_CONTROLER pLcdControler = &_G_am335xLcdControler;
+ INT i;
+
+ if (cpcName == LW_NULL || pData == LW_NULL) {
+ return (PX_ERROR);
+ }
+
+ for (i = 0; i < sizeof(__G_am335xKnownLcdPanels)/sizeof(__G_am335xKnownLcdPanels[0]); i++) {
+ if (strcmp(__G_am335xKnownLcdPanels[i].acName, pData->acType) == 0) {
+ break;
+ }
+ }
+
+ if (i == sizeof(__G_am335xKnownLcdPanels)/sizeof(__G_am335xKnownLcdPanels[0])) {
+ return (PX_ERROR);
+ }
+
+ /*
+ * 仅支持 framebuffer 模式.
+ */
+ _G_am335xGmFileOper.GMFO_pfuncOpen = __am335xLcdOpen;
+ _G_am335xGmFileOper.GMFO_pfuncClose = __am335xLcdClose;
+ _G_am335xGmFileOper.GMFO_pfuncGetVarInfo = (INT (*)(LONG, PLW_GM_VARINFO))__am335xLcdGetVarInfo;
+ _G_am335xGmFileOper.GMFO_pfuncGetScrInfo = (INT (*)(LONG, PLW_GM_SCRINFO))__am335xLcdGetScrInfo;
+
+ pLcdControler->LCDC_gmDev.GMDEV_gmfileop = &_G_am335xGmFileOper;
+ pLcdControler->LCDC_gmDev.GMDEV_ulMapFlags = LW_VMM_FLAG_DMA | LW_VMM_FLAG_BUFFERABLE;
+
+ pLcdControler->LCDC_pPinMux = pPinMux;
+ pLcdControler->LCDC_pcName = cpcName;
+ pLcdControler->LCDC_pData = pData;
+ pLcdControler->LCDC_pCtrlConfig = pData->pCtrlConfig;
+ pLcdControler->LCDC_pPanel = &__G_am335xKnownLcdPanels[i];
+
+ return (gmemDevAdd(pLcdControler->LCDC_pcName, &pLcdControler->LCDC_gmDev));
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/mcasp/am335x_mcasp.c b/SylixOS/driver/mcasp/am335x_mcasp.c
index 026e7f0..89c9652 100644
--- a/SylixOS/driver/mcasp/am335x_mcasp.c
+++ b/SylixOS/driver/mcasp/am335x_mcasp.c
@@ -1,861 +1,936 @@
-/*********************************************************************************************************
-**
-** 中国软件开源组织
-**
-** 嵌入式实时操作系统
-**
-** SylixOS(TM)
-**
-** Copyright All Rights Reserved
-**
-**--------------文件信息--------------------------------------------------------------------------------
-**
-** 文 件 名: am335x_mcasp.c
-**
-** 创 建 人: Jiao.JinXing (焦进星)
-**
-** 文件创建日期: 2015 年 01 月 22 日
-**
-** 描 述: AM335X 处理器 McASP(Multichannel Audio Serial Port) 驱动(总线驱动部分)
-*********************************************************************************************************/
-#define __SYLIXOS_KERNEL
-#include "SylixOS.h"
-#include "system/device/sound/soundcard.h"
-
-#include "driver/am335x_common.h"
-#include "driver/audio/queue/queueLib.h"
-#include "driver/audio/codec/codecDrv.h"
-#include "driver/audio/dsp/dspDrv.h"
-
-#include "mcasp.h"
-#include "am335x_mcasp.h"
-/*********************************************************************************************************
- 定义
-*********************************************************************************************************/
-#define __MCASP_CHANNEL_NR (2)
-
-/* Slot size to send/receive data */
-#define __MCASP_DEFAULT_SLOT_SIZE (16)
-
-/* Word size to send/receive data. Word size <= Slot size */
-#define __MCASP_DEFAULT_WORD_SIZE (16)
-
-#define __MCASP_I2S_CHANNELS_NUM (2)
-
-#define __MCASP_I2S_SLOTS ((1 << __MCASP_I2S_CHANNELS_NUM) - 1)
-
-#define __MCASP_DMA_MAX_NODE_NUM (__DSP_MAX_FRAGMENT_NUM)
-
-#define __MCASP_DMA_QUEUE_SIZE (__MCASP_DMA_MAX_NODE_NUM + 1)
-
-#define __MCASP_DMA_OPT_FIFO_WIDTH (0x02)
-
-#define SNDRV_PCM_STREAM_PLAYBACK 0
-#define SNDRV_PCM_STREAM_CAPTURE 1
-/*********************************************************************************************************
- McASP 通道类型定义
-*********************************************************************************************************/
-typedef struct {
- addr_t MCASPCHAN_ulCtrlPhyAddrBase; /* CTRL 寄存器物理地址基地址 */
- size_t MCASPCHAN_stCtrlPhyAddrSize; /* CTRL 寄存器物理地址空间大小 */
-
- addr_t MCASPCHAN_ulDataPhyAddrBase; /* DATA 寄存器物理地址基地址 */
- addr_t MCASPCHAN_ulFifoRegOffset; /* FIFO 寄存器虚拟地址偏移 */
-
- UINT MCASPCHAN_uiTxDmaChannel; /* 发送 DMA 通道号 */
- UINT MCASPCHAN_uiRxDmaChannel; /* 接收 DMA 通道号 */
-
- INT MCASPCHAN_iTxNumEvt;
- INT MCASPCHAN_iRxNumEvt;
- atomic_t MCASPCHAN_atomicStreams;
-
- INT MCASPCHAN_iBytesPerSample;
-
- addr_t MCASPCHAN_ulCtrlVirtAddrBase; /* CTRL 寄存器虚拟地址基地址 */
-
- BOOL MCASPCHAN_bIsInit; /* 是否已经初始化 */
-
- LW_QUEUE MCASPCHAN_queueRxDma;
- VOIDFUNCPTR MCASPCHAN_pfuncRxDmaComplete[__MCASP_DMA_QUEUE_SIZE];
- PVOID MCASPCHAN_pvRxDmaContex[__MCASP_DMA_QUEUE_SIZE];
- spinlock_t MCASPCHAN_splRxDma;
-
- LW_QUEUE MCASPCHAN_queueTxDma;
- VOIDFUNCPTR MCASPCHAN_pfuncTxDmaComplete[__MCASP_DMA_QUEUE_SIZE];
- PVOID MCASPCHAN_pvTxDmaContex[__MCASP_DMA_QUEUE_SIZE];
- spinlock_t MCASPCHAN_splTxDma;
- BOOL MCASPCHAN_bStarted;
-
- UINT MCASPCHAN_uiSerializerTx;
- UINT MCASPCHAN_uiSerializerRx;
-} __AM335X_MCASP_CHANNEL, *__PAM335X_MCASP_CHANNEL;
-/*********************************************************************************************************
- 全局变量
-*********************************************************************************************************/
-static __AM335X_MCASP_CHANNEL _G_am335xMcAspChannels[__MCASP_CHANNEL_NR] = {
- {
- SOC_MCASP_0_CTRL_REGS,
- 2 * LW_CFG_VMM_PAGE_SIZE,
- SOC_MCASP_0_DATA_REGS,
- 0x1000,
- EDMA3_CHA_MCASP0_TX,
- EDMA3_CHA_MCASP0_RX,
- 32,
- 32,
- },
- {
- SOC_MCASP_1_CTRL_REGS,
- 2 * LW_CFG_VMM_PAGE_SIZE,
- SOC_MCASP_1_DATA_REGS,
- 0x1000,
- EDMA3_CHA_MCASP1_TX,
- EDMA3_CHA_MCASP1_RX,
- 32,
- 32,
- },
-};
-/*********************************************************************************************************
- 来自 linux-3.17.4\sound\soc\davinci\davinci-mcasp.c 的函数,实测比 StarterWare 的稳定
-*********************************************************************************************************/
-#include "davinci-mcasp.h"
-#include <linux/compat.h>
-
-static VOID __am335xMcAspStopTx (__PAM335X_MCASP_CHANNEL pMcAspChannel);
-
-static inline VOID __am335xMcAspSetBits (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- UINT32 uiOffset,
- UINT32 uiValue)
-{
- addr_t ulReg = pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase + uiOffset;
-
- writel(readl(ulReg) | uiValue, ulReg);
-}
-
-static inline VOID __am335xMcAspClrBits (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- UINT32 uiOffset,
- UINT32 uiValue)
-{
- addr_t ulReg = pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase + uiOffset;
-
- writel((readl(ulReg) & ~(uiValue)), ulReg);
-}
-
-#if 0
-static inline VOID __am335xMcAspModBits (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- UINT32 uiOffset,
- UINT32 uiValue,
- UINT32 uiMask)
-{
- addr_t ulReg = pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase + uiOffset;
-
- writel((readl(ulReg) & ~uiMask) | uiValue, ulReg);
-}
-#endif
-
-static inline VOID __am335xMcAspSetReg (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- UINT32 uiOffset,
- UINT32 uiValue)
-{
- writel(uiValue, pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase + uiOffset);
-}
-
-static inline UINT32 __am335xMcAspGetReg (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- UINT32 uiOffset)
-{
- return (UINT32)readl(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase + uiOffset);
-}
-
-static VOID __am335xMcAspSetCtrlReg (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- UINT32 uiOffset,
- UINT32 uiValue)
-{
- INT i = 0;
-
- __am335xMcAspSetBits(pMcAspChannel, uiOffset, uiValue);
-
- /* programming GBLCTL needs to read back from GBLCTL and verfiy */
- /* loop count is to aVOID the lock-up */
- for (i = 0; i < 1000; i++) {
- if ((__am335xMcAspGetReg(pMcAspChannel, uiOffset) & uiValue) == uiValue)
- break;
- }
-
- if (i == 1000 && ((__am335xMcAspGetReg(pMcAspChannel, uiOffset) & uiValue) != uiValue))
- printk(KERN_ERR "__am335xMcAspSetCtrlReg(): GBLCTL write error\n");
-}
-
-static BOOL __am335xMcAspIsSynchronous (__PAM335X_MCASP_CHANNEL pMcAspChannel)
-{
- UINT32 uiRxfmctl = __am335xMcAspGetReg(pMcAspChannel, DAVINCI_MCASP_RXFMCTL_REG);
- UINT32 uiAclkxctl = __am335xMcAspGetReg(pMcAspChannel, DAVINCI_MCASP_ACLKXCTL_REG);
-
- return !(uiAclkxctl & TX_ASYNC) && (uiRxfmctl & AFSRE);
-}
-
-static VOID __am335xMcAspStartRx (__PAM335X_MCASP_CHANNEL pMcAspChannel)
-{
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST);
-
- /*
- * When ASYNC == 0 the transmit and receive sections operate
- * synchronously from the transmit clock and frame sync. We need to make
- * sure that the TX signlas are enabled when starting reception.
- */
- if (__am335xMcAspIsSynchronous(pMcAspChannel)) {
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
- }
-
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_RXBUF_REG, 0);
-
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_RXBUF_REG, 0);
-
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
-
- if (__am335xMcAspIsSynchronous(pMcAspChannel))
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
-}
-
-static VOID __am335xMcAspStartTx (__PAM335X_MCASP_CHANNEL pMcAspChannel)
-{
- UINT32 uiCount;
-
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_TXBUF_REG, 0);
-
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
- __am335xMcAspSetCtrlReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_TXBUF_REG, 0);
-
- /* wait for TX ready */
- uiCount = 0;
- while (!(__am335xMcAspGetReg(pMcAspChannel,
- DAVINCI_MCASP_XRSRCTL_REG(pMcAspChannel->MCASPCHAN_uiSerializerTx)) &
- TXSTATE) && (uiCount < 100000))
- uiCount++;
-
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_TXBUF_REG, 0);
-}
-
-static VOID __am335xMcAspStart (__PAM335X_MCASP_CHANNEL pMcAspChannel, INT iSteam)
-{
- UINT32 ulReg;
-
- API_AtomicInc(&pMcAspChannel->MCASPCHAN_atomicStreams);
-
- if (iSteam == SNDRV_PCM_STREAM_PLAYBACK) {
- if (pMcAspChannel->MCASPCHAN_iTxNumEvt) { /* enable FIFO */
- ulReg = pMcAspChannel->MCASPCHAN_ulFifoRegOffset + MCASP_WFIFOCTL_OFFSET;
- __am335xMcAspClrBits(pMcAspChannel, ulReg, FIFO_ENABLE);
- __am335xMcAspSetBits(pMcAspChannel, ulReg, FIFO_ENABLE);
- }
- __am335xMcAspStartTx(pMcAspChannel);
- } else {
- if (pMcAspChannel->MCASPCHAN_iRxNumEvt) { /* enable FIFO */
- ulReg = pMcAspChannel->MCASPCHAN_ulFifoRegOffset + MCASP_RFIFOCTL_OFFSET;
- __am335xMcAspClrBits(pMcAspChannel, ulReg, FIFO_ENABLE);
- __am335xMcAspSetBits(pMcAspChannel, ulReg, FIFO_ENABLE);
- }
- __am335xMcAspStartRx(pMcAspChannel);
- }
-}
-
-static VOID __am335xMcAspStopRx (__PAM335X_MCASP_CHANNEL pMcAspChannel)
-{
- /*
- * In synchronous mode stop the TX clocks if no other iSteam is
- * running
- */
- if (__am335xMcAspIsSynchronous(pMcAspChannel) &&
- !API_AtomicGet(&pMcAspChannel->MCASPCHAN_atomicStreams))
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, 0);
-
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLR_REG, 0);
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
-}
-
-static VOID __am335xMcAspStopTx (__PAM335X_MCASP_CHANNEL pMcAspChannel)
-{
- UINT32 uiValue = 0;
-
- /*
- * In synchronous mode keep TX clocks running if the capture iSteam is
- * still running.
- */
- if (__am335xMcAspIsSynchronous(pMcAspChannel) &&
- API_AtomicGet(&pMcAspChannel->MCASPCHAN_atomicStreams))
- uiValue = TXHCLKRST | TXCLKRST | TXFSRST;
-
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_GBLCTLX_REG, uiValue);
- __am335xMcAspSetReg(pMcAspChannel, DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
-}
-
-static VOID __am335xMcAspStop (__PAM335X_MCASP_CHANNEL pMcAspChannel, INT iSteam)
-{
- UINT32 ulReg;
-
- API_AtomicDec(&pMcAspChannel->MCASPCHAN_atomicStreams);
-
- if (iSteam == SNDRV_PCM_STREAM_PLAYBACK) {
- if (pMcAspChannel->MCASPCHAN_iTxNumEvt) { /* disable FIFO */
- ulReg = pMcAspChannel->MCASPCHAN_ulFifoRegOffset + MCASP_WFIFOCTL_OFFSET;
- __am335xMcAspClrBits(pMcAspChannel, ulReg, FIFO_ENABLE);
- }
- __am335xMcAspStopTx(pMcAspChannel);
- } else {
- if (pMcAspChannel->MCASPCHAN_iRxNumEvt) { /* disable FIFO */
- ulReg = pMcAspChannel->MCASPCHAN_ulFifoRegOffset + MCASP_RFIFOCTL_OFFSET;
- __am335xMcAspClrBits(pMcAspChannel, ulReg, FIFO_ENABLE);
- }
- __am335xMcAspStopRx(pMcAspChannel);
- }
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspDmaRxDone
-** 功能描述: McAsp DMA 接收完成回调函数
-** 输 入 : uiChannel McAsp DMA 通道号
-** pvArg 参数
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xMcAspDmaRxDone(UINT uiChannel, PVOID pvArg)
-{
- __PAM335X_MCASP_CHANNEL pMcAspChannel = pvArg;
- UINT i;
- INTREG intReg;
- INT iNodeNum;
-
- LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASPCHAN_splRxDma, &intReg);
- API_QueueOut(&pMcAspChannel->MCASPCHAN_queueRxDma, &i);
- LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASPCHAN_splRxDma, intReg);
-
- if (pMcAspChannel->MCASPCHAN_pfuncRxDmaComplete[i]) {
- pMcAspChannel->MCASPCHAN_pfuncRxDmaComplete[i](pMcAspChannel->MCASPCHAN_pvRxDmaContex[i]);
- }
-
- API_DmaJobNodeNum(pMcAspChannel->MCASPCHAN_uiRxDmaChannel, &iNodeNum);
-
- if (iNodeNum == 0) {
- __am335xMcAspStop(pMcAspChannel, SNDRV_PCM_STREAM_CAPTURE);
- }
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspDmaTxDone
-** 功能描述: McAsp DMA 发送完成回调函数
-** 输 入 : uiChannel McAsp DMA 通道号
-** pvArg 参数
-** 输 出 : NONE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static VOID __am335xMcAspDmaTxDone(UINT uiChannel, PVOID pvArg)
-{
- __PAM335X_MCASP_CHANNEL pMcAspChannel = pvArg;
- UINT i;
- INTREG intReg;
- INT iNodeNum;
-
- LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASPCHAN_splTxDma, &intReg);
- API_QueueOut(&pMcAspChannel->MCASPCHAN_queueTxDma, &i);
- LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASPCHAN_splTxDma, intReg);
-
- if (pMcAspChannel->MCASPCHAN_pfuncTxDmaComplete[i]) {
- pMcAspChannel->MCASPCHAN_pfuncTxDmaComplete[i](pMcAspChannel->MCASPCHAN_pvTxDmaContex[i]);
- }
-
- API_DmaJobNodeNum(pMcAspChannel->MCASPCHAN_uiTxDmaChannel, &iNodeNum);
-
- if (iNodeNum == 0) {
- __am335xMcAspStop(pMcAspChannel, SNDRV_PCM_STREAM_PLAYBACK);
- }
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspTransferMsg
-** 功能描述: McASP 传输消息
-** 输 入 : pMcAspChannel McASP 通道
-** pSpiMsg spi 传输消息
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAspTransferMsg (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- PLW_SPI_MESSAGE pSpiMsg)
-{
- LW_DMA_TRANSACTION dmaTransAction;
- INT iError;
- UINT i;
- INTREG intReg;
- INT iNodeNum;
-
- if ((pSpiMsg->SPIMSG_pucWrBuffer == LW_NULL &&
- pSpiMsg->SPIMSG_pucRdBuffer == LW_NULL) ||
- pSpiMsg->SPIMSG_uiLen == 0) {
- return (PX_ERROR);
- }
-
- if (pSpiMsg->SPIMSG_pucRdBuffer) {
-
- lib_memset(&dmaTransAction, 0, sizeof(dmaTransAction));
-
- dmaTransAction.DMAT_pucSrcAddress = (UINT8 *)(pMcAspChannel->MCASPCHAN_ulDataPhyAddrBase);
- dmaTransAction.DMAT_iSrcAddrCtl = LW_DMA_ADDR_FIX;
-
- dmaTransAction.DMAT_pucDestAddress = pSpiMsg->SPIMSG_pucRdBuffer;
- dmaTransAction.DMAT_iDestAddrCtl = LW_DMA_ADDR_INC;
-
- dmaTransAction.DMAT_iTransMode = EDMA3_MAKE_TARNS_MODE(EDMA3_TARNS_MODE_A_SYNC,
- EDMA3_TARNS_MODE_TRIG_MODE_EVENT,
- EDMA3_TARNS_MODE_TX_DUMMY_DISABLE,
- EDMA3_TARNS_MODE_LINK_INVALID,
- __MCASP_DMA_OPT_FIFO_WIDTH);
-
- dmaTransAction.DMAT_ulOption = EDMA3_MAKE_OPTION(pMcAspChannel->MCASPCHAN_iBytesPerSample,
- pSpiMsg->SPIMSG_uiLen /
- pMcAspChannel->MCASPCHAN_iBytesPerSample);
-
- dmaTransAction.DMAT_stDataBytes = pSpiMsg->SPIMSG_uiLen;
-
- dmaTransAction.DMAT_pfuncCallback = __am335xMcAspDmaRxDone;
- dmaTransAction.DMAT_pvArg = (PVOID *)pMcAspChannel;
-
- LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASPCHAN_splRxDma, &intReg);
- API_QueueIn(&pMcAspChannel->MCASPCHAN_queueRxDma, &i);
- LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASPCHAN_splRxDma, intReg);
-
- pMcAspChannel->MCASPCHAN_pvRxDmaContex[i] = pSpiMsg->SPIMSG_pvContext;
- pMcAspChannel->MCASPCHAN_pfuncRxDmaComplete[i] = pSpiMsg->SPIMSG_pfuncComplete;
-
- API_DmaJobNodeNum(pMcAspChannel->MCASPCHAN_uiRxDmaChannel, &iNodeNum);
-
- iError = API_DmaJobAdd(pMcAspChannel->MCASPCHAN_uiRxDmaChannel, &dmaTransAction);
- if (iError != ERROR_NONE) {
- LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASPCHAN_splRxDma, &intReg);
- API_QueueUnIn(&pMcAspChannel->MCASPCHAN_queueRxDma);
- LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASPCHAN_splRxDma, intReg);
- return (iError);
- }
-
- if (iNodeNum == 0) {
- __am335xMcAspStart(pMcAspChannel, SNDRV_PCM_STREAM_CAPTURE);
- }
- }
-
- if (pSpiMsg->SPIMSG_pucWrBuffer) {
-
- lib_memset(&dmaTransAction, 0, sizeof(dmaTransAction));
-
- dmaTransAction.DMAT_pucSrcAddress = pSpiMsg->SPIMSG_pucWrBuffer;
- dmaTransAction.DMAT_iSrcAddrCtl = LW_DMA_ADDR_INC;
-
- dmaTransAction.DMAT_pucDestAddress = (UINT8 *)(pMcAspChannel->MCASPCHAN_ulDataPhyAddrBase);
- dmaTransAction.DMAT_iDestAddrCtl = LW_DMA_ADDR_FIX;
-
- dmaTransAction.DMAT_iTransMode = EDMA3_MAKE_TARNS_MODE(EDMA3_TARNS_MODE_A_SYNC,
- EDMA3_TARNS_MODE_TRIG_MODE_EVENT,
- EDMA3_TARNS_MODE_TX_DUMMY_DISABLE,
- EDMA3_TARNS_MODE_LINK_INVALID,
- __MCASP_DMA_OPT_FIFO_WIDTH);
-
- dmaTransAction.DMAT_ulOption = EDMA3_MAKE_OPTION(pMcAspChannel->MCASPCHAN_iBytesPerSample,
- pSpiMsg->SPIMSG_uiLen /
- pMcAspChannel->MCASPCHAN_iBytesPerSample);
-
- dmaTransAction.DMAT_stDataBytes = pSpiMsg->SPIMSG_uiLen;
-
- dmaTransAction.DMAT_pfuncCallback = __am335xMcAspDmaTxDone;
- dmaTransAction.DMAT_pvArg = (PVOID *)pMcAspChannel;
-
- LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASPCHAN_splTxDma, &intReg);
- API_QueueIn(&pMcAspChannel->MCASPCHAN_queueTxDma, &i);
- LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASPCHAN_splTxDma, intReg);
-
- pMcAspChannel->MCASPCHAN_pvTxDmaContex[i] = pSpiMsg->SPIMSG_pvContext;
- pMcAspChannel->MCASPCHAN_pfuncTxDmaComplete[i] = pSpiMsg->SPIMSG_pfuncComplete;
-
- API_DmaJobNodeNum(pMcAspChannel->MCASPCHAN_uiTxDmaChannel, &iNodeNum);
-
- iError = API_DmaJobAdd(pMcAspChannel->MCASPCHAN_uiTxDmaChannel, &dmaTransAction);
- if (iError != ERROR_NONE) {
- LW_SPIN_LOCK_QUICK(&pMcAspChannel->MCASPCHAN_splTxDma, &intReg);
- API_QueueUnIn(&pMcAspChannel->MCASPCHAN_queueTxDma);
- LW_SPIN_UNLOCK_QUICK(&pMcAspChannel->MCASPCHAN_splTxDma, intReg);
- return (iError);
- }
-
- if (iNodeNum == 0) {
- __am335xMcAspStart(pMcAspChannel, SNDRV_PCM_STREAM_PLAYBACK);
- }
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspTransfer
-** 功能描述: McASP 传输函数
-** 输 入 : pMcAspChannel McASP 通道
-** pSpiAdapter spi 适配器
-** pSpiMsg spi 传输消息组
-** iNum 消息数量
-** 输 出 : 完成传输的消息数量
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAspTransfer (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- PLW_SPI_ADAPTER pSpiAdapter,
- PLW_SPI_MESSAGE pSpiMsg,
- INT iNum)
-{
- REGISTER INT i;
- INT iError;
-
- for (i = 0; i < iNum; i++, pSpiMsg++) {
- iError = __am335xMcAspTransferMsg(pMcAspChannel, pSpiMsg);
- if (iError != ERROR_NONE) {
- return (iNum);
- }
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAsp0Transfer
-** 功能描述: McASP0 传输函数
-** 输 入 : pSpiAdapter spi 适配器
-** pSpiMsg spi 传输消息组
-** iNum 消息数量
-** 输 出 : 完成传输的消息数量
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAsp0Transfer (PLW_SPI_ADAPTER pSpiAdapter,
- PLW_SPI_MESSAGE pSpiMsg,
- INT iNum)
-{
- return (__am335xMcAspTransfer(&_G_am335xMcAspChannels[0], pSpiAdapter, pSpiMsg, iNum));
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAsp1Transfer
-** 功能描述: McASP1 传输函数
-** 输 入 : pSpiAdapter spi 适配器
-** pSpiMsg spi 传输消息组
-** iNum 消息数量
-** 输 出 : 完成传输的消息数量
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAsp1Transfer (PLW_SPI_ADAPTER pSpiAdapter,
- PLW_SPI_MESSAGE pSpiMsg,
- INT iNum)
-{
- return (__am335xMcAspTransfer(&_G_am335xMcAspChannels[1], pSpiAdapter, pSpiMsg, iNum));
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspMasterCtl
-** 功能描述: McASP 控制函数
-** 输 入 : pMcAspChannel McASP 通道
-** pSpiAdapter spi 适配器
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAspMasterCtl (__PAM335X_MCASP_CHANNEL pMcAspChannel,
- PLW_SPI_ADAPTER pSpiAdapter,
- INT iCmd,
- LONG lArg)
-{
- __PAUDIO_CODEC_PARAM pCodceParam = (__PAUDIO_CODEC_PARAM)lArg;
- INT *pIntData = (INT *)lArg;
- UINT uiDataSize;
-
- (VOID)pCodceParam;
-
- switch (iCmd) {
- case __AUDIO_CODEC_OPEN:
- break;
-
- case __AUDIO_CODEC_CLOSE:
- break;
-
- case __AUDIO_CODEC_SETFMT:
- if (*pIntData == AFMT_S16_LE) {
- uiDataSize = 16;
- } else if (*pIntData == AFMT_U8) {
- uiDataSize = 8;
- } else {
- _ErrorHandle(EINVAL);
- return (PX_ERROR);
- }
-
- McASPRxFmtI2SSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, uiDataSize, uiDataSize,
- MCASP_RX_MODE_DMA);
- McASPTxFmtI2SSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, uiDataSize, uiDataSize,
- MCASP_TX_MODE_DMA);
-
- pMcAspChannel->MCASPCHAN_iBytesPerSample = ((uiDataSize >> 3) * __MCASP_I2S_CHANNELS_NUM);
- break;
-
- case __AUDIO_CODEC_CHANNELS:
- if (*pIntData != __MCASP_I2S_CHANNELS_NUM) {
- _ErrorHandle(EINVAL);
- return (PX_ERROR);
- }
- break;
-
- case __AUDIO_CODEC_SPEED:
- break;
- }
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAsp0MasterCtl
-** 功能描述: McASP0 控制函数
-** 输 入 : pSpiAdapter spi 适配器
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAsp0MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
- INT iCmd,
- LONG lArg)
-{
- return (__am335xMcAspMasterCtl(&_G_am335xMcAspChannels[0], pSpiAdapter, iCmd, lArg));
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAsp1MasterCtl
-** 功能描述: McASP1 控制函数
-** 输 入 : pSpiAdapter spi 适配器
-** iCmd 命令
-** lArg 参数
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAsp1MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
- INT iCmd,
- LONG lArg)
-{
- return (__am335xMcAspMasterCtl(&_G_am335xMcAspChannels[1], pSpiAdapter, iCmd, lArg));
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspHwInit
-** 功能描述: 初始化 McASP 硬件通道
-** 输 入 : pMcAspChannel McASP 通道
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAspHwInit(__PAM335X_MCASP_CHANNEL pMcAspChannel,
- PAM335X_PINMUX pPinMux,
- UINT uiSerializerTx,
- UINT uiSerializerRx)
-{
- UINT uiChannel = pMcAspChannel - &_G_am335xMcAspChannels[0];
-
- switch (uiChannel) {
- case 0:
- am335xEnableModuleClock(am335xModuleIdGet("MCASP0"));
- break;
-
- case 1:
- am335xEnableModuleClock(am335xModuleIdGet("MCASP1"));
- break;
-
- default:
- return (PX_ERROR);
- }
-
- am335xPinMuxSetup(pPinMux);
-
- pMcAspChannel->MCASPCHAN_uiSerializerTx = uiSerializerTx;
- pMcAspChannel->MCASPCHAN_uiSerializerRx = uiSerializerRx;
-
- McASPRxReset(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase);
- McASPTxReset(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase);
-
- /* Enable the FIFOs for DMA transfer */
- McASPReadFifoEnable(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase +
- pMcAspChannel->MCASPCHAN_ulFifoRegOffset, 1, 1);
- McASPWriteFifoEnable(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase +
- pMcAspChannel->MCASPCHAN_ulFifoRegOffset, 1, 1);
-
- /* Set I2S format in the transmitter/receiver format units */
- McASPRxFmtI2SSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- __MCASP_DEFAULT_WORD_SIZE, __MCASP_DEFAULT_SLOT_SIZE, MCASP_RX_MODE_DMA);
- McASPTxFmtI2SSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- __MCASP_DEFAULT_WORD_SIZE, __MCASP_DEFAULT_SLOT_SIZE, MCASP_TX_MODE_DMA);
-
- pMcAspChannel->MCASPCHAN_iBytesPerSample = ((__MCASP_DEFAULT_WORD_SIZE >> 3) *
- __MCASP_I2S_CHANNELS_NUM);
-
- /* Configure the frame sync. I2S shall work in TDM format with 2 slots */
- McASPRxFrameSyncCfg(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, 2, MCASP_RX_FS_WIDTH_WORD,
- MCASP_RX_FS_EXT_BEGIN_ON_FALL_EDGE);
- McASPTxFrameSyncCfg(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, 2, MCASP_TX_FS_WIDTH_WORD,
- MCASP_TX_FS_EXT_BEGIN_ON_FALL_EDGE);
-
- /* configure the clock for receiver */
- McASPRxClkCfg(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_RX_CLK_EXTERNAL, 0, 0);
- McASPRxClkPolaritySet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_RX_CLK_POL_RIS_EDGE);
- McASPRxClkCheckConfig(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_RX_CLKCHCK_DIV32,
- 0x00, 0xFF);
-
- /* configure the clock for transmitter */
- McASPTxClkCfg(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_TX_CLK_EXTERNAL, 0, 0);
- McASPTxClkPolaritySet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_TX_CLK_POL_FALL_EDGE);
- McASPTxClkCheckConfig(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_TX_CLKCHCK_DIV32,
- 0x00, 0xFF);
-
- /* Enable synchronization of RX and TX sections */
- McASPTxRxClkSyncEnable(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase);
-
- /* Enable the transmitter/receiver slots. I2S uses 2 slots */
- McASPRxTimeSlotSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, __MCASP_I2S_SLOTS);
- McASPTxTimeSlotSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, __MCASP_I2S_SLOTS);
-
- /*
- ** Set the serializers, Currently only one serializer is set as
- ** transmitter and one serializer as receiver.
- */
- McASPSerializerRxSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- pMcAspChannel->MCASPCHAN_uiSerializerRx);
- McASPSerializerTxSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- pMcAspChannel->MCASPCHAN_uiSerializerTx);
-
- /*
- ** Configure the McASP pins
- ** Input - Frame Sync, Clock and Serializer Rx
- ** Output - Serializer Tx is connected to the input of the codec
- */
- McASPPinMcASPSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- MCASP_PIN_AFSX |
- MCASP_PIN_ACLKX |
- MCASP_PIN_AXR(pMcAspChannel->MCASPCHAN_uiSerializerTx) |
- MCASP_PIN_AXR(pMcAspChannel->MCASPCHAN_uiSerializerRx));
-
- McASPPinDirOutputSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- MCASP_PIN_AXR(pMcAspChannel->MCASPCHAN_uiSerializerTx));
- McASPPinDirInputSet(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase,
- MCASP_PIN_AFSX |
- MCASP_PIN_ACLKX |
- MCASP_PIN_AXR(pMcAspChannel->MCASPCHAN_uiSerializerRx));
-
- McASPAMuteDisable(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase);
-
- /* Start the clocks */
- McASPTxClkStart(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_TX_CLK_EXTERNAL);
- McASPRxClkStart(pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase, MCASP_RX_CLK_EXTERNAL);
-
- return (ERROR_NONE);
-}
-/*********************************************************************************************************
-** 函数名称: __am335xMcAspInit
-** 功能描述: 初始化 McASP 通道
-** 输 入 : pMcAspChannel McASP 通道
-** 输 出 : ERROR_CODE
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-static INT __am335xMcAspInit(__PAM335X_MCASP_CHANNEL pMcAspChannel,
- PAM335X_PINMUX pPinMux,
- UINT uiSerializerTx,
- UINT uiSerializerRx)
-{
- if (!pMcAspChannel->MCASPCHAN_bIsInit) {
-
- pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
- (PVOID)pMcAspChannel->MCASPCHAN_ulCtrlPhyAddrBase,
- pMcAspChannel->MCASPCHAN_stCtrlPhyAddrSize);
- if (!pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase) {
- printk(KERN_ERR "__am335xMcAspInit(): failed to remap!\n");
- goto __error_handle;
- }
-
- API_DmaReset(pMcAspChannel->MCASPCHAN_uiTxDmaChannel);
- API_DmaReset(pMcAspChannel->MCASPCHAN_uiRxDmaChannel);
-
- API_DmaMaxNodeNumSet(pMcAspChannel->MCASPCHAN_uiTxDmaChannel, __MCASP_DMA_MAX_NODE_NUM);
- API_DmaMaxNodeNumSet(pMcAspChannel->MCASPCHAN_uiRxDmaChannel, __MCASP_DMA_MAX_NODE_NUM);
-
- API_QueueInit(&pMcAspChannel->MCASPCHAN_queueTxDma, __MCASP_DMA_QUEUE_SIZE);
- API_QueueInit(&pMcAspChannel->MCASPCHAN_queueRxDma, __MCASP_DMA_QUEUE_SIZE);
-
- LW_SPIN_INIT(&pMcAspChannel->MCASPCHAN_splTxDma);
- LW_SPIN_INIT(&pMcAspChannel->MCASPCHAN_splRxDma);
-
- if (__am335xMcAspHwInit(pMcAspChannel, pPinMux,
- uiSerializerTx, uiSerializerRx) != ERROR_NONE) {
- printk(KERN_ERR "__am335xMcAspInit(): failed to init!\n");
- goto __error_handle;
- }
-
- pMcAspChannel->MCASPCHAN_bIsInit = LW_TRUE;
- }
-
- return (ERROR_NONE);
-
- __error_handle:
-
- if (pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase) {
- API_VmmIoUnmap((PVOID)pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase);
- pMcAspChannel->MCASPCHAN_ulCtrlVirtAddrBase = 0;
- }
-
- return (PX_ERROR);
-}
-/*********************************************************************************************************
- AM335X 处理器 McASP 驱动程序
-*********************************************************************************************************/
-static LW_SPI_FUNCS _G_am335xMcAspFuncs[__MCASP_CHANNEL_NR] = {
- {
- __am335xMcAsp0Transfer,
- __am335xMcAsp0MasterCtl,
- },
- {
- __am335xMcAsp1Transfer,
- __am335xMcAsp1MasterCtl,
- }
-};
-/*********************************************************************************************************
-** 函数名称: mcaspBusDrv
-** 功能描述: 初始化 McASP 总线并获取驱动程序
-** 输 入 : uiChannel 通道号
-** pPinMux 管脚复用
-** uiSerializerTx Tx 编号
-** uiSerializerRx Rx 编号
-** 输 出 : McASP 总线驱动程序
-** 全局变量:
-** 调用模块:
-*********************************************************************************************************/
-PLW_SPI_FUNCS mcaspBusDrv (UINT uiChannel,
- PAM335X_PINMUX pPinMux,
- UINT uiSerializerTx,
- UINT uiSerializerRx)
-{
- if (uiChannel >= __MCASP_CHANNEL_NR) {
- printk(KERN_ERR "mcaspBusDrv(): McASP channel invalid!\n");
- return (LW_NULL);
- }
-
- if (__am335xMcAspInit(&_G_am335xMcAspChannels[uiChannel],
- pPinMux, uiSerializerTx, uiSerializerRx) != ERROR_NONE) {
- return (LW_NULL);
- }
-
- return (&_G_am335xMcAspFuncs[uiChannel]);
-}
-/*********************************************************************************************************
- END
-*********************************************************************************************************/
+/*********************************************************************************************************
+**
+** 中国软件开源组织
+**
+** 嵌入式实时操作系统
+**
+** SylixOS(TM)
+**
+** Copyright All Rights Reserved
+**
+**--------------文件信息--------------------------------------------------------------------------------
+**
+** 文 件 名: am335x_mcasp.c
+**
+** 创 建 人: Jiao.JinXing (焦进星)
+**
+** 文件创建日期: 2015 年 01 月 22 日
+**
+** 描 述: AM335X 处理器 McASP(Multichannel Audio Serial Port) 驱动(总线驱动部分)
+*********************************************************************************************************/
+#define __SYLIXOS_KERNEL
+#include "SylixOS.h"
+#include "system/device/sound/soundcard.h"
+
+#include "driver/am335x_common.h"
+#include "driver/audio/queue/queueLib.h"
+#include "driver/audio/codec/codecDrv.h"
+#include "driver/audio/dsp/dspDrv.h"
+
+#include "mcasp.h"
+#include "edma.h"
+#include "am335x_mcasp.h"
+/*********************************************************************************************************
+ 定义
+*********************************************************************************************************/
+#define __MCASP_CHANNEL_NR (2)
+
+/* Slot size to send/receive data */
+#define __MCASP_DEFAULT_SLOT_SIZE (16)
+
+/* Word size to send/receive data. Word size <= Slot size */
+#define __MCASP_DEFAULT_WORD_SIZE (16)
+
+#define __MCASP_I2S_CHANNELS_NUM (2)
+
+#define __MCASP_I2S_SLOTS ((1 << __MCASP_I2S_CHANNELS_NUM) - 1)
+
+#define __MCASP_DMA_MAX_NODE_NUM (4)
+
+#define PAR_RX_START (70)
+#define PAR_TX_START (PAR_RX_START + __MCASP_DMA_MAX_NODE_NUM)
+
+#define __MSASP_AUIDO_BUF_SIZE (4096)
+
+/*
+** Definitions which are not configurable
+*/
+#define SIZE_PARAMSET (32u)
+
+#define OPT_FIFO_WIDTH (0x02 << 8u)
+
+#define TX_DMA_INT_ENABLE (EDMA3CC_OPT_TCC_SET \
+ (EDMA3_CHA_MCASP1_TX) | (1 \
+ << EDMA3CC_OPT_TCINTEN_SHIFT))
+
+#define RX_DMA_INT_ENABLE (EDMA3CC_OPT_TCC_SET \
+ (EDMA3_CHA_MCASP1_RX) | (1 \
+ << EDMA3CC_OPT_TCINTEN_SHIFT))
+
+#define __DMAJOB_STATUS_FREE (0x00)
+#define __DMAJOB_STATUS_TRANS (0xFF)
+/*********************************************************************************************************
+ 定义
+*********************************************************************************************************/
+typedef struct {
+ LW_SPI_MESSAGE DMAJOB_transMsg;
+ UINT DMAJOB_uiStatus;
+ EDMA3CCPaRAMEntry DMAJOB_paramSet;
+ UINT DMAJOB_uiParId;
+} AUDIO_DMA_JOB, *PAUDIO_DMA_JOB;
+/*********************************************************************************************************
+ McASP 通道类型定义
+*********************************************************************************************************/
+typedef struct {
+ addr_t MCASP_ulCtrlPhyAddrBase; /* CTRL 寄存器物理地址基地址 */
+ size_t MCASP_stCtrlPhyAddrSize; /* CTRL 寄存器物理地址空间大小 */
+
+ addr_t MCASP_ulDataPhyAddrBase; /* DATA 寄存器物理地址基地址 */
+ addr_t MCASP_ulFifoRegOffset; /* FIFO 寄存器虚拟地址偏移 */
+
+ UINT MCASP_uiTxDmaChannel; /* 发送 DMA 通道号 */
+ UINT MCASP_uiRxDmaChannel; /* 接收 DMA 通道号 */
+
+ INT MCASP_iBytesPerSample;
+
+ addr_t MCASP_ulCtrlVirtAddrBase; /* CTRL 寄存器虚拟地址基地址 */
+
+ BOOL MCASP_bIsInit; /* 是否已经初始化 */
+
+ AUDIO_DMA_JOB MCASP_ringRxDmaJob[__MCASP_DMA_MAX_NODE_NUM];
+ AUDIO_DMA_JOB MCASP_ringTxDmaJob[__MCASP_DMA_MAX_NODE_NUM];
+
+ UINT MCASP_uiCurRxDmaJob;
+ UINT MCASP_uiCurTxDmaJob;
+
+ UINT MCASP_uiSerializerRx;
+ UINT MCASP_uiSerializerTx;
+
+ LW_SPI_MESSAGE MCASP_rxMsgPool[__DSP_MAX_FRAGMENT_NUM];
+ LW_SPI_MESSAGE MCASP_txMsgPool[__DSP_MAX_FRAGMENT_NUM];
+
+ LW_QUEUE MCASP_rxMsgQueue;
+ LW_QUEUE MCASP_txMsgQueue;
+
+ UINT8 *MCASP_pucTxDmaBufferDummy;
+ UINT8 *MCASP_pucRxDmaBufferDummy;
+
+ PAM335X_PINMUX MCASP_pPinMux;
+} __AM335X_MCASP_CHANNEL, *__PAM335X_MCASP_CHANNEL;
+/*********************************************************************************************************
+ 全局变量
+*********************************************************************************************************/
+static __AM335X_MCASP_CHANNEL _G_am335xMcAspChannels[__MCASP_CHANNEL_NR] = {
+ {
+ SOC_MCASP_0_CTRL_REGS,
+ 2 * LW_CFG_VMM_PAGE_SIZE,
+ SOC_MCASP_0_DATA_REGS,
+ 0x1000,
+ EDMA3_CHA_MCASP0_TX,
+ EDMA3_CHA_MCASP0_RX,
+ },
+ {
+ SOC_MCASP_1_CTRL_REGS,
+ 2 * LW_CFG_VMM_PAGE_SIZE,
+ SOC_MCASP_1_DATA_REGS,
+ 0x1000,
+ EDMA3_CHA_MCASP1_TX,
+ EDMA3_CHA_MCASP1_RX,
+ },
+};
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspDmaRxDone
+** 功能描述: McAsp DMA 接收完成回调函数
+** 输 入 : uiChannel McAsp DMA 通道号
+** pvArg 参数
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspDmaRxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ PAUDIO_DMA_JOB pDmaJob;
+
+ /*
+ * 获得当前传输完成的 DMA 工作
+ */
+ pDmaJob = &pMcAspChannel->MCASP_ringRxDmaJob[pMcAspChannel->MCASP_uiCurRxDmaJob];
+
+ if (pDmaJob->DMAJOB_uiStatus != __DMAJOB_STATUS_FREE) { /* 是一个真正的传输工作 */
+
+ VOIDFUNCPTR pfuncComplete;
+ PVOID pvContext;
+
+ pfuncComplete = pDmaJob->DMAJOB_transMsg.SPIMSG_pfuncComplete;
+ pvContext = pDmaJob->DMAJOB_transMsg.SPIMSG_pvContext;
+
+ pDmaJob->DMAJOB_uiStatus = __DMAJOB_STATUS_FREE; /* 进入空闲状态 */
+
+ if (pfuncComplete) { /* 调用传输消息的完成函数 */
+ pfuncComplete(pvContext);
+ }
+ }
+
+ pMcAspChannel->MCASP_uiCurRxDmaJob++; /* 调整下一个传输 DMA 工作位置 */
+ pMcAspChannel->MCASP_uiCurRxDmaJob %= __MCASP_DMA_MAX_NODE_NUM;
+
+ if (!API_QueueIsEmpty(&pMcAspChannel->MCASP_rxMsgQueue)) { /* 传递消息队列有消息 */
+
+ /* 第一个传递消息的位置 */
+ UINT uiOut = pMcAspChannel->MCASP_rxMsgQueue.QUEUE_uiFront;
+ UINT uiDmaJobIndex = pMcAspChannel->MCASP_uiCurRxDmaJob; /* 在下一个传输的 DMA 工作找起 */
+ UINT i = 0;
+
+ do {
+ pDmaJob = &pMcAspChannel->MCASP_ringRxDmaJob[uiDmaJobIndex];
+ if (pDmaJob->DMAJOB_uiStatus == __DMAJOB_STATUS_FREE) { /* 找到一个空闲的 DMA 工作 */
+ break;
+ }
+ uiDmaJobIndex++;
+ uiDmaJobIndex %= __MCASP_DMA_MAX_NODE_NUM;
+ i++;
+ } while (i < __MCASP_DMA_MAX_NODE_NUM);
+
+ if (i < __MCASP_DMA_MAX_NODE_NUM) { /* 找到了一个空闲的 DMA 工作 */
+
+ API_QueueOut(&pMcAspChannel->MCASP_rxMsgQueue, &uiOut); /* 传递消息出队 */
+
+ LW_SPI_MESSAGE rxMsg = pMcAspChannel->MCASP_rxMsgPool[uiOut];
+
+ pDmaJob = &pMcAspChannel->MCASP_ringRxDmaJob[uiDmaJobIndex];/* 使用该 DMA 工作 */
+
+ pDmaJob->DMAJOB_uiStatus = __DMAJOB_STATUS_TRANS; /* 进入传输状态 */
+ pDmaJob->DMAJOB_transMsg = rxMsg; /* 记录传递消息 */
+
+ /*
+ * 修改 B COUNT 和 目标地址
+ */
+ pDmaJob->DMAJOB_paramSet.bCnt = rxMsg.SPIMSG_uiLen / pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.destAddr = (UINT)rxMsg.SPIMSG_pucRdBuffer;
+
+ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS,
+ pDmaJob->DMAJOB_uiParId,
+ &pDmaJob->DMAJOB_paramSet);
+ }
+ }
+
+ pDmaJob = &pMcAspChannel->MCASP_ringRxDmaJob[pMcAspChannel->MCASP_uiCurRxDmaJob];
+
+ if (pDmaJob->DMAJOB_uiStatus == __DMAJOB_STATUS_FREE) { /* 是个空闲的 DMA 工作 */
+ /*
+ * 修改 B COUNT 和 目标地址
+ */
+ pDmaJob->DMAJOB_paramSet.bCnt = __MSASP_AUIDO_BUF_SIZE / pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.destAddr = (UINT)pMcAspChannel->MCASP_pucRxDmaBufferDummy;
+ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
+ }
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspDmaTxDone
+** 功能描述: McAsp DMA 发送完成回调函数
+** 输 入 : uiChannel McAsp DMA 通道号
+** pvArg 参数
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspDmaTxDone (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ PAUDIO_DMA_JOB pDmaJob;
+
+ pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[pMcAspChannel->MCASP_uiCurTxDmaJob];
+
+ if (pDmaJob->DMAJOB_uiStatus != __DMAJOB_STATUS_FREE) { /* 是一个真正的传输工作 */
+
+ VOIDFUNCPTR pfuncComplete;
+ PVOID pvContext;
+
+ pfuncComplete = pDmaJob->DMAJOB_transMsg.SPIMSG_pfuncComplete;
+ pvContext = pDmaJob->DMAJOB_transMsg.SPIMSG_pvContext;
+
+ pDmaJob->DMAJOB_uiStatus = __DMAJOB_STATUS_FREE; /* 进入空闲状态 */
+
+ if (pfuncComplete) { /* 调用传输消息的完成函数 */
+ pfuncComplete(pvContext);
+ }
+ }
+
+ pMcAspChannel->MCASP_uiCurTxDmaJob++; /* 调整下一个传输 DMA 工作位置 */
+ pMcAspChannel->MCASP_uiCurTxDmaJob %= __MCASP_DMA_MAX_NODE_NUM;
+
+ if (!API_QueueIsEmpty(&pMcAspChannel->MCASP_txMsgQueue)) { /* 传递消息队列有消息 */
+
+ /* 第一个传递消息的位置 */
+ UINT uiOut = pMcAspChannel->MCASP_txMsgQueue.QUEUE_uiFront;
+ UINT uiDmaJobIndex = pMcAspChannel->MCASP_uiCurTxDmaJob; /* 在下一个传输的 DMA 工作找起 */
+ UINT i = 0;
+
+ do {
+ pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[uiDmaJobIndex];
+ if (pDmaJob->DMAJOB_uiStatus == __DMAJOB_STATUS_FREE) { /* 找到一个空闲的 DMA 工作 */
+ break;
+ }
+ uiDmaJobIndex++;
+ uiDmaJobIndex %= __MCASP_DMA_MAX_NODE_NUM;
+ i++;
+ } while (i < __MCASP_DMA_MAX_NODE_NUM);
+
+ if (i < __MCASP_DMA_MAX_NODE_NUM) { /* 找到了一个空闲的 DMA 工作 */
+
+ API_QueueOut(&pMcAspChannel->MCASP_txMsgQueue, &uiOut); /* 传递消息出队 */
+
+ LW_SPI_MESSAGE txMsg = pMcAspChannel->MCASP_txMsgPool[uiOut];
+
+ pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[uiDmaJobIndex];/* 使用该 DMA 工作 */
+
+ pDmaJob->DMAJOB_uiStatus = __DMAJOB_STATUS_TRANS; /* 进入传输状态 */
+ pDmaJob->DMAJOB_transMsg = txMsg; /* 记录传递消息 */
+
+ /*
+ * 修改 B COUNT 和 源地址
+ */
+ pDmaJob->DMAJOB_paramSet.bCnt = txMsg.SPIMSG_uiLen / pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.srcAddr = (UINT)txMsg.SPIMSG_pucWrBuffer;
+
+ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS,
+ pDmaJob->DMAJOB_uiParId,
+ &pDmaJob->DMAJOB_paramSet);
+ }
+ }
+
+ pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[pMcAspChannel->MCASP_uiCurTxDmaJob];
+
+ if (pDmaJob->DMAJOB_uiStatus == __DMAJOB_STATUS_FREE) { /* 是个空闲的 DMA 工作 */
+ /*
+ * 修改 B COUNT 和 源地址
+ */
+ pDmaJob->DMAJOB_paramSet.bCnt = __MSASP_AUIDO_BUF_SIZE / pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.srcAddr = (UINT)pMcAspChannel->MCASP_pucTxDmaBufferDummy;
+ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
+ }
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspTransferMsg
+** 功能描述: McASP 传输消息
+** 输 入 : pMcAspChannel McASP 通道
+** pSpiMsg spi 传输消息
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAspTransferMsg (__PAM335X_MCASP_CHANNEL pMcAspChannel,
+ PLW_SPI_MESSAGE pSpiMsg)
+{
+ UINT uiIn;
+
+ if ((pSpiMsg->SPIMSG_pucWrBuffer == LW_NULL &&
+ pSpiMsg->SPIMSG_pucRdBuffer == LW_NULL) ||
+ pSpiMsg->SPIMSG_uiLen == 0) {
+ return (PX_ERROR);
+ }
+
+ INTREG iregInterLevel = KN_INT_DISABLE();
+
+ if (pSpiMsg->SPIMSG_pucRdBuffer) {
+
+ if (API_QueueIsFull(&pMcAspChannel->MCASP_rxMsgQueue)) {
+ KN_INT_ENABLE(iregInterLevel);
+ printk(KERN_ERR "__am335xMcAspTransferMsg(): rx queue full\n");
+ return (PX_ERROR);
+ }
+
+ API_QueueIn(&pMcAspChannel->MCASP_rxMsgQueue, &uiIn);
+ pMcAspChannel->MCASP_rxMsgPool[uiIn] = *pSpiMsg;
+
+ } else if (pSpiMsg->SPIMSG_pucWrBuffer) {
+
+ if (API_QueueIsFull(&pMcAspChannel->MCASP_txMsgQueue)) {
+ KN_INT_ENABLE(iregInterLevel);
+ printk(KERN_ERR "__am335xMcAspTransferMsg(): tx queue full\n");
+ return (PX_ERROR);
+ }
+
+ API_QueueIn(&pMcAspChannel->MCASP_txMsgQueue, &uiIn);
+ pMcAspChannel->MCASP_txMsgPool[uiIn] = *pSpiMsg;
+ }
+
+ KN_INT_ENABLE(iregInterLevel);
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspRxDmaInit
+** 功能描述: McASP 接收 DMA 初始化
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspRxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ PAUDIO_DMA_JOB pDmaJob;
+ INT i;
+
+ EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
+ pMcAspChannel->MCASP_uiRxDmaChannel,
+ pMcAspChannel->MCASP_uiRxDmaChannel, 0);
+
+ pMcAspChannel->MCASP_uiCurRxDmaJob = 0;
+
+ API_QueueInit(&pMcAspChannel->MCASP_rxMsgQueue, __DSP_MAX_FRAGMENT_NUM);
+
+ pMcAspChannel->MCASP_pucRxDmaBufferDummy = API_VmmDmaAlloc(__MSASP_AUIDO_BUF_SIZE);
+
+ for (i = 0; i < __MCASP_DMA_MAX_NODE_NUM; i++) {
+ pDmaJob = &pMcAspChannel->MCASP_ringRxDmaJob[i];
+
+ lib_memset(pDmaJob, 0, sizeof(*pDmaJob));
+
+ if (i == 0) {
+ pDmaJob->DMAJOB_uiParId = pMcAspChannel->MCASP_uiRxDmaChannel;
+ } else {
+ pDmaJob->DMAJOB_uiParId = PAR_RX_START + (i - 1);
+ }
+
+ pDmaJob->DMAJOB_paramSet.opt = OPT_FIFO_WIDTH | RX_DMA_INT_ENABLE;
+
+ pDmaJob->DMAJOB_paramSet.srcAddr = pMcAspChannel->MCASP_ulDataPhyAddrBase;
+ pDmaJob->DMAJOB_paramSet.destAddr = (UINT)pMcAspChannel->MCASP_pucRxDmaBufferDummy;
+
+ pDmaJob->DMAJOB_paramSet.aCnt = pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.bCnt = __MSASP_AUIDO_BUF_SIZE /
+ pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.cCnt = 1;
+
+ pDmaJob->DMAJOB_paramSet.bCntReload = 0;
+
+ pDmaJob->DMAJOB_paramSet.srcBIdx = 0;
+ pDmaJob->DMAJOB_paramSet.srcCIdx = 0;
+
+ pDmaJob->DMAJOB_paramSet.destBIdx = pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.destCIdx = 0;
+
+ if (i == __MCASP_DMA_MAX_NODE_NUM - 1) {
+ pDmaJob->DMAJOB_paramSet.linkAddr = pMcAspChannel->MCASP_uiRxDmaChannel * SIZE_PARAMSET;
+
+ } else {
+ pDmaJob->DMAJOB_paramSet.linkAddr = (PAR_RX_START + i) * SIZE_PARAMSET;
+ }
+
+ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
+ }
+
+ /* Enable EDMA for the transfer */
+ EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiRxDmaChannel,
+ EDMA3_TRIG_MODE_EVENT);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspRxDmaDeInit
+** 功能描述: McASP 接收 DMA 初始化
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspRxDmaDeInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ /* Disable EDMA for the transfer */
+ EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiRxDmaChannel,
+ EDMA3_TRIG_MODE_EVENT);
+
+ EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
+ pMcAspChannel->MCASP_uiRxDmaChannel,
+ EDMA3_TRIG_MODE_EVENT,
+ pMcAspChannel->MCASP_uiRxDmaChannel, 0);
+
+ API_VmmDmaFree(pMcAspChannel->MCASP_pucRxDmaBufferDummy);
+ pMcAspChannel->MCASP_pucRxDmaBufferDummy = LW_NULL;
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspTxDmaInit
+** 功能描述: McASP 发送 DMA 初始化
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspTxDmaInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ PAUDIO_DMA_JOB pDmaJob;
+ INT i;
+
+ EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
+ pMcAspChannel->MCASP_uiTxDmaChannel,
+ pMcAspChannel->MCASP_uiTxDmaChannel, 0);
+
+ pMcAspChannel->MCASP_uiCurTxDmaJob = 0;
+
+ API_QueueInit(&pMcAspChannel->MCASP_txMsgQueue, __DSP_MAX_FRAGMENT_NUM);
+
+ pMcAspChannel->MCASP_pucRxDmaBufferDummy = API_VmmDmaAlloc(__MSASP_AUIDO_BUF_SIZE);
+ lib_bzero(pMcAspChannel->MCASP_pucRxDmaBufferDummy, __MSASP_AUIDO_BUF_SIZE);
+
+ for (i = 0; i < __MCASP_DMA_MAX_NODE_NUM; i++) {
+ pDmaJob = &pMcAspChannel->MCASP_ringTxDmaJob[i];
+
+ lib_memset(pDmaJob, 0, sizeof(*pDmaJob));
+
+ if (i == 0) {
+ pDmaJob->DMAJOB_uiParId = pMcAspChannel->MCASP_uiTxDmaChannel;
+ } else {
+ pDmaJob->DMAJOB_uiParId = PAR_TX_START + (i - 1);
+ }
+
+ pDmaJob->DMAJOB_paramSet.opt = OPT_FIFO_WIDTH | TX_DMA_INT_ENABLE;
+
+ pDmaJob->DMAJOB_paramSet.srcAddr = (UINT)pMcAspChannel->MCASP_pucRxDmaBufferDummy;
+ pDmaJob->DMAJOB_paramSet.destAddr = pMcAspChannel->MCASP_ulDataPhyAddrBase;
+
+ pDmaJob->DMAJOB_paramSet.aCnt = pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.bCnt = __MSASP_AUIDO_BUF_SIZE /
+ pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.cCnt = 1;
+
+ pDmaJob->DMAJOB_paramSet.bCntReload = 0;
+
+ pDmaJob->DMAJOB_paramSet.srcBIdx = pMcAspChannel->MCASP_iBytesPerSample;
+ pDmaJob->DMAJOB_paramSet.srcCIdx = 0;
+
+ pDmaJob->DMAJOB_paramSet.destBIdx = 0;
+ pDmaJob->DMAJOB_paramSet.destCIdx = 0;
+
+ if (i == __MCASP_DMA_MAX_NODE_NUM - 1) {
+ pDmaJob->DMAJOB_paramSet.linkAddr = pMcAspChannel->MCASP_uiTxDmaChannel * SIZE_PARAMSET;
+
+ } else {
+ pDmaJob->DMAJOB_paramSet.linkAddr = (PAR_TX_START + i) * SIZE_PARAMSET;
+ }
+
+ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, pDmaJob->DMAJOB_uiParId, &pDmaJob->DMAJOB_paramSet);
+ }
+
+ /* Enable EDMA for the transfer */
+ EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiTxDmaChannel,
+ EDMA3_TRIG_MODE_EVENT);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspTxDmaDeInit
+** 功能描述: McASP 接收 DMA 初始化
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspTxDmaDeInit (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ /* Disable EDMA for the transfer */
+ EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, pMcAspChannel->MCASP_uiTxDmaChannel,
+ EDMA3_TRIG_MODE_EVENT);
+
+ EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
+ pMcAspChannel->MCASP_uiTxDmaChannel,
+ EDMA3_TRIG_MODE_EVENT,
+ pMcAspChannel->MCASP_uiTxDmaChannel, 0);
+
+ API_VmmDmaFree(pMcAspChannel->MCASP_pucTxDmaBufferDummy);
+ pMcAspChannel->MCASP_pucTxDmaBufferDummy = LW_NULL;
+}
+/*********************************************************************************************************
+** 函数名称: am335xMcaspEdma3Done
+** 功能描述: McAsp DMA 完成回调函数
+** 输 入 : uiChannel McAsp DMA 通道号
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+VOID am335xMcaspEdma3Done (UINT uiChannel)
+{
+ switch (uiChannel) {
+ case EDMA3_CHA_MCASP0_RX:
+ __am335xMcAspDmaRxDone(&_G_am335xMcAspChannels[0]);
+ break;
+
+ case EDMA3_CHA_MCASP0_TX:
+ __am335xMcAspDmaTxDone(&_G_am335xMcAspChannels[0]);
+ break;
+
+ case EDMA3_CHA_MCASP1_RX:
+ __am335xMcAspDmaRxDone(&_G_am335xMcAspChannels[1]);
+ break;
+
+ case EDMA3_CHA_MCASP1_TX:
+ __am335xMcAspDmaTxDone(&_G_am335xMcAspChannels[1]);
+ break;
+
+ default:
+ break;
+ }
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspTransfer
+** 功能描述: McASP 传输函数
+** 输 入 : pMcAspChannel McASP 通道
+** pSpiAdapter spi 适配器
+** pSpiMsg spi 传输消息组
+** iNum 消息数量
+** 输 出 : 完成传输的消息数量
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAspTransfer (__PAM335X_MCASP_CHANNEL pMcAspChannel,
+ PLW_SPI_ADAPTER pSpiAdapter,
+ PLW_SPI_MESSAGE pSpiMsg,
+ INT iNum)
+{
+ REGISTER INT i;
+ INT iError;
+
+ for (i = 0; i < iNum; i++, pSpiMsg++) {
+ iError = __am335xMcAspTransferMsg(pMcAspChannel, pSpiMsg);
+ if (iError != ERROR_NONE) {
+ return (i);
+ }
+ }
+
+ return (iNum);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAsp0Transfer
+** 功能描述: McASP0 传输函数
+** 输 入 : pSpiAdapter spi 适配器
+** pSpiMsg spi 传输消息组
+** iNum 消息数量
+** 输 出 : 完成传输的消息数量
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAsp0Transfer (PLW_SPI_ADAPTER pSpiAdapter,
+ PLW_SPI_MESSAGE pSpiMsg,
+ INT iNum)
+{
+ return (__am335xMcAspTransfer(&_G_am335xMcAspChannels[0], pSpiAdapter, pSpiMsg, iNum));
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAsp1Transfer
+** 功能描述: McASP1 传输函数
+** 输 入 : pSpiAdapter spi 适配器
+** pSpiMsg spi 传输消息组
+** iNum 消息数量
+** 输 出 : 完成传输的消息数量
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAsp1Transfer (PLW_SPI_ADAPTER pSpiAdapter,
+ PLW_SPI_MESSAGE pSpiMsg,
+ INT iNum)
+{
+ return (__am335xMcAspTransfer(&_G_am335xMcAspChannels[1], pSpiAdapter, pSpiMsg, iNum));
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspI2SConfigure
+** 功能描述: Configures the McASP Transmit Section in I2S mode
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspI2SConfigure (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ McASPRxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+ McASPTxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+
+ /* Enable the FIFOs for DMA transfer */
+ McASPReadFifoEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase +
+ pMcAspChannel->MCASP_ulFifoRegOffset, 1, 1);
+ McASPWriteFifoEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase +
+ pMcAspChannel->MCASP_ulFifoRegOffset, 1, 1);
+
+ /* Set I2S format in the transmitter/receiver format units */
+ McASPRxFmtI2SSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ __MCASP_DEFAULT_WORD_SIZE, __MCASP_DEFAULT_SLOT_SIZE, MCASP_RX_MODE_DMA);
+ McASPTxFmtI2SSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ __MCASP_DEFAULT_WORD_SIZE, __MCASP_DEFAULT_SLOT_SIZE, MCASP_TX_MODE_DMA);
+
+ pMcAspChannel->MCASP_iBytesPerSample = ((__MCASP_DEFAULT_WORD_SIZE >> 3) *
+ __MCASP_I2S_CHANNELS_NUM);
+
+ /* Configure the frame sync. I2S shall work in TDM format with 2 slots */
+ McASPRxFrameSyncCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, 2, MCASP_RX_FS_WIDTH_WORD,
+ MCASP_RX_FS_EXT_BEGIN_ON_FALL_EDGE);
+ McASPTxFrameSyncCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, 2, MCASP_TX_FS_WIDTH_WORD,
+ MCASP_TX_FS_EXT_BEGIN_ON_FALL_EDGE);
+
+ /* configure the clock for receiver */
+ McASPRxClkCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLK_EXTERNAL, 0, 0);
+ McASPRxClkPolaritySet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLK_POL_RIS_EDGE);
+ McASPRxClkCheckConfig(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLKCHCK_DIV32,
+ 0x00, 0xFF);
+
+ /* configure the clock for transmitter */
+ McASPTxClkCfg(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLK_EXTERNAL, 0, 0);
+ McASPTxClkPolaritySet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLK_POL_FALL_EDGE);
+ McASPTxClkCheckConfig(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLKCHCK_DIV32,
+ 0x00, 0xFF);
+
+ /* Enable synchronization of RX and TX sections */
+ McASPTxRxClkSyncEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+
+ /* Enable the transmitter/receiver slots. I2S uses 2 slots */
+ McASPRxTimeSlotSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, __MCASP_I2S_SLOTS);
+ McASPTxTimeSlotSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, __MCASP_I2S_SLOTS);
+
+ McASPAMuteDisable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+
+ /*
+ * Set the serializers, Currently only one serializer is set as
+ * transmitter and one serializer as receiver.
+ */
+ McASPSerializerRxSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ pMcAspChannel->MCASP_uiSerializerRx);
+ McASPSerializerTxSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ pMcAspChannel->MCASP_uiSerializerTx);
+
+ /*
+ * Configure the McASP pins
+ * Input - Frame Sync, Clock and Serializer Rx
+ * Output - Serializer Tx is connected to the input of the codec
+ */
+ McASPPinMcASPSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ MCASP_PIN_AFSX |
+ MCASP_PIN_ACLKX |
+ MCASP_PIN_AXR(pMcAspChannel->MCASP_uiSerializerTx) |
+ MCASP_PIN_AXR(pMcAspChannel->MCASP_uiSerializerRx));
+
+ McASPPinDirOutputSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ MCASP_PIN_AXR(pMcAspChannel->MCASP_uiSerializerTx));
+ McASPPinDirInputSet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase,
+ MCASP_PIN_AFSX |
+ MCASP_PIN_ACLKX |
+ MCASP_PIN_AXR(pMcAspChannel->MCASP_uiSerializerRx));
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspI2SDataTxRxActivate
+** 功能描述: Activates the data transmission/reception
+** The DMA parameters shall be ready before calling this function.
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : NONE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static VOID __am335xMcAspI2SDataTxRxActivate (__PAM335X_MCASP_CHANNEL pMcAspChannel)
+{
+ /* Start the clocks */
+ McASPTxClkStart(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_TX_CLK_EXTERNAL);
+ McASPRxClkStart(pMcAspChannel->MCASP_ulCtrlVirtAddrBase, MCASP_RX_CLK_EXTERNAL);
+
+ /* Activate the serializers */
+ McASPTxSerActivate(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+ McASPRxSerActivate(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+
+ /* make sure that the XDATA bit is cleared to zero */
+ while (McASPTxStatusGet(pMcAspChannel->MCASP_ulCtrlVirtAddrBase) & MCASP_TX_STAT_DATAREADY);
+
+ /* Activate the state machines */
+ McASPTxEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+ McASPRxEnable(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspMasterCtl
+** 功能描述: McASP 控制函数
+** 输 入 : pMcAspChannel McASP 通道
+** pSpiAdapter spi 适配器
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAspMasterCtl (__PAM335X_MCASP_CHANNEL pMcAspChannel,
+ PLW_SPI_ADAPTER pSpiAdapter,
+ INT iCmd,
+ LONG lArg)
+{
+ __PAUDIO_CODEC_PARAM pCodceParam = (__PAUDIO_CODEC_PARAM)lArg;
+ INT *pIntData = (INT *)lArg;
+ UINT uiChannel = pMcAspChannel - &_G_am335xMcAspChannels[0];
+
+ (VOID)pCodceParam;
+
+ switch (iCmd) {
+ case __AUDIO_CODEC_OPEN:
+ pMcAspChannel->MCASP_ulCtrlVirtAddrBase = (addr_t)API_VmmIoRemapNocache(
+ (PVOID)pMcAspChannel->MCASP_ulCtrlPhyAddrBase,
+ pMcAspChannel->MCASP_stCtrlPhyAddrSize);
+ if (!pMcAspChannel->MCASP_ulCtrlVirtAddrBase) {
+ printk(KERN_ERR "__am335xMcAspMasterCtl(): failed to remap!\n");
+ return (PX_ERROR);
+ }
+
+ switch (uiChannel) {
+ case 0:
+ am335xEnableModuleClock(am335xModuleIdGet("MCASP0"));
+ break;
+
+ case 1:
+ am335xEnableModuleClock(am335xModuleIdGet("MCASP1"));
+ break;
+
+ default:
+ printk(KERN_ERR "__am335xMcAspMasterCtl(): channel invalild!\n");
+ return (PX_ERROR);
+ }
+
+ am335xPinMuxSetup(pMcAspChannel->MCASP_pPinMux);
+
+ __am335xMcAspI2SConfigure(pMcAspChannel);
+
+ __am335xMcAspTxDmaInit(pMcAspChannel);
+
+ __am335xMcAspRxDmaInit(pMcAspChannel);
+
+ __am335xMcAspI2SDataTxRxActivate(pMcAspChannel);
+ break;
+
+ case __AUDIO_CODEC_CLOSE:
+ McASPRxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+ McASPTxReset(pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+
+ __am335xMcAspTxDmaDeInit(pMcAspChannel);
+ __am335xMcAspRxDmaDeInit(pMcAspChannel);
+
+ switch (uiChannel) {
+ case 0:
+ am335xDisableModuleClock(am335xModuleIdGet("MCASP0"), 1);
+ break;
+
+ case 1:
+ am335xDisableModuleClock(am335xModuleIdGet("MCASP1"), 1);
+ break;
+
+ default:
+ printk(KERN_ERR "__am335xMcAspMasterCtl(): channel invalild!\n");
+ return (PX_ERROR);
+ }
+
+ API_VmmIoUnmap((PVOID)pMcAspChannel->MCASP_ulCtrlVirtAddrBase);
+ pMcAspChannel->MCASP_ulCtrlVirtAddrBase = 0;
+ break;
+
+ case __AUDIO_CODEC_SETFMT:
+ if (*pIntData != AFMT_S16_LE) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+ break;
+
+ case __AUDIO_CODEC_CHANNELS:
+ if (*pIntData != __MCASP_I2S_CHANNELS_NUM) {
+ _ErrorHandle(EINVAL);
+ return (PX_ERROR);
+ }
+ break;
+
+ case __AUDIO_CODEC_SPEED:
+ break;
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAsp0MasterCtl
+** 功能描述: McASP0 控制函数
+** 输 入 : pSpiAdapter spi 适配器
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAsp0MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
+ INT iCmd,
+ LONG lArg)
+{
+ return (__am335xMcAspMasterCtl(&_G_am335xMcAspChannels[0], pSpiAdapter, iCmd, lArg));
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAsp1MasterCtl
+** 功能描述: McASP1 控制函数
+** 输 入 : pSpiAdapter spi 适配器
+** iCmd 命令
+** lArg 参数
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAsp1MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
+ INT iCmd,
+ LONG lArg)
+{
+ return (__am335xMcAspMasterCtl(&_G_am335xMcAspChannels[1], pSpiAdapter, iCmd, lArg));
+}
+/*********************************************************************************************************
+** 函数名称: __am335xMcAspInit
+** 功能描述: 初始化 McASP 通道
+** 输 入 : pMcAspChannel McASP 通道
+** 输 出 : ERROR_CODE
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+static INT __am335xMcAspInit(__PAM335X_MCASP_CHANNEL pMcAspChannel,
+ PAM335X_PINMUX pPinMux,
+ UINT uiSerializerTx,
+ UINT uiSerializerRx)
+{
+ if (!pMcAspChannel->MCASP_bIsInit) {
+ pMcAspChannel->MCASP_pPinMux = pPinMux;
+ pMcAspChannel->MCASP_uiSerializerTx = uiSerializerTx;
+ pMcAspChannel->MCASP_uiSerializerRx = uiSerializerRx;
+ pMcAspChannel->MCASP_bIsInit = LW_TRUE;
+ }
+
+ return (ERROR_NONE);
+}
+/*********************************************************************************************************
+ AM335X 处理器 McASP 驱动程序
+*********************************************************************************************************/
+static LW_SPI_FUNCS _G_am335xMcAspFuncs[__MCASP_CHANNEL_NR] = {
+ {
+ __am335xMcAsp0Transfer,
+ __am335xMcAsp0MasterCtl,
+ },
+ {
+ __am335xMcAsp1Transfer,
+ __am335xMcAsp1MasterCtl,
+ }
+};
+/*********************************************************************************************************
+** 函数名称: mcaspBusDrv
+** 功能描述: 初始化 McASP 总线并获取驱动程序
+** 输 入 : uiChannel 通道号
+** pPinMux 管脚复用
+** uiSerializerTx Tx 编号
+** uiSerializerRx Rx 编号
+** 输 出 : McASP 总线驱动程序
+** 全局变量:
+** 调用模块:
+*********************************************************************************************************/
+PLW_SPI_FUNCS mcaspBusDrv (UINT uiChannel,
+ PAM335X_PINMUX pPinMux,
+ UINT uiSerializerTx,
+ UINT uiSerializerRx)
+{
+ if (uiChannel >= __MCASP_CHANNEL_NR) {
+ printk(KERN_ERR "mcaspBusDrv(): McASP channel invalid!\n");
+ return (LW_NULL);
+ }
+
+ if (__am335xMcAspInit(&_G_am335xMcAspChannels[uiChannel],
+ pPinMux, uiSerializerTx, uiSerializerRx) != ERROR_NONE) {
+ return (LW_NULL);
+ }
+
+ return (&_G_am335xMcAspFuncs[uiChannel]);
+}
+/*********************************************************************************************************
+ END
+*********************************************************************************************************/
diff --git a/SylixOS/driver/mcasp/davinci-mcasp.h b/SylixOS/driver/mcasp/davinci-mcasp.h
deleted file mode 100644
index b9f8cd8..0000000
--- a/SylixOS/driver/mcasp/davinci-mcasp.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * ALSA SoC McASP Audio Layer for TI DAVINCI processor
- *
- * MCASP related definitions
- *
- * Author: Nirmal Pandey <n-pandey@ti.com>,
- * Suresh Rajashekara <suresh.r@ti.com>
- * Steve Chen <schen@.mvista.com>
- *
- * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
- * Copyright: (C) 2009 Texas Instruments, India
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef DAVINCI_MCASP_H
-#define DAVINCI_MCASP_H
-
-#define BIT(x) (1 << (x))
-
-/*
- * McASP register definitions
- */
-#define DAVINCI_MCASP_PID_REG 0x00
-#define DAVINCI_MCASP_PWREMUMGT_REG 0x04
-
-#define DAVINCI_MCASP_PFUNC_REG 0x10
-#define DAVINCI_MCASP_PDIR_REG 0x14
-#define DAVINCI_MCASP_PDOUT_REG 0x18
-#define DAVINCI_MCASP_PDSET_REG 0x1c
-
-#define DAVINCI_MCASP_PDCLR_REG 0x20
-
-#define DAVINCI_MCASP_TLGC_REG 0x30
-#define DAVINCI_MCASP_TLMR_REG 0x34
-
-#define DAVINCI_MCASP_GBLCTL_REG 0x44
-#define DAVINCI_MCASP_AMUTE_REG 0x48
-#define DAVINCI_MCASP_LBCTL_REG 0x4c
-
-#define DAVINCI_MCASP_TXDITCTL_REG 0x50
-
-#define DAVINCI_MCASP_GBLCTLR_REG 0x60
-#define DAVINCI_MCASP_RXMASK_REG 0x64
-#define DAVINCI_MCASP_RXFMT_REG 0x68
-#define DAVINCI_MCASP_RXFMCTL_REG 0x6c
-
-#define DAVINCI_MCASP_ACLKRCTL_REG 0x70
-#define DAVINCI_MCASP_AHCLKRCTL_REG 0x74
-#define DAVINCI_MCASP_RXTDM_REG 0x78
-#define DAVINCI_MCASP_EVTCTLR_REG 0x7c
-
-#define DAVINCI_MCASP_RXSTAT_REG 0x80
-#define DAVINCI_MCASP_RXTDMSLOT_REG 0x84
-#define DAVINCI_MCASP_RXCLKCHK_REG 0x88
-#define DAVINCI_MCASP_REVTCTL_REG 0x8c
-
-#define DAVINCI_MCASP_GBLCTLX_REG 0xa0
-#define DAVINCI_MCASP_TXMASK_REG 0xa4
-#define DAVINCI_MCASP_TXFMT_REG 0xa8
-#define DAVINCI_MCASP_TXFMCTL_REG 0xac
-
-#define DAVINCI_MCASP_ACLKXCTL_REG 0xb0
-#define DAVINCI_MCASP_AHCLKXCTL_REG 0xb4
-#define DAVINCI_MCASP_TXTDM_REG 0xb8
-#define DAVINCI_MCASP_EVTCTLX_REG 0xbc
-
-#define DAVINCI_MCASP_TXSTAT_REG 0xc0
-#define DAVINCI_MCASP_TXTDMSLOT_REG 0xc4
-#define DAVINCI_MCASP_TXCLKCHK_REG 0xc8
-#define DAVINCI_MCASP_XEVTCTL_REG 0xcc
-
-/* Left(even TDM Slot) Channel Status Register File */
-#define DAVINCI_MCASP_DITCSRA_REG 0x100
-/* Right(odd TDM slot) Channel Status Register File */
-#define DAVINCI_MCASP_DITCSRB_REG 0x118
-/* Left(even TDM slot) User Data Register File */
-#define DAVINCI_MCASP_DITUDRA_REG 0x130
-/* Right(odd TDM Slot) User Data Register File */
-#define DAVINCI_MCASP_DITUDRB_REG 0x148
-
-/* Serializer n Control Register */
-#define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180
-#define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \
- (n << 2))
-
-/* Transmit Buffer for Serializer n */
-#define DAVINCI_MCASP_TXBUF_REG 0x200
-/* Receive Buffer for Serializer n */
-#define DAVINCI_MCASP_RXBUF_REG 0x280
-
-/* McASP FIFO Registers */
-#define DAVINCI_MCASP_V2_AFIFO_BASE (0x1010)
-#define DAVINCI_MCASP_V3_AFIFO_BASE (0x1000)
-
-/* FIFO register offsets from AFIFO base */
-#define MCASP_WFIFOCTL_OFFSET (0x0)
-#define MCASP_WFIFOSTS_OFFSET (0x4)
-#define MCASP_RFIFOCTL_OFFSET (0x8)
-#define MCASP_RFIFOSTS_OFFSET (0xc)
-
-/*
- * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
- * Register Bits
- */
-#define MCASP_FREE BIT(0)
-#define MCASP_SOFT BIT(1)
-
-/*
- * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits
- */
-#define AXR(n) (1<<n)
-#define PFUNC_AMUTE BIT(25)
-#define ACLKX BIT(26)
-#define AHCLKX BIT(27)
-#define AFSX BIT(28)
-#define ACLKR BIT(29)
-#define AHCLKR BIT(30)
-#define AFSR BIT(31)
-
-/*
- * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits
- */
-#define AXR(n) (1<<n)
-#define PDIR_AMUTE BIT(25)
-#define ACLKX BIT(26)
-#define AHCLKX BIT(27)
-#define AFSX BIT(28)
-#define ACLKR BIT(29)
-#define AHCLKR BIT(30)
-#define AFSR BIT(31)
-
-/*
- * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits
- */
-#define DITEN BIT(0) /* Transmit DIT mode enable/disable */
-#define VA BIT(2)
-#define VB BIT(3)
-
-/*
- * DAVINCI_MCASP_TXFMT_REG - Transmit Bitstream Format Register Bits
- */
-#define TXROT(val) (val)
-#define TXSEL BIT(3)
-#define TXSSZ(val) (val<<4)
-#define TXPBIT(val) (val<<8)
-#define TXPAD(val) (val<<13)
-#define TXORD BIT(15)
-#define FSXDLY(val) (val<<16)
-
-/*
- * DAVINCI_MCASP_RXFMT_REG - Receive Bitstream Format Register Bits
- */
-#define RXROT(val) (val)
-#define RXSEL BIT(3)
-#define RXSSZ(val) (val<<4)
-#define RXPBIT(val) (val<<8)
-#define RXPAD(val) (val<<13)
-#define RXORD BIT(15)
-#define FSRDLY(val) (val<<16)
-
-/*
- * DAVINCI_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits
- */
-#define FSXPOL BIT(0)
-#define AFSXE BIT(1)
-#define FSXDUR BIT(4)
-#define FSXMOD(val) (val<<7)
-
-/*
- * DAVINCI_MCASP_RXFMCTL_REG - Receive Frame Control Register Bits
- */
-#define FSRPOL BIT(0)
-#define AFSRE BIT(1)
-#define FSRDUR BIT(4)
-#define FSRMOD(val) (val<<7)
-
-/*
- * DAVINCI_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits
- */
-#define ACLKXDIV(val) (val)
-#define ACLKXE BIT(5)
-#define TX_ASYNC BIT(6)
-#define ACLKXPOL BIT(7)
-#define ACLKXDIV_MASK 0x1f
-
-/*
- * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
- */
-#define ACLKRDIV(val) (val)
-#define ACLKRE BIT(5)
-#define RX_ASYNC BIT(6)
-#define ACLKRPOL BIT(7)
-#define ACLKRDIV_MASK 0x1f
-
-/*
- * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
- * Register Bits
- */
-#define AHCLKXDIV(val) (val)
-#define AHCLKXPOL BIT(14)
-#define AHCLKXE BIT(15)
-#define AHCLKXDIV_MASK 0xfff
-
-/*
- * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
- * Register Bits
- */
-#define AHCLKRDIV(val) (val)
-#define AHCLKRPOL BIT(14)
-#define AHCLKRE BIT(15)
-#define AHCLKRDIV_MASK 0xfff
-
-/*
- * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
- */
-#define MODE(val) (val)
-#define DISMOD (val)(val<<2)
-#define TXSTATE BIT(4)
-#define RXSTATE BIT(5)
-#define SRMOD_MASK 3
-#define SRMOD_INACTIVE 0
-
-/*
- * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
- */
-#define LBEN BIT(0)
-#define LBORD BIT(1)
-#define LBGENMODE(val) (val<<2)
-
-/*
- * DAVINCI_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration
- */
-#define TXTDMS(n) (1<<n)
-
-/*
- * DAVINCI_MCASP_RXTDMSLOT_REG - Receive TDM Slot Register configuration
- */
-#define RXTDMS(n) (1<<n)
-
-/*
- * DAVINCI_MCASP_GBLCTL_REG - Global Control Register Bits
- */
-#define RXCLKRST BIT(0) /* Receiver Clock Divider Reset */
-#define RXHCLKRST BIT(1) /* Receiver High Frequency Clock Divider */
-#define RXSERCLR BIT(2) /* Receiver Serializer Clear */
-#define RXSMRST BIT(3) /* Receiver State Machine Reset */
-#define RXFSRST BIT(4) /* Frame Sync Generator Reset */
-#define TXCLKRST BIT(8) /* Transmitter Clock Divider Reset */
-#define TXHCLKRST BIT(9) /* Transmitter High Frequency Clock Divider*/
-#define TXSERCLR BIT(10) /* Transmit Serializer Clear */
-#define TXSMRST BIT(11) /* Transmitter State Machine Reset */
-#define TXFSRST BIT(12) /* Frame Sync Generator Reset */
-
-/*
- * DAVINCI_MCASP_AMUTE_REG - Mute Control Register Bits
- */
-#define MUTENA(val) (val)
-#define MUTEINPOL BIT(2)
-#define MUTEINENA BIT(3)
-#define MUTEIN BIT(4)
-#define MUTER BIT(5)
-#define MUTEX BIT(6)
-#define MUTEFSR BIT(7)
-#define MUTEFSX BIT(8)
-#define MUTEBADCLKR BIT(9)
-#define MUTEBADCLKX BIT(10)
-#define MUTERXDMAERR BIT(11)
-#define MUTETXDMAERR BIT(12)
-
-/*
- * DAVINCI_MCASP_REVTCTL_REG - Receiver DMA Event Control Register bits
- */
-#define RXDATADMADIS BIT(0)
-
-/*
- * DAVINCI_MCASP_XEVTCTL_REG - Transmitter DMA Event Control Register bits
- */
-#define TXDATADMADIS BIT(0)
-
-/*
- * DAVINCI_MCASP_W[R]FIFOCTL - Write/Read FIFO Control Register bits
- */
-#define FIFO_ENABLE BIT(16)
-#define NUMEVT_MASK (0xFF << 8)
-#define NUMEVT(x) (((x) & 0xFF) << 8)
-#define NUMDMA_MASK (0xFF)
-
-#endif /* DAVINCI_MCASP_H */
diff --git a/SylixOS/driver/memory/gpmc/gpmc.c b/SylixOS/driver/memory/gpmc/gpmc.c
index 3219aba..2176502 100644
--- a/SylixOS/driver/memory/gpmc/gpmc.c
+++ b/SylixOS/driver/memory/gpmc/gpmc.c
@@ -1,2016 +1,2079 @@
-/*
- * GPMC support functions
- *
- * Copyright (C) 2005-2006 Nokia Corporation
- *
- * Author: Juha Yrjola
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#undef DEBUG
-
-#ifndef SYLIXOS
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_mtd.h>
-#include <linux/of_device.h>
-#include <linux/mtd/nand.h>
-#include <linux/pm_runtime.h>
-
-#include <linux/platform_data/mtd-nand-omap2.h>
-
-#include <asm/mach-types.h>
-
-#include "soc.h"
-#include "common.h"
-#include "omap_device.h"
-#include "gpmc.h"
-#include "gpmc-nand.h"
-#include "gpmc-onenand.h"
-#else
-#define __SYLIXOS_KERNEL
-#include "SylixOS.h"
-#include "driver/memory/memory_config.h"
-#include "driver/memory/memory_port.h"
-#include "gpmc.h"
-#include "driver/memory/platform_data/mtd-nand-omap2.h"
-#endif
-
-#define DEVICE_NAME "omap-gpmc"
-
-/* GPMC register offsets */
-#define GPMC_REVISION 0x00
-#define GPMC_SYSCONFIG 0x10
-#define GPMC_SYSSTATUS 0x14
-#define GPMC_IRQSTATUS 0x18
-#define GPMC_IRQENABLE 0x1c
-#define GPMC_TIMEOUT_CONTROL 0x40
-#define GPMC_ERR_ADDRESS 0x44
-#define GPMC_ERR_TYPE 0x48
-#define GPMC_CONFIG 0x50
-#define GPMC_STATUS 0x54
-#define GPMC_PREFETCH_CONFIG1 0x1e0
-#define GPMC_PREFETCH_CONFIG2 0x1e4
-#define GPMC_PREFETCH_CONTROL 0x1ec
-#define GPMC_PREFETCH_STATUS 0x1f0
-#define GPMC_ECC_CONFIG 0x1f4
-#define GPMC_ECC_CONTROL 0x1f8
-#define GPMC_ECC_SIZE_CONFIG 0x1fc
-#define GPMC_ECC1_RESULT 0x200
-#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */
-#define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */
-#define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */
-#define GPMC_ECC_BCH_RESULT_3 0x24c /* not available on OMAP2 */
-#define GPMC_ECC_BCH_RESULT_4 0x300 /* not available on OMAP2 */
-#define GPMC_ECC_BCH_RESULT_5 0x304 /* not available on OMAP2 */
-#define GPMC_ECC_BCH_RESULT_6 0x308 /* not available on OMAP2 */
-
-/* GPMC ECC control settings */
-#define GPMC_ECC_CTRL_ECCCLEAR 0x100
-#define GPMC_ECC_CTRL_ECCDISABLE 0x000
-#define GPMC_ECC_CTRL_ECCREG1 0x001
-#define GPMC_ECC_CTRL_ECCREG2 0x002
-#define GPMC_ECC_CTRL_ECCREG3 0x003
-#define GPMC_ECC_CTRL_ECCREG4 0x004
-#define GPMC_ECC_CTRL_ECCREG5 0x005
-#define GPMC_ECC_CTRL_ECCREG6 0x006
-#define GPMC_ECC_CTRL_ECCREG7 0x007
-#define GPMC_ECC_CTRL_ECCREG8 0x008
-#define GPMC_ECC_CTRL_ECCREG9 0x009
-
-#define GPMC_CONFIG2_CSEXTRADELAY BIT(7)
-#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7)
-#define GPMC_CONFIG4_OEEXTRADELAY BIT(7)
-#define GPMC_CONFIG4_WEEXTRADELAY BIT(23)
-#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6)
-#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7)
-
-#define GPMC_CS0_OFFSET 0x60
-#define GPMC_CS_SIZE 0x30
-#define GPMC_BCH_SIZE 0x10
-
-#define GPMC_MEM_END 0x3FFFFFFF
-
-#define GPMC_CHUNK_SHIFT 24 /* 16 MB */
-#define GPMC_SECTION_SHIFT 28 /* 128 MB */
-
-#define CS_NUM_SHIFT 24
-#define ENABLE_PREFETCH (0x1 << 7)
-#define DMA_MPU_MODE 2
-
-#define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf)
-#define GPMC_REVISION_MINOR(l) (l & 0xf)
-
-#define GPMC_HAS_WR_ACCESS 0x1
-#define GPMC_HAS_WR_DATA_MUX_BUS 0x2
-#define GPMC_HAS_MUX_AAD 0x4
-
-#define GPMC_NR_WAITPINS 4
-
-/* XXX: Only NAND irq has been considered,currently these are the only ones used
- */
-#define GPMC_NR_IRQ 2
-
-struct gpmc_client_irq {
- unsigned irq;
- u32 bitmask;
-};
-
-/* Structure to save gpmc cs context */
-struct gpmc_cs_config {
- u32 config1;
- u32 config2;
- u32 config3;
- u32 config4;
- u32 config5;
- u32 config6;
- u32 config7;
- int is_valid;
-};
-
-/*
- * Structure to save/restore gpmc context
- * to support core off on OMAP3
- */
-struct omap3_gpmc_regs {
- u32 sysconfig;
- u32 irqenable;
- u32 timeout_ctrl;
- u32 config;
- u32 prefetch_config1;
- u32 prefetch_config2;
- u32 prefetch_control;
- struct gpmc_cs_config cs_context[GPMC_CS_NUM];
-};
-
-#ifndef SYLIXOS
-static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
-static struct irq_chip gpmc_irq_chip;
-static int gpmc_irq_start;
-#endif
-
-static struct resource gpmc_mem_root;
-static struct resource gpmc_cs_mem[GPMC_CS_NUM];
-static DEFINE_SPINLOCK(gpmc_mem_lock);
-/* Define chip-selects as reserved by default until probe completes */
-static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
-static unsigned int gpmc_cs_num = GPMC_CS_NUM;
-static unsigned int gpmc_nr_waitpins;
-static struct device *gpmc_dev;
-#ifndef SYLIXOS
-static int gpmc_irq;
-#endif
-static resource_size_t phys_base, mem_size;
-static unsigned gpmc_capability;
-static void __iomem *gpmc_base;
-
-#ifndef SYLIXOS
-static struct clk *gpmc_l3_clk;
-#else
-static unsigned long gpmc_l3_clk;
-#endif
-
-#ifndef SYLIXOS
-static irqreturn_t gpmc_handle_irq(int irq, void *dev);
-#endif
-
-static void gpmc_write_reg(int idx, u32 val)
-{
- writel_relaxed(val, gpmc_base + idx);
-}
-
-static u32 gpmc_read_reg(int idx)
-{
- return readl_relaxed(gpmc_base + idx);
-}
-
-void gpmc_cs_write_reg(int cs, int idx, u32 val)
-{
- void __iomem *reg_addr;
-
- reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
- writel_relaxed(val, reg_addr);
-}
-
-static u32 gpmc_cs_read_reg(int cs, int idx)
-{
- void __iomem *reg_addr;
-
- reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
- return readl_relaxed(reg_addr);
-}
-
-/* TODO: Add support for gpmc_fck to clock framework and use it */
-static unsigned long gpmc_get_fclk_period(void)
-{
-#ifndef SYLIXOS
- unsigned long rate = clk_get_rate(gpmc_l3_clk);
-#else
- unsigned long rate = gpmc_l3_clk;
-#endif
-
- if (rate == 0) {
- printk(KERN_WARNING "gpmc_l3_clk not enabled\n");
- return 0;
- }
-
- rate /= 1000;
- rate = 1000000000 / rate; /* In picoseconds */
-
- return rate;
-}
-
-static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
-{
- unsigned long tick_ps;
-
- /* Calculate in picosecs to yield more exact results */
- tick_ps = gpmc_get_fclk_period();
-
- return (time_ns * 1000 + tick_ps - 1) / tick_ps;
-}
-
-static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
-{
- unsigned long tick_ps;
-
- /* Calculate in picosecs to yield more exact results */
- tick_ps = gpmc_get_fclk_period();
-
- return (time_ps + tick_ps - 1) / tick_ps;
-}
-
-unsigned int gpmc_ticks_to_ns(unsigned int ticks)
-{
- return ticks * gpmc_get_fclk_period() / 1000;
-}
-
-static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
-{
- return ticks * gpmc_get_fclk_period();
-}
-
-static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
-{
- unsigned long ticks = gpmc_ps_to_ticks(time_ps);
-
- return ticks * gpmc_get_fclk_period();
-}
-
-static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
-{
- u32 l;
-
- l = gpmc_cs_read_reg(cs, reg);
- if (value)
- l |= mask;
- else
- l &= ~mask;
- gpmc_cs_write_reg(cs, reg, l);
-}
-
-static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
-{
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
- GPMC_CONFIG1_TIME_PARA_GRAN,
- p->time_para_granularity);
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
- GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
- GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
- GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
- GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
- GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
- p->cycle2cyclesamecsen);
- gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
- GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN,
- p->cycle2cyclediffcsen);
-}
-
-#ifdef DEBUG
-static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
- int time, const char *name)
-#else
-static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
- int time)
-#endif
-{
- u32 l;
- int ticks, mask, nr_bits;
-
- if (time == 0)
- ticks = 0;
- else
- ticks = gpmc_ns_to_ticks(time);
- nr_bits = end_bit - st_bit + 1;
- if (ticks >= 1 << nr_bits) {
-#ifdef DEBUG
- printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
- cs, name, time, ticks, 1 << nr_bits);
-#endif
- return -1;
- }
-
- mask = (1 << nr_bits) - 1;
- l = gpmc_cs_read_reg(cs, reg);
-#ifdef DEBUG
- printk(KERN_INFO
- "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
- cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
- (l >> st_bit) & mask, time);
-#endif
- l &= ~(mask << st_bit);
- l |= ticks << st_bit;
- gpmc_cs_write_reg(cs, reg, l);
-
- return 0;
-}
-
-#ifdef DEBUG
-#define GPMC_SET_ONE(reg, st, end, field) \
- if (set_gpmc_timing_reg(cs, (reg), (st), (end), \
- t->field, #field) < 0) \
- return -1
-#else
-#define GPMC_SET_ONE(reg, st, end, field) \
- if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \
- return -1
-#endif
-
-int gpmc_calc_divider(unsigned int sync_clk)
-{
- int div;
- u32 l;
-
- l = sync_clk + (gpmc_get_fclk_period() - 1);
- div = l / gpmc_get_fclk_period();
- if (div > 4)
- return -1;
- if (div <= 0)
- div = 1;
-
- return div;
-}
-
-int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
-{
- int div;
- u32 l;
-
- div = gpmc_calc_divider(t->sync_clk);
- if (div < 0)
- return div;
-
- GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on);
- GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off);
- GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off);
-
- GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on);
- GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off);
- GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off);
-
- GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on);
- GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off);
- GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on);
- GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off);
-
- GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle);
- GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle);
- GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access);
-
- GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
-
- GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
- GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
-
- GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
- GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
-
- if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
- GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
- if (gpmc_capability & GPMC_HAS_WR_ACCESS)
- GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
-
- /* caller is expected to have initialized CONFIG1 to cover
- * at least sync vs async
- */
- l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
- if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
-#ifdef DEBUG
- printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
- cs, (div * gpmc_get_fclk_period()) / 1000, div);
-#endif
- l &= ~0x03;
- l |= (div - 1);
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
- }
-
- gpmc_cs_bool_timings(cs, &t->bool_timings);
-
- return 0;
-}
-
-static int gpmc_cs_enable_mem(int cs, u32 base, u32 size)
-{
- u32 l;
- u32 mask;
-
- /*
- * Ensure that base address is aligned on a
- * boundary equal to or greater than size.
- */
- if (base & (size - 1))
- return -EINVAL;
-
- mask = (1 << GPMC_SECTION_SHIFT) - size;
- l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
- l &= ~0x3f;
- l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
- l &= ~(0x0f << 8);
- l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
- l |= GPMC_CONFIG7_CSVALID;
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
-
- return 0;
-}
-
-static void gpmc_cs_disable_mem(int cs)
-{
- u32 l;
-
- l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
- l &= ~GPMC_CONFIG7_CSVALID;
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
-}
-
-static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size)
-{
- u32 l;
- u32 mask;
-
- l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
- *base = (l & 0x3f) << GPMC_CHUNK_SHIFT;
- mask = (l >> 8) & 0x0f;
- *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT);
-}
-
-static int gpmc_cs_mem_enabled(int cs)
-{
- u32 l;
-
- l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
- return l & GPMC_CONFIG7_CSVALID;
-}
-
-static void gpmc_cs_set_reserved(int cs, int reserved)
-{
- gpmc_cs_map &= ~(1 << cs);
- gpmc_cs_map |= (reserved ? 1 : 0) << cs;
-}
-
-static bool gpmc_cs_reserved(int cs)
-{
- return gpmc_cs_map & (1 << cs);
-}
-
-static unsigned long gpmc_mem_align(unsigned long size)
-{
- int order;
-
- size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1);
- order = GPMC_CHUNK_SHIFT - 1;
- do {
- size >>= 1;
- order++;
- } while (size);
- size = 1 << order;
- return size;
-}
-
-static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
-{
- struct resource *res = &gpmc_cs_mem[cs];
- int r;
-
- size = gpmc_mem_align(size);
- spin_lock(&gpmc_mem_lock);
- res->start = base;
- res->end = base + size - 1;
- r = request_resource(&gpmc_mem_root, res);
- spin_unlock(&gpmc_mem_lock);
-
- return r;
-}
-
-#ifndef SYLIXOS
-static int gpmc_cs_delete_mem(int cs)
-{
- struct resource *res = &gpmc_cs_mem[cs];
- int r;
-
- spin_lock(&gpmc_mem_lock);
- r = release_resource(res);
- res->start = 0;
- res->end = 0;
- spin_unlock(&gpmc_mem_lock);
-
- return r;
-}
-
-/**
- * gpmc_cs_remap - remaps a chip-select physical base address
- * @cs: chip-select to remap
- * @base: physical base address to re-map chip-select to
- *
- * Re-maps a chip-select to a new physical base address specified by
- * "base". Returns 0 on success and appropriate negative error code
- * on failure.
- */
-static int gpmc_cs_remap(int cs, u32 base)
-{
- int ret;
- u32 old_base, size;
-
- if (cs > gpmc_cs_num) {
- pr_err("%s: requested chip-select is disabled\n", __func__);
- return -ENODEV;
- }
-
- /*
- * Make sure we ignore any device offsets from the GPMC partition
- * allocated for the chip select and that the new base confirms
- * to the GPMC 16MB minimum granularity.
- */
- base &= ~(SZ_16M - 1);
-
- gpmc_cs_get_memconf(cs, &old_base, &size);
- if (base == old_base)
- return 0;
- gpmc_cs_disable_mem(cs);
- ret = gpmc_cs_delete_mem(cs);
- if (ret < 0)
- return ret;
- ret = gpmc_cs_insert_mem(cs, base, size);
- if (ret < 0)
- return ret;
- ret = gpmc_cs_enable_mem(cs, base, size);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-#endif
-
-int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
-{
- struct resource *res = &gpmc_cs_mem[cs];
- int r = -1;
-
- if (cs > gpmc_cs_num) {
- pr_err("%s: requested chip-select is disabled\n", __func__);
- return -ENODEV;
- }
- size = gpmc_mem_align(size);
- if (size > (1 << GPMC_SECTION_SHIFT))
- return -ENOMEM;
-
- spin_lock(&gpmc_mem_lock);
- if (gpmc_cs_reserved(cs)) {
- r = -EBUSY;
- goto out;
- }
- if (gpmc_cs_mem_enabled(cs))
- r = adjust_resource(res, res->start & ~(size - 1), size);
- if (r < 0)
- r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0,
- size, NULL, NULL);
- if (r < 0)
- goto out;
-
- r = gpmc_cs_enable_mem(cs, res->start, resource_size(res));
- if (r < 0) {
- release_resource(res);
- goto out;
- }
-
- *base = res->start;
- gpmc_cs_set_reserved(cs, 1);
-out:
- spin_unlock(&gpmc_mem_lock);
- return r;
-}
-EXPORT_SYMBOL(gpmc_cs_request);
-
-void gpmc_cs_free(int cs)
-{
- struct resource *res = &gpmc_cs_mem[cs];
-
- spin_lock(&gpmc_mem_lock);
- if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
- printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
- BUG();
- spin_unlock(&gpmc_mem_lock);
- return;
- }
- gpmc_cs_disable_mem(cs);
- if (res->flags)
- release_resource(res);
- gpmc_cs_set_reserved(cs, 0);
- spin_unlock(&gpmc_mem_lock);
-}
-EXPORT_SYMBOL(gpmc_cs_free);
-
-/**
- * gpmc_configure - write request to configure gpmc
- * @cmd: command type
- * @wval: value to write
- * @return status of the operation
- */
-int gpmc_configure(int cmd, int wval)
-{
- u32 regval;
-
- switch (cmd) {
- case GPMC_ENABLE_IRQ:
- gpmc_write_reg(GPMC_IRQENABLE, wval);
- break;
-
- case GPMC_SET_IRQ_STATUS:
- gpmc_write_reg(GPMC_IRQSTATUS, wval);
- break;
-
- case GPMC_CONFIG_WP:
- regval = gpmc_read_reg(GPMC_CONFIG);
- if (wval)
- regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */
- else
- regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */
- gpmc_write_reg(GPMC_CONFIG, regval);
- break;
-
- default:
- pr_err("%s: command not supported\n", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(gpmc_configure);
-
-void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
-{
- int i;
-
- reg->gpmc_status = gpmc_base + GPMC_STATUS;
- reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
- GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
- reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET +
- GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs;
- reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET +
- GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs;
- reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1;
- reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2;
- reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL;
- reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS;
- reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG;
- reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
- reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
- reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
-
- for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) {
- reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
- GPMC_BCH_SIZE * i;
- reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
- GPMC_BCH_SIZE * i;
- reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
- GPMC_BCH_SIZE * i;
- reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
- GPMC_BCH_SIZE * i;
- reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 +
- i * GPMC_BCH_SIZE;
- reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 +
- i * GPMC_BCH_SIZE;
- reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 +
- i * GPMC_BCH_SIZE;
- }
-}
-
-#ifndef SYLIXOS
-int gpmc_get_client_irq(unsigned irq_config)
-{
- int i;
-
- if (hweight32(irq_config) > 1)
- return 0;
-
- for (i = 0; i < GPMC_NR_IRQ; i++)
- if (gpmc_client_irq[i].bitmask & irq_config)
- return gpmc_client_irq[i].irq;
-
- return 0;
-}
-
-static int gpmc_irq_endis(unsigned irq, bool endis)
-{
- int i;
- u32 regval;
-
- for (i = 0; i < GPMC_NR_IRQ; i++)
- if (irq == gpmc_client_irq[i].irq) {
- regval = gpmc_read_reg(GPMC_IRQENABLE);
- if (endis)
- regval |= gpmc_client_irq[i].bitmask;
- else
- regval &= ~gpmc_client_irq[i].bitmask;
- gpmc_write_reg(GPMC_IRQENABLE, regval);
- break;
- }
-
- return 0;
-}
-
-static void gpmc_irq_disable(struct irq_data *p)
-{
- gpmc_irq_endis(p->irq, false);
-}
-
-static void gpmc_irq_enable(struct irq_data *p)
-{
- gpmc_irq_endis(p->irq, true);
-}
-
-static void gpmc_irq_noop(struct irq_data *data) { }
-
-static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
-
-static int gpmc_setup_irq(void)
-{
- int i;
- u32 regval;
-
- if (!gpmc_irq)
- return -EINVAL;
-
- gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0);
- if (gpmc_irq_start < 0) {
- pr_err("irq_alloc_descs failed\n");
- return gpmc_irq_start;
- }
-
- gpmc_irq_chip.name = "gpmc";
- gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
- gpmc_irq_chip.irq_enable = gpmc_irq_enable;
- gpmc_irq_chip.irq_disable = gpmc_irq_disable;
- gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
- gpmc_irq_chip.irq_ack = gpmc_irq_noop;
- gpmc_irq_chip.irq_mask = gpmc_irq_noop;
- gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
-
- gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
- gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
-
- for (i = 0; i < GPMC_NR_IRQ; i++) {
- gpmc_client_irq[i].irq = gpmc_irq_start + i;
- irq_set_chip_and_handler(gpmc_client_irq[i].irq,
- &gpmc_irq_chip, handle_simple_irq);
- set_irq_flags(gpmc_client_irq[i].irq,
- IRQF_VALID | IRQF_NOAUTOEN);
- }
-
- /* Disable interrupts */
- gpmc_write_reg(GPMC_IRQENABLE, 0);
-
- /* clear interrupts */
- regval = gpmc_read_reg(GPMC_IRQSTATUS);
- gpmc_write_reg(GPMC_IRQSTATUS, regval);
-
- return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
-}
-
-static int gpmc_free_irq(void)
-{
- int i;
-
- if (gpmc_irq)
- free_irq(gpmc_irq, NULL);
-
- for (i = 0; i < GPMC_NR_IRQ; i++) {
- irq_set_handler(gpmc_client_irq[i].irq, NULL);
- irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip);
- irq_modify_status(gpmc_client_irq[i].irq, 0, 0);
- }
-
- irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
-
- return 0;
-}
-
-static void gpmc_mem_exit(void)
-{
- int cs;
-
- for (cs = 0; cs < gpmc_cs_num; cs++) {
- if (!gpmc_cs_mem_enabled(cs))
- continue;
- gpmc_cs_delete_mem(cs);
- }
-
-}
-#endif
-
-static void gpmc_mem_init(void)
-{
- int cs;
-
- /*
- * The first 1MB of GPMC address space is typically mapped to
- * the internal ROM. Never allocate the first page, to
- * facilitate bug detection; even if we didn't boot from ROM.
- */
- gpmc_mem_root.start = SZ_1M;
- gpmc_mem_root.end = GPMC_MEM_END;
-#ifdef SYLIXOS
- gpmc_mem_root.current = gpmc_mem_root.start;
-#endif
-
- /* Reserve all regions that has been set up by bootloader */
- for (cs = 0; cs < gpmc_cs_num; cs++) {
- u32 base, size;
-
- if (!gpmc_cs_mem_enabled(cs))
- continue;
- gpmc_cs_get_memconf(cs, &base, &size);
- if (gpmc_cs_insert_mem(cs, base, size)) {
- pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n",
- __func__, cs, base, base + size);
- gpmc_cs_disable_mem(cs);
- }
- }
-}
-
-static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
-{
- u32 temp;
- int div;
-
- div = gpmc_calc_divider(sync_clk);
- temp = gpmc_ps_to_ticks(time_ps);
- temp = (temp + div - 1) / div;
- return gpmc_ticks_to_ps(temp * div);
-}
-
-/* XXX: can the cycles be avoided ? */
-static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t,
- bool mux)
-{
- u32 temp;
-
- /* adv_rd_off */
- temp = dev_t->t_avdp_r;
- /* XXX: mux check required ? */
- if (mux) {
- /* XXX: t_avdp not to be required for sync, only added for tusb
- * this indirectly necessitates requirement of t_avdp_r and
- * t_avdp_w instead of having a single t_avdp
- */
- temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh);
- temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
- }
- gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
-
- /* oe_on */
- temp = dev_t->t_oeasu; /* XXX: remove this ? */
- if (mux) {
- temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach);
- temp = max_t(u32, temp, gpmc_t->adv_rd_off +
- gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
- }
- gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
-
- /* access */
- /* XXX: any scope for improvement ?, by combining oe_on
- * and clk_activation, need to check whether
- * access = clk_activation + round to sync clk ?
- */
- temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk);
- temp += gpmc_t->clk_activation;
- if (dev_t->cyc_oe)
- temp = max_t(u32, temp, gpmc_t->oe_on +
- gpmc_ticks_to_ps(dev_t->cyc_oe));
- gpmc_t->access = gpmc_round_ps_to_ticks(temp);
-
- gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
- gpmc_t->cs_rd_off = gpmc_t->oe_off;
-
- /* rd_cycle */
- temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
- temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
- gpmc_t->access;
- /* XXX: barter t_ce_rdyz with t_cez_r ? */
- if (dev_t->t_ce_rdyz)
- temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
- gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
-
- return 0;
-}
-
-static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t,
- bool mux)
-{
- u32 temp;
-
- /* adv_wr_off */
- temp = dev_t->t_avdp_w;
- if (mux) {
- temp = max_t(u32, temp,
- gpmc_t->clk_activation + dev_t->t_avdh);
- temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
- }
- gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
-
- /* wr_data_mux_bus */
- temp = max_t(u32, dev_t->t_weasu,
- gpmc_t->clk_activation + dev_t->t_rdyo);
- /* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?,
- * and in that case remember to handle we_on properly
- */
- if (mux) {
- temp = max_t(u32, temp,
- gpmc_t->adv_wr_off + dev_t->t_aavdh);
- temp = max_t(u32, temp, gpmc_t->adv_wr_off +
- gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
- }
- gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
-
- /* we_on */
- if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
- gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
- else
- gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
-
- /* wr_access */
- /* XXX: gpmc_capability check reqd ? , even if not, will not harm */
- gpmc_t->wr_access = gpmc_t->access;
-
- /* we_off */
- temp = gpmc_t->we_on + dev_t->t_wpl;
- temp = max_t(u32, temp,
- gpmc_t->wr_access + gpmc_ticks_to_ps(1));
- temp = max_t(u32, temp,
- gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
- gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
-
- gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
- dev_t->t_wph);
-
- /* wr_cycle */
- temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
- temp += gpmc_t->wr_access;
- /* XXX: barter t_ce_rdyz with t_cez_w ? */
- if (dev_t->t_ce_rdyz)
- temp = max_t(u32, temp,
- gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
- gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
-
- return 0;
-}
-
-static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t,
- bool mux)
-{
- u32 temp;
-
- /* adv_rd_off */
- temp = dev_t->t_avdp_r;
- if (mux)
- temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
- gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
-
- /* oe_on */
- temp = dev_t->t_oeasu;
- if (mux)
- temp = max_t(u32, temp,
- gpmc_t->adv_rd_off + dev_t->t_aavdh);
- gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
-
- /* access */
- temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */
- gpmc_t->oe_on + dev_t->t_oe);
- temp = max_t(u32, temp,
- gpmc_t->cs_on + dev_t->t_ce);
- temp = max_t(u32, temp,
- gpmc_t->adv_on + dev_t->t_aa);
- gpmc_t->access = gpmc_round_ps_to_ticks(temp);
-
- gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
- gpmc_t->cs_rd_off = gpmc_t->oe_off;
-
- /* rd_cycle */
- temp = max_t(u32, dev_t->t_rd_cycle,
- gpmc_t->cs_rd_off + dev_t->t_cez_r);
- temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
- gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
-
- return 0;
-}
-
-static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t,
- bool mux)
-{
- u32 temp;
-
- /* adv_wr_off */
- temp = dev_t->t_avdp_w;
- if (mux)
- temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
- gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
-
- /* wr_data_mux_bus */
- temp = dev_t->t_weasu;
- if (mux) {
- temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh);
- temp = max_t(u32, temp, gpmc_t->adv_wr_off +
- gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
- }
- gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
-
- /* we_on */
- if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
- gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
- else
- gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
-
- /* we_off */
- temp = gpmc_t->we_on + dev_t->t_wpl;
- gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
-
- gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
- dev_t->t_wph);
-
- /* wr_cycle */
- temp = max_t(u32, dev_t->t_wr_cycle,
- gpmc_t->cs_wr_off + dev_t->t_cez_w);
- gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
-
- return 0;
-}
-
-static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t)
-{
- u32 temp;
-
- gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
- gpmc_get_fclk_period();
-
- gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
- dev_t->t_bacc,
- gpmc_t->sync_clk);
-
- temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
- gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
-
- if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
- return 0;
-
- if (dev_t->ce_xdelay)
- gpmc_t->bool_timings.cs_extra_delay = true;
- if (dev_t->avd_xdelay)
- gpmc_t->bool_timings.adv_extra_delay = true;
- if (dev_t->oe_xdelay)
- gpmc_t->bool_timings.oe_extra_delay = true;
- if (dev_t->we_xdelay)
- gpmc_t->bool_timings.we_extra_delay = true;
-
- return 0;
-}
-
-static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_device_timings *dev_t,
- bool sync)
-{
- u32 temp;
-
- /* cs_on */
- gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
-
- /* adv_on */
- temp = dev_t->t_avdasu;
- if (dev_t->t_ce_avd)
- temp = max_t(u32, temp,
- gpmc_t->cs_on + dev_t->t_ce_avd);
- gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
-
- if (sync)
- gpmc_calc_sync_common_timings(gpmc_t, dev_t);
-
- return 0;
-}
-
-/* TODO: remove this function once all peripherals are confirmed to
- * work with generic timing. Simultaneously gpmc_cs_set_timings()
- * has to be modified to handle timings in ps instead of ns
-*/
-static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
-{
- t->cs_on /= 1000;
- t->cs_rd_off /= 1000;
- t->cs_wr_off /= 1000;
- t->adv_on /= 1000;
- t->adv_rd_off /= 1000;
- t->adv_wr_off /= 1000;
- t->we_on /= 1000;
- t->we_off /= 1000;
- t->oe_on /= 1000;
- t->oe_off /= 1000;
- t->page_burst_access /= 1000;
- t->access /= 1000;
- t->rd_cycle /= 1000;
- t->wr_cycle /= 1000;
- t->bus_turnaround /= 1000;
- t->cycle2cycle_delay /= 1000;
- t->wait_monitoring /= 1000;
- t->clk_activation /= 1000;
- t->wr_access /= 1000;
- t->wr_data_mux_bus /= 1000;
-}
-
-int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
- struct gpmc_settings *gpmc_s,
- struct gpmc_device_timings *dev_t)
-{
- bool mux = false, sync = false;
-
- if (gpmc_s) {
- mux = gpmc_s->mux_add_data ? true : false;
- sync = (gpmc_s->sync_read || gpmc_s->sync_write);
- }
-
- memset(gpmc_t, 0, sizeof(*gpmc_t));
-
- gpmc_calc_common_timings(gpmc_t, dev_t, sync);
-
- if (gpmc_s && gpmc_s->sync_read)
- gpmc_calc_sync_read_timings(gpmc_t, dev_t, mux);
- else
- gpmc_calc_async_read_timings(gpmc_t, dev_t, mux);
-
- if (gpmc_s && gpmc_s->sync_write)
- gpmc_calc_sync_write_timings(gpmc_t, dev_t, mux);
- else
- gpmc_calc_async_write_timings(gpmc_t, dev_t, mux);
-
- /* TODO: remove, see function definition */
- gpmc_convert_ps_to_ns(gpmc_t);
-
- return 0;
-}
-
-/**
- * gpmc_cs_program_settings - programs non-timing related settings
- * @cs: GPMC chip-select to program
- * @p: pointer to GPMC settings structure
- *
- * Programs non-timing related settings for a GPMC chip-select, such as
- * bus-width, burst configuration, etc. Function should be called once
- * for each chip-select that is being used and must be called before
- * calling gpmc_cs_set_timings() as timing parameters in the CONFIG1
- * register will be initialised to zero by this function. Returns 0 on
- * success and appropriate negative error code on failure.
- */
-int gpmc_cs_program_settings(int cs, struct gpmc_settings *p)
-{
- u32 config1;
-
- if ((!p->device_width) || (p->device_width > GPMC_DEVWIDTH_16BIT)) {
- pr_err("%s: invalid width %d!", __func__, p->device_width);
- return -EINVAL;
- }
-
- /* Address-data multiplexing not supported for NAND devices */
- if (p->device_nand && p->mux_add_data) {
- pr_err("%s: invalid configuration!\n", __func__);
- return -EINVAL;
- }
-
- if ((p->mux_add_data > GPMC_MUX_AD) ||
- ((p->mux_add_data == GPMC_MUX_AAD) &&
- !(gpmc_capability & GPMC_HAS_MUX_AAD))) {
- pr_err("%s: invalid multiplex configuration!\n", __func__);
- return -EINVAL;
- }
-
- /* Page/burst mode supports lengths of 4, 8 and 16 bytes */
- if (p->burst_read || p->burst_write) {
- switch (p->burst_len) {
- case GPMC_BURST_4:
- case GPMC_BURST_8:
- case GPMC_BURST_16:
- break;
- default:
- pr_err("%s: invalid page/burst-length (%d)\n",
- __func__, p->burst_len);
- return -EINVAL;
- }
- }
-
- if (p->wait_pin > gpmc_nr_waitpins) {
- pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin);
- return -EINVAL;
- }
-
- config1 = GPMC_CONFIG1_DEVICESIZE((p->device_width - 1));
-
- if (p->sync_read)
- config1 |= GPMC_CONFIG1_READTYPE_SYNC;
- if (p->sync_write)
- config1 |= GPMC_CONFIG1_WRITETYPE_SYNC;
- if (p->wait_on_read)
- config1 |= GPMC_CONFIG1_WAIT_READ_MON;
- if (p->wait_on_write)
- config1 |= GPMC_CONFIG1_WAIT_WRITE_MON;
- if (p->wait_on_read || p->wait_on_write)
- config1 |= GPMC_CONFIG1_WAIT_PIN_SEL(p->wait_pin);
- if (p->device_nand)
- config1 |= GPMC_CONFIG1_DEVICETYPE(GPMC_DEVICETYPE_NAND);
- if (p->mux_add_data)
- config1 |= GPMC_CONFIG1_MUXTYPE(p->mux_add_data);
- if (p->burst_read)
- config1 |= GPMC_CONFIG1_READMULTIPLE_SUPP;
- if (p->burst_write)
- config1 |= GPMC_CONFIG1_WRITEMULTIPLE_SUPP;
- if (p->burst_read || p->burst_write) {
- config1 |= GPMC_CONFIG1_PAGE_LEN(p->burst_len >> 3);
- config1 |= p->burst_wrap ? GPMC_CONFIG1_WRAPBURST_SUPP : 0;
- }
-
- gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, config1);
-
- return 0;
-}
-
-#ifdef CONFIG_OF
-static struct of_device_id gpmc_dt_ids[] = {
- { .compatible = "ti,omap2420-gpmc" },
- { .compatible = "ti,omap2430-gpmc" },
- { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
- { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
- { .compatible = "ti,am3352-gpmc" }, /* am335x devices */
- { }
-};
-MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
-
-/**
- * gpmc_read_settings_dt - read gpmc settings from device-tree
- * @np: pointer to device-tree node for a gpmc child device
- * @p: pointer to gpmc settings structure
- *
- * Reads the GPMC settings for a GPMC child device from device-tree and
- * stores them in the GPMC settings structure passed. The GPMC settings
- * structure is initialised to zero by this function and so any
- * previously stored settings will be cleared.
- */
-void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p)
-{
- memset(p, 0, sizeof(struct gpmc_settings));
-
- p->sync_read = of_property_read_bool(np, "gpmc,sync-read");
- p->sync_write = of_property_read_bool(np, "gpmc,sync-write");
- of_property_read_u32(np, "gpmc,device-width", &p->device_width);
- of_property_read_u32(np, "gpmc,mux-add-data", &p->mux_add_data);
-
- if (!of_property_read_u32(np, "gpmc,burst-length", &p->burst_len)) {
- p->burst_wrap = of_property_read_bool(np, "gpmc,burst-wrap");
- p->burst_read = of_property_read_bool(np, "gpmc,burst-read");
- p->burst_write = of_property_read_bool(np, "gpmc,burst-write");
- if (!p->burst_read && !p->burst_write)
- pr_warn("%s: page/burst-length set but not used!\n",
- __func__);
- }
-
- if (!of_property_read_u32(np, "gpmc,wait-pin", &p->wait_pin)) {
- p->wait_on_read = of_property_read_bool(np,
- "gpmc,wait-on-read");
- p->wait_on_write = of_property_read_bool(np,
- "gpmc,wait-on-write");
- if (!p->wait_on_read && !p->wait_on_write)
- pr_debug("%s: rd/wr wait monitoring not enabled!\n",
- __func__);
- }
-}
-
-static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
- struct gpmc_timings *gpmc_t)
-{
- struct gpmc_bool_timings *p;
-
- if (!np || !gpmc_t)
- return;
-
- memset(gpmc_t, 0, sizeof(*gpmc_t));
-
- /* minimum clock period for syncronous mode */
- of_property_read_u32(np, "gpmc,sync-clk-ps", &gpmc_t->sync_clk);
-
- /* chip select timtings */
- of_property_read_u32(np, "gpmc,cs-on-ns", &gpmc_t->cs_on);
- of_property_read_u32(np, "gpmc,cs-rd-off-ns", &gpmc_t->cs_rd_off);
- of_property_read_u32(np, "gpmc,cs-wr-off-ns", &gpmc_t->cs_wr_off);
-
- /* ADV signal timings */
- of_property_read_u32(np, "gpmc,adv-on-ns", &gpmc_t->adv_on);
- of_property_read_u32(np, "gpmc,adv-rd-off-ns", &gpmc_t->adv_rd_off);
- of_property_read_u32(np, "gpmc,adv-wr-off-ns", &gpmc_t->adv_wr_off);
-
- /* WE signal timings */
- of_property_read_u32(np, "gpmc,we-on-ns", &gpmc_t->we_on);
- of_property_read_u32(np, "gpmc,we-off-ns", &gpmc_t->we_off);
-
- /* OE signal timings */
- of_property_read_u32(np, "gpmc,oe-on-ns", &gpmc_t->oe_on);
- of_property_read_u32(np, "gpmc,oe-off-ns", &gpmc_t->oe_off);
-
- /* access and cycle timings */
- of_property_read_u32(np, "gpmc,page-burst-access-ns",
- &gpmc_t->page_burst_access);
- of_property_read_u32(np, "gpmc,access-ns", &gpmc_t->access);
- of_property_read_u32(np, "gpmc,rd-cycle-ns", &gpmc_t->rd_cycle);
- of_property_read_u32(np, "gpmc,wr-cycle-ns", &gpmc_t->wr_cycle);
- of_property_read_u32(np, "gpmc,bus-turnaround-ns",
- &gpmc_t->bus_turnaround);
- of_property_read_u32(np, "gpmc,cycle2cycle-delay-ns",
- &gpmc_t->cycle2cycle_delay);
- of_property_read_u32(np, "gpmc,wait-monitoring-ns",
- &gpmc_t->wait_monitoring);
- of_property_read_u32(np, "gpmc,clk-activation-ns",
- &gpmc_t->clk_activation);
-
- /* only applicable to OMAP3+ */
- of_property_read_u32(np, "gpmc,wr-access-ns", &gpmc_t->wr_access);
- of_property_read_u32(np, "gpmc,wr-data-mux-bus-ns",
- &gpmc_t->wr_data_mux_bus);
-
- /* bool timing parameters */
- p = &gpmc_t->bool_timings;
-
- p->cycle2cyclediffcsen =
- of_property_read_bool(np, "gpmc,cycle2cycle-diffcsen");
- p->cycle2cyclesamecsen =
- of_property_read_bool(np, "gpmc,cycle2cycle-samecsen");
- p->we_extra_delay = of_property_read_bool(np, "gpmc,we-extra-delay");
- p->oe_extra_delay = of_property_read_bool(np, "gpmc,oe-extra-delay");
- p->adv_extra_delay = of_property_read_bool(np, "gpmc,adv-extra-delay");
- p->cs_extra_delay = of_property_read_bool(np, "gpmc,cs-extra-delay");
- p->time_para_granularity =
- of_property_read_bool(np, "gpmc,time-para-granularity");
-}
-
-#if IS_ENABLED(CONFIG_MTD_NAND)
-
-static const char * const nand_xfer_types[] = {
- [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled",
- [NAND_OMAP_POLLED] = "polled",
- [NAND_OMAP_PREFETCH_DMA] = "prefetch-dma",
- [NAND_OMAP_PREFETCH_IRQ] = "prefetch-irq",
-};
-
-static int gpmc_probe_nand_child(struct platform_device *pdev,
- struct device_node *child)
-{
- u32 val;
- const char *s;
- struct gpmc_timings gpmc_t;
- struct omap_nand_platform_data *gpmc_nand_data;
-
- if (of_property_read_u32(child, "reg", &val) < 0) {
- dev_err(&pdev->dev, "%s has no 'reg' property\n",
- child->full_name);
- return -ENODEV;
- }
-
- gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
- GFP_KERNEL);
- if (!gpmc_nand_data)
- return -ENOMEM;
-
- gpmc_nand_data->cs = val;
- gpmc_nand_data->of_node = child;
-
- /* Detect availability of ELM module */
- gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
- if (gpmc_nand_data->elm_of_node == NULL)
- gpmc_nand_data->elm_of_node =
- of_parse_phandle(child, "elm_id", 0);
- if (gpmc_nand_data->elm_of_node == NULL)
- pr_warn("%s: ti,elm-id property not found\n", __func__);
-
- /* select ecc-scheme for NAND */
- if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
- pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
- return -ENODEV;
- }
-
- if (!strcmp(s, "sw"))
- gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_SW;
- else if (!strcmp(s, "ham1") ||
- !strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
- gpmc_nand_data->ecc_opt =
- OMAP_ECC_HAM1_CODE_HW;
- else if (!strcmp(s, "bch4"))
- if (gpmc_nand_data->elm_of_node)
- gpmc_nand_data->ecc_opt =
- OMAP_ECC_BCH4_CODE_HW;
- else
- gpmc_nand_data->ecc_opt =
- OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
- else if (!strcmp(s, "bch8"))
- if (gpmc_nand_data->elm_of_node)
- gpmc_nand_data->ecc_opt =
- OMAP_ECC_BCH8_CODE_HW;
- else
- gpmc_nand_data->ecc_opt =
- OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
- else if (!strcmp(s, "bch16"))
- if (gpmc_nand_data->elm_of_node)
- gpmc_nand_data->ecc_opt =
- OMAP_ECC_BCH16_CODE_HW;
- else
- pr_err("%s: BCH16 requires ELM support\n", __func__);
- else
- pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
-
- /* select data transfer mode for NAND controller */
- if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
- for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
- if (!strcasecmp(s, nand_xfer_types[val])) {
- gpmc_nand_data->xfer_type = val;
- break;
- }
-
- val = of_get_nand_bus_width(child);
- if (val == 16)
- gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
-
- gpmc_read_timings_dt(child, &gpmc_t);
- gpmc_nand_init(gpmc_nand_data, &gpmc_t);
-
- return 0;
-}
-#else
-static int gpmc_probe_nand_child(struct platform_device *pdev,
- struct device_node *child)
-{
- return 0;
-}
-#endif
-
-#if IS_ENABLED(CONFIG_MTD_ONENAND)
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
- struct device_node *child)
-{
- u32 val;
- struct omap_onenand_platform_data *gpmc_onenand_data;
-
- if (of_property_read_u32(child, "reg", &val) < 0) {
- dev_err(&pdev->dev, "%s has no 'reg' property\n",
- child->full_name);
- return -ENODEV;
- }
-
- gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
- GFP_KERNEL);
- if (!gpmc_onenand_data)
- return -ENOMEM;
-
- gpmc_onenand_data->cs = val;
- gpmc_onenand_data->of_node = child;
- gpmc_onenand_data->dma_channel = -1;
-
- if (!of_property_read_u32(child, "dma-channel", &val))
- gpmc_onenand_data->dma_channel = val;
-
- gpmc_onenand_init(gpmc_onenand_data);
-
- return 0;
-}
-#else
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
- struct device_node *child)
-{
- return 0;
-}
-#endif
-
-/**
- * gpmc_probe_generic_child - configures the gpmc for a child device
- * @pdev: pointer to gpmc platform device
- * @child: pointer to device-tree node for child device
- *
- * Allocates and configures a GPMC chip-select for a child device.
- * Returns 0 on success and appropriate negative error code on failure.
- */
-static int gpmc_probe_generic_child(struct platform_device *pdev,
- struct device_node *child)
-{
- struct gpmc_settings gpmc_s;
- struct gpmc_timings gpmc_t;
- struct resource res;
- unsigned long base;
- int ret, cs;
-
- if (of_property_read_u32(child, "reg", &cs) < 0) {
- dev_err(&pdev->dev, "%s has no 'reg' property\n",
- child->full_name);
- return -ENODEV;
- }
-
- if (of_address_to_resource(child, 0, &res) < 0) {
- dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
- child->full_name);
- return -ENODEV;
- }
-
- ret = gpmc_cs_request(cs, resource_size(&res), &base);
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs);
- return ret;
- }
-
- /*
- * For some GPMC devices we still need to rely on the bootloader
- * timings because the devices can be connected via FPGA. So far
- * the list is smc91x on the omap2 SDP boards, and 8250 on zooms.
- * REVISIT: Add timing support from slls644g.pdf and from the
- * lan91c96 manual.
- */
- if (of_device_is_compatible(child, "ns16550a") ||
- of_device_is_compatible(child, "smsc,lan91c94") ||
- of_device_is_compatible(child, "smsc,lan91c111")) {
- dev_warn(&pdev->dev,
- "%s using bootloader timings on CS%d\n",
- child->name, cs);
- goto no_timings;
- }
-
- /*
- * FIXME: gpmc_cs_request() will map the CS to an arbitary
- * location in the gpmc address space. When booting with
- * device-tree we want the NOR flash to be mapped to the
- * location specified in the device-tree blob. So remap the
- * CS to this location. Once DT migration is complete should
- * just make gpmc_cs_request() map a specific address.
- */
- ret = gpmc_cs_remap(cs, res.start);
- if (ret < 0) {
- dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n",
- cs, &res.start);
- goto err;
- }
-
- gpmc_read_settings_dt(child, &gpmc_s);
-
- ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
- if (ret < 0)
- goto err;
-
- ret = gpmc_cs_program_settings(cs, &gpmc_s);
- if (ret < 0)
- goto err;
-
- gpmc_read_timings_dt(child, &gpmc_t);
- gpmc_cs_set_timings(cs, &gpmc_t);
-
-no_timings:
- if (of_platform_device_create(child, NULL, &pdev->dev))
- return 0;
-
- dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
- ret = -ENODEV;
-
-err:
- gpmc_cs_free(cs);
-
- return ret;
-}
-
-static int gpmc_probe_dt(struct platform_device *pdev)
-{
- int ret;
- struct device_node *child;
- const struct of_device_id *of_id =
- of_match_device(gpmc_dt_ids, &pdev->dev);
-
- if (!of_id)
- return 0;
-
- ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-cs",
- &gpmc_cs_num);
- if (ret < 0) {
- pr_err("%s: number of chip-selects not defined\n", __func__);
- return ret;
- } else if (gpmc_cs_num < 1) {
- pr_err("%s: all chip-selects are disabled\n", __func__);
- return -EINVAL;
- } else if (gpmc_cs_num > GPMC_CS_NUM) {
- pr_err("%s: number of supported chip-selects cannot be > %d\n",
- __func__, GPMC_CS_NUM);
- return -EINVAL;
- }
-
- ret = of_property_read_u32(pdev->dev.of_node, "gpmc,num-waitpins",
- &gpmc_nr_waitpins);
- if (ret < 0) {
- pr_err("%s: number of wait pins not found!\n", __func__);
- return ret;
- }
-
- for_each_available_child_of_node(pdev->dev.of_node, child) {
-
- if (!child->name)
- continue;
-
- if (of_node_cmp(child->name, "nand") == 0)
- ret = gpmc_probe_nand_child(pdev, child);
- else if (of_node_cmp(child->name, "onenand") == 0)
- ret = gpmc_probe_onenand_child(pdev, child);
- else if (of_node_cmp(child->name, "ethernet") == 0 ||
- of_node_cmp(child->name, "nor") == 0 ||
- of_node_cmp(child->name, "uart") == 0)
- ret = gpmc_probe_generic_child(pdev, child);
-
- if (WARN(ret < 0, "%s: probing gpmc child %s failed\n",
- __func__, child->full_name))
- of_node_put(child);
- }
-
- return 0;
-}
-#else
-#ifndef SYLIXOS
-static int gpmc_probe_dt(struct platform_device *pdev)
-{
- return 0;
-}
-#endif
-#endif
-
-#ifndef SYLIXOS
-static int gpmc_probe(struct platform_device *pdev)
-{
- int rc;
- u32 l;
- struct resource *res;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL)
- return -ENOENT;
-
- phys_base = res->start;
- mem_size = resource_size(res);
-
- gpmc_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(gpmc_base))
- return PTR_ERR(gpmc_base);
-
- res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (res == NULL)
- dev_warn(&pdev->dev, "Failed to get resource: irq\n");
- else
- gpmc_irq = res->start;
-
- gpmc_l3_clk = clk_get(&pdev->dev, "fck");
- if (IS_ERR(gpmc_l3_clk)) {
- dev_err(&pdev->dev, "error: clk_get\n");
- gpmc_irq = 0;
- return PTR_ERR(gpmc_l3_clk);
- }
-
- pm_runtime_enable(&pdev->dev);
- pm_runtime_get_sync(&pdev->dev);
-
- gpmc_dev = &pdev->dev;
-
- l = gpmc_read_reg(GPMC_REVISION);
-
- /*
- * FIXME: Once device-tree migration is complete the below flags
- * should be populated based upon the device-tree compatible
- * string. For now just use the IP revision. OMAP3+ devices have
- * the wr_access and wr_data_mux_bus register fields. OMAP4+
- * devices support the addr-addr-data multiplex protocol.
- *
- * GPMC IP revisions:
- * - OMAP24xx = 2.0
- * - OMAP3xxx = 5.0
- * - OMAP44xx/54xx/AM335x = 6.0
- */
- if (GPMC_REVISION_MAJOR(l) > 0x4)
- gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
- if (GPMC_REVISION_MAJOR(l) > 0x5)
- gpmc_capability |= GPMC_HAS_MUX_AAD;
- dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
- GPMC_REVISION_MINOR(l));
-
- gpmc_mem_init();
-
- if (gpmc_setup_irq() < 0)
- dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
-
- /* Now the GPMC is initialised, unreserve the chip-selects */
- gpmc_cs_map = 0;
-
- if (!pdev->dev.of_node) {
- gpmc_cs_num = GPMC_CS_NUM;
- gpmc_nr_waitpins = GPMC_NR_WAITPINS;
- }
-
- rc = gpmc_probe_dt(pdev);
- if (rc < 0) {
- pm_runtime_put_sync(&pdev->dev);
- clk_put(gpmc_l3_clk);
- dev_err(gpmc_dev, "failed to probe DT parameters\n");
- return rc;
- }
-
- return 0;
-}
-
-static int gpmc_remove(struct platform_device *pdev)
-{
- gpmc_free_irq();
- gpmc_mem_exit();
- pm_runtime_put_sync(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
- gpmc_dev = NULL;
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int gpmc_suspend(struct device *dev)
-{
- omap3_gpmc_save_context();
- pm_runtime_put_sync(dev);
- return 0;
-}
-
-static int gpmc_resume(struct device *dev)
-{
- pm_runtime_get_sync(dev);
- omap3_gpmc_restore_context();
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(gpmc_pm_ops, gpmc_suspend, gpmc_resume);
-
-static struct platform_driver gpmc_driver = {
- .probe = gpmc_probe,
- .remove = gpmc_remove,
- .driver = {
- .name = DEVICE_NAME,
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(gpmc_dt_ids),
- .pm = &gpmc_pm_ops,
- },
-};
-
-static __init int gpmc_init(void)
-{
- return platform_driver_register(&gpmc_driver);
-}
-
-static __exit void gpmc_exit(void)
-{
- platform_driver_unregister(&gpmc_driver);
-
-}
-
-omap_postcore_initcall(gpmc_init);
-module_exit(gpmc_exit);
-
-static int __init omap_gpmc_init(void)
-{
- struct omap_hwmod *oh;
- struct platform_device *pdev;
- char *oh_name = "gpmc";
-
- /*
- * if the board boots up with a populated DT, do not
- * manually add the device from this initcall
- */
- if (of_have_populated_dt())
- return -ENODEV;
-
- oh = omap_hwmod_lookup(oh_name);
- if (!oh) {
- pr_err("Could not look up %s\n", oh_name);
- return -ENODEV;
- }
-
- pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0);
- WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
-
- return PTR_RET(pdev);
-}
-omap_postcore_initcall(omap_gpmc_init);
-
-static irqreturn_t gpmc_handle_irq(int irq, void *dev)
-{
- int i;
- u32 regval;
-
- regval = gpmc_read_reg(GPMC_IRQSTATUS);
-
- if (!regval)
- return IRQ_NONE;
-
- for (i = 0; i < GPMC_NR_IRQ; i++)
- if (regval & gpmc_client_irq[i].bitmask)
- generic_handle_irq(gpmc_client_irq[i].irq);
-
- gpmc_write_reg(GPMC_IRQSTATUS, regval);
-
- return IRQ_HANDLED;
-}
-#endif
-
-static struct omap3_gpmc_regs gpmc_context;
-
-void omap3_gpmc_save_context(void)
-{
- int i;
-
- gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG);
- gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE);
- gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL);
- gpmc_context.config = gpmc_read_reg(GPMC_CONFIG);
- gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
- gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2);
- gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL);
- for (i = 0; i < gpmc_cs_num; i++) {
- gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i);
- if (gpmc_context.cs_context[i].is_valid) {
- gpmc_context.cs_context[i].config1 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG1);
- gpmc_context.cs_context[i].config2 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG2);
- gpmc_context.cs_context[i].config3 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG3);
- gpmc_context.cs_context[i].config4 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG4);
- gpmc_context.cs_context[i].config5 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG5);
- gpmc_context.cs_context[i].config6 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG6);
- gpmc_context.cs_context[i].config7 =
- gpmc_cs_read_reg(i, GPMC_CS_CONFIG7);
- }
- }
-}
-
-void omap3_gpmc_restore_context(void)
-{
- int i;
-
- gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig);
- gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable);
- gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl);
- gpmc_write_reg(GPMC_CONFIG, gpmc_context.config);
- gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1);
- gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2);
- gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control);
- for (i = 0; i < gpmc_cs_num; i++) {
- if (gpmc_context.cs_context[i].is_valid) {
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
- gpmc_context.cs_context[i].config1);
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG2,
- gpmc_context.cs_context[i].config2);
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG3,
- gpmc_context.cs_context[i].config3);
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG4,
- gpmc_context.cs_context[i].config4);
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG5,
- gpmc_context.cs_context[i].config5);
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG6,
- gpmc_context.cs_context[i].config6);
- gpmc_cs_write_reg(i, GPMC_CS_CONFIG7,
- gpmc_context.cs_context[i].config7);
- }
- }
-}
-
-#ifdef SYLIXOS
-int gpmc_probe(struct platform_device *pdev, struct resource *res, unsigned long gpmc_l3_rate)
-{
- u32 l;
-
- gpmc_l3_clk = gpmc_l3_rate;
-
- phys_base = res->start;
- mem_size = resource_size(res);
-
- gpmc_base = API_VmmIoRemapNocache((PVOID)phys_base, mem_size);
- if (!gpmc_base)
- return -1;
-
- gpmc_dev = &pdev->dev;
-
- l = gpmc_read_reg(GPMC_REVISION);
-
- /*
- * FIXME: Once device-tree migration is complete the below flags
- * should be populated based upon the device-tree compatible
- * string. For now just use the IP revision. OMAP3+ devices have
- * the wr_access and wr_data_mux_bus register fields. OMAP4+
- * devices support the addr-addr-data multiplex protocol.
- *
- * GPMC IP revisions:
- * - OMAP24xx = 2.0
- * - OMAP3xxx = 5.0
- * - OMAP44xx/54xx/AM335x = 6.0
- */
- if (GPMC_REVISION_MAJOR(l) > 0x4)
- gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
- if (GPMC_REVISION_MAJOR(l) > 0x5)
- gpmc_capability |= GPMC_HAS_MUX_AAD;
- dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
- GPMC_REVISION_MINOR(l));
-
- gpmc_mem_init();
-
- /* Disable interrupts */
- gpmc_write_reg(GPMC_IRQENABLE, 0);
-
- /* clear interrupts */
- l = gpmc_read_reg(GPMC_IRQSTATUS);
- gpmc_write_reg(GPMC_IRQSTATUS, l);
-
- /* Now the GPMC is initialised, unreserve the chip-selects */
- gpmc_cs_map = 0;
-
- gpmc_cs_num = GPMC_CS_NUM;
- gpmc_nr_waitpins = GPMC_NR_WAITPINS;
-
- return 0;
-}
-
-static INT _G_iOmapGpmcDrvNum = PX_ERROR;
-static LW_DEV_HDR _G_omapGpmcDev;
-
-INT omapGpmcDrv (VOID)
-{
- struct file_operations fileOper;
-
- if (_G_iOmapGpmcDrvNum >= 0) {
- return (ERROR_NONE);
- }
-
- lib_memset(&fileOper, 0, sizeof(struct file_operations));
-
- fileOper.owner = THIS_MODULE;
-
- _G_iOmapGpmcDrvNum = iosDrvInstallEx2(&fileOper, LW_DRV_TYPE_NEW_1);
-
- DRIVER_LICENSE(_G_iOmapGpmcDrvNum, "GPL");
- DRIVER_DESCRIPTION(_G_iOmapGpmcDrvNum, "GPMC support functions.");
-
- return ((_G_iOmapGpmcDrvNum > 0) ? (ERROR_NONE) : (PX_ERROR));
-}
-
-INT omapGpmcDevAdd (VOID)
-{
- if (API_IosDevAddEx(&_G_omapGpmcDev,
- "/dev/"DEVICE_NAME,
- _G_iOmapGpmcDrvNum,
- DT_CHR) != ERROR_NONE) {
- printk(KERN_ERR "omapGpmcDevAdd(): can not add device : %s.\n", strerror(errno));
- return (PX_ERROR);
- }
-
- return (ERROR_NONE);
-}
-#endif
-
+/*
+ * GPMC support functions
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * Author: Juha Yrjola
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#ifndef SYLIXOS
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_mtd.h>
+#include <linux/of_device.h>
+#include <linux/mtd/nand.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/platform_data/mtd-nand-omap2.h>
+
+#include <asm/mach-types.h>
+
+#include "soc.h"
+#include "common.h"
+#include "omap_device.h"
+#include "gpmc.h"
+#include "gpmc-nand.h"
+#include "gpmc-onenand.h"
+#else
+#define __SYLIXOS_KERNEL
+#include "SylixOS.h"
+#include "driver/memory/memory_config.h"
+#include "driver/memory/memory_port.h"
+#include "gpmc.h"
+#include "driver/memory/platform_data/mtd-nand-omap2.h"
+#endif
+
+#define DEVICE_NAME "omap-gpmc"
+
+/* GPMC register offsets */
+#define GPMC_REVISION 0x00
+#define GPMC_SYSCONFIG 0x10
+#define GPMC_SYSSTATUS 0x14
+#define GPMC_IRQSTATUS 0x18
+#define GPMC_IRQENABLE 0x1c
+#define GPMC_TIMEOUT_CONTROL 0x40
+#define GPMC_ERR_ADDRESS 0x44
+#define GPMC_ERR_TYPE 0x48
+#define GPMC_CONFIG 0x50
+#define GPMC_STATUS 0x54
+#define GPMC_PREFETCH_CONFIG1 0x1e0
+#define GPMC_PREFETCH_CONFIG2 0x1e4
+#define GPMC_PREFETCH_CONTROL 0x1ec
+#define GPMC_PREFETCH_STATUS 0x1f0
+#define GPMC_ECC_CONFIG 0x1f4
+#define GPMC_ECC_CONTROL 0x1f8
+#define GPMC_ECC_SIZE_CONFIG 0x1fc
+#define GPMC_ECC1_RESULT 0x200
+#define GPMC_ECC_BCH_RESULT_0 0x240 /* not available on OMAP2 */
+#define GPMC_ECC_BCH_RESULT_1 0x244 /* not available on OMAP2 */
+#define GPMC_ECC_BCH_RESULT_2 0x248 /* not available on OMAP2 */
+#define GPMC_ECC_BCH_RESULT_3 0x24c /* not available on OMAP2 */
+#define GPMC_ECC_BCH_RESULT_4 0x300 /* not available on OMAP2 */
+#define GPMC_ECC_BCH_RESULT_5 0x304 /* not available on OMAP2 */
+#define GPMC_ECC_BCH_RESULT_6 0x308 /* not available on OMAP2 */
+
+/* GPMC ECC control settings */
+#define GPMC_ECC_CTRL_ECCCLEAR 0x100
+#define GPMC_ECC_CTRL_ECCDISABLE 0x000
+#define GPMC_ECC_CTRL_ECCREG1 0x001
+#define GPMC_ECC_CTRL_ECCREG2 0x002
+#define GPMC_ECC_CTRL_ECCREG3 0x003
+#define GPMC_ECC_CTRL_ECCREG4 0x004
+#define GPMC_ECC_CTRL_ECCREG5 0x005
+#define GPMC_ECC_CTRL_ECCREG6 0x006
+#define GPMC_ECC_CTRL_ECCREG7 0x007
+#define GPMC_ECC_CTRL_ECCREG8 0x008
+#define GPMC_ECC_CTRL_ECCREG9 0x009
+
+#define GPMC_CONFIG2_CSEXTRADELAY BIT(7)
+#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7)
+#define GPMC_CONFIG4_OEEXTRADELAY BIT(7)
+#define GPMC_CONFIG4_WEEXTRADELAY BIT(23)
+#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6)
+#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7)
+
+#define GPMC_CS0_OFFSET 0x60
+#define GPMC_CS_SIZE 0x30
+#define GPMC_BCH_SIZE 0x10
+
+#define GPMC_MEM_END 0x3FFFFFFF
+
+#define GPMC_CHUNK_SHIFT 24 /* 16 MB */
+#define GPMC_SECTION_SHIFT 28 /* 128 MB */
+
+#define CS_NUM_SHIFT 24
+#define ENABLE_PREFETCH (0x1 << 7)
+#define DMA_MPU_MODE 2
+
+#define GPMC_REVISION_MAJOR(l) ((l >> 4) & 0xf)
+#define GPMC_REVISION_MINOR(l) (l & 0xf)
+
+#define GPMC_HAS_WR_ACCESS 0x1
+#define GPMC_HAS_WR_DATA_MUX_BUS 0x2
+#define GPMC_HAS_MUX_AAD 0x4
+
+#define GPMC_NR_WAITPINS 4
+
+/* XXX: Only NAND irq has been considered,currently these are the only ones used
+ */
+#define GPMC_NR_IRQ 2
+
+struct gpmc_client_irq {
+ unsigned irq;
+ u32 bitmask;
+};
+
+/* Structure to save gpmc cs context */
+struct gpmc_cs_config {
+ u32 config1;
+ u32 config2;
+ u32 config3;
+ u32 config4;
+ u32 config5;
+ u32 config6;
+ u32 config7;
+ int is_valid;
+};
+
+/*
+ * Structure to save/restore gpmc context
+ * to support core off on OMAP3
+ */
+struct omap3_gpmc_regs {
+ u32 sysconfig;
+ u32 irqenable;
+ u32 timeout_ctrl;
+ u32 config;
+ u32 prefetch_config1;
+ u32 prefetch_config2;
+ u32 prefetch_control;
+ struct gpmc_cs_config cs_context[GPMC_CS_NUM];
+};
+
+#ifndef SYLIXOS
+static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
+static struct irq_chip gpmc_irq_chip;
+static int gpmc_irq_start;
+#endif
+
+static struct resource gpmc_mem_root;
+static struct resource gpmc_cs_mem[GPMC_CS_NUM];
+static DEFINE_SPINLOCK(gpmc_mem_lock);
+/* Define chip-selects as reserved by default until probe completes */
+static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
+static unsigned int gpmc_cs_num = GPMC_CS_NUM;
+static unsigned int gpmc_nr_waitpins;
+static struct device *gpmc_dev;
+#ifndef SYLIXOS
+static int gpmc_irq;
+#endif
+static resource_size_t phys_base, mem_size;
+static unsigned gpmc_capability;
+static void __iomem *gpmc_base;
+
+#ifndef SYLIXOS
+static struct clk *gpmc_l3_clk;
+#else
+static unsigned long gpmc_l3_clk;
+#endif
+
+#ifndef SYLIXOS
+static irqreturn_t gpmc_handle_irq(int irq, void *dev);
+#endif
+
+static void gpmc_write_reg(int idx, u32 val)
+{
+ writel_relaxed(val, gpmc_base + idx);
+}
+
+static u32 gpmc_read_reg(int idx)
+{
+ return readl_relaxed(gpmc_base + idx);
+}
+
+void gpmc_cs_write_reg(int cs, int idx, u32 val)
+{
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
+ writel_relaxed(val, reg_addr);
+}
+
+u32 gpmc_cs_read_reg(int cs, int idx)
+{
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
+ return readl_relaxed(reg_addr);
+}
+
+/* TODO: Add support for gpmc_fck to clock framework and use it */
+static unsigned long gpmc_get_fclk_period(void)
+{
+#ifndef SYLIXOS
+ unsigned long rate = clk_get_rate(gpmc_l3_clk);
+#else
+ unsigned long rate = gpmc_l3_clk;
+#endif
+
+ if (rate == 0) {
+ printk(KERN_WARNING "gpmc_l3_clk not enabled\n");
+ return 0;
+ }
+
+ rate /= 1000;
+ rate = 1000000000 / rate; /* In picoseconds */
+
+ return rate;
+}
+
+static unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = gpmc_get_fclk_period();
+
+ return (time_ns * 1000 + tick_ps - 1) / tick_ps;
+}
+
+static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = gpmc_get_fclk_period();
+
+ return (time_ps + tick_ps - 1) / tick_ps;
+}
+
+unsigned int gpmc_ticks_to_ns(unsigned int ticks)
+{
+ return ticks * gpmc_get_fclk_period() / 1000;
+}
+
+static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
+{
+ return ticks * gpmc_get_fclk_period();
+}
+
+static unsigned int gpmc_round_ps_to_ticks(unsigned int time_ps)
+{
+ unsigned long ticks = gpmc_ps_to_ticks(time_ps);
+
+ return ticks * gpmc_get_fclk_period();
+}
+
+static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
+{
+ u32 l;
+
+ l = gpmc_cs_read_reg(cs, reg);
+ if (value)
+ l |= mask;
+ else
+ l &= ~mask;
+ gpmc_cs_write_reg(cs, reg, l);
+}
+
+static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+{
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_TIME_PARA_GRAN,
+ p->time_para_granularity);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
+ GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
+ GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+ GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+ GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+ GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
+ p->cycle2cyclesamecsen);
+ gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+ GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN,
+ p->cycle2cyclediffcsen);
+}
+
+#ifdef DEBUG
+static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+ int time, const char *name)
+#else
+static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+ int time)
+#endif
+{
+ u32 l;
+ int ticks, mask, nr_bits;
+
+ if (time == 0)
+ ticks = 0;
+ else
+ ticks = gpmc_ns_to_ticks(time);
+ nr_bits = end_bit - st_bit + 1;
+ if (ticks >= 1 << nr_bits) {
+#ifdef DEBUG
+ printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+ cs, name, time, ticks, 1 << nr_bits);
+#endif
+ return -1;
+ }
+
+ mask = (1 << nr_bits) - 1;
+ l = gpmc_cs_read_reg(cs, reg);
+#ifdef DEBUG
+ printk(KERN_INFO
+ "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
+ cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
+ (l >> st_bit) & mask, time);
+#endif
+ l &= ~(mask << st_bit);
+ l |= ticks << st_bit;
+ gpmc_cs_write_reg(cs, reg, l);
+
+ return 0;
+}
+
+#ifdef DEBUG
+#define GPMC_SET_ONE(reg, st, end, field) \
+ if (set_gpmc_timing_reg(cs, (reg), (st), (end), \
+ t->field, #field) < 0) \
+ return -1
+#else
+#define GPMC_SET_ONE(reg, st, end, field) \
+ if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \
+ return -1
+#endif
+
+int gpmc_calc_divider(unsigned int sync_clk)
+{
+ int div;
+ u32 l;
+
+ l = sync_clk + (gpmc_get_fclk_period() - 1);
+ div = l / gpmc_get_fclk_period();
+ if (div > 4)
+ return -1;
+ if (div <= 0)
+ div = 1;
+
+ return div;
+}
+
+int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
+{
+ int div;
+ u32 l;
+
+ div = gpmc_calc_divider(t->sync_clk);
+ if (div < 0)
+ return div;
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off);
+ GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off);
+ GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off);
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle);
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle);
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
+ GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
+
+ if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+ if (gpmc_capability & GPMC_HAS_WR_ACCESS)
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
+
+ /* caller is expected to have initialized CONFIG1 to cover
+ * at least sync vs async
+ */
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+ if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
+#ifdef DEBUG
+ printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
+ cs, (div * gpmc_get_fclk_period()) / 1000, div);
+#endif
+ l &= ~0x03;
+ l |= (div - 1);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
+ }
+
+ gpmc_cs_bool_timings(cs, &t->bool_timings);
+
+ return 0;
+}
+
+static int gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+{
+ u32 l;
+ u32 mask;
+
+ /*
+ * Ensure that base address is aligned on a
+ * boundary equal to or greater than size.
+ */
+ if (base & (size - 1))
+ return -EINVAL;
+
+ mask = (1 << GPMC_SECTION_SHIFT) - size;
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ l &= ~0x3f;
+ l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
+ l &= ~(0x0f << 8);
+ l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
+ l |= GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+
+ return 0;
+}
+
+static void gpmc_cs_disable_mem(int cs)
+{
+ u32 l;
+
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ l &= ~GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+}
+
+static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size)
+{
+ u32 l;
+ u32 mask;
+
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ *base = (l & 0x3f) << GPMC_CHUNK_SHIFT;
+ mask = (l >> 8) & 0x0f;
+ *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT);
+}
+
+static int gpmc_cs_mem_enabled(int cs)
+{
+ u32 l;
+
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ return l & GPMC_CONFIG7_CSVALID;
+}
+
+static void gpmc_cs_set_reserved(int cs, int reserved)
+{
+ gpmc_cs_map &= ~(1 << cs);
+ gpmc_cs_map |= (reserved ? 1 : 0) << cs;
+}
+
+static bool gpmc_cs_reserved(int cs)
+{
+ return gpmc_cs_map & (1 << cs);
+}
+
+static unsigned long gpmc_mem_align(unsigned long size)
+{
+ int order;
+
+ size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1);
+ order = GPMC_CHUNK_SHIFT - 1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ size = 1 << order;
+ return size;
+}
+
+static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+ int r;
+
+ size = gpmc_mem_align(size);
+ spin_lock(&gpmc_mem_lock);
+ res->start = base;
+ res->end = base + size - 1;
+ r = request_resource(&gpmc_mem_root, res);
+ spin_unlock(&gpmc_mem_lock);
+
+ return r;
+}
+
+#ifndef SYLIXOS
+static int gpmc_cs_delete_mem(int cs)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+ int r;
+
+ spin_lock(&gpmc_mem_lock);
+ r = release_resource(res);
+ res->start = 0;
+ res->end = 0;
+ spin_unlock(&gpmc_mem_lock);
+
+ return r;
+}
+
+/**
+ * gpmc_cs_remap - remaps a chip-select physical base address
+ * @cs: chip-select to remap
+ * @base: physical base address to re-map chip-select to
+ *
+ * Re-maps a chip-select to a new physical base address specified by
+ * "base". Returns 0 on success and appropriate negative error code
+ * on failure.
+ */
+static int gpmc_cs_remap(int cs, u32 base)
+{
+ int ret;
+ u32 old_base, size;
+
+ if (cs > gpmc_cs_num) {
+ pr_err("%s: requested chip-select is disabled\n", __func__);
+ return -ENODEV;
+ }
+
+ /*
+ * Make sure we ignore any device offsets from the GPMC partition
+ * allocated for the chip select and that the new base confirms
+ * to the GPMC 16MB minimum granularity.
+ */
+ base &= ~(SZ_16M - 1);
+
+ gpmc_cs_get_memconf(cs, &old_base, &size);
+ if (base == old_base)
+ return 0;
+ gpmc_cs_disable_mem(cs);
+ ret = gpmc_cs_delete_mem(cs);
+ if (ret < 0)
+ return ret;
+ ret = gpmc_cs_insert_mem(cs, base, size);
+ if (ret < 0)
+ return ret;
+ ret = gpmc_cs_enable_mem(cs, base, size);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+#endif
+
+int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+ int r = -1;
+
+ if (cs > gpmc_cs_num) {
+ pr_err("%s: requested chip-select is disabled\n", __func__);
+ return -ENODEV;
+ }
+ size = gpmc_mem_align(size);
+ if (size > (1 << GPMC_SECTION_SHIFT))
+ return -ENOMEM;
+
+ spin_lock(&gpmc_mem_lock);
+ if (gpmc_cs_reserved(cs)) {
+ r = -EBUSY;
+ goto out;
+ }
+ if (gpmc_cs_mem_enabled(cs))
+ r = adjust_resource(res, res->start & ~(size - 1), size);
+ if (r < 0)
+ r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0,
+ size, NULL, NULL);
+ if (r < 0)
+ goto out;
+
+ r = gpmc_cs_enable_mem(cs, res->start, resource_size(res));
+ if (r < 0) {
+ release_resource(res);
+ goto out;
+ }
+
+ *base = res->start;
+ gpmc_cs_set_reserved(cs, 1);
+out:
+ spin_unlock(&gpmc_mem_lock);
+ return r;
+}
+EXPORT_SYMBOL(gpmc_cs_request);
+
+void gpmc_cs_free(int cs)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+
+ spin_lock(&gpmc_mem_lock);
+ if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) {
+ printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
+ BUG();
+ spin_unlock(&gpmc_mem_lock);
+ return;
+ }
+ gpmc_cs_disable_mem(cs);
+ if (res->flags)
+ release_resource(res);
+ gpmc_cs_set_reserved(cs, 0);
+ spin_unlock(&gpmc_mem_lock);
+}
+EXPORT_SYMBOL(gpmc_cs_free);
+
+/**
+ * gpmc_configure - write request to configure gpmc
+ * @cmd: command type
+ * @wval: value to write
+ * @return status of the operation
+ */
+int gpmc_configure(int cmd, int wval)
+{
+ u32 regval;
+
+ switch (cmd) {
+ case GPMC_ENABLE_IRQ:
+ gpmc_write_reg(GPMC_IRQENABLE, wval);
+ break;
+
+ case GPMC_SET_IRQ_STATUS:
+ gpmc_write_reg(GPMC_IRQSTATUS, wval);
+ break;
+
+ case GPMC_CONFIG_WP:
+ regval = gpmc_read_reg(GPMC_CONFIG);
+ if (wval)
+ regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */
+ else
+ regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */
+ gpmc_write_reg(GPMC_CONFIG, regval);
+ break;
+
+ default:
+ pr_err("%s: command not supported\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(gpmc_configure);
+
+void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+{
+ int i;
+
+ reg->gpmc_status = gpmc_base + GPMC_STATUS;
+ reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
+ GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
+ reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET +
+ GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs;
+ reg->gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET +
+ GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs;
+ reg->gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1;
+ reg->gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2;
+ reg->gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL;
+ reg->gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS;
+ reg->gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG;
+ reg->gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
+ reg->gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
+ reg->gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
+
+ for (i = 0; i < GPMC_BCH_NUM_REMAINDER; i++) {
+ reg->gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
+ GPMC_BCH_SIZE * i;
+ reg->gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
+ GPMC_BCH_SIZE * i;
+ reg->gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
+ GPMC_BCH_SIZE * i;
+ reg->gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
+ GPMC_BCH_SIZE * i;
+ reg->gpmc_bch_result4[i] = gpmc_base + GPMC_ECC_BCH_RESULT_4 +
+ i * GPMC_BCH_SIZE;
+ reg->gpmc_bch_result5[i] = gpmc_base + GPMC_ECC_BCH_RESULT_5 +
+ i * GPMC_BCH_SIZE;
+ reg->gpmc_bch_result6[i] = gpmc_base + GPMC_ECC_BCH_RESULT_6 +
+ i * GPMC_BCH_SIZE;
+ }
+}
+
+#ifndef SYLIXOS
+int gpmc_get_client_irq(unsigned irq_config)
+{
+ int i;
+
+ if (hweight32(irq_config) > 1)
+ return 0;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++)
+ if (gpmc_client_irq[i].bitmask & irq_config)
+ return gpmc_client_irq[i].irq;
+
+ return 0;
+}
+
+static int gpmc_irq_endis(unsigned irq, bool endis)
+{
+ int i;
+ u32 regval;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++)
+ if (irq == gpmc_client_irq[i].irq) {
+ regval = gpmc_read_reg(GPMC_IRQENABLE);
+ if (endis)
+ regval |= gpmc_client_irq[i].bitmask;
+ else
+ regval &= ~gpmc_client_irq[i].bitmask;
+ gpmc_write_reg(GPMC_IRQENABLE, regval);
+ break;
+ }
+
+ return 0;
+}
+
+static void gpmc_irq_disable(struct irq_data *p)
+{
+ gpmc_irq_endis(p->irq, false);
+}
+
+static void gpmc_irq_enable(struct irq_data *p)
+{
+ gpmc_irq_endis(p->irq, true);
+}
+
+static void gpmc_irq_noop(struct irq_data *data) { }
+
+static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
+
+static int gpmc_setup_irq(void)
+{
+ int i;
+ u32 regval;
+
+ if (!gpmc_irq)
+ return -EINVAL;
+
+ gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0);
+ if (gpmc_irq_start < 0) {
+ pr_err("irq_alloc_descs failed\n");
+ return gpmc_irq_start;
+ }
+
+ gpmc_irq_chip.name = "gpmc";
+ gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
+ gpmc_irq_chip.irq_enable = gpmc_irq_enable;
+ gpmc_irq_chip.irq_disable = gpmc_irq_disable;
+ gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
+ gpmc_irq_chip.irq_ack = gpmc_irq_noop;
+ gpmc_irq_chip.irq_mask = gpmc_irq_noop;
+ gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
+
+ gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
+ gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
+
+ for (i = 0; i < GPMC_NR_IRQ; i++) {
+ gpmc_client_irq[i].irq = gpmc_irq_start + i;
+ irq_set_chip_and_handler(gpmc_client_irq[i].irq,
+ &gpmc_irq_chip, handle_simple_irq);
+ set_irq_flags(gpmc_client_irq[i].irq,
+ IRQF_VALID | IRQF_NOAUTOEN);
+ }
+
+ /* Disable interrupts */
+ gpmc_write_reg(GPMC_IRQENABLE, 0);
+
+ /* clear interrupts */
+ regval = gpmc_read_reg(GPMC_IRQSTATUS);
+ gpmc_write_reg(GPMC_IRQSTATUS, regval);
+
+ return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
+}
+
+static int gpmc_free_irq(void)
+{
+ int i;
+
+ if (gpmc_irq)
+ free_irq(gpmc_irq, NULL);
+
+ for (i = 0; i < GPMC_NR_IRQ; i++) {
+ irq_set_handler(gpmc_client_irq[i].irq, NULL);
+ irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip);
+ irq_modify_status(gpmc_client_irq[i].irq, 0, 0);
+ }
+
+ irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
+
+ return 0;
+}
+
+static void gpmc_mem_exit(void)
+{
+ int cs;
+
+ for (cs = 0; cs < gpmc_cs_num; cs++) {
+ if (!gpmc_cs_mem_enabled(cs))
+ continue;
+ gpmc_cs_delete_mem(cs);
+ }
+
+}
+#endif
+
+static void gpmc_mem_init(void)
+{
+ int cs;
+
+ /*
+ * The first 1MB of GPMC address space is typically mapped to
+ * the internal ROM. Never allocate the first page, to
+ * facilitate bug detection; even if we didn't boot from ROM.
+ */
+ gpmc_mem_root.start = SZ_1M;
+ gpmc_mem_root.end = GPMC_MEM_END;
+#ifdef SYLIXOS
+ gpmc_mem_root.current = gpmc_mem_root.start;
+#endif
+
+ /* Reserve all regions that has been set up by bootloader */
+ for (cs = 0; cs < gpmc_cs_num; cs++) {
+ u32 base, size;
+
+ if (!gpmc_cs_mem_enabled(cs))
+ continue;
+ gpmc_cs_get_memconf(cs, &base, &size);
+ if (gpmc_cs_insert_mem(cs, base, size)) {
+ pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n",
+ __func__, cs, base, base + size);
+ gpmc_cs_disable_mem(cs);
+ }
+ }
+}
+
+static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
+{
+ u32 temp;
+ int div;
+
+ div = gpmc_calc_divider(sync_clk);
+ temp = gpmc_ps_to_ticks(time_ps);
+ temp = (temp + div - 1) / div;
+ return gpmc_ticks_to_ps(temp * div);
+}
+
+/* XXX: can the cycles be avoided ? */
+static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t,
+ bool mux)
+{
+ u32 temp;
+
+ /* adv_rd_off */
+ temp = dev_t->t_avdp_r;
+ /* XXX: mux check required ? */
+ if (mux) {
+ /* XXX: t_avdp not to be required for sync, only added for tusb
+ * this indirectly necessitates requirement of t_avdp_r and
+ * t_avdp_w instead of having a single t_avdp
+ */
+ temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_avdh);
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ }
+ gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
+
+ /* oe_on */
+ temp = dev_t->t_oeasu; /* XXX: remove this ? */
+ if (mux) {
+ temp = max_t(u32, temp, gpmc_t->clk_activation + dev_t->t_ach);
+ temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+ gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
+ }
+ gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
+
+ /* access */
+ /* XXX: any scope for improvement ?, by combining oe_on
+ * and clk_activation, need to check whether
+ * access = clk_activation + round to sync clk ?
+ */
+ temp = max_t(u32, dev_t->t_iaa, dev_t->cyc_iaa * gpmc_t->sync_clk);
+ temp += gpmc_t->clk_activation;
+ if (dev_t->cyc_oe)
+ temp = max_t(u32, temp, gpmc_t->oe_on +
+ gpmc_ticks_to_ps(dev_t->cyc_oe));
+ gpmc_t->access = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
+ gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+ /* rd_cycle */
+ temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
+ temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
+ gpmc_t->access;
+ /* XXX: barter t_ce_rdyz with t_cez_r ? */
+ if (dev_t->t_ce_rdyz)
+ temp = max_t(u32, temp, gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+ gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t,
+ bool mux)
+{
+ u32 temp;
+
+ /* adv_wr_off */
+ temp = dev_t->t_avdp_w;
+ if (mux) {
+ temp = max_t(u32, temp,
+ gpmc_t->clk_activation + dev_t->t_avdh);
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ }
+ gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
+
+ /* wr_data_mux_bus */
+ temp = max_t(u32, dev_t->t_weasu,
+ gpmc_t->clk_activation + dev_t->t_rdyo);
+ /* XXX: shouldn't mux be kept as a whole for wr_data_mux_bus ?,
+ * and in that case remember to handle we_on properly
+ */
+ if (mux) {
+ temp = max_t(u32, temp,
+ gpmc_t->adv_wr_off + dev_t->t_aavdh);
+ temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+ gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
+ }
+ gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
+
+ /* we_on */
+ if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+ gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
+ else
+ gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+ /* wr_access */
+ /* XXX: gpmc_capability check reqd ? , even if not, will not harm */
+ gpmc_t->wr_access = gpmc_t->access;
+
+ /* we_off */
+ temp = gpmc_t->we_on + dev_t->t_wpl;
+ temp = max_t(u32, temp,
+ gpmc_t->wr_access + gpmc_ticks_to_ps(1));
+ temp = max_t(u32, temp,
+ gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+ gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+ dev_t->t_wph);
+
+ /* wr_cycle */
+ temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
+ temp += gpmc_t->wr_access;
+ /* XXX: barter t_ce_rdyz with t_cez_w ? */
+ if (dev_t->t_ce_rdyz)
+ temp = max_t(u32, temp,
+ gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+ gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t,
+ bool mux)
+{
+ u32 temp;
+
+ /* adv_rd_off */
+ temp = dev_t->t_avdp_r;
+ if (mux)
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
+
+ /* oe_on */
+ temp = dev_t->t_oeasu;
+ if (mux)
+ temp = max_t(u32, temp,
+ gpmc_t->adv_rd_off + dev_t->t_aavdh);
+ gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
+
+ /* access */
+ temp = max_t(u32, dev_t->t_iaa, /* XXX: remove t_iaa in async ? */
+ gpmc_t->oe_on + dev_t->t_oe);
+ temp = max_t(u32, temp,
+ gpmc_t->cs_on + dev_t->t_ce);
+ temp = max_t(u32, temp,
+ gpmc_t->adv_on + dev_t->t_aa);
+ gpmc_t->access = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
+ gpmc_t->cs_rd_off = gpmc_t->oe_off;
+
+ /* rd_cycle */
+ temp = max_t(u32, dev_t->t_rd_cycle,
+ gpmc_t->cs_rd_off + dev_t->t_cez_r);
+ temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+ gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t,
+ bool mux)
+{
+ u32 temp;
+
+ /* adv_wr_off */
+ temp = dev_t->t_avdp_w;
+ if (mux)
+ temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+ gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
+
+ /* wr_data_mux_bus */
+ temp = dev_t->t_weasu;
+ if (mux) {
+ temp = max_t(u32, temp, gpmc_t->adv_wr_off + dev_t->t_aavdh);
+ temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+ gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
+ }
+ gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
+
+ /* we_on */
+ if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
+ gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
+ else
+ gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
+
+ /* we_off */
+ temp = gpmc_t->we_on + dev_t->t_wpl;
+ gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
+
+ gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+ dev_t->t_wph);
+
+ /* wr_cycle */
+ temp = max_t(u32, dev_t->t_wr_cycle,
+ gpmc_t->cs_wr_off + dev_t->t_cez_w);
+ gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
+
+ return 0;
+}
+
+static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t)
+{
+ u32 temp;
+
+ gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
+ gpmc_get_fclk_period();
+
+ gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
+ dev_t->t_bacc,
+ gpmc_t->sync_clk);
+
+ temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
+ gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
+
+ if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
+ return 0;
+
+ if (dev_t->ce_xdelay)
+ gpmc_t->bool_timings.cs_extra_delay = true;
+ if (dev_t->avd_xdelay)
+ gpmc_t->bool_timings.adv_extra_delay = true;
+ if (dev_t->oe_xdelay)
+ gpmc_t->bool_timings.oe_extra_delay = true;
+ if (dev_t->we_xdelay)
+ gpmc_t->bool_timings.we_extra_delay = true;
+
+ return 0;
+}
+
+static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
+ struct gpmc_device_timings *dev_t,
+ bool sync)
+{
+ u32 temp;
+
+ /* cs_on */
+ gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
+
+ /* adv_on */
+ temp = dev_t->t_avdasu;
+ if (dev_t->t_ce_avd)
+ temp = max_t(u32, temp,
+ gpmc_t->cs_on + dev_t->t_ce_avd);
+ gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
+
+ if (sync)
+ gpmc_calc_sync_common_timings(gpmc_t, dev_t);
+
+ return 0;
+}
+
+/* TODO: remove this function once all peripherals are confirmed to
+ * work with generic timing. Simultaneously gpmc_cs_set_timings()
+ * has to be modified to handle timings in ps instead of ns
+*/
+static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
+{
+ t->cs_on /= 1000;
+ t->cs_rd_off /= 1000;
+ t->cs_wr_off /= 1000;
+ t->adv_on /= 1000;
+ t->adv_rd_off /= 1000;
+ t->adv_wr_off /= 1000;
+ t->we_on /= 1000;
+ t->we_off /= 1000;
+ t->oe_on /= 1000;
+ t->oe_off /= 1000;
+ t->page_burst_access /= 1000;
+ t->access /= 1000;
+ t->rd_cycle /= 1000;
+ t->wr_cycle /= 1000;
+ t->bus_turnaround /= 1000;