static int synaptics_ts_probe( struct i2c_client *client, const struct i2c_device_id *id) { struct synaptics_ts_data *ts; int ret = 0; struct vreg *vreg_touch; uint8_t i2c_addr = 0x1B; uint8_t buf_tmp[3]={0,}; HW_ver = 0; SW_ver = 0; printk("[TSP] %s, %d\n", __func__, __LINE__ ); vreg_touch = vreg_get(NULL, "ldo6"); ret = vreg_set_level(vreg_touch, OUT3000mV); if (ret) { printk(KERN_ERR "%s: vreg set level failed (%d)\n", __func__, ret); return -EIO; } ret = vreg_enable(vreg_touch); if (ret) { printk(KERN_ERR "%s: vreg enable failed (%d)\n", __func__, ret); return -EIO; } msleep(700); ts = kzalloc(sizeof(*ts), GFP_KERNEL); if (ts == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } INIT_WORK(&ts->work, synaptics_ts_work_func); INIT_DELAYED_WORK(&ts->work_check_ic, check_ic_work_func ); schedule_delayed_work(&ts->work_check_ic, CHECK_TIME ); ts->client = client; i2c_set_clientdata(client, ts); ts_global = ts; ts->input_dev = input_allocate_device(); if (ts->input_dev == NULL) { ret = -ENOMEM; touch_present = 0; printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } ts->input_dev->name = "sec_touchscreen"; set_bit(EV_SYN, ts->input_dev->evbit); set_bit(EV_KEY, ts->input_dev->evbit); set_bit(BTN_TOUCH, ts->input_dev->keybit); set_bit(EV_ABS, ts->input_dev->evbit); printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n"); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); //0, MAX_X, 0, 0 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); //0, MAX_Y, 0, 0 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); /* ts->input_dev->name = ts->keypad_info->name; */ ret = input_register_device(ts->input_dev); if (ret) { touch_present = 0; printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name); goto err_input_register_device_failed; } printk("[TSP] %s, irq=%d\n", __func__, client->irq ); if (client->irq) { ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts); if (ret == 0) ts->use_irq = 1; else dev_err(&client->dev, "request_irq failed\n"); } #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = synaptics_ts_early_suspend; ts->early_suspend.resume = synaptics_ts_late_resume; register_early_suspend(&ts->early_suspend); #endif printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); /* sys fs */ touch_class = class_create(THIS_MODULE, "touch"); if (IS_ERR(touch_class)) pr_err("Failed to create class(touch)!\n"); firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware"); if (IS_ERR(firmware_dev)) pr_err("Failed to create device(firmware)!\n"); if (device_create_file(firmware_dev, &dev_attr_firmware) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name); if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name); /* sys fs */ /* Check point - i2c check - start */ ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp)); HW_ver = buf_tmp[1]; SW_ver = buf_tmp[2]; if (ret <= 0) { printk(KERN_ERR "i2c_transfer failed\n"); ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp)); if (ret <= 0) { disable_irq(ts_global->client->irq); cancel_delayed_work_sync(&ts_global->work_check_ic); touch_present = 0; printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret); goto err_check_functionality_failed; } } /* Check point - i2c check - end */ printk("[TSP] %s, ver CY=%x\n", __func__ , buf_tmp[0] ); printk("[TSP] %s, ver HW=%x\n", __func__ , buf_tmp[1] ); printk("[TSP] %s, ver SW=%x\n", __func__ , buf_tmp[2] ); touch_present = 1; /* Check point - Firmware */ printk("[TSP] %s:%d, ver SW=%x, HW=%x\n", __func__, __LINE__, SW_ver, HW_ver); printk("[TSP] Here - Deleted Firmware Check Routine \n"); #if 0 switch( (HW_ver+1)/10 ){ case 0: //Degitech if(HW_ver < Digi_HEX_HW_VER){ //Firmware Update firm_update(); }else if((SW_ver<Digi_HEX_SW_VER)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){ printk("[TSP] firm_update START!!, ln=%d\n",__LINE__); firm_update(); }else{ printk("[TSP] Firmware Version(Digitech) is Up-to-date.\n"); }break; case 1: //SMAC if(HW_ver < SMAC_HEX_HW_VER){ //Firmware Update firm_update(); }else if((SW_ver<SMAC_HEX_SW_VER)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){ printk("[TSP] firm_update START!!, ln=%d\n",__LINE__); firm_update(); }else{ printk("[TSP] Firmware Version(SMAC) is Up-to-date.\n"); }break; case 2: ; // } #endif printk(KERN_INFO "synaptics_ts_probe: Manufacturer ID: %x, HW ver=%x, SW ver=%x\n", buf_tmp[0], buf_tmp[1], buf_tmp[2]); /* Check point - Firmware */ return 0; err_input_register_device_failed: input_free_device(ts->input_dev); err_input_dev_alloc_failed: kfree(ts); err_alloc_data_failed: err_check_functionality_failed: return ret; }
static void synaptics_ts_work_func(struct work_struct *work) #endif { int ret=0; uint8_t buf[12];// 02h ~ 0Dh uint8_t i2c_addr = 0x02; int i = 0; int finger = 0; #if USE_THREADED_IRQ struct synaptics_ts_data *ts = dev_id; #else struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); #endif ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__); goto work_func_out; } finger = buf[0] & 0x07; fingerInfo[0].x = (buf[1] << 8) |buf[2]; fingerInfo[0].y = (buf[3] << 8) |buf[4]; fingerInfo[0].z = buf[5]; fingerInfo[0].id = buf[6] >>4; fingerInfo[1].x = (buf[7] << 8) |buf[8]; fingerInfo[1].y = (buf[9] << 8) |buf[10]; fingerInfo[1].z = buf[11]; fingerInfo[1].id = buf[6] & 0xf; /*********************hash if ( board_hw_revision >= 0x2 && HW_ver==1 ) { fingerInfo[0].x = 240 - fingerInfo[0].x; fingerInfo[0].y = 320 - fingerInfo[0].y; fingerInfo[1].x = 240 - fingerInfo[1].x; fingerInfo[1].y = 320 - fingerInfo[1].y; // fingerInfo[0].x = 320 - fingerInfo[0].x; // fingerInfo[1].y = 480 - fingerInfo[1].y; } ************************/ // print message // for ( i= 0; i<MAX_USING_FINGER_NUM; i++ ) // printk("[TSP] finger[%d].x = %d, finger[%d].y = %d, finger[%d].z = %x, finger[%d].id = %x\n", i, fingerInfo[i].x, i, fingerInfo[i].y, i, fingerInfo[i].z, i, fingerInfo[i].id); /* check key event*/ // if(fingerInfo[0].status != 1 && fingerInfo[1].status != 1) // // process_key_event(buf[0]); //HASHTSK /* check touch event */ for ( i= 0; i<MAX_USING_FINGER_NUM; i++ ) { //////////////////////////////////////////////////IC if(fingerInfo[i].id >=1) { fingerInfo[i].status = 1; } else if(fingerInfo[i].id ==0 && fingerInfo[i].status == 1) { fingerInfo[i].status = 0; } else if(fingerInfo[i].id ==0 && fingerInfo[i].status == 0) { fingerInfo[i].status = -1; } if(fingerInfo[i].status == -1) continue; /////////////////////////////////////////////////IC input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[i].x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[i].y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, fingerInfo[i].id); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[i].z); input_mt_sync(ts->input_dev); #if defined(__TOUCH_DEBUG__) printk("[TSP] i[%d] id[%d] xyz[%d, %d, %x] status[%x]\n", i, fingerInfo[i].id, fingerInfo[i].x, fingerInfo[i].y, fingerInfo[i].z, fingerInfo[i].status); #endif } input_sync(ts->input_dev); work_func_out: if (ts->use_irq) { #if USE_THREADED_IRQ #else enable_irq(ts->client->irq); #endif } #if USE_THREADED_IRQ return IRQ_HANDLED; #else #endif }
static void synaptics_ts_work_func(struct work_struct *work) { int ret=0; uint8_t buf[12];// 02h ~ 0Dh uint8_t i2c_addr = 0x02; int i = 0; uint8_t finger = 0; struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__); goto work_func_out; } finger = buf[0] & 0x07; fingerInfo[0].x = (buf[1] << 8) |buf[2]; fingerInfo[0].y = (buf[3] << 8) |buf[4]; fingerInfo[0].z = buf[5]/2; fingerInfo[0].id = (buf[6] >>4)& 0x0f; fingerInfo[1].x = (buf[7] << 8) |buf[8]; fingerInfo[1].y = (buf[9] << 8) |buf[10]; fingerInfo[1].z = buf[11]/2; fingerInfo[1].id = buf[6] & 0x0f; /* check touch event */ for ( i= 0; i<MAX_USING_FINGER_NUM; i++ ) { if(fingerInfo[i].id >=1) // press interrupt { if(i==0 && fingerInfo[1].status != 1) { if((fingerInfo[2].id != fingerInfo[0].id)&&(fingerInfo[2].id != 0))// no release with finger id change { // if(fingerInfo[1].id ==0) { input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[2].x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[2].y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[2].z); input_mt_sync(ts->input_dev); input_sync(ts->input_dev); //printk("[TSP] [%d] 0 (%d, %d, %x)\n", i, fingerInfo[2].x, fingerInfo[2].y, fingerInfo[2].z); fingerInfo[1].status = -1; } } else if(fingerInfo[2].id != 0) // check x or y jump with same finger id { if(ABS(fingerInfo[2].x,fingerInfo[0].x)>150) { input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[2].x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[2].y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[2].z); input_mt_sync(ts->input_dev); input_sync(ts->input_dev); //printk("[TSP] [%d] 0 (%d, %d, %x)\n", i, fingerInfo[2].x, fingerInfo[2].y, fingerInfo[2].z); fingerInfo[1].status = -1; } else if(ABS(fingerInfo[2].y,fingerInfo[0].y)>150) { input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[2].x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[2].y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[2].z); input_mt_sync(ts->input_dev); input_sync(ts->input_dev); //printk("[TSP] [%d] 0 (%d, %d, %x)\n", i, fingerInfo[2].x, fingerInfo[2].y, fingerInfo[2].z); fingerInfo[1].status = -1; } else // no jump { if(fingerInfo[i].status != -2) // force release fingerInfo[i].status = 1; else fingerInfo[i].status = -2; } } else // single touch with normal condition { if(fingerInfo[i].status != -2) // force release fingerInfo[i].status = 1; else fingerInfo[i].status = -2; } } else { if(fingerInfo[i].status != -2) // force release fingerInfo[i].status = 1; else fingerInfo[i].status = -2; } } else if(fingerInfo[i].id ==0) // release interrupt (only first finger) { if(fingerInfo[i].status == 1 || fingerInfo[i].status == -3) // prev status is press fingerInfo[i].status = 0; else if(fingerInfo[i].status == 0 || fingerInfo[i].status == -2) // release already or force release fingerInfo[i].status = -1; } if(fingerInfo[i].status < 0) continue; input_report_abs(ts->input_dev, ABS_MT_POSITION_X, fingerInfo[i].x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, fingerInfo[i].y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, fingerInfo[i].status); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, fingerInfo[i].z); input_mt_sync(ts->input_dev); //printk("[TSP] [%d] %d (%d, %d, %x) %x\n", i, fingerInfo[i].id, fingerInfo[i].x, fingerInfo[i].y, fingerInfo[i].z, fingerInfo[i].status); } input_sync(ts->input_dev); fingerInfo[2].x = fingerInfo[0].x; fingerInfo[2].y = fingerInfo[0].y; fingerInfo[2].z = fingerInfo[0].z; fingerInfo[2].id = fingerInfo[0].id; work_func_out: if (ts->use_irq) { enable_irq(ts->client->irq); } }
static void synaptics_ts_work_func(struct work_struct *work) { int ret=0; uint8_t buf[11]; uint8_t i2c_addr = 0x02; uint16_t x=0; uint16_t y=0; uint16_t z=1; int finger = 0; uint8_t i2c_reg_info; uint8_t InputType =0 ; int v_touch_pressed=0; int press; #ifdef DEBUG_INPUT_REPORT static int prev_finger = 0; #endif struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); #if defined(__TOUCH_DEBUG__) printk("[TSP] %s\n", __func__ ); #endif ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__); goto work_func_out; } #if defined(__TOUCH_DEBUG__) printk("[TSP] buf[0]:%d, buf[1]:%d, buf[2]=%d, buf[3]=%d, buf[4]=%d, buf[5]=%d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); printk("[TSP] buf[6]:%d, buf[7]:%d, buf[8]=%d, buf[9]=%d, buf[10]=%d, buf[11]=%d\n", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]); #endif i2c_reg_info = buf[3]; x = buf[6]; y = buf[4]; if( i2c_reg_info == 1) /* 6bit mask , 1이면 256이 넘은것을 의미*/ y = y + 256; InputType = i2c_reg_info&0x01; v_touch_pressed = (InputType == 0x01) ? TRUE:FALSE; /*1 이면 pressed 0이면 released */ press = buf[5]; if(press) press= 1;//strength; else press = 0; input_report_abs(ts->input_dev, ABS_X, y); input_report_abs(ts->input_dev, ABS_Y, x); input_report_abs(ts->input_dev, ABS_PRESSURE, 1); input_report_key(ts->input_dev, BTN_TOUCH, press); input_sync(ts->input_dev); #if defined(__TOUCH_DEBUG__) printk("[TSP] x=%d, y=%d, press=%d\n", y, x, press ); #endif #ifdef DEBUG_INPUT_REPORT if ( finger ^ prev_finger ) { printk("[TSP] x=%d, y=%d\n", x, y ); prev_finger = finger; } #endif work_func_out: if (ts->use_irq) { #if defined(__TOUCH_DEBUG__) printk("[TSP] synaptics_ts_work_func==>enable_irq\n"); #endif enable_irq(ts->client->irq); } }
static int synaptics_ts_probe( struct i2c_client *client, const struct i2c_device_id *id) { struct synaptics_ts_data *ts; int ret = 0; uint8_t i2c_addr = 0x05; uint8_t buf[3]; int ret_temp=0; uint8_t buf_temp[3]; uint8_t i2c_addr_temp = 0x02; printk("[TSP] %s, %d\n", __func__, __LINE__ ); touch_ctrl_regulator(TOUCH_ON); msleep(100); ts = kzalloc(sizeof(*ts), GFP_KERNEL); if (ts == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } INIT_WORK(&ts->work, synaptics_ts_work_func); ts->client = client; i2c_set_clientdata(client, ts); ts_global = ts; /* Check point - i2c check - start */ ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk(KERN_ERR "i2c_transfer failed\n"); ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret); goto err_check_functionality_failed; } } /* Check point - i2c check - end */ ts->input_dev = input_allocate_device(); if (ts->input_dev == NULL) { ret = -ENOMEM; printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } ts->input_dev->name = "synaptics-rmi-touchscreen"; set_bit(EV_SYN, ts->input_dev->evbit); set_bit(EV_KEY, ts->input_dev->evbit); set_bit(BTN_TOUCH, ts->input_dev->keybit); set_bit(EV_ABS, ts->input_dev->evbit); printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n"); input_set_abs_params(ts->input_dev, ABS_X, 0, MAX_X, 0, 0); input_set_abs_params(ts->input_dev, ABS_Y, 0, MAX_Y, 0, 0); input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); /* ts->input_dev->name = ts->keypad_info->name; */ ret = input_register_device(ts->input_dev); if (ret) { printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name); goto err_input_register_device_failed; } printk("[TSP] %s, irq=%d\n", __func__, client->irq ); if (client->irq) { ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts); if (ret == 0) ts->use_irq = 1; else dev_err(&client->dev, "request_irq failed\n"); } // hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); // ts->timer.function = synaptics_ts_timer_func; #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = synaptics_ts_early_suspend; ts->early_suspend.resume = synaptics_ts_late_resume; register_early_suspend(&ts->early_suspend); #endif printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); /* sys fs */ touch_class = class_create(THIS_MODULE, "touch"); if (IS_ERR(touch_class)) pr_err("Failed to create class(touch)!\n"); firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware"); if (IS_ERR(firmware_dev)) pr_err("Failed to create device(firmware)!\n"); if (device_create_file(firmware_dev, &dev_attr_firmware) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name); if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name); /* sys fs */ /* Check point - Firmware */ printk("[TSP] %s, ver CY=%x\n", __func__ , buf[0] ); printk("[TSP] %s, ver HW=%x\n", __func__ , buf[1] ); printk("[TSP] %s, ver SW=%x\n", __func__ , buf[2] ); HW_ver = buf[1]; printk(KERN_INFO "synaptics_ts_probe: Manufacturer ID: %x, HW ver=%d\n", buf[0], HW_ver); /* Check point - Firmware */ ret_temp = tsp_i2c_read( i2c_addr_temp, buf_temp, sizeof(buf_temp)); if (ret_temp <= 0) { printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret_temp, __LINE__); goto err_check_functionality_failed; } return 0; err_input_register_device_failed: input_free_device(ts->input_dev); err_input_dev_alloc_failed: kfree(ts); err_alloc_data_failed: err_check_functionality_failed: return ret; }
/* firmware - update */ static ssize_t firmware_store( struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { char *after; uint8_t i2c_addr = 0x00; uint8_t buf_tmp[11] = {0}; unsigned long value = simple_strtoul(buf, &after, 10); printk(KERN_INFO "[TSP] %s, %d\n", __func__, __LINE__); firmware_ret_val = -1; tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp)); touch_vendor_id = buf_tmp[7]; touch_hw_ver = buf_tmp[8]; touch_sw_ver = buf_tmp[9]; printk("[TSP] %s:%d, ver tsp=%x, HW=%x, SW=%x\n", __func__,__LINE__, touch_vendor_id, touch_hw_ver, touch_sw_ver); HW_ver = touch_hw_ver; if ( value == 1 ) { printk("[TSP] Firmware update start!!\n" ); now_tst200_update_luisa = 1; firm_update( ); now_tst200_update_luisa = 0; #if FIRM_TEST printk("[TSP] start update cypress touch firmware !!\n"); g_FirmwareImageSize = CYPRESS_FIRMWARE_IMAGE_SIZE; if(g_pTouchFirmware == NULL) { printk("[TSP][ERROR] %s() kmalloc fail !! \n", __FUNCTION__); return -1; } /* ready for firmware code */ size = issp_request_firmware("touch.hex"); /* firmware update */ // issp_upgrade(); g_FirmwareImageSize = 0; // step.1 power off/on // step.2 enable irq #endif return size; } else if( value == 2 ) { printk("[TSP] Special Firmware update start!!\n" ); tsp_special_update = 1; now_tst200_update_luisa = 1; firm_update( ); now_tst200_update_luisa = 0; } return size; }
static int synaptics_ts_resume(struct i2c_client *client) { int ret; int key; struct vreg *vreg_touch; struct synaptics_ts_data *ts = i2c_get_clientdata(client); uint8_t i2c_addr = 0x1D; uint8_t buf[1]; printk("[TSP] %s+\n", __func__ ); gpio_set_value( TSP_SCL , 1 ); gpio_set_value( TSP_SDA , 1 ); gpio_set_value( TSP_INT , 1 ); vreg_touch = vreg_get(NULL, "maxldo06"); ret = vreg_enable(vreg_touch); if (ret) { printk(KERN_ERR "%s: vreg enable failed (%d)\n", __func__, ret); return -EIO; } #ifdef KEY_LED_CONTROL if(!touchkey_led_on_off) { ret = key_led_power_control(TRUE); if (ret < 0) { printk(KERN_ERR "%s: vreg enable failed (%d)\n",__func__, ret); return -EIO; } else { touchkey_led_on_off = 1; } } #endif msleep(200); // for TSK for(key = 0; key < MAX_KEYS; key++) touchkey_status[key] = TK_STATUS_RELEASE; while (ts->use_irq) { msleep(20); ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { // printk("[TSP] %d : i2c_transfer failed\n", __LINE__); } else if ( buf[0] == 0 ) { continue; } else { printk("[TSP] %s:%d, ver SW=%x\n", __func__,__LINE__, buf[0] ); enable_irq(client->irq); break; } msleep(20); } #ifdef TOUCH_VERIFY_WITH_TIMER if(board_hw_revision >= 0x3) { prev_wdog_val = -1; schedule_delayed_work(&ts->work_check_ic, CHECK_TIME ); } #endif printk("[TSP] %s-\n", __func__ ); return 0; }
static int synaptics_ts_probe( struct i2c_client *client, const struct i2c_device_id *id) { struct synaptics_ts_data *ts; int ret = 0; int key = 0; struct vreg *vreg_touch; uint8_t i2c_addr = 0x1B; uint8_t buf_tmp[3]={0,}; HW_ver = 0; SW_ver = 0; printk("[TSP] %s, %d\n", __func__, __LINE__ ); vreg_touch = vreg_get(NULL, "maxldo06"); ret = vreg_set_level(vreg_touch, OUT3000mV); if (ret) { printk(KERN_ERR "%s: vreg set level failed (%d)\n", __func__, ret); return -EIO; } ret = vreg_enable(vreg_touch); if (ret) { printk(KERN_ERR "%s: vreg enable failed (%d)\n", __func__, ret); return -EIO; } msleep(700); ts = kzalloc(sizeof(*ts), GFP_KERNEL); if (ts == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } INIT_WORK(&ts->work, synaptics_ts_work_func); #ifdef TOUCH_VERIFY_WITH_TIMER if(board_hw_revision >= 0x3) { INIT_DELAYED_WORK(&ts->work_check_ic, check_ic_work_func ); schedule_delayed_work(&ts->work_check_ic, CHECK_TIME ); } #endif ts->client = client; i2c_set_clientdata(client, ts); ts_global = ts; ts->input_dev = input_allocate_device(); if (ts->input_dev == NULL) { ret = -ENOMEM; printk(KERN_ERR "synaptics_ts_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } ts->input_dev->name = "synaptics-rmi-touchscreen"; set_bit(EV_SYN, ts->input_dev->evbit); set_bit(EV_KEY, ts->input_dev->evbit); set_bit(BTN_TOUCH, ts->input_dev->keybit); set_bit(EV_ABS, ts->input_dev->evbit); printk(KERN_INFO "synaptics_ts_probe: max_x: 240, max_y: 320\n"); input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, 0, MAX_X, 0, 0); //0, MAX_X, 0, 0 input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0); //0, MAX_Y, 0, 0 input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); for(key = 0; key < MAX_KEYS ; key++) input_set_capability(ts->input_dev, EV_KEY, touchkey_keycodes[key]); // for TSK for(key = 0; key < MAX_KEYS ; key++) touchkey_status[key] = TK_STATUS_RELEASE; /* ts->input_dev->name = ts->keypad_info->name; */ ret = input_register_device(ts->input_dev); if (ret) { printk(KERN_ERR "synaptics_ts_probe: Unable to register %s input device\n", ts->input_dev->name); goto err_input_register_device_failed; } printk("[TSP] %s, irq=%d\n", __func__, client->irq ); if (client->irq) { ret = request_irq(client->irq, synaptics_ts_irq_handler,/* IRQF_TRIGGER_RISING |*/ IRQF_TRIGGER_FALLING , client->name, ts); if (ret == 0) ts->use_irq = 1; else dev_err(&client->dev, "request_irq failed\n"); } #ifdef CONFIG_HAS_EARLYSUSPEND ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = synaptics_ts_early_suspend; ts->early_suspend.resume = synaptics_ts_late_resume; register_early_suspend(&ts->early_suspend); #endif printk(KERN_INFO "synaptics_ts_probe: Start touchscreen %s in %s mode\n", ts->input_dev->name, ts->use_irq ? "interrupt" : "polling"); /* sys fs */ touch_class = class_create(THIS_MODULE, "touch"); if (IS_ERR(touch_class)) pr_err("Failed to create class(touch)!\n"); firmware_dev = device_create(touch_class, NULL, 0, NULL, "firmware"); if (IS_ERR(firmware_dev)) pr_err("Failed to create device(firmware)!\n"); if (device_create_file(firmware_dev, &dev_attr_firmware) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_firmware.attr.name); if (device_create_file(firmware_dev, &dev_attr_firmware_ret) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_firmware_ret.attr.name); /* sys fs */ if(board_hw_revision >= 0x3) { msleep(400); } /* Check point - i2c check - start */ ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp)); HW_ver = buf_tmp[1]; SW_ver = buf_tmp[2]; if (ret <= 0) { printk(KERN_ERR "i2c_transfer failed\n"); ret = tsp_i2c_read( i2c_addr, buf_tmp, sizeof(buf_tmp)); #ifdef EMERGENCY_FIRMWARE_UPDATE emergency_firm_update(); #endif if (ret <= 0) { printk("[TSP] %s, ln:%d, Failed to register TSP!!!\n\tcheck the i2c line!!!, ret=%d\n", __func__,__LINE__, ret); goto err_check_functionality_failed; } } /* Check point - i2c check - end */ printk("[TSP] %s, ver CY=%x\n", __func__ , buf_tmp[0] ); printk("[TSP] %s, ver HW=%x\n", __func__ , buf_tmp[1] ); printk("[TSP] %s, ver SW=%x\n", __func__ , buf_tmp[2] ); /* Check point - Firmware */ printk("[TSP] %s: Board REV[%d], ver SW=%x, HW=%x\n", __func__, board_hw_revision, SW_ver, HW_ver ); if(((HW_ver <= HEX_HW_VER ) || ( HW_ver < HEX_HW_VER && HW_ver > 0 )) && (board_hw_revision < 0x3)) { if((SW_ver<HEX_SW_VER)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){ printk(KERN_INFO "[TSP] Firmware Update on REV01"); firm_update(); } else { printk(KERN_INFO "[TSP] Firmware version is up-to-date"); } } else if(((HW_ver <= HEX_HW_VER_REV03) || (HW_ver < HEX_HW_VER_REV03 && HW_ver>0)) && (board_hw_revision == 0x3)) { if((SW_ver < HEX_SW_VER_REV03)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){ printk(KERN_INFO "[TSP] Firmware Update on REV03"); firm_update(); }else{ printk(KERN_INFO "[TSP] Firmware version is up-to-date"); } } else if(((HW_ver <= HEX_HW_VER_REV04) || (HW_ver < HEX_HW_VER_REV04 && HW_ver>0)) && (board_hw_revision >= 0x4)) { if((SW_ver < HEX_SW_VER_REV04)||((SW_ver&0xF0)==0xF0)||(SW_ver==0)){ printk(KERN_INFO "[TSP] Firmware Update on REV06"); firm_update(); }else{ printk(KERN_INFO "[TSP] Firmware version is up-to-date"); } } printk(KERN_INFO "%s: Manufacturer ID: %x, HW ver=%x, SW ver=%x\n", __func__, buf_tmp[0], buf_tmp[1], buf_tmp[2]); #ifdef KEY_LED_CONTROL init_timer(&g_led_timer); g_led_timer.expires= (jiffies + (HZ*KEY_LED_ON_TIME)); g_led_timer.function = TouchKey_Led_TimerProc; add_timer(&g_led_timer); #endif return 0; err_input_register_device_failed: input_free_device(ts->input_dev); err_input_dev_alloc_failed: kfree(ts); err_alloc_data_failed: err_check_functionality_failed: return ret; }
static void synaptics_ts_work_func(struct work_struct *work) { int ret=0; // uint8_t buf[3]; uint8_t buf[5]; uint8_t temp; uint8_t i2c_addr = 0x02; uint16_t x=0; uint16_t y=0; uint16_t z=1; int finger = 0; static int prev_key = 0; static int curr_key = 0; static int key_report = 0; #ifdef DEBUG_INPUT_REPORT static int prev_finger = 0; #endif struct synaptics_ts_data *ts = container_of(work, struct synaptics_ts_data, work); ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk("[TSP] i2c failed : ret=%d, ln=%d\n",ret, __LINE__); goto work_func_out; } // x = buf[0]; // y = buf[1] & 0x0F; // y = (y << 8) | (buf[2] ); // finger = (buf[1] >> 7); x = buf[1]; //buf[0]; y = buf[2]; //buf[0]; if( buf[0] & 0x40 ) x += 256; finger = buf[0] & 0x01; input_report_abs(ts->input_dev, ABS_X, x); input_report_abs(ts->input_dev, ABS_Y, y); input_report_abs(ts->input_dev, ABS_PRESSURE, z); input_report_key(ts->input_dev, BTN_TOUCH, finger); input_sync(ts->input_dev); // printk("[TSP] buf[0]=%X, buf[1]=%X, buf[2]=%X, buf[3]=%X, buf[4]=%X\n", // buf[0], buf[1], buf[2], buf[3], buf[4] ); // printk("[TSP] temp=%X, key_report=%X, prev_key=%X\n", temp, key_report, prev_key ); // Processing Key Btn // 3 : MENU, 5 : HOME, 9 : PREV, 11 : SEARCH temp = buf[4]; if( temp ) { if( !key_report ) { key_report = 1; switch( temp ) { case 0x03 : //MENU prev_key = 1; #ifdef DEBUG_INPUT_REPORT printk("[TSP] MENU BTN Clicked!! \n" ); #endif input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1); break; case 0x05 : //HOME prev_key = 2; #ifdef DEBUG_INPUT_REPORT printk("[TSP] HOME BTN Clicked!! \n" ); #endif input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1); break; case 0x09 : //PREV prev_key = 3; #ifdef DEBUG_INPUT_REPORT printk("[TSP] PREV BTN Clicked!! \n" ); #endif input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1); break; case 0x11 : //SEARCH prev_key = 4; #ifdef DEBUG_INPUT_REPORT printk("[TSP] SEARCH BTN Clicked!! \n" ); #endif input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 1); break; } } } else if( prev_key ) { #ifdef DEBUG_INPUT_REPORT switch( prev_key ) { case 1 : //MENU printk("[TSP] MENU BTN Released!! \n" ); break; case 2 : //HOME printk("[TSP] HOME BTN Released!! \n" ); break; case 3 : //PREV printk("[TSP] PREV BTN Released!! \n" ); break; case 4 : //SEARCH printk("[TSP] SEARCH BTN Released!! \n" ); break; } #endif input_report_key(ts->input_dev, touchkey_keycodes[prev_key-1], 0); prev_key =0; key_report = 0; } /* // TSP 칩에서 터치키 눌러질때 터치이벤트도 동시에 올라가서 불필요한 처리가 되게 됨. // TSP 펌웨어에서 추가적으로 처리될때까지 임시 루틴을 사용하여 불필요한 터치 이벤트를 올리지 않도록 할 필요가 있음. // if( !key_report && !prev_key ) { key_report = 0; input_report_abs(ts->input_dev, ABS_X, x); input_report_abs(ts->input_dev, ABS_Y, y); input_report_abs(ts->input_dev, ABS_PRESSURE, z); input_report_key(ts->input_dev, BTN_TOUCH, finger); input_sync(ts->input_dev); } */ #ifdef DEBUG_INPUT_REPORT if ( finger ^ prev_finger ) { printk("[TSP] x=%d, y=%d\n", x, y ); prev_finger = finger; } #endif work_func_out: if (ts->use_irq) { enable_irq(ts->client->irq); } }
int tsp_reset( void ) { int ret=1; #if 0 uint8_t i2c_addr = 0x07; uint8_t buf[1]; #endif struct vreg *vreg_touch; printk("[TSP] %s+\n", __func__ ); vreg_touch = vreg_get(NULL, "ldo6"); if (ts_global->use_irq) { disable_irq(ts_global->client->irq); } ret = vreg_disable(vreg_touch); if (ret) { printk(KERN_ERR "%s: vreg enable failed (%d)\n", __func__, ret); ret=-EIO; goto tsp_reset_out; } gpio_configure( TSP_SCL, GPIOF_DRIVE_OUTPUT ); gpio_configure( TSP_SDA, GPIOF_DRIVE_OUTPUT ); gpio_configure( TSP_INT, GPIOF_INPUT ); #if 0 gpio_tlmm_config(GPIO_CFG( TSP_SCL, 0, GPIO_OUTPUT, GPIO_PULL_UP,GPIO_2MA), GPIO_ENABLE); gpio_tlmm_config(GPIO_CFG( TSP_SDA, 0, GPIO_OUTPUT, GPIO_PULL_UP,GPIO_2MA), GPIO_ENABLE); gpio_tlmm_config(GPIO_CFG( TSP_INT, 0, GPIO_OUTPUT, GPIO_PULL_UP,GPIO_2MA), GPIO_ENABLE); #endif gpio_set_value( TSP_SCL , 0 ); gpio_set_value( TSP_SDA , 0 ); gpio_set_value( TSP_INT , 0 ); msleep( 5 ); gpio_set_value( TSP_SCL , 1 ); gpio_set_value( TSP_SDA , 1 ); gpio_set_value( TSP_INT , 1 ); ret = vreg_enable(vreg_touch); if (ret) { printk(KERN_ERR "%s: vreg enable failed (%d)\n", __func__, ret); ret=-EIO; goto tsp_reset_out; } msleep(10); #if 0 while (ts_global->use_irq) { msleep(10); ret = tsp_i2c_read( i2c_addr, buf, sizeof(buf)); if (ret <= 0) { printk("[TSP] %d : i2c_transfer failed\n", __LINE__); } else { printk("[TSP] %s:%d, ver SW=%x\n", __func__,__LINE__, buf[0] ); ret=1; break; } } #endif tsp_reset_out: if (ts_global->use_irq) { enable_irq(ts_global->client->irq); } printk("[TSP] %s-\n", __func__ ); return ret; }