void irq_adc(void) { if ((ADCDAT0 & (1<<15)) == 0) /* 触摸笔仍然处于按下状态 */ { /* 如果是x坐标, 记录下来, 启动Y坐标的ADC */ if ((ADCTSC & 0x3) == 1) { x = ADCDAT0 & 0xfff; /* 清中断 */ ADCCLRINT = 0; enter_to_measure_y(); start_adc(); } else if ((ADCTSC & 0x3) == 2) { /* 如果是Y坐标, 记录下来, wait_for_pen_up */ y = ADCDAT1 & 0xfff; /* 清中断 */ ADCCLRINT = 0; wait_for_pen_up(); has_get_xy = 1; //printf("[x,y] = [%d, %d]\n\r", x, y); } } else { /* 在ADC期间, 触摸笔已经松开了 */ wait_for_pen_down(); } }
static irqreturn_t pen_down_up_isr(int irq, void *dev_ids) { unsigned long data0, data1; int down; data0 = ts_regs->adcdat0; data1 = ts_regs->adcdat1; down = (!(data0 & (1<<15))) && (!(data1 & (1<<15))); if (!down) { printk("pen_down_up_isr: up\n"); wait_for_pen_down(); } else { printk("pen_down_up_isr: down\n"); //wait_for_pen_up(); enter_to_measure_xy(); //enter_to_measure_x(); start_adc(); } /* clear interrupt */ //ts_regs->adcupdn = 0 ; ts_regs->adcclrintpndnup = 0; ts_regs->adcclrint = 0 ; return IRQ_HANDLED; }
void ts_init(void) { /* 一般的设置:比如时钟 */ ADCCON &= ~((0xff << 6) | (1<<2)); /* 12-bit A/D conversion, bit16 * A/D converter prescaler enable, bit14 * A/D converter prescaler value = 13, ADC CLK = 66.5MHz/(255+1)=4.75MHz, bit[13:6] */ ADCCON |= (1<<16) | (1<<14) | (255<<6); ADCDLY = 0xffff; /* 中断设置 */ ts_irq_init(); wait_for_pen_down(); }
void irq_pen_down_up(void) { if (ADCDAT0 & (1<<15)) { //printf("pen up\n\r"); //ADCTSC &= ~(1<<8); /* Detect Stylus Down Interrupt Signal. */ wait_for_pen_down(); } else { //printf("pen down\n\r"); //wait_for_pen_up(); enter_to_measure_x(); start_adc(); } ADCUPDN = 0; ADCCLRINTPNDNUP = 0; }
static void ts_timer_function(unsigned long data) { unsigned long data0, data1; int down; data0 = ts_regs->adcdat0; data1 = ts_regs->adcdat1; down = (!(data0 & (1<<15))) && (!(data1 & (1<<15))); if (down) { if (cnt == 4) { // report input_report_abs(ts_dev, ABS_X, x); input_report_abs(ts_dev, ABS_Y, y); input_report_key(ts_dev, BTN_TOUCH, 1); input_report_abs(ts_dev, ABS_PRESSURE, 1); input_sync(ts_dev); x = y = cnt = 0; mod_timer(&ts_timer, jiffies + HZ * 10 / 1000); } else { enter_to_measure_xy(); start_adc(); } } else { input_report_key(ts_dev, BTN_TOUCH, 0); input_report_abs(ts_dev, ABS_PRESSURE, 0); input_sync(ts_dev); x = y = cnt = 0; wait_for_pen_down(); } }
void s3c_ts_hardware_setup(void) { struct clk *ts_clk = clk_get(NULL, "adc"); clk_enable(ts_clk); /* clock */ ts_regs->adccon &= ~((0xff << 6) | (1<<2)); /* 12-bit A/D conversion, bit16 * A/D converter prescaler enable, bit14 * A/D converter prescaler value = 13, ADC CLK = 66.5MHz/(255+1)=4.75MHz, bit[13:6] */ ts_regs->adccon |= (1<<16) | (1<<14) | (255<<6); ts_regs->adcdly = 0xffff; request_irq(IRQ_TC, pen_down_up_isr, 0, "ts_tc", 1); request_irq(IRQ_ADC, adc_isr, 0, "ts_adc", 1); wait_for_pen_down(); }