/* * 测试触摸屏,打印触点坐标 */ void Test_Ts(void) { isr_handle_array[ISR_ADC_OFT] = AdcTsIntHandle; // 设置ADC中断服务程序 INTMSK &= ~BIT_ADC; // 开启ADC总中断 INTSUBMSK &= ~(BIT_SUB_TC); // 开启INT_TC中断,即触摸屏被按下或松开时产生中断 INTSUBMSK &= ~(BIT_SUB_ADC); // 开启INT_ADC中断,即A/D转换结束时产生中断 // 使能预分频功能,设置A/D转换器的时钟 = PCLK/(49+1) ADCCON = PRESCALE_EN | PRSCVL(49); /* 采样延时时间 = (1/3.6864M)*50000 = 13.56ms * 即按下触摸屏后,再过13.56ms才采样 */ ADCDLY = 50000; wait_down_int(); /* 进入"等待中断模式",等待触摸屏被按下 */ printf("Touch the screem to test, press any key to exit\n\r"); getc(); // 屏蔽ADC中断 INTSUBMSK |= BIT_SUB_TC; INTSUBMSK |= BIT_SUB_ADC; INTMSK |= BIT_ADC; }
/* * INT_TC的中断服务程序 * 当触摸屏被按下时,进入自动(连续) X/Y轴坐标转换模式; * 当触摸屏被松开时,进入等待中断模式,再次等待INT_TC中断 */ static void Isr_Tc(void) { if (ADCDAT0 & 0x8000) { printf("Stylus Up!!\n\r"); wait_down_int(); /* 进入"等待中断模式",等待触摸屏被按下 */ } else { printf("Stylus Down: "); mode_auto_xy(); /* 进入自动(连续) X/Y轴坐标转换模式 */ /* 设置位[0]为1,启动A/D转换 * 注意:ADCDLY为50000,PCLK = 50MHz, * 要经过(1/50MHz)*50000=1ms之后才开始转换X坐标 * 再经过1ms之后才开始转换Y坐标 */ ADCCON |= ADC_START; } // 清INT_TC中断 SUBSRCPND |= BIT_SUB_TC; SRCPND |= BIT_ADC; INTPND |= BIT_ADC; }
static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) { switch (req) { case PM_SUSPEND: tsEvent = tsEvent_dummy; break; case PM_RESUME: tsEvent = tsEvent_raw; wait_down_int(); break; } return 0; }
static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg) { #if 0 DPRINTK("Occured Touch Screen Interrupt\n"); DPRINTK("SUBSRCPND = 0x%08lx\n", SUBSRCPND); #endif spin_lock_irq(&(tsdev.lock)); if (tsdev.penStatus == PEN_UP) { start_ts_adc(); } else { tsdev.penStatus = PEN_UP; DPRINTK("PEN UP: x: %08d, y: %08d\n", x, y); wait_down_int(); tsEvent(); } spin_unlock_irq(&(tsdev.lock)); }
/* * INT_ADC的中断服务程序 * A/D转换结束时发生此中断 * 先读取X、Y坐标值,再进入等待中断模式 */ static void Isr_Adc(void) { // 打印X、Y坐标值 printf("xdata = %4d, ydata = %4d\r\n", (int)(ADCDAT0 & 0x3ff), (int)(ADCDAT1 & 0x3ff)); /* 判断是S3C2410还是S3C2440 */ if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002)) { // S3C2410 wait_down_int(); /* 进入"等待中断模式",等待触摸屏被松开 */ } else { // S3C2440 wait_up_int(); /* 进入"等待中断模式",等待触摸屏被松开 */ } // 清INT_ADC中断 SUBSRCPND |= BIT_SUB_ADC; SRCPND |= BIT_ADC; INTPND |= BIT_ADC; }
static int __init s3c2410_ts_init(void) { int ret; tsEvent = tsEvent_dummy; ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops); if (ret < 0) { printk(DEVICE_NAME " can't get major number\n"); return ret; } tsMajor = ret; /* set gpio to XP, YM, YP and YM */ #if 0 set_GPIO_mode(GPIO106_nYPON_MD); set_GPIO_mode(GPIO105_YMON_MD); set_GPIO_mode(GPIO104_nXPON_MD); set_GPIO_mode(GPIO103_XMON_MD); GPUP(GPIO106_nYPON) |= GPIO_bit(GPIO106_nYPON); GPUP(GPIO105_YMON) &= GPIO_bit(GPIO105_YMON); GPUP(GPIO104_nXPON) |= GPIO_bit(GPIO104_nXPON); GPUP(GPIO103_XMON) &= GPIO_bit(GPIO103_XMON); #else set_gpio_ctrl(GPIO_YPON); set_gpio_ctrl(GPIO_YMON); set_gpio_ctrl(GPIO_XPON); set_gpio_ctrl(GPIO_XMON); #endif /* Enable touch interrupt */ ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT, DEVICE_NAME, s3c2410_isr_adc); if (ret) goto adc_failed; ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT, DEVICE_NAME, s3c2410_isr_tc); if (ret) goto tc_failed; /* Wait for touch screen interrupts */ wait_down_int(); #ifdef CONFIG_DEVFS_FS devfs_ts_dir = devfs_mk_dir(NULL, "touchscreen", NULL); devfs_tsraw = devfs_register(devfs_ts_dir, "0raw", DEVFS_FL_DEFAULT, tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &s3c2410_fops, NULL); #endif #ifdef CONFIG_PM #if 0 tsdev.pm_dev = pm_register(PM_GP_DEV, PM_USER_INPUT, s3c2410_ts_pm_callback); #endif tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT, s3c2410_ts_pm_callback); #endif printk(DEVICE_NAME " initialized\n"); return 0; tc_failed: free_irq(IRQ_ADC_DONE, s3c2410_isr_adc); adc_failed: return ret; }