From 6fc5676f7cf2cae3785989a11f4197c271c874e0 Mon Sep 17 00:00:00 2001 From: hxy Date: Mon, 10 Sep 2012 10:39:27 +0800 Subject: [PATCH] rk3066b: update m701 lcd/tp/gsensor --- arch/arm/configs/rk3066b_m701_defconfig | 39 +- arch/arm/mach-rk30/board-rk3066b-m701.c | 80 +- .../mach-rk30/board-rk3066b-sdk-tps65910.c | 31 +- arch/arm/mach-rk30/include/mach/board.h | 30 +- arch/arm/plat-rk/include/plat/board.h | 9 - drivers/input/gsensor/mma7660.c | 2 +- drivers/input/touchscreen/ft5306_ts.c | 1862 +++++++++-------- drivers/mfd/rk610-core.c | 1 + drivers/mfd/tps65910.c | 4 + drivers/video/display/screen/Kconfig | 3 + drivers/video/display/screen/Makefile | 1 + drivers/video/display/screen/lcd_hsd07pfw1.c | 285 ++- drivers/video/display/transmitter/rk610_lcd.c | 3 + include/linux/mfd/rk610_core.h | 2 +- 14 files changed, 1360 insertions(+), 992 deletions(-) diff --git a/arch/arm/configs/rk3066b_m701_defconfig b/arch/arm/configs/rk3066b_m701_defconfig index 439d6e724e13..4efbcf96bc80 100644 --- a/arch/arm/configs/rk3066b_m701_defconfig +++ b/arch/arm/configs/rk3066b_m701_defconfig @@ -20,7 +20,10 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_ARCH_RK30=y +CONFIG_DDR_SDRAM_FREQ=300 # CONFIG_DDR_TEST is not set +CONFIG_RK_CLOCK_PROC=y +# CONFIG_RK_CONSOLE_THREAD is not set CONFIG_ARCH_RK3066B=y CONFIG_MACH_RK3066B_M701=y CONFIG_FIQ_DEBUGGER=y @@ -41,13 +44,6 @@ CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="console=ttyFIQ0 androidboot.console=ttyFIQ0 init=/init" -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPU_IDLE=y CONFIG_VFP=y CONFIG_NEON=y @@ -178,6 +174,8 @@ CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM4325=y CONFIG_BT_AUTOSLEEP=y +CONFIG_CFG80211=y +CONFIG_MAC80211=y CONFIG_RFKILL=y CONFIG_RFKILL_RK=y CONFIG_DEVTMPFS=y @@ -204,8 +202,6 @@ CONFIG_NETDEVICES=y CONFIG_PHYLIB=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set -CONFIG_WLAN_80211=y -CONFIG_RKWIFI=y CONFIG_USB_USBNET=y CONFIG_PPP=y CONFIG_PPP_MULTILINK=y @@ -238,22 +234,9 @@ CONFIG_TOUCHSCREEN_FT5306=y CONFIG_INPUT_MISC=y CONFIG_INPUT_KEYCHORD=y CONFIG_INPUT_UINPUT=y -CONFIG_COMPASS_AK8975=y -CONFIG_GS_MMA8452=y -CONFIG_GS_LIS3DH=y -CONFIG_GYRO_L3G4200D=y -CONFIG_LS_CM3217=y +CONFIG_GS_MMA7660=y CONFIG_SENSOR_DEVICE=y CONFIG_GSENSOR_DEVICE=y -CONFIG_GS_KXTIK=y -CONFIG_COMPASS_DEVICE=y -CONFIG_GYROSCOPE_DEVICE=y -CONFIG_LIGHT_DEVICE=y -CONFIG_LS_AL3006=y -CONFIG_LS_STK3171=y -CONFIG_PROXIMITY_DEVICE=y -CONFIG_PS_AL3006=y -CONFIG_PS_STK3171=y # CONFIG_SERIO is not set # CONFIG_CONSOLE_TRANSLATIONS is not set # CONFIG_LEGACY_PTYS is not set @@ -270,7 +253,6 @@ CONFIG_I2C1_CONTROLLER_RK30=y CONFIG_I2C2_CONTROLLER_RK30=y CONFIG_I2C3_CONTROLLER_RK30=y CONFIG_I2C4_CONTROLLER_RK30=y -CONFIG_GPIO_WM831X=y CONFIG_EXPANDED_GPIO_NUM=0 CONFIG_EXPANDED_GPIO_IRQ_NUM=0 CONFIG_SPI_FPGA_GPIO_NUM=0 @@ -279,12 +261,10 @@ CONFIG_POWER_SUPPLY=y CONFIG_TEST_POWER=y # CONFIG_HWMON is not set CONFIG_MFD_TPS65910=y -CONFIG_MFD_WM831X_I2C=y CONFIG_MFD_TPS65090=y CONFIG_MFD_RK610=y CONFIG_REGULATOR=y CONFIG_REGULATOR_TPS65910=y -CONFIG_REGULATOR_WM831X=y CONFIG_RK30_PWM_REGULATOR=y CONFIG_MEDIA_SUPPORT=y CONFIG_VIDEO_DEV=y @@ -301,10 +281,10 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set CONFIG_DISPLAY_SUPPORT=y -CONFIG_LCD_B101EW05=y +CONFIG_LCD_HSD07PFW1=y CONFIG_FB_ROCKCHIP=y -CONFIG_LCDC_RK31=y -CONFIG_LCDC1_RK31=y +CONFIG_LCDC_RK3066B=y +CONFIG_LCDC1_RK3066B=y CONFIG_RGA_RK30=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set @@ -398,7 +378,6 @@ CONFIG_LEDS_GPIO=y CONFIG_SWITCH=y CONFIG_SWITCH_GPIO=y CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_WM831X=y CONFIG_TPS65910_RTC=y CONFIG_STAGING=y CONFIG_ANDROID=y diff --git a/arch/arm/mach-rk30/board-rk3066b-m701.c b/arch/arm/mach-rk30/board-rk3066b-m701.c index e0312288b9c0..9d7c8c1a15ad 100644 --- a/arch/arm/mach-rk30/board-rk3066b-m701.c +++ b/arch/arm/mach-rk30/board-rk3066b-m701.c @@ -132,23 +132,24 @@ struct goodix_platform_data goodix_info = { #define TOUCH_INT_PIN RK30_PIN0_PD4 #define TOUCH_PWR_PIN RK30_PIN2_PB4 -static int ft5x0x_init_platform_hw(void) +static int ft5306_init_platform_hw(void) { rk30_mux_api_set(GPIO2C0_LCDC1DATA16_SMCADDR0_TRACECLK_NAME, GPIO2C_GPIO2C0); + rk30_mux_api_set(GPIO0D4_SPI1RXD_NAME, GPIO0D_GPIO0D4); rk30_mux_api_set(GPIO2B4_LCDC1DATA12_SMCDATA12_TRACEDATA12_NAME, GPIO2B_GPIO2B4); //printk("%s:0x%x,0x%x\n",__func__,rk30_mux_api_get(GPIO2C0_LCDC1DATA16_SMCADDR0_TRACECLK_NAME),rk30_mux_api_get(GPIO2B4_LCDC1DATA12_SMCDATA12_TRACEDATA12_NAME)); - printk("==ft5x0x_init_platform_hw =\n"); + printk("ft5306_init_platform_hw \n"); if(gpio_request(TOUCH_RESET_PIN,NULL) != 0){ gpio_free(TOUCH_RESET_PIN); - printk("ft5606_init_platform_hw gpio_request error\n"); + printk("ft5306_init_platform_hw gpio_request error\n"); return -EIO; } if(gpio_request(TOUCH_INT_PIN,NULL) != 0){ gpio_free(TOUCH_INT_PIN); - printk("ift5606_init_platform_hw gpio_request error\n"); + printk("ift5306_init_platform_hw gpio_request error\n"); return -EIO; } @@ -162,21 +163,21 @@ static int ft5x0x_init_platform_hw(void) return 0; } -void ft5x0x_exit_platform_hw(void) +void ft5306_exit_platform_hw(void) { printk("ft5606_exit_platform_hw\n"); gpio_free(TOUCH_RESET_PIN); gpio_free(TOUCH_INT_PIN); } -int ft5x0x_platform_sleep(void) +int ft5306_platform_sleep(void) { printk("ft5606_platform_sleep\n"); gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); return 0; } -int ft5x0x_platform_wakeup(void) +int ft5306_platform_wakeup(void) { printk("ft5606_platform_wakeup\n"); gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); @@ -184,11 +185,12 @@ int ft5x0x_platform_wakeup(void) return 0; } -static struct ft5606_platform_data ft5x0x_info = { - .init_platform_hw= ft5x0x_init_platform_hw, - .exit_platform_hw= ft5x0x_exit_platform_hw, - .platform_sleep = ft5x0x_platform_sleep, - .platform_wakeup = ft5x0x_platform_wakeup, +struct ft5606_platform_data ft5306_info = { + + .init_platform_hw= ft5306_init_platform_hw, + .exit_platform_hw= ft5306_exit_platform_hw, + .platform_sleep= ft5306_platform_sleep, + .platform_wakeup= ft5306_platform_wakeup, }; #endif @@ -450,26 +452,27 @@ struct platform_device rk30_device_sew868 = { #endif +/*MMA7660 gsensor*/ #if defined (CONFIG_GS_MMA7660) -#define MMA7660_INT_PIN RK30_PIN4_PC0 -static int gs_init_platform_hw(void) +#define MMA7660_INT_PIN RK30_PIN3_PD7 + +static int mma7660_init_platform_hw(void) { - rk30_mux_api_set(GPIO4C0_SMCDATA0_TRACEDATA0_NAME, GPIO4C_GPIO4C0); - if(gpio_request(MMA7660_INT_PIN, NULL) != 0){ + if(gpio_request(MMA7660_INT_PIN, NULL) != 0){ gpio_free(MMA7660_INT_PIN); printk("gsensor gpio_request error\n"); return -EIO; } - //gpio_direction_input(MMA7660_INT_PIN); - gpio_pull_updown(MMA7660_INT_PIN, 1); - return 0; + //gpio_direction_input(MMA7660_INT_PIN); + return 0; } - -static struct gs_platform_data mma7660_info = { - .model= 7660, - .swap_xy = 0, - .init_platform_hw= gs_init_platform_hw, +static struct sensor_platform_data mma7660_info = { + .type = SENSOR_TYPE_ACCEL, + .irq_enable = 1, + .poll_delay_ms = 30, + .init_platform_hw = mma7660_init_platform_hw, + .orientation = {-1, 0, 0, 0, 0, -1, 0, 1, 0}, }; #endif @@ -578,11 +581,14 @@ static struct sensor_platform_data cm3217_info = { #ifdef CONFIG_FB_ROCKCHIP -#define LCD_CS_PIN INVALID_GPIO +#define LCD_CS_PIN RK30_PIN2_PB6 #define LCD_CS_VALUE GPIO_HIGH #define LCD_EN_PIN RK30_PIN0_PB0 -#define LCD_EN_VALUE GPIO_HIGH +#define LCD_EN_VALUE GPIO_LOW + +#define LCD_STB_PIN RK30_PIN2_PB3 +#define LCD_STB_VALUE GPIO_HIGH static int rk_fb_io_init(struct rk29_fb_setting_info *fb_setting) { @@ -617,7 +623,25 @@ static int rk_fb_io_init(struct rk29_fb_setting_info *fb_setting) gpio_direction_output(LCD_EN_PIN, LCD_EN_VALUE); } } + + if(LCD_STB_PIN !=INVALID_GPIO) + { + ret = gpio_request(LCD_STB_PIN, NULL); + if (ret != 0) + { + gpio_free(LCD_STB_PIN); + printk(KERN_ERR "request lcd en pin fail!\n"); + return -1; + } + else + { + gpio_direction_output(LCD_STB_PIN, LCD_STB_VALUE); + } + } + return 0; + + } static int rk_fb_io_disable(void) { @@ -1334,7 +1358,7 @@ int __sramdata g_pmic_type = 0; #include "board-rk3066b-sdk-wm8326.c" #endif #ifdef CONFIG_MFD_TPS65910 -#define TPS65910_HOST_IRQ RK30_PIN6_PA4 +#define TPS65910_HOST_IRQ RK30_PIN0_PB3 #include "board-rk3066b-sdk-tps65910.c" #endif @@ -1448,7 +1472,7 @@ static struct i2c_board_info __initdata i2c2_info[] = { .addr = 0x38, .flags = 0, .irq = RK30_PIN0_PD4, - .platform_data = &ft5x0x_info, + .platform_data = &ft5306_info, }, #endif #if defined (CONFIG_LS_CM3217) diff --git a/arch/arm/mach-rk30/board-rk3066b-sdk-tps65910.c b/arch/arm/mach-rk30/board-rk3066b-sdk-tps65910.c index dbe91bca1c92..228b20581f87 100644 --- a/arch/arm/mach-rk30/board-rk3066b-sdk-tps65910.c +++ b/arch/arm/mach-rk30/board-rk3066b-sdk-tps65910.c @@ -26,7 +26,7 @@ #define GPIO6_PB1_UNEN_MASK 0x02000000 #ifdef CONFIG_MFD_TPS65910 -#define PMU_POWER_SLEEP RK30_PIN6_PB1 +#define PMU_POWER_SLEEP RK30_PIN0_PA1 extern int platform_device_register(struct platform_device *pdev); int tps65910_pre_init(struct tps65910 *tps65910){ @@ -37,7 +37,27 @@ int tps65910_pre_init(struct tps65910 *tps65910){ printk("%s,line=%d\n", __func__,__LINE__); //gpio_request(PMU_POWER_SLEEP, "NULL"); - //gpio_direction_output(PMU_POWER_SLEEP, GPIO_HIGH); + //gpio_direction_output(PMU_POWER_SLEEP, GPIO_LOW); + + // ==================================================== + val = tps65910_reg_read(tps65910, TPS65910_VDIG2); + if (val<0) { + printk(KERN_ERR "Unable to read TPS65910_VDIG2 reg\n"); + return val; + } + + val &= ~(0x3 << 2); + err = tps65910_reg_write(tps65910, TPS65910_VDIG2, val); + if (err) { + printk(KERN_ERR "Unable to read TPS65910 Reg at offset 0x%x= \n", TPS65910_VDIG2); + return err; + } + val = tps65910_reg_read(tps65910, TPS65910_VDIG2); + printk("########### vdd11 voltage %08x\n",val); + + mdelay(10); + + // ======================================================= val = tps65910_reg_read(tps65910, TPS65910_DEVCTRL2); if (val<0) { @@ -273,7 +293,7 @@ int tps65910_post_init(struct tps65910 *tps65910) udelay(100); dcdc = regulator_get(NULL, "vdd_cpu"); //vdd_cpu - regulator_set_voltage(dcdc, 1000000, 1000000); + regulator_set_voltage(dcdc, 1100000, 1100000); regulator_enable(dcdc); printk("%s set vdd1 vdd_cpu=%dmV end\n", __func__, regulator_get_voltage(dcdc)); regulator_put(dcdc); @@ -583,12 +603,14 @@ static struct regulator_init_data tps65910_ldo8 = { void __sramfunc board_pmu_tps65910_suspend(void) { +/* grf_writel(GPIO6_PB1_DIR_OUT, GRF_GPIO6L_DIR_ADDR); grf_writel(GPIO6_PB1_DO_HIGH, GRF_GPIO6L_DO_ADDR); //set gpio6_b1 output low grf_writel(GPIO6_PB1_EN_MASK, GRF_GPIO6L_EN_ADDR); +*/ } void __sramfunc board_pmu_tps65910_resume(void) -{ +{/* grf_writel(GPIO6_PB1_DIR_OUT, GRF_GPIO6L_DIR_ADDR); grf_writel(GPIO6_PB1_DO_LOW, GRF_GPIO6L_DO_ADDR); //set gpio6_b1 output low grf_writel(GPIO6_PB1_EN_MASK, GRF_GPIO6L_EN_ADDR); @@ -597,6 +619,7 @@ void __sramfunc board_pmu_tps65910_resume(void) #else sram_udelay(2000); #endif +*/ } static struct tps65910_board tps65910_data = { diff --git a/arch/arm/mach-rk30/include/mach/board.h b/arch/arm/mach-rk30/include/mach/board.h index 3d4fca2e795f..3baf71f9f6bc 100755 --- a/arch/arm/mach-rk30/include/mach/board.h +++ b/arch/arm/mach-rk30/include/mach/board.h @@ -12,6 +12,23 @@ #include #include +struct hdmi_platform_data { + u32 hdmi_on_pin; + u32 hdmi_on_level; + int (*io_init)(void); + int (*io_deinit)(void); + }; +struct gs_platform_data { + u16 model; + u16 swap_xy; + u16 swap_xyz; + signed char orientation[9]; + int (*get_pendown_state)(void); + int (*init_platform_hw)(void); + int (*gs_platform_sleep)(void); + int (*gs_platform_wakeup)(void); + void (*exit_platform_hw)(void); +}; /* adc battery */ struct rk30_adc_battery_platform_data { int (*io_init)(void); @@ -41,13 +58,12 @@ struct wifi_platform_data { #endif #if defined (CONFIG_TOUCHSCREEN_FT5306) -struct ft5x0x_platform_data{ - u16 model; - int (*get_pendown_state)(void); - int (*init_platform_hw)(void); - int (*ft5x0x_platform_sleep)(void); - int (*ft5x0x_platform_wakeup)(void); - void (*exit_platform_hw)(void); +struct ft5606_platform_data{ + int (*get_pendown_state)(void); + int (*init_platform_hw)(void); + int (*platform_sleep)(void); + int (*platform_wakeup)(void); + void (*exit_platform_hw)(void); }; #endif diff --git a/arch/arm/plat-rk/include/plat/board.h b/arch/arm/plat-rk/include/plat/board.h index 4d98dfd23e33..b3b86801de20 100755 --- a/arch/arm/plat-rk/include/plat/board.h +++ b/arch/arm/plat-rk/include/plat/board.h @@ -110,15 +110,6 @@ struct gsensor_platform_data { int (*gsensor_platform_wakeup)(void); void (*exit_platform_hw)(void); }; - -struct ft5606_platform_data { - int (*get_pendown_state)(void); - int (*init_platform_hw)(void); - int (*platform_sleep)(void); - int (*platform_wakeup)(void); - void (*exit_platform_hw)(void); -}; - struct akm8975_platform_data { short m_layout[4][3][3]; char project_name[64]; diff --git a/drivers/input/gsensor/mma7660.c b/drivers/input/gsensor/mma7660.c index bf6c734802bd..b7e5eac7001e 100644 --- a/drivers/input/gsensor/mma7660.c +++ b/drivers/input/gsensor/mma7660.c @@ -567,7 +567,7 @@ static int mma7660_probe(struct i2c_client *client, const struct i2c_device_id /* z-axis acceleration */ input_set_abs_params(mma7660->input_dev, ABS_Z, -MMA7660_RANGE, MMA7660_RANGE, 0, 0); - mma7660->input_dev->name = "compass"; + mma7660->input_dev->name = "gsensor"; mma7660->input_dev->dev.parent = &client->dev; err = input_register_device(mma7660->input_dev); diff --git a/drivers/input/touchscreen/ft5306_ts.c b/drivers/input/touchscreen/ft5306_ts.c index 974d071ba0a2..ca62e13329dd 100755 --- a/drivers/input/touchscreen/ft5306_ts.c +++ b/drivers/input/touchscreen/ft5306_ts.c @@ -1,899 +1,963 @@ -/* - * drivers/input/touchscreen/ft5x0x_ts.c - * - * FocalTech ft5x0x TouchScreen driver. - * - * Copyright (c) 2010 Focal tech Ltd. - * - * 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. - * - * - * note: only support mulititouch Wenfs 2010-10-01 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifdef CONFIG_HAS_EARLYSUSPEND -#include -#endif - - -#define CONFIG_FT5X0X_MULTITOUCH 1 -#define CONFIG_TOUCH_PANEL_KEY 1 -#define NEW_PAL_DRV -#define CHECK_KEY -#define LONGPRESS_LOCK_SPECKEY //是否使用长按某键(如search键)锁住功能键的功能 -#ifdef LONGPRESS_LOCK_SPECKEY -#define KEY_LOCK 195 -#define ORIGIN_KEY KEY_SEARCH -#define LOCK_LONG_PRESS_CNT 100 -static int Origin2LockPressCnt = 0; -static int lockflag =0; -static int touch_key_hold_press = 0; - -ssize_t glock_status_show(struct device *dev, char *buf) -{ - printk("lockflag === %d\n",lockflag); - return sprintf(buf, "%d", lockflag); -} -#endif - - -static int err_ft5X06 = 0; //w++记载有没有此设备 -static int debug1=1; -module_param(debug1, int, S_IRUGO|S_IWUSR); - -static int gpress = 0; -extern void gpio_enable1(); -static int Motoenble = 0; -module_param(Motoenble, int, S_IRUGO|S_IWUSR); -static int MotoStart = 0; - -/* - * Added by yick @RockChip - * Compatible with both types of firmware - * default: point - only pressdown finger num - * event - both down and up event - */ -#define USE_POINT 1 -#if USE_POINT -uint16_t down_table = 0; -uint16_t up_table = ~0; -#endif - -#define SCREEN_MAX_X 480 -#define SCREEN_MAX_Y 800 -#define PRESS_MAX 255 - -#define FT5X0X_NAME "ft5x0x_ts" -#define MAX_CONTACTS 5 -enum ft5x0x_ts_regs { - FT5X0X_REG_PMODE = 0xA5, /* Power Consume Mode */ -}; - -#define KEY_MIN_X 800 -#define KEY_NUM 4 - -int touch_key_press[] = {0, 0, 0, 0}; -//int touch_key_code[] = { KEY_BACK,KEY_HOME, KEY_MENU}; -//int touch_key_min[KEY_NUM] ={-1,59,105}; -//int touch_key_max[KEY_NUM] ={2,73,121}; - -int touch_key_code[] = {KEY_MENU, KEY_HOMEPAGE, KEY_BACK, KEY_SEARCH}; -int touch_key_min[KEY_NUM] ={30,150,270,390}; -int touch_key_max[KEY_NUM] ={90,210,330,450}; - -//FT5X0X_REG_PMODE -#define PMODE_ACTIVE 0x00 -#define PMODE_MONITOR 0x01 -#define PMODE_STANDBY 0x02 -#define PMODE_HIBERNATE 0x03 - -#ifndef ABS_MT_TOUCH_MAJOR -#define ABS_MT_TOUCH_MAJOR 0x30 /* touching ellipse */ -#define ABS_MT_TOUCH_MINOR 0x31 /* (omit if circular) */ -#define ABS_MT_WIDTH_MAJOR 0x32 /* approaching ellipse */ -#define ABS_MT_WIDTH_MINOR 0x33 /* (omit if circular) */ -#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */ -#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */ -#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */ -#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */ -#define ABS_MT_BLOB_ID 0x38 /* Group set of pkts as blob */ -#endif /* ABS_MT_TOUCH_MAJOR */ - -struct point_data { - u8 status; - u8 id; - u16 x; - u16 y; -}; - -struct ts_event { - u16 touch_point; - struct point_data point[5]; -}; - -struct ft5x0x_ts_dev { - struct i2c_client *client; - struct input_dev *input_dev; - int irq; - struct ts_event event; - struct work_struct pen_event_work; - struct workqueue_struct *ts_workqueue; - struct early_suspend early_suspend; - -#ifdef CHECK_KEY - struct timer_list timer; -#endif -}; - -static struct ft5x0x_ts_dev *g_dev; -static bool rember_point_into = true; - - -static ssize_t Moto_status(struct device_driver *_drv,char *_buf) -{ - //printk("Moto_status Motoenble==%d\n", Motoenble); - if(Motoenble) - return sprintf(_buf, "Ledlevel is Low\n"); - else - return sprintf(_buf, "Ledlevel is High\n"); -} -static ssize_t Moto_control(struct device_driver *_drv, const char *_buf, size_t _count) -{ - char temp[5]; - //printk("Read data from Android: %s\n", _buf); - strncpy(temp, _buf, 1); - Motoenble = simple_strtol(temp, NULL, 10); - //printk("Moto_control Motoenble=%d\n", Motoenble); -} - - -static int ft5x0x_i2c_rxdata(char *rxdata, int length) -{ - int ret; - - struct i2c_msg msgs[] = { - { - .addr = g_dev->client->addr, - .flags = 0, - .len = 1, - .buf = rxdata, - .scl_rate = 200 * 1000, - }, - { - .addr = g_dev->client->addr, - .flags = I2C_M_RD, - .len = length, - .buf = rxdata, - .scl_rate = 200 * 1000, - }, - }; - - ret = i2c_transfer(g_dev->client->adapter, msgs, 2); - if (ret < 0) - pr_err("msg %s i2c read error: %d\n", __func__, ret); - - return ret; -} - -static int ft5x0x_i2c_txdata(char *txdata, int length) -{ - int ret; - - struct i2c_msg msg[] = { - { - .addr = g_dev->client->addr, - .flags = 0, - .len = length, - .buf = txdata, - .scl_rate = 200 * 1000, - }, - }; - - ret = i2c_transfer(g_dev->client->adapter, msg, 1); - if (ret < 0) - pr_err("%s i2c write error: %d\n", __func__, ret); - - return ret; -} - -static int ft5x0x_set_reg(u8 addr, u8 para) -{ - u8 buf[3]; - int ret = -1; - - buf[0] = addr; - buf[1] = para; - ret = ft5x0x_i2c_txdata(buf, 2); - if (ret < 0) { - pr_err("write reg failed! %#x ret: %d", buf[0], ret); - return -1; - } - - return 0; -} - -static int ft5x0x_read_data(void) -{ - struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client); - struct ts_event *event = &data->event; - - u8 buf[32]= {0};//set send addr to 0x00 *important* - int ret = -1; - int key; - - - if(Motoenble) - { - if(!MotoStart) - { - //printk("the moto is enable!\n"); - //gpio_enable1(); - MotoStart =1; - } - } - - - ret = ft5x0x_i2c_rxdata(buf, 32); - - if (ret < 0) { - printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret); - return ret; - } -#if 0 // Just for debug - u8 uc_ecc; - int i; - uc_ecc = buf[2]; - for (i=0; i<5; i++) - { - uc_ecc ^= buf[3+6*i]; - uc_ecc ^= buf[4+6*i]; - uc_ecc ^= buf[5+6*i]; - uc_ecc ^= buf[6+6*i]; - } -// if (uc_ecc == buf[1]) break; -// } - - - if (uc_ecc != buf[1]) - { - printk("ecc check error uc_ecc=0x%x, buf[1]=0x%x.\n",uc_ecc, buf[1]); - return 1; - } -#endif - - - memset(event, ~0x00, sizeof(struct ts_event)); - -#if USE_POINT - event->touch_point = buf[2] & 0x07;// 0000 1111 -#else - event->touch_point = buf[2] >>4;// 0000 1111 -#endif - if (event->touch_point == 0) { - rember_point_into = false; -#ifdef LONGPRESS_LOCK_SPECKEY - if(Origin2LockPressCnt) - {//说明按到了search键 - if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT) - {//没有长按 - if(lockflag ==0) - {//键盘没锁 - input_report_key(data->input_dev,KEY_SEARCH,1); //158 //MENU - input_sync(data->input_dev); - input_report_key(data->input_dev,KEY_SEARCH,0); //158 //MENU - input_sync(data->input_dev); - //printk("menu is up ==========================\n"); - } - } - else - { - //printk("release long press !!!!!!!!!!!!!!!!!\n"); - input_report_key(data->input_dev, KEY_LOCK, 0); - //printk("up::KEY_LOCK: %d\n", KEY_LOCK); - input_sync(data->input_dev); - } - Origin2LockPressCnt = 0; - touch_key_hold_press = 0; - } -#endif -#ifdef NEW_PAL_DRV - if(touch_key_hold_press) - { - touch_key_hold_press = 0; - for(key=0; keyinput_dev, touch_key_code[key], 0); - touch_key_press[key] = 0; - input_sync(data->input_dev); - //printk("up::KEY: %d\n", touch_key_code[key]); - } - } - } -#endif - gpress = 0; - MotoStart =0; - //printk("release point !!!!!!!!!!!!!!!!!\n"); - //ft5x0x_ts_release(data); - #ifdef CHECK_KEY - //event->penddown = Release; - #endif - return 0; - } - -#ifdef CONFIG_FT5X0X_MULTITOUCH - switch (event->touch_point) { - case 5: - event->point[4].status = (buf[0x1b] & 0xc0)>>6; - event->point[4].id = (buf[0x1d] & 0xf0)>>4; - event->point[4].x = (s16)(buf[0x1b] & 0x07)<<8 | (s16)buf[0x1c]; - event->point[4].y = (s16)(buf[0x1d] & 0x07)<<8 | (s16)buf[0x1e]; - case 4: - event->point[3].status = (buf[0x15] & 0xc0)>>6; - event->point[3].id = (buf[0x17] & 0xf0)>>4; - event->point[3].x = (s16)(buf[0x15] & 0x07)<<8 | (s16)buf[0x16]; - event->point[3].y = (s16)(buf[0x17] & 0x07)<<8 | (s16)buf[0x18]; - case 3: - event->point[2].status = (buf[0x0f] & 0xc0)>>6; - event->point[2].id = (buf[0x11] & 0xf0)>>4; - event->point[2].x = (s16)(buf[0x0f] & 0x07)<<8 | (s16)buf[0x10]; - event->point[2].y = (s16)(buf[0x11] & 0x07)<<8 | (s16)buf[0x12]; - case 2: - event->point[1].status = (buf[0x09] & 0xc0)>>6; - event->point[1].id = (buf[0x0b] & 0xf0)>>4; - event->point[1].x = (s16)(buf[0x09] & 0x07)<<8 | (s16)buf[0x0a]; - event->point[1].y = (s16)(buf[0x0b] & 0x07)<<8 | (s16)buf[0x0c]; - case 1: - event->point[0].status = (buf[0x03] & 0xc0)>>6; - event->point[0].id = (buf[0x05] & 0xf0)>>4; - - event->point[0].y = (s16)(buf[0x03] & 0x0f)<<8 | (s16)buf[0x04]; - event->point[0].x = (s16)(buf[0x05] & 0x0f)<<8 | (s16)buf[0x06]; - event->point[0].x = 480 - event->point[0].x; - if(event->point[0].x < 0){ - event->point[0].x = 0; - } - - default: - return 0; - } -#endif -} - -static void ft5x0x_report_value(void) -{ - struct ft5x0x_ts_dev *data = i2c_get_clientdata(g_dev->client); - struct ts_event *event = &data->event; - u8 j; - u8 i = 0; - int key_id = 0xff; -#if 0 - printk("point is %d x0 is %d y0 is %d\n", - //P1 status is %x ID1 is %x x1 is 0x%x y1 is 0x%x\n\n", - event->touch_point, - //event->point[0].status, //event->point[0].id, - event->point[0].y, event->point[0].x); - //event->point[1].status, event->point[1].id, - //event->point[1].x, event->point[1].y); -#endif -#if USE_POINT - down_table = 0; - - for(i=0; itouch_point; i++) { - //================ - //printk("event->x[%d]:%d,event->y[%d]:%d\n", i,event->x[i],i,event->y[i]); - if((event->point[i].y > KEY_MIN_X) && (debug1)/*&&(posx[i]point[i].x==%d,event->point[i].y===%d\n",i,event->point[i].x,event->point[i].y); - if((event->point[i].x >touch_key_min[j])&&(event->point[i].x LOCK_LONG_PRESS_CNT) - { - Origin2LockPressCnt = LOCK_LONG_PRESS_CNT + 2; - input_report_key(data->input_dev, KEY_LOCK, 1); - touch_key_hold_press = 1; - if(lockflag) - lockflag =0; - else - lockflag =1; - }*/ - Origin2LockPressCnt=1; - break; - } - //if(lockflag) - //goto out; - #endif - input_report_key(data->input_dev, touch_key_code[key_id], 1); - touch_key_press[key_id] = 1; - touch_key_hold_press = 1; - // printk("down::KEY: %d\n", touch_key_code[key_id]); - } - break; - } - } - } - else - { - input_mt_slot(data->input_dev, event->point[i].id); - - input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id); - - down_table |= 1 << event->point[i].id; - input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 100); - input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x); - input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y); - input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100); - // printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i].id,event->point[i].x,event->point[i].y); - - } - - - } - - for(i=0; iinput_dev, i); - input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1); - /*printk("ABS_MT_TRACKING_ID == %d, ABS_MT_POSITION_X == %d, ABS_MT_POSITION_Y == %d\n",event->point[i] -.id,event->point[i].y,event->point[i].x);*/ - } - } - up_table = ~down_table; - input_sync(data->input_dev); -#else - - for(i=0; itouch_point; i++) { - if(event->point[i].status == 0 || event->point[i].status == 2 ) { - input_mt_slot(data->input_dev, event->point[i].id); - input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->point[i].id); - input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 200); - input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->point[i].x); - input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->point[i].y); - input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 100); - } - else if(event->point[i].status == 1) { - input_mt_slot(data->input_dev, event->point[i].id); - input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1); - } - } - input_sync(data->input_dev); -#endif - - - - - out: - ; -#ifdef CHECK_KEY - data->timer.expires = jiffies +8; - add_timer(&data->timer); - down_table = 0; - -#endif - - - - -} /*end ft5x0x_report_value*/ - -static void ft5x0x_ts_pen_irq_work(struct work_struct *work) -{ - int ret = -1; - //printk("==ft5x0x_ts_pen_work =\n"); - ret = ft5x0x_read_data(); - if (ret == 0) { - ft5x0x_report_value(); - } - enable_irq(g_dev->irq); -} - -static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) -{ - struct ft5x0x_ts_dev *ft5x0x_ts = dev_id; - -#ifdef CHECK_KEY - - del_timer(&ft5x0x_ts->timer); -#endif - disable_irq_nosync(g_dev->irq); - //printk("==ft5x0x_ts_interrupt =\n"); - queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); - - return IRQ_HANDLED; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -static void ft5x0x_ts_suspend(struct early_suspend *handler) -{ - int ret; - struct ft5x0x_ts_dev *ts; - ts = container_of(handler, struct ft5x0x_ts_dev, early_suspend); - - if(ts->irq) - disable_irq_nosync(ts->irq); - - ret = cancel_work_sync(&ts->pen_event_work); - if (ret && ts->irq) /* if work was pending disable-count is now 2 */ - enable_irq(ts->irq); - // ==set mode ==, -// ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE); -} - -static void ft5x0x_ts_resume(struct early_suspend *handler) -{ - struct ft5x0x_ts_dev *ts; - ts = container_of(handler, struct ft5x0x_ts_dev, early_suspend); - // wake the mode -// gpio_direction_output(RK29_PIN6_PC3, 0); -// gpio_set_value(RK29_PIN6_PC3,GPIO_LOW); -// msleep(50); -// gpio_set_value(RK29_PIN6_PC3,GPIO_HIGH); - -#if USE_POINT - down_table = 0; - up_table = ~0; -#endif - - if(ts->irq) - enable_irq(ts->irq); -} -#endif //CONFIG_HAS_EARLYSUSPEND -#ifdef CHECK_KEY -static void Touch_timer_release(unsigned long ft_ts_pdev) -{ - - struct ft5x0x_ts_dev *data = ft_ts_pdev; - int key, i=0; - int inflag =0; - /*if(rember_point_into) - { - for(i=0;iinput_dev, i); - input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1); -#endif - } - - input_sync(data->input_dev); - rember_point_into = true; - }*/ - - for(i=0; iinput_dev, i); - input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, -1); - inflag =1; - } - } - if(inflag==1)input_sync(data->input_dev); - inflag = 0; -//=================================== -#ifdef LONGPRESS_LOCK_SPECKEY - - if(Origin2LockPressCnt) - {//说明按到了search键 - if(Origin2LockPressCnt < LOCK_LONG_PRESS_CNT) - {//没有长按 - //if(lockflag ==0) - {//键盘没锁 - input_report_key(data->input_dev,KEY_SEARCH,1); //158 //MENU - input_sync(data->input_dev); - input_report_key(data->input_dev,KEY_SEARCH,0); //158 //MENU - input_sync(data->input_dev); - //printk("menu is up ==========================\n"); - } - } - else - { - //printk("release long press !!!!!!!!!!!!!!!!!\n"); - //input_report_key(data->input_dev, KEY_LOCK, 0); - //printk("up::KEY_LOCK: %d\n", KEY_LOCK); - //input_sync(data->input_dev); - } - Origin2LockPressCnt = 0; - touch_key_hold_press = 0; - } -#endif -#ifdef NEW_PAL_DRV - if((touch_key_hold_press)&&(debug1)) - { - touch_key_hold_press = 0; - for(key=0; keyinput_dev, touch_key_code[key], 0); - touch_key_press[key] = 0; - input_sync(data->input_dev); - //printk("up::KEY: %d\n", touch_key_code[key]); - } - } - } -#endif - -//=================================== - - - -} - -#endif - -static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) -{ - struct ft5x0x_ts_dev *ft5x0x_ts; - struct ft5x0x_platform_data *pdata = pdata = client->dev.platform_data; - struct input_dev *input_dev; - int err = 0; - u8 buf_w[1]; - u8 buf_r[1]; - u8 buf[3]={0}; //w++ - - - if (pdata == NULL) { - dev_err(&client->dev, "%s: platform data is null\n", __func__); - goto exit_platform_data_null; - } - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - err = -ENODEV; - goto exit_check_functionality_failed; - } - - if (pdata->init_platform_hw) - pdata->init_platform_hw(); - - - err_ft5X06=i2c_master_reg8_recv(client, 0x02, buf, 2, 200*1000); //w++6 - //err_ft5X06 = i2c_master_reg8_recv(client, 0x00, buf, 2, 200 * 1000); //w++5 - - //buf[0] = 0x00; - //err_ft5X06 = ft5x0x_i2c_rxdata(buf,1); - if(err_ft5X06<0){ - printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,err); - return err; - } - - - ft5x0x_ts = (struct ft5x0x_ts_dev *)kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL); - if (!ft5x0x_ts) { - err = -ENOMEM; - goto exit_alloc_data_failed; - } - - input_dev = input_allocate_device(); - if (!input_dev) { - err = -ENOMEM; - dev_err(&client->dev, "failed to allocate input device\n"); - goto exit_input_dev_alloc_failed; - } - - ft5x0x_ts->input_dev = input_dev; - ft5x0x_ts->client = client; - ft5x0x_ts->irq = client->irq; - - __set_bit(EV_ABS, input_dev->evbit); - __set_bit(EV_KEY, input_dev->evbit); - __set_bit(EV_REP, input_dev->evbit); - __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); - set_bit(ABS_MT_POSITION_X, input_dev->absbit); - set_bit(ABS_MT_POSITION_Y, input_dev->absbit); - set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit); - set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit); - - input_mt_init_slots(input_dev, MAX_CONTACTS); - - input_set_abs_params(input_dev,ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0); - input_set_abs_params(input_dev,ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); - input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0); - input_set_abs_params(input_dev,ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0); -#if CONFIG_TOUCH_PANEL_KEY - set_bit(KEY_HOMEPAGE, input_dev->keybit); - set_bit(KEY_MENU, input_dev->keybit); - set_bit(KEY_BACK, input_dev->keybit); - set_bit(KEY_SEARCH, input_dev->keybit); -#ifdef LONGPRESS_LOCK_SPECKEY - // set_bit(KEY_SEARCH, input_dev->keybit); - set_bit(KEY_LOCK, input_dev->keybit); -#endif -#endif - - input_dev->name = FT5X0X_NAME; //dev_name(&client->dev) - err = input_register_device(input_dev); - if (err) { - dev_err(&client->dev, - "ft5x0x_ts_probe: failed to register input device: %s\n", - dev_name(&client->dev)); - goto exit_input_register_device_failed; - } - - g_dev = ft5x0x_ts; - - i2c_set_clientdata(client, ft5x0x_ts); - INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work); - ft5x0x_ts->ts_workqueue = create_workqueue(FT5X0X_NAME); - if (!ft5x0x_ts->ts_workqueue) { - err = -ESRCH; - goto exit_create_singlethread; - } - - //if(pdata->init_platform_hw) - // pdata->init_platform_hw(); - - //ft5x0x_set_reg(0x80,0x64); - - if(!ft5x0x_ts->irq) - { - dev_dbg(&ft5x0x_ts->client->dev, "no IRQ?\n"); - return -ENODEV; - } - else - { - ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq); - } - - err = request_irq(ft5x0x_ts->irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING/*IRQF_DISABLED*/, "ft5x0x_ts", ft5x0x_ts); - if (err < 0) { - dev_err(&client->dev, "ft5x0x_probe: request irq failed\n"); - goto exit_irq_request_failed; - } - - disable_irq_nosync(g_dev->irq); - -#ifdef CONFIG_HAS_EARLYSUSPEND - ft5x0x_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; - ft5x0x_ts->early_suspend.suspend = ft5x0x_ts_suspend; - ft5x0x_ts->early_suspend.resume = ft5x0x_ts_resume; - register_early_suspend(&ft5x0x_ts->early_suspend); -#endif -#ifdef CHECK_KEY - setup_timer(&ft5x0x_ts->timer, Touch_timer_release, (unsigned long)ft5x0x_ts); -#endif - -//wake the CTPM -// __gpio_as_output(GPIO_FT5X0X_WAKE); -// __gpio_clear_pin(GPIO_FT5X0X_WAKE); //set wake = 0,base on system -// msleep(100); -// __gpio_set_pin(GPIO_FT5X0X_WAKE); //set wake = 1,base on system -// msleep(100); -// ft5x0x_set_reg(0x88, 0x05); //5, 6,7,8 -// ft5x0x_set_reg(0x80, 30); -// msleep(50); - - buf_w[0] = 6; - err = ft5x0x_set_reg(0x88,6); - //ft5x0x_i2c_txdata(0x88, buf_w, 1); /* adjust frequency 60Hz */ - - buf_r[0] = 0x88; - err = ft5x0x_i2c_rxdata(buf_r,1); - - enable_irq(g_dev->irq); - -printk("==ft5x0x_ts_probe = %0x\n", buf_r[0]); - - return 0; - -exit_input_register_device_failed: - input_free_device(input_dev); -exit_input_dev_alloc_failed: - free_irq(client->irq, ft5x0x_ts); - //free_irq(IRQ_EINT(6), ft5x0x_ts); -exit_irq_request_failed: -exit_platform_data_null: - cancel_work_sync(&ft5x0x_ts->pen_event_work); - destroy_workqueue(ft5x0x_ts->ts_workqueue); -exit_create_singlethread: - printk("==singlethread error =\n"); - i2c_set_clientdata(client, NULL); - kfree(ft5x0x_ts); -exit_alloc_data_failed: -exit_check_functionality_failed: - return err; -} - -static int __devexit ft5x0x_ts_remove(struct i2c_client *client) -{ - struct ft5x0x_ts_dev *ft5x0x_ts = i2c_get_clientdata(client); - unregister_early_suspend(&ft5x0x_ts->early_suspend); - free_irq(client->irq, ft5x0x_ts); - input_unregister_device(ft5x0x_ts->input_dev); - kfree(ft5x0x_ts); - cancel_work_sync(&ft5x0x_ts->pen_event_work); - destroy_workqueue(ft5x0x_ts->ts_workqueue); - i2c_set_clientdata(client, NULL); - return 0; -} - -static const struct i2c_device_id ft5x0x_ts_id[] = { - { FT5X0X_NAME, 0 },{ } -}; -MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id); - -static struct i2c_driver ft5x0x_ts_driver = { - .probe = ft5x0x_ts_probe, - .remove = __devexit_p(ft5x0x_ts_remove), - .id_table = ft5x0x_ts_id, - .driver = { - .name = FT5X0X_NAME, - .owner = THIS_MODULE, - }, -}; -#ifdef LONGPRESS_LOCK_SPECKEY -static DRIVER_ATTR(get_lock_status, 0777, glock_status_show, NULL); -#endif -static DRIVER_ATTR(MOTOenable, 0666, Moto_status, Moto_control); - -static int __init ft5x0x_ts_init(void) -{ - int ret; -ret = i2c_add_driver(&ft5x0x_ts_driver); - if (ret) - { - printk("Register 5406_ts driver failed.\n"); - return ret; - } -#ifdef LONGPRESS_LOCK_SPECKEY - if(err_ft5X06>=0) //w++ - ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status); -#endif - if(err_ft5X06>=0) // - ret =driver_create_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable); - return ret; -} - -static void __exit ft5x0x_ts_exit(void) -{ - i2c_del_driver(&ft5x0x_ts_driver); -#ifdef LONGPRESS_LOCK_SPECKEY - driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_get_lock_status); -#endif - driver_remove_file(&ft5x0x_ts_driver.driver, &driver_attr_MOTOenable); -} - -module_init(ft5x0x_ts_init); -module_exit(ft5x0x_ts_exit); - -MODULE_AUTHOR(""); -MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver"); -MODULE_LICENSE("GPL"); - +/* + * drivers/input/touchscreen/ft5x0x_ts.c + * + * FocalTech ft5x0x TouchScreen driver. + * + * Copyright (c) 2010 Focal tech Ltd. + * + * 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. + * + * + * note: only support mulititouch Wenfs 2010-10-01 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ANDROID_POWER +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +//#include +//#include /* ddl@rock-chips.com : camera support */ +#include /* ddl@rock-chips.com : camera support */ +//#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include + + +#if 0 +#define FTprintk(x...) printk(x) +#else +#define FTprintk(x...) do{} while(0) +#endif + +#define CONFIG_FT5X0X_MULTITOUCH 1 +#define MAX_POINT 5 +#define FT5306_IIC_SPEED 400*1000 //300*1000 +#define TOUCH_RESET_PIN RK30_PIN1_PC0 +#define FT5X0X_REG_THRES 0x80 /* Thresshold, the threshold be low, the sensitivy will be high */ +#define FT5X0X_REG_REPORT_RATE 0x88 /* **************report rate, in unit of 10Hz **************/ +#define FT5X0X_REG_PMODE 0xA5 /* Power Consume Mode 0 -- active, 1 -- monitor, 3 -- sleep */ +#define FT5X0X_REG_FIRMID 0xA6 /* ***************firmware version **********************/ +#define FT5X0X_REG_NOISE_MODE 0xb2 /* to enable or disable power noise, 1 -- enable, 0 -- disable */ +#define SCREEN_MAX_X 1024 +#define SCREEN_MAX_Y 600 +#define PRESS_MAX 255 +#define FT5X0X_NAME "ft5x0x_ts"//"synaptics_i2c_rmi"//"synaptics-rmi-ts"// +#define TOUCH_MAJOR_MAX 200 +#define WIDTH_MAJOR_MAX 200 +//FT5X0X_REG_PMODE +#define PMODE_ACTIVE 0x00 +#define PMODE_MONITOR 0x01 +#define PMODE_STANDBY 0x02 +#define PMODE_HIBERNATE 0x03 + + +struct ts_event { + u16 x1; + u16 y1; + u16 x2; + u16 y2; + u16 x3; + u16 y3; + u16 x4; + u16 y4; + u16 x5; + u16 y5; + u16 pressure; + s16 touch_ID1; + s16 touch_ID2; + s16 touch_ID3; + s16 touch_ID4; + s16 touch_ID5; + u8 touch_point; + u8 status; +}; + +struct tp_event { + u16 x; + u16 y; + s16 id; + u16 pressure; + u8 touch_point; + u8 flag; +}; + +struct ft5x0x_ts_data { + struct i2c_client *client; + struct input_dev *input_dev; + int irq; + int (*platform_sleep)(void); + int (*platform_wakeup)(void); + struct ts_event event; + struct work_struct pen_event_work; + struct workqueue_struct *ts_workqueue; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend ft5306_early_suspend; +#endif +}; +static struct i2c_client *this_client; + +/***********************************************************************/ + +#define FTS_PACKET_LENGTH 128 + + +static u8 CTPM_FW[]= +{ +#include "7022620120726B.txt" +}; + +typedef enum +{ + ERR_OK, + ERR_MODE, + ERR_READID, + ERR_ERASE, + ERR_STATUS, + ERR_ECC, + ERR_DL_ERASE_FAIL, + ERR_DL_PROGRAM_FAIL, + ERR_DL_VERIFY_FAIL +}E_UPGRADE_ERR_TYPE; + +/***********************************************************************/ + +/*********************************************************************** + [function]: + callback: send data to ctpm by i2c interface; + [parameters]: + txdata[in]: data buffer which is used to send data; + length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static int fts_i2c_txdata(u8 *txdata, int length) +{ + int ret; + + struct i2c_msg msg; + + msg.addr = this_client->addr; + msg.flags = 0; + msg.len = length; + msg.buf = txdata; + msg.scl_rate = FT5306_IIC_SPEED; + ret = i2c_transfer(this_client->adapter, &msg, 1); + if (ret < 0) + pr_err("%s i2c write error: %d\n", __func__, ret); + + return ret; +} + +/*********************************************************************** + [function]: + callback: write data to ctpm by i2c interface; + [parameters]: + buffer[in]: data buffer; + length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool i2c_write_interface(u8* pbt_buf, int dw_lenth) +{ + int ret; + ret=i2c_master_send(this_client, pbt_buf, dw_lenth); + if(ret<=0) + { + FTprintk("[TSP]i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret); + return false; + } + + return true; +} + +/*********************************************************************** + [function]: + callback: read register value ftom ctpm by i2c interface; + [parameters]: + reg_name[in]: the register which you want to write; + tx_buf[in]: buffer which is contained of the writing value; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool fts_register_write(u8 reg_name, u8* tx_buf) +{ + u8 write_cmd[2] = {0}; + + write_cmd[0] = reg_name; + write_cmd[1] = *tx_buf; + + /*call the write callback function*/ + return i2c_write_interface(write_cmd, 2); +} + +/*********************************************************************** +[function]: + callback: send a command to ctpm. +[parameters]: + btcmd[in]: command code; + btPara1[in]: parameter 1; + btPara2[in]: parameter 2; + btPara3[in]: parameter 3; + num[in]: the valid input parameter numbers, + if only command code needed and no + parameters followed,then the num is 1; +[return]: + FTS_TRUE: success; + FTS_FALSE: io fail; +************************************************************************/ +static bool cmd_write(u8 btcmd,u8 btPara1,u8 btPara2,u8 btPara3,u8 num) +{ + u8 write_cmd[4] = {0}; + + write_cmd[0] = btcmd; + write_cmd[1] = btPara1; + write_cmd[2] = btPara2; + write_cmd[3] = btPara3; + return i2c_write_interface(write_cmd, num); +} + +/*********************************************************************** + [function]: + callback: read data from ctpm by i2c interface; + [parameters]: + buffer[in]: data buffer; + length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool i2c_read_interface(u8* pbt_buf, int dw_lenth) +{ + int ret; + + ret=i2c_master_recv(this_client, pbt_buf, dw_lenth); + + if(ret<=0) + { + FTprintk("[TSP]i2c_read_interface error\n"); + return false; + } + + return true; +} + + +/*********************************************************************** +[function]: + callback: read a byte data from ctpm; +[parameters]: + buffer[in]: read buffer; + length[in]: the size of read data; +[return]: + FTS_TRUE: success; + FTS_FALSE: io fail; +************************************************************************/ +static bool byte_read(u8* buffer, int length) +{ + return i2c_read_interface(buffer, length); +} + +/*********************************************************************** +[function]: + callback: write a byte data to ctpm; +[parameters]: + buffer[in]: write buffer; + length[in]: the size of write data; +[return]: + FTS_TRUE: success; + FTS_FALSE: io fail; +************************************************************************/ +static bool byte_write(u8* buffer, int length) +{ + + return i2c_write_interface(buffer, length); +} + +/*********************************************************************** + [function]: + callback: read register value ftom ctpm by i2c interface; + [parameters]: + reg_name[in]: the register which you want to read; + rx_buf[in]: data buffer which is used to store register value; + rx_length[in]: the length of the data buffer; + [return]: + FTS_TRUE: success; + FTS_FALSE: fail; +************************************************************************/ +static bool fts_register_read(u8 reg_name, u8* rx_buf, int rx_length) +{ + u8 read_cmd[2]= {0}; + u8 cmd_len = 0; + + read_cmd[0] = reg_name; + cmd_len = 1; + + /*send register addr*/ + if(!i2c_write_interface(&read_cmd[0], cmd_len)) + { + return false; + } + + /*call the read callback function to get the register value*/ + if(!i2c_read_interface(rx_buf, rx_length)) + { + return false; + } + return true; +} + + + +/*********************************************************************** +[function]: + callback: burn the FW to ctpm. +[parameters]: + pbt_buf[in]: point to Head+FW ; + dw_lenth[in]: the length of the FW + 6(the Head length); +[return]: + ERR_OK: no error; + ERR_MODE: fail to switch to UPDATE mode; + ERR_READID: read id fail; + ERR_ERASE: erase chip fail; + ERR_STATUS: status error; + ERR_ECC: ecc error. +************************************************************************/ +E_UPGRADE_ERR_TYPE fts_ctpm_fw_upgrade(u8* pbt_buf, int dw_lenth) +{ + u8 cmd,reg_val[2] = {0}; + u8 buffer[2] = {0}; + u8 packet_buf[FTS_PACKET_LENGTH + 6]; + u8 auc_i2c_write_buf[10]; + u8 bt_ecc; + + int j,temp,lenght,i_ret,packet_number, i = 0; + int i_is_new_protocol = 0; + + + /******write 0xaa to register 0xfc******/ + cmd=0xaa; + fts_register_write(0xfc,&cmd); + mdelay(50); + + /******write 0x55 to register 0xfc******/ + cmd=0x55; + fts_register_write(0xfc,&cmd); + FTprintk("[TSP] Step 1: Reset CTPM test\n"); + + mdelay(10); + + + /*******Step 2:Enter upgrade mode ****/ + FTprintk("\n[TSP] Step 2:enter new update mode\n"); + auc_i2c_write_buf[0] = 0x55; + auc_i2c_write_buf[1] = 0xaa; + do + { + i ++; + i_ret = fts_i2c_txdata(auc_i2c_write_buf, 2); + mdelay(5); + }while(i_ret <= 0 && i < 10 ); + + if (i > 1) + { + i_is_new_protocol = 1; + } + + /********Step 3:check READ-ID********/ + cmd_write(0x90,0x00,0x00,0x00,4); + byte_read(reg_val,2); + if (reg_val[0] == 0x79 && reg_val[1] == 0x3) + { + FTprintk("[TSP] Step 3: CTPM ID,ID1 = 0x%x,ID2 = 0x%x\n",reg_val[0],reg_val[1]); + } + else + { + return ERR_READID; + //i_is_new_protocol = 1; + } + + + /*********Step 4:erase app**********/ + if (i_is_new_protocol) + { + cmd_write(0x61,0x00,0x00,0x00,1); + } + else + { + cmd_write(0x60,0x00,0x00,0x00,1); + } + mdelay(1500); + FTprintk("[TSP] Step 4: erase. \n"); + + + + /*Step 5:write firmware(FW) to ctpm flash*/ + bt_ecc = 0; + FTprintk("[TSP] Step 5: start upgrade. \n"); + dw_lenth = dw_lenth - 8; + packet_number = (dw_lenth) / FTS_PACKET_LENGTH; + packet_buf[0] = 0xbf; + packet_buf[1] = 0x00; + FTprintk("[TSP] packet_number = %d\n",packet_number); + for (j=0;j>8); + packet_buf[3] = (u8)temp; + lenght = FTS_PACKET_LENGTH; + packet_buf[4] = (u8)(lenght>>8); + packet_buf[5] = (u8)lenght; + + for (i=0;i 0) + { + temp = packet_number * FTS_PACKET_LENGTH; + packet_buf[2] = (u8)(temp>>8); + packet_buf[3] = (u8)temp; + + temp = (dw_lenth) % FTS_PACKET_LENGTH; + packet_buf[4] = (u8)(temp>>8); + packet_buf[5] = (u8)temp; + + for (i=0;i>8); + packet_buf[3] = (u8)temp; + temp =1; + packet_buf[4] = (u8)(temp>>8); + packet_buf[5] = (u8)temp; + packet_buf[6] = pbt_buf[ dw_lenth + i]; + bt_ecc ^= packet_buf[6]; + + byte_write(&packet_buf[0],7); + mdelay(20); + } + + /********send the opration head************/ + cmd_write(0xcc,0x00,0x00,0x00,1); + byte_read(reg_val,1); + FTprintk("[TSP] Step 6: ecc read 0x%x, new firmware 0x%x. \n", reg_val[0], bt_ecc); + if(reg_val[0] != bt_ecc) + { + return ERR_ECC; + } + + /*******Step 7: reset the new FW**********/ + cmd_write(0x07,0x00,0x00,0x00,1); + mdelay(100);//100ms + fts_register_read(0xfc, buffer, 1); + if (buffer[0] == 1) + { + cmd=4; + fts_register_write(0xfc, &cmd); + mdelay(2500);//2500ms + do + { + fts_register_read(0xfc, buffer, 1); + mdelay(100);//100ms + }while (buffer[0] != 1); + } + return ERR_OK; +} + + +/***********************************************************************/ + +int fts_ctpm_fw_upgrade_with_i_file(void) +{ + u8* pbt_buf = 0; + int i_ret; + + pbt_buf = CTPM_FW; + i_ret = fts_ctpm_fw_upgrade(pbt_buf,sizeof(CTPM_FW)); + + return i_ret; +} + +/***********************************************************************/ + +unsigned char fts_ctpm_get_upg_ver(void) +{ + unsigned int ui_sz; + + ui_sz = sizeof(CTPM_FW); + if (ui_sz > 2) + { + return CTPM_FW[ui_sz - 2]; + } + else + return 0xff; + +} + +/*read the it7260 register ,used i2c bus*/ +static int ft5306_read_regs(struct i2c_client *client, u8 reg, u8 *buf, unsigned len) +{ + int ret; + ret = i2c_master_reg8_recv(client, reg, buf, len, FT5306_IIC_SPEED); + return ret; +} + +/* set the it7260 registe,used i2c bus*/ +static int ft5306_set_regs(struct i2c_client *client, u8 reg, u8 *buf, unsigned short len) +{ + int ret; + ret = i2c_master_reg8_send(client, reg, buf, (int)len, FT5306_IIC_SPEED); + return ret; +} + +static void ft5306_queue_work(struct work_struct *work) +{ + struct ft5x0x_ts_data *data = container_of(work, struct ft5x0x_ts_data, pen_event_work); + struct tp_event event; + u8 start_reg=0x0; + u8 buf[32] = {0}; + int ret,i,offset,points; + static u8 points_last_flag[MAX_POINT]={0}; + struct tp_event current_events[MAX_POINT]; + +#if CONFIG_FT5X0X_MULTITOUCH + ret = ft5306_read_regs(data->client,start_reg, buf, 6*MAX_POINT+1); +#else + ret = ft5306_read_regs(data->client,start_reg, buf, 7); +#endif + if (ret < 0) { + dev_err(&data->client->dev, "ft5306_read_regs fail:%d!\n",ret); + enable_irq(data->irq); + return; + } +#if 0 + for (i=0; i<32; i++) { + FTprintk("buf[%d] = 0x%x \n", i, buf[i]); + } +#endif + + points = buf[2] & 0x07; + //dev_info(&data->client->dev, "ft5306_read_and_report_data points = %d\n",points); + if (points == 0) { +#if CONFIG_FT5X0X_MULTITOUCH + //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0); + //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 0); + + for(i=0;iinput_dev, i); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false); + } + } + + memset(points_last_flag, 0, sizeof(points_last_flag)); + //input_mt_sync(data->input_dev); +#else + input_report_abs(data->input_dev, ABS_PRESSURE, 0); + input_report_key(data->input_dev, BTN_TOUCH, 0); +#endif + input_sync(data->input_dev); + enable_irq(data->irq); + return; + } + memset(&event, 0, sizeof(struct tp_event)); +#if CONFIG_FT5X0X_MULTITOUCH + memset(current_events, 0, sizeof(current_events)); + + for(i=0;i>4; + event.flag = ((buf[offset+0] & 0xc0) >> 6); + event.pressure = 200; + FTprintk("x=%d, y=%d event.id=%d event.flag=%d\n",event.x,event.y,event.id,event.flag); + if(event.x<=SCREEN_MAX_X && event.y<=SCREEN_MAX_Y+60){ + //dev_info(&data->client->dev, + // "ft5306 multiple report event[%d]:x = %d,y = %d,id = %d,flag = %d,pressure = %d\n", + // i,event.x,event.y,event.id,event.flag,event.pressure); + if(event.flag) + memcpy(¤t_events[event.id], &event, sizeof(event)); + //points_current[event.id] = event.flag; + } + } + + for(i=0;iinput_dev, i); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, false); + } + else if(current_events[i].flag) + { + FTprintk("Point DN event.id=%d\n",i); + input_mt_slot(data->input_dev, i); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 1); + //input_report_abs(data->input_dev, ABS_MT_PRESSURE, event.pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, current_events[i].x); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, current_events[i].y); + } + points_last_flag[i] = current_events[i].flag; + } +#else + event.x = (s16)(buf[3] & 0x0F)<<8 | (s16)buf[4]; + event.y = (s16)(buf[5] & 0x0F)<<8 | (s16)buf[6]; + event.pressure =200; + input_report_abs(data->input_dev, ABS_X, event.x); + input_report_abs(data->input_dev, ABS_Y, event.y); + //input_report_abs(data->input_dev, ABS_PRESSURE, event.pressure); + input_report_key(data->input_dev, BTN_TOUCH, 1); + + + //dev_info(&data->client->dev, "ft5306 single report event:x = %d,y = %d\n",event.x,event.y); +#endif + //printk("ft5306 sync x = %d ,y = %d\n",event.x,event.y); + input_sync(data->input_dev); + enable_irq(data->irq); + return; +} + +static irqreturn_t ft5306_interrupt(int irq, void *dev_id) +{ + struct ft5x0x_ts_data *ft5x0x_ts = dev_id; + FTprintk("[TSP] ft5306_interrupt\n"); + disable_irq_nosync(ft5x0x_ts->irq); + if (!work_pending(&ft5x0x_ts->pen_event_work)) + queue_work(ft5x0x_ts->ts_workqueue, &ft5x0x_ts->pen_event_work); + return IRQ_HANDLED; +} +#ifdef CONFIG_HAS_EARLYSUSPEND + +static int ft5306_suspend(struct early_suspend *h) +{ + struct ft5x0x_ts_data *ft5x0x_ts; + char buf_w[1] = {3}; + int err; + ft5x0x_ts = container_of(h, struct ft5x0x_ts_data, ft5306_early_suspend); + FTprintk("TSP ft5306_suspend\n"); + //if (ft5x0x_ts->platform_sleep){ + // ft5x0x_ts->platform_sleep(); + //} + err = ft5306_set_regs(this_client,0xA5,buf_w,1); + if (err>0) + printk("ft5306_set_regs OK!!\n"); + disable_irq(ft5x0x_ts->irq); + return 0; +} + + +static int ft5306_resume(struct early_suspend *h) +{ + struct ft5x0x_ts_data *ft5x0x_ts; + ft5x0x_ts = container_of(h, struct ft5x0x_ts_data, ft5306_early_suspend); + FTprintk("TSP ft5306_resume\n"); + enable_irq(ft5x0x_ts->irq); + //if (ft5x0x_ts->platform_wakeup) + //ft5x0x_ts->platform_wakeup(); + gpio_set_value(TOUCH_RESET_PIN,GPIO_LOW); + mdelay(100); + gpio_set_value(TOUCH_RESET_PIN,GPIO_HIGH); + return 0; +} +#endif + +static int __devexit ft5306_remove(struct i2c_client *client) +{ + struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client); + + free_irq(ft5x0x_ts->irq, ft5x0x_ts); + input_unregister_device(ft5x0x_ts->input_dev); + kfree(ft5x0x_ts); + 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(&ft5x0x_ts->ft5306_early_suspend); +#endif + this_client = NULL; + return 0; +} + +static int ft5306_probe(struct i2c_client *client ,const struct i2c_device_id *id) +{ + struct ft5x0x_ts_data *ft5x0x_ts; + struct input_dev *input_dev; + struct ft5606_platform_data *pdata = client->dev.platform_data; + int err = 0; + int ret = 0; + int retry = 0; + u8 buf_w[1]; + u8 buf_r[1]; + const u8 buf_test[1] = {0}; + unsigned char reg_value; + unsigned char reg_version; + + dev_info(&client->dev, "ft5306_ts_probe!\n"); + if (!pdata) { + dev_err(&client->dev, "platform data is required!\n"); + return -EINVAL; + } + + if (pdata->init_platform_hw) + pdata->init_platform_hw(); + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){ + dev_err(&client->dev, "Must have I2C_FUNC_I2C.\n"); + return -ENODEV; + } + + ft5x0x_ts = kzalloc(sizeof(*ft5x0x_ts), GFP_KERNEL); + ft5x0x_ts->platform_wakeup = pdata->platform_wakeup; + ft5x0x_ts->platform_sleep = pdata->platform_sleep; + if (!ft5x0x_ts) { + return -ENOMEM; + } + + while(retry < 5) + { + ret=ft5306_set_regs(client,FT5X0X_REG_PMODE, buf_test,1); + if(ret > 0)break; + retry++; + } + if(ret <= 0) + { + FTprintk("FT5306 I2C TEST ERROR!\n"); + err = -ENODEV; + goto exit_i2c_test_fail; + } + + input_dev = input_allocate_device(); + if (!input_dev) { + err = -ENOMEM; + FTprintk("failed to allocate input device\n"); + goto exit_input_dev_alloc_failed; + } + ft5x0x_ts->client = this_client = client; + ft5x0x_ts->irq = client->irq; + ft5x0x_ts->input_dev = input_dev; + + #if CONFIG_FT5X0X_MULTITOUCH + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + __set_bit(EV_ABS, input_dev->evbit); + + input_mt_init_slots(input_dev, MAX_POINT); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0); + //input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, MAX_POINT, 0, 0); + //input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0); + +#else + set_bit(ABS_X, input_dev->absbit); + set_bit(ABS_Y, input_dev->absbit); + set_bit(ABS_PRESSURE, input_dev->absbit); + set_bit(BTN_TOUCH, input_dev->keybit); + input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0); + //input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0 , 0); +#endif + + //input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + //input_dev->keybit[BIT_WORD(BTN_START)] = BIT_MASK(BTN_START); + //set_bit(EV_ABS, input_dev->evbit); + //set_bit(EV_KEY, input_dev->evbit); + + input_dev->name = "ft5x0x_ts-touchscreen"; //dev_name(&client->dev) + err = input_register_device(input_dev); + if (err) { + FTprintk("ft5306_ts_probe: failed to register input device: \n"); + goto exit_input_register_device_failed; + } + + if (!ft5x0x_ts->irq) { + err = -ENODEV; + dev_err(&ft5x0x_ts->client->dev, "no IRQ?\n"); + goto exit_no_irq_fail; + }else{ + ft5x0x_ts->irq = gpio_to_irq(ft5x0x_ts->irq); + } + + INIT_WORK(&ft5x0x_ts->pen_event_work, ft5306_queue_work); + ft5x0x_ts->ts_workqueue = create_singlethread_workqueue("ft5x0x_ts"); + if (!ft5x0x_ts->ts_workqueue) { + err = -ESRCH; + goto exit_create_singlethread; + } + + /***wait CTP to bootup normally***/ + msleep(200); + + fts_register_read(FT5X0X_REG_FIRMID, ®_version,1); + printk("cdy == [TSP] firmware version = 0x%2x\n", reg_version); + +#if 1 //write firmware + fts_register_read(FT5X0X_REG_FIRMID, ®_version,1); + FTprintk("[TSP] firmware version = 0x%2x\n", reg_version); + if (fts_ctpm_get_upg_ver() != reg_version) + { + FTprintk("[TSP] start upgrade new verison 0x%2x\n", fts_ctpm_get_upg_ver()); + msleep(200); + err = fts_ctpm_fw_upgrade_with_i_file(); + if (err == 0) + { + FTprintk("[TSP] ugrade successfuly.\n"); + msleep(300); + fts_register_read(FT5X0X_REG_FIRMID, ®_value,1); + FTprintk("FTS_DBG from old version 0x%2x to new version = 0x%2x\n", reg_version, reg_value); + } + else + { + FTprintk("[TSP] ugrade fail err=%d, line = %d.\n",err, __LINE__); + } + msleep(4000); + } +#endif + ret = request_irq(ft5x0x_ts->irq, ft5306_interrupt, IRQF_TRIGGER_FALLING, client->dev.driver->name, ft5x0x_ts); + if (ret < 0) { + dev_err(&client->dev, "irq %d busy?\n", ft5x0x_ts->irq); + goto exit_irq_request_fail; + } + i2c_set_clientdata(client, ft5x0x_ts); +#ifdef CONFIG_HAS_EARLYSUSPEND + ft5x0x_ts->ft5306_early_suspend.suspend =ft5306_suspend; + ft5x0x_ts->ft5306_early_suspend.resume =ft5306_resume; + ft5x0x_ts->ft5306_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;; + register_early_suspend(&ft5x0x_ts->ft5306_early_suspend); +#endif + buf_w[0] = 6; + err = ft5306_set_regs(client,0x88,buf_w,1); + buf_r[0] = 0; + err = ft5306_read_regs(client,0x88,buf_r,1); + FTprintk("read buf[0x88] = %d\n", buf_r[0]); + return 0; + + i2c_set_clientdata(client, NULL); + free_irq(ft5x0x_ts->irq,ft5x0x_ts); +exit_irq_request_fail: + cancel_work_sync(&ft5x0x_ts->pen_event_work); + destroy_workqueue(ft5x0x_ts->ts_workqueue); +exit_create_singlethread: +exit_no_irq_fail: + input_unregister_device(input_dev); +exit_input_register_device_failed: + input_free_device(input_dev); +exit_input_dev_alloc_failed: +exit_i2c_test_fail: + if (pdata->exit_platform_hw) + pdata->exit_platform_hw(); + kfree(ft5x0x_ts); + return err; +} + + + +static struct i2c_device_id ft5306_idtable[] = { + { FT5X0X_NAME, 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, ft5306_idtable); + +static struct i2c_driver ft5306_driver = { + .driver = { + .owner = THIS_MODULE, + .name = FT5X0X_NAME + }, + .id_table = ft5306_idtable, + .probe = ft5306_probe, + //.suspend = ft5306_suspend, + //.resume = ft5306_resume, + .remove = __devexit_p(ft5306_remove), +}; + +static int __init ft5306_ts_init(void) +{ + return i2c_add_driver(&ft5306_driver); +} + +static void __exit ft5306_ts_exit(void) +{ + FTprintk("Touchscreen driver of ft5306 exited.\n"); + i2c_del_driver(&ft5306_driver); +} + + +/***********************************************************************/ + +module_init(ft5306_ts_init); +module_exit(ft5306_ts_exit); + +MODULE_AUTHOR(""); +MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver"); + diff --git a/drivers/mfd/rk610-core.c b/drivers/mfd/rk610-core.c index daad513a74c8..547a0e7cd2e2 100755 --- a/drivers/mfd/rk610-core.c +++ b/drivers/mfd/rk610-core.c @@ -255,6 +255,7 @@ static int rk610_control_probe(struct i2c_client *client, else { DBG("rk610_control_probe request gpio ok\n"); gpio_direction_output(RK610_RESET_PIN, GPIO_HIGH); + msleep(100); gpio_direction_output(RK610_RESET_PIN, GPIO_LOW); msleep(100); gpio_set_value(RK610_RESET_PIN, GPIO_HIGH); diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 6b16534548ad..0ae76cf7a375 100755 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -266,6 +266,8 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, ret = mfd_add_devices(tps65910->dev, -1, tps65910s, ARRAY_SIZE(tps65910s), NULL, 0); + + if (ret < 0) goto err; @@ -282,6 +284,8 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); ret = tps65910_irq_init(tps65910, init_data->irq, init_data); + + if (ret < 0) goto err; diff --git a/drivers/video/display/screen/Kconfig b/drivers/video/display/screen/Kconfig index 7f075480c6d7..0994269ff30f 100644 --- a/drivers/video/display/screen/Kconfig +++ b/drivers/video/display/screen/Kconfig @@ -94,6 +94,9 @@ config LCD_COMMON bool "LCD COMMON" config LCD_RK2928_A720 bool "RK2928 A720 panel 800x480" +config LCD_HSD07PFW1 + depends on MFD_RK610 + bool "RGB lcd panel HSD07PFW1" endchoice diff --git a/drivers/video/display/screen/Makefile b/drivers/video/display/screen/Makefile index d9f0b5c890ba..2940cfe7e51b 100644 --- a/drivers/video/display/screen/Makefile +++ b/drivers/video/display/screen/Makefile @@ -43,3 +43,4 @@ obj-$(CONFIG_LCD_HSD100PXN_FOR_TDW851) += lcd_hsd100pxn_for_tdw851.o obj-$(CONFIG_LCD_HV070WSA100) += lcd_hv070wsa.o obj-$(CONFIG_LCD_COMMON) += lcd_common.o obj-$(CONFIG_LCD_RK2928_A720) += lcd_rk2928_a720.o +obj-$(CONFIG_LCD_HSD07PFW1) += lcd_hsd07pfw1.o diff --git a/drivers/video/display/screen/lcd_hsd07pfw1.c b/drivers/video/display/screen/lcd_hsd07pfw1.c index 631b1a7eb81a..8f1e1fb661ba 100755 --- a/drivers/video/display/screen/lcd_hsd07pfw1.c +++ b/drivers/video/display/screen/lcd_hsd07pfw1.c @@ -1,41 +1,295 @@ #include #include -#include "../../rk29_fb.h" +#include #include #include #include +#include "../../rockchip/hdmi/rk_hdmi.h" #include "screen.h" +#ifdef CONFIG_RK610_LVDS +#include "../transmitter/rk610_lcd.h" +#endif + /* Base */ -#define OUT_TYPE SCREEN_RGB +#ifdef CONFIG_RK610_LVDS +#define OUT_TYPE SCREEN_LVDS +#define OUT_FORMAT LVDS_8BIT_1 +#else +#define OUT_TYPE SCREEN_RGB +#endif -//#define OUT_FACE OUT_D888_P666 -#define OUT_FACE OUT_P888 -#define OUT_CLK 45000000 // 65000000 +#define OUT_FACE OUT_P888 +//#define OUT_FACE OUT_P888 +#define OUT_CLK 50000000 // 65000000 #define LCDC_ACLK 312000000//312000000 //29 lcdc axi DMA ƵÂÊ /* Timing */ -#define H_PW 3 -#define H_BP 176 +#define H_PW 20 +#define H_BP 20 #define H_VD 1024 -#define H_FP 0 +#define H_FP 280 -#define V_PW 1 -#define V_BP 25 +#define V_PW 2 +#define V_BP 2 #define V_VD 600 -#define V_FP 0 +#define V_FP 34 #define LCD_WIDTH 154//1024 #define LCD_HEIGHT 91//600 /* Other */ -#define DCLK_POL 0 +#ifdef CONFIG_RK610_LVDS +#define DCLK_POL 1 +#else +#define DCLK_POL 0 +#endif + #define SWAP_RB 0 +int dsp_lut[256] ={ + 0x00000000, 0x00010101, 0x00020202, 0x00030303, 0x00040404, 0x00050505, 0x00060606, 0x00070707, + 0x00080808, 0x00090909, 0x000a0a0a, 0x000b0b0b, 0x000c0c0c, 0x000d0d0d, 0x000e0e0e, 0x000f0f0f, + 0x00101010, 0x00111111, 0x00121212, 0x00131313, 0x00141414, 0x00151515, 0x00161616, 0x00171717, + 0x00181818, 0x00191919, 0x001a1a1a, 0x001b1b1b, 0x001c1c1c, 0x001d1d1d, 0x001e1e1e, 0x001f1f1f, + 0x00202020, 0x00212121, 0x00222222, 0x00232323, 0x00242424, 0x00252525, 0x00262626, 0x00272727, + 0x00282828, 0x00292929, 0x002a2a2a, 0x002b2b2b, 0x002c2c2c, 0x002d2d2d, 0x002e2e2e, 0x002f2f2f, + 0x00303030, 0x00313131, 0x00323232, 0x00333333, 0x00343434, 0x00353535, 0x00363636, 0x00373737, + 0x00383838, 0x00393939, 0x003a3a3a, 0x003b3b3b, 0x003c3c3c, 0x003d3d3d, 0x003e3e3e, 0x003f3f3f, + 0x00404040, 0x00414141, 0x00424242, 0x00434343, 0x00444444, 0x00454545, 0x00464646, 0x00474747, + 0x00484848, 0x00494949, 0x004a4a4a, 0x004b4b4b, 0x004c4c4c, 0x004d4d4d, 0x004e4e4e, 0x004f4f4f, + 0x00505050, 0x00515151, 0x00525252, 0x00535353, 0x00545454, 0x00555555, 0x00565656, 0x00575757, + 0x00585858, 0x00595959, 0x005a5a5a, 0x005b5b5b, 0x005c5c5c, 0x005d5d5d, 0x005e5e5e, 0x005f5f5f, + 0x00606060, 0x00616161, 0x00626262, 0x00636363, 0x00646464, 0x00656565, 0x00666666, 0x00676767, + 0x00686868, 0x00696969, 0x006a6a6a, 0x006b6b6b, 0x006c6c6c, 0x006d6d6d, 0x006e6e6e, 0x006f6f6f, + 0x00707070, 0x00717171, 0x00727272, 0x00737373, 0x00747474, 0x00757575, 0x00767676, 0x00777777, + 0x00787878, 0x00797979, 0x007a7a7a, 0x007b7b7b, 0x007c7c7c, 0x007d7d7d, 0x007e7e7e, 0x007f7f7f, + 0x00808080, 0x00818181, 0x00828282, 0x00838383, 0x00848484, 0x00858585, 0x00868686, 0x00878787, + 0x00888888, 0x00898989, 0x008a8a8a, 0x008b8b8b, 0x008c8c8c, 0x008d8d8d, 0x008e8e8e, 0x008f8f8f, + 0x00909090, 0x00919191, 0x00929292, 0x00939393, 0x00949494, 0x00959595, 0x00969696, 0x00979797, + 0x00989898, 0x00999999, 0x009a9a9a, 0x009b9b9b, 0x009c9c9c, 0x009d9d9d, 0x009e9e9e, 0x009f9f9f, + 0x00a0a0a0, 0x00a1a1a1, 0x00a2a2a2, 0x00a3a3a3, 0x00a4a4a4, 0x00a5a5a5, 0x00a6a6a6, 0x00a7a7a7, + 0x00a8a8a8, 0x00a9a9a9, 0x00aaaaaa, 0x00ababab, 0x00acacac, 0x00adadad, 0x00aeaeae, 0x00afafaf, + 0x00b0b0b0, 0x00b1b1b1, 0x00b2b2b2, 0x00b3b3b3, 0x00b4b4b4, 0x00b5b5b5, 0x00b6b6b6, 0x00b7b7b7, + 0x00b8b8b8, 0x00b9b9b9, 0x00bababa, 0x00bbbbbb, 0x00bcbcbc, 0x00bdbdbd, 0x00bebebe, 0x00bfbfbf, + 0x00c0c0c0, 0x00c1c1c1, 0x00c2c2c2, 0x00c3c3c3, 0x00c4c4c4, 0x00c5c5c5, 0x00c6c6c6, 0x00c7c7c7, + 0x00c8c8c8, 0x00c9c9c9, 0x00cacaca, 0x00cbcbcb, 0x00cccccc, 0x00cdcdcd, 0x00cecece, 0x00cfcfcf, + 0x00d0d0d0, 0x00d1d1d1, 0x00d2d2d2, 0x00d3d3d3, 0x00d4d4d4, 0x00d5d5d5, 0x00d6d6d6, 0x00d7d7d7, + 0x00d8d8d8, 0x00d9d9d9, 0x00dadada, 0x00dbdbdb, 0x00dcdcdc, 0x00dddddd, 0x00dedede, 0x00dfdfdf, + 0x00e0e0e0, 0x00e1e1e1, 0x00e2e2e2, 0x00e3e3e3, 0x00e4e4e4, 0x00e5e5e5, 0x00e6e6e6, 0x00e7e7e7, + 0x00e8e8e8, 0x00e9e9e9, 0x00eaeaea, 0x00ebebeb, 0x00ececec, 0x00ededed, 0x00eeeeee, 0x00efefef, + 0x00f0f0f0, 0x00f1f1f1, 0x00f2f2f2, 0x00f3f3f3, 0x00f4f4f4, 0x00f5f5f5, 0x00f6f6f6, 0x00f7f7f7, + 0x00f8f8f8, 0x00f9f9f9, 0x00fafafa, 0x00fbfbfb, 0x00fcfcfc, 0x00fdfdfd, 0x00fefefe, 0x00ffffff, +}; + +#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)&& defined(CONFIG_RK610_LVDS) + +/* scaler Timing */ +//1920*1080*60 + +#define S_OUT_CLK SCALE_RATE(148500000,66000000) //m=16 n=9 no=4 +#define S_H_PW 10 +#define S_H_BP 10 +#define S_H_VD 1280 +#define S_H_FP 20 + +#define S_V_PW 10 +#define S_V_BP 10 +#define S_V_VD 800 +#define S_V_FP 13 + +#define S_H_ST 440 +#define S_V_ST 13 + +//1920*1080*50 +#define S1_OUT_CLK SCALE_RATE(148500000,57375000) //m=17 n=11 no=4 +#define S1_H_PW 10 +#define S1_H_BP 10 +#define S1_H_VD 1280 +#define S1_H_FP 77 + +#define S1_V_PW 10 +#define S1_V_BP 10 +#define S1_V_VD 800 +#define S1_V_FP 13 + +#define S1_H_ST 459 +#define S1_V_ST 13 + +//1280*720*60 +#define S2_OUT_CLK SCALE_RATE(74250000,66000000) //m=32 n=9 no=4 +#define S2_H_PW 10 +#define S2_H_BP 10 +#define S2_H_VD 1280 +#define S2_H_FP 20 + +#define S2_V_PW 10 +#define S2_V_BP 10 +#define S2_V_VD 800 +#define S2_V_FP 13 + +#define S2_H_ST 440 +#define S2_V_ST 13 + +//1280*720*50 + +#define S3_OUT_CLK SCALE_RATE(74250000,57375000) // m=34 n=11 no=4 +#define S3_H_PW 10 +#define S3_H_BP 10 +#define S3_H_VD 1280 +#define S3_H_FP 77 + +#define S3_V_PW 10 +#define S3_V_BP 10 +#define S3_V_VD 800 +#define S3_V_FP 13 + +#define S3_H_ST 459 +#define S3_V_ST 13 + +//720*576*50 +#define S4_OUT_CLK SCALE_RATE(27000000,63281250) //m=75 n=4 no=8 +#define S4_H_PW 10 +#define S4_H_BP 10 +#define S4_H_VD 1280 +#define S4_H_FP 185 + +#define S4_V_PW 10 +#define S4_V_BP 10 +#define S4_V_VD 800 +#define S4_V_FP 48 + +#define S4_H_ST 81 +#define S4_V_ST 48 + +//720*480*60 +#define S5_OUT_CLK SCALE_RATE(27000000,75000000) //m=100 n=9 no=4 +#define S5_H_PW 10 +#define S5_H_BP 10 +#define S5_H_VD 1280 +#define S5_H_FP 130 + +#define S5_V_PW 10 +#define S5_V_BP 10 +#define S5_V_VD 800 +#define S5_V_FP 54 + +#define S5_H_ST 476 +#define S5_V_ST 48 + +#define S_DCLK_POL 0 + +static int set_scaler_info(struct rk29fb_screen *screen, u8 hdmi_resolution) +{ + screen->s_clk_inv = S_DCLK_POL; + screen->s_den_inv = 0; + screen->s_hv_sync_inv = 0; + switch(hdmi_resolution){ + case HDMI_1920x1080p_60Hz: + /* Scaler Timing */ + screen->hdmi_resolution = hdmi_resolution; + screen->s_pixclock = S_OUT_CLK; + screen->s_hsync_len = S_H_PW; + screen->s_left_margin = S_H_BP; + screen->s_right_margin = S_H_FP; + screen->s_hsync_len = S_H_PW; + screen->s_upper_margin = S_V_BP; + screen->s_lower_margin = S_V_FP; + screen->s_vsync_len = S_V_PW; + screen->s_hsync_st = S_H_ST; + screen->s_vsync_st = S_V_ST; + break; + case HDMI_1920x1080p_50Hz: + /* Scaler Timing */ + screen->hdmi_resolution = hdmi_resolution; + screen->s_pixclock = S1_OUT_CLK; + screen->s_hsync_len = S1_H_PW; + screen->s_left_margin = S1_H_BP; + screen->s_right_margin = S1_H_FP; + screen->s_hsync_len = S1_H_PW; + screen->s_upper_margin = S1_V_BP; + screen->s_lower_margin = S1_V_FP; + screen->s_vsync_len = S1_V_PW; + screen->s_hsync_st = S1_H_ST; + screen->s_vsync_st = S1_V_ST; + break; + case HDMI_1280x720p_60Hz: + /* Scaler Timing */ + screen->hdmi_resolution = hdmi_resolution; + screen->s_pixclock = S2_OUT_CLK; + screen->s_hsync_len = S2_H_PW; + screen->s_left_margin = S2_H_BP; + screen->s_right_margin = S2_H_FP; + screen->s_hsync_len = S2_H_PW; + screen->s_upper_margin = S2_V_BP; + screen->s_lower_margin = S2_V_FP; + screen->s_vsync_len = S2_V_PW; + screen->s_hsync_st = S2_H_ST; + screen->s_vsync_st = S2_V_ST; + break; + case HDMI_1280x720p_50Hz: + /* Scaler Timing */ + screen->hdmi_resolution = hdmi_resolution; + screen->s_pixclock = S3_OUT_CLK; + screen->s_hsync_len = S3_H_PW; + screen->s_left_margin = S3_H_BP; + screen->s_right_margin = S3_H_FP; + screen->s_hsync_len = S3_H_PW; + screen->s_upper_margin = S3_V_BP; + screen->s_lower_margin = S3_V_FP; + screen->s_vsync_len = S3_V_PW; + screen->s_hsync_st = S3_H_ST; + screen->s_vsync_st = S3_V_ST; + break; + case HDMI_720x576p_50Hz_4_3: + case HDMI_720x576p_50Hz_16_9: + /* Scaler Timing */ + screen->hdmi_resolution = hdmi_resolution; + screen->s_pixclock = S4_OUT_CLK; + screen->s_hsync_len = S4_H_PW; + screen->s_left_margin = S4_H_BP; + screen->s_right_margin = S4_H_FP; + screen->s_hsync_len = S4_H_PW; + screen->s_upper_margin = S4_V_BP; + screen->s_lower_margin = S4_V_FP; + screen->s_vsync_len = S4_V_PW; + screen->s_hsync_st = S4_H_ST; + screen->s_vsync_st = S4_V_ST; + break; + case HDMI_720x480p_60Hz_16_9: + case HDMI_720x480p_60Hz_4_3: + /* Scaler Timing */ + screen->hdmi_resolution = hdmi_resolution; + screen->s_pixclock = S5_OUT_CLK; + screen->s_hsync_len = S5_H_PW; + screen->s_left_margin = S5_H_BP; + screen->s_right_margin = S5_H_FP; + screen->s_hsync_len = S5_H_PW; + screen->s_upper_margin = S5_V_BP; + screen->s_lower_margin = S5_V_FP; + screen->s_vsync_len = S5_V_PW; + screen->s_hsync_st = S5_H_ST; + screen->s_vsync_st = S5_V_ST; + break; + default : + printk("%s lcd not support dual display at this hdmi resolution %d \n",__func__,hdmi_resolution); + return -1; + break; + } + + return 0; +} +#else +#define set_scaler_info NULL +#endif + void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info ) { /* screen type & face */ screen->type = OUT_TYPE; +#ifdef CONFIG_RK610_LVDS + screen->hw_format = OUT_FORMAT; +#endif screen->face = OUT_FACE; /* Screen size */ @@ -70,7 +324,12 @@ void set_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info ) /* Operation function*/ screen->init = NULL; - screen->standby = NULL; + screen->standby = NULL; + screen->dsp_lut = dsp_lut; + screen->sscreen_get = set_scaler_info; +#ifdef CONFIG_RK610_LVDS + screen->sscreen_set = rk610_lcd_scaler_set_param; +#endif } diff --git a/drivers/video/display/transmitter/rk610_lcd.c b/drivers/video/display/transmitter/rk610_lcd.c index 9ffac8db2654..7b223ee018e9 100644 --- a/drivers/video/display/transmitter/rk610_lcd.c +++ b/drivers/video/display/transmitter/rk610_lcd.c @@ -353,6 +353,7 @@ static void rk610_lcd_early_resume(struct early_suspend *h) #endif int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enable:0 bypass 1: scale { + printk("%s>>>>>>>>>\n",__func__); int ret=0; struct i2c_client *client = g_lcd_inf->client; if(client == NULL){ @@ -380,6 +381,8 @@ int rk610_lcd_scaler_set_param(struct rk29fb_screen *screen,bool enable )//enabl rk610_output_config(client,screen,LCD_OUT_BYPASS); ret = rk610_lcd_scaler_bypass(client,enable); } + + printk("%s>>>>>>>>>>\n",__func__); return ret; } int rk610_lcd_init(struct rk610_core_info *rk610_core_info) diff --git a/include/linux/mfd/rk610_core.h b/include/linux/mfd/rk610_core.h index e67b146224bf..1b50c812266a 100644 --- a/include/linux/mfd/rk610_core.h +++ b/include/linux/mfd/rk610_core.h @@ -2,7 +2,7 @@ #define __RK610_CONTROL_H_ #define INVALID_GPIO -1 -//#define RK610_DEBUG +#define RK610_DEBUG #ifdef RK610_DEBUG #define RK610_DBG(dev, format, arg...) \ -- 2.34.1