Merge remote-tracking branch 'kernel-2.6.32/develop' into develop-2.6.36

Conflicts:
	arch/arm/mm/mmu.c
	drivers/input/keyboard/Makefile
	drivers/media/video/gc0309.c
	drivers/misc/Kconfig
	drivers/mmc/core/core.c
	drivers/regulator/Kconfig
	drivers/regulator/Makefile
	drivers/usb/gadget/f_mass_storage.c
	drivers/video/backlight/Makefile
	include/linux/fb.h
	include/linux/mmc/host.h
This commit is contained in:
黄涛 2011-09-26 14:53:47 +08:00
commit d120da9fa2
268 changed files with 167532 additions and 7564 deletions

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32.27
# Wed Jul 13 20:55:31 2011
# Thu Aug 25 15:26:43 2011
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@ -35,6 +35,12 @@ CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZO=y
# CONFIG_KERNEL_GZIP is not set
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
CONFIG_KERNEL_LZO=y
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_POSIX_MQUEUE is not set
@ -52,7 +58,7 @@ CONFIG_RCU_FANOUT=32
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_LOG_BUF_SHIFT=19
CONFIG_CGROUPS=y
CONFIG_CGROUP_DEBUG=y
# CONFIG_CGROUP_NS is not set
@ -193,9 +199,7 @@ CONFIG_MMU=y
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_BCMRING is not set
# CONFIG_ARCH_RK2818 is not set
CONFIG_ARCH_RK29=y
CONFIG_WIFI_CONTROL_FUNC=y
# CONFIG_MACH_RK29SDK is not set
# CONFIG_MACH_RK29SDK_DDR3 is not set
# CONFIG_MACH_RK29WINACCORD is not set
@ -229,14 +233,17 @@ CONFIG_DDR_TYPE_LPDDR=y
# CONFIG_DDR_TYPE_DDR3_2133M is not set
# CONFIG_DDR_TYPE_DDR3_2133N is not set
# CONFIG_DDR_TYPE_DDR3_DEFAULT is not set
CONFIG_RK29_MEM_SIZE_512M=y
# CONFIG_RK29_MEM_SIZE_1G is not set
CONFIG_RK29_MEM_SIZE_M=512
CONFIG_DDR_SDRAM_FREQ=192
# CONFIG_DDR_RECONFIG is not set
CONFIG_WIFI_CONTROL_FUNC=y
#
# RK29 VPU (Video Processing Unit) support
#
CONFIG_RK29_VPU=y
CONFIG_RK29_VPU_SERVICE=y
# CONFIG_RK29_VPU_DEBUG is not set
# CONFIG_RK29_JTAG is not set
CONFIG_RK29_LAST_LOG=y
@ -248,6 +255,7 @@ CONFIG_RK29_WORKING_POWER_MANAGEMENT=y
CONFIG_RK29_CLK_SWITCH_TO_32K=y
CONFIG_RK29_GPIO_SUSPEND=y
CONFIG_RK29_SPI_INSRAM=y
# CONFIG_RK29_CHARGE_EARLYSUSPEND is not set
#
# Processor Type
@ -441,7 +449,27 @@ CONFIG_INET_TCP_DIAG=y
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
CONFIG_IPV6=y
CONFIG_IPV6_PRIVACY=y
CONFIG_IPV6_ROUTER_PREF=y
# CONFIG_IPV6_ROUTE_INFO is not set
CONFIG_IPV6_OPTIMISTIC_DAD=y
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
CONFIG_IPV6_MIP6=y
CONFIG_INET6_XFRM_TUNNEL=y
CONFIG_INET6_TUNNEL=y
CONFIG_INET6_XFRM_MODE_TRANSPORT=y
CONFIG_INET6_XFRM_MODE_TUNNEL=y
CONFIG_INET6_XFRM_MODE_BEET=y
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
CONFIG_IPV6_SIT=y
CONFIG_IPV6_NDISC_NODETYPE=y
CONFIG_IPV6_TUNNEL=y
CONFIG_IPV6_MULTIPLE_TABLES=y
# CONFIG_IPV6_SUBTREES is not set
# CONFIG_IPV6_MROUTE is not set
CONFIG_ANDROID_PARANOID_NETWORK=y
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
@ -492,8 +520,8 @@ CONFIG_BT_HCIUART_H4=y
# CONFIG_BT_HCIVHCI is not set
# CONFIG_BT_MRVL is not set
CONFIG_BT_HCIBCM4325=y
CONFIG_IDBLOCK=y
# CONFIG_WIFI_MAC is not set
# CONFIG_IDBLOCK is not set
CONFIG_WIFI_MAC=y
# CONFIG_AF_RXRPC is not set
CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
@ -634,7 +662,7 @@ CONFIG_ANDROID_PMEM=y
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_KERNEL_DEBUGGER_CORE is not set
# CONFIG_ISL29003 is not set
# CONFIG_UID_STAT is not set
CONFIG_UID_STAT=y
# CONFIG_WL127X_RFKILL is not set
CONFIG_APANIC=y
CONFIG_APANIC_PLABEL="kpanic"
@ -653,6 +681,7 @@ CONFIG_MTK23D=y
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_MAX6875 is not set
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_RK29_SUPPORT_MODEM is not set
CONFIG_RK29_GPS=y
CONFIG_GPS_GNS7560=y
@ -660,8 +689,9 @@ CONFIG_GPS_GNS7560=y
# Motion Sensors Support
#
# CONFIG_MPU_NONE is not set
# CONFIG_SENSORS_MPU3050 is not set
# CONFIG_SENSORS_MPU6000 is not set
# CONFIG_MPU_SENSORS_MPU3050 is not set
# CONFIG_MPU_SENSORS_MPU6000 is not set
# CONFIG_MPU_SENSORS_TIMERIRQ is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@ -869,10 +899,12 @@ CONFIG_TOUCHSCREEN_ILI2102_IIC=y
# CONFIG_SINTEK_3FA16 is not set
# CONFIG_EETI_EGALAX is not set
# CONFIG_TOUCHSCREEN_IT7260 is not set
# CONFIG_TOUCHSCREEN_NAS is not set
# CONFIG_LAIBAO_TS is not set
# CONFIG_TOUCHSCREEN_GT801_IIC is not set
# CONFIG_TOUCHSCREEN_GT818_IIC is not set
# CONFIG_D70_L3188A is not set
# CONFIG_TOUCHSCREEN_GOODIX_NEWTON is not set
# CONFIG_TOUCHSCREEN_GT819 is not set
# CONFIG_TOUCHSCREEN_FT5406 is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_LPSENSOR_ISL29028 is not set
@ -1011,7 +1043,6 @@ CONFIG_SPIM1_RK29=y
CONFIG_ADC=y
# CONFIG_ADC_RK28 is not set
CONFIG_ADC_RK29=y
# CONFIG_SPI_FPGA is not set
#
# Headset device support
@ -1074,6 +1105,7 @@ CONFIG_WM831X_WITH_BATTERY=y
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_BATTERY_STC3100 is not set
# CONFIG_BATTERY_BQ27510 is not set
# CONFIG_BATTERY_BQ27541 is not set
# CONFIG_BATTERY_BQ3060 is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
@ -1101,7 +1133,6 @@ CONFIG_MFD_CORE=y
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_WM8400 is not set
CONFIG_MFD_WM831X=y
# CONFIG_MFD_WM831X_I2C is not set
@ -1189,6 +1220,7 @@ CONFIG_SOC_CAMERA_MT9T111=y
# CONFIG_SOC_CAMERA_OV5640 is not set
# CONFIG_SOC_CAMERA_S5K6AA is not set
# CONFIG_SOC_CAMERA_GT2005 is not set
# CONFIG_SOC_CAMERA_GC0307 is not set
# CONFIG_SOC_CAMERA_GC0308 is not set
CONFIG_SOC_CAMERA_GC0309=y
# CONFIG_SOC_CAMERA_GC2015 is not set
@ -1276,6 +1308,7 @@ CONFIG_DISPLAY_SUPPORT=y
# CONFIG_LCD_RGB_TFT480800_25_E is not set
# CONFIG_LCD_HSD100PXN is not set
# CONFIG_LCD_HSD07PFW1 is not set
# CONFIG_LCD_BYD8688FTGF is not set
# CONFIG_LCD_B101AW06 is not set
# CONFIG_LCD_LS035Y8DX02A is not set
# CONFIG_LCD_CPTCLAA038LA31XE is not set
@ -1421,27 +1454,28 @@ CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_UNSAFE_RESUME=y
CONFIG_MMC_EMBEDDED_SDIO=y
# CONFIG_MMC_PARANOID_SD_INIT is not set
CONFIG_MMC_PARANOID_SD_INIT=y
#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_BOUNCE=y
CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set
#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_SDMMC_RK29_OLD=y
CONFIG_SDMMC_RK29=y
#
# Now, there are two SDMMC controllers selected, SDMMC0 and SDMMC1.
#
# CONFIG_SDMMC_RK29_OLD is not set
CONFIG_SDMMC0_RK29=y
# CONFIG_EMMC_RK29 is not set
CONFIG_SDMMC1_RK29=y
# CONFIG_MMC_SDHCI is not set
# CONFIG_MMC_AT91 is not set
@ -1456,6 +1490,7 @@ CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_GPIO_PLATFORM=y
# CONFIG_LEDS_NEWTON_PWM is not set
# CONFIG_LEDS_LP3944 is not set
# CONFIG_LEDS_PCA955X is not set
CONFIG_LEDS_WM831X_STATUS=y
@ -1577,21 +1612,6 @@ CONFIG_ANDROID_LOW_MEMORY_KILLER=y
# CONFIG_RAR_REGISTER is not set
# CONFIG_IIO is not set
#
# DSP
#
# CONFIG_RK2818_DSP is not set
#
# RK1000 control
#
# CONFIG_RK1000_CONTROL is not set
#
# rk2818 POWER CONTROL
#
# CONFIG_RK2818_POWER is not set
#
# GPU Vivante
#
@ -1601,6 +1621,7 @@ CONFIG_VIVANTE=y
# IPP
#
CONFIG_RK29_IPP=y
# CONFIG_DEINTERLACE is not set
#
# CMMB
@ -1620,12 +1641,12 @@ CONFIG_RK29_IPP=y
# CONFIG_EXT2_FS is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
# CONFIG_EXT4_FS is not set
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_EXT4_FS=y
# CONFIG_EXT4_FS_XATTR is not set
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=y
CONFIG_FS_MBCACHE=y
CONFIG_JBD2=y
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
@ -1641,7 +1662,8 @@ CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
CONFIG_FUSE_FS=y
# CONFIG_CUSE is not set
#
# Caches
@ -1683,17 +1705,7 @@ CONFIG_MISC_FILESYSTEMS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_YAFFS_FS=y
CONFIG_YAFFS_YAFFS1=y
# CONFIG_YAFFS_9BYTE_TAGS is not set
# CONFIG_YAFFS_DOES_ECC is not set
CONFIG_YAFFS_YAFFS2=y
CONFIG_YAFFS_AUTO_YAFFS2=y
# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
# CONFIG_YAFFS_EMPTY_LOST_AND_FOUND is not set
# CONFIG_YAFFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32.27
# Tue Aug 23 09:57:52 2011
# Thu Sep 15 19:19:01 2011
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@ -236,6 +236,7 @@ CONFIG_MACH_RK29SDK_DDR3=y
CONFIG_DDR_TYPE_DDR3_DEFAULT=y
CONFIG_RK29_MEM_SIZE_M=512
CONFIG_DDR_SDRAM_FREQ=456
CONFIG_DDR_FREQ=y
# CONFIG_DDR_RECONFIG is not set
CONFIG_WIFI_CONTROL_FUNC=y
@ -469,7 +470,123 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IPV6_MROUTE is not set
CONFIG_ANDROID_PARANOID_NETWORK=y
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_NETFILTER_ADVANCED=y
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_NETLINK=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
CONFIG_NETFILTER_NETLINK_LOG=y
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CT_ACCT=y
CONFIG_NF_CONNTRACK_MARK=y
CONFIG_NF_CONNTRACK_EVENTS=y
CONFIG_NF_CT_PROTO_DCCP=y
CONFIG_NF_CT_PROTO_GRE=y
CONFIG_NF_CT_PROTO_SCTP=y
CONFIG_NF_CT_PROTO_UDPLITE=y
CONFIG_NF_CONNTRACK_AMANDA=y
CONFIG_NF_CONNTRACK_FTP=y
CONFIG_NF_CONNTRACK_H323=y
CONFIG_NF_CONNTRACK_IRC=y
CONFIG_NF_CONNTRACK_NETBIOS_NS=y
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_CONNTRACK_SANE=y
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
CONFIG_NF_CT_NETLINK=y
CONFIG_NETFILTER_XTABLES=y
CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
CONFIG_NETFILTER_XT_TARGET_MARK=y
# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
CONFIG_NETFILTER_XT_MATCH_COMMENT=y
CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
# CONFIG_NETFILTER_XT_MATCH_ESP is not set
CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
CONFIG_NETFILTER_XT_MATCH_HELPER=y
CONFIG_NETFILTER_XT_MATCH_HL=y
# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
# CONFIG_NETFILTER_XT_MATCH_MAC is not set
# CONFIG_NETFILTER_XT_MATCH_MARK is not set
# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
CONFIG_NETFILTER_XT_MATCH_QUOTA=y
# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
# CONFIG_NETFILTER_XT_MATCH_REALM is not set
# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
CONFIG_NETFILTER_XT_MATCH_STATE=y
CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
CONFIG_NETFILTER_XT_MATCH_STRING=y
# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
CONFIG_NETFILTER_XT_MATCH_TIME=y
CONFIG_NETFILTER_XT_MATCH_U32=y
# CONFIG_NETFILTER_XT_MATCH_OSF is not set
# CONFIG_IP_VS is not set
#
# IP: Netfilter Configuration
#
CONFIG_NF_DEFRAG_IPV4=y
CONFIG_NF_CONNTRACK_IPV4=y
CONFIG_NF_CONNTRACK_PROC_COMPAT=y
# CONFIG_IP_NF_QUEUE is not set
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_ADDRTYPE=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_LOG=y
# CONFIG_IP_NF_TARGET_ULOG is not set
CONFIG_NF_NAT=y
CONFIG_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
# CONFIG_NF_NAT_SNMP_BASIC is not set
CONFIG_NF_NAT_PROTO_DCCP=y
CONFIG_NF_NAT_PROTO_GRE=y
CONFIG_NF_NAT_PROTO_UDPLITE=y
CONFIG_NF_NAT_PROTO_SCTP=y
CONFIG_NF_NAT_FTP=y
CONFIG_NF_NAT_IRC=y
CONFIG_NF_NAT_TFTP=y
CONFIG_NF_NAT_AMANDA=y
CONFIG_NF_NAT_PPTP=y
CONFIG_NF_NAT_H323=y
CONFIG_NF_NAT_SIP=y
# CONFIG_IP_NF_MANGLE is not set
# CONFIG_IP_NF_TARGET_TTL is not set
# CONFIG_IP_NF_RAW is not set
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
#
# IPv6: Netfilter Configuration
#
# CONFIG_NF_CONNTRACK_IPV6 is not set
# CONFIG_IP6_NF_QUEUE is not set
# CONFIG_IP6_NF_IPTABLES is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_RDS is not set
@ -858,6 +975,7 @@ CONFIG_INPUT_KEYRESET=y
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYS_RK29=y
# CONFIG_KEYS_RK29_NEWTON is not set
# CONFIG_SYNAPTICS_SO340010 is not set
# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ATKBD is not set
@ -905,6 +1023,7 @@ CONFIG_EETI_EGALAX_MAX_X=1087
CONFIG_EETI_EGALAX_MAX_Y=800
# CONFIG_EETI_EGALAX_DEBUG is not set
# CONFIG_TOUCHSCREEN_IT7260 is not set
# CONFIG_TOUCHSCREEN_IT7260_I2C is not set
# CONFIG_TOUCHSCREEN_NAS is not set
# CONFIG_LAIBAO_TS is not set
# CONFIG_TOUCHSCREEN_GT801_IIC is not set
@ -930,7 +1049,10 @@ CONFIG_INPUT_UINPUT=y
CONFIG_G_SENSOR_DEVICE=y
# CONFIG_GS_MMA7660 is not set
CONFIG_GS_MMA8452=y
# CONFIG_GS_KXTF9 is not set
# CONFIG_GS_LIS3DH is not set
# CONFIG_GS_L3G4200D is not set
# CONFIG_GYRO_SENSOR_DEVICE is not set
# CONFIG_INPUT_JOGBALL is not set
# CONFIG_LIGHT_SENSOR_DEVICE is not set
@ -1125,6 +1247,7 @@ CONFIG_REGULATOR=y
# CONFIG_REGULATOR_TPS6507X is not set
# CONFIG_RK2818_REGULATOR_CHARGE is not set
# CONFIG_RK2818_REGULATOR_LP8725 is not set
# CONFIG_REGULATOR_ACT8891 is not set
CONFIG_RK29_PWM_REGULATOR=y
CONFIG_MEDIA_SUPPORT=y
@ -1305,7 +1428,7 @@ CONFIG_FB_RK29=y
CONFIG_FB_WORK_IPP=y
# CONFIG_FB_SCALING_OSD is not set
# CONFIG_FB_ROTATE_VIDEO is not set
# CONFIG_CLOSE_WIN1_DYNAMIC is not set
CONFIG_CLOSE_WIN1_DYNAMIC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
@ -1315,6 +1438,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_RK29_BL=y
# CONFIG_BACKLIGHT_RK29_NEWTON_BL is not set
# CONFIG_FIH_TOUCHKEY_LED is not set
# CONFIG_BACKLIGHT_AW9364 is not set
# CONFIG_BUTTON_LIGHT is not set
@ -1410,6 +1534,7 @@ CONFIG_SND_RK29_SOC_WM8900=y
# CONFIG_SND_RK29_SOC_CS42L52 is not set
# CONFIG_SND_RK29_CODEC_SOC_MASTER is not set
CONFIG_SND_RK29_CODEC_SOC_SLAVE=y
# CONFIG_ADJUST_VOL_BY_CODEC is not set
CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_WM8900=y
@ -1811,6 +1936,7 @@ CONFIG_VIVANTE=y
# IPP
#
CONFIG_RK29_IPP=y
CONFIG_DEINTERLACE=y
#
# CMMB
@ -2081,7 +2207,7 @@ CONFIG_CRYPTO_ECB=y
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
CONFIG_CRYPTO_CRC32C=y
# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
@ -2141,13 +2267,17 @@ CONFIG_CRC16=y
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_LIBCRC32C=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_REED_SOLOMON=y
CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REED_SOLOMON_DEC8=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=y
CONFIG_TEXTSEARCH_BM=y
CONFIG_TEXTSEARCH_FSM=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y

View File

@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.32.27
# Tue Aug 16 20:21:21 2011
# Thu Sep 1 11:02:10 2011
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@ -210,6 +210,7 @@ CONFIG_ARCH_RK29=y
# CONFIG_MACH_RK29_PHONEPADSDK is not set
CONFIG_MACH_RK29_newton=y
# CONFIG_MACH_RK29_P91 is not set
CONFIG_RK29_NEWTON_CLOCK=y
# CONFIG_DDR_TYPE_DDRII is not set
# CONFIG_DDR_TYPE_LPDDR is not set
# CONFIG_DDR_TYPE_DDR3_800D is not set
@ -236,6 +237,7 @@ CONFIG_MACH_RK29_newton=y
CONFIG_DDR_TYPE_DDR3_DEFAULT=y
CONFIG_RK29_MEM_SIZE_M=512
CONFIG_DDR_SDRAM_FREQ=400
# CONFIG_DDR_FREQ is not set
# CONFIG_DDR_RECONFIG is not set
CONFIG_WIFI_CONTROL_FUNC=y
@ -1037,7 +1039,8 @@ CONFIG_INPUT_KEYRESET=y
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYS_RK29=y
# CONFIG_KEYS_RK29 is not set
CONFIG_KEYS_RK29_NEWTON=y
# CONFIG_SYNAPTICS_SO340010 is not set
# CONFIG_KEYBOARD_ADP5588 is not set
# CONFIG_KEYBOARD_ATKBD is not set
@ -1083,6 +1086,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_SINTEK_3FA16 is not set
# CONFIG_EETI_EGALAX is not set
# CONFIG_TOUCHSCREEN_IT7260 is not set
# CONFIG_TOUCHSCREEN_IT7260_I2C is not set
# CONFIG_TOUCHSCREEN_NAS is not set
# CONFIG_LAIBAO_TS is not set
# CONFIG_TOUCHSCREEN_GT801_IIC is not set
@ -1111,6 +1115,7 @@ CONFIG_COMPASS_AK8975=y
CONFIG_G_SENSOR_DEVICE=y
# CONFIG_GS_MMA7660 is not set
CONFIG_GS_MMA8452=y
# CONFIG_GS_KXTF9 is not set
CONFIG_GS_L3G4200D=y
# CONFIG_INPUT_JOGBALL is not set
# CONFIG_LIGHT_SENSOR_DEVICE is not set
@ -1263,6 +1268,7 @@ CONFIG_POWER_SUPPLY=y
# CONFIG_BATTERY_BQ27510 is not set
CONFIG_BATTERY_BQ27541=y
# CONFIG_BATTERY_BQ3060 is not set
# CONFIG_NO_BATTERY_IC is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
@ -1289,7 +1295,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_MFD_TC6387XB is not set
# CONFIG_MFD_TC6393XB is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM8350_I2C is not set
@ -1376,6 +1381,7 @@ CONFIG_OV3640_AUTOFOCUS=y
# CONFIG_SOC_CAMERA_OV5640 is not set
# CONFIG_SOC_CAMERA_S5K6AA is not set
# CONFIG_SOC_CAMERA_GT2005 is not set
# CONFIG_SOC_CAMERA_GC0307 is not set
# CONFIG_SOC_CAMERA_GC0308 is not set
# CONFIG_SOC_CAMERA_GC0309 is not set
# CONFIG_SOC_CAMERA_GC2015 is not set
@ -1445,13 +1451,7 @@ CONFIG_USB_PWC_INPUT_EVDEV=y
# CONFIG_USB_ZR364XX is not set
# CONFIG_USB_STKWEBCAM is not set
# CONFIG_USB_S2255 is not set
CONFIG_RADIO_ADAPTERS=y
# CONFIG_I2C_SI4713 is not set
# CONFIG_RADIO_SI4713 is not set
# CONFIG_USB_DSBR is not set
# CONFIG_RADIO_SI470X is not set
# CONFIG_USB_MR800 is not set
# CONFIG_RADIO_TEA5764 is not set
# CONFIG_RADIO_ADAPTERS is not set
# CONFIG_SMS_SIANO_MDTV is not set
# CONFIG_DAB is not set
@ -1486,8 +1486,9 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_RK2818 is not set
CONFIG_FB_RK29=y
CONFIG_FB_WORK_IPP=y
# CONFIG_FB_SCALING_OSD is not set
CONFIG_FB_SCALING_OSD=y
# CONFIG_FB_ROTATE_VIDEO is not set
# CONFIG_CLOSE_WIN1_DYNAMIC is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
@ -1496,7 +1497,8 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_RK29_BL=y
# CONFIG_BACKLIGHT_RK29_BL is not set
CONFIG_BACKLIGHT_RK29_NEWTON_BL=y
# CONFIG_FIH_TOUCHKEY_LED is not set
# CONFIG_BACKLIGHT_AW9364 is not set
# CONFIG_BUTTON_LIGHT is not set
@ -1575,9 +1577,7 @@ CONFIG_SND_JACK=y
# CONFIG_SND_EMU10K1_SEQ is not set
# CONFIG_SND_DRIVERS is not set
# CONFIG_SND_ARM is not set
CONFIG_SND_USB=y
# CONFIG_SND_USB_AUDIO is not set
# CONFIG_SND_USB_CAIAQ is not set
# CONFIG_SND_USB is not set
CONFIG_SND_SOC=y
CONFIG_SND_RK29_SOC=y
CONFIG_SND_RK29_SOC_I2S=y
@ -1592,6 +1592,7 @@ CONFIG_SND_RK29_SOC_I2S_8CH=y
CONFIG_SND_RK29_SOC_CS42L52=y
# CONFIG_SND_RK29_CODEC_SOC_MASTER is not set
CONFIG_SND_RK29_CODEC_SOC_SLAVE=y
# CONFIG_ADJUST_VOL_BY_CODEC is not set
CONFIG_SND_SOC_I2C_AND_SPI=y
# CONFIG_SND_SOC_ALL_CODECS is not set
CONFIG_SND_SOC_CS42L52=y
@ -2020,6 +2021,7 @@ CONFIG_VIVANTE=y
# IPP
#
CONFIG_RK29_IPP=y
CONFIG_DEINTERLACE=y
#
# CMMB

View File

@ -230,7 +230,9 @@ CONFIG_MACH_RK29_PHONEPADSDK=y
# CONFIG_DDR_TYPE_DDR3_2133N is not set
CONFIG_DDR_TYPE_DDR3_DEFAULT=y
CONFIG_RK29_MEM_SIZE_M=512
CONFIG_DDR_SDRAM_FREQ=400
CONFIG_DDR_SDRAM_FREQ=456
# CONFIG_DDR_RECONFIG is not set
CONFIG_WIFI_CONTROL_FUNC=y
#
# RK29 VPU (Video Processing Unit) support
@ -1437,6 +1439,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_RK2818 is not set
CONFIG_FB_RK29=y
CONFIG_FB_WORK_IPP=y
CONFIG_CLOSE_WIN1_DYNAMIC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set

View File

@ -232,6 +232,7 @@ CONFIG_RK29_MEM_SIZE_512M=y
# CONFIG_RK29_MEM_SIZE_1G is not set
CONFIG_RK29_MEM_SIZE_M=512
CONFIG_DDR_SDRAM_FREQ=192
CONFIG_DDR_FREQ=y
#
# RK29 VPU (Video Processing Unit) support
@ -1331,6 +1332,7 @@ CONFIG_FB_RK29=y
CONFIG_FB_WORK_IPP=y
# CONFIG_FB_SCALING_OSD is not set
CONFIG_FB_ROTATE_VIDEO=y
CONFIG_CLOSE_WIN1_DYNAMIC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
@ -1825,6 +1827,7 @@ CONFIG_VIVANTE=y
# IPP
#
CONFIG_RK29_IPP=y
CONFIG_DEINTERLACE=n
#
# CMMB

View File

@ -236,6 +236,7 @@ CONFIG_MACH_RK29SDK=y
CONFIG_DDR_TYPE_DDR3_DEFAULT=y
CONFIG_RK29_MEM_SIZE_M=512
CONFIG_DDR_SDRAM_FREQ=400
CONFIG_DDR_FREQ=y
# CONFIG_DDR_RECONFIG is not set
CONFIG_WIFI_CONTROL_FUNC=y
@ -1480,7 +1481,7 @@ CONFIG_FB_RK29=y
CONFIG_FB_WORK_IPP=y
CONFIG_FB_SCALING_OSD=y
# CONFIG_FB_ROTATE_VIDEO is not set
# CONFIG_CLOSE_WIN1_DYNAMIC is not set
CONFIG_CLOSE_WIN1_DYNAMIC=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set

10
arch/arm/mach-rk29/Kconfig Executable file → Normal file
View File

@ -67,6 +67,12 @@ config MACH_RK29_P91
endchoice
config RK29_NEWTON_CLOCK
depends on MACH_RK29_newton
bool "enable newton 1.2G cpu clock support"
help
support for newton 1.2G cpu clock.
choice DDR_TYPE
prompt "DDR Memory Type"
default DDR_TYPE_DDR3_DEFAULT
@ -157,6 +163,10 @@ config DDR_SDRAM_FREQ
int "DDR SDRAM frequence (in MHz)"
default 400
config DDR_FREQ
bool "Enable DDR frequency scaling"
default y
config DDR_RECONFIG
bool "Enable dynamic DDR reconfiguration (EXPERIMENTAL)"

3
arch/arm/mach-rk29/Makefile Executable file → Normal file
View File

@ -8,6 +8,7 @@ obj-$(CONFIG_RK29_LAST_LOG) += last_log.o
obj-$(CONFIG_USB_GADGET) += usb_detect.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
obj-$(CONFIG_DDR_FREQ) += ddrfreq.o
obj-$(CONFIG_RK29_VPU) += vpu_mem.o
obj-y += spi_sram.o
obj-$(CONFIG_RK29_VPU_SERVICE) += vpu_service.o
@ -22,5 +23,5 @@ obj-$(CONFIG_MACH_RK29_PHONESDK) += board-rk29-phonesdk.o board-rk29-phonesdk-ke
obj-$(CONFIG_MACH_RK29FIH) += board-rk29-fih.o board-rk29-fih-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
obj-$(CONFIG_MACH_RK29_A22) += board-rk29-a22.o board-rk29-a22-key.o board-rk29-a22-rfkill.o
obj-$(CONFIG_MACH_RK29_PHONEPADSDK) += board-rk29phonepadsdk.o board-rk29phonepadsdk-key.o board-rk29phonepadsdk-rfkill.o board-rk29phonepadsdk-power.o
obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-rk29sdk-rfkill.o board-rk29sdk-power.o
obj-$(CONFIG_MACH_RK29_newton) += board-rk29-newton.o board-rk29-newton-key.o board-newton-rfkill.o board-rk29sdk-power.o

View File

@ -0,0 +1,296 @@
/*
* Copyright (C) 2010 ROCKCHIP, Inc.
* Author: roger_chen <cz@rock-chips.com>
*
* This program is the bluetooth device bcm4329's driver,
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/rfkill.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/wakelock.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <mach/gpio.h>
#include <asm/irq.h>
#include <mach/iomux.h>
#include <linux/wakelock.h>
#include <linux/timer.h>
#if 0
#define DBG(x...) printk(KERN_INFO x)
#else
#define DBG(x...)
#endif
#define BT_WAKE_HOST_SUPPORT 0
struct bt_ctrl
{
struct rfkill *bt_rfk;
#if BT_WAKE_HOST_SUPPORT
struct timer_list tl;
bool b_HostWake;
struct wake_lock bt_wakelock;
#endif
};
#define BT_GPIO_POWER RK29_PIN5_PD6
#define IOMUX_BT_GPIO_POWER rk29_mux_api_set(GPIO5D6_SDMMC1PWREN_NAME, GPIO5H_GPIO5D6);
#define BT_GPIO_RESET RK29_PIN6_PC4
#define BT_GPIO_WAKE_UP RK29_PIN6_PC5
#define BT_GPIO_WAKE_UP_HOST //RK2818_PIN_PA7
#define IOMUX_BT_GPIO_WAKE_UP_HOST() //rk2818_mux_api_set(GPIOA7_FLASHCS3_SEL_NAME,0);
#define BT_WAKE_LOCK_TIMEOUT 10 //s
static const char bt_name[] = "bcm4329";
extern int rk29sdk_bt_power_state;
extern int rk29sdk_wifi_power_state;
struct bt_ctrl gBtCtrl;
#if BT_WAKE_HOST_SUPPORT
void resetBtHostSleepTimer(void)
{
mod_timer(&(gBtCtrl.tl),jiffies + BT_WAKE_LOCK_TIMEOUT*HZ);//再重新设置超时值。
}
void btWakeupHostLock(void)
{
if(gBtCtrl.b_HostWake == false){
DBG("*************************Lock\n");
wake_lock(&(gBtCtrl.bt_wakelock));
gBtCtrl.b_HostWake = true;
}
}
void btWakeupHostUnlock(void)
{
if(gBtCtrl.b_HostWake == true){
DBG("*************************UnLock\n");
wake_unlock(&(gBtCtrl.bt_wakelock)); //让系统睡眠
gBtCtrl.b_HostWake = false;
}
}
static void timer_hostSleep(unsigned long arg)
{
DBG("%s---b_HostWake=%d\n",__FUNCTION__,gBtCtrl.b_HostWake);
btWakeupHostUnlock();
}
#ifdef CONFIG_PM
static int bcm4329_rfkill_suspend(struct platform_device *pdev, pm_message_t state)
{
DBG("%s\n",__FUNCTION__);
return 0;
}
static int bcm4329_rfkill_resume(struct platform_device *pdev)
{
DBG("%s\n",__FUNCTION__);
btWakeupHostLock();
resetBtHostSleepTimer();
return 0;
}
#else
#define bcm4329_rfkill_suspend NULL
#define bcm4329_rfkill_resume NULL
#endif
static irqreturn_t bcm4329_wake_host_irq(int irq, void *dev)
{
btWakeupHostLock();
resetBtHostSleepTimer();
return IRQ_HANDLED;
}
#endif
#ifdef CONFIG_BT_HCIBCM4325
int bcm4325_sleep(int bSleep)
{
// printk("*************bt enter sleep***************\n");
if (bSleep)
gpio_set_value(BT_GPIO_WAKE_UP, GPIO_LOW); //low represent bt device may enter sleep
else
gpio_set_value(BT_GPIO_WAKE_UP, GPIO_HIGH); //high represent bt device must be awake
//printk("sleep=%d\n",bSleep);
}
#endif
static int bcm4329_set_block(void *data, bool blocked)
{
DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
IOMUX_BT_GPIO_POWER;
if (false == blocked) {
gpio_set_value(BT_GPIO_POWER, GPIO_HIGH); /* bt power on */
gpio_set_value(BT_GPIO_RESET, GPIO_LOW);
mdelay(200);
gpio_set_value(BT_GPIO_RESET, GPIO_HIGH); /* bt reset deactive*/
mdelay(200);
#if BT_WAKE_HOST_SUPPORT
btWakeupHostLock();
#endif
pr_info("bt turn on power\n");
}
else {
#if BT_WAKE_HOST_SUPPORT
btWakeupHostUnlock();
#endif
// cwz 0: close for bt uart2 larkage.
#if 0
if (!rk29sdk_wifi_power_state) {
gpio_set_value(BT_GPIO_POWER, GPIO_LOW); /* bt power off */
mdelay(20);
pr_info("bt shut off power\n");
}else {
pr_info("bt shouldn't shut off power, wifi is using it!\n");
}
#endif
gpio_set_value(BT_GPIO_RESET, GPIO_LOW); /* bt reset active*/
mdelay(20);
}
rk29sdk_bt_power_state = !blocked;
return 0;
}
static const struct rfkill_ops bcm4329_rfk_ops = {
.set_block = bcm4329_set_block,
};
static int __devinit bcm4329_rfkill_probe(struct platform_device *pdev)
{
int rc = 0;
bool default_state = true;
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
/* default to bluetooth off */
bcm4329_set_block(NULL, default_state); /* blocked -> bt off */
gBtCtrl.bt_rfk = rfkill_alloc(bt_name,
NULL,
RFKILL_TYPE_BLUETOOTH,
&bcm4329_rfk_ops,
NULL);
if (!gBtCtrl.bt_rfk)
{
printk("fail to rfkill_allocate************\n");
return -ENOMEM;
}
rfkill_set_states(gBtCtrl.bt_rfk, default_state, false);
rc = rfkill_register(gBtCtrl.bt_rfk);
if (rc)
{
printk("failed to rfkill_register,rc=0x%x\n",rc);
rfkill_destroy(gBtCtrl.bt_rfk);
}
gpio_request(BT_GPIO_POWER, NULL);
gpio_request(BT_GPIO_RESET, NULL);
gpio_request(BT_GPIO_WAKE_UP, NULL);
#if BT_WAKE_HOST_SUPPORT
init_timer(&(gBtCtrl.tl));
gBtCtrl.tl.expires = jiffies + BT_WAKE_LOCK_TIMEOUT*HZ;
gBtCtrl.tl.function = timer_hostSleep;
add_timer(&(gBtCtrl.tl));
gBtCtrl.b_HostWake = false;
wake_lock_init(&(gBtCtrl.bt_wakelock), WAKE_LOCK_SUSPEND, "bt_wake");
rc = gpio_request(BT_GPIO_WAKE_UP_HOST, "bt_wake");
if (rc) {
printk("%s:failed to request RAHO_BT_WAKE_UP_HOST\n",__FUNCTION__);
}
IOMUX_BT_GPIO_WAKE_UP_HOST();
gpio_pull_updown(BT_GPIO_WAKE_UP_HOST,GPIOPullUp);
rc = request_irq(gpio_to_irq(BT_GPIO_WAKE_UP_HOST),bcm4329_wake_host_irq,IRQF_TRIGGER_FALLING,NULL,NULL);
if(rc)
{
printk("%s:failed to request RAHO_BT_WAKE_UP_HOST irq\n",__FUNCTION__);
gpio_free(BT_GPIO_WAKE_UP_HOST);
}
enable_irq_wake(gpio_to_irq(BT_GPIO_WAKE_UP_HOST)); // so RAHO_BT_WAKE_UP_HOST can wake up system
printk(KERN_INFO "bcm4329 module has been initialized,rc=0x%x\n",rc);
#endif
return rc;
}
static int __devexit bcm4329_rfkill_remove(struct platform_device *pdev)
{
if (gBtCtrl.bt_rfk)
rfkill_unregister(gBtCtrl.bt_rfk);
gBtCtrl.bt_rfk = NULL;
#if BT_WAKE_HOST_SUPPORT
del_timer(&(gBtCtrl.tl));//删掉定时器
btWakeupHostUnlock();
wake_lock_destroy(&(gBtCtrl.bt_wakelock));
#endif
platform_set_drvdata(pdev, NULL);
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
return 0;
}
static struct platform_driver bcm4329_rfkill_driver = {
.probe = bcm4329_rfkill_probe,
.remove = __devexit_p(bcm4329_rfkill_remove),
.driver = {
.name = "rk29sdk_rfkill",
.owner = THIS_MODULE,
},
#if BT_WAKE_HOST_SUPPORT
.suspend = bcm4329_rfkill_suspend,
.resume = bcm4329_rfkill_resume,
#endif
};
/*
* Module initialization
*/
static int __init bcm4329_mod_init(void)
{
int ret;
DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
ret = platform_driver_register(&bcm4329_rfkill_driver);
printk("ret=0x%x\n", ret);
return ret;
}
static void __exit bcm4329_mod_exit(void)
{
platform_driver_unregister(&bcm4329_rfkill_driver);
}
module_init(bcm4329_mod_init);
module_exit(bcm4329_mod_exit);
MODULE_DESCRIPTION("bcm4329 Bluetooth driver");
MODULE_AUTHOR("roger_chen cz@rock-chips.com");
MODULE_LICENSE("GPL");

View File

@ -133,7 +133,11 @@
#else
#define MEM_FBIPP_SIZE 0
#endif
#define PMEM_GPU_BASE ((u32)RK29_SDRAM_PHYS + SDRAM_SIZE - PMEM_GPU_SIZE)
#if SDRAM_SIZE > SZ_512M
#define PMEM_GPU_BASE (RK29_SDRAM_PHYS + SZ_512M - PMEM_GPU_SIZE)
#else
#define PMEM_GPU_BASE (RK29_SDRAM_PHYS + SDRAM_SIZE - PMEM_GPU_SIZE)
#endif
#define PMEM_UI_BASE (PMEM_GPU_BASE - PMEM_UI_SIZE)
#define PMEM_VPU_BASE (PMEM_UI_BASE - PMEM_VPU_SIZE)
#define PMEM_CAM_BASE (PMEM_VPU_BASE - PMEM_CAM_SIZE)
@ -654,7 +658,7 @@ int wm831x_post_init(struct wm831x *parm)
dcdc = regulator_get(NULL, "dcdc3"); // 1th IO
regulator_set_voltage(dcdc,3000000,3000000);
regulator_set_suspend_voltage(dcdc, 3000000);
regulator_set_suspend_voltage(dcdc, 2800000);
regulator_enable(dcdc);
printk("%s set dcdc3=%dmV end\n", __FUNCTION__, regulator_get_voltage(dcdc));
regulator_put(dcdc);
@ -852,9 +856,9 @@ struct wm831x_battery_pdata wm831x_battery_platdata = {
.off_mask = 1, /** Mask OFF while charging */
.trickle_ilim = 200, /** Trickle charge current limit, in mA */
.vsel = 4200, /** Target voltage, in mV */
.eoc_iterm = 90, /** End of trickle charge current, in mA */
.eoc_iterm = 50, /** End of trickle charge current, in mA */
.fast_ilim = 600, /** Fast charge current limit, in mA */
.timeout = 240, /** Charge cycle timeout, in minutes */
.timeout = 480, /** Charge cycle timeout, in minutes */
.syslo = 3300, /* syslo threshold, in mV*/
.sysok = 3500, /* sysko threshold, in mV*/
};
@ -1435,7 +1439,12 @@ struct platform_device rk29_device_gps = {
* author: qjb@rock-chips.com
*****************************************************************************************/
struct wm8994_pdata wm8994_platdata = {
.BB_input_diff = 0,
.BB_class = NO_PCM_BB,
.no_earpiece = 0,
.sp_hp_same_channel = 0,
.PA_control_pin = RK29_PIN6_PD3,
.Power_EN_Pin = RK29_PIN5_PA1,
@ -2159,7 +2168,11 @@ static int rk29_sdmmc0_cfg_gpio(void)
rk29_mux_api_set(GPIO1D3_SDMMC0DATA1_NAME, GPIO1H_SDMMC0_DATA1);
rk29_mux_api_set(GPIO1D4_SDMMC0DATA2_NAME, GPIO1H_SDMMC0_DATA2);
rk29_mux_api_set(GPIO1D5_SDMMC0DATA3_NAME, GPIO1H_SDMMC0_DATA3);
rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);
#ifdef CONFIG_SDMMC_RK29_OLD
rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_GPIO2A2);
#else
rk29_mux_api_set(GPIO2A2_SDMMC0DETECTN_NAME, GPIO2L_SDMMC0_DETECT_N);//Modifyed by xbw.
#endif
rk29_mux_api_set(GPIO5D5_SDMMC0PWREN_NAME, GPIO5H_GPIO5D5); ///GPIO5H_SDMMC0_PWR_EN); ///GPIO5H_GPIO5D5);
gpio_request(RK29_PIN5_PD5,"sdmmc");
gpio_set_value(RK29_PIN5_PD5,GPIO_HIGH);
@ -2182,6 +2195,7 @@ struct rk29_sdmmc_platform_data default_sdmmc0_data = {
.use_dma = 0,
#endif
.detect_irq = INVALID_GPIO,
.enable_sd_wakeup = 0,
};
#endif
#ifdef CONFIG_SDMMC1_RK29
@ -2421,13 +2435,13 @@ static struct resource resources_gpu[] = {
[1] = {
.name = "gpu_base",
.start = RK29_GPU_PHYS,
.end = RK29_GPU_PHYS + RK29_GPU_SIZE,
.end = RK29_GPU_PHYS + RK29_GPU_SIZE - 1,
.flags = IORESOURCE_MEM,
},
[2] = {
.name = "gpu_mem",
.start = PMEM_GPU_BASE,
.end = PMEM_GPU_BASE + PMEM_GPU_SIZE,
.end = PMEM_GPU_BASE + PMEM_GPU_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
@ -2477,7 +2491,25 @@ struct platform_device rk29_device_vibrator ={
static void __init rk29_board_iomux_init(void)
{
int err;
int err;
#ifdef CONFIG_UART1_RK29
//disable uart1 pull down
rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_GPIO2A5);
rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_GPIO2A4);
gpio_request(RK29_PIN2_PA5, NULL);
gpio_request(RK29_PIN2_PA4, NULL);
gpio_pull_updown(RK29_PIN2_PA5, PullDisable);
gpio_pull_updown(RK29_PIN2_PA4, PullDisable);
rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_UART1_SOUT);
rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_UART1_SIN);
gpio_free(RK29_PIN2_PA5);
gpio_free(RK29_PIN2_PA4);
#endif
#if CONFIG_ANDROID_TIMED_GPIO
rk29_mux_api_set(GPIO1B5_PWM0_NAME, GPIO1L_GPIO1B5);//for timed gpio
@ -3029,6 +3061,7 @@ static void rk29_pm_power_off(void)
while (1);
}
extern struct usb_mass_storage_platform_data mass_storage_pdata;
static void __init machine_rk29_board_init(void)
{
rk29_board_iomux_init();
@ -3039,6 +3072,8 @@ static void __init machine_rk29_board_init(void)
pm_power_off = rk29_pm_power_off;
//arm_pm_restart = rk29_pm_power_restart;
mass_storage_pdata.nluns = 1;//change number of LUNS
platform_add_devices(devices, ARRAY_SIZE(devices));
#ifdef CONFIG_I2C0_RK29
i2c_register_board_info(default_i2c0_data.bus_num, board_i2c0_devices,
@ -3074,6 +3109,11 @@ static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tag
mi->bank[0].start = RK29_SDRAM_PHYS;
mi->bank[0].node = PHYS_TO_NID(RK29_SDRAM_PHYS);
mi->bank[0].size = LINUX_SIZE;
#if SDRAM_SIZE > SZ_512M
mi->nr_banks = 2;
mi->bank[1].start = RK29_SDRAM_PHYS + SZ_512M;
mi->bank[1].size = SDRAM_SIZE - SZ_512M;
#endif
}
static void __init machine_rk29_mapio(void)
@ -3088,7 +3128,7 @@ static void __init machine_rk29_mapio(void)
MACHINE_START(RK29, "RK29board")
/* UART for LL DEBUG */
.phys_io = RK29_UART1_PHYS,
.phys_io = RK29_UART1_PHYS & 0xfff00000,
.io_pg_offst = ((RK29_UART1_BASE) >> 18) & 0xfffc,
.boot_params = RK29_SDRAM_PHYS + 0x88000,
.fixup = machine_rk29_fixup,

File diff suppressed because it is too large Load Diff

64
arch/arm/mach-rk29/board-rk29-newton-key.c Executable file → Normal file
View File

@ -14,97 +14,43 @@ static struct rk29_keys_button key_button[] = {
.code = EV_MENU,
.gpio = RK29_PIN6_PA3, // PA0--> PA3: home -> menu
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "vol+",
.code = KEY_VOLUMEUP,
.gpio = RK29_PIN6_PA2,
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "vol-",
.code = KEY_VOLUMEDOWN,
.gpio = RK29_PIN6_PA1,
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "home",
.code = KEY_HOME,
.gpio = RK29_PIN6_PA5, //PA3 --> PA5
.active_low = PRESS_LEV_LOW,
},
{
.desc = "search",
.code = KEY_SEARCH,
.gpio = RK29_PIN6_PA4,
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "esc",
.code = KEY_BACK,
.gpio = RK29_PIN6_PA0, //PA5-->PA0: menu-> esc
.active_low = PRESS_LEV_LOW,
},
{
.desc = "sensor",
.code = KEY_CAMERA,
.gpio = RK29_PIN6_PA6,
.active_low = PRESS_LEV_LOW,
.wakeup = 0,
},
{
.desc = "play",
.code = KEY_POWER,
.gpio = RK29_PIN6_PA7,
.active_low = PRESS_LEV_LOW,
//.code_long_press = EV_ENCALL,
.wakeup = 1,
},
#if 0
{
.desc = "vol+",
.code = KEY_VOLUMEDOWN,
.adc_value = 95,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "vol-",
.code = KEY_VOLUMEUP,
.adc_value = 249,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "menu",
.code = EV_MENU,
.adc_value = 406,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "home",
.code = KEY_HOME,
.code_long_press = KEY_F4,
.adc_value = 561,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "esc",
.code = KEY_ESC,
.adc_value = 726,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
{
.desc = "adkey6",
.code = KEY_BACK,
.code_long_press = EV_ENCALL,
.adc_value = 899,
.gpio = INVALID_GPIO,
.active_low = PRESS_LEV_LOW,
},
#endif
};
struct rk29_keys_platform_data rk29_keys_pdata = {
.buttons = key_button,

127
arch/arm/mach-rk29/board-rk29-newton.c Executable file → Normal file
View File

@ -61,6 +61,10 @@
#include "../../../drivers/cir/bu92747guw_cir.h"
#endif
// define for newton for hardware 1.5V
#define RK29_NEWTON_NEWBOARD
#ifdef CONFIG_VIDEO_RK29
/*---------------- Camera Sensor Macro Define Begin ------------------------*/
/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/
@ -515,6 +519,7 @@ int ft5406_platform_wakeup(void)
{
printk("ft5406_platform_wakeup\n");
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
msleep(300);
return 0;
}
@ -548,11 +553,11 @@ int gt819_init_platform_hw(void)
gpio_direction_output(TOUCH_RESET_PIN, 0);
gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
mdelay(10);
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
mdelay(10);
gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
// gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
// mdelay(10);
// gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
gpio_direction_input(TOUCH_INT_PIN);
mdelay(10);
// mdelay(10);
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
msleep(300);
return 0;
@ -617,6 +622,9 @@ struct cs42l52_platform_data cs42l52_info = {
#if defined (CONFIG_BATTERY_BQ27541)
#define DC_CHECK_PIN RK29_PIN4_PA1
#define LI_LION_BAT_NUM 1
#define CHG_OK RK29_PIN4_PA3
#define BAT_LOW RK29_PIN4_PA2
static int bq27541_init_dc_check_pin(void){
if(gpio_request(DC_CHECK_PIN,"dc_check") != 0){
gpio_free(DC_CHECK_PIN);
@ -631,6 +639,8 @@ struct bq27541_platform_data bq27541_info = {
.init_dc_check_pin = bq27541_init_dc_check_pin,
.dc_check_pin = DC_CHECK_PIN,
.bat_num = LI_LION_BAT_NUM,
.chgok_check_pin = CHG_OK,
.bat_check_pin = BAT_LOW,
};
#endif
static struct android_pmem_platform_data android_pmem_pdata = {
@ -741,6 +751,31 @@ static struct eeti_egalax_platform_data eeti_egalax_info = {
.disp_on_value = TOUCH_SCREEN_DISPLAY_VALUE,
};
#endif
#ifdef CONFIG_GS_KXTF9
#include <linux/kxtf9.h>
#define KXTF9_DEVICE_MAP 1
#define KXTF9_MAP_X (KXTF9_DEVICE_MAP-1)%2
#define KXTF9_MAP_Y KXTF9_DEVICE_MAP%2
#define KXTF9_NEG_X (KXTF9_DEVICE_MAP/2)%2
#define KXTF9_NEG_Y (KXTF9_DEVICE_MAP+1)/4
#define KXTF9_NEG_Z (KXTF9_DEVICE_MAP-1)/4
struct kxtf9_platform_data kxtf9_pdata = {
.min_interval = 1,
.poll_interval = 20,
.g_range = KXTF9_G_2G,
.axis_map_x = KXTF9_MAP_X,
.axis_map_y = KXTF9_MAP_Y,
.axis_map_z = 2,
.negate_x = KXTF9_NEG_X,
.negate_y = KXTF9_NEG_Y,
.negate_z = KXTF9_NEG_Z,
//.ctrl_regc_init = KXTF9_G_2G | ODR50F,
//.ctrl_regb_init = ENABLE,
};
#endif /* CONFIG_GS_KXTF9 */
/*MMA8452 gsensor*/
#if defined (CONFIG_GS_MMA8452)
#define MMA8452_INT_PIN RK29_PIN0_PA3
@ -1150,7 +1185,7 @@ static struct i2c_board_info __initdata board_i2c2_devices[] = {
#ifdef CONFIG_I2C3_RK29
static struct i2c_board_info __initdata board_i2c3_devices[] = {
#if defined (CONFIG_BATTERY_BQ27541)
#if defined (CONFIG_BATTERY_BQ27541)
{
.type = "bq27541",
.addr = 0x55,
@ -1230,7 +1265,7 @@ static struct rk29camera_platform_ioctl_cb sensor_ioctl_cb = {
* backlight devices
* author: nzy@rock-chips.com
*****************************************************************************************/
#ifdef CONFIG_BACKLIGHT_RK29_BL
#ifdef CONFIG_BACKLIGHT_RK29_NEWTON_BL
/*
GPIO1B5_PWM0_NAME, GPIO1L_PWM0
GPIO5D2_PWM1_UART1SIRIN_NAME, GPIO5H_PWM1
@ -1324,6 +1359,13 @@ struct rk29_bl_info rk29_bl_info = {
.pwm_resume = rk29_backlight_pwm_resume,
.min_brightness = BACKLIGHT_MINVALUE,
};
struct platform_device rk29_device_backlight = {
.name = "rk29_backlight",
.id = -1,
.dev = {
.platform_data = &rk29_bl_info,
}
};
#endif
/*****************************************************************************************
* pwm voltage regulator devices
@ -1346,7 +1388,11 @@ static struct regulator_init_data rk29_pwm_regulator_data = {
.constraints = {
.name = "PWM2",
.min_uV = 950000,
#ifdef CONFIG_RK29_NEWTON_CLOCK
.max_uV = 1500000,
#else
.max_uV = 1400000,
#endif
.apply_uV = 1,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE,
},
@ -1510,7 +1556,12 @@ static int rk29sdk_wifi_bt_gpio_control_init(void)
return -1;
}
// cwz 0: close for bt uart2 larkage.
#if 0
gpio_direction_output(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
#else
gpio_direction_output(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_HIGH);
#endif
gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
gpio_direction_output(RK29SDK_BT_GPIO_RESET_N, GPIO_LOW);
@ -1528,6 +1579,8 @@ static int rk29sdk_wifi_power(int on)
mdelay(100);
pr_info("wifi turn on power\n");
}else{
// cwz 0: close for bt uart2 larkage.
#if 0
if (!rk29sdk_bt_power_state){
gpio_set_value(RK29SDK_WIFI_BT_GPIO_POWER_N, GPIO_LOW);
mdelay(100);
@ -1536,8 +1589,8 @@ static int rk29sdk_wifi_power(int on)
{
pr_info("wifi shouldn't shut off power, bt is using it!\n");
}
#endif
gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW);
}
rk29sdk_wifi_power_state = on;
@ -1649,8 +1702,13 @@ static struct platform_device rk29sdk_rfkill = {
#ifdef CONFIG_VIVANTE
#ifdef CONFIG_RK29_NEWTON_CLOCK
#define GPU_HIGH_CLOCK 504 // 504 456
#define GPU_LOW_CLOCK 300
#else
#define GPU_HIGH_CLOCK 552
#define GPU_LOW_CLOCK (periph_pll_default / 1000000) /* same as general pll clock rate below */
#endif
static struct resource resources_gpu[] = {
[0] = {
.name = "gpu_irq",
@ -1685,7 +1743,7 @@ static struct platform_device rk29_device_gpu = {
};
#endif
#ifdef CONFIG_KEYS_RK29
#ifdef CONFIG_KEYS_RK29_NEWTON
extern struct rk29_keys_platform_data rk29_keys_pdata;
static struct platform_device rk29_device_keys = {
.name = "rk29-keypad",
@ -1857,6 +1915,9 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_KEYS_RK29
&rk29_device_keys,
#endif
#ifdef CONFIG_KEYS_RK29_NEWTON
&rk29_device_keys,
#endif
#ifdef CONFIG_SDMMC0_RK29
&rk29_device_sdmmc0,
#endif
@ -1887,6 +1948,9 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_BACKLIGHT_RK29_BL
&rk29_device_backlight,
#endif
#ifdef CONFIG_BACKLIGHT_RK29_NEWTON_BL
&rk29_device_backlight,
#endif
#ifdef CONFIG_RK29_VMAC
&rk29_device_vmac,
#endif
@ -2190,30 +2254,41 @@ static void __init machine_rk29_init_irq(void)
}
static struct cpufreq_frequency_table freq_table[] = {
#ifdef CONFIG_RK29_NEWTON_CLOCK
{ .index = 1200000, .frequency = 408000 },
{ .index = 1250000, .frequency = 816000 },
{ .index = 1300000, .frequency = 1008000 },
{ .index = 1460000, .frequency = 1200000 },
#else
#ifdef RK29_NEWTON_NEWBOARD
/*
* hardware change the max vdd from 1.4 to 1.5, so new table is:
* 1.075 -> 1.133
* 1.1 -> 1.16
* 1.125 -> 1.20
* 1.15 -> 1.225
* 1.225 -> 1.313
* 1.30 -> 1.404
* 1.325 -> 1.436
* 1.35 -> 1.46
* 1.40 -> 1.5
*
*/
{ .index = 1125000, .frequency = 408000 },
{ .index = 1150000, .frequency = 816000 },
{ .index = 1225000, .frequency = 1008000 },
#else
{ .index = 1200000, .frequency = 408000 },
{ .index = 1200000, .frequency = 816000 },
{ .index = 1300000, .frequency = 1008000 },
#endif // RK29_NEWTON_NEWBOARD
#endif // CONFIG_RK29_NEWTON_CLOCK
{ .frequency = CPUFREQ_TABLE_END },
};
#define BAT_LOW RK29_PIN4_PA2
#define POWER_ON_PIN RK29_PIN4_PA4
static void __init machine_rk29_board_init(void)
{
int val =0;
gpio_request(BAT_LOW, NULL);
gpio_direction_input(BAT_LOW);
val = gpio_get_value(BAT_LOW);
if (val == 0){
printk("no battery, no power up\n");
gpio_request(POWER_ON_PIN, "poweronpin");
gpio_direction_output(POWER_ON_PIN, GPIO_LOW);
while(1){
gpio_set_value(POWER_ON_PIN, GPIO_LOW);
mdelay(100);
}
}
gpio_free(BAT_LOW);
rk29_board_iomux_init();
board_power_init();
@ -2272,7 +2347,11 @@ static void __init machine_rk29_mapio(void)
rk29_map_common_io();
rk29_setup_early_printk();
rk29_sram_init();
#ifdef CONFIG_RK29_NEWTON_CLOCK
rk29_clock_init(periph_pll_144mhz);
#else
rk29_clock_init(periph_pll_default);
#endif
rk29_iomux_init();
ddr_init(DDR_TYPE,DDR_FREQ); // DDR3_1333H, 400
}

View File

@ -118,7 +118,7 @@
#else
#define SDRAM_SIZE SZ_512M
#endif
#define PMEM_GPU_SIZE SZ_64M
#define PMEM_GPU_SIZE SZ_16M
#define PMEM_UI_SIZE SZ_32M
#define PMEM_VPU_SIZE SZ_64M
#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY
@ -381,7 +381,7 @@ static struct android_pmem_platform_data android_pmem_pdata = {
.name = "pmem",
.start = PMEM_UI_BASE,
.size = PMEM_UI_SIZE,
.no_allocator = 0,
.no_allocator = 1,
.cached = 1,
};
@ -930,9 +930,9 @@ struct wm831x_battery_pdata wm831x_battery_platdata = {
.off_mask = 1, /** Mask OFF while charging */
.trickle_ilim = 200, /** Trickle charge current limit, in mA */
.vsel = 4200, /** Target voltage, in mV */
.eoc_iterm = 90, /** End of trickle charge current, in mA */
.eoc_iterm = 50, /** End of trickle charge current, in mA */
.fast_ilim = 500, /** Fast charge current limit, in mA */
.timeout = 240, /** Charge cycle timeout, in minutes */
.timeout = 480, /** Charge cycle timeout, in minutes */
.syslo = 3300, /* syslo threshold, in mV*/
.sysok = 3500, /* sysko threshold, in mV*/
};
@ -1514,6 +1514,12 @@ struct platform_device rk29_device_gps = {
*****************************************************************************************/
struct wm8994_pdata wm8994_platdata = {
.BB_input_diff = 0,
.BB_class = NO_PCM_BB,
.no_earpiece = 0,
.sp_hp_same_channel = 0,
.PA_control_pin = 0,
.Power_EN_Pin = RK29_PIN5_PA1,
@ -1526,7 +1532,7 @@ struct wm8994_pdata wm8994_platdata = {
.headset_normal_vol = -6,
.BT_incall_vol = 0,
.BT_incall_mic_vol = 0,
.recorder_vol = 20,
.recorder_vol = 30,
};
@ -2452,6 +2458,24 @@ static struct platform_device gpio_wave_device = {
static void __init rk29_board_iomux_init(void)
{
int err;
#ifdef CONFIG_UART1_RK29
//disable uart1 pull down
rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_GPIO2A5);
rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_GPIO2A4);
gpio_request(RK29_PIN2_PA5, NULL);
gpio_request(RK29_PIN2_PA4, NULL);
gpio_pull_updown(RK29_PIN2_PA5, PullDisable);
gpio_pull_updown(RK29_PIN2_PA4, PullDisable);
rk29_mux_api_set(GPIO2A5_UART1SOUT_NAME, GPIO2L_UART1_SOUT);
rk29_mux_api_set(GPIO2A4_UART1SIN_NAME, GPIO2L_UART1_SIN);
gpio_free(RK29_PIN2_PA5);
gpio_free(RK29_PIN2_PA4);
#endif
#ifdef CONFIG_RK29_PWM_REGULATOR
rk29_mux_api_set(REGULATOR_PWM_MUX_NAME,REGULATOR_PWM_MUX_MODE);
#endif

130
arch/arm/mach-rk29/board-rk29phonepadsdk.c Normal file → Executable file
View File

@ -103,7 +103,7 @@
#else
#define SDRAM_SIZE SZ_512M
#endif
#define PMEM_GPU_SIZE SZ_64M
#define PMEM_GPU_SIZE SZ_16M
#define PMEM_UI_SIZE SZ_32M
#define PMEM_VPU_SIZE SZ_64M
#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY
@ -384,7 +384,7 @@ static struct android_pmem_platform_data android_pmem_pdata = {
.name = "pmem",
.start = PMEM_UI_BASE,
.size = PMEM_UI_SIZE,
.no_allocator = 0,
.no_allocator = 1,
.cached = 1,
};
@ -608,7 +608,10 @@ int laibao_init_platform_hw(void)
struct laibao_platform_data laibao_info = {
.model= 1003,
.init_platform_hw= laibao_init_platform_hw,
.lcd_disp_on_pin = RK29_PIN6_PD0,
.disp_on_value = GPIO_HIGH,
.lcd_cs_pin = RK29_PIN6_PD1,
.lcd_cs_value = GPIO_HIGH,
};
#endif
@ -670,7 +673,7 @@ static struct mpu3050_platform_data mpu3050_data = {
//.orientation = { 0, -1, 0,-1, 0, 0,0, 0, -1 },
//.orientation = { 0, 1, 0,1, 0, 0,0, 0, -1 },
.orientation = { -1, 0, 0, 0, -1, 0, 0, 0, 1 },
.orientation = { 0, -1, 0, 1, 0, 0, 0, 0, 1 },
//.orientation = { 0, 1, 0, -1, 0, 0, 0, 0, -1 },
},
#endif
@ -719,112 +722,12 @@ struct bq27510_platform_data bq27510_info = {
* wm8994 codec
* author: qjb@rock-chips.com
*****************************************************************************************/
//#if defined(CONFIG_MFD_WM8994)
#if defined (CONFIG_REGULATOR_WM8994)
static struct regulator_consumer_supply wm8994_ldo1_consumers[] = {
{
.supply = "DBVDD",
},
{
.supply = "AVDD1",
},
{
.supply = "CPVDD",
},
{
.supply = "SPKVDD1",
}
};
static struct regulator_consumer_supply wm8994_ldo2_consumers[] = {
{
.supply = "DCVDD",
},
{
.supply = "AVDD2",
},
{
.supply = "SPKVDD2",
}
};
struct regulator_init_data regulator_init_data_ldo1 = {
.constraints = {
.name = "wm8994-ldo1",
.min_uA = 00000,
.max_uA = 18000,
.always_on = true,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_CURRENT,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_ldo1_consumers),
.consumer_supplies = wm8994_ldo1_consumers,
};
struct regulator_init_data regulator_init_data_ldo2 = {
.constraints = {
.name = "wm8994-ldo2",
.min_uA = 00000,
.max_uA = 18000,
.always_on = true,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_CURRENT,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_ldo2_consumers),
.consumer_supplies = wm8994_ldo2_consumers,
};
#endif
struct wm8994_drc_cfg wm8994_drc_cfg_pdata = {
.name = "wm8994_DRC",
.regs = {0,0,0,0,0},
};
struct wm8994_retune_mobile_cfg wm8994_retune_mobile_cfg_pdata = {
.name = "wm8994_EQ",
.rate = 0,
.regs = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
};
struct wm8994_pdata wm8994_platdata = {
#if defined (CONFIG_GPIO_WM8994)
.gpio_base = WM8994_GPIO_EXPANDER_BASE,
//Fill value to initialize the GPIO
.gpio_defaults ={},
#endif
//enable=0 disable ldo
#if defined (CONFIG_REGULATOR_WM8994)
.ldo = {
{
.enable = 0,
//RK29_PIN5_PA1
.supply = NULL,
.init_data = &regulator_init_data_ldo1,
},
{
.enable = 0,
.supply = NULL,
.init_data = &regulator_init_data_ldo2,
}
},
#endif
//DRC 0--use default
.num_drc_cfgs = 0,
.drc_cfgs = &wm8994_drc_cfg_pdata,
//EQ 0--use default
.num_retune_mobile_cfgs = 0,
.retune_mobile_cfgs = &wm8994_retune_mobile_cfg_pdata,
.lineout1_diff = 1,
.lineout2_diff = 1,
.lineout1fb = 1,
.lineout2fb = 1,
.micbias1_lvl = 1,
.micbias2_lvl = 1,
.jd_scthr = 0,
.jd_thr = 0,
.no_earpiece = 1,
.sp_hp_same_channel = 1,
.BB_input_diff = 1,
.phone_pad = 1,
.BB_class = PCM_BB,
.PA_control_pin = RK29_PIN6_PB6,
.Power_EN_Pin = RK29_PIN5_PA1,
@ -1200,11 +1103,14 @@ static struct i2c_board_info __initdata board_i2c2_devices[] = {
};
#endif
#if defined (CONFIG_ANX7150)
#define HDMI_VDD_CTL RK29_PIN6_PD3
#define HDMI_V33_CTL RK29_PIN6_PD3 //3.3V power control
#define HDMI_V5_CTL RK29_PIN4_PD0 //5V power control
int anx7150_io_init(void)
{
gpio_request(HDMI_VDD_CTL, "hdmi pwr ctl");
gpio_direction_output(HDMI_VDD_CTL, GPIO_HIGH);
gpio_request(HDMI_V33_CTL, "hdmi pwr ctl 0");
gpio_request(HDMI_V5_CTL, "hdmi pwr ctl 1");
gpio_direction_output(HDMI_V33_CTL, GPIO_HIGH);
gpio_direction_output(HDMI_V5_CTL, GPIO_HIGH);
//gpio_set_value(HDMI_VDD_CTL, GPIO_HIGH);
mdelay(10);
return 0;
@ -1361,7 +1267,7 @@ static int rk29_backlight_pwm_suspend(void)
return -1;
}
gpio_direction_output(PWM_GPIO, GPIO_LOW);
#ifdef LCD_DISP_ON_PIN
#if 0//def LCD_DISP_ON_PIN
gpio_direction_output(BL_EN_PIN, 0);
gpio_set_value(BL_EN_PIN, !BL_EN_VALUE);
#endif
@ -1373,7 +1279,7 @@ static int rk29_backlight_pwm_resume(void)
gpio_free(PWM_GPIO);
rk29_mux_api_set(PWM_MUX_NAME, PWM_MUX_MODE);
#ifdef LCD_DISP_ON_PIN
#if 0//def LCD_DISP_ON_PIN
msleep(30);
gpio_direction_output(BL_EN_PIN, 1);
gpio_set_value(BL_EN_PIN, BL_EN_VALUE);

528
arch/arm/mach-rk29/board-rk29sdk.c Executable file → Normal file
View File

@ -39,11 +39,13 @@
#include <mach/rk29_iomap.h>
#include <mach/board.h>
#include <mach/rk29_nand.h>
#include <mach/rk29_camera.h> /* ddl@rock-chips.com : camera support */
#include <media/soc_camera.h> /* ddl@rock-chips.com : camera support */
#include <mach/rk29_camera.h> /* ddl@rock-chips.com : camera support */
#include <mach/vpu_mem.h>
#include <mach/sram.h>
#include <mach/ddr.h>
#include <mach/cpufreq.h>
#include <mach/rk29_smc.h>
#include <linux/regulator/rk29-pwm-regulator.h>
#include <linux/regulator/machine.h>
@ -55,6 +57,9 @@
#include "devices.h"
#include "../../../drivers/input/touchscreen/xpt2046_cbn_ts.h"
#ifdef CONFIG_BU92747GUW_CIR
#include "../../../drivers/cir/bu92747guw_cir.h"
#endif
#ifdef CONFIG_VIDEO_RK29
/*---------------- Camera Sensor Macro Define Begin ------------------------*/
/*---------------- Camera Sensor Configuration Macro Begin ------------------------*/
@ -93,8 +98,8 @@
#else
#define SDRAM_SIZE SZ_512M
#endif
#define PMEM_GPU_SIZE SZ_64M
#define PMEM_UI_SIZE SZ_32M
#define PMEM_GPU_SIZE SZ_16M
#define PMEM_UI_SIZE (48 * SZ_1M) /* 1280x800: 64M 1024x768: 48M ... */
#define PMEM_VPU_SIZE SZ_64M
#define PMEM_CAM_SIZE PMEM_CAM_NECESSARY
#ifdef CONFIG_VIDEO_RK29_WORK_IPP
@ -153,15 +158,10 @@ struct rk29_nand_platform_data rk29_nand_data = {
.io_init = rk29_nand_io_init,
};
/*****************************************************************************************
* touch screen devices
* author: cf@rock-chips.com
*****************************************************************************************/
#define TOUCH_SCREEN_STANDBY_PIN INVALID_GPIO
#define TOUCH_SCREEN_STANDBY_VALUE GPIO_HIGH
#define TOUCH_SCREEN_DISPLAY_PIN INVALID_GPIO
#define TOUCH_SCREEN_DISPLAY_VALUE GPIO_HIGH
#ifdef CONFIG_FB_RK29
/*****************************************************************************************
* lcd devices
@ -370,11 +370,349 @@ struct platform_device rk29_device_dma_cpy = {
#endif
#if defined(CONFIG_RK_IRDA) || defined(CONFIG_BU92747GUW_CIR)
#define BU92747GUW_RESET_PIN RK29_PIN3_PD4// INVALID_GPIO //
#define BU92747GUW_RESET_MUX_NAME GPIO3D4_HOSTWRN_NAME//NULL //
#define BU92747GUW_RESET_MUX_MODE GPIO3H_GPIO3D4//NULL //
#define BU92747GUW_PWDN_PIN RK29_PIN3_PD3//RK29_PIN5_PA7 //
#define BU92747GUW_PWDN_MUX_NAME GPIO3D3_HOSTRDN_NAME//GPIO5A7_HSADCDATA2_NAME //
#define BU92747GUW_PWDN_MUX_MODE GPIO3H_GPIO3D3//GPIO5L_GPIO5A7 //
static int bu92747guw_io_init(void)
{
int ret;
//reset pin
if(BU92747GUW_RESET_MUX_NAME != NULL)
{
rk29_mux_api_set(BU92747GUW_RESET_MUX_NAME, BU92747GUW_RESET_MUX_MODE);
}
ret = gpio_request(BU92747GUW_RESET_PIN, NULL);
if(ret != 0)
{
gpio_free(BU92747GUW_RESET_PIN);
printk(">>>>>> BU92747GUW_RESET_PIN gpio_request err \n ");
}
gpio_direction_output(BU92747GUW_RESET_PIN, GPIO_HIGH);
//power down pin
if(BU92747GUW_PWDN_MUX_NAME != NULL)
{
rk29_mux_api_set(BU92747GUW_PWDN_MUX_NAME, BU92747GUW_PWDN_MUX_MODE);
}
ret = gpio_request(BU92747GUW_PWDN_PIN, NULL);
if(ret != 0)
{
gpio_free(BU92747GUW_PWDN_PIN);
printk(">>>>>> BU92747GUW_PWDN_PIN gpio_request err \n ");
}
//power down as default
gpio_direction_output(BU92747GUW_PWDN_PIN, GPIO_LOW);
return 0;
}
static int bu92747guw_io_deinit(void)
{
gpio_free(BU92747GUW_PWDN_PIN);
gpio_free(BU92747GUW_RESET_PIN);
return 0;
}
//power ctl func is share with irda and remote
static int nPowerOnCount = 0;
static DEFINE_MUTEX(bu92747_power_mutex);
//1---power on; 0---power off
static int bu92747guw_power_ctl(int enable)
{
printk("%s \n",__FUNCTION__);
mutex_lock(&bu92747_power_mutex);
if (enable) {
nPowerOnCount++;
if (nPowerOnCount == 1) {//power on first
//smc0_init(NULL);
gpio_set_value(BU92747GUW_PWDN_PIN, GPIO_HIGH);
gpio_set_value(BU92747GUW_RESET_PIN, GPIO_LOW);
mdelay(5);
gpio_set_value(BU92747GUW_RESET_PIN, GPIO_HIGH);
mdelay(5);
}
}
else {
nPowerOnCount--;
if (nPowerOnCount <= 0) {//power down final
nPowerOnCount = 0;
//smc0_exit();
gpio_set_value(BU92747GUW_PWDN_PIN, GPIO_LOW);
}
}
mutex_unlock(&bu92747_power_mutex);
return 0;
}
#endif
#ifdef CONFIG_RK_IRDA
#define IRDA_IRQ_PIN RK29_PIN5_PB2
#define IRDA_IRQ_MUX_NAME GPIO5B2_HSADCDATA5_NAME
#define IRDA_IRQ_MUX_MODE GPIO5L_GPIO5B2
int irda_iomux_init(void)
{
int ret = 0;
//irda irq pin
if(IRDA_IRQ_MUX_NAME != NULL)
{
rk29_mux_api_set(IRDA_IRQ_MUX_NAME, IRDA_IRQ_MUX_MODE);
}
ret = gpio_request(IRDA_IRQ_PIN, NULL);
if(ret != 0)
{
gpio_free(IRDA_IRQ_PIN);
printk(">>>>>> IRDA_IRQ_PIN gpio_request err \n ");
}
gpio_pull_updown(IRDA_IRQ_PIN, GPIO_HIGH);
gpio_direction_input(IRDA_IRQ_PIN);
return 0;
}
int irda_iomux_deinit(void)
{
gpio_free(IRDA_IRQ_PIN);
return 0;
}
static struct irda_info rk29_irda_info = {
.intr_pin = IRDA_IRQ_PIN,
.iomux_init = irda_iomux_init,
.iomux_deinit = irda_iomux_deinit,
.irda_pwr_ctl = bu92747guw_power_ctl,
};
static struct platform_device irda_device = {
#ifdef CONFIG_RK_IRDA_NET
.name = "rk_irda",
#else
.name = "bu92747_irda",
#endif
.id = -1,
.dev = {
.platform_data = &rk29_irda_info,
}
};
#endif
#ifdef CONFIG_BU92747GUW_CIR
#define BU92747_CIR_IRQ_PIN RK29_PIN5_PB0
#define CIR_IRQ_PIN_IOMUX_NAME GPIO5B0_HSADCDATA3_NAME
#define CIR_IRQ_PIN_IOMUX_VALUE GPIO5L_GPIO5B0
static int cir_iomux_init(void)
{
if (CIR_IRQ_PIN_IOMUX_NAME)
rk29_mux_api_set(CIR_IRQ_PIN_IOMUX_NAME, CIR_IRQ_PIN_IOMUX_VALUE);
rk29_mux_api_set(GPIO5A7_HSADCDATA2_NAME, GPIO5L_GPIO5A7);
return 0;
}
static struct bu92747guw_platform_data bu92747guw_pdata = {
.intr_pin = BU92747_CIR_IRQ_PIN,
.iomux_init = cir_iomux_init,
.iomux_deinit = NULL,
.cir_pwr_ctl = bu92747guw_power_ctl,
};
#endif
#ifdef CONFIG_RK29_NEWTON
struct rk29_newton_data rk29_newton_info = {
};
struct platform_device rk29_device_newton = {
.name = "rk29_newton",
.id = -1,
.dev = {
.platform_data = &rk29_newton_info,
}
};
#endif
#if defined (CONFIG_TOUCHSCREEN_FT5406)
#define TOUCH_RESET_PIN RK29_PIN6_PC3
#define TOUCH_INT_PIN RK29_PIN0_PA2
int ft5406_init_platform_hw(void)
{
printk("ft5406_init_platform_hw\n");
if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){
gpio_free(TOUCH_RESET_PIN);
printk("ft5406_init_platform_hw gpio_request error\n");
return -EIO;
}
if(gpio_request(TOUCH_INT_PIN,NULL) != 0){
gpio_free(TOUCH_INT_PIN);
printk("ift5406_init_platform_hw gpio_request error\n");
return -EIO;
}
gpio_direction_output(TOUCH_RESET_PIN, 0);
gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
mdelay(10);
gpio_direction_input(TOUCH_INT_PIN);
mdelay(10);
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
msleep(300);
return 0;
}
void ft5406_exit_platform_hw(void)
{
printk("ft5406_exit_platform_hw\n");
gpio_free(TOUCH_RESET_PIN);
gpio_free(TOUCH_INT_PIN);
}
int ft5406_platform_sleep(void)
{
printk("ft5406_platform_sleep\n");
gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
return 0;
}
int ft5406_platform_wakeup(void)
{
printk("ft5406_platform_wakeup\n");
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
msleep(300);
return 0;
}
struct ft5406_platform_data ft5406_info = {
.init_platform_hw= ft5406_init_platform_hw,
.exit_platform_hw= ft5406_exit_platform_hw,
.platform_sleep = ft5406_platform_sleep,
.platform_wakeup = ft5406_platform_wakeup,
};
#endif
#if defined(CONFIG_TOUCHSCREEN_GT819)
#define TOUCH_RESET_PIN RK29_PIN6_PC3
#define TOUCH_INT_PIN RK29_PIN0_PA2
int gt819_init_platform_hw(void)
{
printk("gt819_init_platform_hw\n");
if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){
gpio_free(TOUCH_RESET_PIN);
printk("gt819_init_platform_hw gpio_request error\n");
return -EIO;
}
if(gpio_request(TOUCH_INT_PIN,NULL) != 0){
gpio_free(TOUCH_INT_PIN);
printk("gt819_init_platform_hw gpio_request error\n");
return -EIO;
}
gpio_direction_output(TOUCH_RESET_PIN, 0);
gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
mdelay(10);
// gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
// mdelay(10);
// gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
gpio_direction_input(TOUCH_INT_PIN);
// mdelay(10);
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
msleep(300);
return 0;
}
void gt819_exit_platform_hw(void)
{
printk("gt819_exit_platform_hw\n");
gpio_free(TOUCH_RESET_PIN);
gpio_free(TOUCH_INT_PIN);
}
int gt819_platform_sleep(void)
{
printk("gt819_platform_sleep\n");
gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW);
return 0;
}
int gt819_platform_wakeup(void)
{
printk("gt819_platform_wakeup\n");
gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH);
//msleep(5);
//gpio_set_value(TOUCH_INT_PIN, GPIO_LOW);
//msleep(20);
//gpio_set_value(TOUCH_INT_PIN, GPIO_HIGH);
return 0;
}
struct goodix_platform_data goodix_info = {
.init_platform_hw= gt819_init_platform_hw,
.exit_platform_hw= gt819_exit_platform_hw,
.platform_sleep = gt819_platform_sleep,
.platform_wakeup = gt819_platform_wakeup,
};
#endif
#if defined (CONFIG_SND_SOC_CS42L52)
int cs42l52_init_platform_hw()
{
printk("cs42l52_init_platform_hw\n");
if(gpio_request(RK29_PIN6_PB6,NULL) != 0){
gpio_free(RK29_PIN6_PB6);
printk("cs42l52_init_platform_hw gpio_request error\n");
return -EIO;
}
gpio_direction_output(RK29_PIN6_PB6, 0);
gpio_set_value(RK29_PIN6_PB6,GPIO_HIGH);
return 0;
}
struct cs42l52_platform_data cs42l52_info = {
.init_platform_hw= cs42l52_init_platform_hw,
};
#endif
#if defined (CONFIG_BATTERY_BQ27541)
#define DC_CHECK_PIN RK29_PIN4_PA1
#define LI_LION_BAT_NUM 1
#define CHG_OK RK29_PIN4_PA3
#define BAT_LOW RK29_PIN4_PA2
static int bq27541_init_dc_check_pin(void){
if(gpio_request(DC_CHECK_PIN,"dc_check") != 0){
gpio_free(DC_CHECK_PIN);
printk("bq27541 init dc check pin request error\n");
return -EIO;
}
gpio_direction_input(DC_CHECK_PIN);
return 0;
}
struct bq27541_platform_data bq27541_info = {
.init_dc_check_pin = bq27541_init_dc_check_pin,
.dc_check_pin = DC_CHECK_PIN,
.bat_num = LI_LION_BAT_NUM,
.chgok_check_pin = CHG_OK,
.bat_check_pin = BAT_LOW,
};
#endif
static struct android_pmem_platform_data android_pmem_pdata = {
.name = "pmem",
.start = PMEM_UI_BASE,
.size = PMEM_UI_SIZE,
.no_allocator = 0,
.no_allocator = 1,
.cached = 1,
};
@ -478,6 +816,31 @@ static struct eeti_egalax_platform_data eeti_egalax_info = {
.disp_on_value = TOUCH_SCREEN_DISPLAY_VALUE,
};
#endif
#ifdef CONFIG_GS_KXTF9
#include <linux/kxtf9.h>
#define KXTF9_DEVICE_MAP 1
#define KXTF9_MAP_X (KXTF9_DEVICE_MAP-1)%2
#define KXTF9_MAP_Y KXTF9_DEVICE_MAP%2
#define KXTF9_NEG_X (KXTF9_DEVICE_MAP/2)%2
#define KXTF9_NEG_Y (KXTF9_DEVICE_MAP+1)/4
#define KXTF9_NEG_Z (KXTF9_DEVICE_MAP-1)/4
struct kxtf9_platform_data kxtf9_pdata = {
.min_interval = 1,
.poll_interval = 20,
.g_range = KXTF9_G_2G,
.axis_map_x = KXTF9_MAP_X,
.axis_map_y = KXTF9_MAP_Y,
.axis_map_z = 2,
.negate_x = KXTF9_NEG_X,
.negate_y = KXTF9_NEG_Y,
.negate_z = KXTF9_NEG_Z,
//.ctrl_regc_init = KXTF9_G_2G | ODR50F,
//.ctrl_regb_init = ENABLE,
};
#endif /* CONFIG_GS_KXTF9 */
/*MMA8452 gsensor*/
#if defined (CONFIG_GS_MMA8452)
#define MMA8452_INT_PIN RK29_PIN0_PA3
@ -793,6 +1156,22 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
.platform_data = &mpu3050_data,
},
#endif
#if defined (CONFIG_SND_SOC_CS42L52)
{
.type = "cs42l52",
.addr = 0x4A,
.flags = 0,
.platform_data = &cs42l52_info,
},
#endif
#if defined (CONFIG_RTC_M41T66)
{
.type = "rtc-M41T66",
.addr = 0x68,
.flags = 0,
.irq = RK29_PIN0_PA1,
},
#endif
};
#endif
#if defined (CONFIG_ANX7150)
@ -818,6 +1197,15 @@ static struct i2c_board_info __initdata board_i2c1_devices[] = {
.platform_data = &anx7150_data,
},
#endif
#ifdef CONFIG_BU92747GUW_CIR
{
.type ="bu92747_cir",
.addr = 0x77,
.flags =0,
.irq = BU92747_CIR_IRQ_PIN,
.platform_data = &bu92747guw_pdata,
},
#endif
};
#endif
@ -843,11 +1231,37 @@ static struct i2c_board_info __initdata board_i2c2_devices[] = {
.platform_data = &eeti_egalax_info,
},
#endif
#if defined (CONFIG_TOUCHSCREEN_GT819)
{
.type = "Goodix-TS",
.addr = 0x55,
.flags =0,
.irq =RK29_PIN0_PA2,
.platform_data = &goodix_info,
},
#endif
#if defined (CONFIG_TOUCHSCREEN_FT5406)
{
.type ="ft5x0x_ts",
.addr = 0x38, //0x70,
.flags =0,
.irq =RK29_PIN0_PA2, // support goodix tp detect, 20110706
.platform_data = &ft5406_info,
},
#endif
};
#endif
#ifdef CONFIG_I2C3_RK29
static struct i2c_board_info __initdata board_i2c3_devices[] = {
#if defined (CONFIG_BATTERY_BQ27541)
{
.type = "bq27541",
.addr = 0x55,
.flags = 0,
.platform_data = &bq27541_info,
},
#endif
};
#endif
@ -1384,6 +1798,76 @@ static struct platform_device rk29_device_keys = {
};
#endif
#ifdef CONFIG_LEDS_GPIO_PLATFORM
struct gpio_led rk29_leds[] = {
{
.name = "rk29_red_led",
.gpio = RK29_PIN4_PB2,
.default_trigger = "timer",
.active_low = 0,
.retain_state_suspended = 1,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
.name = "rk29_green_led",
.gpio = RK29_PIN4_PB1,
.default_trigger = "timer",
.active_low = 0,
.retain_state_suspended = 1,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
{
.name = "rk29_blue_led",
.gpio = RK29_PIN4_PB0,
.default_trigger = "timer",
.active_low = 0,
.retain_state_suspended = 1,
.default_state = LEDS_GPIO_DEFSTATE_OFF,
},
};
struct gpio_led_platform_data rk29_leds_pdata = {
.leds = &rk29_leds,
.num_leds = ARRAY_SIZE(rk29_leds),
};
struct platform_device rk29_device_gpio_leds = {
.name = "leds-gpio",
.id = -1,
.dev = {
.platform_data = &rk29_leds_pdata,
},
};
#endif
#ifdef CONFIG_LEDS_NEWTON_PWM
static struct led_newton_pwm rk29_pwm_leds[] = {
{
.name = "power_led",
.pwm_id = 1,
.pwm_gpio = RK29_PIN5_PD2,
.pwm_iomux_name = GPIO5D2_PWM1_UART1SIRIN_NAME,
.pwm_iomux_pwm = GPIO5H_PWM1,
.pwm_iomux_gpio = GPIO5H_GPIO5D2,
.freq = 1000,
.period = 255,
},
};
static struct led_newton_pwm_platform_data rk29_pwm_leds_pdata = {
.leds = &rk29_pwm_leds,
.num_leds = ARRAY_SIZE(rk29_pwm_leds),
};
static struct platform_device rk29_device_pwm_leds = {
.name = "leds_newton_pwm",
.id = -1,
.dev = {
.platform_data = &rk29_pwm_leds_pdata,
},
};
#endif
static void __init rk29_board_iomux_init(void)
{
#ifdef CONFIG_RK29_PWM_REGULATOR
@ -1445,6 +1929,9 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_KEYS_RK29
&rk29_device_keys,
#endif
#ifdef CONFIG_KEYS_RK29_NEWTON
&rk29_device_keys,
#endif
#ifdef CONFIG_SDMMC0_RK29
&rk29_device_sdmmc0,
#endif
@ -1475,6 +1962,9 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_BACKLIGHT_RK29_BL
&rk29_device_backlight,
#endif
#ifdef CONFIG_BACKLIGHT_RK29_NEWTON_BL
&rk29_device_backlight,
#endif
#ifdef CONFIG_RK29_VMAC
&rk29_device_vmac,
#endif
@ -1513,6 +2003,21 @@ static struct platform_device *devices[] __initdata = {
#ifdef CONFIG_VIDEO_RK29XX_VOUT
&rk29_v4l2_output_devce,
#endif
#ifdef CONFIG_RK29_NEWTON
&rk29_device_newton,
#endif
#ifdef CONFIG_RK_IRDA
&irda_device,
#endif
#ifdef CONFIG_LEDS_GPIO_PLATFORM
&rk29_device_gpio_leds,
#endif
#ifdef CONFIG_LEDS_NEWTON_PWM
&rk29_device_pwm_leds,
#endif
#ifdef CONFIG_SND_RK29_SOC_CS42L52
&rk29_cs42l52_device,
#endif
};
/*****************************************************************************************
@ -1794,6 +2299,11 @@ static void __init machine_rk29_board_init(void)
#endif
board_usb_detect_init(RK29_PIN0_PA0);
#if defined(CONFIG_RK_IRDA) || defined(CONFIG_BU92747GUW_CIR)
smc0_init(NULL);
bu92747guw_io_init();
#endif
}
static void __init machine_rk29_fixup(struct machine_desc *desc, struct tag *tags,

View File

@ -1,6 +1,6 @@
/* arch/arm/mach-rk29/clock.c
*
* Copyright (C) 2010 ROCKCHIP, Inc.
* Copyright (C) 2010, 2011 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@ -33,6 +33,7 @@
#include <mach/pmu.h>
#include <mach/sram.h>
#include <mach/board.h>
#include <mach/clock.h>
/* Clock flags */
@ -61,7 +62,8 @@ struct clk {
long (*round_rate)(struct clk *, unsigned long);
struct clk* (*get_parent)(struct clk *); /* get clk's parent from the hardware. default is clksel_get_parent if parents present */
int (*set_parent)(struct clk *, struct clk *); /* default is clksel_set_parent if parents present */
s32 usecount;
s16 usecount;
u16 notifier_count;
u8 gate_idx;
u8 pll_idx;
u8 clksel_con;
@ -73,6 +75,8 @@ struct clk {
struct clk **parents;
};
static void clk_notify(struct clk *clk, unsigned long msg,
unsigned long old_rate, unsigned long new_rate);
static int clk_enable_nolock(struct clk *clk);
static void clk_disable_nolock(struct clk *clk);
static int clk_set_rate_nolock(struct clk *clk, unsigned long rate);
@ -404,9 +408,9 @@ static unsigned long lpj_gpll;
static const struct arm_pll_set arm_pll[] = {
// rate = 24 * NF / (NR * NO)
// rate NR NF NO adiv hdiv pdiv
ARM_PLL(1200, 1, 50, 1, 21, 21, 81),
ARM_PLL(1176, 2, 98, 1, 21, 21, 81),
ARM_PLL(1104, 1, 46, 1, 21, 21, 81),
ARM_PLL(1200, 1, 50, 1, 31, 21, 81),
ARM_PLL(1176, 2, 98, 1, 31, 21, 81),
ARM_PLL(1104, 1, 46, 1, 31, 21, 81),
ARM_PLL(1008, 1, 42, 1, 21, 21, 81),
ARM_PLL( 912, 1, 38, 1, 21, 21, 81),
ARM_PLL( 888, 2, 74, 1, 21, 21, 81),
@ -2220,13 +2224,16 @@ static int clk_enable_nolock(struct clk *clk)
return ret;
}
if (clk->mode) {
if (clk->notifier_count)
clk_notify(clk, CLK_PRE_ENABLE, clk->rate, clk->rate);
if (clk->mode)
ret = clk->mode(clk, 1);
if (ret) {
if (clk->parent)
clk_disable_nolock(clk->parent);
return ret;
}
if (clk->notifier_count)
clk_notify(clk, ret ? CLK_ABORT_ENABLE : CLK_POST_ENABLE, clk->rate, clk->rate);
if (ret) {
if (clk->parent)
clk_disable_nolock(clk->parent);
return ret;
}
pr_debug("%s enabled\n", clk->name);
}
@ -2259,10 +2266,15 @@ static void clk_disable_nolock(struct clk *clk)
}
if (--clk->usecount == 0) {
int ret = 0;
if (clk->notifier_count)
clk_notify(clk, CLK_PRE_DISABLE, clk->rate, clk->rate);
if (clk->mode)
clk->mode(clk, 0);
ret = clk->mode(clk, 0);
if (clk->notifier_count)
clk_notify(clk, ret ? CLK_ABORT_DISABLE : CLK_POST_DISABLE, clk->rate, clk->rate);
pr_debug("%s disabled\n", clk->name);
if (clk->parent)
if (ret == 0 && clk->parent)
clk_disable_nolock(clk->parent);
}
}
@ -2332,6 +2344,7 @@ static void __clk_recalc(struct clk *clk)
static int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
{
int ret;
unsigned long old_rate;
if (rate == clk->rate)
return 0;
@ -2344,6 +2357,10 @@ static int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
if (!clk->set_rate)
return -EINVAL;
old_rate = clk->rate;
if (clk->notifier_count)
clk_notify(clk, CLK_PRE_RATE_CHANGE, old_rate, rate);
ret = clk->set_rate(clk, rate);
if (ret == 0) {
@ -2351,6 +2368,9 @@ static int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
__propagate_rate(clk);
}
if (clk->notifier_count)
clk_notify(clk, ret ? CLK_ABORT_RATE_CHANGE : CLK_POST_RATE_CHANGE, old_rate, clk->rate);
return ret;
}
@ -2634,7 +2654,6 @@ static void __init clk_enable_init_clocks(void)
clk_enable_nolock(&clk_dma1);
clk_enable_nolock(&clk_emem);
clk_enable_nolock(&clk_intmem);
clk_enable_nolock(&clk_ddr);
clk_enable_nolock(&clk_debug);
clk_enable_nolock(&clk_tpiu);
clk_enable_nolock(&clk_jtag);
@ -2695,7 +2714,7 @@ void __init rk29_clock_init2(enum periph_pll ppll_rate, enum codec_pll cpll_rate
printk(KERN_INFO "Clocking rate (apll/dpll/cpll/gpll/core/aclk_cpu/hclk_cpu/pclk_cpu/aclk_periph/hclk_periph/pclk_periph): %ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld/%ld MHz",
arm_pll_clk.rate / MHZ, ddr_pll_clk.rate / MHZ, codec_pll_clk.rate / MHZ, general_pll_clk.rate / MHZ, clk_core.rate / MHZ,
aclk_cpu.rate / MHZ, hclk_cpu.rate / MHZ, pclk_cpu.rate / MHZ, aclk_periph.rate / MHZ, hclk_periph.rate / MHZ, pclk_periph.rate / MHZ);
printk(KERN_CONT " (20110812)\n");
printk(KERN_CONT " (20110909)\n");
preset_lpj = loops_per_jiffy;
}
@ -2769,6 +2788,8 @@ static void dump_clock(struct seq_file *s, struct clk *clk, int deep)
case CRU_GENERAL_MODE_SLOW27: seq_printf(s, "slow27 "); break;
}
if (cru_readl(CRU_GPLL_CON) & PLL_BYPASS) seq_printf(s, "bypass ");
} else if (clk == &clk_ddr) {
rate = clk->recalc(clk);
}
if (rate >= MHZ) {
@ -2877,3 +2898,183 @@ static int __init clk_proc_init(void)
late_initcall(clk_proc_init);
#endif /* CONFIG_PROC_FS */
/* Clk notifier implementation */
/**
* struct clk_notifier - associate a clk with a notifier
* @clk: struct clk * to associate the notifier with
* @notifier_head: a raw_notifier_head for this clk
* @node: linked list pointers
*
* A list of struct clk_notifier is maintained by the notifier code.
* An entry is created whenever code registers the first notifier on a
* particular @clk. Future notifiers on that @clk are added to the
* @notifier_head.
*/
struct clk_notifier {
struct clk *clk;
struct raw_notifier_head notifier_head;
struct list_head node;
};
static LIST_HEAD(clk_notifier_list);
/**
* _clk_free_notifier_chain - safely remove struct clk_notifier
* @cn: struct clk_notifier *
*
* Removes the struct clk_notifier @cn from the clk_notifier_list and
* frees it.
*/
static void _clk_free_notifier_chain(struct clk_notifier *cn)
{
list_del(&cn->node);
kfree(cn);
}
/**
* clk_notify - call clk notifier chain
* @clk: struct clk * that is changing rate
* @msg: clk notifier type (i.e., CLK_POST_RATE_CHANGE; see mach/clock.h)
* @old_rate: old rate
* @new_rate: new rate
*
* Triggers a notifier call chain on the post-clk-rate-change notifier
* for clock 'clk'. Passes a pointer to the struct clk and the
* previous and current rates to the notifier callback. Intended to be
* called by internal clock code only. No return value.
*/
static void clk_notify(struct clk *clk, unsigned long msg,
unsigned long old_rate, unsigned long new_rate)
{
struct clk_notifier *cn;
struct clk_notifier_data cnd;
cnd.clk = clk;
cnd.old_rate = old_rate;
cnd.new_rate = new_rate;
UNLOCK();
list_for_each_entry(cn, &clk_notifier_list, node) {
if (cn->clk == clk) {
pr_debug("%s msg %lu rate %lu -> %lu\n", clk->name, msg, old_rate, new_rate);
raw_notifier_call_chain(&cn->notifier_head, msg, &cnd);
break;
}
}
LOCK();
}
/**
* clk_notifier_register - add a clock parameter change notifier
* @clk: struct clk * to watch
* @nb: struct notifier_block * with callback info
*
* Request notification for changes to the clock 'clk'. This uses a
* blocking notifier. Callback code must not call into the clock
* framework, as clocks_mutex is held. Pre-notifier callbacks will be
* passed the previous and new rate of the clock.
*
* clk_notifier_register() must be called from process
* context. Returns -EINVAL if called with null arguments, -ENOMEM
* upon allocation failure; otherwise, passes along the return value
* of blocking_notifier_chain_register().
*/
int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
{
struct clk_notifier *cn = NULL, *cn_new = NULL;
int r;
struct clk *clkp;
if (!clk || !nb)
return -EINVAL;
mutex_lock(&clocks_mutex);
list_for_each_entry(cn, &clk_notifier_list, node)
if (cn->clk == clk)
break;
if (cn->clk != clk) {
cn_new = kzalloc(sizeof(struct clk_notifier), GFP_KERNEL);
if (!cn_new) {
r = -ENOMEM;
goto cnr_out;
};
cn_new->clk = clk;
RAW_INIT_NOTIFIER_HEAD(&cn_new->notifier_head);
list_add(&cn_new->node, &clk_notifier_list);
cn = cn_new;
}
r = raw_notifier_chain_register(&cn->notifier_head, nb);
if (!IS_ERR_VALUE(r)) {
clkp = clk;
do {
clkp->notifier_count++;
} while ((clkp = clkp->parent));
} else {
if (cn_new)
_clk_free_notifier_chain(cn);
}
cnr_out:
mutex_unlock(&clocks_mutex);
return r;
}
EXPORT_SYMBOL(clk_notifier_register);
/**
* clk_notifier_unregister - remove a clock change notifier
* @clk: struct clk *
* @nb: struct notifier_block * with callback info
*
* Request no further notification for changes to clock 'clk'.
* Returns -EINVAL if called with null arguments; otherwise, passes
* along the return value of blocking_notifier_chain_unregister().
*/
int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
{
struct clk_notifier *cn = NULL;
struct clk *clkp;
int r = -EINVAL;
if (!clk || !nb)
return -EINVAL;
mutex_lock(&clocks_mutex);
list_for_each_entry(cn, &clk_notifier_list, node)
if (cn->clk == clk)
break;
if (cn->clk != clk) {
r = -ENOENT;
goto cnu_out;
};
r = raw_notifier_chain_unregister(&cn->notifier_head, nb);
if (!IS_ERR_VALUE(r)) {
clkp = clk;
do {
clkp->notifier_count--;
} while ((clkp = clkp->parent));
}
/*
* XXX ugh, layering violation. There should be some
* support in the notifier code for this.
*/
if (!cn->notifier_head.head)
_clk_free_notifier_chain(cn);
cnu_out:
mutex_unlock(&clocks_mutex);
return r;
}
EXPORT_SYMBOL(clk_notifier_unregister);

View File

@ -1,6 +1,6 @@
/* arch/arm/mach-rk2818/cpufreq.c
/* arch/arm/mach-rk29/cpufreq.c
*
* Copyright (C) 2010 ROCKCHIP, Inc.
* Copyright (C) 2010, 2011 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@ -13,11 +13,6 @@
*
*/
#ifdef CONFIG_CPU_FREQ_DEBUG
#define DEBUG
#endif
#define pr_fmt(fmt) "%s: " fmt, __func__
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/err.h>
@ -27,11 +22,11 @@
#include <linux/suspend.h>
#include <linux/tick.h>
#include <linux/workqueue.h>
#include <mach/clock.h>
#include <mach/cpufreq.h>
#include <../../../drivers/video/rk29_fb.h>
#define MHZ (1000*1000)
#define KHZ 1000
static int no_cpufreq_access;
@ -51,6 +46,7 @@ static struct cpufreq_frequency_table default_freq_table[] = {
static struct cpufreq_frequency_table *freq_table = default_freq_table;
static struct clk *arm_clk;
static struct clk *ddr_clk;
static unsigned long ddr_max_rate;
static DEFINE_MUTEX(mutex);
#ifdef CONFIG_REGULATOR
@ -59,23 +55,22 @@ static int vcore_uV;
#define CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
#endif
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
static struct workqueue_struct *wq;
static void rk29_cpufreq_work_func(struct work_struct *work);
static DECLARE_DELAYED_WORK(rk29_cpufreq_work, rk29_cpufreq_work_func);
#define WORK_DELAY HZ
static int limit = 1;
module_param(limit, int, 0644);
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
static bool limit = true;
module_param(limit, bool, 0644);
#define LIMIT_SECS 30
static int limit_secs = LIMIT_SECS;
static int limit_secs = 30;
module_param(limit_secs, int, 0644);
static int limit_secs_1200 = 6;
module_param(limit_secs_1200, int, 0644);
static int limit_temp;
module_param(limit_temp, int, 0444);
#define LIMIT_AVG_VOLTAGE 1225000 /* vU */
#define LIMIT_AVG_VOLTAGE 1200000 /* vU */
#else /* !CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP */
#define LIMIT_AVG_VOLTAGE 1400000 /* vU */
#endif /* CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP */
@ -87,19 +82,11 @@ enum {
};
static uint debug_mask = DEBUG_CHANGE;
module_param(debug_mask, uint, 0644);
#define dprintk(mask, fmt, ...) do { if (mask & debug_mask) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0)
#define dprintk(mask, fmt, ...) do { if (mask & debug_mask) printk(KERN_DEBUG "cpufreq: " fmt, ##__VA_ARGS__); } while (0)
#define LIMIT_AVG_FREQ (816 * KHZ) /* kHz */
#define LIMIT_AVG_FREQ (816 * 1000) /* kHz */
static unsigned int limit_avg_freq = LIMIT_AVG_FREQ;
static int rk29_cpufreq_set_limit_avg_freq(const char *val, struct kernel_param *kp)
{
int err = param_set_uint(val, kp);
if (!err) {
board_update_cpufreq_table(freq_table);
}
return err;
}
module_param_call(limit_avg_freq, rk29_cpufreq_set_limit_avg_freq, param_get_uint, &limit_avg_freq, 0644);
module_param(limit_avg_freq, uint, 0444);
static int limit_avg_index = -1;
@ -114,15 +101,24 @@ static int rk29_cpufreq_set_limit_avg_voltage(const char *val, struct kernel_par
}
module_param_call(limit_avg_voltage, rk29_cpufreq_set_limit_avg_voltage, param_get_uint, &limit_avg_voltage, 0644);
static bool limit_fb1_is_on;
static bool limit_hdmi_is_on;
static bool aclk_limit(void) { return limit_hdmi_is_on && limit_fb1_is_on; }
#define CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
static bool limit_fb1_enabled;
static bool limit_hdmi_enabled;
static inline bool aclk_limit(void) { return limit_hdmi_enabled && limit_fb1_enabled; }
module_param(limit_fb1_enabled, bool, 0644);
module_param(limit_hdmi_enabled, bool, 0644);
#else
static inline bool aclk_limit(void) { return false; }
#endif
#if defined(CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP) || defined(CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP)
static unsigned int limit_max_freq;
static int limit_index_816 = -1;
static unsigned int limit_freq_816;
static int limit_index_1008 = -1;
module_param(limit_fb1_is_on, bool, 0644);
module_param(limit_hdmi_is_on, bool, 0644);
module_param(limit_index_816, int, 0444);
module_param(limit_index_1008, int, 0444);
static unsigned int limit_freq_1008;
#endif
static bool rk29_cpufreq_is_ondemand_policy(struct cpufreq_policy *policy)
{
@ -138,23 +134,34 @@ static void board_do_update_cpufreq_table(struct cpufreq_frequency_table *table)
limit_avg_freq = 0;
limit_avg_index = -1;
#if defined(CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP) || defined(CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP)
limit_max_freq = 0;
limit_index_816 = -1;
limit_freq_816 = 0;
limit_index_1008 = -1;
limit_freq_1008 = 0;
#endif
for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
table[i].frequency = clk_round_rate(arm_clk, table[i].frequency * KHZ) / KHZ;
table[i].frequency = clk_round_rate(arm_clk, table[i].frequency * 1000) / 1000;
if (table[i].index <= limit_avg_voltage && limit_avg_freq < table[i].frequency) {
limit_avg_freq = table[i].frequency;
limit_avg_index = i;
}
if (table[i].frequency <= 816 * KHZ &&
#if defined(CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP) || defined(CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP)
if (limit_max_freq < table[i].frequency)
limit_max_freq = table[i].frequency;
if (table[i].frequency <= 816000 &&
(limit_index_816 < 0 ||
(limit_index_816 >= 0 && table[limit_index_816].frequency < table[i].frequency)))
limit_index_816 = i;
if (table[i].frequency <= 1008 * KHZ &&
if (table[i].frequency <= 1008000 &&
(limit_index_1008 < 0 ||
(limit_index_1008 >= 0 && table[limit_index_1008].frequency < table[i].frequency)))
(limit_index_1008 >= 0 && table[limit_index_1008].frequency < table[i].frequency))) {
limit_index_1008 = i;
limit_freq_1008 = table[i].frequency;
}
#endif
}
if (!limit_avg_freq)
@ -178,6 +185,25 @@ static int rk29_cpufreq_verify(struct cpufreq_policy *policy)
}
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
static bool limit_vpu_enabled;
static bool limit_gpu_enabled;
static bool limit_gpu_high;
module_param(limit_vpu_enabled, bool, 0644);
module_param(limit_gpu_enabled, bool, 0644);
module_param(limit_gpu_high, bool, 0644);
static struct clk* aclk_vepu;
static struct clk* clk_gpu;
#define GPU_LOW_RATE (300 * MHZ)
static unsigned long limit_gpu_low_rate = GPU_LOW_RATE;
module_param(limit_gpu_low_rate, ulong, 0644);
#define TEMP_COEFF_IDLE -1000
#define TEMP_COEFF_408 -325
#define TEMP_COEFF_624 -202
#define TEMP_COEFF_816 -78
#define TEMP_COEFF_1008 325
#define TEMP_COEFF_1200 1300
#define WORK_DELAY HZ
static void rk29_cpufreq_limit_by_temp(struct cpufreq_policy *policy, unsigned int relation, int *index)
{
int c, ms;
@ -186,10 +212,16 @@ static void rk29_cpufreq_limit_by_temp(struct cpufreq_policy *policy, unsigned i
cputime64_t wall;
u64 idle_time_us;
static u64 last_idle_time_us;
int idle;
unsigned int cur = policy->cur;
int overheat_temp_1200, overheat_temp;
int temp;
int target_index;
unsigned int target_freq;
bool overheat;
if (!limit || !wq || !rk29_cpufreq_is_ondemand_policy(policy) ||
(limit_avg_index < 0) || (relation & MASK_FURTHER_CPUFREQ)) {
if (!limit || !rk29_cpufreq_is_ondemand_policy(policy) ||
(limit_index_816 < 0) || (relation & MASK_FURTHER_CPUFREQ)) {
limit_temp = 0;
last.tv64 = 0;
return;
@ -203,50 +235,71 @@ static void rk29_cpufreq_limit_by_temp(struct cpufreq_policy *policy, unsigned i
return;
}
limit_temp -= idle_time_us - last_idle_time_us; // -1000
dprintk(DEBUG_TEMP, "idle %lld us (%lld - %lld)\n", idle_time_us - last_idle_time_us, idle_time_us, last_idle_time_us);
last_idle_time_us = idle_time_us;
temp = limit_temp;
idle = idle_time_us - last_idle_time_us;
if (idle) {
temp -= idle; // -1000
last_idle_time_us = idle_time_us;
}
ms = div_u64(ktime_us_delta(now, last), 1000);
dprintk(DEBUG_TEMP, "%d kHz (%d uV) elapsed %d ms (%lld - %lld)\n", cur, vcore_uV, ms, now.tv64, last.tv64);
dprintk(DEBUG_TEMP, "%d kHz (%d uV) elapsed %d ms idle %d us\n", cur, vcore_uV, ms, idle);
last = now;
if (cur <= 408 * 1000)
c = -325;
c = TEMP_COEFF_408;
else if (cur <= 624 * 1000)
c = -202;
else if (cur <= limit_avg_freq)
c = -78;
c = TEMP_COEFF_624;
else if (cur <= 816 * 1000)
c = TEMP_COEFF_816;
else if (cur <= 1008 * 1000)
c = TEMP_COEFF_1008;
else
c = 325;
limit_temp += c * ms;
c = TEMP_COEFF_1200;
temp += c * ms;
if (limit_temp < 0)
limit_temp = 0;
if (limit_temp > 325 * limit_secs * 1000 && freq_table[*index].frequency > limit_avg_freq)
*index = limit_avg_index;
dprintk(DEBUG_TEMP, "c %d temp %d (%s) index %d", c, limit_temp, limit_temp > 325 * limit_secs * 1000 ? "overheat" : "normal", *index);
if (temp < 0)
temp = 0;
target_index = *index;
target_freq = freq_table[target_index].frequency;
overheat_temp = TEMP_COEFF_1008 * limit_secs * MSEC_PER_SEC;
overheat_temp_1200 = TEMP_COEFF_1200 * limit_secs_1200 * MSEC_PER_SEC;
overheat = false;
if (temp >= overheat_temp && target_freq > limit_freq_816) {
target_index = limit_index_816;
overheat = true;
} else if (target_freq > limit_freq_1008 && limit_freq_1008 > limit_freq_816 &&
temp >= overheat_temp_1200 && temp < overheat_temp) {
target_index = limit_index_1008;
overheat = true;
} else if (target_freq > 1008000 && (limit_vpu_enabled || (limit_gpu_enabled && limit_gpu_high))) {
target_index = limit_index_1008;
}
dprintk(DEBUG_TEMP, "%d kHz c %d temp %d (%s) selected %d kHz\n", target_freq, c, temp, overheat ? "overheat" : "normal", freq_table[target_index].frequency);
limit_temp = temp;
*index = target_index;
}
#else
#define rk29_cpufreq_limit_by_temp(...) do {} while (0)
#endif
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
static void rk29_cpufreq_limit_by_disp(int *index)
{
unsigned long ddr_rate;
unsigned int frequency = freq_table[*index].frequency;
int new_index = -1;
if (!ddr_clk || !aclk_limit())
if (!aclk_limit())
return;
ddr_rate = clk_get_rate(ddr_clk);
if (ddr_rate < 492 * MHZ) {
if (limit_index_816 >= 0 && frequency > 816 * KHZ)
if (ddr_max_rate < 492 * MHZ) {
if (limit_index_816 >= 0 && frequency > 816000)
new_index = limit_index_816;
} else {
if (limit_index_1008 >= 0 && frequency > 1008 * KHZ)
if (limit_index_1008 >= 0 && frequency > 1008000)
new_index = limit_index_1008;
}
@ -255,6 +308,9 @@ static void rk29_cpufreq_limit_by_disp(int *index)
*index = new_index;
}
}
#else
#define rk29_cpufreq_limit_by_disp(...) do {} while (0)
#endif
static int rk29_cpufreq_do_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation)
{
@ -264,6 +320,7 @@ static int rk29_cpufreq_do_target(struct cpufreq_policy *policy, unsigned int ta
const struct cpufreq_frequency_table *freq;
int err = 0;
bool force = relation & CPUFREQ_FORCE_CHANGE;
unsigned long new_arm_rate;
relation &= ~CPUFREQ_FORCE_CHANGE;
@ -300,7 +357,8 @@ static int rk29_cpufreq_do_target(struct cpufreq_policy *policy, unsigned int ta
freqs.new = freq->frequency;
freqs.cpu = 0;
new_vcore_uV = freq->index;
dprintk(DEBUG_CHANGE, "%d Hz r %d(%c) selected %d Hz (%d uV)\n",
new_arm_rate = freqs.new * 1000;
dprintk(DEBUG_CHANGE, "%d kHz r %d(%c) selected %d kHz (%d uV)\n",
target_freq, relation, relation & CPUFREQ_RELATION_H ? 'H' : 'L',
freq->frequency, new_vcore_uV);
@ -319,9 +377,9 @@ static int rk29_cpufreq_do_target(struct cpufreq_policy *policy, unsigned int ta
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
dprintk(DEBUG_CHANGE, "pre change\n");
clk_set_rate(arm_clk, freqs.new * KHZ + aclk_limit());
clk_set_rate(arm_clk, freqs.new * 1000 + aclk_limit());
dprintk(DEBUG_CHANGE, "post change\n");
freqs.new = clk_get_rate(arm_clk) / KHZ;
freqs.new = clk_get_rate(arm_clk) / 1000;
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
#ifdef CONFIG_REGULATOR
@ -335,7 +393,7 @@ static int rk29_cpufreq_do_target(struct cpufreq_policy *policy, unsigned int ta
}
}
#endif
dprintk(DEBUG_CHANGE, "ok, got %d kHz\n", freqs.new);
dprintk(DEBUG_CHANGE, "got %d kHz\n", freqs.new);
return err;
}
@ -355,26 +413,23 @@ static int rk29_cpufreq_target(struct cpufreq_policy *policy, unsigned int targe
}
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
static void rk29_cpufreq_limit_by_temp_work_func(struct work_struct *work);
static DECLARE_DELAYED_WORK(rk29_cpufreq_limit_by_temp_work, rk29_cpufreq_limit_by_temp_work_func);
static int rk29_cpufreq_notifier_policy(struct notifier_block *nb,
unsigned long val, void *data)
{
struct cpufreq_policy *policy = data;
bool is_ondemand;
if (val != CPUFREQ_NOTIFY)
return 0;
is_ondemand = rk29_cpufreq_is_ondemand_policy(policy);
if (!wq && is_ondemand) {
dprintk(DEBUG_TEMP, "start wq\n");
wq = create_singlethread_workqueue("rk29_cpufreqd");
if (wq)
queue_delayed_work(wq, &rk29_cpufreq_work, WORK_DELAY);
} else if (wq && !is_ondemand) {
dprintk(DEBUG_TEMP, "stop wq\n");
cancel_delayed_work(&rk29_cpufreq_work);
destroy_workqueue(wq);
wq = NULL;
if (rk29_cpufreq_is_ondemand_policy(policy)) {
dprintk(DEBUG_TEMP, "queue work\n");
queue_delayed_work(wq, &rk29_cpufreq_limit_by_temp_work, WORK_DELAY);
} else {
dprintk(DEBUG_TEMP, "cancel work\n");
cancel_delayed_work(&rk29_cpufreq_limit_by_temp_work);
}
return 0;
@ -384,16 +439,140 @@ static struct notifier_block notifier_policy_block = {
.notifier_call = rk29_cpufreq_notifier_policy
};
static void rk29_cpufreq_work_func(struct work_struct *work)
static void rk29_cpufreq_limit_by_temp_work_func(struct work_struct *work)
{
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
if (policy) {
dprintk(DEBUG_TEMP, "check %d kHz\n", policy->cur);
cpufreq_driver_target(policy, policy->cur, CPUFREQ_RELATION_L);
cpufreq_cpu_put(policy);
}
queue_delayed_work(wq, &rk29_cpufreq_work, WORK_DELAY);
queue_delayed_work(wq, &rk29_cpufreq_limit_by_temp_work, WORK_DELAY);
}
static int rk29_cpufreq_aclk_vepu_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
switch (event) {
case CLK_PRE_ENABLE:
limit_vpu_enabled = true;
break;
case CLK_ABORT_ENABLE:
case CLK_POST_DISABLE:
limit_vpu_enabled = false;
break;
default:
return NOTIFY_OK;
}
if (limit_vpu_enabled) {
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
if (policy) {
dprintk(DEBUG_TEMP, "vpu on\n");
cpufreq_driver_target(policy, policy->cur, CPUFREQ_RELATION_L);
cpufreq_cpu_put(policy);
}
}
return NOTIFY_OK;
}
static struct notifier_block rk29_cpufreq_aclk_vepu_notifier = {
.notifier_call = rk29_cpufreq_aclk_vepu_notifier_event,
};
static int rk29_cpufreq_clk_gpu_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct clk_notifier_data *cnd = ptr;
bool gpu_high_old = limit_gpu_enabled && limit_gpu_high;
bool gpu_high;
switch (event) {
case CLK_PRE_RATE_CHANGE:
if (cnd->new_rate > limit_gpu_low_rate)
limit_gpu_high = true;
break;
case CLK_ABORT_RATE_CHANGE:
if (cnd->new_rate > limit_gpu_low_rate && cnd->old_rate <= limit_gpu_low_rate)
limit_gpu_high = false;
break;
case CLK_POST_RATE_CHANGE:
if (cnd->new_rate <= limit_gpu_low_rate)
limit_gpu_high = false;
break;
case CLK_PRE_ENABLE:
limit_gpu_enabled = true;
break;
case CLK_ABORT_ENABLE:
case CLK_POST_DISABLE:
limit_gpu_enabled = false;
break;
default:
return NOTIFY_OK;
}
gpu_high = limit_gpu_enabled && limit_gpu_high;
if (gpu_high_old != gpu_high && gpu_high) {
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
if (policy) {
dprintk(DEBUG_TEMP, "gpu high\n");
cpufreq_driver_target(policy, policy->cur, CPUFREQ_RELATION_L);
cpufreq_cpu_put(policy);
}
}
return NOTIFY_OK;
}
static struct notifier_block rk29_cpufreq_clk_gpu_notifier = {
.notifier_call = rk29_cpufreq_clk_gpu_notifier_event,
};
#endif
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
static void rk29_cpufreq_limit_by_disp_work_func(struct work_struct *work)
{
struct cpufreq_policy *policy;
policy = cpufreq_cpu_get(0);
if (policy) {
cpufreq_driver_target(policy, policy->cur, CPUFREQ_RELATION_L | CPUFREQ_FORCE_CHANGE);
cpufreq_cpu_put(policy);
}
}
static DECLARE_WORK(rk29_cpufreq_limit_by_disp_work, rk29_cpufreq_limit_by_disp_work_func);
static int rk29_cpufreq_fb_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
switch (event) {
case RK29FB_EVENT_HDMI_ON:
limit_hdmi_enabled = true;
break;
case RK29FB_EVENT_HDMI_OFF:
limit_hdmi_enabled = false;
break;
case RK29FB_EVENT_FB1_ON:
limit_fb1_enabled = true;
break;
case RK29FB_EVENT_FB1_OFF:
limit_fb1_enabled = false;
break;
}
dprintk(DEBUG_DISP, "event: %lu aclk_limit: %d\n", event, aclk_limit());
flush_work(&rk29_cpufreq_limit_by_disp_work);
queue_work(wq, &rk29_cpufreq_limit_by_disp_work);
return NOTIFY_OK;
}
static struct notifier_block rk29_cpufreq_fb_notifier = {
.notifier_call = rk29_cpufreq_fb_notifier_event,
};
#endif
static int rk29_cpufreq_init(struct cpufreq_policy *policy)
@ -404,15 +583,19 @@ static int rk29_cpufreq_init(struct cpufreq_policy *policy)
arm_clk = clk_get(NULL, "arm_pll");
if (IS_ERR(arm_clk)) {
int err = PTR_ERR(arm_clk);
pr_err("fail to get arm_pll clk: %d\n", err);
arm_clk = NULL;
return err;
}
ddr_clk = clk_get(NULL, "ddr");
if (IS_ERR(ddr_clk)) {
pr_err("fail to get ddr clk: %ld\n", PTR_ERR(ddr_clk));
int err = PTR_ERR(ddr_clk);
pr_err("fail to get ddr clk: %d\n", err);
ddr_clk = NULL;
return err;
}
ddr_max_rate = clk_get_rate(ddr_clk);
#ifdef CONFIG_REGULATOR
vcore = regulator_get(NULL, "vcore");
@ -425,37 +608,61 @@ static int rk29_cpufreq_init(struct cpufreq_policy *policy)
board_update_cpufreq_table(freq_table); /* force update frequency */
BUG_ON(cpufreq_frequency_table_cpuinfo(policy, freq_table));
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
policy->cur = clk_get_rate(arm_clk) / KHZ;
policy->cur = clk_get_rate(arm_clk) / 1000;
policy->cpuinfo.transition_latency = 40 * NSEC_PER_USEC; // make default sampling_rate to 40000
wq = create_singlethread_workqueue("rk29_cpufreqd");
if (!wq) {
pr_err("fail to create workqueue\n");
return -ENOMEM;
}
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
if (rk29_cpufreq_is_ondemand_policy(policy)) {
dprintk(DEBUG_TEMP, "start wq\n");
wq = create_singlethread_workqueue("rk29_cpufreqd");
if (wq)
queue_delayed_work(wq, &rk29_cpufreq_work, WORK_DELAY);
dprintk(DEBUG_TEMP, "queue work\n");
queue_delayed_work(wq, &rk29_cpufreq_limit_by_temp_work, WORK_DELAY);
}
cpufreq_register_notifier(&notifier_policy_block, CPUFREQ_POLICY_NOTIFIER);
if (limit_max_freq > 1008000) {
clk_gpu = clk_get(NULL, "gpu");
aclk_vepu = clk_get(NULL, "aclk_vepu");
clk_notifier_register(clk_gpu, &rk29_cpufreq_clk_gpu_notifier);
clk_notifier_register(aclk_vepu, &rk29_cpufreq_aclk_vepu_notifier);
}
#endif
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
rk29fb_register_notifier(&rk29_cpufreq_fb_notifier);
#endif
return 0;
}
static int rk29_cpufreq_exit(struct cpufreq_policy *policy)
{
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_DISP
rk29fb_unregister_notifier(&rk29_cpufreq_fb_notifier);
#endif
#ifdef CONFIG_RK29_CPU_FREQ_LIMIT_BY_TEMP
if (limit_max_freq > 1008000) {
clk_notifier_unregister(clk_gpu, &rk29_cpufreq_clk_gpu_notifier);
clk_notifier_unregister(aclk_vepu, &rk29_cpufreq_aclk_vepu_notifier);
clk_put(clk_gpu);
clk_put(aclk_vepu);
}
cpufreq_unregister_notifier(&notifier_policy_block, CPUFREQ_POLICY_NOTIFIER);
if (wq)
cancel_delayed_work(&rk29_cpufreq_limit_by_temp_work);
#endif
if (wq) {
dprintk(DEBUG_TEMP, "stop wq\n");
cancel_delayed_work(&rk29_cpufreq_work);
flush_workqueue(wq);
destroy_workqueue(wq);
wq = NULL;
}
#endif
#ifdef CONFIG_REGULATOR
if (vcore)
regulator_put(vcore);
#endif
clk_put(ddr_clk);
clk_put(arm_clk);
return 0;
}
@ -489,7 +696,7 @@ static int rk29_cpufreq_pm_notifier_event(struct notifier_block *this,
switch (event) {
case PM_SUSPEND_PREPARE:
ret = cpufreq_driver_target(policy, limit_avg_freq, DISABLE_FURTHER_CPUFREQ | CPUFREQ_RELATION_L);
ret = cpufreq_driver_target(policy, limit_avg_freq, DISABLE_FURTHER_CPUFREQ | CPUFREQ_RELATION_H);
if (ret < 0) {
ret = NOTIFY_BAD;
goto out;
@ -498,7 +705,7 @@ static int rk29_cpufreq_pm_notifier_event(struct notifier_block *this,
break;
case PM_POST_RESTORE:
case PM_POST_SUSPEND:
cpufreq_driver_target(policy, limit_avg_freq, ENABLE_FURTHER_CPUFREQ | CPUFREQ_RELATION_L);
cpufreq_driver_target(policy, limit_avg_freq, ENABLE_FURTHER_CPUFREQ | CPUFREQ_RELATION_H);
ret = NOTIFY_OK;
break;
}
@ -517,7 +724,7 @@ static int rk29_cpufreq_reboot_notifier_event(struct notifier_block *this,
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
if (policy) {
cpufreq_driver_target(policy, limit_avg_freq, DISABLE_FURTHER_CPUFREQ | CPUFREQ_RELATION_L);
cpufreq_driver_target(policy, limit_avg_freq, DISABLE_FURTHER_CPUFREQ | CPUFREQ_RELATION_H);
cpufreq_cpu_put(policy);
}
@ -528,45 +735,10 @@ static struct notifier_block rk29_cpufreq_reboot_notifier = {
.notifier_call = rk29_cpufreq_reboot_notifier_event,
};
static int rk29_cpufreq_fb_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
struct cpufreq_policy *policy;
switch (event) {
case RK29FB_EVENT_HDMI_ON:
limit_hdmi_is_on = true;
break;
case RK29FB_EVENT_HDMI_OFF:
limit_hdmi_is_on = false;
break;
case RK29FB_EVENT_FB1_ON:
limit_fb1_is_on = true;
break;
case RK29FB_EVENT_FB1_OFF:
limit_fb1_is_on = false;
break;
}
dprintk(DEBUG_DISP, "event: %lu aclk_limit: %d\n", event, aclk_limit());
policy = cpufreq_cpu_get(0);
if (policy) {
cpufreq_driver_target(policy, policy->cur, CPUFREQ_RELATION_L | CPUFREQ_FORCE_CHANGE);
cpufreq_cpu_put(policy);
}
return NOTIFY_OK;
}
static struct notifier_block rk29_cpufreq_fb_notifier = {
.notifier_call = rk29_cpufreq_fb_notifier_event,
};
static int __init rk29_cpufreq_register(void)
{
register_pm_notifier(&rk29_cpufreq_pm_notifier);
register_reboot_notifier(&rk29_cpufreq_reboot_notifier);
rk29fb_register_notifier(&rk29_cpufreq_fb_notifier);
return cpufreq_register_driver(&rk29_cpufreq_driver);
}

View File

@ -0,0 +1,155 @@
/* arch/arm/mach-rk29/ddrfreq.c
*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/module.h>
#include <mach/clock.h>
#include <mach/ddr.h>
#define MHZ (1000*1000)
enum {
DEBUG_CHANGE = 1U << 0,
DEBUG_EVENT = 1U << 1,
};
static uint debug_mask = DEBUG_CHANGE;
module_param(debug_mask, uint, 0644);
#define dprintk(mask, fmt, ...) do { if (mask & debug_mask) printk(KERN_DEBUG "ddrfreq: " fmt, ##__VA_ARGS__); } while (0)
static struct clk *clk_ddr;
static struct clk *ddr_pll_clk;
static struct clk *aclk_lcdc;
static bool ddr_pll_can_change;
static bool aclk_lcdc_disabled;
static bool disable_ddr_freq;
module_param(ddr_pll_can_change, bool, 0644);
module_param(aclk_lcdc_disabled, bool, 0644);
module_param(disable_ddr_freq, bool, 0644);
static unsigned long ddr_max_mhz;
static unsigned long ddr_min_mhz = 96;
static void rk29_ddrfreq_change_freq(void);
static int rk29_ddrfreq_set_ddr_mhz(const char *val, struct kernel_param *kp)
{
int err = param_set_uint(val, kp);
if (!err) {
rk29_ddrfreq_change_freq();
}
return err;
}
module_param_call(ddr_max_mhz, rk29_ddrfreq_set_ddr_mhz, param_get_uint, &ddr_max_mhz, 0644);
module_param_call(ddr_min_mhz, rk29_ddrfreq_set_ddr_mhz, param_get_uint, &ddr_min_mhz, 0644);
static DEFINE_SPINLOCK(ddr_lock);
static void rk29_ddrfreq_change_freq(void)
{
unsigned long ddr_rate, mhz;
if (disable_ddr_freq)
return;
ddr_rate = clk_get_rate(clk_ddr);
mhz = (ddr_pll_can_change && aclk_lcdc_disabled) ? ddr_min_mhz : ddr_max_mhz;
if ((mhz * MHZ) != ddr_rate) {
dprintk(DEBUG_CHANGE, "%lu -> %lu Hz\n", ddr_rate, mhz * MHZ);
ddr_change_freq(mhz);
dprintk(DEBUG_CHANGE, "got %lu Hz\n", clk_get_rate(clk_ddr));
}
}
static int rk29_ddrfreq_ddr_pll_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
spin_lock_bh(&ddr_lock);
switch (event) {
case CLK_PRE_ENABLE:
ddr_pll_can_change = false;
break;
case CLK_ABORT_ENABLE:
case CLK_POST_DISABLE:
ddr_pll_can_change = true;
break;
default:
goto out;
}
if (!disable_ddr_freq) {
dprintk(DEBUG_EVENT, "event: %lu ddr_pll_can_change: %d\n", event, ddr_pll_can_change);
rk29_ddrfreq_change_freq();
}
out:
spin_unlock_bh(&ddr_lock);
return NOTIFY_OK;
}
static struct notifier_block rk29_ddrfreq_ddr_pll_notifier = {
.notifier_call = rk29_ddrfreq_ddr_pll_notifier_event,
};
static int rk29_ddrfreq_aclk_lcdc_notifier_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
spin_lock_bh(&ddr_lock);
switch (event) {
case CLK_PRE_ENABLE:
aclk_lcdc_disabled = false;
break;
case CLK_ABORT_ENABLE:
case CLK_POST_DISABLE:
aclk_lcdc_disabled = true;
break;
default:
goto out;
}
if (!disable_ddr_freq) {
dprintk(DEBUG_EVENT, "event: %lu aclk_lcdc_disabled: %d\n", event, aclk_lcdc_disabled);
rk29_ddrfreq_change_freq();
}
out:
spin_unlock_bh(&ddr_lock);
return NOTIFY_OK;
}
static struct notifier_block rk29_ddrfreq_aclk_lcdc_notifier = {
.notifier_call = rk29_ddrfreq_aclk_lcdc_notifier_event,
};
static int __init rk29_ddrfreq_init(void)
{
clk_ddr = clk_get(NULL, "ddr");
if (IS_ERR(clk_ddr)) {
int err = PTR_ERR(clk_ddr);
pr_err("fail to get ddr clk: %d\n", err);
clk_ddr = NULL;
return err;
}
ddr_max_mhz = clk_get_rate(clk_ddr) / MHZ;
ddr_pll_clk = clk_get(NULL, "ddr_pll");
aclk_lcdc = clk_get(NULL, "aclk_lcdc");
clk_notifier_register(ddr_pll_clk, &rk29_ddrfreq_ddr_pll_notifier);
clk_notifier_register(aclk_lcdc, &rk29_ddrfreq_aclk_lcdc_notifier);
printk("ddrfreq: version 1.0\n");
return 0;
}
late_initcall(rk29_ddrfreq_init);

16
arch/arm/mach-rk29/gpio.c Normal file → Executable file
View File

@ -550,12 +550,22 @@ void __init rk29_gpio_init(void)
}
rk29_gpio_irq_setup();
}
__weak void rk29_setgpio_suspend_board(void)
{
}
__weak void rk29_setgpio_resume_board(void)
{
}
#ifdef CONFIG_PM
static int rk29_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
{
unsigned i;
rk29_setgpio_suspend_board();
for (i = 0; i < MAX_BANK; i++) {
struct rk29_gpio_chip *rk29_gpio = &rk29gpio_chip[i];
@ -572,7 +582,9 @@ static int rk29_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
static int rk29_gpio_resume(struct sys_device *dev)
{
unsigned i;
rk29_setgpio_resume_board();
for (i = 0; i < MAX_BANK; i++) {
struct rk29_gpio_chip *rk29_gpio = &rk29gpio_chip[i];

9
arch/arm/mach-rk29/include/mach/board.h Normal file → Executable file
View File

@ -143,6 +143,7 @@ struct rk29_sdmmc_platform_data {
int (*register_status_notify)(void (*callback)(int card_present, void *dev_id), void *dev_id);
int detect_irq;
int enable_sd_wakeup;
int write_prt;
};
struct rk29_i2c_platform_data {
int bus_num;
@ -164,7 +165,9 @@ struct bq27510_platform_data {
struct bq27541_platform_data {
int (*init_dc_check_pin)(void);
unsigned int dc_check_pin;
unsigned int dc_check_pin;
unsigned int bat_check_pin;
unsigned int chgok_check_pin;
unsigned int bat_num;
};
@ -304,6 +307,10 @@ struct laibao_platform_data {
int (*laibao_platform_sleep)(void);
int (*laibao_platform_wakeup)(void);
void (*exit_platform_hw)(void);
int lcd_disp_on_pin;
int disp_on_value;
int lcd_cs_pin;
int lcd_cs_value;
};
struct akm8975_platform_data {

View File

@ -0,0 +1,76 @@
/* arch/arm/mach-rk29/include/mach/clock.h
*
* Copyright (C) 2011 ROCKCHIP, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ASM_ARCH_RK29_CLOCK_H
#define __ASM_ARCH_RK29_CLOCK_H
/**
* struct clk_notifier_data - rate data to pass to the notifier callback
* @clk: struct clk * being changed
* @old_rate: previous rate of this clock
* @new_rate: new rate of this clock
*
* For a pre-notifier, old_rate is the clock's rate before this rate
* change, and new_rate is what the rate will be in the future. For a
* post-notifier, old_rate and new_rate are both set to the clock's
* current rate (this was done to optimize the implementation).
*/
struct clk_notifier_data {
struct clk *clk;
unsigned long old_rate;
unsigned long new_rate;
};
/*
* Clk notifier callback types
*
* Since the notifier is called with interrupts disabled, any actions
* taken by callbacks must be extremely fast and lightweight.
*
* CLK_PRE_RATE_CHANGE - called after all callbacks have approved the
* rate change, immediately before the clock rate is changed, to
* indicate that the rate change will proceed. Drivers must
* immediately terminate any operations that will be affected by
* the rate change. Callbacks must always return NOTIFY_DONE.
*
* CLK_ABORT_RATE_CHANGE: called if the rate change failed for some
* reason after CLK_PRE_RATE_CHANGE. In this case, all registered
* notifiers on the clock will be called with
* CLK_ABORT_RATE_CHANGE. Callbacks must always return
* NOTIFY_DONE.
*
* CLK_POST_RATE_CHANGE - called after the clock rate change has
* successfully completed. Callbacks must always return
* NOTIFY_DONE.
*
*/
#define CLK_PRE_RATE_CHANGE 1
#define CLK_POST_RATE_CHANGE 2
#define CLK_ABORT_RATE_CHANGE 3
#define CLK_PRE_ENABLE 4
#define CLK_POST_ENABLE 5
#define CLK_ABORT_ENABLE 6
#define CLK_PRE_DISABLE 7
#define CLK_POST_DISABLE 8
#define CLK_ABORT_DISABLE 9
struct notifier_block;
extern int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
extern int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
#endif

View File

@ -34,7 +34,7 @@ struct rk29_ipp_req {
*/
uint8_t store_clip_mode;
//deinterlace_enable 1:enable 0:disable
//deinterlace_enable 0:disable 1:enable 2:query
uint8_t deinterlace_enable;
//the sum of three paras should be 32,and single para should be less than 32
uint8_t deinterlace_para0;

View File

@ -471,21 +471,30 @@ int __sramdata crumode;
//static GRF_REG_SAVE __sramdata pm_grf;
static void pm_keygpio_prepare(void)
{
gpio6_pull = grf_readl(GRF_GPIO6_PULL);
gpio2_pull = grf_readl(GRF_GPIO2_PULL);
}
void pm_keygpio_suspend(void)
void pm_keygpio_sdk_suspend(void)
{
grf_writel(gpio6_pull|0x7f,GRF_GPIO6_PULL);//key pullup/pulldown disable
grf_writel(gpio2_pull|0x00000f30,GRF_GPIO2_PULL);
}
void pm_keygpio_resume(void)
void pm_keygpio_sdk_resume(void)
{
grf_writel(gpio6_pull,GRF_GPIO6_PULL);//key pullup/pulldown enable
grf_writel(gpio2_pull,GRF_GPIO2_PULL);
}
void pm_keygpio_a22_suspend(void)
{
grf_writel(gpio6_pull|0x7f,GRF_GPIO6_PULL);//key pullup/pulldown disable
grf_writel(gpio2_pull|0x00000900,GRF_GPIO2_PULL);
}
void pm_keygpio_a22_resume(void)
{
grf_writel(gpio6_pull,GRF_GPIO6_PULL);//key pullup/pulldown enable
grf_writel(gpio2_pull,GRF_GPIO2_PULL);
}
static void pm_spi_gpio_prepare(void)
{
@ -542,7 +551,11 @@ void pm_gpio_suspend(void)
{
pm_spi_gpio_suspend(); // spi pullup/pulldown disable....
#if defined(CONFIG_MACH_RK29_PHONESDK)
{ pm_keygpio_suspend();// key pullup/pulldown disable.....
{ pm_keygpio_sdk_suspend();// key pullup/pulldown disable.....
}
#endif
#if defined(CONFIG_MACH_RK29_A22)
{ pm_keygpio_a22_suspend();// key pullup/pulldown disable.....
}
#endif
}
@ -550,7 +563,11 @@ void pm_gpio_resume(void)
{
pm_spi_gpio_resume(); // spi pullup/pulldown enable.....
#if defined(CONFIG_MACH_RK29_PHONESDK)
{ pm_keygpio_resume();// key pullup/pulldown enable.....
{ pm_keygpio_sdk_resume();// key pullup/pulldown enable.....
}
#endif
#if defined(CONFIG_MACH_RK29_A22)
{ pm_keygpio_a22_resume();// key pullup/pulldown enable.....
}
#endif
}

View File

@ -35,13 +35,15 @@
#define TIMER_ENABLE 3
#define TIMER_ENABLE_FREE_RUNNING 5
#define timer_writel(v, addr) do { writel(v, addr); readl(addr); } while (0)
#if 1 /* by default, use periph sync timer */
#define RK_TIMER_ENABLE(n) writel(TIMER_ENABLE, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CONTROL_REG)
#define RK_TIMER_ENABLE_FREE_RUNNING(n) writel(TIMER_ENABLE_FREE_RUNNING, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CONTROL_REG)
#define RK_TIMER_DISABLE(n) writel(TIMER_DISABLE, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CONTROL_REG)
#define RK_TIMER_ENABLE(n) timer_writel(TIMER_ENABLE, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CONTROL_REG)
#define RK_TIMER_ENABLE_FREE_RUNNING(n) timer_writel(TIMER_ENABLE_FREE_RUNNING, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CONTROL_REG)
#define RK_TIMER_DISABLE(n) timer_writel(TIMER_DISABLE, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CONTROL_REG)
#define RK_TIMER_SETCOUNT(n, count) writel(count, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_LOAD_COUNT)
#define RK_TIMER_SETCOUNT(n, count) timer_writel(count, RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_LOAD_COUNT)
#define RK_TIMER_GETCOUNT(n) readl(RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_LOAD_COUNT)
#define RK_TIMER_READVALUE(n) readl(RK29_TIMER2_BASE + 0x4000 * (n - 2) + TIMER_CUR_VALUE)
@ -59,11 +61,11 @@
#else
#define RK_TIMER_ENABLE(n) writel(TIMER_ENABLE, RK29_TIMER0_BASE + 0x2000 * n + TIMER_CONTROL_REG)
#define RK_TIMER_ENABLE_FREE_RUNNING(n) writel(TIMER_ENABLE_FREE_RUNNING, RK29_TIMER0_BASE + 0x2000 * n + TIMER_CONTROL_REG)
#define RK_TIMER_DISABLE(n) writel(TIMER_DISABLE, RK29_TIMER0_BASE + 0x2000 * n + TIMER_CONTROL_REG)
#define RK_TIMER_ENABLE(n) timer_writel(TIMER_ENABLE, RK29_TIMER0_BASE + 0x2000 * n + TIMER_CONTROL_REG)
#define RK_TIMER_ENABLE_FREE_RUNNING(n) timer_writel(TIMER_ENABLE_FREE_RUNNING, RK29_TIMER0_BASE + 0x2000 * n + TIMER_CONTROL_REG)
#define RK_TIMER_DISABLE(n) timer_writel(TIMER_DISABLE, RK29_TIMER0_BASE + 0x2000 * n + TIMER_CONTROL_REG)
#define RK_TIMER_SETCOUNT(n, count) writel(count, RK29_TIMER0_BASE + 0x2000 * n + TIMER_LOAD_COUNT)
#define RK_TIMER_SETCOUNT(n, count) timer_writel(count, RK29_TIMER0_BASE + 0x2000 * n + TIMER_LOAD_COUNT)
#define RK_TIMER_GETCOUNT(n) readl(RK29_TIMER0_BASE + 0x2000 * n + TIMER_LOAD_COUNT)
#define RK_TIMER_READVALUE(n) readl(RK29_TIMER0_BASE + 0x2000 * n + TIMER_CUR_VALUE)

View File

@ -98,6 +98,7 @@ typedef struct vpu_session {
struct list_head done;
wait_queue_head_t wait;
pid_t pid;
atomic_t task_running;
} vpu_session;
/**
@ -127,7 +128,7 @@ typedef struct vpu_service_info {
struct list_head running; /* link to link_reg in struct vpu_reg */
struct list_head done; /* link to link_reg in struct vpu_reg */
struct list_head session; /* link to list_session in struct vpu_session */
atomic_t task_running;
atomic_t total_running;
bool enabled;
vpu_reg *reg_codec;
vpu_reg *reg_pproc;
@ -169,53 +170,129 @@ static void vpu_put_clk(void)
clk_put(hclk_cpu_vcodec);
}
static void vpu_reset(void)
{
clk_disable(aclk_ddr_vepu);
cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, true);
cru_set_soft_reset(SOFT_RST_DDR_VCODEC_PORT, true);
cru_set_soft_reset(SOFT_RST_VCODEC_AHB_BUS, true);
cru_set_soft_reset(SOFT_RST_VCODEC_AXI_BUS, true);
mdelay(10);
cru_set_soft_reset(SOFT_RST_VCODEC_AXI_BUS, false);
cru_set_soft_reset(SOFT_RST_VCODEC_AHB_BUS, false);
cru_set_soft_reset(SOFT_RST_DDR_VCODEC_PORT, false);
cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, false);
clk_enable(aclk_ddr_vepu);
service.reg_codec = NULL;
service.reg_pproc = NULL;
service.reg_resev = NULL;
}
static void reg_deinit(vpu_reg *reg);
static void vpu_service_session_clear(vpu_session *session)
{
vpu_reg *reg, *n;
list_for_each_entry_safe(reg, n, &session->waiting, session_link) {
reg_deinit(reg);
}
list_for_each_entry_safe(reg, n, &session->running, session_link) {
reg_deinit(reg);
}
list_for_each_entry_safe(reg, n, &session->done, session_link) {
reg_deinit(reg);
}
}
static void vpu_service_dump(void)
{
int running;
vpu_reg *reg, *reg_tmp;
vpu_session *session, *session_tmp;
running = atomic_read(&service.total_running);
printk("total_running %d\n", running);
printk("reg_codec 0x%.8x\n", (unsigned int)service.reg_codec);
printk("reg_pproc 0x%.8x\n", (unsigned int)service.reg_pproc);
printk("reg_resev 0x%.8x\n", (unsigned int)service.reg_resev);
list_for_each_entry_safe(session, session_tmp, &service.session, list_session) {
printk("session pid %d type %d:\n", session->pid, session->type);
running = atomic_read(&session->task_running);
printk("task_running %d\n", running);
list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) {
printk("waiting register set 0x%.8x\n", (unsigned int)reg);
}
list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) {
printk("running register set 0x%.8x\n", (unsigned int)reg);
}
list_for_each_entry_safe(reg, reg_tmp, &session->done, session_link) {
printk("done register set 0x%.8x\n", (unsigned int)reg);
}
}
}
static void vpu_service_power_off(void)
{
int total_running;
if (!service.enabled)
return;
service.enabled = false;
printk("vpu: power off\n");
while(atomic_read(&service.task_running)) {
pr_alert("power off when task running!!\n");
udelay(10);
total_running = atomic_read(&service.total_running);
if (total_running) {
pr_alert("power off when %d task running!!\n", total_running);
mdelay(50);
pr_alert("delay 50 ms for running task\n");
vpu_service_dump();
}
printk("vpu: power off...");
pmu_set_power_domain(PD_VCODEC, false);
udelay(10);
clk_disable(hclk_cpu_vcodec);
clk_disable(aclk_ddr_vepu);
clk_disable(hclk_vepu);
clk_disable(aclk_vepu);
printk("done\n");
}
static void vpu_service_power_off_work_func(unsigned long data)
{
printk("vpu: delayed power off work\n");
printk("delayed ");
vpu_service_power_off();
}
static void vpu_service_power_maintain(void)
{
if (service.enabled) {
mod_timer(&service.timer, jiffies + POWER_OFF_DELAY);
} else {
pr_err("maintain power when power is off!\n");
}
}
static void vpu_service_power_on(void)
{
if (service.enabled) {
mod_timer(&service.timer, jiffies + POWER_OFF_DELAY);
return;
}
service.enabled = true;
printk("vpu: power on\n");
if (!service.enabled) {
service.enabled = true;
printk("vpu: power on\n");
clk_enable(aclk_vepu);
clk_enable(hclk_vepu);
clk_enable(hclk_cpu_vcodec);
udelay(10);
pmu_set_power_domain(PD_VCODEC, true);
udelay(10);
clk_enable(aclk_ddr_vepu);
init_timer(&service.timer);
service.timer.expires = jiffies + POWER_OFF_DELAY;
service.timer.function = vpu_service_power_off_work_func;
add_timer(&service.timer);
clk_enable(aclk_vepu);
clk_enable(hclk_vepu);
clk_enable(hclk_cpu_vcodec);
udelay(10);
pmu_set_power_domain(PD_VCODEC, true);
udelay(10);
clk_enable(aclk_ddr_vepu);
init_timer(&service.timer);
service.timer.expires = jiffies + POWER_OFF_DELAY;
service.timer.function = vpu_service_power_off_work_func;
add_timer(&service.timer);
} else {
vpu_service_power_maintain();
}
}
static vpu_reg *reg_init(vpu_session *session, void __user *src, unsigned long size)
@ -311,6 +388,8 @@ static void reg_from_run_to_done(vpu_reg *reg)
break;
}
}
atomic_sub(1, &reg->session->task_running);
atomic_sub(1, &service.total_running);
wake_up_interruptible_sync(&reg->session->wait);
spin_unlock(&service.lock);
}
@ -319,7 +398,8 @@ void reg_copy_to_hw(vpu_reg *reg)
{
int i;
u32 *src = (u32 *)&reg->reg[0];
atomic_add(1, &service.task_running);
atomic_add(1, &service.total_running);
atomic_add(1, &reg->session->task_running);
switch (reg->type) {
case VPU_ENC : {
u32 *dst = (u32 *)enc_dev.hwregs;
@ -380,7 +460,8 @@ void reg_copy_to_hw(vpu_reg *reg)
} break;
default : {
pr_err("unsupport session type %d", reg->type);
atomic_sub(1, &service.task_running);
atomic_sub(1, &service.total_running);
atomic_sub(1, &reg->session->task_running);
break;
}
}
@ -394,12 +475,12 @@ static void try_set_reg(void)
if (!list_empty(&service.waiting)) {
vpu_reg *reg = list_entry(service.waiting.next, vpu_reg, status_link);
vpu_service_power_maintain();
if (((VPU_DEC_PP == reg->type) && (NULL == service.reg_codec) && (NULL == service.reg_pproc)) ||
((VPU_DEC == reg->type) && (NULL == service.reg_codec)) ||
((VPU_PP == reg->type) && (NULL == service.reg_pproc)) ||
((VPU_ENC == reg->type) && (NULL == service.reg_codec))) {
((VPU_DEC == reg->type) && (NULL == service.reg_codec)) ||
((VPU_PP == reg->type) && (NULL == service.reg_pproc)) ||
((VPU_ENC == reg->type) && (NULL == service.reg_codec))) {
reg_from_wait_to_run(reg);
vpu_service_power_on();
reg_copy_to_hw(reg);
}
}
@ -485,6 +566,7 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, unsigned long
if (NULL == reg) {
return -EFAULT;
} else {
vpu_service_power_on();
try_set_reg();
}
@ -493,6 +575,7 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, unsigned long
case VPU_IOC_GET_REG : {
vpu_request req;
vpu_reg *reg;
unsigned long flag;
if (copy_from_user(&req, (void __user *)arg, sizeof(vpu_request))) {
pr_err("VPU_IOC_GET_REG copy_from_user failed\n");
return -EFAULT;
@ -500,19 +583,31 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, unsigned long
int ret = wait_event_interruptible_timeout(session->wait, !list_empty(&session->done), TIMEOUT_DELAY);
if (unlikely(ret < 0)) {
pr_err("pid %d wait task ret %d\n", session->pid, ret);
return ret;
} else if (0 == ret) {
pr_err("pid %d wait task done timeout\n", session->pid);
return -ETIMEDOUT;
pr_err("pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running));
ret = -ETIMEDOUT;
}
}
{
unsigned long flag;
spin_lock_irqsave(&service.lock, flag);
reg = list_entry(session->done.next, vpu_reg, session_link);
return_reg(reg, (u32 __user *)req.req);
if (ret < 0) {
int task_running = atomic_read(&session->task_running);
vpu_service_dump();
if (task_running) {
atomic_set(&session->task_running, 0);
atomic_sub(task_running, &service.total_running);
printk("%d task is running but not return, reset hardware...", task_running);
vpu_reset();
printk("done\n");
}
vpu_service_session_clear(session);
spin_unlock_irqrestore(&service.lock, flag);
return ret;
}
spin_unlock_irqrestore(&service.lock, flag);
}
spin_lock_irqsave(&service.lock, flag);
reg = list_entry(session->done.next, vpu_reg, session_link);
return_reg(reg, (u32 __user *)req.req);
spin_unlock_irqrestore(&service.lock, flag);
break;
}
default : {
@ -621,6 +716,7 @@ static int vpu_service_open(struct inode *inode, struct file *filp)
init_waitqueue_head(&session->wait);
/* no need to protect */
list_add_tail(&session->list_session, &service.session);
atomic_set(&session->task_running, 0);
filp->private_data = (void *)session;
pr_debug("dev opened\n");
@ -629,34 +725,28 @@ static int vpu_service_open(struct inode *inode, struct file *filp)
static int vpu_service_release(struct inode *inode, struct file *filp)
{
int task_running;
unsigned long flag;
vpu_session *session = (vpu_session *)filp->private_data;
if (NULL == session)
return -EINVAL;
task_running = atomic_read(&session->task_running);
if (task_running) {
pr_err("vpu_service session %d still has %d task running when closing\n", session->pid, task_running);
msleep(50);
}
wake_up_interruptible_sync(&session->wait);
msleep(50);
spin_lock_irqsave(&service.lock, flag);
/* remove this filp from the asynchronusly notified filp's */
//vpu_service_fasync(-1, filp, 0);
list_del(&session->list_session);
spin_lock_irqsave(&service.lock, flag);
{
vpu_reg *reg, *n;
list_for_each_entry_safe(reg, n, &session->waiting, session_link) {
reg_deinit(reg);
}
list_for_each_entry_safe(reg, n, &session->running, session_link) {
reg_deinit(reg);
}
list_for_each_entry_safe(reg, n, &session->done, session_link) {
reg_deinit(reg);
}
}
spin_unlock_irqrestore(&service.lock, flag);
vpu_service_session_clear(session);
kfree(session);
spin_unlock_irqrestore(&service.lock, flag);
pr_debug("dev closed\n");
return 0;
@ -700,6 +790,7 @@ static int vpu_service_resume(struct platform_device *pdev)
if (service.enabled) {
service.enabled = false;
vpu_service_power_on();
try_set_reg();
}
return 0;
}
@ -913,7 +1004,6 @@ static irqreturn_t vdpu_isr(int irq, void *dev_id)
/* clear dec IRQ */
writel(irq_status_dec & (~DEC_INTERRUPT_BIT), dev->hwregs + DEC_INTERRUPT_REGISTER);
pr_debug("DEC IRQ received!\n");
atomic_sub(1, &service.task_running);
if (NULL == service.reg_codec) {
pr_err("dec isr with no task waiting\n");
} else {
@ -925,7 +1015,6 @@ static irqreturn_t vdpu_isr(int irq, void *dev_id)
/* clear pp IRQ */
writel(irq_status_pp & (~DEC_INTERRUPT_BIT), dev->hwregs + PP_INTERRUPT_REGISTER);
pr_debug("PP IRQ received!\n");
atomic_sub(1, &service.task_running);
if (NULL == service.reg_pproc) {
pr_err("pp isr with no task waiting\n");
} else {
@ -947,7 +1036,6 @@ static irqreturn_t vepu_isr(int irq, void *dev_id)
/* clear enc IRQ */
writel(irq_status & (~ENC_INTERRUPT_BIT), dev->hwregs + ENC_INTERRUPT_REGISTER);
pr_debug("ENC IRQ received!\n");
atomic_sub(1, &service.task_running);
if (NULL == service.reg_codec) {
pr_err("enc isr with no task waiting\n");
} else {
@ -976,7 +1064,7 @@ static int __init vpu_service_init(void)
spin_lock_init(&service.lock);
service.reg_codec = NULL;
service.reg_pproc = NULL;
atomic_set(&service.task_running, 0);
atomic_set(&service.total_running, 0);
service.enabled = false;
vpu_get_clk();

View File

@ -725,7 +725,7 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
}
#if defined(CONFIG_RK29_MEM_SIZE_M) && CONFIG_RK29_MEM_SIZE_M >= 1024
static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_256M);
static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_512M);
#else
static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
#endif

View File

@ -55,6 +55,8 @@ static usb_parameter skip_device_list[] = {
// 山寨
// {0x05C6, -1, NULL, NULL, NULL},
{0x05C6, 0x1000, NULL, NULL, NULL},
{0x1AB7, 0x5700, NULL, NULL, NULL},
{0x20B9, 0x1682, NULL, NULL, NULL},
{0x028A, 0x1006, NULL, NULL, NULL},
@ -71,19 +73,6 @@ static usb_parameter skip_device_list[] = {
{0x0685, 0x7000, NULL, NULL, NULL},
};
/*
0 -
1 -
*/
static int match_string(const char* s1, const char* s2)
{
int count = 0;
while( s1[count] && s2[count] && !(s1[count]-s2[count]) )
++count;
return !(s1[count]-s2[count]);
}
/* 1 - match
* 0 - no match
*/

113
drivers/cir/bu92747guw_cir.c Executable file → Normal file
View File

@ -34,7 +34,7 @@
#include "bu92747guw_cir.h"
#if 0
#if 1
#define BU92747_DBG(x...) printk(x)
#else
#define BU92747_DBG(x...)
@ -59,19 +59,19 @@ static struct miscdevice bu92747guw_device;
int repeat_flag=-1;
int start_flag = 0;
//mutex lock between remote and irda
static DEFINE_MUTEX(bu92747_mutex);
void bu92747_lock(void)
{
mutex_lock(&bu92747_mutex);
}
void bu92747_unlock(void)
{
mutex_unlock(&bu92747_mutex);
}
#ifdef CONFIG_RK_IRDA_UART
extern int bu92747_try_lock(void);
extern void bu92747_unlock(void);
#else
int bu92747_try_lock(void) {return 1;}
void bu92747_unlock(void) {return;}
#endif
static int bu92747_cir_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf, int len)
{
@ -380,8 +380,7 @@ static int bu92747_start(struct i2c_client *client)
start_flag = 1;
//enable_irq(bu92747->irq);
//enable clk
bu92747->state = 0;
bu92747_cir_i2c_read_regs(client, REG_SETTING0, reg_value, 1);
reg_value[0] = reg_value[0]|0x01;
bu92747_cir_i2c_set_regs(client, REG_SETTING0, reg_value, 1);
@ -754,11 +753,21 @@ static int bu92747_open(struct inode *inode, struct file *file)
struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
struct bu92747guw_platform_data *pdata = bu92747->platdata;
int ret = 0;
BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
printk("bu92747_open\n");
ret = bu92747_try_lock();
if (ret == 0){
printk("cannot get lock. Please close irda!\n");
return -2;
}
bu92747->state = 0;
start_flag = 0;
repeat_flag = -1;
// if (BU92747_OPEN == bu92747->state)
// return -EBUSY;
// bu92747->state = BU92747_OPEN;
@ -776,7 +785,7 @@ static int bu92747_open(struct inode *inode, struct file *file)
//register init
bu92747_cir_init_device(client, bu92747);
start_flag = -1;
start_flag = 0;
BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
return 0;
@ -789,6 +798,8 @@ static int bu92747_release(struct inode *inode, struct file *file)
struct bu92747guw_platform_data *pdata = bu92747->platdata;
BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)|0x0040);
start_flag = -1;
//power down
if (pdata && pdata->cir_pwr_ctl) {
@ -796,12 +807,77 @@ static int bu92747_release(struct inode *inode, struct file *file)
}
// bu92747->state = BU92747_CLOSE;
bu92747_unlock();
BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
return 0;
}
#if CONFIG_PM
static int bu92747_suspend(struct i2c_client *i, pm_message_t mesg)
{
struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
struct bu92747guw_platform_data *pdata = bu92747->platdata;
BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
if (start_flag == 0){
BU92747_DBG("realy suspend!\n");
disable_irq(bu92747->irq);
smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)|0x0040);
start_flag = 0;
repeat_flag = -1;
if (pdata && pdata->cir_pwr_ctl) {
pdata->cir_pwr_ctl(0);
}
}
BU92747_DBG("line %d: exit %s\n", __LINE__, __FUNCTION__);
return 0;
}
static int bu92747_resume(struct i2c_client *i)
{
struct i2c_client *client = container_of(bu92747guw_device.parent, struct i2c_client, dev);
struct bu92747_data_info *bu92747 = (struct bu92747_data_info *)i2c_get_clientdata(client);
struct bu92747guw_platform_data *pdata = bu92747->platdata;
BU92747_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
if (start_flag == 0){
BU92747_DBG("realy resume!\n");
enable_irq(bu92747->irq);
bu92747->state = 0;
//power on
if (pdata && pdata->cir_pwr_ctl) {
pdata->cir_pwr_ctl(1);
}
//switch to remote control, mcr, ec_en=1,rc_mode=1
smc0_write(REG_MCR_ADDR, smc0_read(REG_MCR_ADDR)|(3<<10));
//set irda pwdownpin = 0
smc0_write(REG_TRCR_ADDR, smc0_read(REG_TRCR_ADDR)&0xffbf);
BU92747_DBG("irda power down pin = %d\n", gpio_get_value(RK29_PIN5_PA7));
//register init
bu92747_cir_init_device(client, bu92747);
}
printk("line %d: exit %s\n", __LINE__, __FUNCTION__);
return 0;
}
#else
#define bu92747_suspend NULL
#define bu92747_resume NULL
#endif
static struct file_operations bu92747_fops = {
.owner = THIS_MODULE,
.open = bu92747_open,
@ -841,7 +917,8 @@ static int __devinit bu92747_cir_probe(struct i2c_client *client, const struct i
bu92747->platdata = pdata;
bu92747->client = client;
i2c_set_clientdata(client, bu92747);
bu92747->state = BU92747_CLOSE;
bu92747->state = 0;
start_flag = -1;
//register device
bu92747guw_device.parent = &client->dev;
@ -909,7 +986,7 @@ static int __devexit bu92747_cir_remove(struct i2c_client *client)
struct bu92747guw_platform_data *pdata = bu92747->platdata;
printk(" cir_remove \n");
start_flag = 0;
start_flag = -1;
free_irq(bu92747->irq, bu92747);
gpio_free(pdata->intr_pin);
misc_deregister(&bu92747guw_device);
@ -933,6 +1010,10 @@ static struct i2c_driver bu92747_cir_driver = {
.probe = bu92747_cir_probe,
.remove = __devexit_p(bu92747_cir_remove),
.id_table = bu92747_cir_id,
#ifdef CONFIG_PM
.suspend = bu92747_suspend,
.resume = bu92747_resume,
#endif
};
static int __init bu92747_cir_init(void)

View File

@ -229,7 +229,6 @@ static void headsetobserve_work(struct work_struct *work)
}
headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
disable_irq(headset_info->irq[HOOK]);
}
break;
default:

View File

@ -198,6 +198,8 @@ source "drivers/input/magnetometer/Kconfig"
source "drivers/input/gsensor/Kconfig"
source "drivers/input/gyroscope/Kconfig"
source "drivers/input/jogball/Kconfig"
source "drivers/input/lightsensor/Kconfig"

View File

@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
obj-$(CONFIG_G_SENSOR_DEVICE) += gsensor/
obj-$(CONFIG_GYRO_SENSOR_DEVICE) += gyroscope/
obj-$(CONFIG_INPUT_JOGBALL) += jogball/
obj-$(CONFIG_LIGHT_SENSOR_DEVICE) += lightsensor/

18
drivers/input/gsensor/Kconfig Normal file → Executable file
View File

@ -27,6 +27,24 @@ config GS_MMA8452
To have support for your specific gsesnor you will have to
select the proper drivers which depend on this option.
config GS_KXTF9
bool "gs_kxtf9"
depends on G_SENSOR_DEVICE && SYSFS && I2C_RK29
default n
help
If you say yes here you get support for the Kionix KXTF9 digital tri-axis
accelerometer.
This driver can also be built as a module. If so, the module will be
called kxtf9.
config GS_LIS3DH
bool "gs_lis3dh"
depends on G_SENSOR_DEVICE
default n
help
To have support for your specific gsesnor you will have to
select the proper drivers which depend on this option.
config GS_L3G4200D
bool "gs_l3g4200d"
depends on G_SENSOR_DEVICE

2
drivers/input/gsensor/Makefile Normal file → Executable file
View File

@ -3,3 +3,5 @@
obj-$(CONFIG_GS_MMA7660) += mma7660.o
obj-$(CONFIG_GS_MMA8452) += mma8452.o
obj-$(CONFIG_GS_L3G4200D) += l3g4200d.o
obj-$(CONFIG_GS_KXTF9) += kxtf9.o
obj-$(CONFIG_GS_LIS3DH) += lis3dh_acc_misc.o

1456
drivers/input/gsensor/kxtf9.c Executable file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
*
* File Name : lis3dh_misc.h
* Authors : MH - C&I BU - Application Team
* : Carmine Iascone (carmine.iascone@st.com)
* : Matteo Dameno (matteo.dameno@st.com)
* Version : V 1.0.5
* Date : 26/08/2010
*
********************************************************************************
*
* 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.
*
* THE PRESENT SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, FOR THE SOLE
* PURPOSE TO SUPPORT YOUR APPLICATION DEVELOPMENT.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* THIS SOFTWARE IS SPECIFICALLY DESIGNED FOR EXCLUSIVE USE WITH ST PARTS.
*
*******************************************************************************/
/*******************************************************************************
Version History.
Revision 1-0-0 05/11/2009
First Release
Revision 1-0-1 26/01/2010
Linux K&R Compliant Release
Revision 1-0-5 16/08/2010
Interrupt Management
*******************************************************************************/
#ifndef __LIS3DH_H__
#define __LIS3DH_H__
#include <linux/ioctl.h> /* For IOCTL macros */
#include <linux/input.h>
#define SAD0L 0x00
#define SAD0H 0x01
#define LIS3DH_ACC_I2C_SADROOT 0x0C
#define LIS3DH_ACC_I2C_SAD_L ((LIS3DH_ACC_I2C_SADROOT<<1)|SAD0L)
#define LIS3DH_ACC_I2C_SAD_H ((LIS3DH_ACC_I2C_SADROOT<<1)|SAD0H)
#define LIS3DH_ACC_DEV_NAME "lis3dh_acc_misc"
#define LIS3DH_ACC_IOCTL_BASE 77
/** The following define the IOCTL command values via the ioctl macros */
#define LIS3DH_ACC_IOCTL_SET_DELAY _IOW(LIS3DH_ACC_IOCTL_BASE, 0, int)
#define LIS3DH_ACC_IOCTL_GET_DELAY _IOR(LIS3DH_ACC_IOCTL_BASE, 1, int)
#define LIS3DH_ACC_IOCTL_SET_ENABLE _IOW(LIS3DH_ACC_IOCTL_BASE, 2, int)
#define LIS3DH_ACC_IOCTL_GET_ENABLE _IOR(LIS3DH_ACC_IOCTL_BASE, 3, int)
#define LIS3DH_ACC_IOCTL_SET_FULLSCALE _IOW(LIS3DH_ACC_IOCTL_BASE, 4, int)
#define LIS3DH_ACC_IOCTL_SET_G_RANGE LIS3DH_ACC_IOCTL_SET_FULLSCALE
#define LIS3DH_ACC_IOCTL_SET_CTRL_REG3 _IOW(LIS3DH_ACC_IOCTL_BASE, 6, int)
#define LIS3DH_ACC_IOCTL_SET_CTRL_REG6 _IOW(LIS3DH_ACC_IOCTL_BASE, 7, int)
#define LIS3DH_ACC_IOCTL_SET_DURATION1 _IOW(LIS3DH_ACC_IOCTL_BASE, 8, int)
#define LIS3DH_ACC_IOCTL_SET_THRESHOLD1 _IOW(LIS3DH_ACC_IOCTL_BASE, 9, int)
#define LIS3DH_ACC_IOCTL_SET_CONFIG1 _IOW(LIS3DH_ACC_IOCTL_BASE, 10, int)
#define LIS3DH_ACC_IOCTL_SET_DURATION2 _IOW(LIS3DH_ACC_IOCTL_BASE, 11, int)
#define LIS3DH_ACC_IOCTL_SET_THRESHOLD2 _IOW(LIS3DH_ACC_IOCTL_BASE, 12, int)
#define LIS3DH_ACC_IOCTL_SET_CONFIG2 _IOW(LIS3DH_ACC_IOCTL_BASE, 13, int)
#define LIS3DH_ACC_IOCTL_GET_SOURCE1 _IOW(LIS3DH_ACC_IOCTL_BASE, 14, int)
#define LIS3DH_ACC_IOCTL_GET_SOURCE2 _IOW(LIS3DH_ACC_IOCTL_BASE, 15, int)
#define LIS3DH_ACC_IOCTL_GET_TAP_SOURCE _IOW(LIS3DH_ACC_IOCTL_BASE, 16, int)
#define LIS3DH_ACC_IOCTL_SET_TAP_TW _IOW(LIS3DH_ACC_IOCTL_BASE, 17, int)
#define LIS3DH_ACC_IOCTL_SET_TAP_CFG _IOW(LIS3DH_ACC_IOCTL_BASE, 18, int)
#define LIS3DH_ACC_IOCTL_SET_TAP_TLIM _IOW(LIS3DH_ACC_IOCTL_BASE, 19, int)
#define LIS3DH_ACC_IOCTL_SET_TAP_THS _IOW(LIS3DH_ACC_IOCTL_BASE, 20, int)
#define LIS3DH_ACC_IOCTL_SET_TAP_TLAT _IOW(LIS3DH_ACC_IOCTL_BASE, 21, int)
/************************************************/
/* Accelerometer defines section */
/************************************************/
/* Accelerometer Sensor Full Scale */
#define LIS3DH_ACC_FS_MASK 0x30
#define LIS3DH_ACC_G_2G 0x00
#define LIS3DH_ACC_G_4G 0x10
#define LIS3DH_ACC_G_8G 0x20
#define LIS3DH_ACC_G_16G 0x30
/* Accelerometer Sensor Operating Mode */
#define LIS3DH_ACC_ENABLE 0x01
#define LIS3DH_ACC_DISABLE 0x00
#ifdef __KERNEL__
struct lis3dh_acc_platform_data {
int poll_interval;
int min_interval;
u8 g_range;
u8 axis_map_x;
u8 axis_map_y;
u8 axis_map_z;
u8 negate_x;
u8 negate_y;
u8 negate_z;
int (*init)(void);
void (*exit)(void);
int (*power_on)(void);
int (*power_off)(void);
int gpio_int1;
int gpio_int2;
};
#endif /* __KERNEL__ */
#endif /* __LIS3DH_H__ */

22
drivers/input/gyroscope/Kconfig Executable file
View File

@ -0,0 +1,22 @@
#
# gyroscope drivers configuration
#
menuconfig GYRO_SENSOR_DEVICE
bool "gyroscope device support"
default n
help
Enable this to be able to choose the drivers for controlling the
gyroscope sensor on some platforms, for example on PDAs.
if GYRO_SENSOR_DEVICE
config GYRO_SENSOR_K3G
bool "gyroscope k3g"
depends on GYRO_SENSOR_DEVICE
default n
help
To have support for your specific gyroscope sesnor you will have to
select the proper drivers which depend on this option.
endif

View File

@ -0,0 +1,4 @@
# gyroscope drivers
obj-$(CONFIG_GYRO_SENSOR_K3G) += k3g.o

703
drivers/input/gyroscope/k3g.c Executable file
View File

@ -0,0 +1,703 @@
/*
* Copyright (C) 2010, Samsung Electronics Co. Ltd. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/uaccess.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/div64.h>
//#include <linux/input/k3g.h>
#include <linux/delay.h>
/* k3g chip id */
#define DEVICE_ID 0xD3
/* k3g gyroscope registers */
#define WHO_AM_I 0x0F
#define CTRL_REG1 0x20 /* power control reg */
#define CTRL_REG2 0x21 /* power control reg */
#define CTRL_REG3 0x22 /* power control reg */
#define CTRL_REG4 0x23 /* interrupt control reg */
#define CTRL_REG5 0x24 /* interrupt control reg */
#define OUT_TEMP 0x26 /* Temperature data */
#define STATUS_REG 0x27
#define AXISDATA_REG 0x28
#define OUT_Y_L 0x2A
#define FIFO_CTRL_REG 0x2E
#define FIFO_SRC_REG 0x2F
#define PM_OFF 0x00
#define PM_NORMAL 0x08
#define ENABLE_ALL_AXES 0x07
#define BYPASS_MODE 0x00
#define FIFO_MODE 0x20
#define FIFO_EMPTY 0x20
#define FSS_MASK 0x1F
#define ODR_MASK 0xF0
#define ODR105_BW12_5 0x00 /* ODR = 105Hz; BW = 12.5Hz */
#define ODR105_BW25 0x10 /* ODR = 105Hz; BW = 25Hz */
#define ODR210_BW12_5 0x40 /* ODR = 210Hz; BW = 12.5Hz */
#define ODR210_BW25 0x50 /* ODR = 210Hz; BW = 25Hz */
#define ODR210_BW50 0x60 /* ODR = 210Hz; BW = 50Hz */
#define ODR210_BW70 0x70 /* ODR = 210Hz; BW = 70Hz */
#define ODR420_BW20 0x80 /* ODR = 420Hz; BW = 20Hz */
#define ODR420_BW25 0x90 /* ODR = 420Hz; BW = 25Hz */
#define ODR420_BW50 0xA0 /* ODR = 420Hz; BW = 50Hz */
#define ODR420_BW110 0xB0 /* ODR = 420Hz; BW = 110Hz */
#define ODR840_BW30 0xC0 /* ODR = 840Hz; BW = 30Hz */
#define ODR840_BW35 0xD0 /* ODR = 840Hz; BW = 35Hz */
#define ODR840_BW50 0xE0 /* ODR = 840Hz; BW = 50Hz */
#define ODR840_BW110 0xF0 /* ODR = 840Hz; BW = 110Hz */
#define MIN_ST 175
#define MAX_ST 875
#define AC (1 << 7) /* register auto-increment bit */
#define MAX_ENTRY 1
#define MAX_DELAY (MAX_ENTRY * 9523809LL)
/* default register setting for device init */
static const char default_ctrl_regs[] = {
0x3F, /* 105HZ, PM-normal, xyz enable */
0x00, /* normal mode */
0x04, /* fifo wtm interrupt on */
0xA0, /* block data update, 2000d/s */
0x40, /* fifo enable */
};
static const struct odr_delay {
u8 odr; /* odr reg setting */
u32 delay_ns; /* odr in ns */
} odr_delay_table[] = {
{ ODR840_BW110, 1190476LL }, /* 840Hz */
{ ODR420_BW110, 2380952LL }, /* 420Hz */
{ ODR210_BW70, 4761904LL }, /* 210Hz */
{ ODR105_BW25, 9523809LL }, /* 105Hz */
};
/*
* K3G gyroscope data
* brief structure containing gyroscope values for yaw, pitch and roll in
* signed short
*/
struct k3g_t {
s16 x;
s16 y;
s16 z;
};
struct k3g_data {
struct i2c_client *client;
struct input_dev *input_dev;
struct mutex lock;
struct workqueue_struct *k3g_wq;
struct work_struct work;
struct hrtimer timer;
bool enable;
bool drop_next_event;
bool interruptible; /* interrupt or polling? */
int entries; /* number of fifo entries */
u8 ctrl_regs[5]; /* saving register settings */
u32 time_to_read; /* time needed to read one entry */
ktime_t polling_delay; /* polling time for timer */
};
static int k3g_read_fifo_status(struct k3g_data *k3g_data)
{
int fifo_status;
fifo_status = i2c_smbus_read_byte_data(k3g_data->client, FIFO_SRC_REG);
if (fifo_status < 0) {
pr_err("%s: failed to read fifo source register\n",
__func__);
return fifo_status;
}
return (fifo_status & FSS_MASK) + !(fifo_status & FIFO_EMPTY);
}
static int k3g_restart_fifo(struct k3g_data *k3g_data)
{
int res = 0;
res = i2c_smbus_write_byte_data(k3g_data->client,
FIFO_CTRL_REG, BYPASS_MODE);
if (res < 0) {
pr_err("%s : failed to set bypass_mode\n", __func__);
return res;
}
res = i2c_smbus_write_byte_data(k3g_data->client,
FIFO_CTRL_REG, FIFO_MODE | (k3g_data->entries - 1));
if (res < 0)
pr_err("%s : failed to set fifo_mode\n", __func__);
return res;
}
static void set_polling_delay(struct k3g_data *k3g_data, int res)
{
s64 delay_ns;
delay_ns = k3g_data->entries + 1 - res;
if (delay_ns < 0)
delay_ns = 0;
delay_ns = delay_ns * k3g_data->time_to_read;
k3g_data->polling_delay = ns_to_ktime(delay_ns);
}
/* gyroscope data readout */
static int k3g_read_gyro_values(struct i2c_client *client,
struct k3g_t *data, int total_read)
{
int err;
struct i2c_msg msg[2];
u8 reg_buf;
u8 gyro_data[sizeof(*data) * (total_read ? (total_read - 1) : 1)];
msg[0].addr = client->addr;
msg[0].buf = &reg_buf;
msg[0].flags = 0;
msg[0].len = 1;
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].buf = gyro_data;
if (total_read > 1) {
reg_buf = AXISDATA_REG | AC;
msg[1].len = sizeof(gyro_data);
err = i2c_transfer(client->adapter, msg, 2);
if (err != 2)
return (err < 0) ? err : -EIO;
}
reg_buf = AXISDATA_REG;
msg[1].len = 1;
err = i2c_transfer(client->adapter, msg, 2);
if (err != 2)
return (err < 0) ? err : -EIO;
reg_buf = OUT_Y_L | AC;
msg[1].len = sizeof(*data);
err = i2c_transfer(client->adapter, msg, 2);
if (err != 2)
return (err < 0) ? err : -EIO;
data->y = (gyro_data[1] << 8) | gyro_data[0];
data->z = (gyro_data[3] << 8) | gyro_data[2];
data->x = (gyro_data[5] << 8) | gyro_data[4];
return 0;
}
static int k3g_report_gyro_values(struct k3g_data *k3g_data)
{
int res;
struct k3g_t data;
res = k3g_read_gyro_values(k3g_data->client, &data,
k3g_data->entries + k3g_data->drop_next_event);
if (res < 0)
return res;
res = k3g_read_fifo_status(k3g_data);
k3g_data->drop_next_event = !res;
if (res >= 31 - k3g_data->entries) {
/* reset fifo to start again - data isn't trustworthy,
* our locked read might not have worked and we
* could have done i2c read in mid register update
*/
return k3g_restart_fifo(k3g_data);
}
input_report_rel(k3g_data->input_dev, REL_RX, data.x);
input_report_rel(k3g_data->input_dev, REL_RY, data.y);
input_report_rel(k3g_data->input_dev, REL_RZ, data.z);
input_sync(k3g_data->input_dev);
return res;
}
static enum hrtimer_restart k3g_timer_func(struct hrtimer *timer)
{
struct k3g_data *k3g_data = container_of(timer, struct k3g_data, timer);
queue_work(k3g_data->k3g_wq, &k3g_data->work);
return HRTIMER_NORESTART;
}
static void k3g_work_func(struct work_struct *work)
{
int res;
struct k3g_data *k3g_data = container_of(work, struct k3g_data, work);
do {
res = k3g_read_fifo_status(k3g_data);
if (res < 0)
return;
if (res < k3g_data->entries) {
pr_warning("%s: fifo entries are less than we want\n",
__func__);
goto timer_set;
}
res = k3g_report_gyro_values(k3g_data);
if (res < 0)
return;
timer_set:
set_polling_delay(k3g_data, res);
} while (!ktime_to_ns(k3g_data->polling_delay));
hrtimer_start(&k3g_data->timer,
k3g_data->polling_delay, HRTIMER_MODE_REL);
}
static irqreturn_t k3g_interrupt_thread(int irq, void *k3g_data_p)
{
int res;
struct k3g_data *k3g_data = k3g_data_p;
res = k3g_report_gyro_values(k3g_data);
if (res < 0)
pr_err("%s: failed to report gyro values\n", __func__);
return IRQ_HANDLED;
}
static ssize_t k3g_show_enable(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct k3g_data *k3g_data = dev_get_drvdata(dev);
return sprintf(buf, "%d\n", k3g_data->enable);
}
static ssize_t k3g_set_enable(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
int err = 0;
struct k3g_data *k3g_data = dev_get_drvdata(dev);
bool new_enable;
if (sysfs_streq(buf, "1"))
new_enable = true;
else if (sysfs_streq(buf, "0"))
new_enable = false;
else {
pr_debug("%s: invalid value %d\n", __func__, *buf);
return -EINVAL;
}
if (new_enable == k3g_data->enable)
return size;
mutex_lock(&k3g_data->lock);
if (new_enable) {
/* turning on */
err = i2c_smbus_write_i2c_block_data(k3g_data->client,
CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs),
k3g_data->ctrl_regs);
if (err < 0) {
err = -EIO;
goto unlock;
}
/* reset fifo entries */
err = k3g_restart_fifo(k3g_data);
if (err < 0) {
err = -EIO;
goto turn_off;
}
if (k3g_data->interruptible)
enable_irq(k3g_data->client->irq);
else {
set_polling_delay(k3g_data, 0);
hrtimer_start(&k3g_data->timer,
k3g_data->polling_delay, HRTIMER_MODE_REL);
}
} else {
if (k3g_data->interruptible)
disable_irq(k3g_data->client->irq);
else {
hrtimer_cancel(&k3g_data->timer);
cancel_work_sync(&k3g_data->work);
}
/* turning off */
err = i2c_smbus_write_byte_data(k3g_data->client,
CTRL_REG1, 0x00);
if (err < 0)
goto unlock;
}
k3g_data->enable = new_enable;
turn_off:
if (err < 0)
i2c_smbus_write_byte_data(k3g_data->client,
CTRL_REG1, 0x00);
unlock:
mutex_unlock(&k3g_data->lock);
return err ? err : size;
}
static ssize_t k3g_show_delay(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct k3g_data *k3g_data = dev_get_drvdata(dev);
u64 delay;
delay = k3g_data->time_to_read * k3g_data->entries;
delay = ktime_to_ns(ns_to_ktime(delay));
return sprintf(buf, "%lld\n", delay);
}
static ssize_t k3g_set_delay(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct k3g_data *k3g_data = dev_get_drvdata(dev);
int odr_value = ODR105_BW25;
int res = 0;
int i;
u64 delay_ns;
u8 ctrl;
res = strict_strtoll(buf, 10, &delay_ns);
if (res < 0)
return res;
mutex_lock(&k3g_data->lock);
if (!k3g_data->interruptible)
hrtimer_cancel(&k3g_data->timer);
else
disable_irq(k3g_data->client->irq);
/* round to the nearest supported ODR that is less than
* the requested value
*/
for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++)
if (delay_ns <= odr_delay_table[i].delay_ns) {
odr_value = odr_delay_table[i].odr;
delay_ns = odr_delay_table[i].delay_ns;
k3g_data->time_to_read = delay_ns;
k3g_data->entries = 1;
break;
}
if (delay_ns >= odr_delay_table[3].delay_ns) {
if (delay_ns >= MAX_DELAY) {
k3g_data->entries = MAX_ENTRY;
delay_ns = MAX_DELAY;
} else {
do_div(delay_ns, odr_delay_table[3].delay_ns);
k3g_data->entries = delay_ns;
}
k3g_data->time_to_read = odr_delay_table[3].delay_ns;
}
if (odr_value != (k3g_data->ctrl_regs[0] & ODR_MASK)) {
ctrl = (k3g_data->ctrl_regs[0] & ~ODR_MASK);
ctrl |= odr_value;
k3g_data->ctrl_regs[0] = ctrl;
res = i2c_smbus_write_byte_data(k3g_data->client,
CTRL_REG1, ctrl);
}
/* we see a noise in the first sample or two after we
* change rates. this delay helps eliminate that noise.
*/
msleep((u32)delay_ns * 2 / NSEC_PER_MSEC);
/* (re)start fifo */
k3g_restart_fifo(k3g_data);
if (!k3g_data->interruptible) {
delay_ns = k3g_data->entries * k3g_data->time_to_read;
k3g_data->polling_delay = ns_to_ktime(delay_ns);
if (k3g_data->enable)
hrtimer_start(&k3g_data->timer,
k3g_data->polling_delay, HRTIMER_MODE_REL);
} else
enable_irq(k3g_data->client->irq);
mutex_unlock(&k3g_data->lock);
return size;
}
static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
k3g_show_enable, k3g_set_enable);
static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
k3g_show_delay, k3g_set_delay);
static int k3g_probe(struct i2c_client *client,
const struct i2c_device_id *devid)
{
int ret;
int err = 0;
struct k3g_data *data;
struct input_dev *input_dev;
if (client->dev.platform_data == NULL) {
dev_err(&client->dev, "platform data is NULL. exiting.\n");
err = -ENODEV;
goto exit;
}
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) {
dev_err(&client->dev,
"failed to allocate memory for module data\n");
err = -ENOMEM;
goto exit;
}
data->client = client;
/* read chip id */
ret = i2c_smbus_read_byte_data(client, WHO_AM_I);
if (ret != DEVICE_ID) {
if (ret < 0) {
pr_err("%s: i2c for reading chip id failed\n",
__func__);
err = ret;
} else {
pr_err("%s : Device identification failed\n",
__func__);
err = -ENODEV;
}
goto err_read_reg;
}
mutex_init(&data->lock);
/* allocate gyro input_device */
input_dev = input_allocate_device();
if (!input_dev) {
pr_err("%s: could not allocate input device\n", __func__);
err = -ENOMEM;
goto err_input_allocate_device;
}
data->input_dev = input_dev;
input_set_drvdata(input_dev, data);
input_dev->name = "gyro";
/* X */
input_set_capability(input_dev, EV_REL, REL_RX);
input_set_abs_params(input_dev, REL_RX, -2048, 2047, 0, 0);
/* Y */
input_set_capability(input_dev, EV_REL, REL_RY);
input_set_abs_params(input_dev, REL_RY, -2048, 2047, 0, 0);
/* Z */
input_set_capability(input_dev, EV_REL, REL_RZ);
input_set_abs_params(input_dev, REL_RZ, -2048, 2047, 0, 0);
err = input_register_device(input_dev);
if (err < 0) {
pr_err("%s: could not register input device\n", __func__);
input_free_device(data->input_dev);
goto err_input_register_device;
}
memcpy(&data->ctrl_regs, &default_ctrl_regs, sizeof(default_ctrl_regs));
if (data->client->irq >= 0) { /* interrupt */
data->interruptible = true;
err = request_threaded_irq(data->client->irq, NULL,
k3g_interrupt_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"k3g", data);
if (err < 0) {
pr_err("%s: can't allocate irq.\n", __func__);
goto err_request_irq;
}
disable_irq(data->client->irq);
} else { /* polling */
u64 delay_ns;
data->ctrl_regs[2] = 0x00; /* disable interrupt */
/* hrtimer settings. we poll for gyro values using a timer. */
hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
data->polling_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
data->time_to_read = 10000000LL;
delay_ns = ktime_to_ns(data->polling_delay);
do_div(delay_ns, data->time_to_read);
data->entries = delay_ns;
data->timer.function = k3g_timer_func;
/* the timer just fires off a work queue request.
We need a thread to read i2c (can be slow and blocking). */
data->k3g_wq = create_singlethread_workqueue("k3g_wq");
if (!data->k3g_wq) {
err = -ENOMEM;
pr_err("%s: could not create workqueue\n", __func__);
goto err_create_workqueue;
}
/* this is the thread function we run on the work queue */
INIT_WORK(&data->work, k3g_work_func);
}
if (device_create_file(&input_dev->dev,
&dev_attr_enable) < 0) {
pr_err("Failed to create device file(%s)!\n",
dev_attr_enable.attr.name);
goto err_device_create_file;
}
if (device_create_file(&input_dev->dev,
&dev_attr_poll_delay) < 0) {
pr_err("Failed to create device file(%s)!\n",
dev_attr_poll_delay.attr.name);
goto err_device_create_file2;
}
i2c_set_clientdata(client, data);
dev_set_drvdata(&input_dev->dev, data);
return 0;
err_device_create_file2:
device_remove_file(&input_dev->dev, &dev_attr_enable);
err_device_create_file:
if (data->interruptible) {
enable_irq(data->client->irq);
free_irq(data->client->irq, data);
} else
destroy_workqueue(data->k3g_wq);
input_unregister_device(data->input_dev);
err_create_workqueue:
err_request_irq:
err_input_register_device:
err_input_allocate_device:
mutex_destroy(&data->lock);
err_read_reg:
kfree(data);
exit:
return err;
}
static int k3g_remove(struct i2c_client *client)
{
int err = 0;
struct k3g_data *k3g_data = i2c_get_clientdata(client);
device_remove_file(&k3g_data->input_dev->dev, &dev_attr_enable);
device_remove_file(&k3g_data->input_dev->dev, &dev_attr_poll_delay);
if (k3g_data->enable)
err = i2c_smbus_write_byte_data(k3g_data->client,
CTRL_REG1, 0x00);
if (k3g_data->interruptible) {
if (!k3g_data->enable) /* no disable_irq before free_irq */
enable_irq(k3g_data->client->irq);
free_irq(k3g_data->client->irq, k3g_data);
} else {
hrtimer_cancel(&k3g_data->timer);
cancel_work_sync(&k3g_data->work);
destroy_workqueue(k3g_data->k3g_wq);
}
input_unregister_device(k3g_data->input_dev);
mutex_destroy(&k3g_data->lock);
kfree(k3g_data);
return err;
}
static int k3g_suspend(struct device *dev)
{
int err = 0;
struct i2c_client *client = to_i2c_client(dev);
struct k3g_data *k3g_data = i2c_get_clientdata(client);
if (k3g_data->enable) {
mutex_lock(&k3g_data->lock);
if (!k3g_data->interruptible) {
hrtimer_cancel(&k3g_data->timer);
cancel_work_sync(&k3g_data->work);
}
err = i2c_smbus_write_byte_data(k3g_data->client,
CTRL_REG1, 0x00);
mutex_unlock(&k3g_data->lock);
}
return err;
}
static int k3g_resume(struct device *dev)
{
int err = 0;
struct i2c_client *client = to_i2c_client(dev);
struct k3g_data *k3g_data = i2c_get_clientdata(client);
if (k3g_data->enable) {
mutex_lock(&k3g_data->lock);
if (!k3g_data->interruptible)
hrtimer_start(&k3g_data->timer,
k3g_data->polling_delay, HRTIMER_MODE_REL);
err = i2c_smbus_write_i2c_block_data(client,
CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs),
k3g_data->ctrl_regs);
mutex_unlock(&k3g_data->lock);
}
return err;
}
static const struct dev_pm_ops k3g_pm_ops = {
.suspend = k3g_suspend,
.resume = k3g_resume
};
static const struct i2c_device_id k3g_id[] = {
{ "k3g", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, k3g_id);
static struct i2c_driver k3g_driver = {
.probe = k3g_probe,
.remove = __devexit_p(k3g_remove),
.id_table = k3g_id,
.driver = {
.pm = &k3g_pm_ops,
.owner = THIS_MODULE,
.name = "k3g"
},
};
static int __init k3g_init(void)
{
return i2c_add_driver(&k3g_driver);
}
static void __exit k3g_exit(void)
{
i2c_del_driver(&k3g_driver);
}
module_init(k3g_init);
module_exit(k3g_exit);
MODULE_DESCRIPTION("k3g digital gyroscope driver");
MODULE_AUTHOR("Tim SK Lee Samsung Electronics <tim.sk.lee@samsung.com>");
MODULE_LICENSE("GPL");

6
drivers/input/keyboard/Kconfig Executable file → Normal file
View File

@ -19,6 +19,12 @@ config KEYS_RK29
help
rk29 keyboard drivers(gpio and adc)
config KEYS_RK29_NEWTON
tristate "rk29 newton keyboard"
depends on ARCH_RK29
help
rk29 newton keyboard drivers(gpio and adc)
config SYNAPTICS_SO340010
tristate "Synaptics So340010 TouchPad KEY"
depends on I2C

3
drivers/input/keyboard/Makefile Executable file → Normal file
View File

@ -4,7 +4,8 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_KEYS_RK29) += rk29_keys.o
obj-$(CONFIG_KEYS_RK29) += rk29_keys.o
obj-$(CONFIG_KEYS_RK29_NEWTON) += rk29_newton_keys.o
obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o

View File

@ -0,0 +1,411 @@
/*
* Driver for keys on GPIO lines capable of generating interrupts.
*
* Copyright 2005 Phil Blundell
*
* 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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/adc.h>
#include <linux/earlysuspend.h>
#include <asm/gpio.h>
#include <mach/key.h>
#include <mach/board.h>
#define EMPTY_ADVALUE 950
#define DRIFT_ADVALUE 70
#define INVALID_ADVALUE 10
#if 0
#define key_dbg(bdata, format, arg...) \
dev_printk(KERN_INFO , &bdata->input->dev , format , ## arg)
#else
#define key_dbg(bdata, format, arg...)
#endif
struct rk29_button_data {
int state;
int long_press_count;
struct rk29_keys_button *button;
struct input_dev *input;
struct timer_list timer;
};
struct rk29_keys_drvdata {
int nbuttons;
int result;
struct input_dev *input;
struct adc_client *client;
struct timer_list timer;
struct rk29_button_data data[0];
};
static struct input_dev *input_dev;
static struct early_suspend newton_key_power;
static int suspend = 0;
void rk29_send_power_key(int state)
{
if (!input_dev)
return;
if(state)
{
input_report_key(input_dev, KEY_POWER, 1);
input_sync(input_dev);
}
else
{
input_report_key(input_dev, KEY_POWER, 0);
input_sync(input_dev);
}
}
void rk28_send_wakeup_key(void)
{
if (!input_dev)
return;
input_report_key(input_dev, KEY_WAKEUP, 1);
input_sync(input_dev);
input_report_key(input_dev, KEY_WAKEUP, 0);
input_sync(input_dev);
}
static void keys_long_press_timer(unsigned long _data)
{
int state;
struct rk29_button_data *bdata = (struct rk29_button_data *)_data;
struct rk29_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = EV_KEY;
if(button->gpio != INVALID_GPIO )
state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low);
else
state = !!button->adc_state;
if(state) {
if(bdata->long_press_count != 0) {
if(bdata->long_press_count % (LONG_PRESS_COUNT+ONE_SEC_COUNT) == 0){
key_dbg(bdata, "%skey[%s]: report ev[%d] state[0]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code_long_press);
input_event(input, type, button->code_long_press, 0);
input_sync(input);
}
else if(bdata->long_press_count%LONG_PRESS_COUNT == 0) {
key_dbg(bdata, "%skey[%s]: report ev[%d] state[1]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code_long_press);
input_event(input, type, button->code_long_press, 1);
input_sync(input);
}
}
bdata->long_press_count++;
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
}
else {
if(bdata->long_press_count <= LONG_PRESS_COUNT) {
bdata->long_press_count = 0;
key_dbg(bdata, "%skey[%s]: report ev[%d] state[1], report ev[%d] state[0]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code, button->code);
input_event(input, type, button->code, 1);
input_sync(input);
input_event(input, type, button->code, 0);
input_sync(input);
}
else if(bdata->state != state) {
key_dbg(bdata, "%skey[%s]: report ev[%d] state[0]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code_long_press);
input_event(input, type, button->code_long_press, 0);
input_sync(input);
}
}
bdata->state = state;
}
static void keys_timer(unsigned long _data)
{
int state;
struct rk29_button_data *bdata = (struct rk29_button_data *)_data;
struct rk29_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned int type = EV_KEY;
if((suspend)&&(!button->wakeup))
return;
if(button->gpio != INVALID_GPIO)
state = !!((gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low);
else
state = !!button->adc_state;
if(bdata->state != state) {
bdata->state = state;
key_dbg(bdata, "%skey[%s]: report ev[%d] state[%d]\n",
(button->gpio == INVALID_GPIO)?"ad":"io", button->desc, button->code, bdata->state);
input_event(input, type, button->code, bdata->state);
input_sync(input);
}
if(state)
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
}
static irqreturn_t keys_isr(int irq, void *dev_id)
{
struct rk29_button_data *bdata = dev_id;
struct rk29_keys_button *button = bdata->button;
BUG_ON(irq != gpio_to_irq(button->gpio));
bdata->long_press_count = 0;
mod_timer(&bdata->timer,
jiffies + msecs_to_jiffies(DEFAULT_DEBOUNCE_INTERVAL));
return IRQ_HANDLED;
}
static void newton_key_early_suspend(struct early_suspend *h);
static void newton_key_last_resume(struct early_suspend *h);
static int __devinit keys_probe(struct platform_device *pdev)
{
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
struct rk29_keys_drvdata *ddata;
struct input_dev *input;
int i, error = 0;
int wakeup = 0;
if(!pdata)
return -EINVAL;
ddata = kzalloc(sizeof(struct rk29_keys_drvdata) +
pdata->nbuttons * sizeof(struct rk29_button_data),
GFP_KERNEL);
input = input_allocate_device();
if (!ddata || !input) {
error = -ENOMEM;
goto fail0;
}
platform_set_drvdata(pdev, ddata);
input->name = pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
/* Enable auto repeat feature of Linux input subsystem */
if (pdata->rep)
__set_bit(EV_REP, input->evbit);
ddata->nbuttons = pdata->nbuttons;
ddata->input = input;
for (i = 0; i < pdata->nbuttons; i++) {
struct rk29_keys_button *button = &pdata->buttons[i];
struct rk29_button_data *bdata = &ddata->data[i];
int irq;
unsigned int type = EV_KEY;
bdata->input = input;
bdata->button = button;
if(button->code_long_press)
setup_timer(&bdata->timer,
keys_long_press_timer, (unsigned long)bdata);
else if(button->code)
setup_timer(&bdata->timer,
keys_timer, (unsigned long)bdata);
if(button->gpio != INVALID_GPIO) {
error = gpio_request(button->gpio, button->desc ?: "keys");
if (error < 0) {
pr_err("gpio-keys: failed to request GPIO %d,"
" error %d\n", button->gpio, error);
goto fail2;
}
error = gpio_direction_input(button->gpio);
if (error < 0) {
pr_err("gpio-keys: failed to configure input"
" direction for GPIO %d, error %d\n",
button->gpio, error);
gpio_free(button->gpio);
goto fail2;
}
irq = gpio_to_irq(button->gpio);
if (irq < 0) {
error = irq;
pr_err("gpio-keys: Unable to get irq number"
" for GPIO %d, error %d\n",
button->gpio, error);
gpio_free(button->gpio);
goto fail2;
}
error = request_irq(irq, keys_isr,
(button->active_low)?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING,
button->desc ? button->desc : "keys",
bdata);
if (error) {
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
irq, error);
gpio_free(button->gpio);
goto fail2;
}
}
if (button->wakeup)
wakeup = 1;
input_set_capability(input, type, button->code);
}
input_set_capability(input, EV_KEY, KEY_WAKEUP);
error = input_register_device(input);
if (error) {
pr_err("gpio-keys: Unable to register input device, "
"error: %d\n", error);
goto fail2;
}
device_init_wakeup(&pdev->dev, wakeup);
input_dev = input;
newton_key_power.suspend = newton_key_early_suspend;
newton_key_power.resume = newton_key_last_resume;
newton_key_power.level = 0x2;
register_early_suspend(&newton_key_power);
return error;
fail2:
while (--i >= 0) {
free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
}
platform_set_drvdata(pdev, NULL);
fail0:
input_free_device(input);
kfree(ddata);
return error;
}
static int __devexit keys_remove(struct platform_device *pdev)
{
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
struct rk29_keys_drvdata *ddata = platform_get_drvdata(pdev);
struct input_dev *input = ddata->input;
int i;
input_dev = NULL;
device_init_wakeup(&pdev->dev, 0);
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
free_irq(irq, &ddata->data[i]);
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
}
if(pdata->chn >= 0 && ddata->client);
adc_unregister(ddata->client);
input_unregister_device(input);
return 0;
}
#ifdef CONFIG_PM
static int keys_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
int i;
if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->nbuttons; i++) {
struct rk29_keys_button *button = &pdata->buttons[i];
if (button->wakeup) {
int irq = gpio_to_irq(button->gpio);
enable_irq_wake(irq);
}
}
}
return 0;
}
static int keys_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct rk29_keys_platform_data *pdata = pdev->dev.platform_data;
int i;
if (device_may_wakeup(&pdev->dev)) {
for (i = 0; i < pdata->nbuttons; i++) {
struct rk29_keys_button *button = &pdata->buttons[i];
if (button->wakeup) {
int irq = gpio_to_irq(button->gpio);
disable_irq_wake(irq);
}
}
}
return 0;
}
static void newton_key_early_suspend(struct early_suspend *h)
{
suspend = 1;
}
static void newton_key_last_resume(struct early_suspend *h)
{
suspend = 0;
}
static const struct dev_pm_ops keys_pm_ops = {
.suspend = keys_suspend,
.resume = keys_resume,
};
#endif
static struct platform_driver keys_device_driver = {
.probe = keys_probe,
.remove = __devexit_p(keys_remove),
.driver = {
.name = "rk29-keypad",
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &keys_pm_ops,
#endif
}
};
static int __init keys_init(void)
{
return platform_driver_register(&keys_device_driver);
}
static void __exit keys_exit(void)
{
platform_driver_unregister(&keys_device_driver);
}
module_init(keys_init);
module_exit(keys_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
MODULE_ALIAS("platform:gpio-keys");

View File

@ -0,0 +1,29 @@
#define MAX_BUFFER_SIZE 144
#define MAX_FINGER_NUMBER 3
#define MAX_PRESSURE 15
#define DEVICE_NAME "IT7260"
#define DEVICE_VENDOR 0
#define DEVICE_PRODUCT 0
#define DEVICE_VERSION 0
#define IT7260_X_RESOLUTION 1024
#define IT7260_Y_RESOLUTION 600
#define SCREEN_X_RESOLUTION 1024
#define SCREEN_Y_RESOLUTION 600
#define VERSION_ABOVE_ANDROID_20
//unsigned char bufferIndex;
//unsigned int length;
//unsigned char buffer[MAX_BUFFER_SIZE];
struct ioctl_cmd168 {
unsigned short bufferIndex;
unsigned short length;
unsigned short buffer[MAX_BUFFER_SIZE];
};
#define IOC_MAGIC 'd'
#define IOCTL_SET _IOW(IOC_MAGIC, 1, struct ioctl_cmd168)
#define IOCTL_GET _IOR(IOC_MAGIC, 2, struct ioctl_cmd168)
#define IOCTL_READ_CDC _IOR(IOC_MAGIC, 0x10, struct ioctl_cmd168)
//#define IOCTL_SET _IOW(IOC_MAGIC, 1, struct ioctl_cmd)
//#define IOCTL_GET _IOR(IOC_MAGIC, 2, struct ioctl_cmd)
//#define IOCTL_READ_CDC _IOR(IOC_MAGIC, 0x10, struct ioctl_cmd)

View File

@ -0,0 +1,858 @@
/* drivers/input/touchscreen/IT7260_ts_i2c.c
*
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/earlysuspend.h>
#include <linux/i2c.h>
#include <asm/uaccess.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include "IT7260_ts.h"
// >>> [110308] protect touch panel [Derek]
#include <linux/timer.h>
#include <linux/gpio.h>
static struct timer_list tp_timer;
static void tp_irq_handler_reg(unsigned long arg);
// <<< [110308] protect touch panel [Derek]
extern void set_tp_status(int number, int status) ;
extern int get_tp_status(int number) ;
#define IT7260_I2C_NAME "IT7260"
#include <linux/gpio.h>
static int ite7260_major = 0; // dynamic major by default
static int ite7260_minor = 0;
static struct cdev ite7260_cdev;
static struct class *ite7260_class = NULL;
static dev_t ite7260_dev;
static struct input_dev *input_dev;
#ifdef DEBUG
#define TS_DEBUG(fmt,args...) printk( KERN_DEBUG "[it7260_i2c]: " fmt, ## args)
#define DBG() printk("[%s]:%d => \n",__FUNCTION__,__LINE__)
#else
#define TS_DEBUG(fmt,args...)
#define DBG()
#endif
static struct workqueue_struct *IT7260_wq;
struct IT7260_ts_data {
struct i2c_client *client;
struct input_dev *input_dev;
int use_irq;
struct work_struct work;
struct early_suspend early_suspend;
uint8_t debug_log_level;
};
#ifdef CONFIG_HAS_EARLYSUSPEND
static void IT7260_ts_early_suspend(struct early_suspend *h);
static void IT7260_ts_late_resume(struct early_suspend *h);
#endif
static struct IT7260_ts_data *gl_ts;
int i2cReadFromIt7260(struct i2c_client *client, unsigned char bufferIndex,
unsigned char dataBuffer[], unsigned short dataLength) {
int ret;
struct i2c_msg msgs[2] = { { .addr = client->addr, .flags = I2C_M_NOSTART,
.len = 1, .buf = &bufferIndex }, { .addr = client->addr, .flags =
I2C_M_RD, .len = dataLength, .buf = dataBuffer } };
memset(dataBuffer, 0xFF, dataLength);
ret = i2c_transfer(client->adapter, msgs, 2);
return ret;
}
int i2cWriteToIt7260(struct i2c_client *client, unsigned char bufferIndex,
unsigned char const dataBuffer[], unsigned short dataLength) {
unsigned char buffer4Write[256];
struct i2c_msg msgs[1] = { { .addr = client->addr, .flags = 0, .len =
dataLength + 1, .buf = buffer4Write } };
buffer4Write[0] = bufferIndex;
memcpy(&(buffer4Write[1]), dataBuffer, dataLength);
return i2c_transfer(client->adapter, msgs, 1);
}
static int IdentifyCapSensor(struct IT7260_ts_data *ts);
static void Read_Point(struct IT7260_ts_data *ts) {
unsigned char ucQuery = 0;
unsigned char pucPoint[14];
#ifdef HAS_8_BYTES_LIMIT
unsigned char cPoint[8];
unsigned char ePoint[6];
#endif //HAS_8_BYTES_LIMIT
int ret = 0;
int finger2_pressed = 0;
int xraw, yraw, xtmp, ytmp;
int i = 0;
static int x[2] = { (int) -1, (int) -1 };
static int y[2] = { (int) -1, (int) -1 };
static bool finger[2] = { 0, 0 };
static bool flag = 0;
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
if (ucQuery < 0) {
//pr_info("=error Read_Point=\n");
if (ts->use_irq)
enable_irq(ts->client->irq);
return;
} else {
if (ucQuery & 0x80) {
#ifdef HAS_8_BYTES_LIMIT
i2cReadFromIt7260(ts->client, 0xC0, cPoint, 8);
ret = i2cReadFromIt7260(ts->client, 0xE0, ePoint, 6);
for(i=0; i<6; i++) {
pucPoint[i] = ePoint[i];
}
for(i=0; i<8; i++) {
pucPoint[i+6] = cPoint[i];
}
#else //HAS_8_BYTES_LIMIT
ret = i2cReadFromIt7260(ts->client, 0xE0, pucPoint, 14);
#endif //HAS_8_BYTES_LIMIT
//pr_info("=Read_Point read ret[%d]--point[%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x]=\n",
// ret,pucPoint[0],pucPoint[1],pucPoint[2],
// pucPoint[3],pucPoint[4],pucPoint[5],pucPoint[6],pucPoint[7],pucPoint[8],
// pucPoint[9],pucPoint[10],pucPoint[11],pucPoint[12],pucPoint[13]);
if (ret) {
// gesture
if (pucPoint[0] & 0xF0) {
if (ts->use_irq)
enable_irq(ts->client->irq);
//pr_info("(pucPoint[0] & 0xF0) is true, it's a gesture\n") ;
//pr_info("pucPoint[0]=%x\n", pucPoint[0]);
return;
}
// palm
if (pucPoint[1] & 0x01) {
if (ts->use_irq)
enable_irq(ts->client->irq);
//pr_info("pucPoint 1 is 0x01, it's a palm\n") ;
return;
}
// no more data
if (!(pucPoint[0] & 0x08)) {
if (finger[0]) {
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 1);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure_point);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x[0]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y[0]);
input_mt_sync(ts->input_dev);
finger[0] = 0;
flag = 1;
}
if (finger[1]) {
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 2);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure_point);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x[1]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y[1]);
input_mt_sync(ts->input_dev);
finger[1] = 0;
flag = 1;
}
if (flag) {
input_sync(ts->input_dev);
flag = 0;
}
if (ts->use_irq)
enable_irq(ts->client->irq);
//pr_info("(pucPoint[0] & 0x08) is false, means no more data\n") ;
return;
}
// 3 fingers
if (pucPoint[0] & 0x04) {
if (ts->use_irq)
enable_irq(ts->client->irq);
//pr_info("(pucPoint[0] & 0x04) is true, we don't support three fingers\n") ;
return;
}
if (pucPoint[0] & 0x01) {
char pressure_point, z, w;
xraw = ((pucPoint[3] & 0x0F) << 8) + pucPoint[2];
yraw = ((pucPoint[3] & 0xF0) << 4) + pucPoint[4];
pressure_point = pucPoint[5] & 0x0f;
//pr_info("=Read_Point1 x=%d y=%d p=%d=\n",xraw,yraw,pressure_point);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 1);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure_point);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, xraw);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, yraw);
input_mt_sync(ts->input_dev);
x[0] = xraw;
y[0] = yraw;
finger[0] = 1;
//pr_info("=input Read_Point1 x=%d y=%d p=%d=\n",xraw,yraw,pressure_point);
} else {
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 1);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure_point);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x[0]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y[0]);
input_mt_sync(ts->input_dev);
finger[0] = 0;
}
if (pucPoint[0] & 0x02) {
char pressure_point, z, w;
xraw = ((pucPoint[7] & 0x0F) << 8) + pucPoint[6];
yraw = ((pucPoint[7] & 0xF0) << 4) + pucPoint[8];
pressure_point = pucPoint[9] & 0x0f;
//pr_info("=Read_Point2 x=%d y=%d p=%d=\n",xraw,yraw,pressure_point);
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 2);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1);
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure_point);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, xraw);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, yraw);
input_mt_sync(ts->input_dev);
x[1] = xraw;
y[1] = yraw;
finger[1] = 1;
//pr_info("input Read_Point2 x=%d y=%d p=%d=\n",xraw,yraw,pressure_point);
} else {
input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 2);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
//input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, pressure_point);
input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x[1]);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y[1]);
input_mt_sync(ts->input_dev);
finger[1] = 0;
}
input_sync(ts->input_dev);
}
}
}
if (ts->use_irq)
enable_irq(ts->client->irq);
//pr_info("=end Read_Point=\n");
//IdentifyCapSensor(gl_ts);
}
///////////////////////////////////////////////////////////////////////////////////////
static void IT7260_ts_work_func(struct work_struct *work) {
int i;
int ret;
int bad_data = 0;
struct i2c_msg msg[2];
uint8_t start_reg;
uint8_t buf[15];
//printk(KERN_INFO "=IT7260_ts_work_func=\n");
struct IT7260_ts_data *ts = container_of(work, struct IT7260_ts_data, work);
gl_ts = ts;
Read_Point(ts);
}
// >>> [110308] protect touch panel [Derek]
int delayCount = 1;
static irqreturn_t IT7260_ts_irq_handler(int irq, void *dev_id) {
struct IT7260_ts_data *ts = dev_id;
if (delayCount == 1)
{
pr_info("=IT7260_ts_irq_handler=\n");
}
disable_irq_nosync(ts->client->irq);
queue_work(IT7260_wq, &ts->work);
return IRQ_HANDLED;
}
// <<< [110308] protect touch panel [Derek]
/////////////////////////////////////////////////////////
void sendCalibrationCmd(void) {
int ret = 0;
struct IT7260_ts_data *ts = gl_ts;
unsigned char data[] = { 0x13, 0x00, 0x00, 0x00, 0x00 };
unsigned char resp[2];
ret = i2cWriteToIt7260(ts->client, 0x20, data, 5);
printk(KERN_INFO "IT7260 sent calibration command [%d]!!!\n", ret);
//MUST sleep 5 seconds here!
mdelay(5000);
//Read out response to clear interrupt.
i2cReadFromIt7260(ts->client, 0xA0, resp, 2);
}
EXPORT_SYMBOL( sendCalibrationCmd);
// >>> [110308] protect touch panel [Derek]
static void tp_irq_handler_reg(unsigned long arg)
{
delayCount = 0;
}
// <<< [110308] protect touch panel [Derek]
static int IdentifyCapSensor(struct IT7260_ts_data *ts) {
unsigned char ucQuery;
unsigned char pucCmd[80];
int ret = 0;
int test_read_count = 0;
//pr_info("=entry IdentifyCapSensor=\n");
//pr_info("=entry IdentifyCapSensor---name[%s]---addr[%x]-flags[%d]=\n",ts->client->name,ts->client->addr,ts->client->flags);
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
//pr_info("=IdentifyCapSensor read 0x80 =%d=\n",ucQuery);
if (ucQuery < 0) {
msleep(250);
ucQuery = 0xFF;
}
while (ucQuery & 0x01) {
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
if (ucQuery < 0) {
ucQuery = 0xFF;
}
}
//pr_info("=IdentifyCapSensor write cmd=\n");
pucCmd[0] = 0x00;
ret = i2cWriteToIt7260(ts->client, 0x20, pucCmd, 1);
if (ret < 0) {
printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
/* fail? */
return ret;
}
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
if (ucQuery < 0) {
ucQuery = 0xFF;
}
test_read_count = 0;
while ((ucQuery & 0x01) && (test_read_count < 0x2000)) {
test_read_count++;
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
if (ucQuery < 0) {
ucQuery = 0xFF;
}
}
//pr_info("=IdentifyCapSensor write read id=\n");
ret = i2cReadFromIt7260(ts->client, 0xA0, pucCmd, 8);
//pr_info(
// "=IdentifyCapSensor read id--[%d][%x][%x][%x][%x][%x][%x][%x][%x][%x][%x]=\n",
// ret, pucCmd[0], pucCmd[1], pucCmd[2], pucCmd[3], pucCmd[4],
// pucCmd[5], pucCmd[6], pucCmd[7], pucCmd[8], pucCmd[9]);
}
static int IT7260_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id) {
struct IT7260_ts_data *ts;
int ret = 0;
struct IT7260_i2c_platform_data *pdata;
unsigned long irqflags;
unsigned char ucQuery = 0;
u8 cmdbuf[2] = { 0x07, 0 };
irqflags = IRQF_TRIGGER_HIGH;
pr_info("=entry IT7260_ts_probe=\n");
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
printk(KERN_ERR "IT7260_ts_probe: need I2C_FUNC_I2C\n");
ret = -ENODEV;
goto err_check_functionality_failed;
}
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
if (ts == NULL) {
ret = -ENOMEM;
goto err_check_functionality_failed;
}
ts->client = client;
ts->debug_log_level = 0x3;
ts->input_dev = input_dev;
i2c_set_clientdata(client, ts);
pdata = client->dev.platform_data;
#if 0
//ret=IdentifyCapSensor(ts);
//if(ret<0)
// goto err_power_failed;
// Ant start -- to identify if this device is exist
if (get_tp_status(1) == 0)
{
printk(KERN_ERR "The ite TP device is not exist\n");
ret = -ENODEV;
goto err_power_failed;
} else {
set_tp_status(1, 1) ;
}
// Ant end
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
ts->early_suspend.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1;
ts->early_suspend.suspend = IT7260_ts_early_suspend;
ts->early_suspend.resume = IT7260_ts_late_resume;
register_early_suspend(&ts->early_suspend);
#endif
//IT7260_wq = create_singlethread_workqueue("IT7260_wq");
IT7260_wq = create_workqueue("IT7260_wq");
if (!IT7260_wq)
goto err_check_functionality_failed;
INIT_WORK(&ts->work, IT7260_ts_work_func);
// >>> [110308] protect touch panel [Derek]
init_timer(&tp_timer) ;
tp_timer.expires = jiffies + 30 * HZ;
tp_timer.function = &tp_irq_handler_reg;
add_timer(&tp_timer);
// >>> [110308] protect touch panel [Derek]
pr_info("IT7260_ts_probe-client->irq[%d]=\n", client->irq);
if (client->irq) {
ret = request_irq(client->irq, IT7260_ts_irq_handler, IRQF_TRIGGER_LOW,
// ret = request_irq(client->irq, IT7260_ts_irq_handler, IRQF_DISABLED | IRQF_TRIGGER_LOW,
// ret = request_irq(client->irq, IT7260_ts_irq_handler, IRQF_SHARED | IRQF_TRIGGER_LOW,
client->name, ts);
pr_info("IT7260_ts_probe-request_irq[%d]=\n", ret);
if (ret == 0)
ts->use_irq = 1;
else
dev_err(&client->dev, "request_irq failed\n");
}
gl_ts = ts;
pr_info("=end IT7260_ts_probe=\n");
//To reset point queue.
i2cWriteToIt7260(ts->client, 0x20, cmdbuf, 1);
mdelay(10);
i2cReadFromIt7260(ts->client, 0xA0, cmdbuf, 2);
mdelay(10);
return 0;
err_power_failed: kfree(ts);
err_check_functionality_failed: return ret;
}
static int IT7260_ts_remove(struct i2c_client *client) {
return 0;
}
static int IT7260_ts_suspend(struct i2c_client *client, pm_message_t mesg) {
char ret;
u8 cmdbuf[] = { 0x04, 0x00, 0x02 };
printk(KERN_DEBUG "IT7260_ts_i2c call suspend\n");
if (i2cWriteToIt7260(client, 0x20, cmdbuf, 3) >= 0)
ret = 0;
else
ret = -1;
return ret;
}
static int IT7260_ts_resume(struct i2c_client *client) {
unsigned char ucQuery;
printk(KERN_DEBUG "IT7260_ts_i2c call resume\n");
#ifdef INT_PIN_OPEN_DRAIN
//TODO: Here 2 is the pin number of INT pin, so please modify it to the one your system uses.
gpio_direction_output(2, 0);
mdelay(10);
#endif //INT_PIN_OPEN_DRAIN
i2cReadFromIt7260(client, 0x80, &ucQuery, 1);
#ifdef INT_PIN_OPEN_DRAIN
mdelay(10);
gpio_direction_output(2, 1);
mdelay(50);
gpio_direction_input(2);
#endif //INT_PIN_OPEN_DRAIN
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void IT7260_ts_early_suspend(struct early_suspend *h)
{
struct IT7260_ts_data *ts;
ts = container_of(h, struct IT7260_ts_data, early_suspend);
IT7260_ts_suspend(ts->client, PMSG_SUSPEND);
}
static void IT7260_ts_late_resume(struct early_suspend *h)
{
struct IT7260_ts_data *ts;
ts = container_of(h, struct IT7260_ts_data, early_suspend);
IT7260_ts_resume(ts->client);
}
#endif
static const struct i2c_device_id IT7260_ts_id[] = { { IT7260_I2C_NAME, 0 },
{ } };
bool IT7260_Init(void) {
int i;
int tmp;
unsigned char ucQuery = 0;
unsigned char buffer[128];
struct IT7260_ts_data *ts = gl_ts;
// Identify Cap Sensor
do {
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
} while (ucQuery & 0x01);
buffer[0] = 0x00;
i2cWriteToIt7260(ts->client, 0x20, buffer, 1);
do {
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
} while (ucQuery & 0x01);
memset(&buffer, 0, sizeof(buffer));
i2cReadFromIt7260(ts->client, 0xA0, buffer, 8);
pr_info("=IT7260_Init --[%x][%x][%x][%x][%x][%x]=\n", buffer[0], buffer[1],
buffer[2], buffer[3], buffer[4], buffer[5]);
if (buffer[1] != 'I' || buffer[2] != 'T' || buffer[3] != 'E') {
// return false;
}
// Get firmware information
do {
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
} while (ucQuery & 0x01);
buffer[0] = 0x01;
buffer[1] = 0x00;
i2cWriteToIt7260(ts->client, 0x20, buffer, 2);
do {
i2cReadFromIt7260(ts->client, 0x80, &ucQuery, 1);
} while (ucQuery & 0x01);
memset(&buffer, 0, sizeof(buffer));
i2cReadFromIt7260(ts->client, 0xA0, buffer, 8);
tmp = 0;
//for (i = 5; i < 9; i++) {
for (i = 5; i < 8; i++) {
tmp += buffer[i];
}
if (tmp == 0) {
// return false;
}
//// Reinitialize Firmware
//set_ite_i2c_nostop(1);
//do {
// ucQuery = i2c_smbus_read_byte_data(ts->client, 0x80);
//} while (ucQuery & 0x01);
//buffer[0] = 0x6F;
//set_ite_i2c_nostop(0);
//i2c_smbus_write_byte_data(ts->client, 0x20, buffer[0]);
return true;
}
static struct i2c_driver IT7260_ts_driver = { .probe = IT7260_ts_probe,
.remove = IT7260_ts_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = IT7260_ts_suspend, .resume = IT7260_ts_resume,
#endif
.id_table = IT7260_ts_id, .driver = { .name = "IT7260-ts", }, };
struct ite7260_data {
rwlock_t lock;
unsigned short bufferIndex;
unsigned short length;
unsigned short buffer[MAX_BUFFER_SIZE];
};
int ite7260_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg) {
struct ite7260_data *dev = filp->private_data;
int retval = 0;
int i;
unsigned char ucQuery;
unsigned char buffer[MAX_BUFFER_SIZE];
struct ioctl_cmd168 data;
unsigned char datalen;
unsigned char ent[] = {0x60, 0x00, 0x49, 0x54, 0x37, 0x32};
unsigned char ext[] = {0x60, 0x80, 0x49, 0x54, 0x37, 0x32};
//pr_info("=ite7260_ioctl=\n");
memset(&data, 0, sizeof(struct ioctl_cmd168));
switch (cmd) {
case IOCTL_SET:
//pr_info("=IOCTL_SET=\n");
if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) {
retval = -EFAULT;
goto done;
}
if ( copy_from_user(&data, (int __user *)arg, sizeof(struct ioctl_cmd168)) ) {
retval = -EFAULT;
goto done;
}
buffer[0] = (unsigned char) data.bufferIndex;
//pr_info("%.2X ", buffer[0]);
for (i = 1; i < data.length + 1; i++) {
buffer[i] = (unsigned char) data.buffer[i - 1];
//pr_info("%.2X ", buffer[i]);
}
if (!memcmp(&(buffer[1]), ent, sizeof(ent))) {
pr_info("Disabling IRQ.\n");
disable_irq(gl_ts->client->irq);
}
if (!memcmp(&(buffer[1]), ext, sizeof(ext))) {
pr_info("Enabling IRQ.\n");
enable_irq(gl_ts->client->irq);
}
//pr_info("=================================================\n");
//pr_info("name[%s]---addr[%x]-flags[%d]=\n",gl_ts->client->name,gl_ts->client->addr,gl_ts->client->flags);
datalen = (unsigned char) (data.length + 1);
//pr_info("datalen=%d\n", datalen);
//write_lock(&dev->lock);
retval = i2cWriteToIt7260(gl_ts->client,
(unsigned char) data.bufferIndex, &(buffer[1]), datalen - 1);
//write_unlock(&dev->lock);
//pr_info("SET:retval=%x\n", retval);
retval = 0;
break;
case IOCTL_GET:
//pr_info("=IOCTL_GET=\n");
if (!access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))) {
retval = -EFAULT;
goto done;
}
if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) {
retval = -EFAULT;
goto done;
}
//pr_info("sizeof(struct ioctl_cmd168)=%d\n", sizeof(struct ioctl_cmd168));
if ( copy_from_user(&data, (int __user *)arg, sizeof(struct ioctl_cmd168)) ) {
retval = -EFAULT;
goto done;
}
//pr_info("=================================================\n");
//pr_info("name[%s]---addr[%x]-flags[%d]=\n",gl_ts->client->name,gl_ts->client->addr,gl_ts->client->flags);
//read_lock(&dev->lock);
retval = i2cReadFromIt7260(gl_ts->client,
(unsigned char) data.bufferIndex, (unsigned char*) buffer,
(unsigned char) data.length);
//read_unlock(&dev->lock);
//pr_info("GET:retval=%x\n", retval);
retval = 0;
for (i = 0; i < data.length; i++) {
data.buffer[i] = (unsigned short) buffer[i];
}
//pr_info("GET:bufferIndex=%x, dataLength=%d, buffer[0]=%x, buffer[1]=%x, buffer[2]=%x, buffer[3]=%x\n", data.bufferIndex, data.length, buffer[0], buffer[1], buffer[2], buffer[3]);
//pr_info("GET:bufferIndex=%x, dataLength=%d, buffer[0]=%x, buffer[1]=%x, buffer[2]=%x, buffer[3]=%x\n", data.bufferIndex, data.length, data.buffer[0], data.buffer[1], data.buffer[2], data.buffer[3]);
//if (data.bufferIndex == 0x80)
// data.buffer[0] = 0x00;
if ( copy_to_user((int __user *)arg, &data, sizeof(struct ioctl_cmd168)) ) {
retval = -EFAULT;
goto done;
}
break;
default:
retval = -ENOTTY;
break;
}
done:
//pr_info("DONE! retval=%d\n", retval);
return (retval);
}
int ite7260_open(struct inode *inode, struct file *filp) {
int i;
struct ite7260_data *dev;
pr_info("=ite7260_open=\n");
dev = kmalloc(sizeof(struct ite7260_data), GFP_KERNEL);
if (dev == NULL) {
return -ENOMEM;
}
/* initialize members */
rwlock_init(&dev->lock);
for (i = 0; i < MAX_BUFFER_SIZE; i++) {
dev->buffer[i] = 0xFF;
}
filp->private_data = dev;
return 0; /* success */
}
int ite7260_close(struct inode *inode, struct file *filp) {
struct ite7260_data *dev = filp->private_data;
if (dev) {
kfree(dev);
}
return 0; /* success */
}
struct file_operations ite7260_fops = { .owner = THIS_MODULE, .open =
ite7260_open, .release = ite7260_close, .ioctl = ite7260_ioctl, };
static int __devinit IT7260_ts_init(void) {
dev_t dev = MKDEV(ite7260_major, 0);
int alloc_ret = 0;
int cdev_err = 0;
int input_err = 0;
struct device *class_dev = NULL;
DBG();
// if(!IT7260_Init()) {
// TS_DEBUG("IT7260 cannot be connected or is in firmware upgrade mode.\n");
// goto error;
// }
alloc_ret = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
if (alloc_ret) {
TS_DEBUG("IT7260 cdev can't get major number\n");
goto error;
}
ite7260_major = MAJOR(dev);
// allocate the character device
cdev_init(&ite7260_cdev, &ite7260_fops);
ite7260_cdev.owner = THIS_MODULE;
ite7260_cdev.ops = &ite7260_fops;
cdev_err = cdev_add(&ite7260_cdev, MKDEV(ite7260_major, ite7260_minor), 1);
if(cdev_err) {
goto error;
}
// register class
ite7260_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(ite7260_class)) {
TS_DEBUG("Err: failed in creating class.\n");
goto error;
}
ite7260_dev = MKDEV(ite7260_major, ite7260_minor);
class_dev = device_create(ite7260_class, NULL, ite7260_dev, NULL, DEVICE_NAME);
if(class_dev == NULL)
{
TS_DEBUG("Err: failed in creating device.\n");
goto error;
}
TS_DEBUG("=========================================\n");
TS_DEBUG("register IT7260 cdev, major: %d, minor: %d \n", ite7260_major, ite7260_minor);
TS_DEBUG("=========================================\n");
input_dev = input_allocate_device();
if (input_dev == NULL) {
input_err = -ENOMEM;
printk(KERN_ERR "IT7260_ts_probe: Failed to allocate input device\n");
goto error;
}
input_dev->name = "IT7260";
input_dev->phys = "I2C";
input_dev->id.bustype = BUS_I2C;
input_dev->id.vendor = 0x0001;
input_dev->id.product = 0x7260;
//set_bit(EV_SYN, input_dev->evbit);
//set_bit(EV_KEY, input_dev->evbit);
set_bit(EV_ABS, input_dev->evbit);
//set_bit(BTN_TOUCH, input_dev->keybit);
//set_bit(BTN_2, input_dev->keybit);
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 1024, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 600, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 2, 0, 0);
input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, 2, 0, 0);
input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, 600, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
input_err = input_register_device(input_dev);
if (input_err) goto error;
pr_info("it7260 driver is on###############################################################\n");
return i2c_add_driver(&IT7260_ts_driver);
error:
if(cdev_err == 0) {
cdev_del(&ite7260_cdev);
}
if(alloc_ret == 0) {
unregister_chrdev_region(dev, 1);
}
if(input_dev) {
input_free_device(input_dev);
}
if (IT7260_wq)
destroy_workqueue(IT7260_wq);
return -1;
}
static void __exit IT7260_ts_exit(void) {
dev_t dev = MKDEV(ite7260_major, ite7260_minor);
// unregister class
device_destroy(ite7260_class, ite7260_dev);
class_destroy(ite7260_class);
// unregister driver handle
cdev_del(&ite7260_cdev);
unregister_chrdev_region(dev, 1);
i2c_del_driver(&IT7260_ts_driver);
if (IT7260_wq)
destroy_workqueue(IT7260_wq);
}
module_init( IT7260_ts_init);
module_exit( IT7260_ts_exit);
MODULE_DESCRIPTION("IT7260 Touchscreen Driver");
MODULE_LICENSE("GPL");

10
drivers/input/touchscreen/Kconfig Normal file → Executable file
View File

@ -822,6 +822,16 @@ config TOUCHSCREEN_IT7260
code includes that in its table of I2C devices.
If unsure, say N (but it's safe to say "Y").
config TOUCHSCREEN_IT7260_I2C
tristate "IT7260 based touchscreens: IT7260 I2C Interface"
depends on I2C_RK29
help
Say Y here if you have a touchscreen interface using the
IT7260 controller, and your board-specific initialization
code includes that in its table of I2C devices.
If unsure, say N (but it's safe to say "Y").
config TOUCHSCREEN_NAS
tristate "NAS based touchscreens: NAS Interface"

1
drivers/input/touchscreen/Makefile Normal file → Executable file
View File

@ -63,6 +63,7 @@ obj-$(CONFIG_TOUCHSCREEN_IT7250) += ctp_it7250.o
obj-$(CONFIG_RK28_I2C_TS_NTP070) += ntp070.o
obj-$(CONFIG_HANNSTAR_P1003) += hannstar_p1003.o
obj-$(CONFIG_TOUCHSCREEN_IT7260) += it7260_ts.o
obj-$(CONFIG_TOUCHSCREEN_IT7260_I2C) += IT7260_ts_i2c.o
obj-$(CONFIG_SINTEK_3FA16) += sintek_3FA16.o
obj-$(CONFIG_EETI_EGALAX) += eeti_egalax_i2c.o
obj-$(CONFIG_ATMEL_MXT224) += atmel_maxtouch.o

View File

@ -41,6 +41,10 @@
#include <linux/async.h>
#include <mach/board.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
//#define DEBUG
#ifdef CONFIG_EETI_EGALAX_DEBUG
#define TS_DEBUG(fmt,args...) printk( KERN_DEBUG "[egalax_i2c]: " fmt, ## args)
@ -67,6 +71,8 @@ static int global_minor = 0;
#define EGALAX_IOCWAKEUP _IO(EGALAX_IOC_MAGIC, 1)
#define EGALAX_IOC_MAXNR 1
#define EETI_EARLYSUSPEND_LEVEL 151
struct point_data {
short Status;
short X;
@ -83,6 +89,13 @@ struct _egalax_i2c {
int irq;
};
#ifdef CONFIG_HAS_EARLYSUSPEND
struct suspend_info {
struct early_suspend early_suspend;
struct _egalax_i2c *egalax_i2c;
};
#endif
struct egalax_char_dev
{
int OpenCnts;
@ -501,9 +514,8 @@ static void egalax_i2c_wq(struct work_struct *work)
egalax_i2c->skip_packet = 0;
mutex_unlock(&egalax_i2c->mutex_wq);
if( egalax_i2c->work_state > 0 )
enable_irq(p_egalax_i2c_dev->irq);
enable_irq(p_egalax_i2c_dev->irq);
TS_DEBUG("egalax_i2c_wq leave\n");
}
@ -549,9 +561,13 @@ static int egalax_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
i2c_master_normal_send(client, cmdbuf, MAX_I2C_LEN, EETI_I2C_RATE);
egalax_i2c->work_state = 0;
disable_irq(p_egalax_i2c_dev->irq);
cancel_work_sync(&egalax_i2c->work);
egalax_i2c->work_state = 0;
if (cancel_work_sync(&egalax_i2c->work)) {
/* if work was pending disable-count is now 2 */
pr_info("%s: work was pending\n", __func__);
enable_irq(p_egalax_i2c_dev->irq);
}
printk(KERN_DEBUG "[egalax_i2c]: device suspend done\n");
@ -588,11 +604,45 @@ static int egalax_i2c_resume(struct i2c_client *client)
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void egalax_i2c_early_suspend(struct early_suspend *h)
{
pm_message_t mesg = {.event = 0};
struct suspend_info *info = container_of(h,struct suspend_info,early_suspend);
struct i2c_client *client = info->egalax_i2c->client;
egalax_i2c_suspend(client,mesg);
}
static void egalax_i2c_early_resume(struct early_suspend *h)
{
struct suspend_info *info = container_of(h,struct suspend_info,early_suspend);
struct i2c_client *client = info->egalax_i2c->client;
egalax_i2c_resume(client);
}
#endif
#else
#define egalax_i2c_suspend NULL
#define egalax_i2c_resume NULL
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
static struct suspend_info suspend_info = {
.early_suspend.suspend = egalax_i2c_early_suspend,
.early_suspend.resume = egalax_i2c_early_resume,
.early_suspend.level = EETI_EARLYSUSPEND_LEVEL,
};
#endif
static int __devinit egalax_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int ret;
@ -654,6 +704,13 @@ if (pdata->init_platform_hw)
device_init_wakeup(&client->dev, 0);
#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
suspend_info.egalax_i2c = p_egalax_i2c_dev;
register_early_suspend(&suspend_info.early_suspend);
#endif
printk(KERN_DEBUG "[egalax_i2c]: probe done\n");
return 0;
@ -722,8 +779,8 @@ static struct i2c_driver egalax_i2c_driver = {
.id_table = egalax_i2c_idtable,
.probe = egalax_i2c_probe,
.remove = __devexit_p(egalax_i2c_remove),
.suspend = egalax_i2c_suspend,
.resume = egalax_i2c_resume,
//.suspend = egalax_i2c_suspend,
//.resume = egalax_i2c_resume,
};
static const struct file_operations egalax_cdev_fops = {

View File

@ -59,10 +59,8 @@
#include <media/soc_camera.h> /* ddl@rock-chips.com : camera support */
#include <mach/vpu_mem.h>
#include <mach/sram.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
static struct early_suspend ft5406_early_suspend;
#endif
static struct early_suspend ft5406_power;
@ -676,6 +674,15 @@ static int ft5406_resume(struct i2c_client *client)
return 0;
}
static void ft5406_suspend_early(struct early_suspend *h)
{
ft5406_suspend(this_client,PMSG_SUSPEND);
}
static void ft5406_resume_early(struct early_suspend *h)
{
ft5406_resume(this_client);
}
static int __devexit ft5406_remove(struct i2c_client *client)
{
struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);
@ -686,9 +693,7 @@ static int __devexit ft5406_remove(struct i2c_client *client)
cancel_work_sync(&ft5x0x_ts->pen_event_work);
destroy_workqueue(ft5x0x_ts->ts_workqueue);
i2c_set_clientdata(client, NULL);
#ifdef CONFIG_HAS_EARLYSUSPEND
unregister_early_suspend(&ft5406_early_suspend);
#endif
unregister_early_suspend(&ft5406_power);
this_client = NULL;
return 0;
}
@ -836,12 +841,10 @@ static int ft5406_probe(struct i2c_client *client ,const struct i2c_device_id *
}
i2c_set_clientdata(client, ft5x0x_ts);
#if 0//def CONFIG_HAS_EARLYSUSPEND
ft5406_early_suspend.suspend =ft5406_ts_suspend;
ft5406_early_suspend.resume =ft5406_ts_resume;
ft5406_early_suspend.level = 0x2;
register_early_suspend(&ft5406_early_suspend);
#endif
ft5406_power.suspend =ft5406_suspend_early;
ft5406_power.resume =ft5406_resume_early;
ft5406_power.level = 0x2;
register_early_suspend(&ft5406_power);
buf_w[0] = 6;
err = ft5406_set_regs(client,0x88,buf_w,1);
@ -884,8 +887,6 @@ static struct i2c_driver ft5406_driver = {
},
.id_table = ft5406_idtable,
.probe = ft5406_probe,
.suspend = ft5406_suspend,
.resume = ft5406_resume,
.remove = __devexit_p(ft5406_remove),
};

View File

@ -30,6 +30,17 @@
#include <linux/async.h>
#include <mach/gpio.h>
#include <mach/board.h>
#include <linux/earlysuspend.h>
struct FTS_TS_DATA_T {
struct i2c_client *client;
struct input_dev *input_dev;
struct FTS_TS_EVENT_T event;
struct work_struct pen_event_work;
struct workqueue_struct *ts_workqueue;
struct early_suspend early_suspend;
};
/* -------------- global variable definition -----------*/
static struct i2c_client *this_client;
static REPORT_FINGER_INFO_T _st_finger_infos[CFG_MAX_POINT_NUM];
@ -54,6 +65,13 @@ char *tsp_keyname[CFG_NUMOFKEYS] ={
static bool tsp_keystatus[CFG_NUMOFKEYS];
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ft5x0x_ts_early_suspend(struct early_suspend *h);
static void ft5x0x_ts_late_resume(struct early_suspend *h);
#endif
/***********************************************************************
[function]:
callback: read data from ctpm by i2c interface;
@ -234,7 +252,7 @@ static int fts_i2c_rxdata(u8 *rxdata, int length)
ret = i2c_transfer(this_client->adapter, &msg, 1);
if (ret < 0)
pr_err("msg %s i2c write error: %d\n", __func__, ret);
pr_err("msg %s line:%d i2c write error: %d\n", __func__, __LINE__,ret);
msg.addr = this_client->addr;
msg.flags = I2C_M_RD;
@ -242,7 +260,7 @@ static int fts_i2c_rxdata(u8 *rxdata, int length)
msg.buf = rxdata;
ret = i2c_transfer(this_client->adapter, &msg, 1);
if (ret < 0)
pr_err("msg %s i2c write error: %d\n", __func__, ret);
pr_err("msg %s line:%d i2c write error: %d\n", __func__,__LINE__, ret);
return ret;
}
@ -423,11 +441,9 @@ int fts_read_data(void)
_st_finger_infos[id].ui2_id = size;
_si_touch_num ++;
}
else
/*bad event, ignore*/
else /*bad event, ignore*/
continue;
if ( (touch_event==1) )
{
// printk("[TSP]id=%d up\n", id);
@ -436,7 +452,6 @@ int fts_read_data(void)
for( i= 0; i<CFG_MAX_POINT_NUM; ++i )
{
input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, _st_finger_infos[i].ui2_id);
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, _st_finger_infos[i].u2_pressure);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, SCREEN_MAX_X - _st_finger_infos[i].i2_x);
@ -796,6 +811,66 @@ unsigned char fts_ctpm_get_upg_ver(void)
}
void ft5x0x_ts_set_standby(struct i2c_client *client, int enable)
{
struct laibao_platform_data *mach_info = client->dev.platform_data;
unsigned display_on = mach_info->lcd_disp_on_pin;
unsigned lcd_cs = mach_info->lcd_cs_pin;
int display_on_pol = mach_info->disp_on_value;
int lcd_cs_pol = mach_info->lcd_cs_value;
printk("%s : %s, enable = %d", __FILE__, __FUNCTION__,enable);
if(display_on != INVALID_GPIO)
{
gpio_direction_output(display_on, 0);
gpio_set_value(display_on, enable ? display_on_pol : !display_on_pol);
}
if(lcd_cs != INVALID_GPIO)
{
gpio_direction_output(lcd_cs, 0);
gpio_set_value(lcd_cs, enable ? lcd_cs_pol : !lcd_cs_pol);
}
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void ft5x0x_ts_early_suspend(struct early_suspend *h)
{
struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client);
printk("enter ft5x0x_ts_early_suspend\n");
disable_irq_nosync(this_client->irq);
cancel_work_sync(&data->pen_event_work);
ft5x0x_ts_set_standby(this_client,0);
return;
}
static void ft5x0x_ts_late_resume(struct early_suspend *h)
{
struct FTS_TS_DATA_T *data = i2c_get_clientdata(this_client);
ft5x0x_ts_set_standby(this_client,1);
if(!work_pending(&data->pen_event_work)){
PREPARE_WORK(&data->pen_event_work, fts_work_func);
queue_work(data->ts_workqueue, &data->pen_event_work);
}
else
enable_irq(this_client->irq);
printk("ft5x0x_ts_late_resume finish\n");
return ;
}
#else
#define egalax_i2c_suspend NULL
#define egalax_i2c_resume NULL
#endif
static int fts_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
@ -826,6 +901,7 @@ static int fts_ts_probe(struct i2c_client *client, const struct i2c_device_id *i
}
this_client = client;
ft5x0x_ts->client = client;
i2c_set_clientdata(client, ft5x0x_ts);
INIT_WORK(&ft5x0x_ts->pen_event_work, fts_work_func);
@ -944,6 +1020,15 @@ static int fts_ts_probe(struct i2c_client *client, const struct i2c_device_id *i
goto exit_input_register_device_failed;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;
ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_early_suspend;
ft5x0x_ts->early_suspend.resume = ft5x0x_ts_late_resume;
register_early_suspend(&ft5x0x_ts->early_suspend);
#endif
enable_irq(_sui_irq_num);
printk("[TSP] file(%s), function (%s), -- end\n", __FILE__, __FUNCTION__);
return 0;

10
drivers/input/touchscreen/ft5x0x_i2c_ts.h Normal file → Executable file
View File

@ -13,8 +13,8 @@
#define CFG_NUMOFKEYS 0x4 //number of touch keys
#ifdef CONFIG_FTS_CUSTOME_ENV
#define SCREEN_MAX_X 1024
#define SCREEN_MAX_Y 600
#define SCREEN_MAX_X 1044//1024
#define SCREEN_MAX_Y 620//600
#else
#define SCREEN_MAX_X 800
#define SCREEN_MAX_Y 480
@ -80,12 +80,6 @@ typedef enum
u8 touch_point;
};
struct FTS_TS_DATA_T {
struct input_dev *input_dev;
struct FTS_TS_EVENT_T event;
struct work_struct pen_event_work;
struct workqueue_struct *ts_workqueue;
};

View File

@ -554,7 +554,7 @@
0x12,0x1f,0xea,0x90,0x8, 0x27,0xe0,0x70,0x10,0x90,0x8, 0x20,0xe0,0xb4,0x4, 0x9,
0x90,0xa, 0xda,0xe4,0xf0,0xa3,0x74,0xa, 0xf0,0xd3,0x90,0xa, 0xdb,0xe0,0x94,0x0,
0x90,0xa, 0xda,0xe0,0x94,0x0, 0x40,0x12,0xa3,0xe0,0x24,0xff,0xf0,0x90,0xa, 0xda,
0xe0,0x34,0xff,0xf0,0x90,0x8, 0x20,0x74,0x4, 0xf0,0xb1,0xcc,0x12,0x50,0x8, 0x90,
0xe0,0x34,0xff,0xf0,0x90,0x8, 0x20,0x74,0x4, 0xf0,0xb1,0xcc,0x12,0x50,0x5, 0x90,
0x9, 0x15,0xef,0xf0,0xf1,0x6c,0xb1,0xd5,0x12,0x58,0x41,0xf1,0x43,0x11,0xe6,0x90,
0x8, 0x20,0xe0,0xb4,0x6, 0xe, 0x90,0x8, 0x60,0xe0,0xd3,0x94,0x1, 0x40,0x5, 0xe4,
0x90,0x8, 0x20,0xf0,0xf1,0xaf,0x75,0x27,0x1, 0x75,0x28,0x9, 0x75,0x29,0x18,0xf1,
@ -1167,17 +1167,17 @@
0x74,0x53,0x25,0x2c,0xf5,0x82,0x74,0xb, 0x35,0x2b,0xf5,0x83,0xe4,0xf0,0x5, 0x2c,
0xe5,0x2c,0x70,0x2, 0x5, 0x2b,0xb4,0x5e,0xe7,0xe5,0x2b,0xb4,0x1, 0xe2,0xe5,0x2d,
0xf4,0x60,0x4, 0x7f,0x4, 0x51,0xbf,0x22,0xa3,0xf0,0xe4,0xa3,0xf0,0xa3,0x22,0x12,
0x17,0xeb,0x90,0xc, 0xb2,0x74,0x11,0xf0,0xa3,0x74,0x32,0xf0,0x90,0xc, 0xb7,0x74,
0x17,0xeb,0x90,0xc, 0xb2,0x74,0x19,0xf0,0xa3,0x74,0x32,0xf0,0x90,0xc, 0xb7,0x74,
0xa0,0xf0,0xa3,0x74,0x1, 0xf0,0xa3,0x74,0xc8,0xf0,0xa3,0x74,0x7, 0xf0,0xa3,0x74,
0x28,0xf0,0x90,0xc, 0xc9,0x74,0x32,0xf0,0x90,0xc, 0xd2,0x74,0xff,0xf0,0x90,0xc,
0xd5,0x74,0x55,0xf0,0xa3,0x74,0x1, 0xf0,0xe4,0xa3,0xf0,0xa3,0x74,0x14,0xf0,0xa3,
0xd5,0x74,0x55,0xf0,0xa3,0x74,0x1, 0xf0,0xe4,0xa3,0xf0,0xa3,0x74,0x15,0xf0,0xa3,
0x74,0x1, 0xf0,0x74,0x79,0x31,0x8, 0xf0,0x90,0xc, 0xe1,0x4, 0xf0,0x90,0xc, 0xe0,
0x74,0x96,0xf0,0x90,0xc, 0xe5,0x74,0x1e,0xf0,0xa3,0x74,0x28,0xf0,0x12,0x15,0xfb,
0xe4,0x12,0x1, 0xc5,0x12,0x15,0xfb,0x4, 0x12,0x3f,0xb7,0x90,0x0, 0x9, 0xe4,0x12,
0x1, 0xd7,0x90,0x0, 0x3, 0x74,0xe, 0x12,0x1, 0xd7,0x74,0x7, 0x12,0x27,0xed,0x74,
0x28,0x51,0x7a,0x74,0x28,0x12,0x1, 0xd7,0x90,0x0, 0x8, 0x74,0xc8,0x12,0x1, 0xd7,
0x90,0x0, 0xa, 0x74,0x1, 0x12,0x1, 0xd7,0x12,0x47,0x5c,0x12,0x16,0x23,0xe4,0x75,
0xf0,0x46,0x12,0x3, 0x3c,0x12,0x16,0x23,0x90,0x0, 0x2, 0x74,0x11,0x12,0x1, 0xd7,
0xf0,0x64,0x12,0x3, 0x3c,0x12,0x16,0x23,0x90,0x0, 0x2, 0x74,0x19,0x12,0x1, 0xd7,
0x90,0x0, 0x3, 0xe4,0x75,0xf0,0x32,0x12,0x3, 0x5b,0x90,0x0, 0x22,0x74,0x10,0x12,
0x1, 0xd7,0x90,0x0, 0x15,0x74,0x3, 0x12,0x1, 0xd7,0x90,0x0, 0x16,0x74,0x3, 0x12,
0x1, 0xd7,0x90,0x0, 0x1a,0xe4,0x12,0x1, 0xd7,0x90,0x0, 0x1b,0x74,0x18,0x12,0x1,
@ -1258,51 +1258,51 @@
0xaf,0x33,0xfe,0xc2,0x88,0xd2,0xa8,0xc2,0xaf,0x30,0x89,0x6, 0xc2,0x89,0xe4,0xff,
0x80,0x1, 0xf, 0xef,0xd3,0x94,0xfa,0x40,0xf0,0xee,0x24,0xff,0x92,0xaf,0x75,0xf7,
0xff,0x22,0x12,0x17,0xeb,0xe4,0xf5,0x24,0x75,0x25,0x1, 0x12,0x16,0x23,0xe5,0x25,
0x12,0x68,0x11,0xe5,0x24,0x12,0x68,0xb, 0x12,0x2, 0xb7,0xc3,0x94,0xf1,0x12,0x51,
0x7c,0x40,0x2, 0xe1,0xf0,0xe4,0xf5,0x27,0x85,0x25,0x26,0x12,0x16,0x23,0x12,0x67,
0x94,0x75,0xf0,0x2, 0xe5,0x24,0x12,0x14,0x5c,0x12,0x68,0x8e,0x94,0x80,0x50,0x5,
0x75,0x27,0x1, 0x80,0xb, 0xe5,0x26,0xd3,0x94,0x1, 0x40,0x4, 0x15,0x26,0x80,0xdb,
0xe5,0x27,0x70,0x2a,0xe5,0x25,0x4, 0xf5,0x26,0xe5,0x26,0xc3,0x94,0x18,0x50,0x1e,
0x12,0x16,0x23,0x12,0x67,0x94,0x75,0xf0,0x2, 0xe5,0x24,0x12,0x14,0x5c,0x12,0x68,
0x8e,0x94,0x80,0x50,0x5, 0x75,0x27,0x1, 0x80,0x4, 0x5, 0x26,0x80,0xdb,0xe5,0x27,
0x64,0x1, 0x60,0x2, 0xe1,0xf0,0x12,0x16,0x23,0xe5,0x25,0x12,0x1b,0xee,0x12,0x67,
0xbb,0xea,0x35,0xf0,0x12,0x37,0xef,0x12,0x37,0xbe,0xae,0xf0,0x2d,0xf5,0x29,0xec,
0x3e,0xf5,0x28,0xe5,0x26,0x12,0x1b,0xee,0xe5,0x26,0x12,0x67,0xbd,0xea,0x35,0xf0,
0x12,0x37,0xef,0x12,0x37,0xbe,0xae,0xf0,0x2d,0xf5,0x2b,0xec,0x3e,0xf5,0x2a,0xe5,
0x26,0x7c,0x0, 0x12,0x67,0xbf,0xec,0x35,0xf0,0x12,0x37,0xef,0x33,0x8f,0x82,0xf5,
0x83,0x12,0x1b,0xff,0x12,0x67,0xbb,0xea,0x35,0xf0,0x12,0x37,0xef,0x12,0x37,0xbe,
0x12,0x68,0x84,0xc0,0x6, 0xc0,0x7, 0xc3,0xe5,0x29,0x95,0x2b,0xff,0xe5,0x28,0x95,
0x2a,0xfe,0x12,0x0, 0x6, 0xd0,0x5, 0xd0,0x4, 0xd3,0xef,0x9d,0xec,0x12,0x5f,0x15,
0x40,0x3e,0xab,0x21,0xe5,0x23,0x24,0x60,0xf9,0xe5,0x22,0x34,0x7, 0xfa,0xe5,0x25,
0x75,0xf0,0x10,0xa4,0x25,0x24,0x12,0x66,0xd7,0xfe,0xef,0x78,0x3, 0x12,0x2d,0x56,
0xd8,0xfb,0x12,0x7, 0x74,0xff,0xe5,0x25,0xc4,0x54,0xf0,0x25,0x24,0x54,0x7, 0xfe,
0x74,0x1, 0xa8,0x6, 0x8, 0x80,0x2, 0xc3,0x33,0xd8,0xfc,0xf4,0x5f,0x12,0x1, 0xc5,
0x5, 0x25,0xe5,0x25,0xc3,0x94,0x18,0x50,0x2, 0xc1,0xbb,0x5, 0x24,0xe5,0x24,0xc3,
0x94,0xe, 0x50,0x3, 0x2, 0x4e,0xb8,0x22,0x12,0x17,0xeb,0xe4,0xf5,0x2b,0xf5,0x2c,
0x12,0x15,0xfb,0x12,0x17,0xe5,0x60,0x8, 0x90,0x0, 0x2e,0x12,0x1, 0x65,0x60,0x3,
0x7f,0x0, 0x22,0x12,0x1, 0x4c,0xc3,0x13,0xf5,0x28,0x12,0x2b,0x2f,0xc3,0x13,0xf5,
0x29,0xe4,0xf5,0x2a,0xf5,0x27,0x12,0x16,0x23,0x12,0x14,0x4c,0x12,0x0, 0x6, 0xd3,
0xef,0x94,0x14,0xee,0x64,0x80,0x94,0x80,0x40,0x2, 0x5, 0x2a,0x31,0x3e,0x40,0xe6,
0xe5,0x2a,0xd3,0x94,0xa, 0x40,0x2, 0x31,0x46,0xe4,0xf5,0x2a,0xe5,0x28,0xd3,0x94,
0x0, 0x40,0x32,0xe4,0xf5,0x27,0x12,0x16,0x23,0x12,0x14,0x4c,0x12,0x0, 0x6, 0xc0,
0x6, 0xc0,0x7, 0xe5,0x28,0x75,0xf0,0x20,0xa4,0x24,0x60,0x31,0x61,0x12,0x16,0x23,
0x12,0x14,0x57,0x12,0x0, 0x6, 0xd0,0x5, 0xd0,0x4, 0x12,0x2e,0xbe,0x40,0x2, 0x5,
0x2a,0x31,0x3e,0x40,0xd1,0xe5,0x2a,0xd3,0x94,0xa, 0x40,0x2, 0x31,0x46,0xe4,0xf5,
0x2a,0xe5,0x28,0xc3,0x94,0x18,0x50,0x32,0xe4,0xf5,0x27,0x12,0x16,0x23,0x12,0x14,
0x4c,0x12,0x0, 0x6, 0xc0,0x6, 0xc0,0x7, 0xe5,0x28,0x75,0xf0,0x20,0xa4,0x24,0xa0,
0x31,0x61,0x12,0x16,0x23,0x12,0x14,0x57,0x12,0x0, 0x6, 0xd0,0x5, 0xd0,0x4, 0x12,
0x2e,0xbe,0x40,0x2, 0x5, 0x2a,0x31,0x3e,0x40,0xd1,0xe5,0x2a,0xd3,0x94,0xa, 0x40,
0x2, 0x31,0x46,0xe5,0x29,0xd3,0x94,0x0, 0x40,0x1f,0xe5,0x28,0x75,0xf0,0x20,0x12,
0x1b,0xe2,0xe5,0x29,0x75,0xf0,0x2, 0xa4,0x24,0x7e,0xff,0xe5,0xf0,0x34,0x3, 0xfe,
0x12,0x2e,0xd6,0x31,0x76,0x50,0x2, 0x31,0x6a,0xe5,0x29,0x24,0x1, 0xff,0xe4,0x33,
0xfe,0xc3,0xef,0x94,0x19,0xee,0x64,0x80,0x94,0x80,0x50,0x1f,0xe5,0x28,0x75,0xf0,
0x12,0x68,0x11,0xe5,0x24,0x12,0x68,0xb, 0x12,0x2, 0xb7,0x12,0x51,0x6d,0x40,0x2,
0xe1,0xed,0xe4,0xf5,0x27,0x85,0x25,0x26,0x12,0x16,0x23,0x12,0x67,0x94,0x75,0xf0,
0x2, 0xe5,0x24,0x12,0x14,0x5c,0x12,0x68,0x8e,0x94,0x80,0x50,0x5, 0x75,0x27,0x1,
0x80,0xb, 0xe5,0x26,0xd3,0x94,0x1, 0x40,0x4, 0x15,0x26,0x80,0xdb,0xe5,0x27,0x70,
0x2a,0xe5,0x25,0x4, 0xf5,0x26,0xe5,0x26,0xc3,0x94,0x18,0x50,0x1e,0x12,0x16,0x23,
0x12,0x67,0x94,0x75,0xf0,0x2, 0xe5,0x24,0x12,0x14,0x5c,0x12,0x68,0x8e,0x94,0x80,
0x50,0x5, 0x75,0x27,0x1, 0x80,0x4, 0x5, 0x26,0x80,0xdb,0xe5,0x27,0x64,0x1, 0x60,
0x2, 0xe1,0xed,0x12,0x16,0x23,0xe5,0x25,0x12,0x1b,0xee,0x12,0x67,0xbb,0xea,0x35,
0xf0,0x12,0x37,0xef,0x12,0x37,0xbe,0xae,0xf0,0x2d,0xf5,0x29,0xec,0x3e,0xf5,0x28,
0xe5,0x26,0x12,0x1b,0xee,0xe5,0x26,0x12,0x67,0xbd,0xea,0x35,0xf0,0x12,0x37,0xef,
0x12,0x37,0xbe,0xae,0xf0,0x2d,0xf5,0x2b,0xec,0x3e,0xf5,0x2a,0xe5,0x26,0x7c,0x0,
0x12,0x67,0xbf,0xec,0x35,0xf0,0x12,0x37,0xef,0x33,0x8f,0x82,0xf5,0x83,0x12,0x1b,
0xff,0x12,0x67,0xbb,0xea,0x35,0xf0,0x12,0x37,0xef,0x12,0x37,0xbe,0x12,0x68,0x84,
0xc0,0x6, 0xc0,0x7, 0xc3,0xe5,0x29,0x95,0x2b,0xff,0xe5,0x28,0x95,0x2a,0xfe,0x12,
0x0, 0x6, 0xd0,0x5, 0xd0,0x4, 0xd3,0xef,0x9d,0xec,0x12,0x5f,0x15,0x40,0x3e,0xab,
0x21,0xe5,0x23,0x24,0x60,0xf9,0xe5,0x22,0x34,0x7, 0xfa,0xe5,0x25,0x75,0xf0,0x10,
0xa4,0x25,0x24,0x12,0x66,0xd7,0xfe,0xef,0x78,0x3, 0x12,0x2d,0x56,0xd8,0xfb,0x12,
0x7, 0x74,0xff,0xe5,0x25,0xc4,0x54,0xf0,0x25,0x24,0x54,0x7, 0xfe,0x74,0x1, 0xa8,
0x6, 0x8, 0x80,0x2, 0xc3,0x33,0xd8,0xfc,0xf4,0x5f,0x12,0x1, 0xc5,0x5, 0x25,0xe5,
0x25,0xc3,0x94,0x18,0x50,0x2, 0xc1,0xbb,0x5, 0x24,0xe5,0x24,0xc3,0x94,0xe, 0x50,
0x3, 0x2, 0x4e,0xb8,0x22,0x12,0x17,0xeb,0xe4,0xf5,0x2b,0xf5,0x2c,0x12,0x15,0xfb,
0x12,0x17,0xe5,0x60,0x8, 0x90,0x0, 0x2e,0x12,0x1, 0x65,0x60,0x3, 0x7f,0x0, 0x22,
0x12,0x1, 0x4c,0xc3,0x13,0xf5,0x28,0x12,0x2b,0x2f,0xc3,0x13,0xf5,0x29,0xe4,0xf5,
0x2a,0xf5,0x27,0x12,0x16,0x23,0x12,0x14,0x4c,0x12,0x0, 0x6, 0xd3,0xef,0x94,0x14,
0xee,0x64,0x80,0x94,0x80,0x40,0x2, 0x5, 0x2a,0x31,0x41,0x40,0xe6,0xe5,0x2a,0xd3,
0x94,0xa, 0x40,0x2, 0x31,0x49,0xe4,0xf5,0x2a,0xe5,0x28,0xd3,0x94,0x0, 0x40,0x32,
0xe4,0xf5,0x27,0x12,0x16,0x23,0x12,0x14,0x4c,0x12,0x0, 0x6, 0xc0,0x6, 0xc0,0x7,
0xe5,0x28,0x75,0xf0,0x20,0xa4,0x24,0x60,0x31,0x64,0x12,0x16,0x23,0x12,0x14,0x57,
0x12,0x0, 0x6, 0xd0,0x5, 0xd0,0x4, 0x12,0x2e,0xbe,0x40,0x2, 0x5, 0x2a,0x31,0x41,
0x40,0xd1,0xe5,0x2a,0xd3,0x94,0xa, 0x40,0x2, 0x31,0x49,0xe4,0xf5,0x2a,0xe5,0x28,
0xc3,0x94,0x18,0x50,0x32,0xe4,0xf5,0x27,0x12,0x16,0x23,0x12,0x14,0x4c,0x12,0x0,
0x6, 0xc0,0x6, 0xc0,0x7, 0xe5,0x28,0x75,0xf0,0x20,0xa4,0x24,0xa0,0x31,0x64,0x12,
0x16,0x23,0x12,0x14,0x57,0x12,0x0, 0x6, 0xd0,0x5, 0xd0,0x4, 0x12,0x2e,0xbe,0x40,
0x2, 0x5, 0x2a,0x31,0x41,0x40,0xd1,0xe5,0x2a,0xd3,0x94,0xa, 0x40,0x2, 0x31,0x49,
0xe5,0x29,0xd3,0x94,0x0, 0x40,0x22,0xe5,0x28,0x75,0xf0,0x20,0x12,0x1b,0xe2,0xe5,
0x29,0x75,0xf0,0x2, 0xa4,0x24,0x7e,0xff,0xe5,0xf0,0x34,0x3, 0xfe,0x12,0x2e,0xd6,
0x12,0x2, 0x8c,0x31,0x6d,0x50,0x2, 0x31,0x77,0xe5,0x29,0x24,0x1, 0xff,0xe4,0x33,
0xfe,0xc3,0xef,0x94,0x19,0xee,0x64,0x80,0x94,0x80,0x50,0x22,0xe5,0x28,0x75,0xf0,
0x20,0x12,0x1b,0xe2,0xe5,0x29,0x75,0xf0,0x2, 0xa4,0x24,0x82,0xff,0xe5,0xf0,0x34,
0x3, 0xfe,0x12,0x2e,0xd6,0x31,0x76,0x50,0x2, 0x31,0x6a,0xaf,0x2c,0x22,0x5, 0x27,
0xe5,0x27,0xc3,0x94,0xe, 0x22,0xe5,0x2a,0x24,0xf6,0xff,0xe4,0x34,0xff,0xfe,0x7c,
0x0, 0x7d,0xa, 0x12,0x1, 0xf9,0xef,0x25,0x2c,0xf5,0x2c,0xee,0x35,0x2b,0xf5,0x2b,
0x22,0xf5,0x82,0x74,0x3, 0x35,0xf0,0xf5,0x83,0x22,0x74,0xa, 0x25,0x2c,0xf5,0x2c,
0xe4,0x35,0x2b,0xf5,0x2b,0x22,0x12,0x2, 0x8c,0xc3,0x94,0xce,0xe5,0xf0,0x64,0x80,
0x94,0x7f,0x22,0x12,0x17,0xeb,0x90,0x0, 0x2f,0x51,0xe, 0x30,0xe0,0x3a,0x12,0x16,
0x3, 0xfe,0x12,0x2e,0xd6,0x12,0x2, 0x8c,0x31,0x6d,0x50,0x2, 0x31,0x77,0xaf,0x2c,
0x22,0x5, 0x27,0xe5,0x27,0xc3,0x94,0xe, 0x22,0xe5,0x2a,0x24,0xf6,0xff,0xe4,0x34,
0xff,0xfe,0x7c,0x0, 0x7d,0xa, 0x12,0x1, 0xf9,0xef,0x25,0x2c,0xf5,0x2c,0xee,0x35,
0x2b,0xf5,0x2b,0x22,0xf5,0x82,0x74,0x3, 0x35,0xf0,0xf5,0x83,0x22,0xc3,0x94,0xce,
0xe5,0xf0,0x64,0x80,0x94,0x7f,0x22,0x74,0xa, 0x25,0x2c,0xf5,0x2c,0xe4,0x35,0x2b,
0xf5,0x2b,0x22,0x12,0x17,0xeb,0x90,0x0, 0x2f,0x51,0xe, 0x30,0xe0,0x3a,0x12,0x16,
0x23,0x90,0x0, 0x4d,0x12,0x2, 0xb7,0xc3,0x94,0x3c,0xe5,0xf0,0x94,0x0, 0x50,0xc,
0x90,0x0, 0x4d,0xe4,0x75,0xf0,0x1, 0x12,0x2, 0xef,0x80,0x1c,0x12,0x15,0xfb,0x12,
0x3e,0xc5,0x85,0x24,0x35,0x12,0x3f,0x94,0x12,0x14,0x13,0x12,0x2d,0xf1,0x90,0xa,
@ -1681,4 +1681,4 @@
0xff,0x74,0xff,0x3e,0xfe,0x22,0xe0,0xfc,0xa3,0xe0,0xd3,0x9f,0xec,0x22,0xee,0xf0,
0xa3,0xef,0xf0,0x5, 0x2c,0x22,0xff,0xab,0x29,0xe5,0x2b,0x24,0x1c,0x22,0x74,0x32,
0x25,0x2a,0xf8,0x76,0x1, 0x22,0xf9,0xe4,0x35,0x22,0xfa,0xe5,0x2b,0x22,0xc3,0xef,
0x94,0x3, 0xee,0x94,0x0, 0x22,0x69,0x36,0x96,0xc9,0x9, 0xf6,0x14,0xeb,
0x94,0x3, 0xee,0x94,0x0, 0x22,0x69,0x36,0x96,0xc9,0x7c,0x83,0x15,0xea,

View File

@ -98,6 +98,7 @@ unsigned int crc32_table[256];
unsigned int oldcrc32 = 0xFFFFFFFF;
unsigned int ulPolynomial = 0x04c11db7;
struct i2c_client * i2c_connect_client = NULL;
static struct early_suspend gt819_power;
static u8 gt819_fw[]=
{
#include "gt819_fw.i"
@ -555,6 +556,17 @@ static int gt819_resume(struct i2c_client *client)
return 0;
}
static void gt819_early_suspend(struct early_suspend *h)
{
dev_info(&i2c_connect_client->dev, "gt819_early_suspend!\n");
gt819_suspend(i2c_connect_client,PMSG_SUSPEND);
}
static void gt819_early_resume(struct early_suspend *h)
{
dev_info(&i2c_connect_client->dev, "gt819_resume_early!\n");
gt819_resume(i2c_connect_client);
}
/*******************************************************
Description:
@ -573,14 +585,16 @@ static int gt819_remove(struct i2c_client *client)
remove_proc_entry("goodix-update", NULL);
#endif
//goodix_debug_sysfs_deinit();
gpio_direction_input(ts->irq_gpio);
gpio_free(ts->irq_gpio);
free_irq(client->irq, ts);
gpio_direction_input(ts->irq_gpio);
gpio_free(ts->irq_gpio);
free_irq(client->irq, ts);
if(ts->goodix_wq)
destroy_workqueue(ts->goodix_wq);
dev_notice(&client->dev,"The driver is removing...\n");
i2c_set_clientdata(client, NULL);
input_unregister_device(ts->input_dev);
unregister_early_suspend(&gt819_power);
i2c_connect_client = 0;
kfree(ts);
return 0;
}
@ -588,7 +602,22 @@ static int gt819_remove(struct i2c_client *client)
static int gt819_init_panel(struct goodix_ts_data *ts)
{
int ret,I2cDelay;
int len = sizeof(config_info)-1;
uint8_t rd_cfg_buf[10];
struct goodix_platform_data *pdata = ts->client->dev.platform_data;
ret = gt819_set_regs(ts->client, 101, &config_info[1], len);
if(ret < 0)
{
pdata->platform_sleep();
msleep(10);
pdata->platform_wakeup();
msleep(100);
printk("First IIC request failed,retry!\n");
ret = gt819_set_regs(ts->client, 101, &config_info[1], len);
if(ret<0)
return ret;
}
ret = gt819_read_regs(ts->client, 101, rd_cfg_buf, 10);
if (ret < 0)
@ -636,7 +665,7 @@ static int gt819_probe(struct i2c_client *client, const struct i2c_device_id *id
{
int ret = 0;
char version[17];
char version_base[17]={"GT81XNI_1R05_18G"};
char version_base[17]={"GT81XNI_1R05_18Q"};
struct goodix_ts_data *ts;
struct goodix_platform_data *pdata = client->dev.platform_data;
const char irq_table[4] = {IRQ_TYPE_EDGE_RISING,
@ -726,6 +755,10 @@ static int gt819_probe(struct i2c_client *client, const struct i2c_device_id *id
}
i2c_set_clientdata(client, ts);
gt819_power.suspend = gt819_early_suspend;
gt819_power.resume = gt819_early_resume;
gt819_power.level = 0x2;
register_early_suspend(&gt819_power);
return 0;
i2c_set_clientdata(client, NULL);
input_unregister_device(ts->input_dev);
@ -754,8 +787,6 @@ static const struct i2c_device_id gt819_id[] = {
static struct i2c_driver gt819_driver = {
.probe = gt819_probe,
.remove = gt819_remove,
.suspend = gt819_suspend,
.resume = gt819_resume,
.id_table = gt819_id,
.driver = {
.name = GOODIX_I2C_NAME,

View File

@ -1 +1 @@
0x65,0x02,0x03,0x20,0x01,0xE0,0x05,0xA1,0x21,0x00,0x0F,0x0F,0x02,0x10,0x10,0x00,0x00,0x38,0x00,0x00,0x10,0x10,0x10,0x00,0x17,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,0x00,0x28,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40
0x65,0x02,0x03,0x20,0x01,0xE0,0x05,0xA1,0x21,0x00,0x0F,0x0F,0x20,0x10,0x10,0x00,0x00,0x20,0x00,0x00,0x10,0x10,0x10,0x00,0x37,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0xFF,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0x00,0x00,0x46,0x78,0x2E,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x02,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -151,7 +151,7 @@ static ssize_t ilitek_file_write(struct file *filp, const char *buf, size_t coun
msg[0].scl_rate = 400*1000;
msg[0].udelay = 80;
printk("%s:count=0x%x\n",__FUNCTION__,count);
DBG("%s:count=0x%x\n",__FUNCTION__,count);
// before sending data to touch device, we need to check whether the device is working or not
if(g_ts->valid_i2c_register == 0){
@ -266,7 +266,7 @@ static int ilitek_file_ioctl(struct inode *inode, struct file *filp, unsigned in
return -1;
}
printk("%s:cmd=0x%x\n",__FUNCTION__,cmd);
DBG("%s:cmd=0x%x\n",__FUNCTION__,cmd);
return 0;
}

17
drivers/media/video/gc0309.c Normal file → Executable file
View File

@ -428,7 +428,18 @@ static struct reginfo sensor_init_data[] =
/////////////////////////////////////////////////////////////////////
/////////////////////////// eeintp_t///////////////////////////////
#endif
{0x23,0x00},
{0x2d,0x0a}, // 0x08
{0x20,0xff},
{0xd2,0x90},
{0x73,0x00},
{0x77,0x54},
{0xb3,0x40},
{0xb4,0x80},
{0xba,0x00},
{0xbb,0x00},
{0x00,0x00}
};
@ -1811,9 +1822,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
sensor->info_priv.snap2preview = false;
}
SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),__FUNCTION__,set_w,set_h);
}
else
{
} else {
SENSOR_DG("\n %s .. Current Format is validate. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),set_w,set_h);
}

24
drivers/media/video/mt9t111.c Normal file → Executable file
View File

@ -31,7 +31,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
printk(KERN_WARNING fmt , ## arg); } while (0)
#define SENSOR_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
#define SENSOR_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
#define SENSOR_DG(format, ...) dprintk(1, format, ## __VA_ARGS__)
#define _CONS(a,b) a##b
#define CONS(a,b) _CONS(a,b)
@ -1813,7 +1813,7 @@ static struct reginfo sensor_init_data[] =
{0x0014, 0x2447, WORD_LEN, 0 }, // PLL_CONTROL
{0x0014, 0x2047, WORD_LEN, 0 }, // PLL_CONTROL
{ SEQUENCE_WAIT_MS,10, WORD_LEN, 0},
{SEQUENCE_WAIT_MS,50, WORD_LEN, 0},
// POLL PLL_CONTROL::PLL_LOCK => 0x01
{0x0014, 0x2046, WORD_LEN, 0 }, // PLL_CONTROL
{0x0022, 0x01E0, WORD_LEN, 0 }, // VDD_DIS_COUNTER//208
@ -1826,7 +1826,7 @@ static struct reginfo sensor_init_data[] =
{0x0018, 0x402C, WORD_LEN, 0 }, // STANDBY_CONTROL_AND_STATUS
{0x001e,0x0006, WORD_LEN, 0 }, //adjust slew rate to minimize EMI
{ SEQUENCE_WAIT_MS,10, WORD_LEN, 0},
{SEQUENCE_WAIT_MS,100, WORD_LEN, 0},
// POLL STANDBY_CONTROL_AND_STATUS::STANDBY_DONE => 0x00
//{0x098E, 0x6006, WORD_LEN, 0 }, // MCU_ADDRESS
@ -7238,12 +7238,10 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
ret |= sensor_write_array(client, sensor_Preview2Capture);
if (ret != 0) {
SENSOR_TR("-----------%s : %s : %d Preview 2 Capture failed\n", SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
goto sensor_s_fmt_end;
}
SENSOR_TR("-----------%s : %s : %d Preview 2 Capture success!\n", SENSOR_NAME_STRING(),__FUNCTION__,__LINE__);
SENSOR_TR("%s Preview 2 Capture failed\n", SENSOR_NAME_STRING());
goto sensor_s_fmt_end;
}
SENSOR_DG("%s Preview 2 Capture success!\n", SENSOR_NAME_STRING());
#if CONFIG_SENSOR_Flash
if( (sensor->info_priv.flash == 1)|| (sensor->info_priv.flash == 2)) {
@ -7271,7 +7269,7 @@ static int sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
mdelay(200); //delay microseconds to forbid invalidate data
SENSOR_TR("%s Capture 2 Preview success\n", SENSOR_NAME_STRING());
SENSOR_DG("%s Capture 2 Preview success\n", SENSOR_NAME_STRING());
/* #if CONFIG_SENSOR_Flash
if ((sensor->info_priv.flash == 1) || (sensor->info_priv.flash == 2)) {
@ -8083,8 +8081,6 @@ static int sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_c
if (sensor_set_flash(icd, qctrl,ext_ctrl->value) != 0)
return -EINVAL;
sensor->info_priv.flash = ext_ctrl->value;
SENSOR_DG("--------flash------------%s flash is %x %d\n",SENSOR_NAME_STRING(), sensor->info_priv.flash,__LINE__);
break;
}
#endif
@ -8126,9 +8122,7 @@ static int sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_control
{
struct i2c_client *client = sd->priv;
struct soc_camera_device *icd = client->dev.platform_data;
int i, error_cnt=0, error_idx=-1;
SENSOR_DG("\n%s..%s.. ext_ctrl->count = %d\n",__FUNCTION__,SENSOR_NAME_STRING(),ext_ctrl->count);
int i, error_cnt=0, error_idx=-1;
for (i=0; i<ext_ctrl->count; i++) {
if (sensor_s_ext_control(icd, &ext_ctrl->controls[i]) != 0) {

View File

@ -65,8 +65,8 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
#define CONFIG_SENSOR_Focus 0
#define CONFIG_SENSOR_Exposure 0
#define CONFIG_SENSOR_Flash 1
#define CONFIG_SENSOR_Mirror 1
#define CONFIG_SENSOR_Flip 1
#define CONFIG_SENSOR_Mirror 0
#define CONFIG_SENSOR_Flip 0
#define CONFIG_SENSOR_I2C_SPEED 350000 /* Hz */
/* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */

2
drivers/media/video/ov3640.c Executable file → Normal file
View File

@ -63,7 +63,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR);
#define CONFIG_SENSOR_Scene 1
#define CONFIG_SENSOR_DigitalZoom 0
#define CONFIG_SENSOR_Exposure 0
#define CONFIG_SENSOR_Flash 1
#define CONFIG_SENSOR_Flash 0
#define CONFIG_SENSOR_Mirror 0
#define CONFIG_SENSOR_Flip 0
#ifdef CONFIG_OV3640_AUTOFOCUS

View File

@ -1648,7 +1648,7 @@ static int sensor_write_array(struct i2c_client *client, struct reginfo *regarra
int size_num;
size_num = reg_num + 1;
ptemp = phead = (u8*)kmalloc(size_num*sizeof(u8),GFP_KERNEL);
ptemp = phead = (u8*)kmalloc((size_num+10)*sizeof(u8),GFP_KERNEL);
if (!phead) {
SENSOR_DG("-------------write registers allocate memory fail!!!\n");
i = j;

View File

@ -862,15 +862,17 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
if (urb == NULL)
continue;
usb_kill_urb(urb);
usb_free_urb(urb);
stream->urb[i] = NULL;
/* ddl@rock-chips.com */
/* ddl@rock-chips.com: Tasklet must be kill before kill urb in uninit */
if (stream->tasklet[i]) {
tasklet_kill(stream->tasklet[i]);
kfree(stream->tasklet[i]);
stream->tasklet[i] = NULL;
}
usb_kill_urb(urb);
usb_free_urb(urb);
stream->urb[i] = NULL;
}
if (free_buffers)

View File

@ -401,21 +401,6 @@ config EP93XX_PWM
To compile this driver as a module, choose M here: the module will
be called ep93xx_pwm.
config STE
bool "STE modem control driver"
config MTK23D
bool "MTK6223D modem control driver"
config FM580X
bool "FM rda580x driver"
config MU509
bool "MU509 modem control driver"
config RK29_NEWTON
bool "RK29_NEWTON misc driver"
config DS1682
tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
depends on I2C && EXPERIMENTAL
@ -511,6 +496,28 @@ config TEGRA_CRYPTO_DEV
Dev node /dev/tegra-crypto in order to get access to tegra aes
hardware from user space
config STE
bool "STE modem control driver"
default n
config MTK23D
bool "MTK6223D modem control driver"
default n
config FM580X
bool "FM rda580x driver"
default n
config MU509
bool "MU509 modem control driver"
default n
config MW100
bool "MW100 modem control driver"
default n
config RK29_NEWTON
bool "RK29_NEWTON misc driver"
default n
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"

274
drivers/misc/MW100.c Normal file
View File

@ -0,0 +1,274 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/circ_buf.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <mach/iomux.h>
#include <mach/gpio.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <linux/wakelock.h>
#include <linux/workqueue.h>
#include <linux/mu509.h>
#include <mach/iomux.h>
#include<linux/ioctl.h>
MODULE_LICENSE("GPL");
//#define DEBUG
#ifdef DEBUG
#define MODEMDBG(x...) printk(x)
#else
#define MODEMDBG(fmt,argss...)
#endif
#define MW100IO 0XA1
#define MW_IOCTL_RESET _IO(MW100IO,0X01)
#define SLEEP 1
#define READY 0
#define MU509_RESET 0x01
static struct wake_lock modem_wakelock;
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
struct rk29_mu509_data *gpdata = NULL;
static int bp_wakeup_ap_irq = 0;
static void ap_wakeup_bp(struct platform_device *pdev, int wake)
{
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
MODEMDBG("ap_wakeup_bp\n");
gpio_set_value(pdata->ap_wakeup_bp, wake);
}
extern void rk28_send_wakeup_key(void);
static void do_wakeup(struct work_struct *work)
{
MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
rk28_send_wakeup_key();
enable_irq(bp_wakeup_ap_irq);
}
static DECLARE_DELAYED_WORK(wakeup_work, do_wakeup);
static irqreturn_t detect_irq_handler(int irq, void *dev_id)
{
disable_irq_nosync( irq);
printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
schedule_delayed_work(&wakeup_work, HZ / 10);
return IRQ_HANDLED;
}
int modem_poweron_off(int on_off)
{
struct rk29_mu509_data *pdata = gpdata;
if(on_off)
{
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
/*
gpio_set_value(pdata->bp_power, GPIO_LOW);
msleep(1000);
gpio_set_value(pdata->bp_power, GPIO_HIGH);
msleep(700);
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
*/
}
else
{
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
/*
gpio_set_value(pdata->bp_power, GPIO_LOW);
mdelay(2500);
gpio_set_value(pdata->bp_power, GPIO_HIGH);
*/
}
return 0;
}
static int mu509_open(struct inode *inode, struct file *file)
{
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
//modem_poweron_off(1);
return 0;
}
static int mu509_release(struct inode *inode, struct file *file)
{
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
//modem_poweron_off(0);
return 0;
}
static int mu509_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
{
struct rk29_mu509_data *pdata = gpdata;
switch(cmd)
{
case MW_IOCTL_RESET:
printk("%s::%d--bruins--ioctl mw100 reset\n",__func__,__LINE__);
gpio_direction_output(pdata->bp_reset,GPIO_LOW);
mdelay(120);
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
break;
default:
break;
}
return 0;
}
static struct file_operations mu509_fops = {
.owner = THIS_MODULE,
.open = mu509_open,
.release = mu509_release,
.ioctl = mu509_ioctl
};
static struct miscdevice mu509_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mw100",
.fops = &mu509_fops
};
static int mu509_probe(struct platform_device *pdev)
{
struct rk29_mu509_data *pdata = gpdata = pdev->dev.platform_data;
struct modem_dev *mu509_data = NULL;
int result, irq = 0;
gpio_request(pdata->bp_power,"bp_power");
gpio_request(pdata->bp_reset,"bp_reset");
gpio_request(pdata->bp_wakeup_ap,"bp_wakeup_ap");
gpio_request(pdata->ap_wakeup_bp,"ap_wakeup_bp");
rk29_mux_api_set(GPIO6C76_CPUTRACEDATA76_NAME, GPIO4H_GPIO6C76);
gpio_direction_output(pdata->bp_reset,GPIO_LOW);
mdelay(120);
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
gpio_direction_output(pdata->ap_wakeup_bp,GPIO_HIGH);
gpio_set_value(pdata->bp_power, GPIO_HIGH);
gpio_direction_output(pdata->bp_power,GPIO_HIGH);
mdelay(120);
gpio_set_value(pdata->bp_power, GPIO_LOW);
gpio_direction_output(pdata->bp_power,GPIO_LOW);
//±£Áô
/* gpio_set_value(pdata->bp_reset, GPIO_LOW);
gpio_direction_output(pdata->bp_reset,GPIO_LOW);
mdelay(120);
gpio_set_value(pdata->bp_reset, GPIO_HIGH);
gpio_direction_output(pdata->bp_reset,GPIO_HIGH);
*/
mu509_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
if(mu509_data == NULL){
printk("failed to request mu509_data\n");
goto err2;
}
platform_set_drvdata(pdev, mu509_data);
gpio_direction_input(pdata->bp_wakeup_ap);
irq = gpio_to_irq(pdata->bp_wakeup_ap);
if(irq < 0){
gpio_free(pdata->bp_wakeup_ap);
printk("failed to request bp_wakeup_ap\n");
}
bp_wakeup_ap_irq = irq;
result = request_irq(irq, detect_irq_handler, IRQ_BB_WAKEUP_AP_TRIGGER, "bp_wakeup_ap", NULL);
if (result < 0) {
printk("%s: request_irq(%d) failed\n", __func__, irq);
gpio_free(pdata->bp_wakeup_ap);
goto err0;
}
enable_irq_wake(bp_wakeup_ap_irq);
result = misc_register(&mu509_misc);
if(result){
MODEMDBG("misc_register err\n");
}
return result;
err0:
gpio_free(pdata->bp_wakeup_ap);
err1:
gpio_free(pdata->ap_wakeup_bp);
err2:
kfree(mu509_data);
return 0;
}
int mu509_suspend(struct platform_device *pdev)
{
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
MODEMDBG("%s::%d--\n",__func__,__LINE__);
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
return 0;
}
int mu509_resume(struct platform_device *pdev)
{
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
gpio_set_value(pdata->ap_wakeup_bp, GPIO_HIGH);
return 0;
}
void mu509_shutdown(struct platform_device *pdev, pm_message_t state)
{
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
struct modem_dev *mu509_data = platform_get_drvdata(pdev);
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
gpio_set_value(pdata->bp_power, GPIO_HIGH);
mdelay(2010);
gpio_free(pdata->bp_power);
gpio_free(pdata->bp_reset);
gpio_free(pdata->ap_wakeup_bp);
gpio_free(pdata->bp_wakeup_ap);
kfree(mu509_data);
}
static struct platform_driver mu509_driver = {
.probe = mu509_probe,
.shutdown = mu509_shutdown,
.suspend = mu509_suspend,
.resume = mu509_resume,
.driver = {
.name = "MW100",
.owner = THIS_MODULE,
},
};
static int __init mu509_init(void)
{
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
return platform_driver_register(&mu509_driver);
}
static void __exit mu509_exit(void)
{
MODEMDBG("%s::%d--bruins--\n",__func__,__LINE__);
platform_driver_unregister(&mu509_driver);
}
module_init(mu509_init);
module_exit(mu509_exit);

View File

@ -39,6 +39,7 @@ obj-y += cb710/
obj-$(CONFIG_MTK23D) += mtk23d.o
obj-$(CONFIG_FM580X) += fm580x.o
obj-$(CONFIG_MU509) += mu509.o
obj-$(CONFIG_MW100) += MW100.o
obj-$(CONFIG_STE) += ste.o
obj-$(CONFIG_RK29_SUPPORT_MODEM) += rk29_modem/
obj-$(CONFIG_GPS_GNS7560) += gps/

6
drivers/misc/gps/rk29_gps.c Normal file → Executable file
View File

@ -34,8 +34,14 @@ static int rk29_gps_uart_to_gpio(int uart_id)
gpio_request(RK29_PIN2_PB3, NULL);
gpio_request(RK29_PIN2_PB2, NULL);
gpio_pull_updown(RK29_PIN2_PB3, PullDisable);
gpio_pull_updown(RK29_PIN2_PB2, PullDisable);
gpio_direction_output(RK29_PIN2_PB3, GPIO_LOW);
gpio_direction_output(RK29_PIN2_PB2, GPIO_LOW);
gpio_free(RK29_PIN2_PB3);
gpio_free(RK29_PIN2_PB2);
}
else if(uart_id == 2) {
rk29_mux_api_set(GPIO2B1_UART2SOUT_NAME, GPIO2L_GPIO2B1);

View File

@ -30,18 +30,19 @@ MODULE_LICENSE("GPL");
#endif
#define SLEEP 1
#define READY 0
#define MU509_RESET 0x01
static struct wake_lock modem_wakelock;
#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_FALLING
//#define IRQ_BB_WAKEUP_AP_TRIGGER IRQF_TRIGGER_RISING
#define airplane_mode RK29_PIN6_PC1
#define MU509_RESET 0x01
#define AIRPLANE_MODE_OFF 0x03
#define AIRPLANE_MODE_ON 0x00
struct rk29_mu509_data *gpdata = NULL;
static int do_wakeup_irq = 0;
static void ap_wakeup_bp(struct platform_device *pdev, int wake)
{
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
//struct modem_dev *mu509_data = platform_get_drvdata(pdev);
MODEMDBG("ap_wakeup_bp\n");
gpio_set_value(pdata->ap_wakeup_bp, wake);
@ -50,7 +51,7 @@ extern void rk28_send_wakeup_key(void);
static void do_wakeup(struct work_struct *work)
{
printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
// MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
rk28_send_wakeup_key();
}
@ -60,7 +61,7 @@ static irqreturn_t detect_irq_handler(int irq, void *dev_id)
if(do_wakeup_irq)
{
do_wakeup_irq = 0;
printk("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
// MODEMDBG("%s[%d]: %s\n", __FILE__, __LINE__, __FUNCTION__);
wake_lock_timeout(&modem_wakelock, 10 * HZ);
schedule_delayed_work(&wakeup_work, HZ / 10);
}
@ -71,21 +72,17 @@ int modem_poweron_off(int on_off)
struct rk29_mu509_data *pdata = gpdata;
if(on_off)
{
printk("------------modem_poweron\n");
// gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_LOW:GPIO_HIGH);
// mdelay(300);
// gpio_set_value(pdata->bp_reset, pdata->bp_reset_active_low? GPIO_HIGH:GPIO_LOW);
// msleep(4000);
// gpio_set_value(pdata->bp_power, pdata->bp_power_active_low? GPIO_HIGH:GPIO_LOW);
MODEMDBG("------------modem_poweron\n");
gpio_set_value(pdata->bp_power, GPIO_LOW);
msleep(1000);
gpio_set_value(pdata->bp_power, GPIO_HIGH);
msleep(700);
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
gpio_set_value(airplane_mode, GPIO_HIGH);
}
else
{
printk("------------modem_poweroff\n");
MODEMDBG("------------modem_poweroff\n");
gpio_set_value(pdata->bp_power, GPIO_LOW);
mdelay(2500);
gpio_set_value(pdata->bp_power, GPIO_HIGH);
@ -94,22 +91,23 @@ int modem_poweron_off(int on_off)
}
static int mu509_open(struct inode *inode, struct file *file)
{
printk("-------------%s\n",__FUNCTION__);
modem_poweron_off(1);
//MODEMDBG("-------------%s\n",__FUNCTION__);
struct rk29_mu509_data *pdata = gpdata;
struct platform_data *pdev = container_of(pdata, struct device, platform_data);
device_init_wakeup(&pdev, 1);
return 0;
}
static int mu509_release(struct inode *inode, struct file *file)
{
printk("-------------%s\n",__FUNCTION__);
//modem_poweron_off(0);
//MODEMDBG("-------------%s\n",__FUNCTION__);
return 0;
}
static int mu509_ioctl(struct inode *inode,struct file *file, unsigned int cmd, unsigned long arg)
{
struct rk29_mu509_data *pdata = gpdata;
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
switch(cmd)
{
case MU509_RESET:
@ -122,6 +120,13 @@ static int mu509_ioctl(struct inode *inode,struct file *file, unsigned int cmd,
gpio_set_value(pdata->bp_power, GPIO_HIGH);
msleep(700);
gpio_set_value(pdata->ap_wakeup_bp, GPIO_LOW);
gpio_set_value(airplane_mode, GPIO_HIGH);
break;
case AIRPLANE_MODE_ON:
gpio_set_value(airplane_mode, GPIO_LOW);
break;
case AIRPLANE_MODE_OFF:
gpio_set_value(airplane_mode, GPIO_HIGH);
break;
default:
break;
@ -147,7 +152,7 @@ static int mu509_probe(struct platform_device *pdev)
struct rk29_mu509_data *pdata = gpdata = pdev->dev.platform_data;
struct modem_dev *mu509_data = NULL;
int result, irq = 0;
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
modem_poweron_off(1);
mu509_data = kzalloc(sizeof(struct modem_dev), GFP_KERNEL);
if(mu509_data == NULL)
@ -182,11 +187,11 @@ static int mu509_probe(struct platform_device *pdev)
goto err0;
}
enable_irq_wake(gpio_to_irq(pdata->bp_wakeup_ap));
printk("%s: request_irq(%d) success\n", __func__, irq);
result = misc_register(&mu509_misc);
if(result)
{
MODEMDBG("misc_register err\n");
printk("misc_register err\n");
}
return result;
err0:
@ -202,16 +207,14 @@ static int mu509_probe(struct platform_device *pdev)
int mu509_suspend(struct platform_device *pdev)
{
do_wakeup_irq = 1;
//struct rk29_mu509_data *pdata = pdev->dev.platform_data;
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
ap_wakeup_bp(pdev, 1);
return 0;
}
int mu509_resume(struct platform_device *pdev)
{
//struct rk29_mu509_data *pdata = pdev->dev.platform_data;
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
ap_wakeup_bp(pdev, 0);
return 0;
}
@ -221,7 +224,7 @@ void mu509_shutdown(struct platform_device *pdev, pm_message_t state)
struct rk29_mu509_data *pdata = pdev->dev.platform_data;
struct modem_dev *mu509_data = platform_get_drvdata(pdev);
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
modem_poweron_off(0);
cancel_work_sync(&mu509_data->work);
gpio_free(pdata->bp_power);
@ -244,13 +247,13 @@ static struct platform_driver mu509_driver = {
static int __init mu509_init(void)
{
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
return platform_driver_register(&mu509_driver);
}
static void __exit mu509_exit(void)
{
printk("-------------%s\n",__FUNCTION__);
//MODEMDBG("-------------%s\n",__FUNCTION__);
platform_driver_unregister(&mu509_driver);
}

View File

@ -211,6 +211,7 @@ static void mmc_wait_done(struct mmc_request *mrq)
*/
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
{
unsigned long waittime;
DECLARE_COMPLETION_ONSTACK(complete);
mrq->done_data = &complete;
@ -219,8 +220,13 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
mmc_start_request(host, mrq);
#if defined(CONFIG_SDMMC_RK29) && !defined(CONFIG_SDMMC_RK29_OLD)
wait_for_completion_timeout(&complete,HZ*3); //for cmd dead. Modifyed by xbw at 2011-06-02
#else
waittime = wait_for_completion_timeout(&complete,HZ*7); //for cmd dead. Modifyed by xbw at 2011-06-02
if(waittime <= 1)
{
host->doneflag = 0;
printk("%s...%d.. =====!!!!!!!!!CMD%d timeout ===xbw===\n",__FUNCTION__, __LINE__, mrq->cmd->opcode);
}
#else
wait_for_completion(&complete);
#endif
}

13
drivers/mmc/host/Kconfig Normal file → Executable file
View File

@ -24,6 +24,13 @@ if SDMMC_RK29
depends on ARCH_RK29
help
This supports the use of the SDMMC0 controller on Rk29 processors.
config SDMMC0_RK29_WRITE_PROTECT
bool "Write-protect for SDMMC0"
depends on SDMMC0_RK29
help
You will add the feature of write-protect for sdmmc-card if you say Yes.
Please note that this feature requires hardware support.
# config EMMC_RK29
# tristate "RK29 EMMC controller support(sdmmc)"
# default y
@ -36,6 +43,12 @@ if SDMMC_RK29
depends on ARCH_RK29
help
This supports the use of the SDMMC1 controller on Rk29 processors.
config SDMMC1_RK29_WRITE_PROTECT
bool "Write-protect for SDMMC1"
depends on SDMMC1_RK29
help
You will add the feature of write-protect for sdio-card if you say Yes.
Please note that this feature requires hardware support.
endif
config MMC_ARMMMCI

View File

@ -63,7 +63,7 @@ int debug_level = 7;
#define xbwprintk(n, arg...)
#endif
#define RK29_SDMMC_ERROR_FLAGS (SDMMC_INT_FRUN | SDMMC_INT_RTO | SDMMC_INT_HLE )
#define RK29_SDMMC_ERROR_FLAGS (SDMMC_INT_FRUN | SDMMC_INT_HLE )
#define RK29_SDMMC_INTMASK_USEDMA (SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS | SDMMC_INT_CD)
#define RK29_SDMMC_INTMASK_USEIO (SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS | SDMMC_INT_CD| SDMMC_INT_TXDR | SDMMC_INT_RXDR )
@ -74,7 +74,7 @@ int debug_level = 7;
#define RK29_SDMMC_WAIT_DTO_INTERNVAL 1500 //The time interval from the CMD_DONE_INT to DTO_INT
#define RK29_SDMMC_REMOVAL_DELAY 2000 //The time interval from the CD_INT to detect_timer react.
#define RK29_SDMMC_VERSION "Ver.2.01 The last modify date is 2011-08-19,modifyed by XBW."
#define RK29_SDMMC_VERSION "Ver.2.09 The last modify date is 2011-09-22,modifyed by XBW."
#define RK29_CTRL_SDMMC_ID 0 //mainly used by SDMMC
#define RK29_CTRL_SDIO1_ID 1 //mainly used by sdio-wifi
@ -198,10 +198,17 @@ struct rk29_sdmmc {
unsigned int oldstatus;
unsigned int complete_done;
unsigned int retryfunc;
#ifdef CONFIG_PM
int gpio_irq;
int gpio_det;
#endif
#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) || defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
int write_protect;
#endif
};
@ -211,6 +218,8 @@ static struct rk29_sdmmc *globalSDhost[3];
#define rk29_sdmmc_test_and_clear_pending(host, event) \
test_and_clear_bit(event, &host->pending_events)
#define rk29_sdmmc_test_pending(host, event) \
test_bit(event, &host->pending_events)
#define rk29_sdmmc_set_completed(host, event) \
set_bit(event, &host->completed_events)
@ -271,7 +280,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
if( !strncmp(buf,"version" , strlen("version")))
{
printk("The driver SDMMC named 'rk29_sdmmc.c' is %s. ====xbw====\n", RK29_SDMMC_VERSION);
printk("\n The driver SDMMC named 'rk29_sdmmc.c' is %s. ==xbw==\n", RK29_SDMMC_VERSION);
return count;
}
@ -332,7 +341,7 @@ ssize_t rk29_sdmmc_progress_store(struct kobject *kobj, struct kobj_attribute *a
__LINE__, unmounting_times, host->dma_name);
}
host->mmc->re_initialized_flags = 0;
mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY));
mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY*2));
}
else if( !strncmp(buf, "sd-No-Media", strlen("sd-No-Media")))
{
@ -650,6 +659,7 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command
host->cmd = cmd;
host->old_cmd = cmd->opcode;
host->errorstep = 0;
rk29_sdmmc_write(host->regs, SDMMC_CMDARG, cmd->arg); // write to SDMMC_CMDARG register
rk29_sdmmc_write(host->regs, SDMMC_CMD, cmd_flags | SDMMC_CMD_START); // write to SDMMC_CMD register
@ -658,6 +668,8 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command
xbwprintk(5, "\n%s..%d..************.start cmd=%d, arg=0x%x ********=====xbw[%s]=======\n", \
__FUNCTION__, __LINE__, cmd->opcode, cmd->arg, host->dma_name);
host->mmc->doneflag = 1;
/* wait until CIU accepts the command */
while (--tmo && (rk29_sdmmc_read(host->regs, SDMMC_CMD) & SDMMC_CMD_START))
{
@ -679,7 +691,7 @@ static int rk29_sdmmc_start_command(struct rk29_sdmmc *host, struct mmc_command
host->errorstep = 0x1;
return SDM_WAIT_FOR_CMDSTART_TIMEOUT;
}
return SDM_SUCCESS;
}
@ -734,7 +746,9 @@ static int rk29_sdmmc_wait_unbusy(struct rk29_sdmmc *host)
static void send_stop_cmd(struct rk29_sdmmc *host)
{
mod_timer(&host->request_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_SEND_START_TIMEOUT+250));
int ret;
mod_timer(&host->request_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_SEND_START_TIMEOUT+600));
host->stopcmd.opcode = MMC_STOP_TRANSMISSION;
host->stopcmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;;
@ -743,9 +757,23 @@ static void send_stop_cmd(struct rk29_sdmmc *host)
host->stopcmd.mrq = NULL;
host->stopcmd.retries = 0;
host->stopcmd.error = 0;
if(host->mrq && host->mrq->stop)
{
host->mrq->stop->error = 0;
}
host->cmdr = rk29_sdmmc_prepare_command(&host->stopcmd);
rk29_sdmmc_start_command(host, &host->stopcmd, host->cmdr);
rk29_sdmmc_wait_unbusy(host);
ret = rk29_sdmmc_start_command(host, &host->stopcmd, host->cmdr);
if(SDM_SUCCESS != ret)
{
rk29_sdmmc_start_error(host);
host->state = STATE_IDLE;
host->complete_done = 4;
}
}
static void rk29_sdmmc_dma_cleanup(struct rk29_sdmmc *host)
@ -949,7 +977,7 @@ static int rk29_sdmmc_prepare_write_data(struct rk29_sdmmc *host, struct mmc_dat
}
else
{
xbwprintk(3, "%s..%d... trace data, ======xbw=[%s]====\n", __FUNCTION__, __LINE__, host->dma_name);
xbwprintk(7, "%s..%d... trace data, ======xbw=[%s]====\n", __FUNCTION__, __LINE__, host->dma_name);
output = rk29_sdmmc_submit_data_dma(host, data);
if(output)
{
@ -1134,6 +1162,7 @@ static void rk29_sdmmc_submit_data(struct rk29_sdmmc *host, struct mmc_data *dat
{
host->data = data;
data->error = 0;
host->cmd->data = data;
data->bytes_xfered = 0;
host->pbuf = (u32*)sg_virt(data->sg);
@ -1151,13 +1180,13 @@ static void rk29_sdmmc_submit_data(struct rk29_sdmmc *host, struct mmc_data *dat
rk29_sdmmc_write(host->regs, SDMMC_BYTCNT,data->blksz*data->blocks);
rk29_sdmmc_write(host->regs, SDMMC_BLKSIZ,data->blksz);
xbwprintk(3, "%s..%d... trace data, CMD%d, data->blksz=%d, data->blocks=%d ======xbw=[%s]====\n", \
__FUNCTION__, __LINE__, host->cmd->opcode,data->blksz, data->blocks, host->dma_name);
xbwprintk(3, "%s..%d..CMD%d(arg=0x%x), data->blksz=%d, data->blocks=%d ==xbw=[%s]==\n", \
__FUNCTION__, __LINE__, host->cmd->opcode,host->cmd->arg,data->blksz, data->blocks, host->dma_name);
if (data->flags & MMC_DATA_WRITE)
{
host->cmdr |= (SDMMC_CMD_DAT_WRITE | SDMMC_CMD_DAT_EXP);
xbwprintk(3, "%s..%d... write data, len=%d ======xbw=[%s]====\n", \
xbwprintk(7, "%s..%d... write data, len=%d ======xbw=[%s]====\n", \
__FUNCTION__, __LINE__, data->blksz*data->blocks, host->dma_name);
ret = rk29_sdmmc_prepare_write_data(host, data);
@ -1165,7 +1194,7 @@ static void rk29_sdmmc_submit_data(struct rk29_sdmmc *host, struct mmc_data *dat
else
{
host->cmdr |= (SDMMC_CMD_DAT_READ | SDMMC_CMD_DAT_EXP);
xbwprintk(3, "%s..%d... read data len=%d ======xbw=[%s]====\n", \
xbwprintk(7, "%s..%d... read data len=%d ======xbw=[%s]====\n", \
__FUNCTION__, __LINE__, data->blksz*data->blocks, host->dma_name);
ret = rk29_sdmmc_prepare_read_data(host, data);
@ -1580,6 +1609,9 @@ void rk29_sdmmc_set_frq(struct rk29_sdmmc *host)
static void rk29_sdmmc_dealwith_timeout(struct rk29_sdmmc *host)
{
if(0 == host->mmc->doneflag)
return; //not to generate error flag if the command has been over.
switch(host->state)
{
case STATE_IDLE:
@ -1629,6 +1661,9 @@ static void rk29_sdmmc_dealwith_timeout(struct rk29_sdmmc *host)
static void rk29_sdmmc_INT_CMD_DONE_timeout(unsigned long host_data)
{
struct rk29_sdmmc *host = (struct rk29_sdmmc *) host_data;
unsigned long iflags;
spin_lock_irqsave(&host->lock, iflags);
if(STATE_SENDING_CMD == host->state)
{
@ -1640,6 +1675,7 @@ static void rk29_sdmmc_INT_CMD_DONE_timeout(unsigned long host_data)
rk29_sdmmc_dealwith_timeout(host);
}
spin_unlock_irqrestore(&host->lock, iflags);
}
@ -1647,6 +1683,9 @@ static void rk29_sdmmc_INT_CMD_DONE_timeout(unsigned long host_data)
static void rk29_sdmmc_INT_DTO_timeout(unsigned long host_data)
{
struct rk29_sdmmc *host = (struct rk29_sdmmc *) host_data;
unsigned long iflags;
spin_lock_irqsave(&host->lock, iflags);
if( (host->cmdr & SDMMC_CMD_DAT_EXP) && (STATE_DATA_BUSY == host->state))
@ -1659,6 +1698,8 @@ static void rk29_sdmmc_INT_DTO_timeout(unsigned long host_data)
rk29_sdmmc_dealwith_timeout(host);
}
spin_unlock_irqrestore(&host->lock, iflags);
}
@ -1678,7 +1719,6 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
mrq = host->new_mrq;
cmd = mrq->cmd;
cmd->error = 0;
host->complete_done = 0;
cmdr = rk29_sdmmc_prepare_command(cmd);
ret = SDM_SUCCESS;
@ -1721,6 +1761,7 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
mrq = host->mrq;
cmd = mrq->cmd;
cmd->error = 0;
cmd->data = NULL;
host->cmdr = cmdr;
host->cmd = cmd;
@ -1731,6 +1772,8 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
host->errorstep = 0;
host->dodma = 0;
host->complete_done = 0;
host->retryfunc = 0;
if(RK29_CTRL_SDMMC_ID == host->pdev->id)
{
@ -1789,9 +1832,18 @@ static int rk29_sdmmc_start_request(struct mmc_host *mmc )
}
host->state = STATE_IDLE; //modifyed by xbw at 2011-08-15
spin_unlock_irqrestore(&host->lock, iflags);
mmc_request_done(host->mmc, host->mrq);
if(host->mrq && host->mmc->doneflag)
{
host->mmc->doneflag = 0;
spin_unlock_irqrestore(&host->lock, iflags);
mmc_request_done(host->mmc, host->mrq);
}
else
{
spin_unlock_irqrestore(&host->lock, iflags);
}
return ret;
@ -1815,6 +1867,7 @@ static void rk29_sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
printk("%s..%d.. ==== The %s had been closed by myself for the experiment. ====xbw[%s]===\n",\
__FUNCTION__, __LINE__, host->dma_name, host->dma_name);
host->state = STATE_IDLE;
spin_unlock_irqrestore(&host->lock, iflags);
mmc_request_done(mmc, mrq);
goto request_ext;//return;
@ -1854,14 +1907,15 @@ static void rk29_sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
else
{
if(host->error_times++ % (RK29_ERROR_PRINTK_INTERVAL*2) ==0)
if(host->error_times++ % (RK29_ERROR_PRINTK_INTERVAL*3) ==0)
{
printk("%s: Refuse to run CMD%2d(arg=0x%8x) due to the removal of card. 3==xbw[%s]==\n", \
__FUNCTION__, mrq->cmd->opcode, mrq->cmd->arg, host->dma_name);
}
host->old_cmd = mrq->cmd->opcode;
}
}
host->state = STATE_IDLE;
spin_unlock_irqrestore(&host->lock, iflags);
mmc_request_done(mmc, mrq);
goto request_ext;//return;
@ -1888,10 +1942,10 @@ static void rk29_sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
__FUNCTION__, __LINE__, host->state, host->cmd->opcode,mrq->cmd->opcode,mrq->cmd->arg, host->dma_name);
}
host->new_mrq = mrq;
spin_unlock_irqrestore(&host->lock, iflags);
host->new_mrq = mrq;
rk29_sdmmc_start_request(mmc);
#else
@ -2047,10 +2101,26 @@ static void rk29_sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
static int rk29_sdmmc_get_ro(struct mmc_host *mmc)
{
struct rk29_sdmmc *host = mmc_priv(mmc);
struct rk29_sdmmc *host = mmc_priv(mmc);
#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) || defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
int ret;
if(INVALID_GPIO == host->write_protect)
ret = 0;//no write-protect
else
ret = gpio_get_value(host->write_protect)?1:0;
xbwprintk(7,"%s..%d.. write_prt_pin=%d, get_ro=%d ===xbw[%s]===\n",\
__FUNCTION__, __LINE__,host->write_protect, ret, host->dma_name);
return ret;
#else
u32 wrtprt = rk29_sdmmc_read(host->regs, SDMMC_WRTPRT);
return (wrtprt & SDMMC_WRITE_PROTECT)?1:0;
#endif
}
@ -2076,6 +2146,52 @@ static void rk29_sdmmc_init_card(struct mmc_host *mmc, struct mmc_card *card)
}
static int rk29_sdmmc_clear_fifo(struct rk29_sdmmc *host)
{
unsigned int timeout, value;
if(RK29_CTRL_SDMMC_ID == host->pdev->id)
{
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS, 0xFFFFFFFF);
}
//stop DMA
if(host->dodma)
{
rk29_sdmmc_stop_dma(host);
rk29_sdmmc_control_host_dma(host, FALSE);
host->dodma = 0;
}
//Clean the fifo.
for(timeout=0; timeout<FIFO_DEPTH; timeout++)
{
if(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)
break;
value = rk29_sdmmc_read(host->regs, SDMMC_DATA);
}
/* reset */
rk29_sdmmc_write(host->regs, SDMMC_CTRL,(SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET ));
timeout = 1000;
value = rk29_sdmmc_read(host->regs, SDMMC_CTRL);
while (( value & (SDMMC_CTRL_FIFO_RESET | SDMMC_CTRL_RESET)) && (timeout > 0))
{
udelay(1);
timeout--;
value = rk29_sdmmc_read(host->regs, SDMMC_CTRL);
}
if (timeout == 0)
{
host->errorstep = 0x0A;
return SDM_WAIT_FOR_FIFORESET_TIMEOUT;
}
}
static const struct mmc_host_ops rk29_sdmmc_ops[] = {
{
@ -2129,7 +2245,7 @@ static void rk29_sdmmc_request_end(struct rk29_sdmmc *host, struct mmc_command *
{
if(status & (SDMMC_INT_DCRC | SDMMC_INT_EBE))
{
cmd->data->error = -EILSEQ;;//mrq->data->error = -EILSEQ;
cmd->data->error = -EILSEQ;
output = SDM_DATA_CRC_ERROR;
host->errorstep = 0x16;
}
@ -2206,6 +2322,7 @@ static void rk29_sdmmc_request_end(struct rk29_sdmmc *host, struct mmc_command *
printk("%s..%d......CMD=%d error!!!, arg=%x, errorTimes=%d, errorStep=0x%x ! ====xbw[%s]====\n",\
__FUNCTION__, __LINE__, cmd->opcode, cmd->arg, host->error_times,host->errorstep, host->dma_name);
}
cmd->error = -ENODATA;
}
exit:
@ -2374,10 +2491,14 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
struct rk29_sdmmc *host = (struct rk29_sdmmc *)priv;
struct mmc_data *data = host->cmd->data;
enum rk29_sdmmc_state state = host->state;
spin_lock(&host->lock);
int pending_flag, stopflag;
unsigned long iflags;
spin_lock_irqsave(&host->lock, iflags);
state = host->state;
pending_flag = 0;
stopflag = 0;
do
{
@ -2412,7 +2533,7 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
__FUNCTION__, __LINE__,host->cmd->opcode,host->dma_name);
host->complete_done = 1;
goto unlock;
break;//goto unlock;
}
if(host->cmd->error)
@ -2424,8 +2545,12 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
xbwprintk(7, "%s..%d.. cmderr, so call send_stop_cmd() ====xbw[%s]====\n", \
__FUNCTION__, __LINE__, host->dma_name);
#if 0
state = STATE_SENDING_CMD;//STATE_SENDING_STOP;
send_stop_cmd(host);
send_stop_cmd(host);
#else
stopflag = 1; //Moidfyed by xbw at 2011-09-08
#endif
break;
}
@ -2433,7 +2558,7 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
}
state = STATE_DATA_BUSY;
state = STATE_DATA_BUSY;
/* fall through */
}
@ -2457,17 +2582,22 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
if(!( (MMC_READ_SINGLE_BLOCK == host->cmd->opcode)&&( -EIO == data->error))) //deal with START_BIT_ERROR
{
host->complete_done = 1;
goto unlock;
host->complete_done = 2;
break;//goto unlock;
}
}
xbwprintk(7, "%s..%d.. after DATA_COMPLETE, so call send_stop_cmd() ====xbw[%s]====\n", \
__FUNCTION__, __LINE__, host->dma_name);
#if 0
state = STATE_SENDING_CMD;
send_stop_cmd(host);
#else
stopflag = 1; //Moidfyed by xbw at 2011-09-08
#endif
break;
}
@ -2483,26 +2613,59 @@ static void rk29_sdmmc_tasklet_func(unsigned long priv)
del_timer_sync(&host->request_timer); //delete the timer for INT_CMD_DONE int CMD12
rk29_sdmmc_request_end(host, host->cmd);
host->complete_done = 1;
goto unlock;
host->complete_done = 3;
break;//goto unlock;
}
}
} while(0);
pending_flag = (host->complete_done > 0) && (host->retryfunc<50) \
&& (rk29_sdmmc_test_pending(host, EVENT_CMD_COMPLETE)|| rk29_sdmmc_test_pending(host, EVENT_DATA_COMPLETE) );
if(pending_flag)
{
xbwprintk(7, "%s..%d... cmd=%d(arg=0x%x),completedone=%d, retrycount=%d, doneflag=%d, \n \
host->state=0x%x, switchstate=%x, \n \
pendingEvent=0x%lu, completeEvents=0x%lu, \n \
mrqCMD=%d, arg=0x%x \n ====xbw[%s]====\n",\
__FUNCTION__, __LINE__,host->cmd->opcode, host->cmd->arg, host->complete_done,\
host->retryfunc, host->mmc->doneflag,host->state, state, \
host->pending_events,host->completed_events,\
host->mrq->cmd->opcode, host->mrq->cmd->arg, host->dma_name);
cpu_relax();
}
} while(pending_flag && ++host->retryfunc); //while(0);
if(1==stopflag)
{
state = STATE_SENDING_CMD;
send_stop_cmd(host); //Moidfyed by xbw at 2011-09-08
}
host->state = state;
unlock:
unlock:
if(0==host->complete_done)
{
spin_unlock(&host->lock);
spin_unlock_irqrestore(&host->lock, iflags);
return;
}
host->state = STATE_IDLE;
spin_unlock(&host->lock);
mmc_request_done(host->mmc, host->mrq);
if(host->mrq && host->mmc->doneflag)
{
host->mmc->doneflag = 0;
spin_unlock_irqrestore(&host->lock, iflags);
mmc_request_done(host->mmc, host->mrq);
}
else
{
spin_unlock_irqrestore(&host->lock, iflags);
}
}
@ -2541,8 +2704,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
pending = rk29_sdmmc_read(host->regs, SDMMC_MINTSTS);// read only mask reg
if (!pending)
{
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
goto Exit_INT;
}
@ -2570,7 +2732,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
if(host->mmc->re_initialized_flags)
{
mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY/2));
mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY));
}
else
{
@ -2587,8 +2749,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
}
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
goto Exit_INT;
}
@ -2601,6 +2762,8 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_CMD_DONE); // clear interrupt
rk29_sdmmc_cmd_interrupt(host, status);
goto Exit_INT;
}
if(pending & SDMMC_INT_SDIO)
@ -2610,6 +2773,8 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_SDIO);
mmc_signal_sdio_irq(host->mmc);
goto Exit_INT;
}
@ -2627,8 +2792,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
if(!(pending & SDMMC_INT_CMD_DONE))
tasklet_schedule(&host->tasklet);
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
goto Exit_INT;
}
@ -2638,8 +2802,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
__FUNCTION__, pending,host->cmd->opcode, host->cmd->arg, host->cmd->retries, host->dma_name);
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_HLE);
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
goto Exit_INT;
}
@ -2658,9 +2821,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
rk29_sdmmc_set_pending(host, EVENT_DATA_COMPLETE);
tasklet_schedule(&host->tasklet);
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
goto Exit_INT;
}
@ -2670,8 +2831,7 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
__FUNCTION__, pending, host->cmd->opcode, host->cmd->arg, host->cmd->retries,host->dma_name);
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_FRUN);
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
goto Exit_INT;
}
if (pending & SDMMC_INT_RXDR)
@ -2693,6 +2853,8 @@ static irqreturn_t rk29_sdmmc_interrupt(int irq, void *dev_id)
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_TXDR); // clear interrupt
}
Exit_INT:
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
}
@ -2800,6 +2962,9 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
host->error_times = 0;
host->state = STATE_IDLE;
host->complete_done = 0;
host->retryfunc = 0;
host->mrq = NULL;
host->new_mrq = NULL;
#ifdef CONFIG_PM
host->gpio_det = pdata->detect_irq;
@ -2851,7 +3016,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
}
else
{
mmc->f_max = RK29_MAX_SDIO_FREQ;//SDHC_FPP_FREQ / 2;
mmc->f_max = RK29_MAX_SDIO_FREQ;
}
#endif
@ -2860,6 +3025,7 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
| MMC_VDD_31_32|MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_34_35| MMC_VDD_35_36; ///set valid volage 2.7---3.6v
mmc->caps = pdata->host_caps;
mmc->re_initialized_flags = 1;
mmc->doneflag = 1;
/*
* We can do SGIO
@ -2891,6 +3057,11 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
tasklet_init(&host->tasklet, rk29_sdmmc_tasklet_func, (unsigned long)host);
/* Create card detect handler thread */
setup_timer(&host->detect_timer, rk29_sdmmc_detect_change,(unsigned long)host);
setup_timer(&host->request_timer,rk29_sdmmc_INT_CMD_DONE_timeout,(unsigned long)host);
setup_timer(&host->DTO_timer,rk29_sdmmc_INT_DTO_timeout,(unsigned long)host);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
{
@ -2947,6 +3118,10 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
host->dma_addr = regs->start + SDMMC_DATA;
}
#if defined(CONFIG_SDMMC0_RK29_WRITE_PROTECT) || defined(CONFIG_SDMMC1_RK29_WRITE_PROTECT)
host->write_protect = pdata->write_prt;
#endif
rk29_sdmmc_hw_init(host);
ret = request_irq(irq, rk29_sdmmc_interrupt, 0, dev_name(&pdev->dev), host);
@ -2966,7 +3141,14 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
if(RK29_CTRL_SDMMC_ID== host->pdev->id)
{
clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
if(rk29_sdmmc_get_cd(host->mmc))
{
set_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
}
else
{
clear_bit(RK29_SDMMC_CARD_PRESENT, &host->flags);
}
}
@ -2980,10 +3162,6 @@ static int rk29_sdmmc_probe(struct platform_device *pdev)
}
}
/* Create card detect handler thread */
setup_timer(&host->detect_timer, rk29_sdmmc_detect_change,(unsigned long)host);
setup_timer(&host->request_timer,rk29_sdmmc_INT_CMD_DONE_timeout,(unsigned long)host);
setup_timer(&host->DTO_timer,rk29_sdmmc_INT_DTO_timeout,(unsigned long)host);
platform_set_drvdata(pdev, mmc);

View File

@ -27,16 +27,30 @@
#include "bu92725guw.h"
#include "ir_serial.h"
#define MAX_FRAME_NUM 20
struct rev_frame_length {
unsigned long frame_length[MAX_FRAME_NUM];
int iRead;
int iWrite;
int iCount;
};
#define frame_read_empty(f) ((f)->iCount == 0)
#define frame_write_full(f) ((f)->iCount == MAX_FRAME_NUM)
#define frame_length_buf_clear(f) ((f)->iCount = (f)->iWrite = (f)->iRead = 0)
struct bu92747_port {
struct device *dev;
struct irda_info *pdata;
struct uart_port port;
/*for FIR fream read*/
unsigned long last_frame_length;
struct rev_frame_length rev_frames;
//unsigned long last_frame_length;
unsigned long cur_frame_length;
wait_queue_head_t data_ready_wq;
atomic_t data_ready;
//wait_queue_head_t data_ready_wq;
//atomic_t data_ready;
spinlock_t data_lock;
int tx_empty; /* last TX empty bit */
@ -46,6 +60,7 @@ struct bu92747_port {
int rx_enabled; /* if we should rx chars */
int irq_pin;
int irq; /* irq assigned to the bu92747 */
int minor; /* minor number */
@ -54,6 +69,8 @@ struct bu92747_port {
struct work_struct work;
/* set to 1 to make the workhandler exit as soon as possible */
int force_end_work;
int open_flag;
/* need to know we are suspending to avoid deadlock on workqueue */
int suspending;
@ -70,17 +87,69 @@ static int max_rate = 4000000;
static u8 g_receive_buf[BU92725GUW_FIFO_SIZE];
#if 0
#define BU92747_IRDA_DBG(x...) printk(x)
#define IRDA_DBG_FUNC(x...) printk(x)
#else
#define BU92747_IRDA_DBG(x...)
#define IRDA_DBG_FUNC(x...)
#endif
#if 0
#define IRDA_DBG_RECV(x...) printk(x)
#else
#define IRDA_DBG_RECV(x...)
#endif
#if 0
#define IRDA_DBG_SENT(x...) printk(x)
#else
#define IRDA_DBG_SENT(x...)
#endif
/* race on startup&shutdown, mutex lock with CIR driver */
static DEFINE_MUTEX(irda_cir_lock);
int bu92747_try_lock(void)
{
if (mutex_trylock(&irda_cir_lock))
return 1; //ready
else
return 0; //busy
}
void bu92747_unlock(void)
{
return mutex_unlock(&irda_cir_lock);
}
static int add_frame_length(struct rev_frame_length *f, unsigned long length)
{
if (frame_write_full(f))
return -1;
f->frame_length[f->iWrite] = length;
f->iCount++;
f->iWrite = (f->iWrite+1) % MAX_FRAME_NUM;
return 0;
}
static int get_frame_length(struct rev_frame_length *f, unsigned long *length)
{
if (frame_read_empty(f))
return -1;
*length = f->frame_length[f->iRead];
f->iCount--;
f->iRead = (f->iRead+1) % MAX_FRAME_NUM;
return 0;
}
static int bu92747_irda_do_rx(struct bu92747_port *s)
{
int i;
unsigned int ch, flag;
//int i;
//unsigned int ch, flag;
int len;
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
struct tty_struct *tty = s->port.state->port.tty;
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (s->rx_enabled == 0) {
BU92725GUW_clr_fifo();
@ -89,6 +158,7 @@ static int bu92747_irda_do_rx(struct bu92747_port *s)
}
len = BU92725GUW_get_data(g_receive_buf);
#if 0
flag = TTY_NORMAL;
//printk("receive data:\n");
for (i=0;i<len;i++) {
@ -98,31 +168,29 @@ static int bu92747_irda_do_rx(struct bu92747_port *s)
//printk("%d ", ch);
}
//printk("\n");
#else
if (len > 0) {
IRDA_DBG_RECV("line %d, enter %s, receive %d data........\n", __LINE__, __func__, len);
tty_insert_flip_string(tty, g_receive_buf, len);
s->port.icount.rx += len;
}
#endif
return len;
}
static int bu92747_irda_do_tx(struct bu92747_port *s)
{
int i;
//int i;
struct circ_buf *xmit = &s->port.state->xmit;
int len = uart_circ_chars_pending(xmit);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_SENT("line %d, enter %s, sending %d data\n", __LINE__, __FUNCTION__, len);
if (IS_FIR(s)) {
//printk("fir sending.....\n");
irda_hw_tx_enable_irq(BU92725GUW_FIR);
}
else {
//printk("sir sending.....\n");
irda_hw_tx_enable_irq(BU92725GUW_SIR);
}
BU92747_IRDA_DBG("data:\n");
for (i=0; i<len; i++) {
BU92747_IRDA_DBG("%d ", xmit->buf[xmit->tail+i]);
}
BU92747_IRDA_DBG("\n");
if (len>0) {
s->tx_empty = 0;
@ -151,12 +219,9 @@ static void bu92747_irda_work(struct work_struct *w)
struct bu92747_port *s = container_of(w, struct bu92747_port, work);
struct circ_buf *xmit = &s->port.state->xmit;
dev_dbg(s->dev, "%s\n", __func__);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_SENT("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (!s->force_end_work && !freezing(current)) {
//BU92725GUW_dump_register();
if (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) {
if (s->tx_empty)
bu92747_irda_do_tx(s);
@ -171,16 +236,15 @@ static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
struct bu92747_port *s = dev_id;
u32 irq_src = 0;
unsigned long len;
struct rev_frame_length *f = &(s->rev_frames);
dev_dbg(s->dev, "%s\n", __func__);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
irq_src = irda_hw_get_irqsrc();
printk("[%s][%d], 0x%x\n",__FUNCTION__,__LINE__, irq_src);
IRDA_DBG_RECV("[%s][%d], 0x%x\n",__FUNCTION__,__LINE__, irq_src);
/* error */
if (irq_src & (REG_INT_TO| REG_INT_CRC | REG_INT_OE | REG_INT_FE
if (irq_src & (REG_INT_CRC | REG_INT_OE | REG_INT_FE
| REG_INT_AC | REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX)) {
BU92747_IRDA_DBG("[%s][%d]: do err\n", __FUNCTION__, __LINE__);
//BU92725GUW_dump_register();
printk("[%s][%d]: do err, REG_EIR = 0x%x\n", __FUNCTION__, __LINE__, irq_src);
BU92725GUW_clr_fifo();
BU92725GUW_reset();
if ((BU92725GUW_SEND==irda_hw_get_mode())
@ -193,20 +257,23 @@ static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
len = bu92747_irda_do_rx(s);
if (!IS_FIR(s))
tty_flip_buffer_push(s->port.state->port.tty);
else
else {
spin_lock(&s->data_lock);
s->cur_frame_length += len;
spin_unlock(&s->data_lock);
}
}
if ((irq_src & REG_INT_EOF) && (s->port.state->port.tty != NULL)) {
tty_flip_buffer_push(s->port.state->port.tty);
if (IS_FIR(s)) {
spin_lock(&s->data_lock);
s->last_frame_length += s->cur_frame_length;
s->cur_frame_length = 0;
atomic_set(&(s->data_ready), 1);
wake_up(&(s->data_ready_wq) );
if (add_frame_length(f, s->cur_frame_length) == 0) {
s->cur_frame_length = 0;
}
else {
printk("func %s,line %d: FIR frame length buf full......\n", __FUNCTION__, __LINE__);
}
spin_unlock(&s->data_lock);
}
}
@ -215,19 +282,26 @@ static irqreturn_t bu92747_irda_irq(int irqno, void *dev_id)
s->tx_empty = 1;
irda_hw_set_moderx();
}
#if 0
/* error */
if (irq_src & REG_INT_TO) {
printk("[%s][%d]: do timeout err\n", __FUNCTION__, __LINE__);
BU92725GUW_clr_fifo();
BU92725GUW_reset();
if ((BU92725GUW_SEND==irda_hw_get_mode())
|| (BU92725GUW_MULTI_SEND==irda_hw_get_mode())) {
s->tx_empty = 1;
}
}
#endif
return IRQ_HANDLED;
}
static void bu92747_irda_stop_tx(struct uart_port *port)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
}
static void bu92747_irda_start_tx(struct uart_port *port)
@ -235,18 +309,13 @@ static void bu92747_irda_start_tx(struct uart_port *port)
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
//wait for start cmd
if (IS_FIR(s))
return ;
if (s->tx_empty)
bu92747_irda_do_tx(s);
else
bu92747_irda_dowork(s);
bu92747_irda_dowork(s);
}
static void bu92747_irda_stop_rx(struct uart_port *port)
@ -255,12 +324,9 @@ static void bu92747_irda_stop_rx(struct uart_port *port)
struct bu92747_port,
port);
dev_dbg(s->dev, "%s\n", __func__);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
s->rx_enabled = 0;
bu92747_irda_dowork(s);
}
static unsigned int bu92747_irda_tx_empty(struct uart_port *port)
@ -269,11 +335,9 @@ static unsigned int bu92747_irda_tx_empty(struct uart_port *port)
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
/* may not be truly up-to-date */
//bu92747_irda_dowork(s);
return s->tx_empty;
}
@ -283,20 +347,14 @@ static const char *bu92747_irda_type(struct uart_port *port)
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
return s->port.type == PORT_IRDA ? "BU92747" : NULL;
}
static void bu92747_irda_release_port(struct uart_port *port)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
}
static void bu92747_irda_config_port(struct uart_port *port, int flags)
@ -305,8 +363,7 @@ static void bu92747_irda_config_port(struct uart_port *port, int flags)
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (flags & UART_CONFIG_TYPE)
s->port.type = PORT_IRDA;
@ -315,13 +372,9 @@ static void bu92747_irda_config_port(struct uart_port *port, int flags)
static int bu92747_irda_verify_port(struct uart_port *port,
struct serial_struct *ser)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
int ret = -EINVAL;
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (ser->type == PORT_UNKNOWN || ser->type == PORT_IRDA)
ret = 0;
@ -334,13 +387,14 @@ static void bu92747_irda_shutdown(struct uart_port *port)
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
struct rev_frame_length *f = &(s->rev_frames);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (s->suspending)
return;
s->open_flag = 0;
s->force_end_work = 1;
if (s->workqueue) {
@ -350,8 +404,7 @@ static void bu92747_irda_shutdown(struct uart_port *port)
}
spin_lock(&s->data_lock);
atomic_set(&(s->data_ready), 0);
s->last_frame_length = 0;
frame_length_buf_clear(f);
s->cur_frame_length = 0;
spin_unlock(&s->data_lock);
@ -360,8 +413,9 @@ static void bu92747_irda_shutdown(struct uart_port *port)
irda_hw_shutdown();
if (s->pdata->irda_pwr_ctl)
s->pdata->irda_pwr_ctl(0);
s->pdata->irda_pwr_ctl(0);
bu92747_unlock();
}
static int bu92747_irda_startup(struct uart_port *port)
@ -370,40 +424,46 @@ static int bu92747_irda_startup(struct uart_port *port)
struct bu92747_port,
port);
char b[32];
struct rev_frame_length *f = &(s->rev_frames);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
s->baud = 9600;
s->rx_enabled = 1;
spin_lock(&s->data_lock);
s->last_frame_length = 0;
s->cur_frame_length = 0;
spin_unlock(&s->data_lock);
if (s->suspending)
return 0;
if (!bu92747_try_lock()) {
printk("func %s, cannot get bu92747 lock, bu92747 in using\n", __func__);
return -EBUSY;
}
s->baud = 9600;
spin_lock(&s->data_lock);
frame_length_buf_clear(f);
s->cur_frame_length = 0;
spin_unlock(&s->data_lock);
s->tx_empty = 1;
s->force_end_work = 0;
sprintf(b, "bu92747_irda-%d", s->minor);
s->workqueue = create_freezeable_workqueue(b);
s->workqueue = create_rt_workqueue(b);
if (!s->workqueue) {
dev_warn(s->dev, "cannot create workqueue\n");
bu92747_unlock();
return -EBUSY;
}
INIT_WORK(&s->work, bu92747_irda_work);
atomic_set(&(s->data_ready), 0);
if (request_irq(s->irq, bu92747_irda_irq,
IRQ_TYPE_LEVEL_LOW, "bu92747_irda", s) < 0) {
IRQF_TRIGGER_LOW, "bu92747_irda", s) < 0) {
dev_warn(s->dev, "cannot allocate irq %d\n", s->irq);
s->irq = 0;
destroy_workqueue(s->workqueue);
s->workqueue = NULL;
bu92747_unlock();
return -EBUSY;
}
@ -417,49 +477,30 @@ static int bu92747_irda_startup(struct uart_port *port)
enable_irq(s->irq);
s->open_flag = 1;
return 0;
}
static int bu92747_irda_request_port(struct uart_port *port)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
return 0;
}
static void bu92747_irda_break_ctl(struct uart_port *port, int break_state)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
}
static unsigned int bu92747_irda_get_mctrl(struct uart_port *port)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
dev_dbg(s->dev, "%s\n", __func__);
return TIOCM_DSR | TIOCM_CAR;
}
static void bu92747_irda_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct bu92747_port *s = container_of(port,
struct bu92747_port,
port);
dev_dbg(s->dev, "%s\n", __func__);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
}
static void
@ -473,8 +514,7 @@ bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned cflag;
struct tty_struct *tty = s->port.state->port.tty;
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
dev_dbg(s->dev, "%s\n", __func__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (!tty)
return;
@ -489,8 +529,10 @@ bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios,
case 115200:
case 4000000:
if (s->baud!=baud) {
IRDA_DBG_RECV("func %s:irda set baudrate %d........\n", __FUNCTION__, baud);
irda_hw_set_speed(baud);
s->baud = baud;
s->tx_empty = 1;
}
break;
@ -504,19 +546,14 @@ bu92747_irda_set_termios(struct uart_port *port, struct ktermios *termios,
static int bu92747_get_frame_length(struct bu92747_port *s)
{
unsigned long len;
wait_event_interruptible_timeout(s->data_ready_wq,
atomic_read(&(s->data_ready) ),
msecs_to_jiffies(1000) );
if ( 0 == atomic_read(&(s->data_ready)) ) {
printk("waiting 'data_ready_wq' timed out.");
return -1;
}
struct rev_frame_length *f = &(s->rev_frames);
unsigned long len = 0;
spin_lock(&s->data_lock);
len = s->last_frame_length;
s->last_frame_length = 0;
atomic_set(&(s->data_ready), 0);
if (get_frame_length(f, &len) != 0) {
IRDA_DBG_RECV("func %s, line %d: FIR data not ready......\n", __FUNCTION__, __LINE__);
len = 0;
}
spin_unlock(&s->data_lock);
return len;
@ -530,12 +567,12 @@ static int bu92747_irda_ioctl(struct uart_port *port, unsigned int cmd, unsigned
void __user *argp = (void __user *)arg;
unsigned long len = 0;
int ret = 0;
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
switch (cmd) {
case TTYIR_GETLENGTH:
len = bu92747_get_frame_length(s);
if (len > 0) {
if (len >= 0) {
if (copy_to_user(argp, &len, sizeof(len)))
ret = -EFAULT;
}
@ -589,7 +626,7 @@ static int __devinit bu92747_irda_probe(struct platform_device *pdev)
int i, retval;
struct irda_info *platdata = pdev->dev.platform_data;
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (!platdata) {
dev_warn(&pdev->dev, "no platform data info\n");
return -1;
@ -624,6 +661,7 @@ static int __devinit bu92747_irda_probe(struct platform_device *pdev)
return -ENOMEM;
}
bu92747s[i]->dev = &pdev->dev;
bu92747s[i]->irq_pin = platdata->intr_pin;
bu92747s[i]->irq = gpio_to_irq(platdata->intr_pin);
if (platdata->iomux_init)
platdata->iomux_init();
@ -644,13 +682,12 @@ static int __devinit bu92747_irda_probe(struct platform_device *pdev)
dev_warn(&pdev->dev,
"uart_add_one_port failed for line %d with error %d\n",
i, retval);
/* set shutdown mode to save power. Will be woken-up on open */
bu92747s[i]->open_flag = 0;
bu92747s[i]->suspending = 0;
/* set shutdown mode to save power. Will be woken-up on open */
if (bu92747s[i]->pdata->irda_pwr_ctl)
bu92747s[i]->pdata->irda_pwr_ctl(0);
init_waitqueue_head(&(bu92747s[i]->data_ready_wq));
spin_lock_init(&(bu92747s[i]->data_lock));
mutex_unlock(&bu92747s_lock);
@ -663,7 +700,7 @@ static int __devexit bu92747_irda_remove(struct platform_device *pdev)
struct bu92747_port *s = dev_get_drvdata(&pdev->dev);
int i;
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
IRDA_DBG_FUNC("line %d, enter %s \n", __LINE__, __FUNCTION__);
mutex_lock(&bu92747s_lock);
/* find out the index for the chip we are removing */
@ -695,42 +732,44 @@ static int bu92747_irda_suspend(struct platform_device *pdev, pm_message_t state
{
struct bu92747_port *s = dev_get_drvdata(&pdev->dev);
dev_dbg(s->dev, "%s\n", __func__);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
disable_irq(s->irq);
s->suspending = 1;
uart_suspend_port(&bu92747_irda_uart_driver, &s->port);
//irda_hw_shutdown();
if (s->pdata->irda_pwr_ctl)
s->pdata->irda_pwr_ctl(0);
if (s->open_flag) {
printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
disable_irq(s->irq);
cancel_work_sync(&s->work);
s->suspending = 1;
uart_suspend_port(&bu92747_irda_uart_driver, &s->port);
irda_hw_shutdown();
if (s->pdata->irda_pwr_ctl)
s->pdata->irda_pwr_ctl(0);
}
return 0;
}
static int bu92747_irda_resume(struct platform_device *pdev)
{
struct bu92747_port *s = dev_get_drvdata(&pdev->dev);
dev_dbg(s->dev, "%s\n", __func__);
BU92747_IRDA_DBG("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (s->pdata->irda_pwr_ctl)
s->pdata->irda_pwr_ctl(1);
//irda_hw_startup();
irda_hw_set_speed(s->baud);
if (s->open_flag) {
printk("line %d, enter %s \n", __LINE__, __FUNCTION__);
if (s->pdata->irda_pwr_ctl)
s->pdata->irda_pwr_ctl(1);
irda_hw_startup();
irda_hw_set_speed(s->baud);
irda_hw_set_moderx();
uart_resume_port(&bu92747_irda_uart_driver, &s->port);
s->suspending = 0;
uart_resume_port(&bu92747_irda_uart_driver, &s->port);
s->suspending = 0;
enable_irq(s->irq);
if (!s->tx_empty)
s->tx_empty = 1;
enable_irq(s->irq);
if (s->workqueue && !IS_FIR(s))
bu92747_irda_dowork(s);
}
if (s->workqueue)
bu92747_irda_dowork(s);
return 0;
}
#else

View File

@ -96,7 +96,8 @@ static void vmac_mdio_xmit(struct vmac_priv *ap, unsigned val)
{
init_completion(&ap->mdio_complete);
vmac_writel(ap, val, MDIO_DATA);
wait_for_completion(&ap->mdio_complete);
if(!wait_for_completion_timeout(&ap->mdio_complete, msecs_to_jiffies(1000)))
printk("Time out for waiting mdio completion\n");
}
static int vmac_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
@ -173,9 +174,9 @@ static void vmac_handle_link_change(struct net_device *dev)
static int __devinit vmac_mii_probe(struct net_device *dev)
{
struct vmac_priv *ap = netdev_priv(dev);
struct phy_device *phydev = NULL;
struct clk *sys_clk;
unsigned long clock_rate;
struct phy_device *phydev = NULL;
//struct clk *sys_clk;
//unsigned long clock_rate;
int phy_addr, err;
/* find the first phy */
@ -234,9 +235,8 @@ static int __devinit vmac_mii_probe(struct net_device *dev)
ap->phy_dev = phydev;
return 0;
err_disconnect:
phy_disconnect(phydev);
//err_disconnect:
// phy_disconnect(phydev);
err_out:
return err;
}
@ -287,6 +287,7 @@ static int __devinit vmac_mii_init(struct vmac_priv *ap)
kfree(ap->mii_bus->irq);
err_out:
mdiobus_free(ap->mii_bus);
ap->mii_bus = NULL;
return err;
}
@ -296,10 +297,12 @@ static void vmac_mii_exit(struct net_device *dev)
if (ap->phy_dev)
phy_disconnect(ap->phy_dev);
mdiobus_unregister(ap->mii_bus);
kfree(ap->mii_bus->irq);
mdiobus_free(ap->mii_bus);
if (ap->mii_bus) {
mdiobus_unregister(ap->mii_bus);
kfree(ap->mii_bus->irq);
mdiobus_free(ap->mii_bus);
ap->mii_bus = NULL;
}
}
static int vmacether_get_settings(struct net_device *dev,
@ -1035,6 +1038,8 @@ int vmac_open(struct net_device *dev)
if (ap == NULL)
return -ENODEV;
wake_lock_timeout(&ap->resume_lock, 5*HZ);
ap->shutdown = 0;
//set rmii ref clock 50MHz
@ -1113,6 +1118,9 @@ int vmac_open(struct net_device *dev)
dev_info(&ap->pdev->dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
ap->suspending = 0;
ap->open_flag = 1;
return 0;
err_free_irq:
@ -1136,6 +1144,11 @@ int vmac_close(struct net_device *dev)
struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
printk("enter func %s...\n", __func__);
if (ap->suspending == 1)
return 0;
ap->open_flag = 0;
netif_stop_queue(dev);
napi_disable(&ap->napi);
@ -1186,67 +1199,43 @@ int vmac_close(struct net_device *dev)
return 0;
}
static void rk29_init_vmac(struct net_device *dev)
int vmac_shutdown(struct net_device *dev)
{
struct vmac_priv *ap = netdev_priv(dev);
unsigned int temp;
struct clk *mac_clk = NULL;
struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
printk("enter func %s...\n", __func__);
//set rmii ref clock 50MHz
mac_clk = clk_get(NULL, "mac_ref_div");
clk_set_rate(mac_clk, 50000000);
clk_enable(mac_clk);
clk_enable(clk_get(NULL,"mii_rx"));
clk_enable(clk_get(NULL,"mii_tx"));
clk_enable(clk_get(NULL,"hclk_mac"));
clk_enable(clk_get(NULL,"mac_ref"));
//phy power on
if (pdata && pdata->rmii_power_control)
pdata->rmii_power_control(1);
netif_stop_queue(dev);
napi_disable(&ap->napi);
//msleep(1000);
/* IRQ mask */
temp = RXINT_MASK | ERR_MASK | TXCH_MASK | MDIO_MASK;
vmac_writel(ap, temp, ENABLE);
/* Set control */
temp = (RX_BDT_LEN << 24) | (TX_BDT_LEN << 16) | TXRN_MASK | RXRN_MASK;
/* stop running transfers */
temp = vmac_readl(ap, CONTROL);
temp &= ~(TXRN_MASK | RXRN_MASK);
vmac_writel(ap, temp, CONTROL);
/* enable, after all other bits are set */
vmac_writel(ap, temp | EN_MASK, CONTROL);
}
del_timer_sync(&ap->rx_timeout);
/* disable phy */
phy_stop(ap->phy_dev);
vmac_mii_exit(dev);
netif_carrier_off(dev);
static void rk29_vmac_shutdown(struct net_device *dev)
{
struct vmac_priv *ap = netdev_priv(dev);
struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
printk("enter func %s...\n", __func__);
/* disable interrupts */
vmac_writel(ap, 0, ENABLE);
free_irq(dev->irq, dev);
/* turn off vmac */
vmac_writel(ap, 0, CONTROL);
//phy power off
if (pdata && pdata->rmii_power_control)
pdata->rmii_power_control(0);
//clock close
clk_disable(clk_get(NULL, "mac_ref_div"));
clk_disable(clk_get(NULL,"mii_rx"));
clk_disable(clk_get(NULL,"mii_tx"));
clk_disable(clk_get(NULL,"hclk_mac"));
clk_disable(clk_get(NULL,"mac_ref"));
}
/* vmac_reset_hw(vmac) */
ap->shutdown = 1;
wmb();
free_buffers(dev);
return 0;
}
void vmac_update_stats(struct vmac_priv *ap)
{
@ -1474,7 +1463,6 @@ static int __devinit vmac_probe(struct platform_device *pdev)
struct resource *res;
unsigned int mem_base, mem_size, irq;
int err;
struct clk *sys_clk;
struct rk29_vmac_platform_data *pdata = pdev->dev.platform_data;
dev = alloc_etherdev(sizeof(*ap));
@ -1553,7 +1541,10 @@ static int __devinit vmac_probe(struct platform_device *pdev)
dev->irq, dev->dev_addr);
platform_set_drvdata(pdev, dev);
ap->suspending = 0;
ap->open_flag = 0;
wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "vmac");
wake_lock_init(&ap->resume_lock, WAKE_LOCK_SUSPEND, "vmac_resume");
//config rk29 vmac as rmii, 100MHz
if (pdata && pdata->vmac_register_set)
@ -1607,16 +1598,42 @@ static int __devexit vmac_remove(struct platform_device *pdev)
return 0;
}
static void rk29_vmac_power_off(struct net_device *dev)
{
struct vmac_priv *ap = netdev_priv(dev);
struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
printk("enter func %s...\n", __func__);
//phy power off
if (pdata && pdata->rmii_power_control)
pdata->rmii_power_control(0);
//clock close
clk_disable(clk_get(NULL, "mac_ref_div"));
clk_disable(clk_get(NULL,"mii_rx"));
clk_disable(clk_get(NULL,"mii_tx"));
clk_disable(clk_get(NULL,"hclk_mac"));
clk_disable(clk_get(NULL,"mac_ref"));
}
static int
rk29_vmac_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev);
struct vmac_priv *ap = netdev_priv(ndev);
if (ndev) {
if (netif_running(ndev)) {
if (ap->open_flag == 1) {
netif_stop_queue(ndev);
netif_device_detach(ndev);
rk29_vmac_shutdown(ndev);
if (ap->suspending == 0) {
vmac_shutdown(ndev);
rk29_vmac_power_off(ndev);
ap->suspending = 1;
}
}
}
return 0;
@ -1627,11 +1644,12 @@ rk29_vmac_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev);
struct vmac_priv *ap = netdev_priv(ndev);
if (ndev) {
if (netif_running(ndev)) {
rk29_init_vmac(ndev);
if (ap->open_flag == 1) {
netif_device_attach(ndev);
netif_start_queue(ndev);
}
}
return 0;

View File

@ -183,6 +183,10 @@ struct vmac_priv {
int speed;
int duplex;
int open_flag;
int suspending;
struct wake_lock resume_lock;
/* debug */
int shutdown;
};

View File

@ -60,7 +60,7 @@ choice
(4) Murata SP-8HEP-P
source "drivers/net/wireless/bcm4319/Kconfig"
source "drivers/net/wireless/rtl8192c/Kconfig"
endchoice
#source "drivers/net/wireless/bcm4329/Kconfig"

View File

@ -1,8 +1,9 @@
#
# Makefile for the Linux Wireless network device drivers.
#
obj-y += wifi_sys/rkwifi_sys_iface.o
obj-$(CONFIG_BCM4329) += bcm4329/
obj-$(CONFIG_MV8686) += mv8686/
obj-$(CONFIG_BCM4319) += bcm4319/
obj-$(CONFIG_RTL8192CU) += rtl8192c/
#obj-m += wlan/

View File

@ -0,0 +1,6 @@
config RTL8192CU
tristate "Realtek 8192C USB WiFi"
depends on USB
---help---
Help message of RTL8192CU

View File

@ -0,0 +1,202 @@
#
# Makefile for RTL8188/8192 USB WiFi
#
EXTRA_CFLAGS += -O1
#EXTRA_CFLAGS += -O3
EXTRA_CFLAGS += -Wall
#EXTRA_CFLAGS += -Wextra
#EXTRA_CFLAGS += -Werror
#EXTRA_CFLAGS += -pedantic
#EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes
EXTRA_CFLAGS += -Wno-unused-variable
EXTRA_CFLAGS += -Wno-unused-value
EXTRA_CFLAGS += -Wno-unused-label
EXTRA_CFLAGS += -Wno-unused-parameter
EXTRA_CFLAGS += -Wno-unused-function
EXTRA_CFLAGS += -Wno-unused
EXTRA_CFLAGS += -Wno-uninitialized
EXTRA_CFLAGS += -I$(src)/include
CONFIG_AUTOCFG_CP = n
CONFIG_RTL8192C = y
CONFIG_RTL8192D = n
CONFIG_USB_HCI = y
CONFIG_PCI_HCI = n
CONFIG_SDIO_HCI = n
CONFIG_MP_INCLUDED = n
CONFIG_POWER_SAVING = n
CONFIG_USB_AUTOSUSPEND = n
CONFIG_HW_PWRP_DETECTION = n
CONFIG_WIFI_TEST = n
CONFIG_BT_COEXISTENCE = n
CONFIG_RTL8192CU_REDEFINE_1X1 = n
CONFIG_PLATFORM_ARM_RK2918 = y
CONFIG_DRVEXT_MODULE = n
export TopDIR ?= $(shell pwd)
ifeq ($(CONFIG_RTL8192C), y)
RTL871X = rtl8192c
ifeq ($(CONFIG_USB_HCI), y)
MODULE_NAME = 8192cu
FW_FILES := hal/$(RTL871X)/usb/Hal8192CUHWImg.o
endif
CHIP_FILES := hal/$(RTL871X)/$(RTL871X)_sreset.o
CHIP_FILES += $(FW_FILES)
endif
os_dep/linux/ioctl_linux.o: os_dep/linux/ioctl_linux.uu
@echo "UUDE os_dep/linux/ioctl_linux.uu"
@uudecode os_dep/linux/ioctl_linux.uu -o os_dep/linux/ioctl_linux.o
ifeq ($(CONFIG_USB_HCI), y)
HCI_NAME = usb
_OS_INTFS_FILES := os_dep/osdep_service.o \
os_dep/linux/os_intfs.o \
os_dep/linux/$(HCI_NAME)_intf.o \
os_dep/linux/ioctl_linux.o \
os_dep/linux/xmit_linux.o \
os_dep/linux/ioctl_linux.o \
os_dep/linux/mlme_linux.o \
os_dep/linux/recv_linux.o
_HAL_INTFS_FILES := hal/hal_init.o \
hal/$(RTL871X)/$(RTL871X)_hal_init.o \
hal/$(RTL871X)/$(RTL871X)_phycfg.o \
hal/$(RTL871X)/$(RTL871X)_rf6052.o \
hal/$(RTL871X)/$(RTL871X)_dm.o \
hal/$(RTL871X)/$(RTL871X)_rxdesc.o \
hal/$(RTL871X)/$(RTL871X)_cmd.o \
hal/$(RTL871X)/usb/usb_ops_linux.o \
hal/$(RTL871X)/usb/usb_halinit.o \
hal/$(RTL871X)/usb/rtl$(MODULE_NAME)_led.o \
hal/$(RTL871X)/usb/rtl$(MODULE_NAME)_xmit.o \
hal/$(RTL871X)/usb/rtl$(MODULE_NAME)_recv.o
_HAL_INTFS_FILES += $(CHIP_FILES)
endif
ifeq ($(CONFIG_AUTOCFG_CP), y)
$(shell cp $(TopDIR)/autoconf_$(RTL871X)_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h)
endif
ifeq ($(CONFIG_USB_HCI), y)
ifeq ($(CONFIG_USB_AUTOSUSPEND), y)
EXTRA_CFLAGS += -DCONFIG_USB_AUTOSUSPEND
endif
endif
ifeq ($(CONFIG_POWER_SAVING), y)
EXTRA_CFLAGS += -DCONFIG_POWER_SAVING
endif
ifeq ($(CONFIG_HW_PWRP_DETECTION), y)
EXTRA_CFLAGS += -DCONFIG_HW_PWRP_DETECTION
endif
ifeq ($(CONFIG_WIFI_TEST), y)
EXTRA_CFLAGS += -DCONFIG_WIFI_TEST
endif
ifeq ($(CONFIG_BT_COEXISTENCE), y)
EXTRA_CFLAGS += -DCONFIG_BT_COEXISTENCE
endif
ifeq ($(CONFIG_RTL8192CU_REDEFINE_1X1), y)
EXTRA_CFLAGS += -DRTL8192C_RECONFIG_TO_1T1R
endif
ifeq ($(CONFIG_PLATFORM_ARM_RK2918), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ROCKCHIPS
ARCH := arm
CROSS_COMPILE := /opt/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
KSRC := 2.6.25.1
#MODULE_NAME := wlan0
endif
#
# Add minimize memory usage.
#
EXTRA_CFLAGS += -DCONFIG_MINIMAL_MEMORY_USAGE
ifneq ($(KERNELRELEASE),)
rtk_core := core/rtw_cmd.o \
core/rtw_security.o \
core/rtw_debug.o \
core/rtw_io.o \
core/rtw_ioctl_query.o \
core/rtw_ioctl_set.o \
core/rtw_ieee80211.o \
core/rtw_mlme.o \
core/rtw_mlme_ext.o \
core/rtw_wlan_util.o \
core/rtw_pwrctrl.o \
core/rtw_rf.o \
core/rtw_recv.o \
core/rtw_sta_mgt.o \
core/rtw_xmit.o \
core/rtw_p2p.o
rtl$(MODULE_NAME)-y += $(rtk_core)
rtl$(MODULE_NAME)-y += core/efuse/rtw_efuse.o
rtl$(MODULE_NAME)-y += $(_HAL_INTFS_FILES)
rtl$(MODULE_NAME)-y += $(_OS_INTFS_FILES)
core/rtw_ioctl_set.o: core/rtw_ioctl_set.uu
@echo "UUDE core/rtw_ioctl_set.uu"
@uudecode core/rtw_ioctl_set.uu -o core/rtw_ioctl_set.o
rtl$(MODULE_NAME)-$(CONFIG_MP_INCLUDED) += core/rtw_mp.o \
core/rtw_mp_ioctl.o \
core/rtw_ioctl_rtl.o
rk_cfg := \
os_dep/linux/wifi_power.o \
os_dep/linux/wifi_power_usb.o \
os_dep/linux/wifi_power_ops.o
rkcfg-y += $(rk_cfg)
obj-$(CONFIG_RTL8192CU) := rtl$(MODULE_NAME).o rkcfg.o
else
export CONFIG_RTL8192CU = m
all: modules
modules:
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd) modules
strip:
$(CROSS_COMPILE)strip $(MODULE_NAME).ko --strip-unneeded
config_r:
@echo "make config"
/bin/bash script/Configure script/config.in
.PHONY: modules clean
endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,611 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_DEBUG_C_
#include <rtw_debug.h>
#ifdef CONFIG_DEBUG_RTL871X
u32 GlobalDebugLevel = _drv_info_;
u64 GlobalDebugComponents = \
_module_rtl871x_xmit_c_ |
_module_xmit_osdep_c_ |
_module_rtl871x_recv_c_ |
_module_recv_osdep_c_ |
_module_rtl871x_mlme_c_ |
_module_mlme_osdep_c_ |
_module_rtl871x_sta_mgt_c_ |
_module_rtl871x_cmd_c_ |
_module_cmd_osdep_c_ |
_module_rtl871x_io_c_ |
_module_io_osdep_c_ |
_module_os_intfs_c_|
_module_rtl871x_security_c_|
_module_rtl871x_eeprom_c_|
_module_hal_init_c_|
_module_hci_hal_init_c_|
_module_rtl871x_ioctl_c_|
_module_rtl871x_ioctl_set_c_|
_module_rtl871x_ioctl_query_c_|
_module_rtl871x_pwrctrl_c_|
_module_hci_intfs_c_|
_module_hci_ops_c_|
_module_hci_ops_os_c_|
_module_rtl871x_ioctl_os_c|
_module_rtl8712_cmd_c_|
_module_rtl8192c_xmit_c_|
_module_rtl8712_recv_c_ |
_module_mp_ |
_module_efuse_;
#endif
#ifdef CONFIG_PROC_DEBUG
#include <rtw_version.h>
int proc_get_drv_version(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
int len = 0;
len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION);
*eof = 1;
return len;
}
int proc_get_write_reg(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
*eof = 1;
return 0;
}
int proc_set_write_reg(struct file *file, const char *buffer,
unsigned long count, void *data)
{
struct net_device *dev = (struct net_device *)data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
char tmp[32];
u32 addr, val, len;
if (count < 3)
{
DBG_8192C("argument size is less than 3\n");
return -EFAULT;
}
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
int num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
if (num != 3) {
DBG_8192C("invalid write_reg parameter!\n");
return count;
}
switch(len)
{
case 1:
rtw_write8(padapter, addr, (u8)val);
break;
case 2:
rtw_write16(padapter, addr, (u16)val);
break;
case 4:
rtw_write32(padapter, addr, val);
break;
default:
DBG_8192C("error write length=%d", len);
break;
}
}
return count;
}
static u32 proc_get_read_addr=0xeeeeeeee;
static u32 proc_get_read_len=0x4;
int proc_get_read_reg(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
int len = 0;
if(proc_get_read_addr==0xeeeeeeee)
{
*eof = 1;
return len;
}
switch(proc_get_read_len)
{
case 1:
len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
break;
case 2:
len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
break;
case 4:
len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
break;
default:
len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
break;
}
*eof = 1;
return len;
}
int proc_set_read_reg(struct file *file, const char *buffer,
unsigned long count, void *data)
{
struct net_device *dev = (struct net_device *)data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
char tmp[16];
u32 addr, len;
if (count < 2)
{
DBG_8192C("argument size is less than 2\n");
return -EFAULT;
}
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
int num = sscanf(tmp, "%x %x", &addr, &len);
if (num != 2) {
DBG_8192C("invalid read_reg parameter!\n");
return count;
}
proc_get_read_addr = addr;
proc_get_read_len = len;
}
return count;
}
int proc_get_fwstate(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv));
*eof = 1;
return len;
}
int proc_get_sec_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct security_priv *psecuritypriv = &padapter->securitypriv;
int len = 0;
len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
*eof = 1;
return len;
}
int proc_get_mlmext_state(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
int len = 0;
len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
*eof = 1;
return len;
}
int proc_get_qos_option(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option);
*eof = 1;
return len;
}
int proc_get_ht_option(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option);
*eof = 1;
return len;
}
int proc_get_rf_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
int len = 0;
len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n",
pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
*eof = 1;
return len;
}
int proc_get_ap_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct sta_info *psta;
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
struct sta_priv *pstapriv = &padapter->stapriv;
int len = 0;
psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
if(psta)
{
int i;
struct recv_reorder_ctrl *preorder_ctrl;
len += snprintf(page + len, count - len, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
for(i=0;i<16;i++)
{
preorder_ctrl = &psta->recvreorder_ctrl[i];
if(preorder_ctrl->enable)
{
len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
}
}
}
else
{
len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
}
*eof = 1;
return len;
}
int proc_get_adapter_state(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
int len = 0;
len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n",
padapter->bSurpriseRemoved, padapter->bDriverStopped);
*eof = 1;
return len;
}
int proc_get_trx_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
struct recv_priv *precvpriv = &padapter->recvpriv;
int len = 0;
len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d\n",
pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt);
#ifdef CONFIG_USB_HCI
len += snprintf(page + len, count - len, "rx_urb_pending_cn=%d\n", precvpriv->rx_pending_cnt);
#endif
*eof = 1;
return len;
}
int proc_get_rx_signal(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
int len = 0;
len += snprintf(page + len, count - len,
"rssi:%d\n"
"rxpwdb:%d\n"
"signal_strength:%u\n"
"signal_qual:%u\n"
"noise:%u\n",
padapter->recvpriv.rssi,
padapter->recvpriv.rxpwdb,
padapter->recvpriv.signal_strength,
padapter->recvpriv.signal_qual,
padapter->recvpriv.noise
);
*eof = 1;
return len;
}
int proc_set_rx_signal(struct file *file, const char *buffer,
unsigned long count, void *data)
{
struct net_device *dev = (struct net_device *)data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
char tmp[32];
u32 is_signal_dbg, signal_strength;
if (count < 1)
return -EFAULT;
if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength);
is_signal_dbg = is_signal_dbg==0?0:1;
if(is_signal_dbg && num!=2)
return count;
signal_strength = signal_strength>100?100:signal_strength;
signal_strength = signal_strength<0?0:signal_strength;
padapter->recvpriv.is_signal_dbg = is_signal_dbg;
padapter->recvpriv.signal_strength_dbg=signal_strength;
if(is_signal_dbg)
DBG_871X("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength);
else
DBG_871X("set %s\n", "HW_SIGNAL_STRENGTH");
}
return count;
}
#ifdef CONFIG_AP_MODE
int proc_get_all_sta_info(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
_irqL irqL;
struct sta_info *psta;
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct sta_priv *pstapriv = &padapter->stapriv;
int i, j;
_list *plist, *phead;
struct recv_reorder_ctrl *preorder_ctrl;
int len = 0;
len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
for(i=0; i< NUM_STA; i++)
{
phead = &(pstapriv->sta_hash[i]);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
{
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
plist = get_next(plist);
//if(extra_arg == psta->aid)
{
len += snprintf(page + len, count - len, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len);
len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability);
len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags);
len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk);
len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info);
len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
for(j=0;j<16;j++)
{
preorder_ctrl = &psta->recvreorder_ctrl[j];
if(preorder_ctrl->enable)
{
len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
}
}
}
}
}
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
*eof = 1;
return len;
}
#endif
#ifdef MEMORY_LEAK_DEBUG
#include <asm/atomic.h>
extern atomic_t _malloc_cnt;;
extern atomic_t _malloc_size;;
int proc_get_malloc_cnt(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
int len = 0;
len += snprintf(page + len, count - len, "_malloc_cnt=%d\n", atomic_read(&_malloc_cnt));
len += snprintf(page + len, count - len, "_malloc_size=%d\n", atomic_read(&_malloc_size));
*eof = 1;
return len;
}
#endif /* MEMORY_LEAK_DEBUG */
#ifdef CONFIG_FIND_BEST_CHANNEL
int proc_get_best_channel(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
{
struct net_device *dev = data;
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
int len = 0;
u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
if ( pmlmeext->channel_set[i].ChannelNum == 1)
index_24G = i;
if ( pmlmeext->channel_set[i].ChannelNum == 36)
index_5G = i;
}
for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
// 2.4G
if ( pmlmeext->channel_set[i].ChannelNum == 6 ) {
if ( pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count ) {
index_24G = i;
best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
}
}
// 5G
if ( pmlmeext->channel_set[i].ChannelNum >= 36
&& pmlmeext->channel_set[i].ChannelNum < 140 ) {
// Find primary channel
if ( (( pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0)
&& (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) {
index_5G = i;
best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
}
}
if ( pmlmeext->channel_set[i].ChannelNum >= 149
&& pmlmeext->channel_set[i].ChannelNum < 165) {
// find primary channel
if ( (( pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0)
&& (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) {
index_5G = i;
best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
}
}
#if 1 // debug
len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n",
pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count);
#endif
}
len += snprintf(page + len, count - len, "best_channel_5G = %d\n", best_channel_5G);
len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G);
*eof = 1;
return len;
}
#endif /* CONFIG_FIND_BEST_CHANNEL */
#endif

View File

@ -0,0 +1,424 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_EEPROM_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
void up_clk(_adapter* padapter, u16 *x)
{
_func_enter_;
*x = *x | _EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
rtw_udelay_os(CLOCK_RATE);
_func_exit_;
}
void down_clk(_adapter * padapter, u16 *x )
{
_func_enter_;
*x = *x & ~_EESK;
rtw_write8(padapter, EE_9346CR, (u8)*x);
rtw_udelay_os(CLOCK_RATE);
_func_exit_;
}
void shift_out_bits(_adapter * padapter, u16 data, u16 count)
{
u16 x,mask;
_func_enter_;
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
mask = 0x01 << (count - 1);
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDO | _EEDI);
do
{
x &= ~_EEDI;
if(data & mask)
x |= _EEDI;
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
rtw_write8(padapter, EE_9346CR, (u8)x);
rtw_udelay_os(CLOCK_RATE);
up_clk(padapter, &x);
down_clk(padapter, &x);
mask = mask >> 1;
} while(mask);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x &= ~_EEDI;
rtw_write8(padapter, EE_9346CR, (u8)x);
out:
_func_exit_;
}
u16 shift_in_bits (_adapter * padapter)
{
u16 x,d=0,i;
_func_enter_;
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~( _EEDO | _EEDI);
d = 0;
for(i=0; i<16; i++)
{
d = d << 1;
up_clk(padapter, &x);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI);
if(x & _EEDO)
d |= 1;
down_clk(padapter, &x);
}
out:
_func_exit_;
return d;
}
void standby(_adapter * padapter )
{
u8 x;
_func_enter_;
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EECS | _EESK);
rtw_write8(padapter, EE_9346CR,x);
rtw_udelay_os(CLOCK_RATE);
x |= _EECS;
rtw_write8(padapter, EE_9346CR, x);
rtw_udelay_os(CLOCK_RATE);
_func_exit_;
}
u16 wait_eeprom_cmd_done(_adapter* padapter)
{
u8 x;
u16 i,res=_FALSE;
_func_enter_;
standby(padapter );
for (i=0; i<200; i++)
{
x = rtw_read8(padapter, EE_9346CR);
if (x & _EEDO){
res=_TRUE;
goto exit;
}
rtw_udelay_os(CLOCK_RATE);
}
exit:
_func_exit_;
return res;
}
void eeprom_clean(_adapter * padapter)
{
u16 x;
_func_enter_;
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x = rtw_read8(padapter, EE_9346CR);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x &= ~(_EECS | _EEDI);
rtw_write8(padapter, EE_9346CR, (u8)x);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
up_clk(padapter, &x);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
down_clk(padapter, &x);
out:
_func_exit_;
}
void eeprom_write16(_adapter * padapter, u16 reg, u16 data)
{
u8 x;
#ifdef CONFIG_RTL8712
u8 tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new;
tmp8_ori=rtw_read8(padapter, 0x102502f1);
tmp8_new=tmp8_ori & 0xf7;
if(tmp8_ori != tmp8_new){
rtw_write8(padapter, 0x102502f1, tmp8_new);
RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n"));
}
tmp8_clk_ori=rtw_read8(padapter,0x10250003);
tmp8_clk_new=tmp8_clk_ori|0x20;
if(tmp8_clk_new!=tmp8_clk_ori){
RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n"));
rtw_write8(padapter, 0x10250003, tmp8_clk_new);
}
#endif
_func_enter_;
x = rtw_read8(padapter, EE_9346CR);
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, x);
shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
if(padapter->EepromAddressSize==8) //CF+ and SDIO
shift_out_bits(padapter, 0, 6);
else //USB
shift_out_bits(padapter, 0, 4);
standby( padapter);
// Commented out by rcnjko, 2004.0
// // Erase this particular word. Write the erase opcode and register
// // number in that order. The opcode is 3bits in length; reg is 6 bits long.
// shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3);
// shift_out_bits(Adapter, reg, Adapter->EepromAddressSize);
//
// if (wait_eeprom_cmd_done(Adapter ) == FALSE)
// {
// return;
// }
standby(padapter );
// write the new word to the EEPROM
// send the write opcode the EEPORM
shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
// select which word in the EEPROM that we are writing to.
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
// write the data to the selected EEPROM word.
shift_out_bits(padapter, data, 16);
if (wait_eeprom_cmd_done(padapter ) == _FALSE)
{
goto exit;
}
standby(padapter );
shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
shift_out_bits(padapter, reg, 4);
eeprom_clean(padapter );
exit:
#ifdef CONFIG_RTL8712
if(tmp8_clk_new!=tmp8_clk_ori)
rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
if(tmp8_new!=tmp8_ori)
rtw_write8(padapter, 0x102502f1, tmp8_ori);
#endif
_func_exit_;
return;
}
u16 eeprom_read16(_adapter * padapter, u16 reg) //ReadEEprom
{
u16 x;
u16 data=0;
#ifdef CONFIG_RTL8712
u8 tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new;
tmp8_ori= rtw_read8(padapter, 0x102502f1);
tmp8_new = tmp8_ori & 0xf7;
if(tmp8_ori != tmp8_new){
rtw_write8(padapter, 0x102502f1, tmp8_new);
RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n"));
}
tmp8_clk_ori=rtw_read8(padapter,0x10250003);
tmp8_clk_new=tmp8_clk_ori|0x20;
if(tmp8_clk_new!=tmp8_clk_ori){
RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n"));
rtw_write8(padapter, 0x10250003, tmp8_clk_new);
}
#endif
_func_enter_;
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
// select EEPROM, reset bits, set _EECS
x = rtw_read8(padapter, EE_9346CR);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, (unsigned char)x);
// write the read opcode and register number in that order
// The opcode is 3bits in length, reg is 6 bits long
shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
// Now read the data (16 bits) in from the selected EEPROM word
data = shift_in_bits(padapter);
eeprom_clean(padapter);
out:
#ifdef CONFIG_RTL8712
if(tmp8_clk_new!=tmp8_clk_ori)
rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
if(tmp8_new!=tmp8_ori)
rtw_write8(padapter, 0x102502f1, tmp8_ori);
#endif
_func_exit_;
return data;
}
//From even offset
void eeprom_read_sz(_adapter * padapter, u16 reg, u8* data, u32 sz)
{
u16 x, data16;
u32 i;
_func_enter_;
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
// select EEPROM, reset bits, set _EECS
x = rtw_read8(padapter, EE_9346CR);
if(padapter->bSurpriseRemoved==_TRUE){
RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
goto out;
}
x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
x |= _EEM1 | _EECS;
rtw_write8(padapter, EE_9346CR, (unsigned char)x);
// write the read opcode and register number in that order
// The opcode is 3bits in length, reg is 6 bits long
shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
shift_out_bits(padapter, reg, padapter->EepromAddressSize);
for(i=0; i<sz; i+=2)
{
data16 = shift_in_bits(padapter);
data[i] = data16 & 0xff;
data[i+1] = data16 >>8;
}
eeprom_clean(padapter);
out:
_func_exit_;
}
//addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg)
u8 eeprom_read(_adapter * padapter, u32 addr_off, u8 sz, u8* rbuf)
{
u8 quotient, remainder, addr_2align_odd;
u16 reg, stmp , i=0, idx = 0;
_func_enter_;
reg = (u16)(addr_off >> 1);
addr_2align_odd = (u8)(addr_off & 0x1);
if(addr_2align_odd) //read that start at high part: e.g 1,3,5,7,9,...
{
stmp = eeprom_read16(padapter, reg);
rbuf[idx++] = (u8) ((stmp>>8)&0xff); //return hogh-part of the short
reg++; sz--;
}
quotient = sz >> 1;
remainder = sz & 0x1;
for( i=0 ; i < quotient; i++)
{
stmp = eeprom_read16(padapter, reg+i);
rbuf[idx++] = (u8) (stmp&0xff);
rbuf[idx++] = (u8) ((stmp>>8)&0xff);
}
reg = reg+i;
if(remainder){ //end of read at lower part of short : 0,2,4,6,...
stmp = eeprom_read16(padapter, reg);
rbuf[idx] = (u8)(stmp & 0xff);
}
_func_exit_;
return _TRUE;
}
VOID read_eeprom_content(_adapter * padapter)
{
_func_enter_;
_func_exit_;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,525 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_INTEL_WIDI_C_
#include <drv_types.h>
#include <wifi.h>
#ifdef CONFIG_INTEL_WIDI
#include <rtw_intel_widi.h>
void intel_widi_listen_timer_hdl(void *FunctionContext);
void rtw_init_intel_widi( _adapter *padapter)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
pmlmepriv->widi_state = INTEL_WIDI_STATE_NONE;
_init_timer(&pmlmepriv->listen_timer, padapter->pnetdev, intel_widi_listen_timer_hdl, padapter);
}
void rtw_free_intel_widi( _adapter *padapter)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
if (padapter->bDriverStopped == _TRUE)
{
_cancel_timer_ex(&pmlmepriv->listen_timer);
}
}
void issue_probereq_widi(_adapter *padapter, l2_msg_t *l2_msg)
{
u8 wpsie[256];
u16 wpsielen = 0;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
_rtw_memcpy(get_my_bssid(&(pmlmeinfo->network)), l2_msg->u.l2sd_service_msg.dst_mac, ETH_ALEN);
//add wps_ie for WiDi
wpsielen = 0;
// WPS OUI
*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
wpsielen += 4;
// WPS version
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
wpsielen += 2;
// Value:
wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
// Request Type
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_REQUEST_TYPE );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
wpsielen += 2;
// Value:
wpsie[wpsielen++] = WPS_REQ_TYPE_ENROLLEE_INFO_ONLY;
// Config Method
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
wpsielen += 2;
// Value:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_DISPLAY| WPS_CONFIG_METHOD_LABEL );
wpsielen += 2;
// UUID-E
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
wpsielen += 2;
// Value:
_rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
wpsielen += 0x10;
// Primary Device Type
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( L2SDTA_PRIMARY_DEV_LEN );
wpsielen += 2;
// Value:
_rtw_memcpy( wpsie + wpsielen, l2_msg->u.l2sd_service_msg.sa_primary_dev, L2SDTA_PRIMARY_DEV_LEN );
wpsielen += L2SDTA_PRIMARY_DEV_LEN;
// RF Bands
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RF_BANDS );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
wpsielen += 2;
// Value:
wpsie[wpsielen++] = WPS_RF_BANDS_2_4_GHZ; // 2.4GHz
// Association State
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_ASSOCIATION_STATE );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
wpsielen += 2;
// Value:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ASSOC_STATE_NOT_ASSOCIATED);
wpsielen += 2;
// Configuration Error
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONFIG_ERROR);
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
wpsielen += 2;
// Value:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0000);
wpsielen += 2;
// Device Password ID
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID);
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
wpsielen += 2;
// Value:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PIN);
wpsielen += 2;
// Device Name
// Type:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
wpsielen += 2;
// Length:
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( L2SDTA_DEVICE_NAME_LEN );
wpsielen += 2;
// Value:
_rtw_memcpy( wpsie + wpsielen, l2_msg->u.l2sd_service_msg.sa_device_name, L2SDTA_DEVICE_NAME_LEN );
wpsielen += L2SDTA_DEVICE_NAME_LEN;
// Vendor Extension
_rtw_memcpy( wpsie + wpsielen, l2_msg->u.l2sd_service_msg.sa_ext, L2SDTA_SERVICE_VE_LEN );
wpsielen += L2SDTA_SERVICE_VE_LEN;
pmlmepriv->probereq_wpsie[0] = 0xdd;
pmlmepriv->probereq_wpsie[1] = wpsielen;
pmlmepriv->probereq_wpsie_len = wpsielen + 2;
_rtw_memcpy(&pmlmepriv->probereq_wpsie[2], wpsie, wpsielen);
//DBG_871X("WiDi wps ie length = %d\n",wpsielen);
// driver should issue probe request in the right channel
if( l2_msg->u.l2sd_service_msg.channel == pmlmeext->channel_set[pmlmepriv->channel_idx].ChannelNum)
{
issue_probereq(padapter, 0);
}
//clear wps ie length after send probe request.
pmlmepriv->probereq_wpsie_len = 0;
}
static void indicate_widi_msg(_adapter *padapter, _pkt *skb)
{
skb->dev = padapter->pnetdev;
skb->ip_summed = CHECKSUM_NONE;
skb->protocol = eth_type_trans(skb, padapter->pnetdev);
skb->protocol = htons(ETH_P_WIDI_NOTIF);
netif_rx(skb);
}
void process_intel_widi_assoc_status(_adapter *padapter, u8 assoc_status)
{
_pkt *skb;
l2_msg_t *l2_notif;
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
skb = dev_alloc_skb(sizeof(l2_msg_t));
#else
skb = netdev_alloc_skb(padapter->pnetdev, sizeof(l2_msg_t));
#endif
if(skb != NULL)
{
l2_notif = (l2_msg_t *)skb->data;
_rtw_memset(l2_notif, 0, sizeof(l2_msg_t));
skb_put(skb, sizeof(struct l2sd_assoc_msg_t)+1);
l2_notif->msg_type = L2SDTA_MSG_TYPE_ASSOC_STATUS;
_rtw_memcpy(l2_notif->u.l2sd_assoc_msg.peer_mac, get_my_bssid(cur_network), ETH_ALEN);
l2_notif->u.l2sd_assoc_msg.assoc_stat = assoc_status;
DBG_871X("indicate_widi_assoc_status %d\n",assoc_status);
indicate_widi_msg(padapter, skb);
}
}
void process_intel_widi_disconnect(_adapter *padapter, u8 bdisassoc)
{
if(padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_CONNECTED)
{
padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_DISASSOCIATED;
process_intel_widi_assoc_status(padapter, L2SDTA_DISASSOCIATED);
}
}
void process_intel_widi_wps_status(_adapter *padapter, u8 wps_status)
{
if ( wps_status == 2 ) // WPS Stop because of wps success
{
DBG_871X("Intel WiDi WPS Success with RDS Source\n");
process_intel_widi_assoc_status(padapter, L2SDTA_WPS_STATUS_SUCCESS);
}
else if ( wps_status == 3 ) // WPS Stop because of wps fail
{
DBG_871X("Intel WiDi WPS Fail with RDS Source\n");
process_intel_widi_assoc_status(padapter, L2SDTA_WPS_STATUS_FAIL);
}
}
int process_intel_widi_query_or_tigger(_adapter *padapter, WLAN_BSSID_EX *bssid)
{
u8 *wps_ie, *wps_attr;
u32 wps_len, wps_attr_len;
_pkt *skb;
l2_msg_t *l2_notif;
struct l2sd_wps_attrib_hdr_t *l2sd_attr;
if(padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_LISTEN)
return 0;
wps_ie = rtw_get_wps_ie(bssid->IEs, bssid->IELength, NULL, &wps_len);
if(wps_ie && wps_len>0)
{
wps_attr = rtw_get_wps_attr_ie(wps_ie, wps_len, WPS_ATTR_VENDOR_EXT, NULL, &wps_attr_len);
if(wps_attr && wps_attr_len>0)
{
l2sd_attr = (struct l2sd_wps_attrib_hdr_t *)wps_attr;
if(IS_INTEL_SMI(l2sd_attr->smi_intel))
{
DBG_871X("Get WPS Vendor extension IE from Intel, length = %d\n",wps_attr_len);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
skb = dev_alloc_skb(sizeof(l2_msg_t));
#else
skb = netdev_alloc_skb(padapter->pnetdev, sizeof(l2_msg_t));
#endif
if(skb != NULL)
{
l2_notif = (l2_msg_t *)skb->data;
_rtw_memset(l2_notif, 0, sizeof(l2_msg_t));
skb_put(skb, sizeof(struct l2sd_query_or_trig_msg_t)+1);
l2_notif->msg_type = L2SDTA_MSG_TYPE_QUERY_OR_TRIGGER;
_rtw_memcpy(l2_notif->u.l2sd_query_or_trig_msg.src_mac, bssid->MacAddress, ETH_ALEN);
l2_notif->u.l2sd_query_or_trig_msg.channel = bssid->Configuration.DSConfig;
l2_notif->u.l2sd_query_or_trig_msg.ssid_len = bssid->Ssid.SsidLength;
_rtw_memcpy(l2_notif->u.l2sd_query_or_trig_msg.ssid, bssid->Ssid.Ssid, bssid->Ssid.SsidLength);
_rtw_memcpy(l2_notif->u.l2sd_query_or_trig_msg.qa_ta_ext, wps_attr, wps_attr_len+4);
DBG_871X("Recvive WIDI Query or Trigger Msg\n");
indicate_widi_msg(padapter, skb);
}
}
}
}
return 1;
}
void process_intel_widi_cmd(_adapter*padapter, u8 *cmd)
{
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
DBG_8192C( "[%s] cmd = %s\n", __FUNCTION__, cmd );
if( _rtw_memcmp( cmd, "enable", 6 ) )
{
DBG_871X("Intel WiDi Enable\n");
}
else if ( _rtw_memcmp( cmd, "disable", 7 ) )
{
DBG_871X("Intel WiDi Disable\n");
pmlmepriv->widi_state = INTEL_WIDI_STATE_NONE;
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK);
}
else if ( _rtw_memcmp( cmd, "listen", 6 ) )
{
DBG_871X("Intel WiDi start listening for RDS Source\n");
pmlmepriv->widi_state = INTEL_WIDI_STATE_LISTEN;
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK);
}
else if ( _rtw_memcmp( cmd, "wps_start", 9 ) )
{
DBG_871X("Intel WiDi start WPS with RDS Source\n");
pmlmepriv->widi_state = INTEL_WIDI_STATE_WPS;
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK);
}
else if ( _rtw_memcmp( cmd, "associate", 9 ) )
{
DBG_871X("Intel WiDi is ready to associate with RDS Source\n");
pmlmepriv->widi_state = INTEL_WIDI_STATE_ASSOICATE;
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK);
}
else if ( _rtw_memcmp( cmd, "connected", 9 ) )
{
DBG_871X("Intel WiDi is connected with RDS Source\n");
pmlmepriv->widi_state = INTEL_WIDI_STATE_CONNECTED;
process_intel_widi_assoc_status(padapter, L2SDTA_ASSOCIATED);
}
}
void intel_widi_listen_timer_hdl(void *FunctionContext)
{
_adapter *padapter = (_adapter *)FunctionContext;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
if(pmlmepriv->listen_state == INTEL_WIDI_LISTEN_PROCESS)
{
pmlmepriv->channel_idx++;
}
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK);
}
void intel_widi_listen_stop_handler(_adapter *padapter)
{
u8 val8;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
if(pmlmepriv->listen_state == INTEL_WIDI_LISTEN_STOP)
return;
DBG_871X("Leave WiDi Listen Mode\n");
_cancel_timer_ex(&(pmlmepriv->listen_timer));
val8 = 0;
padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
//config MSR
Set_MSR(padapter, (pmlmeinfo->state & 0x3));
//turn on dynamic functions
Restore_DM_Func_Flag(padapter);
pmlmepriv->listen_state = INTEL_WIDI_LISTEN_STOP;
pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
}
void intel_widi_listen_handler(_adapter *padapter)
{
u8 listen_channel, val8;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if(pmlmepriv->widi_state != INTEL_WIDI_STATE_LISTEN)
{
if(pmlmepriv->listen_state != INTEL_WIDI_LISTEN_STOP)
{
intel_widi_listen_stop_handler(padapter);
}
return;
}
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE)
{
_set_timer(&(pmlmepriv->listen_timer), 1000);
return;
}
if(pmlmepriv->listen_state == INTEL_WIDI_LISTEN_STOP)
{
pmlmepriv->channel_idx = 0;
_rtw_memset(pmlmeext->sitesurvey_res.ss_ssid, 0, (IW_ESSID_MAX_SIZE + 1));
pmlmeext->sitesurvey_res.ss_ssidlen = 0;
//disable dynamic functions, such as high power, DIG
Save_DM_Func_Flag(padapter);
Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
//set MSR to no link state
Set_MSR(padapter, _HW_STATE_NOLINK_);
val8 = 1; //before site survey
padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
pmlmepriv->listen_state = INTEL_WIDI_LISTEN_PROCESS;
pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
}
listen_channel = pmlmeext->channel_set[pmlmepriv->channel_idx].ChannelNum;
if(listen_channel == 0)
{
// Get Back to first channel
pmlmepriv->channel_idx = 0;
listen_channel = pmlmeext->channel_set[pmlmepriv->channel_idx].ChannelNum;
}
if(pmlmepriv->channel_idx == 0)
{
set_channel_bwmode(padapter, listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
}
else
{
SelectChannel(padapter, listen_channel);
}
_set_timer(&(pmlmepriv->listen_timer), SURVEY_TO);
}
void intel_widi_wk_hdl(_adapter *padapter, u8 intel_widi_state)
{
_func_enter_;
switch(intel_widi_state)
{
case INTEL_WIDI_LISTEN_WK:
intel_widi_listen_handler(padapter);
break;
case INTEL_WIDI_LISTEN_STOP_WK:
intel_widi_listen_stop_handler(padapter);
break;
default:
break;
}
_func_exit_;
}
u8 intel_widi_wk_cmd(_adapter*padapter, u8 intel_widi_state)
{
struct cmd_obj *ph2c;
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
u8 res = _SUCCESS;
_func_enter_;
ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
if(ph2c==NULL){
res= _FAIL;
goto exit;
}
pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
if(pdrvextra_cmd_parm==NULL){
rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
res= _FAIL;
goto exit;
}
pdrvextra_cmd_parm->ec_id = INTEl_WIDI_WK_CID;
pdrvextra_cmd_parm->type_size = intel_widi_state;
pdrvextra_cmd_parm->pbuf = NULL;
init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
exit:
_func_exit_;
return res;
}
#endif //CONFIG_INTEL_WIDI

View File

@ -0,0 +1,436 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
/*
The purpose of rtw_io.c
a. provides the API
b. provides the protocol engine
c. provides the software interface between caller and the hardware interface
Compiler Flag Option:
1. CONFIG_SDIO_HCI:
a. USE_SYNC_IRP: Only sync operations are provided.
b. USE_ASYNC_IRP:Both sync/async operations are provided.
2. CONFIG_USB_HCI:
a. USE_ASYNC_IRP: Both sync/async operations are provided.
3. CONFIG_CFIO_HCI:
b. USE_SYNC_IRP: Only sync operations are provided.
Only sync read/rtw_write_mem operations are provided.
jackson@realtek.com.tw
*/
#define _RTW_IO_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_io.h>
#include <osdep_intf.h>
#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
#error "Shall be Linux or Windows, but not both!\n"
#endif
#ifdef CONFIG_SDIO_HCI
#include <sdio_ops.h>
#endif
#ifdef CONFIG_USB_HCI
#include <usb_ops.h>
#endif
#ifdef CONFIG_PCI_HCI
#include <pci_ops.h>
#endif
u8 _rtw_read8(_adapter *adapter, u32 addr)
{
u8 r_val;
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
_func_enter_;
_read8 = pintfhdl->io_ops._read8;
r_val = _read8(pintfhdl, addr);
_func_exit_;
return r_val;
}
u16 _rtw_read16(_adapter *adapter, u32 addr)
{
u16 r_val;
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
_func_enter_;
_read16 = pintfhdl->io_ops._read16;
r_val = _read16(pintfhdl, addr);
_func_exit_;
return r_val;
}
u32 _rtw_read32(_adapter *adapter, u32 addr)
{
u32 r_val;
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
_func_enter_;
_read32 = pintfhdl->io_ops._read32;
r_val = _read32(pintfhdl, addr);
_func_exit_;
return r_val;
}
int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_func_enter_;
_write8 = pintfhdl->io_ops._write8;
ret = _write8(pintfhdl, addr, val);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_func_enter_;
_write16 = pintfhdl->io_ops._write16;
ret = _write16(pintfhdl, addr, val);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_func_enter_;
_write32 = pintfhdl->io_ops._write32;
ret = _write32(pintfhdl, addr, val);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = (struct intf_hdl*)(&(pio_priv->intf));
int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata);
int ret;
_func_enter_;
_writeN = pintfhdl->io_ops._writeN;
ret = _writeN(pintfhdl, addr,length,pdata);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
int ret;
_func_enter_;
_write8_async = pintfhdl->io_ops._write8_async;
ret = _write8_async(pintfhdl, addr, val);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
int ret;
_func_enter_;
_write16_async = pintfhdl->io_ops._write16_async;
ret = _write16_async(pintfhdl, addr, val);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
{
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
int ret;
_func_enter_;
_write32_async = pintfhdl->io_ops._write32_async;
ret = _write32_async(pintfhdl, addr, val);
_func_exit_;
return RTW_STATUS_CODE(ret);
}
void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_func_enter_;
if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
{
RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
return;
}
_read_mem = pintfhdl->io_ops._read_mem;
_read_mem(pintfhdl, addr, cnt, pmem);
_func_exit_;
}
void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_func_enter_;
_write_mem = pintfhdl->io_ops._write_mem;
_write_mem(pintfhdl, addr, cnt, pmem);
_func_exit_;
}
void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_func_enter_;
if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
{
RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
return;
}
_read_port = pintfhdl->io_ops._read_port;
_read_port(pintfhdl, addr, cnt, pmem);
_func_exit_;
}
void _rtw_read_port_cancel(_adapter *adapter)
{
void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
if(_read_port_cancel)
_read_port_cancel(pintfhdl);
}
void _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
{
u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_func_enter_;
_write_port = pintfhdl->io_ops._write_port;
_write_port(pintfhdl, addr, cnt, pmem);
_func_exit_;
}
void _rtw_write_port_cancel(_adapter *adapter)
{
void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
if(_write_port_cancel)
_write_port_cancel(pintfhdl);
}
void _rtw_attrib_read(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem){
#ifdef CONFIG_SDIO_HCI
void (*_attrib_read)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_func_enter_;
_attrib_read= pintfhdl->io_ops._attrib_read;
_attrib_read(pintfhdl, addr, cnt, pmem);
_func_exit_;
#endif
}
void _rtw_attrib_write(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem){
#ifdef CONFIG_SDIO_HCI
void (*_attrib_write)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
//struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
struct io_priv *pio_priv = &adapter->iopriv;
struct intf_hdl *pintfhdl = &(pio_priv->intf);
_func_enter_;
_attrib_write= pintfhdl->io_ops._attrib_write;
_attrib_write(pintfhdl, addr, cnt, pmem);
_func_exit_;
#endif
}
int rtw_init_io_priv(_adapter *padapter)
{
void (*set_intf_ops)(struct _io_ops *pops);
struct io_priv *piopriv = &padapter->iopriv;
struct intf_hdl *pintf = &piopriv->intf;
piopriv->padapter = padapter;
pintf->padapter = padapter;
pintf->pintf_dev = &padapter->dvobjpriv;
#ifdef CONFIG_SDIO_HCI
set_intf_ops = &sdio_set_intf_ops;
#endif //END OF CONFIG_SDIO_HCI
#ifdef CONFIG_USB_HCI
if(padapter->chip_type == RTL8188C_8192C)
{
#ifdef CONFIG_RTL8192C
set_intf_ops = &rtl8192cu_set_intf_ops;
#endif
}
else if(padapter->chip_type == RTL8192D)
{
#ifdef CONFIG_RTL8192D
set_intf_ops = &rtl8192du_set_intf_ops;
#endif
}
else
{
set_intf_ops = NULL;
}
#endif //END OF CONFIG_USB_HCI
#ifdef CONFIG_PCI_HCI
if(padapter->chip_type == RTL8188C_8192C)
{
#ifdef CONFIG_RTL8192C
set_intf_ops = &rtl8192ce_set_intf_ops;
#endif
}
else if(padapter->chip_type == RTL8192D)
{
#ifdef CONFIG_RTL8192D
set_intf_ops = &rtl8192de_set_intf_ops;
#endif
}
else
{
set_intf_ops = NULL;
}
#endif //END OF CONFIG_PCI_HCI
if(set_intf_ops==NULL)
return _FAIL;
set_intf_ops(&pintf->io_ops);
return _SUCCESS;
}

View File

@ -0,0 +1,197 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_IOCTL_QUERY_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
#include <rtw_ioctl_query.h>
#include <wifi.h>
#ifdef PLATFORM_WINDOWS
//
// Added for WPA2-PSK, by Annie, 2005-09-20.
//
u8
query_802_11_capability(
_adapter* Adapter,
u8* pucBuf,
u32 * pulOutLen
)
{
static NDIS_802_11_AUTHENTICATION_ENCRYPTION szAuthEnc[] =
{
{Ndis802_11AuthModeOpen, Ndis802_11EncryptionDisabled},
{Ndis802_11AuthModeOpen, Ndis802_11Encryption1Enabled},
{Ndis802_11AuthModeShared, Ndis802_11EncryptionDisabled},
{Ndis802_11AuthModeShared, Ndis802_11Encryption1Enabled},
{Ndis802_11AuthModeWPA, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPA2, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA2, Ndis802_11Encryption3Enabled},
{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled},
{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled}
};
static ULONG ulNumOfPairSupported = sizeof(szAuthEnc)/sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
NDIS_802_11_CAPABILITY * pCap = (NDIS_802_11_CAPABILITY *)pucBuf;
u8* pucAuthEncryptionSupported = (u8*) pCap->AuthenticationEncryptionSupported;
pCap->Length = sizeof(NDIS_802_11_CAPABILITY);
if(ulNumOfPairSupported > 1 )
pCap->Length += (ulNumOfPairSupported-1) * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
pCap->Version = 2;
pCap->NoOfPMKIDs = NUM_PMKID_CACHE;
pCap->NoOfAuthEncryptPairsSupported = ulNumOfPairSupported;
if( sizeof (szAuthEnc) <= 240 ) // 240 = 256 - 4*4 // SecurityInfo.szCapability: only 256 bytes in size.
{
_rtw_memcpy( pucAuthEncryptionSupported, (u8*)szAuthEnc, sizeof (szAuthEnc) );
*pulOutLen = pCap->Length;
return _TRUE;
}
else
{
*pulOutLen = 0;
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("_query_802_11_capability(): szAuthEnc size is too large.\n"));
return _FALSE;
}
}
u8 query_802_11_association_information( _adapter *padapter,PNDIS_802_11_ASSOCIATION_INFORMATION pAssocInfo)
{
struct wlan_network *tgt_network;
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
struct security_priv *psecuritypriv=&(padapter->securitypriv);
WLAN_BSSID_EX *psecnetwork=(WLAN_BSSID_EX*)&(psecuritypriv->sec_bss);
u8 * pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
unsigned char i,*auth_ie,*supp_ie;
//NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
_rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
//pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
//------------------------------------------------------
// Association Request related information
//------------------------------------------------------
// Req_1. AvailableRequestFixedIEs
if(psecnetwork!=NULL){
pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES|NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short)* & psecnetwork->IEs[10];
_rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress,
& psecnetwork->MacAddress, 6);
pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
if(check_fwstate( pmlmepriv, _FW_UNDER_LINKING|_FW_LINKED)==_TRUE)
{
if(psecuritypriv->ndisauthtype>=Ndis802_11AuthModeWPA2)
pDest[0] =48; //RSN Information Element
else
pDest[0] =221; //WPA(SSN) Information Element
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n Adapter->ndisauthtype==Ndis802_11AuthModeWPA)?0xdd:0x30 [%d]",pDest[0]));
supp_ie=&psecuritypriv->supplicant_ie[0];
for(i=0;i<supp_ie[0];i++)
{
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("IEs [%d] = 0x%x \n\n", i,supp_ie[i]));
}
i=13; //0~11 is fixed information element
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("i= %d tgt_network->network.IELength=%d\n\n", i,(int)psecnetwork->IELength));
while((i<supp_ie[0]) && (i<256)){
if((unsigned char)supp_ie[i]==pDest[0]){
_rtw_memcpy((u8 *)(pDest),
&supp_ie[i],
supp_ie[1+i]+2);
break;
}
i=i+supp_ie[i+1]+2;
if(supp_ie[1+i]==0)
i=i+1;
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("iteration i=%d IEs [%d] = 0x%x \n\n", i,i,supp_ie[i+1]));
}
pAssocInfo->RequestIELength += (2 + supp_ie[1+i]);// (2 + psecnetwork->IEs[1+i]+4);
}
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n psecnetwork != NULL,fwstate==_FW_UNDER_LINKING \n"));
}
//------------------------------------------------------
// Association Response related information
//------------------------------------------------------
if(check_fwstate( pmlmepriv, _FW_LINKED)==_TRUE)
{
tgt_network =&(pmlmepriv->cur_network);
if(tgt_network!=NULL){
pAssocInfo->AvailableResponseFixedIEs =
NDIS_802_11_AI_RESFI_CAPABILITIES
|NDIS_802_11_AI_RESFI_ASSOCIATIONID
;
pAssocInfo->ResponseFixedIEs.Capabilities =(unsigned short)* & tgt_network->network.IEs[10];
pAssocInfo->ResponseFixedIEs.StatusCode = 0;
pAssocInfo->ResponseFixedIEs.AssociationId =(unsigned short) tgt_network->aid;
pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+pAssocInfo->RequestIELength;
auth_ie=&psecuritypriv->authenticator_ie[0];
for(i=0;i<auth_ie[0];i++)
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("IEs [%d] = 0x%x \n\n", i,auth_ie[i]));
i=auth_ie[0]-12;
if(i>0){
_rtw_memcpy((u8 *)&pDest[0],&auth_ie[1],i);
pAssocInfo->ResponseIELength =i;
}
pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength;
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n tgt_network != NULL,fwstate==_FW_LINKED \n"));
}
}
RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n exit query_802_11_association_information \n"));
_func_exit_;
return _TRUE;
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,170 @@
begin 644 core/rtw_ioctl_set.o
M?T5,1@$!`0````````````$`*``!``````````````!D$```````!30`````
M`"@`$``-``1`+>4`()#E(`!2XQ0``(H``%+C%```"@0PT.4@,$/B<S#OYEX`
M4^,`0*"3!!"@DP8``)H*``#J!#"`X`$PT^<@,$/B<S#OYEX`4^,$``"*`4"$
MXG1`[^8$`%+A]?__B@$``.H`0*#C````Z@%`H.,$`*#A$`"]Z![_+^$00"WI
M`#"@X00@D>4-$=+C$P``&@$#$N,'```:!CN`X@PP@^(#(`+B`@*#X``0H.,0
M(*#C_O__ZPD``.I7#8#B&`"`XN`0@^+^___K`$!0X@,```H1#H3B`!"@XQ`@
MH./^___K`0"@XQ"`O>CP02WI`4"@X0%@H.$`4*#A`0!PX@``H#.A#Y#A%0``
M&@,`4>,3``"*7GV%XC0`A^(!`H#@`!"@XQ`@H./^___K!0"@X2@0A^($(*#A
M`#"@X_[__^M?3H3B#$"$X@1!A>`$0(3B`#"@XP`PA.4#0%#@`4"@$P```.H`
M0*#C!`"@X?"!O>AP0"WI`$"@X0%0H.$$8)'E`V'&XP0`5N,`0*##(@``R@@P
MD>4%`%/C`2"@`ZPW`0,#((0'!@``"@T`4^,`(*`3K#<!$P,@A!<%(*`#K#<!
M`P,@A`=>#X;B`P"`X@`"A.`$`(#B#!"%X@@@E>7^___K7SZ&X@PP@^(#,83@
M"""5Y00@@^6P-P'C`V"$YP0`H.%>'83B*!"!X@8@H.$!,*#C_O__ZP!`4.(!
M0*`3!`"@X7"`O>CP1RWI"-!-X@!`H.$!4*#A!#"1Y0``4^,"``"Z`0$3XRX`
M``I#`0#J`0$3XRL```I7#8#B&`"`XN`0A.+^___K`&!0X@0```JH-P'C`S"4
MYP(`4^/L8)8%`0``"JPW`>,#8)3G!##5Y0``4^,Q`0`:##"5Y0$`<^,R`0`:
ML"'5X?\_#^,#`%+A+@$`&BD!`.H(,)7E(`!3XR8!`!I,``#J!`!6XPD``!H(
M,)7E$`!3XP8```H@`%/C'@$`&A`PH.,(,(7E`'"@XP>`H.%$``#J!0!6XP$`
M5A,6`0`*/```ZA`[`>,#,)3G`P!3XQ,``(H$.`'C`S"4YP``4^,/```:"#"5
MY04`4^,!(*`#K#<!`P,@A`<&```*#0!3XP`@H!.L-P$3`R"$%P4@H`.L-P$#
M`R"$!ZPW`>,#8)3G`0``Z@0X`>,#8)3G;#"4Y2``$^,&```*##"5Y0$`<^/U
M```:L"'5X?\_#^,#`%+A\0``&@(`5N,#```:"#"5Y2``4^/L```:"```Z@0`
M5N,&```:"#"5Y1``4^,@`%,3Y0``&B``4^,0,*`#"#"%!01PE>77?>#G;#"4
MY2``$^,'```*`0`3XP%PH!,'@*`1`P``"@,``.H`<*#C!X"@X0```.H!@*#C
MJ#<!XP,PE.<"`%/C)@``"@4`5N,!`%83(P``&@@@E>4@((+BE#X!XP,@A.<$
M8)7E`F'&XY@^`>,#8(3G"""5Y9P^`>,#((3G('"%XGJ-A.(@`(CB!Q"@X0@@
ME>7^___K7C^&X@,P@^(#,H3@!`"#X@<0H.$(()7E_O__ZU\^AN(,,(/B`S&$
MX`@@E>4$((/EL#<!XP-@A.<$`*#A%!"(XO[__^L!0*#CJ@``Z@0PE>4"`A/C
M&P``"@$`6.,,```:V`'%X0`@X./_/P_C`"`"X`$P`^`($(WB^"!AX6,-A.(8
M`(#B#1"@X0@@H./^___K#@``ZM@!Q>$`(.#C_S\/XP`@`N`!,`/@"!"-XO@@
M8>%C#83B$`"`X@T0H.$((*#C_O__ZU```.H!`%CC3@``&@$`5^,$(-4%"#@!
M`P,@A`<$,)7E`P`3XX$```H&:X3B#&"&X@,P`^(#`H;@`!"@XQ`@H./^___K
M87V$X@QPA^($`-7E`P``X@`"A^``$*#C$""@X_[__^MBC83B#("(X@0`U>4#
M``#B``*(X``0H.,0(*#C_O__ZP0PE>4!`A/C"P``"@,P`^(#`H?@,!"%X@@@
MH./^___K!`#5Y0,``.(``HC@.!"%X@@@H./^___K"@``Z@,P`^(#`H?@.!"%
MX@@@H./^___K!`#5Y0,``.(``HC@,!"%X@@@H./^___K!`#5Y0,``.(``H;@
M(!"%X@@@E>7^___K!#"5Y0,P`^($,(7E`3"@XQLLH.,",,3G`!"@XP(K`>,"
M$,3G!`"@X5X=A.(H$('B!""5Y?[__^L`0%#B`4"@$SH``.I7#83B&`"`XN`0
MA.+^___K`(!0X@%`H`,S```*$:Z(X@H`H.$`$*#C$""@X_[__^L@D(7B"@"@
MX0D0H.$0(*#C_O__ZP(`5N,6```:`""@XP$[`>,#(,3G!#"5Y0$"$^,(```*
M\`"(XA`0B>(((*#C_O__ZP$,B.(8$(GB"""@X_[__^L'``#J\`"(XA@0B>((
M(*#C_O__ZP$,B.(0$(GB"""@X_[__^L``%?C!0``"@0`H.$($*#A`""@X_[_
M_^L`0*#A!```Z@0`H.$($*#A`2"@X_[__^L`0*#A`$!4X@%`H!,```#J`$"@
MXP0`H.$(T(WB\(>]Z`(`5N/3_O\:SO[_ZA!`+>E>38#B*$"$XA`[`>,#$(#G
M`P!1XP(@H(.H-P&#`R"`AP00H.'^___K`0!0XP``H!,!`*`#$("]Z'!`+>DH
MT$WB`$!0XAX```J!-0/C`S#4YP``4^,:```*;#"4Y2(-$^,9```:$#74Y0$`
M4^,6```*_O__ZPTPH.%_;</C/V#&XP0PEN4!,(/B!#"&Y010C>(%`*#A`!"@
MXR0@H./^___K!`"@X040H.'^___K`$"@X00PEN4!,$/B!#"&Y?[__^L"``#J
M`$"@XP```.H!0*#C!`"@X2C0C>)P@+WH$$`MZ0!`H.'^___K#2"@X7\]PN,_
M,,/C!""3Y0$@@N($((/E;#"4Y0$`$^,%```*!`"@X?[__^L$`*#A_O__ZP0`
MH.'^___K#2"@X7\]PN,_,,/C!""3Y0$@0N($((/E_O__ZP$`H.,0@+WH<$`M
MZ0!`H.$!4*#A/#&0Y0$`4^$^```*_O__ZPT@H.%_/<+C/S##XP0@D^4!((+B
M!""#Y6PPE.4!`!/C`@``&CPAE.4``%+C!```&@0`H.'^___K;#"4Y0$`$^,!
M```:0``3XP0```H$`*#A_O__ZVPPE.4!`!/C!```&CPQE.4!`%/C`0``"@``
M4^,!```:!`"@X?[__^L\,93E!`!3XP,``!H`,.#CV#"$Y00`H.'^___K/%&$
MY6PPE.5X,,/C;#"$Y0$`5>,(,(,#;#"$!0@```H@,(,S;#"$-04``#H$`%7C
M`P``&A`P@^-L,(3E!`"@X?[__^L-(*#A?SW"XS\PP^,$()/E`2!"X@0@@^7^
M___K`0"@XW"`O>AP0"WI`$"@X810D.4!,.#CV#"`Y6PPD.6`,(/C;#"`Y7A0
M@.4!,*#C<##`Y80`@.+^___K`0!0XPT``!IL,)3E@###XVPPA.40-=3E``!3
MXP(```IQ,-3E``!3XSP```H$`*#AE!"$XO[__^L`0*#A.```ZFP`A.+^___K
M`0!0XPL``!H`,*#C<##$Y0`P`.,`,$#C`!"3Y44.A.(,`(#BHA^!X@(0@>+^
M___K`4"@XR@``.IL,)3E(``3XQ<```I`,*#C;#"$Y:EMA.(M4(;B!0"@X0`0
MH.,D(*#C_O__ZP4`H.&4$(3B)""@X_[__^L$`*#A_O__ZR4`AN+^___K!`"@
MX?[__^L!`%#C`$"@$P`PH`-P,,0%`4"@`PT``.J`,,/C;#"$Y1`UU.4``%/C
M`@``"G$PU.4``%/C!```"@0`H.&4$(3B_O__ZP!`H.$```#J`4"@XP0`H.%P
M@+WH\$$MZ0!0H.$!<*#A@34#XP,PT.<``%/C`$"@`V\```IL,)#E@``3XP%`
MH!-K```:`@L3XVL``!H0``#J;#"5Y0(+$^,%```*!@"@X?[__^L!0$3B`0!T
MX_?__QH!``#J``!4XP4``,J,`9_EC!&?Y?[__^ML0)7EU$/@YU```.K^___K
M#2"@X7\]PN,_,,/C!""3Y0$@@N($((/E;#"5Y4$`$^,S```*E""5Y0`PE^4#
M`%+A(0``&I@`A>($$(?B_O__ZP$`4.,<```:;#"5Y0@`$^,4```:!0"@X<`0
MA>+^___K``!0XP%`H!,T```:!0"@X?[__^ML,)7E`0`3XP$```H%`*#A_O__
MZP4`H.'^___K;#"5Y4``$^-`,,,3(#"#$VPPA142``#J!0"@X0$0H.,!(*#A
M_O__ZPT``.H%`*#A_O__ZVPPE>4!`!/C`0``"@4`H.'^___K!0"@X?[__^ML
M,)7E0``3XT`PPQ,@,(,3;#"%%0PV`N,#,-7G`0!3XPT```H'`*#A_O__ZP``
M4.,)```*E`"%X@<0H.$D(*#C_O__ZP`PH..,-(7E!0"@X?[__^L`0*#A````
MZ@!`H.,-(*#A?SW"XS\PP^,$()/E`2!"X@0@@^7^___K!`"@X?"!O>AD`*#C
M_O__ZS!`H.-D8*#CC___Z@``````````<$`MZ0!`H.$!4*#A`##1Y0``4^,/
M```:`2#1Y0``4N,,```:`C#1Y0``4^,:```:`S#1Y0``4^,7```:!##1Y0``
M4^,4```:!3#1Y0``4^,1```:1P``ZO\`4^,.```:`3#5Y?\`4^,+```:`C#5
MY?\`4^,(```:`S#5Y?\`4^,%```:!##5Y?\`4^,"```:!3#5Y?\`4^,V```*
M_O__ZPT@H.%_/<+C/S##XP0@D^4!((+B!""#Y6PPE.4B#1/CTT/@%R,``!I!
M`!/C&```"N``A.(%$*#A!B"@X_[__^L!`%#C!```&FPPE.4(`!/C`4"@`Q<`
M``H-``#J!`"@X?[__^ML,)3E`0`3XP$```H$`*#A_O__ZP0`H.'^___K;#"4
MY4``$^-`,,,3(#"#$VPPA!6X`(3B!1"@X08@H./^___K`3"@XXPTA.4$`*#A
M_O__ZP!`H.$-(*#A?SW"XS\PP^,$()/E`2!"X@0@@^7^___K````Z@!`H.,$
M`*#A<("]Z`````"PL*"`?````+"PJ(#H````L+"L@&P!``"PL*J`(`(``+"N
M`8!T!P``L+"H@+`'``"PJ@F`5`@``+"PJ(#`"```L+"J@-P)``"PL*J`/`L`
M`+"PK(!`#0``L+"J@')T=U]S971?.#`R7S$Q7W-S:60`)7,Z(%-E="!34TE$
M(&ES(&YO="!A;&QO=V5D('5N9&5R('-U<G9E>6EN9PH``````$=#0SH@*$=.
M52D@-"XT+C``02H```!A96%B:0`!(`````4W+4$`!@H'00@!$@04`14!%P,8
M`1D!&@(>`0`N<WEM=&%B`"YS=')T86(`+G-H<W1R=&%B`"YR96PN=&5X=``N
M9&%T80`N8G-S`"Y!4DTN97AT86(`+G)E;"Y!4DTN97AI9'@`+G)O9&%T80`N
M<F]D871A+G-T<C$N-``N8V]M;65N=``N;F]T92Y'3E4M<W1A8VL`+D%232YA
M='1R:6)U=&5S````````````````````````````````````````````````
M````````'P````$````&`````````#0```#$#@`````````````$````````
M`!L````)```````````````8&@``N`(```X````!````!`````@````E````
M`0````,`````````^`X```````````````````$`````````*P````@````#
M`````````/@.```````````````````!`````````#`````!`````@``````
M``#X#@```````````````````0`````````_`````0``<((`````````^`X`
M`&`````!``````````0`````````.P````D``````````````-`<``!H````
M#@````8````$````"````$H````!`````@````````!8#P``%```````````
M````!`````````!2`````0```#(`````````;`\``#````````````````0`
M```!````80````$``````````````)P/```2```````````````!````````
M`&H````!``````````````"N#P```````````````````0````````!Z````
M`P``<```````````K@\``"L```````````````$`````````$0````,`````
M`````````-D/``"*```````````````!``````````$````"````````````
M``#D$@``$`0```\````:````!````!`````)`````P``````````````]!8`
M`",#``````````````$```````````````````````````````$`````````
M``````0`\?\````````````````#``$``````````````````P`#````````
M``````````,`!``1``````````````````$``````````````````P`%````
M``````````````,`!@`1````?`````````````$`$0```.@````````````!
M`!$```!L`0```````````0`1````(`(```````````$`$0```'0'````````
M```!`!$```"P!P```````````0`1````5`@```````````$`$0```,`(````
M```````!`!$```#<"0```````````0`1````/`L```````````$`%````#@-
M```````````!`!$```!`#0```````````0`````````````````#``@`%P``
M```````4`````0`(``````````````````,`"0`````````````````#``L`
M`````````````````P`*``````````````````,`#``F`````````'P````2
M``$`.```````````````$````$\```!\````;````!(``0!I````````````
M```0````=0``````````````$````(4```#H````A````!(``0"?````````
M```````0````JP```&P!``"T````$@`!`,(``````````````!````#.````
M(`(``%0%```2``$`Y0``````````````$````/<```!T!P``/````!(``0`:
M`0`````````````0````)P$``+`'``"D````$@`!`$8!`````````````!``
M``!7`0`````````````0````:@$`````````````$````'H!``!4"```;```
M`!(``0"6`0`````````````0````IP$`````````````$````+\!````````
M`````!````#8`0``P`@``!P!```2``$`^P$`````````````$`````@"````
M`````````!`````6`@``W`D``&`!```2``$`(@(`````````````$````#,"
M`````````````!````!:`@`````````````0````8@(`````````````$```
M`&P"`````````````!````"0`@`````````````0````J0(`````````````
M$````+L"```\"P``!`(``!(``0#/`@`````````````0````U@(`````````
M````$````-T"`````````````!````#I`@`````````````0````^@(`````
M````````$`````X#``!`#0``A`$``!(``0``<G1W7VEO8W1L7W-E="YC`"1A
M`"1D`%]?9G5N8U]?+C,T-C8V`')T=U]V86QI9&%T95]S<VED`%]?865A8FE?
M=6YW:6YD7V-P<%]P<C``<G1W7W-E=%\X,#)?,3%?<F5M;W9E7VME>0!?<G1W
M7VUE;7-E=`!R='=?9V5T7W-T86EN9F\`<G1W7W-E=%\X,#)?,3%?<F5M;W9E
M7W=E<`!R='=?<V5T7VME>0!R='=?<V5T7S@P,E\Q,5]A9&1?=V5P`%]R='=?
M;65M8W!Y`')T=U]S971?.#`R7S$Q7V%D9%]K97D`<G1W7W-E='-T86ME>5]C
M;60`<G1W7W-E=%\X,#)?,3%?875T:&5N=&EC871I;VY?;6]D90!R='=?<V5T
M7V%U=&@`<G1W7W-E=%\X,#)?,3%?8G-S:61?;&ES=%]S8V%N`&QO8V%L7V)H
M7V1I<V%B;&4`<G1W7W-I=&5S=7)V97E?8VUD`&QO8V%L7V)H7V5N86)L90!R
M='=?<V5T7S@P,E\Q,5]D:7-A<W-O8VEA=&4`<G1W7V1I<V%S<V]C7V-M9`!R
M='=?:6YD:6-A=&5?9&ES8V]N;F5C=`!R='=?9G)E95]A<W-O8U]R97-O=7)C
M97,`<G1W7W-E=%\X,#)?,3%?:6YF<F%S=')U8W1U<F5?;6]D90!S=&]P7V%P
M7VUO9&4`<W1A<G1?87!?;6]D90!R='=?9&]?:F]I;@!?<G1W7W%U975E7V5M
M<'1Y`')T=U]S96QE8W1?86YD7VIO:6Y?9G)O;5]S8V%N;F5D7W%U975E`&II
M9F9I97,`;6]D7W1I;65R`')T=U]U<&1A=&5?<F5G:7-T<GEP<FEV7V1E=E]N
M971W;W)K`')T=U]G96YE<F%T95]R86YD;VU?:6)S<P!R='=?8W)E871E8G-S
M7V-M9`!R='=?<V5T7S@P,E\Q,5]S<VED`&US;&5E<`!P<FEN=&L`7W)T=U]M
M96UC;7``<G1W7VES7W-A;65?:6)S<P!R='=?;'!S7V-T<FQ?=VM?8VUD`')T
M=U]S971?.#`R7S$Q7V)S<VED``"P````'!T``,0````<'@``W````!P=```D
M`0``'!T``#@!```<(```V`$``!PB```,`@``'"```%P"```<'@``8`0``!PB
M``!\!```'"(``*0$```<(0``\`0``!PB```D!0``'"(``&@%```<'0``B`4`
M`!P=``"H!0``'!T``,@%```<(@``X`4``!PB``#X!0``'"(``!`&```<(@``
M*`8``!PB``!@!@``'"```'P&```<'@``G`8``!P=``"P!@``'"(``.`&```<
M(@``\`8``!PB```$!P``'"(``!0'```<(@``+`<``!PD``!$!P``'"0``)P'
M```<)@``Z`<``!PH```4"```'!T``"`(```<*0``-`@``!PJ``!<"```'"@`
M`(@(```<+```D`@``!PM``"8"```'"X``+0(```<*@``V`@``!PH```0"0``
M'"P``"P)```<+@``5`D``!PM``!P"0``'#```+0)```<,0``T`D``!PJ```,
M"@``'#,``$0*```<*0``5`H``!PT``!H"@``*S4``&P*```L-0``A`H``!PV
M``"X"@``'!T``,@*```<(@``T`H``!PW``#8"@``'#@``.`*```<.0``)`L`
M`!PI``"("P``'#L``*P+```</```O`L``!PH``#\"P``'#T``!P,```</@``
M,`P``!PL``!$#```'"T``$P,```<+@``=`P``!P_``"`#```'"P``)0,```<
M+0``G`P``!PN``#(#```'!H``.`,```<(@``\`P``!PR```8#0``'"H``"@-
M```<.P``.`T```(6```\#0```A0``-P-```<*```'`X``!P]``!`#@``'"P`
M`%0.```<+0``7`X``!PN``"`#@``'"(``)`.```<,@``L`X``!PJ````````
M*@(`````````&P``"````"H"```0````*@(``!@````J`@``(````"H"```H
M````*@(``#`````J`@``.````"H"``!`````*@(``$@````J`@``4````"H"
*``!8````*@(`````
`
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_RF_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
#include <xmit_osdep.h>
struct ch_freq {
u32 channel;
u32 frequency;
};
struct ch_freq ch_freq_map[] = {
{1, 2412},{2, 2417},{3, 2422},{4, 2427},{5, 2432},
{6, 2437},{7, 2442},{8, 2447},{9, 2452},{10, 2457},
{11, 2462},{12, 2467},{13, 2472},{14, 2484},
/* UNII */
{36, 5180},{40, 5200},{44, 5220},{48, 5240},{52, 5260},
{56, 5280},{60, 5300},{64, 5320},{149, 5745},{153, 5765},
{157, 5785},{161, 5805},{165, 5825},{167, 5835},{169, 5845},
{171, 5855},{173, 5865},
/* HiperLAN2 */
{100, 5500},{104, 5520},{108, 5540},{112, 5560},{116, 5580},
{120, 5600},{124, 5620},{128, 5640},{132, 5660},{136, 5680},
{140, 5700},
/* Japan MMAC */
{34, 5170},{38, 5190},{42, 5210},{46, 5230},
/* Japan */
{184, 4920},{188, 4940},{192, 4960},{196, 4980},
{208, 5040},/* Japan, means J08 */
{212, 5060},/* Japan, means J12 */
{216, 5080},/* Japan, means J16 */
};
int ch_freq_map_num = (sizeof(ch_freq_map) / sizeof(struct ch_freq));
u32 rtw_ch2freq(u32 channel)
{
u8 i;
u32 freq = 0;
for (i = 0; i < ch_freq_map_num; i++)
{
if (channel == ch_freq_map[i].channel)
{
freq = ch_freq_map[i].frequency;
break;
}
}
if (i == ch_freq_map_num)
freq = 2412;
return freq;
}
u32 rtw_freq2ch(u32 freq)
{
u8 i;
u32 ch = 0;
for (i = 0; i < ch_freq_map_num; i++)
{
if (freq == ch_freq_map[i].frequency)
{
ch = ch_freq_map[i].channel;
break;
}
}
if (i == ch_freq_map_num)
ch = 1;
return ch;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,654 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
*
*
******************************************************************************/
#define _RTW_STA_MGT_C_
#include <drv_conf.h>
#include <osdep_service.h>
#include <drv_types.h>
#include <recv_osdep.h>
#include <xmit_osdep.h>
#include <mlme_osdep.h>
#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
#error "Shall be Linux or Windows, but not both!\n"
#endif
#include <sta_info.h>
void _rtw_init_stainfo(struct sta_info *psta)
{
_func_enter_;
_rtw_memset((u8 *)psta, 0, sizeof (struct sta_info));
_rtw_spinlock_init(&psta->lock);
_rtw_init_listhead(&psta->list);
_rtw_init_listhead(&psta->hash_list);
//_rtw_init_listhead(&psta->asoc_list);
//_rtw_init_listhead(&psta->sleep_list);
//_rtw_init_listhead(&psta->wakeup_list);
_rtw_init_queue(&psta->sleep_q);
psta->sleepq_len = 0;
_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
_rtw_init_sta_recv_priv(&psta->sta_recvpriv);
#ifdef CONFIG_AP_MODE
_rtw_init_listhead(&psta->asoc_list);
_rtw_init_listhead(&psta->auth_list);
psta->expire_to = 0;
psta->flags = 0;
psta->capability = 0;
#ifdef CONFIG_NATIVEAP_MLME
psta->nonerp_set = 0;
psta->no_short_slot_time_set = 0;
psta->no_short_preamble_set = 0;
psta->no_ht_gf_set = 0;
psta->no_ht_set = 0;
psta->ht_20mhz_set = 0;
#endif
#endif
_func_exit_;
}
u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
{
struct sta_info *psta;
s32 i;
_func_enter_;
pstapriv->pallocated_stainfo_buf = rtw_zvmalloc (sizeof(struct sta_info) * NUM_STA+ 4);
if(!pstapriv->pallocated_stainfo_buf)
return _FAIL;
pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
((SIZE_PTR)(pstapriv->pallocated_stainfo_buf ) & 3);
_rtw_init_queue(&pstapriv->free_sta_queue);
_rtw_spinlock_init(&pstapriv->sta_hash_lock);
//_rtw_init_queue(&pstapriv->asoc_q);
pstapriv->asoc_sta_count = 0;
_rtw_init_queue(&pstapriv->sleep_q);
_rtw_init_queue(&pstapriv->wakeup_q);
psta = (struct sta_info *)(pstapriv->pstainfo_buf);
for(i = 0; i < NUM_STA; i++)
{
_rtw_init_stainfo(psta);
_rtw_init_listhead(&(pstapriv->sta_hash[i]));
rtw_list_insert_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
psta++;
}
#ifdef CONFIG_AP_MODE
pstapriv->sta_dz_bitmap = 0;
pstapriv->tim_bitmap = 0;
_rtw_init_listhead(&pstapriv->asoc_list);
_rtw_init_listhead(&pstapriv->auth_list);
pstapriv->auth_to = 3; // 3*2 = 6 sec
pstapriv->assoc_to = 3;
pstapriv->expire_to = 900;// 900*2 = 1800 sec = 30 min, expire after no any traffic.
pstapriv->max_num_sta = NUM_STA;
#endif
_func_exit_;
return _SUCCESS;
}
void _rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv)
{
_func_enter_;
_rtw_spinlock_free(&psta_xmitpriv->lock);
_rtw_spinlock_free(&(psta_xmitpriv->be_q.sta_pending.lock));
_rtw_spinlock_free(&(psta_xmitpriv->bk_q.sta_pending.lock));
_rtw_spinlock_free(&(psta_xmitpriv->vi_q.sta_pending.lock));
_rtw_spinlock_free(&(psta_xmitpriv->vo_q.sta_pending.lock));
_func_exit_;
}
static void _rtw_free_sta_recv_priv_lock(struct sta_recv_priv *psta_recvpriv)
{
_func_enter_;
_rtw_spinlock_free(&psta_recvpriv->lock);
_rtw_spinlock_free(&(psta_recvpriv->defrag_q.lock));
_func_exit_;
}
void rtw_mfree_stainfo(struct sta_info *psta)
{
_func_enter_;
if(&psta->lock != NULL)
_rtw_spinlock_free(&psta->lock);
_rtw_free_sta_xmit_priv_lock(&psta->sta_xmitpriv);
_rtw_free_sta_recv_priv_lock(&psta->sta_recvpriv);
_func_exit_;
}
// this function is used to free the memory of lock || sema for all stainfos
void rtw_mfree_all_stainfo(struct sta_priv *pstapriv )
{
_irqL irqL;
_list *plist, *phead;
struct sta_info *psta = NULL;
_func_enter_;
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
phead = get_list_head(&pstapriv->free_sta_queue);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
{
psta = LIST_CONTAINOR(plist, struct sta_info ,list);
plist = get_next(plist);
rtw_mfree_stainfo(psta);
}
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
_func_exit_;
}
void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv)
{
rtw_mfree_all_stainfo(pstapriv); //be done before free sta_hash_lock
_rtw_spinlock_free(&pstapriv->free_sta_queue.lock);
_rtw_spinlock_free(&pstapriv->sta_hash_lock);
_rtw_spinlock_free(&pstapriv->wakeup_q.lock);
_rtw_spinlock_free(&pstapriv->sleep_q.lock);
}
u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
{
_func_enter_;
if(pstapriv){
rtw_mfree_sta_priv_lock(pstapriv);
if(pstapriv->pallocated_stainfo_buf) {
rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4);
}
}
_func_exit_;
return _SUCCESS;
}
//struct sta_info *rtw_alloc_stainfo(_queue *pfree_sta_queue, unsigned char *hwaddr)
struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
{
_irqL irqL, irqL2;
uint tmp_aid;
s32 index;
_list *phash_list;
struct sta_info *psta;
_queue *pfree_sta_queue;
struct recv_reorder_ctrl *preorder_ctrl;
int i = 0;
u16 wRxSeqInitialValue = 0xffff;
_func_enter_;
pfree_sta_queue = &pstapriv->free_sta_queue;
_enter_critical_bh(&(pfree_sta_queue->lock), &irqL);
if (_rtw_queue_empty(pfree_sta_queue) == _TRUE)
{
psta = NULL;
}
else
{
psta = LIST_CONTAINOR(get_next(&pfree_sta_queue->queue), struct sta_info, list);
rtw_list_delete(&(psta->list));
tmp_aid = psta->aid;
_rtw_init_stainfo(psta);
_rtw_memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
index = wifi_mac_hash(hwaddr);
RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("rtw_alloc_stainfo: index = %x", index));
if(index >= NUM_STA){
RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("ERROR=> rtw_alloc_stainfo: index >= NUM_STA"));
psta= NULL;
goto exit;
}
phash_list = &(pstapriv->sta_hash[index]);
_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
rtw_list_insert_tail(&psta->hash_list, phash_list);
pstapriv->asoc_sta_count ++ ;
_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
// Commented by Albert 2009/08/13
// For the SMC router, the sequence number of first packet of WPS handshake will be 0.
// In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable.
// So, we initialize the tid_rxseq variable as the 0xffff.
for( i = 0; i < 16; i++ )
{
_rtw_memcpy( &psta->sta_recvpriv.rxcache.tid_rxseq[ i ], &wRxSeqInitialValue, 2 );
}
RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_info_,("alloc number_%d stainfo with hwaddr = %x %x %x %x %x %x \n",
pstapriv->asoc_sta_count , hwaddr[0], hwaddr[1], hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]));
init_addba_retry_timer(pstapriv->padapter, psta);
#ifdef CONFIG_TDLS
psta->padapter = pstapriv->padapter;
init_TPK_timer(pstapriv->padapter, psta);
_init_workitem(&psta->option_workitem, TDLS_option_workitem_callback, psta);
init_ch_switch_timer(pstapriv->padapter, psta);
init_base_ch_timer(pstapriv->padapter, psta);
_init_workitem(&psta->base_ch_workitem, base_channel_workitem_callback, psta);
init_off_ch_timer(pstapriv->padapter, psta);
_init_workitem(&psta->off_ch_workitem, off_channel_workitem_callback, psta);
#endif
//for A-MPDU Rx reordering buffer control
for(i=0; i < 16 ; i++)
{
preorder_ctrl = &psta->recvreorder_ctrl[i];
preorder_ctrl->padapter = pstapriv->padapter;
preorder_ctrl->enable = _FALSE;
preorder_ctrl->indicate_seq = 0xffff;
#ifdef DBG_RX_SEQ
DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d\n", __FUNCTION__, __LINE__,
preorder_ctrl->indicate_seq);
#endif
preorder_ctrl->wend_b= 0xffff;
//preorder_ctrl->wsize_b = (NR_RECVBUFF-2);
preorder_ctrl->wsize_b = 64;//64;
_rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
rtw_init_recv_timer(preorder_ctrl);
}
}
exit:
_exit_critical_bh(&(pfree_sta_queue->lock), &irqL);
_func_exit_;
return psta;
}
// using pstapriv->sta_hash_lock to protect
u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta)
{
int i;
_irqL irqL0;
_queue *pfree_sta_queue;
struct recv_reorder_ctrl *preorder_ctrl;
struct sta_xmit_priv *pstaxmitpriv;
struct xmit_priv *pxmitpriv= &padapter->xmitpriv;
struct sta_priv *pstapriv = &padapter->stapriv;
_func_enter_;
if (psta == NULL)
goto exit;
pfree_sta_queue = &pstapriv->free_sta_queue;
pstaxmitpriv = &psta->sta_xmitpriv;
//rtw_list_delete(&psta->sleep_list);
//rtw_list_delete(&psta->wakeup_list);
rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
psta->sleepq_len = 0;
_enter_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0);
rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
rtw_list_delete(&(pstaxmitpriv->vo_q.tx_pending));
_exit_critical_bh(&(pxmitpriv->vo_pending.lock), &irqL0);
_enter_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0);
rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
rtw_list_delete(&(pstaxmitpriv->vi_q.tx_pending));
_exit_critical_bh(&(pxmitpriv->vi_pending.lock), &irqL0);
_enter_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0);
rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
rtw_list_delete(&(pstaxmitpriv->bk_q.tx_pending));
_exit_critical_bh(&(pxmitpriv->bk_pending.lock), &irqL0);
_enter_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0);
rtw_free_xmitframe_queue( pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
rtw_list_delete(&(pstaxmitpriv->be_q.tx_pending));
_exit_critical_bh(&(pxmitpriv->be_pending.lock), &irqL0);
rtw_list_delete(&psta->hash_list);
RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("\n free number_%d stainfo with hwaddr = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",pstapriv->asoc_sta_count , psta->hwaddr[0], psta->hwaddr[1], psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]));
pstapriv->asoc_sta_count --;
// re-init sta_info; 20061114
_rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
_rtw_init_sta_recv_priv(&psta->sta_recvpriv);
_cancel_timer_ex(&psta->addba_retry_timer);
#ifdef CONFIG_TDLS
_cancel_timer_ex(&psta->TPK_timer);
_cancel_timer_ex(&psta->option_timer);
_cancel_timer_ex(&psta->base_ch_timer);
_cancel_timer_ex(&psta->off_ch_timer);
#endif
//for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer
for(i=0; i < 16 ; i++)
{
preorder_ctrl = &psta->recvreorder_ctrl[i];
_cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
}
#ifdef CONFIG_AP_MODE
rtw_list_delete(&psta->asoc_list);
rtw_list_delete(&psta->auth_list);
psta->expire_to = 0;
psta->sleepq_ac_len = 0;
psta->qos_info = 0;
psta->max_sp_len = 0;
psta->uapsd_bk = 0;
psta->uapsd_be = 0;
psta->uapsd_vi = 0;
psta->uapsd_vo = 0;
psta->has_legacy_ac = 0;
#ifdef CONFIG_NATIVEAP_MLME
pstapriv->sta_dz_bitmap &=~BIT(psta->aid);
pstapriv->tim_bitmap &=~BIT(psta->aid);
rtw_indicate_sta_disassoc_event(padapter, psta);
if (pstapriv->sta_aid[psta->aid - 1] == psta)
{
pstapriv->sta_aid[psta->aid - 1] = NULL;
psta->aid = 0;
}
#endif
#endif
_enter_critical_bh(&(pfree_sta_queue->lock), &irqL0);
rtw_list_insert_tail(&psta->list, get_list_head(pfree_sta_queue));
_exit_critical_bh(&(pfree_sta_queue->lock), &irqL0);
exit:
_func_exit_;
return _SUCCESS;
}
// free all stainfo which in sta_hash[all]
void rtw_free_all_stainfo(_adapter *padapter)
{
_irqL irqL;
_list *plist, *phead;
s32 index;
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
struct sta_info* pbcmc_stainfo =rtw_get_bcmc_stainfo( padapter);
_func_enter_;
if(pstapriv->asoc_sta_count==1)
goto exit;
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
for(index=0; index< NUM_STA; index++)
{
phead = &(pstapriv->sta_hash[index]);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
{
psta = LIST_CONTAINOR(plist, struct sta_info ,hash_list);
plist = get_next(plist);
if(pbcmc_stainfo!=psta)
rtw_free_stainfo(padapter , psta);
}
}
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
exit:
_func_exit_;
}
/* any station allocated can be searched by hash list */
struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
{
_irqL irqL;
_list *plist, *phead;
struct sta_info *psta = NULL;
u32 index;
u8 *addr;
u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
_func_enter_;
if(hwaddr==NULL)
return NULL;
if(IS_MCAST(hwaddr))
{
addr = bc_addr;
}
else
{
addr = hwaddr;
}
index = wifi_mac_hash(addr);
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
phead = &(pstapriv->sta_hash[index]);
plist = get_next(phead);
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
{
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
if ((_rtw_memcmp(psta->hwaddr, addr, ETH_ALEN))== _TRUE)
{ // if found the matched address
break;
}
psta=NULL;
plist = get_next(plist);
}
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
_func_exit_;
return psta;
}
u32 rtw_init_bcmc_stainfo(_adapter* padapter)
{
struct sta_info *psta;
struct tx_servq *ptxservq;
u32 res=_SUCCESS;
NDIS_802_11_MAC_ADDRESS bcast_addr= {0xff,0xff,0xff,0xff,0xff,0xff};
struct sta_priv *pstapriv = &padapter->stapriv;
_queue *pstapending = &padapter->xmitpriv.bm_pending;
_func_enter_;
psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
if(psta==NULL){
res=_FAIL;
RT_TRACE(_module_rtl871x_sta_mgt_c_,_drv_err_,("rtw_alloc_stainfo fail"));
goto exit;
}
// default broadcast & multicast use macid 1
psta->mac_id = 1;
ptxservq= &(psta->sta_xmitpriv.be_q);
/*
_enter_critical(&pstapending->lock, &irqL0);
if (rtw_is_list_empty(&ptxservq->tx_pending))
rtw_list_insert_tail(&ptxservq->tx_pending, get_list_head(pstapending));
_exit_critical(&pstapending->lock, &irqL0);
*/
exit:
_func_exit_;
return _SUCCESS;
}
struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter)
{
struct sta_info *psta;
struct sta_priv *pstapriv = &padapter->stapriv;
u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
_func_enter_;
psta = rtw_get_stainfo(pstapriv, bc_addr);
_func_exit_;
return psta;
}
u8 rtw_access_ctrl(struct wlan_acl_pool* pacl_list, u8 * mac_addr)
{
return _TRUE;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More