对于MTK TP驱动移植一般分为六部分:

1、硬件IO口配置;

2、TP驱动移植。

3、I2C通信;

4、中断触发;

5、数据上报;

6、虚拟按键。

硬件电路:

1、GPIO配置

打开 mediatek\dct\DrvGen.exe 

选择 mediatek\custom\xiaoxi\kernel\dct\dct\codegen.dws 配置文件

配置EINT7_CTP引脚、CTP_RST复位引脚

2、TP驱动移植(以ft5x16为例)

在\mediatek\custom\common\kernel\touchpanel文件夹下创建ft5x16,将供应商提供的驱动驱动资料复制到该文件夹下。

改动配置文件:mediatek\config\prj\ProjectConfig.mk下的CUSTOM_KERNEL_TOUCHPANEL其值由改为ft5x16。表明相应ft5x16子文件夹;

打开ft5x16.c文件。改动一下:

static struct i2c_board_info __initdata ft5x16_i2c_tpd={ I2C_BOARD_INFO("ft5x16", (0x70>>1))}; //"ft5x16"为设备名 ,设备地址为高7位

static struct tpd_driver_t tpd_device_driver = {
.tpd_device_name = "FT5x16",
.tpd_local_init = tpd_local_init,
.suspend = tpd_suspend,
.resume = tpd_resume,
#ifdef TPD_HAVE_BUTTON
.tpd_have_button = 1,
#else
.tpd_have_button = 0,
#endif
}; /* called when loaded into kernel */
static int __init tpd_driver_init(void) {
printk("MediaTek FT5x16 touch panel driver init\n");
/* 注冊板级设备信息 */
i2c_register_board_info(IIC_PORT, &ft5x16_i2c_tpd, 1); //IIC_PORT表示i2c控制器号。由电路原理图可知TP设备连接到i2c控制器0,ft5x16_i2c_tpd为i2c设备结构,1表示该i2c_board_info个数
if(tpd_driver_add(&tpd_device_driver) < 0)
printk("add FT5x16 driver failed\n");
return 0;
}
</span>

又一次编译:./mk n k && ./mk bootimage 

3、I2C通信

新驱动编译进内核,启动内核后,我们如何验证i2c接口能够正常通信呢?

系统启动后通过串口或adb shell进入系统命令行窗体,查询/sys/bus/i2c/devices文件夹下是否有0-0038信息。查询/sys/bus/i2c/drivers文件夹下是否存在‘ft5x16’设备名;先保证i2c能够正常通信。

4、中断触发

中断注冊函数:mt_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE, tpd_eint_interrupt_handler, 1);

//tpd_eint_interrupt_handler函数为中断回调函数

5、数据上报

当触摸屏产生中断的时候就会调用到该接口;然后在中断处理函数中唤醒执行在子线程中的等待队列,再通过子线程获取TP数据并上报到系统;

static DECLARE_WAIT_QUEUE_HEAD(waiter);  //初始化等待队列

thread = kthread_run(touch_event_handler, 0, TPD_DEVICE);  //新建线程

static int touch_event_handler(void *unused)
{
......
do
{
mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
set_current_state(TASK_INTERRUPTIBLE);
wait_event_interruptible(waiter,tpd_flag!=0); //等待队列进入休眠。等待唤醒
tpd_flag = 0;
set_current_state(TASK_RUNNING);
......
if (tpd_touchinfo(&cinfo, &pinfo)) //获取TP数据
{
//TPD_DEBUG("point_num = %d\n",point_num);
TPD_DEBUG_SET_TIME;
if(point_num >0)
{
for(i =0; i<point_num; i++)//only support 3 point
{
cinfo.x[i] = cinfo.x[i];
cinfo.y[i] = cinfo.y[i]; tpd_down(cinfo.x[i], cinfo.y[i], cinfo.id[i]); //上报按下数据
printk(KERN_DEBUG"----calibration----- X:%4d, Y:%4d, P:%4d \n", cinfo.x[i], cinfo.y[i], cinfo.id[i]);
}
input_sync(tpd->dev);
}
else
{
tpd_up(cinfo.x[0], cinfo.y[0]); //上报弹起数据
//TPD_DEBUG("release --->\n");
//input_mt_sync(tpd->dev);
input_sync(tpd->dev);
}
}
...... }while(!kthread_should_stop()); return 0;
}

TP数据能够通过打印的方式进行查看。也能够激活‘系统设置’中‘开发人员选项’的‘指针位置’,如今触摸操作在LCD的轨迹,也能够在packages\apps\Launcher2\src\com\android\launcher2\Launcher.java的onCreate方法最后加入Settings.System.putInt(this.getContentResolver(),Settings.System.POINTER_LOCATION,
1); 在Launcher中开启‘指针位置’功能(须要mm Launcher模块并又一次打包和烧录system.img文件)。

注:假设TP获取到的数据比較乱的时候建议通过打开‘指针位置’功能进行查看。排除TP固件分辨与LCD没相应等问题;

6、虚拟按键

static struct tpd_driver_t tpd_device_driver = {
.tpd_device_name = "FT5x16",
.tpd_local_init = tpd_local_init,
.suspend = tpd_suspend,
.resume = tpd_resume,
#ifdef TPD_HAVE_BUTTON
.tpd_have_button = 1,
#else
.tpd_have_button = 0,
#endif
};

从tpd_driver_t结构可知tpd_have_button成员为虚拟按键标志位;由宏TPD_HAVA_BUTTON开关决定的,宏定义在tpd_custom_fts.h中;

在tpd_custom_fts.h中定义了一系列关于虚拟按键的宏:

#define TPD_HAVE_BUTTON  //虚拟按键开关
#define TPD_BUTTON_WIDTH    (200)  //按键宽度
#define TPD_BUTTON_HEIGH    (100)  //按键高度
#define TPD_KEY_COUNT             3       //按键个数
#define TPD_KEYS                        {KEY_MENU, KEY_HOMEPAGE, KEY_BACK}  //按键相应的功能
#define TPD_KEYS_DIM              {{80,900,TPD_BUTTON_WIDTH,TPD_BUTTON_HEIGH}, {240,900,TPD_BUTTON_WIDTH,TPD_BUTTON_HEIGH}, {400,900,TPD_BUTTON_WIDTH,TPD_BUTTON_HEIGH}}  //按键相应位置

TPD_KEYS_DIM中的坐标是该按键区域的中心点:

TP驱动简要分析

static struct tpd_driver_t tpd_device_driver = {
.tpd_device_name = FT5x16,
.tpd_local_init = tpd_local_init, //初始化函数
.suspend = tpd_suspend,
.resume = tpd_resume,
#ifdef TPD_HAVE_BUTTON
.tpd_have_button = 1,
#else
.tpd_have_button = 0,
#endif
}; /* called when loaded into kernel */
static int __init tpd_driver_init(void) {
printk("MediaTek FT5x16 touch panel driver init\n");
i2c_register_board_info(0, &ft5x16_i2c_tpd, 1); //注冊板级设备信息
if(tpd_driver_add(&tpd_device_driver) < 0) //加入驱动
printk("add FT5x16 driver failed\n");
return 0;
}

MTK自己编写了一套TP框架,通过该框架管理TP设备,tpd_driver_add为框架的接口之中的一个;系统通过tpd_driver_add加入驱动后会回调tpd_local_init函数。

#ifdef TPD_HAVE_BUTTON
static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS; //存放按键功能信息
static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM; //存放虚拟按键信息
#endif static int tpd_local_init(void)
{
TPD_DMESG("FTS I2C Touchscreen Driver (Built %s @ %s)\n", __DATE__, __TIME__); if(i2c_add_driver(&tpd_i2c_driver)!=0) //注冊i2c驱动
{
TPD_DMESG("FTS unable to add i2c driver.\n");
return -1;
}
if(tpd_load_status == 0)
{
TPD_DMESG("FTS add error touch panel driver.\n");
i2c_del_driver(&tpd_i2c_driver);
return -1;
} #ifdef TPD_HAVE_BUTTON //假设定义虚拟按键。则初始化按键信息
tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data
#endif #if (defined(TPD_WARP_START) && defined(TPD_WARP_END))
TPD_DO_WARP = 1;
memcpy(tpd_wb_start, tpd_wb_start_local, TPD_WARP_CNT*4);
memcpy(tpd_wb_end, tpd_wb_start_local, TPD_WARP_CNT*4);
#endif #if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION))
memcpy(tpd_calmat, tpd_def_calmat_local, 8*4);
memcpy(tpd_def_calmat, tpd_def_calmat_local, 8*4);
#endif
TPD_DMESG("end %s, %d\n", __FUNCTION__, __LINE__);
tpd_type_cap = 1;
return 0;
}

向系统注冊i2c驱动后。假设找到相应的设备就会调用tpd_probe函数。

static const struct i2c_device_id ft5x16_tpd_id[] = {{TPD_NAME,0},{}};

static struct i2c_driver tpd_i2c_driver = {
.driver = {
.name = TPD_NAME,
},
.probe = tpd_prob,
.remove = __devexit_p(tpd_remove),
.id_table = ft5x16_tpd_id,
.detect = tpd_detect,
}; static int __devinit tpd_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int retval = TPD_OK;
char data;
u8 report_rate=0;
int err=0;
int reset_count = 0;
u8 chip_id,i; reset_proc:
i2c_client = client;
#ifdef MAIERXUN_TP_COM
if(touchpanel_flag){
return 0;
}
#endif
//复位
//power on, need confirm with SA
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);
msleep(5);
TPD_DMESG(" fts ic reset\n"); //打开TP电源
#ifdef TPD_POWER_SOURCE_CUSTOM
hwPowerOn(TPD_POWER_SOURCE_CUSTOM, VOL_3300, "TP");
#else
hwPowerOn(MT65XX_POWER_LDO_VGP2, VOL_3300, "TP");
#endif mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE); #ifdef TPD_CLOSE_POWER_IN_SLEEP
hwPowerDown(TPD_POWER_SOURCE,"TP");
hwPowerOn(TPD_POWER_SOURCE,VOL_3300,"TP");
msleep(100); #else /* 结束复位 */
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);
msleep(5);
TPD_DMESG(" fts ic reset\n");
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);
#endif /* 初始化中断引脚 */
mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT);
mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_IN);
mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE);
mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN, GPIO_PULL_UP); /* 中断配置和注冊 */
mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
mt_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE, tpd_eint_interrupt_handler, 1); //注冊中断处理函数,TP产生中断时就会回调tpd_eint_interrupt函数
mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); msleep(400); err=i2c_smbus_read_i2c_block_data(i2c_client, 0x00, 1, &data); TPD_DMESG("gao_i2c:err %d,data:%d\n", err,data);
if(err< 0 || data!=0)// reg0 data running state is 0; other state is not 0
{
TPD_DMESG("I2C transfer error, line: %d\n", __LINE__);
#ifdef TPD_RESET_ISSUE_WORKAROUND
if ( reset_count < TPD_MAX_RESET_COUNT )
{
reset_count++;
goto reset_proc;
}
#endif
//add at 20150330 by zhu
#ifdef MAIERXUN_TP_COM
touchpanel_flag=false;
#endif
return -1;
} ...... #ifdef VELOCITY_CUSTOM_FT5206
if((err = misc_register(&tpd_misc_device))) //注冊混杂设备驱动
{
printk("mtk_tpd: tpd_misc_device register failed\n"); }
#endif #ifdef TPD_AUTO_UPGRADE
printk("********************Enter CTP Auto Upgrade********************\n");
fts_ctpm_auto_upgrade(i2c_client);
#endif
thread = kthread_run(touch_event_handler, 0, TPD_DEVICE); //创建子线程,通过该子线程获取和上报数据
if (IS_ERR(thread))
{
retval = PTR_ERR(thread);
TPD_DMESG(TPD_DEVICE " failed to create kernel thread: %d\n", retval);
} TPD_DMESG("FTS Touch Panel Device Probe %s\n", (retval < TPD_OK) ? "FAIL" : "PASS"); /* 初始化TP的P-sensor功能,暂不分析 */
#ifdef TPD_PROXIMITY
struct hwmsen_object obj_ps; obj_ps.polling = 0;//interrupt mode
obj_ps.sensor_operate = tpd_ps_operate;
if((err = hwmsen_attach(ID_PROXIMITY, &obj_ps)))
{
APS_ERR("proxi_fts attach fail = %d\n", err);
}
else
{
APS_ERR("proxi_fts attach ok = %d\n", err);
}
#endif #ifdef MAIERXUN_TP_COM
touchpanel_flag=true;
#endif return 0; }

/* 中断处理函数 */

static void tpd_eint_interrupt_handler(void)
{
//TPD_DEBUG("TPD interrupt has been triggered\n");
TPD_DEBUG_PRINT_INT;
tpd_flag = 1;
wake_up_interruptible(&waiter); //唤醒等待队列
}

中断处理遵循中断上下文的设计原则,使得中断子程序仅仅是简单唤醒等待队列就能够了,没有多余的操作;

/* 子线程处理函数 */

static int touch_event_handler(void *unused)
{
struct touch_info cinfo, pinfo;
int i=0; struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
sched_setscheduler(current, SCHED_RR, ¶m); #ifdef TPD_PROXIMITY
int err;
hwm_sensor_data sensor_data;
u8 proximity_status; #endif
u8 state; do //进入while循环进行睡眠-等待唤醒的操作
{
mt_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); //中断使能(解除屏蔽)
set_current_state(TASK_INTERRUPTIBLE);
wait_event_interruptible(waiter,tpd_flag!=0); //进入睡眠等待唤醒 tpd_flag = 0; set_current_state(TASK_RUNNING);
...... #ifdef TPD_PROXIMITY //TP的P-sensor功能,暂不分析
if (tpd_proximity_flag == 1)
{
i2c_smbus_read_i2c_block_data(i2c_client, 0xB0, 1, &state);
TPD_PROXIMITY_DEBUG("proxi_5206 0xB0 state value is 1131 0x%02X\n", state); if(!(state&0x01))
{
tpd_enable_ps(1);
} i2c_smbus_read_i2c_block_data(i2c_client, 0x01, 1, &proximity_status);
TPD_PROXIMITY_DEBUG("proxi_5206 0x01 value is 1139 0x%02X\n", proximity_status); if (proximity_status == 0xC0)
{
tpd_proximity_detect = 0;
}
else if(proximity_status == 0xE0)
{
tpd_proximity_detect = 1;
} TPD_PROXIMITY_DEBUG("tpd_proximity_detect 1149 = %d\n", tpd_proximity_detect); if ((err = tpd_read_ps()))
{
TPD_PROXIMITY_DMESG("proxi_5206 read ps data 1156: %d\n", err);
}
sensor_data.values[0] = tpd_get_ps_value();
sensor_data.value_divide = 1;
sensor_data.status = SENSOR_STATUS_ACCURACY_MEDIUM;
if ((err = hwmsen_get_interrupt_data(ID_PROXIMITY, &sensor_data)))
{
TPD_PROXIMITY_DMESG(" proxi_5206 call hwmsen_get_interrupt_data failed= %d\n", err);
}
}
#endif if (tpd_touchinfo(&cinfo, &pinfo)) //获取TP设备数据,并把数据保存在cinfob buf中
{
//TPD_DEBUG("point_num = %d\n",point_num);
TPD_DEBUG_SET_TIME;
if(point_num >0)
{
for(i =0; i<point_num; i++)//only support 3 point
{
printk(KERN_DEBUG"X:%4d, Y:%4d, P:%4d \n", cinfo.x[i], cinfo.y[i], cinfo.id[i]); cinfo.x[i] = cinfo.x[i];
cinfo.y[i] = cinfo.y[i]; tpd_down(cinfo.x[i], cinfo.y[i], cinfo.id[i]); //按下数据处理
printk(KERN_DEBUG"----calibration----- X:%4d, Y:%4d, P:%4d \n", cinfo.x[i], cinfo.y[i], cinfo.id[i]);
}
input_sync(tpd->dev);
}
else
{
tpd_up(cinfo.x[0], cinfo.y[0]); //弹起数据处理
//TPD_DEBUG("release --->\n");
//input_mt_sync(tpd->dev);
input_sync(tpd->dev);
}
}
...... }while(!kthread_should_stop()); return 0;
}

/* 获取TP数据 */

static int tpd_touchinfo(struct touch_info *cinfo, struct touch_info *pinfo)
{
int i = 0;
char data[128] = {0};
u16 high_byte,low_byte,reg;
u8 report_rate =0; p_point_num = point_num;
if (tpd_halt)
{
TPD_DMESG( "tpd_touchinfo return ..\n");
return false;
}
mutex_lock(&i2c_access); reg = 0x00;
fts_i2c_Read(i2c_client, &reg, 1, data, 64); //获取TP数据,一些TP是支持多点触控的。所以有可能就产生多个触点的数据
mutex_unlock(&i2c_access); /*get the number of the touch points*/
point_num= data[2] & 0x0f; TPD_DEBUG("point_num =%d\n",point_num); /* 依据芯片协议解析数据并存放在cinfo buf中 */
for(i = 0; i < point_num; i++)
{
cinfo->p[i] = data[3+6*i] >> 6; //event flag
cinfo->id[i] = data[3+6*i+2]>>4; //touch id
/*get the X coordinate, 2 bytes*/
high_byte = data[3+6*i];
high_byte <<= 8;
high_byte &= 0x0f00;
low_byte = data[3+6*i + 1];
cinfo->x[i] = high_byte |low_byte; /*get the Y coordinate, 2 bytes*/
high_byte = data[3+6*i+2];
high_byte <<= 8;
high_byte &= 0x0f00;
low_byte = data[3+6*i+3];
cinfo->y[i] = high_byte |low_byte;
} }
TPD_DEBUG(" cinfo->x[0] = %d, cinfo->y[0] = %d, cinfo->p[0] = %d\n", cinfo->x[0], cinfo->y[0], cinfo->p[0]); return true;
}

static  void tpd_down(int x, int y, int p) {
static int tpd_x = 0;
static int tpd_y = 0; tpd_x = x;
tpd_y = y; /* 通过输入子系统上报数据 */
input_report_key(tpd->dev, BTN_TOUCH, 1);
input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, 20);
input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y); printk(KERN_ERR, "D[%4d %4d %4d] ", x, y, p);
/* track id Start 0 */
input_report_abs(tpd->dev, ABS_MT_TRACKING_ID, p);
input_mt_sync(tpd->dev);
#ifndef MT6572
if (FACTORY_BOOT == get_boot_mode()|| RECOVERY_BOOT == get_boot_mode())
#endif
{
tpd_button(x, y, 1); //虚拟按键的处理
}
TPD_EM_PRINT(x, y, x, y, p-1, 1);
} static void tpd_up(int x, int y) { input_report_key(tpd->dev, BTN_TOUCH, 0);
input_mt_sync(tpd->dev);
TPD_EM_PRINT(x, y, x, y, 0, 0); #ifndef MT6572
if (FACTORY_BOOT == get_boot_mode()|| RECOVERY_BOOT == get_boot_mode())
#endif
{
tpd_button(x, y, 0);
}
}

/* 虚拟按键推断和处理函数 */

void tpd_button(unsigned int x, unsigned int y, unsigned int down) {
int i;
if(down) {
for(i=0;i<tpd_keycnt;i++)
{
/* 推断数据是否落在虚拟按键的范围内,数据处理算法实现了以坐标点为中心的虚拟按键 */
if(x>=tpd_keys_dim[i][0]-(tpd_keys_dim[i][2]/2) &&
x<=tpd_keys_dim[i][0]+(tpd_keys_dim[i][2]/2) &&
y>=tpd_keys_dim[i][1]-(tpd_keys_dim[i][3]/2) &&
y<=tpd_keys_dim[i][1]+(tpd_keys_dim[i][3]/2) &&
!(tpd->btn_state&(1<<i)))
{
input_report_key(tpd->kpd, tpd_keys[i], 1); //上报按键
input_sync(tpd->kpd);
tpd->btn_state|=(1<<i);
TPD_DEBUG("[mtk-tpd] press key %d (%d)\n",i, tpd_keys[i]);
printk("[mtk-tpd] press key %d (%d)\n",i, tpd_keys[i]);
}
}
} else {
for(i=0;i<tpd_keycnt;i++) {
if(tpd->btn_state&(1<<i)) {
input_report_key(tpd->kpd, tpd_keys[i], 0);
input_sync(tpd->kpd);
TPD_DEBUG("[mtk-tpd] release key %d (%d)\n",i, tpd_keys[i]);
printk("[mtk-tpd] release key %d (%d)\n",i, tpd_keys[i]);
}
}
tpd->btn_state=0;
}
}
tpd_keys_dim和tpd_keys的数据是通过tpd_button_setting初始化的,能够去看tpd_button_setting()的实现;

通过简单分析。由此可知MTK的TP驱动的总体框架跟普通TP驱动框架也是大致差点儿相同;

  • 本文已收录于下面专栏:

基于MTK 的 TP 驱动分析

1. 克隆serverproject源代码并切换分支 

git clone git@192.168.20.2: mt658292_kk v9 

git checkout -b submit_v9_dongx...

  • zhubin0613
  • 2015年01月03日 21:10
  • 1843

MTK平台tp触摸屏驱动分析

转自http://m.blog.csdn.net/article/details?

id=51362009

本博文将解说基于Goodix触控芯片的tp驱动程序。如有不足之处,敬请指出。

初始化
st...

  • gnnulzy
  • 2016年08月24日 14:57
  • 3310

MTK平台TP驱动具体解释

MTK平台tp驱动具体解释本博文将解说基于goodix9157触控芯片的tp驱动程序。

这里有相应的驱动程序。初始化static int __init tpd_driver_init(void)
{
...

  • encourage2011
  • 2016年05月10日 11:52
  • 9511

Mtk touch panel驱动/TP驱动具体解释

TP还算是比LCM好理解的多。
在启动过程中。先注冊/mediatek/custom/comond/kernel/touchpanel文件夹下的详细驱动(如focaltech_driver.c),in...
  • sdkdlwk
  • 2017年05月26日 11:47
  • 635

MTK MT8163 7.0 TP驱动简单移植

本文仅仅是按照MTK MT8163 7.0框架移植进行的实际操作,基于驱动代码已经ok的情况下。并没有考虑到调试层面,如有须要必须抓log等各种方法进行调试!
1. GT9xx驱动及驱动文件简单介绍
...
  • qf0727
  • 2016年12月16日 21:00
  • 3047

mtk android tp 调试

msg2133 tp调试
重要函数为:
tpd_local_init(tpd_probe), tpd_suspend, tpd_resume

Msg2133_driver.c:

...

  • gaoguoxin2
  • 2012年09月01日 10:44
  • 4554

基于MTK 的 TP 驱动分析

1. 克隆serverproject源代码
   git clone git@192.168.20.2: mt658292_kk v9
 
2. TP 硬件分析
1)硬件图:
 

2)硬件管...

  • xiaopangzi313
  • 2014年09月11日 17:52
  • 4250

Android MTK 6572 光感/TP控制

Z:\project_name\mediatek\config\keytak72_wet_lca\ProjectConfig.mk
改动ProjectConfig.mk文件里的 以下两个字段 开启和...
  • Mr_kings
  • 2016年04月01日 18:14
  • 863

android TP驱动移植调试笔记

1. 加入I2C 设备
TP 一般採用的是I2C 作为数据和命令接口,所以TP 驱动也能够归类为I2C 驱动。TP驱动的主要逻辑不在这里,可是了解了Linux 的I2C 体系架构,就能够对整个驱动流...
  • jkzrc
  • 2014年01月20日 11:28
  • 2956

MTK android的TouchPanel的驱动配置

CUSTOM_KERNEL_TOUCHPANEL = FT5206
alps\mediatek\custom\mt6571v1_phone_emmc\kernel\touchpanel\FT5206\...
  • aree
  • 2014年03月21日 17:22
  • 2309

1、硬件IO口配置;的更多相关文章

  1. STM32的IO口是如何配置为某个外设使用的 ---?

    @2019-03-01 [猜想] 使用片内外设功能: 首先将对应 IO 口配置为复用输出 其次是 IO 口对应的多个功能外设,哪个外设使能即将外设与 IO 口相连 [疑问] 若多个外设都使能,那么到底 ...

  2. STM32f10xxx 之 GPIO口配置

    背景 配置stm32f103使其完成PWM输出的过程中,在配置GPIO口的时候,按照习惯配置GPIO口的speed为50MHZ,突然就意识到,为什么大部分例程习惯配置为50MHZ,而不是其它值,即有了 ...

  3. STM32F030如何正确配置IO口的复用功能

    本文所使用的单片机型号为STM32F030C8T6. 在030系列的单片机中,PA2引脚除了作为普通的IO引脚用作输入输出功能以外,还可以作为内部外设串口1,串口2,定时器15通道1这三个外设的功能引 ...

  4. STM32JTAG口用作普通IO的配置

    使用Jlink向STM32烧录程序时,需要使用6个芯片的引脚(以STM32F103C8T6为例),分别是PB4/JNTRST.PB3/JTDO.PA13/JTMS.PA14/JTCK.PA15/JTD ...

  5. STM32的IO口的8种配置

    STM32的IO口的8种配置 1 STM32的输入输出管脚有以下8种可能的配置:(4输入+2输出+2复用输出) ① 浮空输入_IN_FLOATING ② 带上拉输入_IPU ③ 带下拉输入_IPD ④ ...

  6. 【STM32】IIC的基本原理(实例:普通IO口模拟IIC时序读取24C02)(转载)

     版权声明:本文为博主原创文章,允许转载,但希望标注转载来源. https://blog.csdn.net/qq_38410730/article/details/80312357 IIC的基本介绍 ...

  7. Silicon C8051F340之GPIO口配置与使用

    一.背景: 很久前用过C8051,现在有相关需求需要重新使用C8051,然后发现一年前开发的相关经验都忘得 基本上差不多了.连最基本的GPIO口配置还得重新来看手册,所以有此文,做个记录,以备下次快速 ...

  8. IO口

    STM32的每个IO端口都有7个寄存器来控制.他们是:CRH CRL IDR ODR BSRR BRR LCKR.我们常用的IO端口寄存器位CRL CRH IDR ODR.CRL CRH控制着每个IO ...

  9. STM32系列单片机IO口模式设置

    STM32单片机的每组IO口都有4个32位配置寄存器用于配置GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR和GPIOx_PUPDR,2个32位数据寄存器用于配置输入和 ...

随机推荐

  1. [bzoj3122][SDOI2013]随机数生成器 ——BSGS,数列

    题目大意 给定递推序列: F[i] = a*F[i-1] + b (mod c) 求一个最小的i使得F[i] == t 题解 我们首先要化简这个数列,作为一个学渣,我查阅了一些资料: http://d ...

  2. [译] 如何像 Python 高手一样编程?

    转自:http://www.liuhaihua.cn/archives/23475.html Harries 发布于 7天前 分类:编程技术 阅读(15) 评论(0) 最近在网上看到一篇介绍Pytho ...

  3. 获得NOTEPAD++ Download Manager的所有下载列表的内容的au3脚本

    ;~ 获得NOTEPAD++ Download Manager的所有下载列表的内容的au3脚本 ;~ 作者: 鹏程万里 ;~ Email:aprial@163.com ;~ 创建日期: 2014年11 ...

  4. Video for Linux Two API Specification Revision 2.6.32【转】

    转自:https://www.linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html Video for ...

  5. C++ 调节PCM音频音量大小

    在用解码器解码音频数据得到PCM音频数据块之后,可以在将数据送给声卡播放之前调节其音量大小,具体的实现函数如下: void RaiseVolume(char* buf, UINT32 size, UI ...

  6. LVM更换硬盘

    #检测坏道 smartctl -a /dev/sdd #硬盘检测 e2fsck -f /dev/mapper/vg_root-lv_data #重新定义空间大小,将原来的大小上减去要移走的硬盘 res ...

  7. .apache.commons.io 源代码学习(一)

    java的初学者,准备通读各种高水平源代码,提升能力. 为了避免自己的惰性,写博客. 版本:2.5 开发平台:netbeans. 今天是第一天,网上先看个例子:http://www.importnew ...

  8. Android 中带有进度条效果的按钮(Button)

    安卓中带有进度条效果的按钮,如下图: 1.布局文件如下activity_main.xml <RelativeLayout xmlns:android="http://schemas.a ...

  9. EGS5在linux系统下安装过程

    转载自52MC论坛 作者:xinruibj 平台:Fedora 13 内核版本为:2.6.33, g77版本为:3.4.6: 用户名为xinrui,下面出现这个文件夹xinrui时,修改为你自己的用户 ...

  10. hdu 1556 Color the ball 线段树

    题目链接:HDU - 1556 N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气 ...