static int ct363_init(struct ct36x_data *ts) { int ret = 0, fwchksum, binchksum, updcnt = 5; struct ct363_priv *ct363 = NULL; ret = ct363_init_hw(ts); if(ret < 0) return ret; /* Hardware reset */ ct363_reset_hw(ts); // Get binary Checksum binchksum = ct36x_chip_get_binchksum(); ct36x_dbg(ts, "CT363 init: binchksum = %d\n", binchksum); ret = ct36x_chip_get_fwchksum(ts); if(ret < 0){ dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n"); return ret; } fwchksum = ret; ct36x_dbg(ts, "CT363 init: fwchksum = %d\n", fwchksum); while(binchksum != fwchksum && updcnt--) { /* Update Firmware */ ret = ct36x_chip_go_bootloader(ts); if(ret < 0){ dev_err(ts->dev, "CT36X chip: Failed to go bootloader\n"); return ret; } /* Hardware reset */ ct363_reset_hw(ts); ret = ct36x_chip_get_fwchksum(ts); if(ret < 0){ dev_err(ts->dev, "CT36X chip: Failed to get fwchksum\n"); return ret; } fwchksum = ret; ct36x_dbg(ts, "CT363 update FW: fwchksum = %d\n", fwchksum); } if(binchksum != fwchksum){ dev_err(ts->dev, "Fail to update FW\n"); return -ENODEV; } /* Hardware reset */ ct363_reset_hw(ts); msleep(5); ts->point_num = CT363_POINT_NUM; ct363 = kzalloc(sizeof(struct ct363_priv), GFP_KERNEL); if(!ct363){ dev_err(ts->dev, "No memory for ct36x"); return -ENOMEM; } ts->priv = ct363; return 0; }
static void ct36x_ts_late_resume(struct early_suspend *h) { struct ct36x_data *ts = container_of(h, struct ct36x_data, early_suspend); ct36x_dbg(ts, "<%s> tochscreen resume\n", CT36X_NAME); if(ts->ops->resume) ts->ops->resume(ts); enable_irq(ts->irq); }
static void ct36x_ts_early_suspend(struct early_suspend *h) { struct ct36x_data *ts = container_of(h, struct ct36x_data, early_suspend); ct36x_dbg(ts, "<%s> touchscreen suspend\n", CT36X_NAME); disable_irq_nosync(ts->irq); if(ts->ops->suspend) ts->ops->suspend(ts); }
static irqreturn_t ct36x_irq_handler(int irq, void *data) { struct ct36x_data *ts = data; ct36x_dbg(ts, "----------- ct36x_irq_handler -----------\n"); //disable_irq(ts->irq); if(ts->ops->report) ts->ops->report(ts); //enable_irq(ts->irq); return IRQ_HANDLED; }
static void ct363_report(struct ct36x_data *ts) { int i, ret = 0; int sync = 0, x, y; int len = sizeof(struct ct363_finger_data) * ts->point_num; struct ct363_priv *ct363 = ts->priv; ret = ct36x_read(ts, ct363->buf, len); if(ret < 0){ dev_warn(ts->dev, "Failed to read finger data\n"); return; } int t ,m; if(ct36x_dbg_level==2) for(t=0;t< ts->point_num;t++){ ct36x_dbg(ts, "CT363buf[%d]: ", t); for(m=0;m<6;m++){ ct36x_dbg(ts, " 0x%x %x %x %x %x %x %x %x ",ct363->pts[t].xhi, ct363->pts[t].yhi, ct363->pts[t].ylo, ct363->pts[t].xlo, ct363->pts[t].status, ct363->pts[t].id, ct363->pts[t].area, ct363->pts[t].pressure); } ct36x_dbg(ts, " \n "); } ct363->press = 0; for(i = 0; i < ts->point_num; i++){ if((ct363->pts[i].xhi != 0xFF && ct363->pts[i].yhi != 0xFF) && (ct363->pts[i].status == 1 || ct363->pts[i].status == 2)){ x = (ct363->pts[i].xhi<<4)|(ct363->pts[i].xlo&0xF); y = (ct363->pts[i].yhi<<4)|(ct363->pts[i].ylo&0xF); ct363->x = ts->orientation[0] * x + ts->orientation[1] * y; ct363->y = ts->orientation[2] * x + ts->orientation[3] * y; if( (ct363->x > ts->x_max) || (ct363->y > ts->y_max) || (ct363->x < 0) || (ct363->y < 0) ){ continue ; } input_mt_slot(ts->input, ct363->pts[i].id - 1); input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 1); input_report_abs(ts->input, ABS_MT_POSITION_X, ct363->x); input_report_abs(ts->input, ABS_MT_POSITION_Y, 1200 - ct363->y); input_report_abs(ts->input, ABS_MT_PRESSURE, ct363->pts[i].pressure); ct36x_dbg(ts, "CT363 report value: id: %d, x: %d, y:%d\n",ct363->pts[i].id - 1, ct363->x, ct363->y); sync = 1; ct363->press |= 0x01 << (ct363->pts[i].id - 1); } } ct363->release &= ct363->release ^ ct363->press; for(i = 0; i < ts->point_num; i++){ if ( ct363->release & (0x01<<i) ) { input_mt_slot(ts->input, i); input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, false); ct36x_dbg(ts, "CT363 release\n"); sync = 1; } } ct363->release = ct363->press; if(sync) input_sync(ts->input); return; }