static int AMI304_Report_Value(int en_dis) { struct ami304_i2c_data *data = i2c_get_clientdata(ami304_i2c_client); char report_enable = 0; if( !en_dis ) return 0; if(atomic_read(&o_status)) { input_report_abs(data->input_dev, ABS_RX, ami304mid_data.yaw); /* yaw */ input_report_abs(data->input_dev, ABS_RY, ami304mid_data.pitch);/* pitch */ input_report_abs(data->input_dev, ABS_RZ, ami304mid_data.roll);/* roll */ input_report_abs(data->input_dev, ABS_RUDDER, ami304mid_data.mag_status);/* status of orientation sensor */ report_enable = 1; } if(atomic_read(&a_status)) { input_report_abs(data->input_dev, ABS_X, ami304mid_data.nax);/* x-axis raw acceleration */ input_report_abs(data->input_dev, ABS_Y, ami304mid_data.nay);/* y-axis raw acceleration */ input_report_abs(data->input_dev, ABS_Z, ami304mid_data.naz);/* z-axis raw acceleration */ report_enable = 1; } if(atomic_read(&m_status)) { input_report_abs(data->input_dev, ABS_HAT0X, ami304mid_data.nmx); /* x-axis of raw magnetic vector */ input_report_abs(data->input_dev, ABS_HAT0Y, ami304mid_data.nmy); /* y-axis of raw magnetic vector */ input_report_abs(data->input_dev, ABS_BRAKE, ami304mid_data.nmz); /* z-axis of raw magnetic vector */ input_report_abs(data->input_dev, ABS_WHEEL, ami304mid_data.mag_status);/* status of magnetic sensor */ report_enable = 1; } if (AMI304_DEBUG_DEV_DEBOUNCE & ami304_debug_mask) { AMID("yaw: %d, pitch: %d, roll: %d\n", ami304mid_data.yaw, ami304mid_data.pitch, ami304mid_data.roll); AMID("nax: %d, nay: %d, naz: %d\n", ami304mid_data.nax, ami304mid_data.nay, ami304mid_data.naz); AMID("nmx: %d, nmy: %d, nmz: %d\n", ami304mid_data.nmx, ami304mid_data.nmy, ami304mid_data.nmz); AMID("mag_status: %d\n", ami304mid_data.mag_status); } if(report_enable) input_sync(data->input_dev); return 0; }
static void gtco_urb_callback(struct urb *urbinfo) { struct gtco *device = urbinfo->context; struct input_dev *inputdev; int rc; u32 val = 0; s8 valsigned = 0; char le_buffer[2]; inputdev = device->inputdevice; if (urbinfo->status == -ECONNRESET || urbinfo->status == -ENOENT || urbinfo->status == -ESHUTDOWN) { return; } if (urbinfo->status != 0) { goto resubmit; } if (inputdev->id.product == PID_1000 || inputdev->id.product == PID_1001 || inputdev->id.product == PID_1002) { switch (device->buffer[0]) { case 5: val = ((u16)(device->buffer[8]) << 1); val |= (u16)(device->buffer[7] >> 7); input_report_abs(inputdev, ABS_PRESSURE, device->buffer[8]); device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); case 4: if (device->buffer[6] & 0x40) device->buffer[6] |= 0x80; if (device->buffer[7] & 0x40) device->buffer[7] |= 0x80; valsigned = (device->buffer[6]); input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned); valsigned = (device->buffer[7]); input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); case 2: case 3: val = (device->buffer[5]) & MASK_BUTTON; input_event(inputdev, EV_MSC, MSC_SERIAL, val); case 1: val = get_unaligned_le16(&device->buffer[1]); input_report_abs(inputdev, ABS_X, val); val = get_unaligned_le16(&device->buffer[3]); input_report_abs(inputdev, ABS_Y, val); val = device->buffer[5] & MASK_INRANGE ? 1 : 0; input_report_abs(inputdev, ABS_DISTANCE, val); if (device->buffer[0] == 1) { val = device->buffer[5] & MASK_BUTTON; dbg("======>>>>>>REPORT 1: val 0x%X(%d)", val, val); input_event(inputdev, EV_MSC, MSC_SERIAL, val); } break; case 7: input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); break; } } if (inputdev->id.product == PID_400 || inputdev->id.product == PID_401) { if (device->buffer[0] == 2) { input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); } if (device->buffer[0] == 1) { char buttonbyte; if (device->max_X > 0x10000) { val = (u16)(((u16)(device->buffer[2] << 8)) | (u8)device->buffer[1]); val |= (u32)(((u8)device->buffer[3] & 0x1) << 16); input_report_abs(inputdev, ABS_X, val); le_buffer[0] = (u8)((u8)(device->buffer[3]) >> 1); le_buffer[0] |= (u8)((device->buffer[3] & 0x1) << 7); le_buffer[1] = (u8)(device->buffer[4] >> 1); le_buffer[1] |= (u8)((device->buffer[5] & 0x1) << 7); val = get_unaligned_le16(le_buffer); input_report_abs(inputdev, ABS_Y, val); buttonbyte = device->buffer[5] >> 1; } else {
int thread_fn() { if(enable_update == 1){ // ksocket things struct timeval start, stop; struct sockaddr_in addr_srv; int char_size = 21,rate = 50, recv_size,ctr = 0,thresh=1000; unsigned long cnt=0; char buf[char_size], *tmp, bufs[24]; char extra[10]; int addr_len,len,ax,ay,az,count,axs,ays,azs; unsigned long elapsed; //float adx, ady, adz; enable_count++; #ifdef KSOCKET_ADDR_SAFE mm_segment_t old_fs; old_fs = get_fs(); set_fs(KERNEL_DS); #endif sprintf(current->comm, "ksockThrd"); /**buf = "Hello!";*/ memset(&addr_srv, 0, sizeof(addr_srv)); addr_srv.sin_family = AF_INET; addr_srv.sin_port = htons(port); addr_srv.sin_addr.s_addr = inet_addr("152.14.93.160"); addr_len = sizeof(struct sockaddr_in); // Connect the socket ca->sockfd_globl = ksocket(AF_INET, SOCK_STREAM, 0); if (debug==1) printk("sockfd_cli = 0x%p\n", ca->sockfd_globl); if (ca->sockfd_globl == NULL){ printk("socket failed\n"); return -1; } if (kconnect(ca->sockfd_globl, (struct sockaddr*)&addr_srv, addr_len) < 0){ printk("connect failed\n"); return -1; } tmp = inet_ntoa(addr_srv.sin_addr); if (debug==1) printk("connected to : %s %d\n", tmp, ntohs(addr_srv.sin_port)); kfree(tmp); rate = ca->rate; len = sprintf(bufs, "%s%d%s%d", "03,ON,",10,",",10); if (debug==1) printk("Sending: %s\n",bufs); ksend(ca->sockfd_globl, bufs, len, 0); memset(bufs,'\0',sizeof(bufs)); ctr = thresh; do_gettimeofday(&start); while(1){ if(enable_update == 0){ if (debug==1){ printk(KERN_INFO "thread1 break\n"); printk(KERN_ALERT "Closing accl socket now!\n\n"); } //kclose(sockfd_cli); kclose(ca->sockfd_globl); #ifdef KSOCKET_ADDR_SAFE set_fs(old_fs); #endif break; } memset(buf,'\0',sizeof(buf)); //printk("1.buf:%s",buf); if((recv_size = krecv(ca->sockfd_globl, buf, char_size, 0))>0){ //printk("buf:%s",buf); //printk("bufs:%s\n",bufs); count = sscanf(buf, "%d,%d,%d,%d,%d,%d!%s",&ax,&axs,&ay,&ays,&az,&azs,extra); //printk("recv_size:%d, count: %d\n",recv_size,count); //printk("ax:%d, axs:%d, ay:%d,ays:%d, az:%d, azs:%d, extra: %s\n", ax,axs,ay,ays,az,azs,extra); //Apply logic for sign if(axs==1) ax *= -1; if(ays==1) ay *= -1; if(azs==1) az *= -1; input_report_abs(cloudaccl_input_dev, ABS_X, ax); input_report_abs(cloudaccl_input_dev, ABS_Y, ay); input_report_abs(cloudaccl_input_dev, ABS_Z, az); input_sync(cloudaccl_input_dev); accx = ax; accy = ay; accz = az; ctr--; cnt++; //printk(KERN_ALERT "Reported(%d)::ax:%d,ay:%d,az:%d\n", cnt,ax,ay,az); if (ctr==0){ ctr=thresh; do_gettimeofday(&stop); elapsed = (stop.tv_sec-start.tv_sec)*1000000 + stop.tv_usec-start.tv_usec; printk("Reported(%ld)::ax:%d,ay:%d,az:%d\n", cnt,ax,ay,az); printk(KERN_ALERT "L:%d,%ld,%ld\n", enable_count,cnt,elapsed); do_gettimeofday(&start); } } //schedule(); } } return 0; }
static inline int bma250_report_data(struct driver_data *dd) { int rc = 0; u8 rx_buf[8]; char bypass = 0; int retrycount = 0; struct bma250_accel_data data; struct bma250_platform_data *pdata = dd->ic_dev->dev.platform_data; read_data_start: if (slave_hw) pdata->bypass_state(READ_BYPASS_STATE, &bypass); if (!slave_hw || !bypass) { /* Bypass mode */ FIFO_ACCESS_MUTEX_LOCK(); rc = bma250_ic_read(dd->ic_dev, BMA250_X_AXIS_LSB_REG, rx_buf, 7); FIFO_ACCESS_MUTEX_UNLOCK(); if (rc) { if (retrycount > BMA250_READDATA_RETRY) goto report_error; else { retrycount++; msleep(BMA250_BYPASS_STABEL); goto read_data_start; } } /* 10bit signed to 16bit signed */ data.accel_x = ((rx_buf[1] << 8) | (rx_buf[0] & 0xC0)); data.accel_y = ((rx_buf[3] << 8) | (rx_buf[2] & 0xC0)); data.accel_z = ((rx_buf[5] << 8) | (rx_buf[4] & 0xC0)); /* sensitivty 0.5C, center temprature 24C */ data.temp = (signed char)rx_buf[6] + 24*2; } else { /* Master mode */ FIFO_ACCESS_MUTEX_LOCK(); rc = pdata->read_axis_data(dd->ic_dev, &rx_buf[0], 6); FIFO_ACCESS_MUTEX_UNLOCK(); if (rc) { if (retrycount > BMA250_READDATA_RETRY) goto report_error; else { retrycount++; msleep(BMA250_BYPASS_STABEL); goto read_data_start; } } /* 10bit signed to 16bit signed */ data.accel_x = ((rx_buf[1] << 8) | (rx_buf[0] & 0xC0)); data.accel_y = ((rx_buf[3] << 8) | (rx_buf[2] & 0xC0)); data.accel_z = ((rx_buf[5] << 8) | (rx_buf[4] & 0xC0)); /* set defaults value. */ data.temp = 32*2; } /* sensitivty 256lsb/g for all g-ranges */ data.accel_x = data.accel_x >> dd->shift; data.accel_y = data.accel_y >> dd->shift; data.accel_z = data.accel_z >> dd->shift; input_report_abs(dd->ip_dev, ABS_X, data.accel_x); input_report_abs(dd->ip_dev, ABS_Y, data.accel_y); input_report_abs(dd->ip_dev, ABS_Z, data.accel_z); input_report_abs(dd->ip_dev, ABS_MISC, data.temp); input_sync(dd->ip_dev); return rc; report_error: printk(KERN_ERR "%s: Data read error from register.\n", __func__); return rc; }
static void gs_work_func(struct work_struct *work) { int ret,i; struct gs_data *gs = container_of(work, struct gs_data, work); unsigned char dataX_low = 0; unsigned char dataX_high = 0; uint16 dataX = 0; unsigned char dataY_low = 0; unsigned char dataY_high = 0; uint16 dataY = 0; unsigned char dataZ_low = 0; unsigned char dataZ_high = 0; uint16 dataZ = 0; boolean data_is_err = 0; int x,y,z; uint8_t buf[6]; uint8_t start_reg; struct i2c_msg msg[2]; int sesc = accel_delay/1000; int nsesc = (accel_delay%1000)*1000000; msg[0].addr = gs->client->addr; msg[0].flags = 0; msg[0].len = 1; msg[0].buf = &start_reg; start_reg = 0x32; msg[1].addr = gs->client->addr; msg[1].flags = I2C_M_RD; msg[1].len = sizeof(buf); msg[1].buf = buf; #if 0 /************************************************************************** ADI345X#8451849PHIL of PP1 phone need set offset, but ADI345B can't set offset value, if set the value will work MMITest fail ***************************************************************************/ ret = gs_set_offset(); if (ret < 0) { printk(KERN_ERR "gs_set_offset faild\n"); /* fail? */ goto restart_timer; } #endif ret = reg_read(gs, GS_ADI_REG_INT_SOURCE); /* read IRQ STATUS */ if (ret < 0) { printk(KERN_ERR "i2c_smbus_read_int status_0X30 failed\n"); /* fail? */ goto restart_timer; } if((ret&0x20))//double tap { // printk(KERN_DEBUG"double tap\n"); } else if((ret&0x40))//sigle tap { // printk(KERN_DEBUG"sigle tap\n"); } else if((ret&0x80)) { //printk(KERN_DEBUG"data ready\n"); for (i = 0; i < 10; i++) { ret = i2c_transfer(gs->client->adapter, msg, 2); if (ret < 0) { printk(KERN_ERR "gs_ts_work_func: i2c_transfer failed\n"); data_is_err = 1; } else { data_is_err = 0; break; } } } else { printk(KERN_ERR"data err\n"); data_is_err = 1; } dataX_low = msg[1].buf[0]; dataX_high = msg[1].buf[1]; dataY_low = msg[1].buf[2]; dataY_high = msg[1].buf[3]; dataZ_low = msg[1].buf[4]; dataZ_high = msg[1].buf[5]; if(!data_is_err) { dataX = ((dataX_high&0x1f) <<8) |dataX_low; dataY = ((dataY_high&0x1f) <<8) |dataY_low; dataZ = ((dataZ_high&0x1f) <<8) |dataZ_low; if(dataX&0x1000)/*负值*/ { x=dataX -8192; /*13 bit is sign bit, */ } else { x = dataX; } if(dataY&0x1000)/*负值*/ { y=dataY - 8192; /*13 bit is sign bit, */ } else { y = dataY; } if(dataZ&0x1000)/*负值*/ { z =dataZ -8192; /*13 bit is sign bit, */ } else { z = dataZ; } /* change the x,y,z for u8300 because orientation of accelerometer of u8300 is different.*/ //if(machine_is_msm7x25_u8300()) { int x1,y1,z1; x1 = y * (-1); y1 = x * (-1); z1 = z * (-1); x = x1; y = y1; z = z1; } sensor_data[0] = (s16)x; sensor_data[1] = (s16)y; sensor_data[2] = (s16)z; x = (MG_PER_SAMPLE * (s16)x)/FILTER_SAMPLE_NUMBER; y = (MG_PER_SAMPLE * (s16)y)/FILTER_SAMPLE_NUMBER; z = (MG_PER_SAMPLE * (s16)z)/FILTER_SAMPLE_NUMBER; x *=(-1); input_report_abs(gs->input_dev, ABS_X, x); input_report_abs(gs->input_dev, ABS_Y, y); input_report_abs(gs->input_dev, ABS_Z, z); input_sync(gs->input_dev); } restart_timer: if (gs->use_irq) enable_irq(gs->client->irq); else hrtimer_start(&gs->timer, ktime_set(sesc, nsesc), HRTIMER_MODE_REL); }
static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; /* * Xbox 360 wireless controller will send many key events at * the same time when pairing is done. Ignore them since they * are unnecessary input events. */ if (xpad->xtype == XTYPE_XBOX360W && data[1] == 0xcc) return; /* digital pad */ if (xpad->dpad_mapping == MAP_DPAD_TO_AXES) { input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); } else if (xpad->dpad_mapping == MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (right, left, down, up) */ input_report_key(dev, BTN_LEFT, data[2] & 0x04); input_report_key(dev, BTN_RIGHT, data[2] & 0x08); input_report_key(dev, BTN_0, data[2] & 0x01); /* up */ input_report_key(dev, BTN_1, data[2] & 0x02); /* down */ } /* start/back buttons */ input_report_key(dev, BTN_START, data[2] & 0x10); input_report_key(dev, BTN_BACK, data[2] & 0x20); /* stick press left/right */ input_report_key(dev, BTN_THUMBL, data[2] & 0x40); input_report_key(dev, BTN_THUMBR, data[2] & 0x80); /* buttons A,B,X,Y,TL,TR and MODE */ input_report_key(dev, BTN_A, data[3] & 0x10); input_report_key(dev, BTN_B, data[3] & 0x20); input_report_key(dev, BTN_X, data[3] & 0x40); input_report_key(dev, BTN_Y, data[3] & 0x80); input_report_key(dev, BTN_TL, data[3] & 0x01); input_report_key(dev, BTN_TR, data[3] & 0x02); input_report_key(dev, BTN_MODE, data[3] & 0x04); /* left stick */ input_report_abs(dev, ABS_X, (__s16) le16_to_cpup((__le16 *)(data + 6))); input_report_abs(dev, ABS_Y, ~(__s16) le16_to_cpup((__le16 *)(data + 8))); /* right stick */ input_report_abs(dev, ABS_RX, (__s16) le16_to_cpup((__le16 *)(data + 10))); input_report_abs(dev, ABS_RY, ~(__s16) le16_to_cpup((__le16 *)(data + 12))); /* triggers left/right */ input_report_abs(dev, ABS_Z, data[4]); input_report_abs(dev, ABS_RZ, data[5]); input_sync(dev); }
/** * hdaps_set_power - enable or disable power to the accelerometer. * Returns zero on success and negative error code on failure. Can sleep. */ static int hdaps_set_power(int on) { struct thinkpad_ec_row args = { .mask = 0x0003, .val = {0x14, on?0x01:0x00} }; struct thinkpad_ec_row data = { .mask = 0x8000 }; int ret = thinkpad_ec_read_row(&args, &data); if (ret) return ret; if (data.val[0xF] != 0x00) return -EIO; return 0; } /** * hdaps_set_ec_config - set accelerometer parameters. * @ec_rate: embedded controller sampling rate * @order: embedded controller running average filter order * (Normally we have @ec_rate = sampling_rate * oversampling_ratio.) * Returns zero on success and negative error code on failure. Can sleep. */ static int hdaps_set_ec_config(int ec_rate, int order) { struct thinkpad_ec_row args = { .mask = 0x000F, .val = {0x10, (u8)ec_rate, (u8)(ec_rate>>8), order} }; struct thinkpad_ec_row data = { .mask = 0x8000 }; int ret = thinkpad_ec_read_row(&args, &data); printk(KERN_DEBUG "hdaps: setting ec_rate=%d, filter_order=%d\n", ec_rate, order); if (ret) return ret; if (data.val[0xF] == 0x03) { printk(KERN_WARNING "hdaps: config param out of range\n"); return -EINVAL; } if (data.val[0xF] == 0x06) { printk(KERN_WARNING "hdaps: config change already pending\n"); return -EBUSY; } if (data.val[0xF] != 0x00) { printk(KERN_WARNING "hdaps: config change error, ret=%d\n", data.val[0xF]); return -EIO; } return 0; } /** * hdaps_get_ec_config - get accelerometer parameters. * @ec_rate: embedded controller sampling rate * @order: embedded controller running average filter order * Returns zero on success and negative error code on failure. Can sleep. */ static int hdaps_get_ec_config(int *ec_rate, int *order) { const struct thinkpad_ec_row args = { .mask = 0x0003, .val = {0x17, 0x82} }; struct thinkpad_ec_row data = { .mask = 0x801F }; int ret = thinkpad_ec_read_row(&args, &data); if (ret) return ret; if (data.val[0xF] != 0x00) return -EIO; if (!(data.val[0x1] & 0x01)) return -ENXIO; /* accelerometer polling not enabled */ if (data.val[0x1] & 0x02) return -EBUSY; /* config change in progress, retry later */ *ec_rate = data.val[0x2] | ((int)(data.val[0x3]) << 8); *order = data.val[0x4]; return 0; } /** * hdaps_get_ec_mode - get EC accelerometer mode * Returns zero on success and negative error code on failure. Can sleep. */ static int hdaps_get_ec_mode(u8 *mode) { const struct thinkpad_ec_row args = { .mask = 0x0001, .val = {0x13} }; struct thinkpad_ec_row data = { .mask = 0x8002 }; int ret = thinkpad_ec_read_row(&args, &data); if (ret) return ret; if (data.val[0xF] != 0x00) { printk(KERN_WARNING "accelerometer not implemented (0x%02x)\n", data.val[0xF]); return -EIO; } *mode = data.val[0x1]; return 0; } /** * hdaps_check_ec - checks something about the EC. * Follows the clean-room spec for HDAPS; we don't know what it means. * Returns zero on success and negative error code on failure. Can sleep. */ static int hdaps_check_ec(void) { const struct thinkpad_ec_row args = { .mask = 0x0003, .val = {0x17, 0x81} }; struct thinkpad_ec_row data = { .mask = 0x800E }; int ret = thinkpad_ec_read_row(&args, &data); if (ret) return ret; if (!((data.val[0x1] == 0x00 && data.val[0x2] == 0x60) || /* cleanroom spec */ (data.val[0x1] == 0x01 && data.val[0x2] == 0x00)) || /* seen on T61 */ data.val[0x3] != 0x00 || data.val[0xF] != 0x00) { printk(KERN_WARNING "hdaps_check_ec: bad response (0x%x,0x%x,0x%x,0x%x)\n", data.val[0x1], data.val[0x2], data.val[0x3], data.val[0xF]); return -EIO; } return 0; } /** * hdaps_device_init - initialize the accelerometer. * * Call several embedded controller functions to test and initialize the * accelerometer. * Returns zero on success and negative error code on failure. Can sleep. */ #define FAILED_INIT(msg) printk(KERN_ERR "hdaps init failed at: %s\n", msg) static int hdaps_device_init(void) { int ret; u8 mode; ret = thinkpad_ec_lock(); if (ret) return ret; if (hdaps_get_ec_mode(&mode)) { FAILED_INIT("hdaps_get_ec_mode failed"); goto bad; } printk(KERN_DEBUG "hdaps: initial mode latch is 0x%02x\n", mode); if (mode == 0x00) { FAILED_INIT("accelerometer not available"); goto bad; } if (hdaps_check_ec()) { FAILED_INIT("hdaps_check_ec failed"); goto bad; } if (hdaps_set_power(1)) { FAILED_INIT("hdaps_set_power failed"); goto bad; } if (hdaps_set_ec_config(sampling_rate*oversampling_ratio, running_avg_filter_order)) { FAILED_INIT("hdaps_set_ec_config failed"); goto bad; } thinkpad_ec_invalidate(); udelay(200); /* Just prefetch instead of reading, to avoid ~1sec delay on load */ ret = thinkpad_ec_prefetch_row(&ec_accel_args); if (ret) { FAILED_INIT("initial prefetch failed"); goto bad; } goto good; bad: thinkpad_ec_invalidate(); ret = -ENXIO; good: stale_readout = 1; thinkpad_ec_unlock(); return ret; } /** * hdaps_device_shutdown - power off the accelerometer * Returns nonzero on failure. Can sleep. */ static int hdaps_device_shutdown(void) { int ret; ret = hdaps_set_power(0); if (ret) { printk(KERN_WARNING "hdaps: cannot power off\n"); return ret; } ret = hdaps_set_ec_config(0, 1); if (ret) printk(KERN_WARNING "hdaps: cannot stop EC sampling\n"); return ret; } /* Device model stuff */ static int hdaps_probe(struct platform_device *dev) { int ret; ret = hdaps_device_init(); if (ret) return ret; printk(KERN_INFO "hdaps: device successfully initialized.\n"); return 0; } static int hdaps_suspend(struct platform_device *dev, pm_message_t state) { /* Don't do hdaps polls until resume re-initializes the sensor. */ del_timer_sync(&hdaps_timer); hdaps_device_shutdown(); /* ignore errors, effect is negligible */ return 0; } static int hdaps_resume(struct platform_device *dev) { int ret = hdaps_device_init(); if (ret) return ret; mutex_lock(&hdaps_users_mtx); if (hdaps_users) mod_timer(&hdaps_timer, jiffies + HZ/sampling_rate); mutex_unlock(&hdaps_users_mtx); return 0; } static struct platform_driver hdaps_driver = { .probe = hdaps_probe, .suspend = hdaps_suspend, .resume = hdaps_resume, .driver = { .name = "hdaps", .owner = THIS_MODULE, }, }; /** * hdaps_calibrate - set our "resting" values. * Does its own locking. */ static void hdaps_calibrate(void) { needs_calibration = 1; hdaps_update(); /* If that fails, the mousedev poll will take care of things later. */ } /* Timer handler for updating the input device. Runs in softirq context, * so avoid lenghty or blocking operations. */ static void hdaps_mousedev_poll(unsigned long unused) { int ret; stale_readout = 1; /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ if (thinkpad_ec_try_lock()) goto keep_active; ret = __hdaps_update(1); /* fast update, we're in softirq context */ thinkpad_ec_unlock(); /* Any of "successful", "not yet ready" and "not prefetched"? */ if (ret != 0 && ret != -EBUSY && ret != -ENODATA) { printk(KERN_ERR "hdaps: poll failed, disabling updates\n"); return; } keep_active: /* Even if we failed now, pos_x,y may have been updated earlier: */ input_report_abs(hdaps_idev, ABS_X, pos_x - rest_x); input_report_abs(hdaps_idev, ABS_Y, pos_y - rest_y); input_sync(hdaps_idev); input_report_abs(hdaps_idev_raw, ABS_X, pos_x); input_report_abs(hdaps_idev_raw, ABS_Y, pos_y); input_sync(hdaps_idev_raw); mod_timer(&hdaps_timer, jiffies + HZ/sampling_rate); } /* Sysfs Files */ static ssize_t hdaps_position_show(struct device *dev, struct device_attribute *attr, char *buf) { int ret = hdaps_update(); if (ret) return ret; return sprintf(buf, "(%d,%d)\n", pos_x, pos_y); }
static ssize_t proximity_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cm36686_data *cm36686 = dev_get_drvdata(dev); bool new_value; if (sysfs_streq(buf, "1")) new_value = true; else if (sysfs_streq(buf, "0")) new_value = false; else { pr_err("%s: invalid value %d\n", __func__, *buf); return -EINVAL; } mutex_lock(&cm36686->power_lock); pr_info("%s, new_value = %d\n", __func__, new_value); if (new_value && !(cm36686->power_state & PROXIMITY_ENABLED)) { u8 val = 1; int i; int err = 0; cm36686->power_state |= PROXIMITY_ENABLED; if (cm36686->pdata->cm36686_led_on) { cm36686->pdata->cm36686_led_on(true); msleep(20); } #ifdef CM36686_CANCELATION /* open cancelation data */ err = proximity_open_cancelation(cm36686); if (err < 0 && err != -ENOENT) pr_err("%s: proximity_open_cancelation() failed\n", __func__); #endif /* enable settings */ for (i = 0; i < PS_REG_NUM; i++) { cm36686_i2c_write_word(cm36686, ps_reg_init_setting[i][REG_ADDR], ps_reg_init_setting[i][CMD]); } val = gpio_get_value(cm36686->pdata->irq); /* 0 is close, 1 is far */ input_report_abs(cm36686->proximity_input_dev, ABS_DISTANCE, val); input_sync(cm36686->proximity_input_dev); enable_irq(cm36686->irq); enable_irq_wake(cm36686->irq); } else if (!new_value && (cm36686->power_state & PROXIMITY_ENABLED)) { cm36686->power_state &= ~PROXIMITY_ENABLED; disable_irq_wake(cm36686->irq); disable_irq(cm36686->irq); /* disable settings */ cm36686_i2c_write_word(cm36686, REG_PS_CONF1, 0x0001); if (cm36686->pdata->cm36686_led_on) cm36686->pdata->cm36686_led_on(false); } mutex_unlock(&cm36686->power_lock); return size; }
static void ucb1400_ts_event_release(struct input_dev *idev) { input_report_abs(idev, ABS_PRESSURE, 0); input_report_key(idev, BTN_TOUCH, 0); input_sync(idev); }
static ssize_t proximity_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct gp2a_data *gp2a = dev_get_drvdata(dev); bool new_value; u8 value; int ret; #ifdef GP2AP002X_PROXIMITY_OFFSET int err; #endif if (sysfs_streq(buf, "1")) { new_value = true; } else if (sysfs_streq(buf, "0")) { new_value = false; } else { pr_err("%s: invalid value %d\n", __func__, *buf); return -EINVAL; } mutex_lock(&gp2a->power_lock); gp2a_dbgmsg("new_value = %d, old state = %d\n", new_value, (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0); #ifdef ALPS_DEBUG pr_info("[TMP] new_value = %d, old state = %d\n", new_value, (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0); #endif if (new_value && !(gp2a->power_state & PROXIMITY_ENABLED)) { pr_info("[TMP] %s, %d\n", __func__, __LINE__); #if defined(CONFIG_MACH_AMAZING_CDMA) LED_onoff(1); #endif #ifdef GP2AP002X_PROXIMITY_OFFSET err = gp2a_cal_mode_read_file(&gp2a->cal_mode); if (err < 0 && err != -ENOENT) pr_err("%s: cal_mode file read fail\n", __func__); pr_info("%s: mode = %02x\n", __func__, gp2a->cal_mode); if (gp2a->cal_mode == 2) { nondetect = PROX_NONDETECT_MODE2; detect = PROX_DETECT_MODE2; } else if (gp2a->cal_mode == 1) { nondetect = PROX_NONDETECT_MODE1; detect = PROX_DETECT_MODE1; } else { nondetect = PROX_NONDETECT; detect = PROX_DETECT; } #endif gp2a->val_state = 1; input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, gp2a->val_state); input_sync(gp2a->proximity_input_dev); gp2a->power_state |= PROXIMITY_ENABLED; gp2a->pdata->power(true); msleep(20); value = 0x18; gp2a_i2c_write(gp2a, REGS_CON, &value); #if defined(CONFIG_MACH_KYLE) value = 0x00; #else value = 0x08; #endif gp2a_i2c_write(gp2a, REGS_GAIN, &value); value = nondetect; gp2a_i2c_write(gp2a, REGS_HYS, &value); value = 0x04; gp2a_i2c_write(gp2a, REGS_CYCLE, &value); #if defined(CONFIG_MACH_GEIM) enable_irq_wake(gp2a->irq); #else enable_irq_wake(gp2a->irq); #endif value = 0x03; ret = gp2a_i2c_write(gp2a, REGS_OPMOD, &value); pr_info("%s: ret = %d\n", __func__, ret); enable_irq(gp2a->irq); value = 0x00; ret = gp2a_i2c_write(gp2a, REGS_CON, &value); pr_info("%s: ret = %d\n", __func__, ret); } else if (!new_value && (gp2a->power_state & PROXIMITY_ENABLED)) { pr_info("[TMP] %s, %d\n", __func__, __LINE__); #if defined(CONFIG_MACH_AMAZING_CDMA) LED_onoff(0); #endif #if defined(CONFIG_MACH_GEIM) disable_irq_wake(gp2a->irq); #else disable_irq_wake(gp2a->irq); #endif disable_irq(gp2a->irq); value = 0x02; gp2a_i2c_write(gp2a, REGS_OPMOD, &value); gp2a->power_state &= ~PROXIMITY_ENABLED; gp2a->pdata->power(false); } mutex_unlock(&gp2a->power_lock); return size; }
static int gp2a_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct input_dev *input_dev; struct gp2a_data *gp2a; struct gp2a_platform_data *pdata = client->dev.platform_data; pr_info("[TMP] %s, %d\n", __func__, __LINE__); nondetect = PROX_NONDETECT; detect = PROX_DETECT; /*#else if (board_hw_revision >= 0x07) { nondetect = PROX_REV_07_NONDETECT; detect = PROX_REV_07_DETECT; } else { nondetect = PROX_REV_06_NONDETECT; detect = PROX_REV_06_DETECT; } #endif*/ pr_info("%s: %02x %02x\n", __func__, nondetect, detect); if (!pdata) { pr_err("%s: missing pdata!\n", __func__); return ret; } if (!pdata->power) { pr_err("%s: incomplete pdata!\n", __func__); return ret; } /* power on gp2a */ pdata->power(true); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); return ret; } gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); if (!gp2a) { pr_err("%s: failed to alloc memory for module data\n", __func__); return -ENOMEM; } gp2a->pdata = pdata; gp2a->i2c_client = client; i2c_set_clientdata(client, gp2a); /* wake lock init */ wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); mutex_init(&gp2a->power_lock); /* allocate proximity input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); goto err_input_allocate_device_proximity; } input_dev->name = "proximity_sensor"; ret = input_register_device(input_dev); if (ret < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_allocate_device_proximity; } gp2a->proximity_input_dev = input_dev; input_set_drvdata(input_dev, gp2a); input_set_capability(input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_proximity; } /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func); ret = gp2a_setup_irq(gp2a); if (ret) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } ret = sensors_register(gp2a->proximity_dev, gp2a, proxi_attrs, "proximity_sensor"); if (ret < 0) { pr_info("%s: could not sensors_register\n", __func__); goto exit_gp2a_sensors_register; } #ifdef CONFIG_SENSOR_USE_SYMLINK ret = sensors_initialize_symlink(gp2a->proximity_input_dev); if (ret) { pr_err("%s: cound not make proximity sensor symlink(%d).\n", __func__, ret); goto exit_sensors_initialize_symlink; } #endif /* set initial proximity value as 1 */ input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1); input_sync(gp2a->proximity_input_dev); pr_info("[TMP] %s, %d\n", __func__, __LINE__); pdata->power(false); goto done; /* error, unwind it all */ #ifdef CONFIG_SENSOR_USE_SYMLINK exit_sensors_initialize_symlink: #endif exit_gp2a_sensors_register: free_irq(gp2a->irq, gp2a); gpio_free(gp2a->pdata->p_out); err_setup_irq: pr_info("err_setup_irq\n"); sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: pr_info("err_sysfs_create_group_proximity\n"); input_unregister_device(gp2a->proximity_input_dev); err_input_allocate_device_proximity: pr_info("err_input_allocate_device_proximity\n"); mutex_destroy(&gp2a->power_lock); wake_lock_destroy(&gp2a->prx_wake_lock); kfree(gp2a); done: pr_info("done\n"); return ret; }
int wacom_i2c_coord(struct wacom_i2c *wac_i2c) { bool prox = false; int ret = 0; u8 *data; int rubber, stylus; static u16 x, y, pressure; static u16 tmp; int rdy = 0; #ifdef WACOM_IRQ_WORK_AROUND cancel_delayed_work(&wac_i2c->pendct_dwork); #endif data = wac_i2c->wac_feature->data; ret = i2c_master_recv(wac_i2c->client, data, COM_COORD_NUM); if (ret < 0) { printk(KERN_ERR "[E-PEN] %s failed to read i2c.L%d\n", __func__, __LINE__); return -1; } #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) pr_debug("[E-PEN] %x, %x, %x, %x, %x, %x, %x\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6]); #endif if (data[0] & 0x80) { /* enable emr device */ if (!wac_i2c->pen_prox) { wac_i2c->pen_prox = 1; if (data[0] & 0x40) wac_i2c->tool = BTN_TOOL_RUBBER; else wac_i2c->tool = BTN_TOOL_PEN; #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) pr_debug("[E-PEN] is in(%d)\n", wac_i2c->tool); #endif } prox = !!(data[0] & 0x10); stylus = !!(data[0] & 0x20); rubber = !!(data[0] & 0x40); rdy = !!(data[0] & 0x80); x = ((u16) data[1] << 8) + (u16) data[2]; y = ((u16) data[3] << 8) + (u16) data[4]; pressure = ((u16) data[5] << 8) + (u16) data[6]; #ifdef WACOM_IMPORT_FW_ALGO /* Change Position to Active Area */ if (x <= origin_offset[0]) x = 0; else x = x - origin_offset[0]; if (y <= origin_offset[1]) y = 0; else y = y - origin_offset[1]; #ifdef COOR_WORK_AROUND wacom_i2c_coord_offset(&x, &y); wacom_i2c_coord_average(&x, &y, rdy); #endif #endif if (wac_i2c->wac_pdata->x_invert) x = wac_i2c->wac_feature->x_max - x; if (wac_i2c->wac_pdata->y_invert) y = wac_i2c->wac_feature->y_max - y; if (wac_i2c->wac_pdata->xy_switch) { tmp = x; x = y; y = tmp; } #ifdef COOR_WORK_AROUND /* Add offset */ x = x + tilt_offsetX[user_hand][screen_rotate]; y = y + tilt_offsetY[user_hand][screen_rotate]; #endif if (wacom_i2c_coord_range(&x, &y)) { input_report_abs(wac_i2c->input_dev, ABS_X, x); input_report_abs(wac_i2c->input_dev, ABS_Y, y); input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, pressure); input_report_key(wac_i2c->input_dev, BTN_STYLUS, stylus); input_report_key(wac_i2c->input_dev, BTN_TOUCH, prox); input_report_key(wac_i2c->input_dev, wac_i2c->tool, 1); input_sync(wac_i2c->input_dev); if (prox && !wac_i2c->pen_pressed) { #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK set_dvfs_lock(wac_i2c, true); #endif #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) printk(KERN_DEBUG "[E-PEN] is pressed(%d,%d,%d)(%d)\n", x, y, pressure, wac_i2c->tool); #else printk(KERN_DEBUG "[E-PEN] pressed\n"); #endif } else if (!prox && wac_i2c->pen_pressed) { #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK set_dvfs_lock(wac_i2c, false); #endif #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) printk(KERN_DEBUG "[E-PEN] is released(%d,%d,%d)(%d)\n", x, y, pressure, wac_i2c->tool); #else printk(KERN_DEBUG "[E-PEN] released\n"); #endif } wac_i2c->pen_pressed = prox; if (stylus && !wac_i2c->side_pressed) printk(KERN_DEBUG "[E-PEN] side on\n"); else if (!stylus && wac_i2c->side_pressed) printk(KERN_DEBUG "[E-PEN] side off\n"); wac_i2c->side_pressed = stylus; } #if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER) else printk(KERN_DEBUG "[E-PEN] raw data x=0x%x, y=0x%x\n", x, y); #endif } else { #ifdef WACOM_IRQ_WORK_AROUND if (!gpio_get_value(wac_i2c->wac_pdata->gpio_pendct)) { x = ((u16) data[1] << 8) + (u16) data[2]; y = ((u16) data[3] << 8) + (u16) data[4]; if (data[0] & 0x40) wac_i2c->tool = BTN_TOOL_RUBBER; else wac_i2c->tool = BTN_TOOL_PEN; input_report_abs(wac_i2c->input_dev, ABS_X, x); input_report_abs(wac_i2c->input_dev, ABS_Y, y); input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, 0); input_report_key(wac_i2c->input_dev, BTN_STYLUS, 0); input_report_key(wac_i2c->input_dev, BTN_TOUCH, 0); input_report_key(wac_i2c->input_dev, wac_i2c->tool, 1); input_sync(wac_i2c->input_dev); } schedule_delayed_work(&wac_i2c->pendct_dwork, HZ / 10); return 0; #else /* WACOM_IRQ_WORK_AROUND */ #ifdef COOR_WORK_AROUND /* enable emr device */ wacom_i2c_coord_average(0, 0, 0); #endif #ifdef WACOM_PDCT_WORK_AROUND if (wac_i2c->pen_pdct == PDCT_DETECT_PEN) forced_hover(wac_i2c); else #endif if (wac_i2c->pen_prox) { /* input_report_abs(wac->input_dev, ABS_X, x); */ /* input_report_abs(wac->input_dev, ABS_Y, y); */ input_report_abs(wac_i2c->input_dev, ABS_PRESSURE, 0); input_report_key(wac_i2c->input_dev, BTN_STYLUS, 0); input_report_key(wac_i2c->input_dev, BTN_TOUCH, 0); #if defined(WACOM_PDCT_WORK_AROUND) input_report_key(wac_i2c->input_dev, BTN_TOOL_RUBBER, 0); input_report_key(wac_i2c->input_dev, BTN_TOOL_PEN, 0); #else input_report_key(wac_i2c->input_dev, wac_i2c->tool, 0); #endif input_sync(wac_i2c->input_dev); printk(KERN_DEBUG "[E-PEN] is out"); } wac_i2c->pen_prox = 0; wac_i2c->pen_pressed = 0; wac_i2c->side_pressed = 0; #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK set_dvfs_lock(wac_i2c, false); #endif #endif } return 0; }
static void tm1726_send_event(struct tm1726 *tm) { struct input_dev *input = tm->input; u8 i, fingers, finger_state[MAX_FINGERS]; static int prev_touch = 0; static int curr_touch = 0; int event = 0; finger_state[0] = tm->reg_data[TM_FINGER_STATE1] & 0x03; finger_state[1] = (tm->reg_data[TM_FINGER_STATE1] & 0x0c) >> 2; finger_state[2] = (tm->reg_data[TM_FINGER_STATE1] & 0x30) >> 4; finger_state[3] = (tm->reg_data[TM_FINGER_STATE1] & 0xc0) >> 6; finger_state[4] = tm->reg_data[TM_FINGER_STATE2] & 0x03; curr_touch = 0; for (i = 0; i < MAX_FINGERS; i++) { if (finger_state[i] == 1 || finger_state[i] == 2) { curr_touch++; } } /* Button Pressed */ if (!prev_touch && curr_touch) { input_report_abs(input, BTN_TOUCH, curr_touch); TM1726_DEBUG("Finger Pressed\n"); } /* Button Released */ if (prev_touch && !curr_touch) { event = 1; input_report_abs(input, ABS_PRESSURE, 0); input_report_abs(input, BTN_TOUCH, 0); input_report_abs(input, ABS_MT_TOUCH_MAJOR, 0); input_mt_sync(input); TM1726_DEBUG("Finger Released\n\n\n"); } fingers = 0; for (i = 0; i < MAX_FINGERS; i++) { if (finger_state[i] == 1 || finger_state[i] == 2) { u8 xh, xl, yh, yl; u32 x, y; fingers++; xh = tm->reg_data[TM_X1_HIGH + 5 * i]; xl = tm->reg_data[TM_XY1_LOW + 5 * i] & 0x0f; yh = tm->reg_data[TM_Y1_HIGH + 5 * i]; yl = (tm->reg_data[TM_XY1_LOW + 5 * i] & 0xf0) >> 4; x = (xh << 4) | xl; y = (yh << 4) | yl; TM1726_DEBUG("Finger%d Raw: (%d, %d)\n", fingers, x, y); if (x < tm->fix.x_min) { x = tm->fix.x_min; } if (x > tm->fix.x_max) { x = tm->fix.x_max; } if (y < tm->fix.y_min) { y = tm->fix.y_min; } if (y > tm->fix.y_max) { y = tm->fix.y_max; } if (tm->fix.x_invert) { x = tm->fix.x_max - x + tm->fix.x_min; } if (tm->fix.y_invert) { y = tm->fix.y_max - y + tm->fix.y_min; } event = 1; if (fingers == 1) { input_report_abs(input, ABS_PRESSURE, MAX_Z); input_report_abs(input, ABS_X, x); input_report_abs(input, ABS_Y, y); } input_report_abs(input, ABS_MT_TOUCH_MAJOR, MAX_Z); input_report_abs(input, ABS_MT_POSITION_X, x); input_report_abs(input, ABS_MT_POSITION_Y, y); input_mt_sync(input); TM1726_DEBUG("Finger%d Calibrated: (%d, %d)\n", fingers, x, y); } }
static void hil_dev_handle_ptr_events(struct hil_dev *ptr) { struct input_dev *dev = ptr->dev; int idx = ptr->idx4 / 4; hil_packet p = ptr->data[idx - 1]; int i, cnt, laxis; bool absdev, ax16; if ((p & HIL_CMDCT_POL) != idx - 1) { // printk(KERN_WARNING PREFIX ; return; } i = (p & HIL_POL_AXIS_ALT) ? 3 : 0; laxis = (p & HIL_POL_NUM_AXES_MASK) + i; ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; for (cnt = 1; i < laxis; i++) { unsigned int lo, hi, val; lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK; hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0; if (absdev) { val = lo + (hi << 8); #ifdef TABLET_AUTOADJUST if (val < input_abs_get_min(dev, ABS_X + i)) input_abs_set_min(dev, ABS_X + i, val); if (val > input_abs_get_max(dev, ABS_X + i)) input_abs_set_max(dev, ABS_X + i, val); #endif if (i % 3) val = input_abs_get_max(dev, ABS_X + i) - val; input_report_abs(dev, ABS_X + i, val); } else { val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); if (i % 3) val *= -1; input_report_rel(dev, REL_X + i, val); } } while (cnt < idx - 1) { unsigned int btn = ptr->data[cnt++]; int up = btn & 1; btn &= 0xfe; if (btn == 0x8e) continue; /* TODO: proximity == touch? */ if (btn > 0x8c || btn < 0x80) continue; btn = (btn - 0x80) >> 1; btn = ptr->btnmap[btn]; input_report_key(dev, btn, !up); } input_sync(dev); }
/******************************************************* 功能: 触摸屏工作函数 由中断触发,接受1组坐标数据,校验后再分析输出 参数: ts: client私有数据结构体 return: 执行结果码,0表示正常执行 ********************************************************/ static void goodix_ts_work_func(struct work_struct *work) { static uint8_t finger_bit=0; //last time fingers' state struct point_data * p = NULL; uint8_t read_position = 0; uint8_t point_data[READ_BYTES_NUM]={ 0 }; uint8_t finger=0; //record which finger is changed uint8_t check_sum = 0; int ret = -1; int count = 0; struct goodix_ts_data *ts = container_of(work, struct goodix_ts_data, work); if (ts->use_shutdown && gpio_get_value(ts->gpio_shutdown)) goto NO_ACTION; //The data is invalid. //if i2c-transfer is failed, let it restart less than 10 times. FOR DEBUG. /* if( ts->retry > 9) { if(!ts->use_irq && (ts->timer.state != HRTIMER_STATE_INACTIVE)) hrtimer_cancel(&ts->timer); dev_info(&(ts->client->dev), "Because of transfer error, %s stop working.\n",s3c_ts_name); ts->bad_data = 1; return ; } */ ret=i2c_read_bytes(ts->client, point_data, sizeof(point_data)); if(ret <= 0) { dev_dbg(&(ts->client->dev),"I2C transfer error. ERROR Number:%d\n ", ret); ts->retry++; if(ts->power) { ts->power(ts, 0); ts->power(ts, 1); } else { goodix_init_panel(ts); msleep(260); } goto XFER_ERROR; } //如果能够保证在INT中断后及时的读取坐标数据,可以不进行校验 if(!ts->use_irq) { switch(point_data[1]& 0x1f) { case 0: break; case 1: for(count=1; count<8; count++) check_sum += (int)point_data[count]; read_position = 8; break; case 2: case 3: for(count=1; count<13;count++) check_sum += (int)point_data[count]; read_position = 13; break; default: //(point_data[1]& 0x1f) > 3 for(count=1; count<34;count++) check_sum += (int)point_data[count]; read_position = 34; } if(check_sum != point_data[read_position]) goto XFER_ERROR; } //The bits indicate which fingers pressed down point_data[1]&=0x1f; finger = finger_bit^point_data[1]; if(finger == 0 && point_data[1] == 0) goto NO_ACTION; //no fingers and no action else if(finger == 0) //the same as last time goto BIT_NO_CHANGE; //check which point(s) DOWN or UP analyse_points(&finger_list, finger_bit, finger); if(finger_list.head == NULL) goto NO_ACTION; else dev_dbg(&ts->client->dev, "fingers count:%d\n", finger_list.length); BIT_NO_CHANGE: for(p = finger_list.head; p != NULL; p = p->next) { if(p->state == FLAG_UP) { p->x = p->y = 0; p->pressure = 0; continue; } if(p->id < 3) read_position = p->id*5+3; else read_position = 29; if(p->id != 3) { p->x = (unsigned int) (point_data[read_position]<<8) + (unsigned int)( point_data[read_position+1]); p->y = (unsigned int)(point_data[read_position+2]<<8) + (unsigned int) (point_data[read_position+3]); p->pressure = point_data[read_position+4]; } #if MAX_FINGER_NUM > 3 else { p->x = (unsigned int) (point_data[18]<<8) + (unsigned int)( point_data[25]); p->y = (unsigned int)(point_data[26]<<8) + (unsigned int) (point_data[27]); p->pressure = point_data[28]; } #endif // 将触摸屏的坐标映射到LCD坐标上. 触摸屏短边为X轴,LCD坐标一般长边为X轴,可能需要调整原点位置 p->x = (TOUCH_MAX_WIDTH - p->x)*SCREEN_MAX_WIDTH/TOUCH_MAX_WIDTH;//y if (board_version == 0){ p->y = p->y*SCREEN_MAX_HEIGHT/TOUCH_MAX_HEIGHT;//x } else if (board_version == 1) { p->y = (TOUCH_MAX_HEIGHT - p->y)*SCREEN_MAX_HEIGHT/TOUCH_MAX_HEIGHT;//x } swap(p->x, p->y); } #ifndef GOODIX_MULTI_TOUCH if(finger_list.head->state == FLAG_DOWN) { input_report_abs(ts->input_dev, ABS_X, finger_list.head->x); input_report_abs(ts->input_dev, ABS_Y, finger_list.head.y); } input_report_abs(ts->input_dev, ABS_PRESSURE, finger_list.head->pressure); input_report_key(ts->input_dev, BTN_TOUCH, finger_list.head->state); #else /* ABS_MT_TOUCH_MAJOR is used as ABS_MT_PRESSURE in android. */ for(p = finger_list.head; p != NULL; p = p->next) { if(p->state == FLAG_DOWN) { input_report_abs(ts->input_dev, ABS_MT_POSITION_X, p->x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, p->y); } //input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, p->id); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, p->pressure); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, p->pressure); //printk("ID:%d.\n", p->id); input_mt_sync(ts->input_dev); } #endif input_sync(ts->input_dev); delete_points(&finger_list); finger_bit = point_data[1]&0x1f; //restore last presse state. XFER_ERROR: NO_ACTION: if(ts->use_irq) enable_irq(ts->client->irq); }
static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) { struct input_dev *dev = xpad->dev; /* digital pad */ if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { /* dpad as buttons (left, right, up, down) */ input_report_key(dev, BTN_TRIGGER_HAPPY1, data[2] & 0x04); input_report_key(dev, BTN_TRIGGER_HAPPY2, data[2] & 0x08); input_report_key(dev, BTN_TRIGGER_HAPPY3, data[2] & 0x01); input_report_key(dev, BTN_TRIGGER_HAPPY4, data[2] & 0x02); } else { input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x08) - !!(data[2] & 0x04)); input_report_abs(dev, ABS_HAT0Y, !!(data[2] & 0x02) - !!(data[2] & 0x01)); } /* start/back buttons */ input_report_key(dev, BTN_START, data[2] & 0x10); input_report_key(dev, BTN_SELECT, data[2] & 0x20); /* stick press left/right */ input_report_key(dev, BTN_THUMBL, data[2] & 0x40); input_report_key(dev, BTN_THUMBR, data[2] & 0x80); /* buttons A,B,X,Y,TL,TR and MODE */ input_report_key(dev, BTN_A, data[3] & 0x10); input_report_key(dev, BTN_B, data[3] & 0x20); input_report_key(dev, BTN_X, data[3] & 0x40); input_report_key(dev, BTN_Y, data[3] & 0x80); input_report_key(dev, BTN_TL, data[3] & 0x01); input_report_key(dev, BTN_TR, data[3] & 0x02); input_report_key(dev, BTN_MODE, data[3] & 0x04); if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { /* left stick */ input_report_abs(dev, ABS_X, (__s16) le16_to_cpup((__le16 *)(data + 6))); input_report_abs(dev, ABS_Y, ~(__s16) le16_to_cpup((__le16 *)(data + 8))); /* right stick */ input_report_abs(dev, ABS_RX, (__s16) le16_to_cpup((__le16 *)(data + 10))); input_report_abs(dev, ABS_RY, ~(__s16) le16_to_cpup((__le16 *)(data + 12))); } /* triggers left/right */ if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { input_report_key(dev, BTN_TL2, data[4]); input_report_key(dev, BTN_TR2, data[5]); } else { input_report_abs(dev, ABS_Z, data[4]); input_report_abs(dev, ABS_RZ, data[5]); } input_sync(dev); }
static void change_sensor_delay(struct ssp_data *data, int iSensorType, int64_t dNewDelay) { u8 uBuf[2]; unsigned int uNewEnable = 0; int64_t dTempDelay = data->adDelayBuf[iSensorType]; if (!(atomic_read(&data->aSensorEnable) & (1 << iSensorType))) { data->aiCheckStatus[iSensorType] = NO_SENSOR_STATE; return; } data->adDelayBuf[iSensorType] = dNewDelay; if (iSensorType == ORIENTATION_SENSOR) iSensorType = ACCELEROMETER_SENSOR; switch (data->aiCheckStatus[iSensorType]) { case ADD_SENSOR_STATE: ssp_dbg("[SSP]: %s - add %u, New = %lldns\n", __func__, 1 << iSensorType, dNewDelay); uBuf[1] = (u8)get_msdelay(dNewDelay); uBuf[0] = (u8)get_delay_cmd(uBuf[1]); if (send_instruction(data, ADD_SENSOR, iSensorType, uBuf, 2) != SUCCESS) { uNewEnable = (unsigned int)atomic_read(&data->aSensorEnable) & (~(unsigned int)(1 << iSensorType)); atomic_set(&data->aSensorEnable, uNewEnable); data->aiCheckStatus[iSensorType] = NO_SENSOR_STATE; data->uMissSensorCnt++; break; } data->aiCheckStatus[iSensorType] = RUNNING_SENSOR_STATE; if (iSensorType == PROXIMITY_SENSOR) { proximity_open_lcd_ldi(data); proximity_open_calibration(data); input_report_abs(data->prox_input_dev, ABS_DISTANCE, 1); input_sync(data->prox_input_dev); } break; case RUNNING_SENSOR_STATE: if (get_msdelay(dTempDelay) == get_msdelay(data->adDelayBuf[iSensorType])) break; ssp_dbg("[SSP]: %s - Change %u, New = %lldns\n", __func__, 1 << iSensorType, dNewDelay); uBuf[1] = (u8)get_msdelay(dNewDelay); uBuf[0] = (u8)get_delay_cmd(uBuf[1]); send_instruction(data, CHANGE_DELAY, iSensorType, uBuf, 2); break; default: break; } }
/** * stkxxx_work() - work queue handler (initiated by the interrupt handler) * @work: work queue to handle */ static void stkxxx_work(struct work_struct *work) { #ifdef TS_DELAY_WORK struct stkxxx *ts = container_of(to_delayed_work(work), struct stkxxx, work); #else struct stkxxx *ts = container_of(work, struct stkxxx, work); #endif struct ts_event *event; int i; if (stkxxx_get_pendown_state(ts)) { if (stkxxx_read_sensor(ts) < 0) { printk(KERN_INFO "work read i2c failed\n"); goto restart; } event = &ts->event[0]; if (!ts->pendown) { ts->pendown = 1; //input_report_key(ts->input, BTN_TOUCH, 1); printk(KERN_INFO "DOWN\n"); } for (i=0; i<ts->touching_num; i++) { input_report_abs(ts->input, ABS_MT_TRACKING_ID, i); #ifdef STKXXX_DEBUG printk(KERN_INFO "ABS_MT_TRACKING_ID = %d\n", i); #endif input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 1); #ifdef STKXXX_DEBUG printk(KERN_INFO "ABS_MT_TOUCH_MAJOR = %d\n", 1); #endif input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, 0); #ifdef STKXXX_DEBUG printk(KERN_INFO "ABS_MT_WIDTH_MAJOR = %d\n", 0); #endif input_report_abs(ts->input, ABS_MT_POSITION_X, event->x); #ifdef STKXXX_DEBUG printk(KERN_INFO "ABS_MT_POSITION_X = %d\n", event->x); #endif input_report_abs(ts->input, ABS_MT_POSITION_Y, event->y); #ifdef STKXXX_DEBUG printk(KERN_INFO "ABS_MT_POSITION_Y = %d\n", event->y); #endif input_mt_sync(ts->input); #ifdef STKXXX_DEBUG printk(KERN_INFO "input_mt_sync\n"); #endif event++; } input_sync(ts->input); #ifdef STKXXX_DEBUG printk(KERN_INFO "input_sync\n"); #endif restart: #ifdef TS_DELAY_WORK schedule_delayed_work(&ts->work, msecs_to_jiffies(TS_POLL_PERIOD)); #else hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); #endif } else { /* enable IRQ after the pen was lifted */ if (ts->pendown) { ts->pendown = 0; input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, 0); input_mt_sync(ts->input); input_sync(ts->input); printk(KERN_INFO "UP\n"); } ts->touching_num = 0; ts->pre_touching_num = 0; enable_irq(ts->client->irq); } }
static void gt801_ts_work_func(struct work_struct *work) { #if SINGLTOUCH_MODE #else int touch_state_index = 0; #endif unsigned char start_reg = 0x02; unsigned char buf[TOUCH_NUMBER*TOUCH_REG_NUM]; unsigned short x; unsigned short y; int i,ret; int syn_flag = 0; int bufLen = TOUCH_NUMBER*TOUCH_REG_NUM; struct gt801_ts_data *ts = container_of(work, struct gt801_ts_data, work); gt801printk("%s\n",__FUNCTION__); ret=gt801_read_regs(ts->client, start_reg, buf,bufLen); if (ret < 0) { printk("%s:i2c_transfer fail =%d\n",__FUNCTION__,ret); if (ts->use_irq) enable_irq(ts->client->irq); return; } #if SINGLTOUCH_MODE i = 0; if(buf[i+ptpressure] == 0) { gt801printk(" realse ts_dev->point.x=%d ,ts_dev->point.y=%d \n",ts->point.x,ts->point.y); if (touch_state[i] == TOUCH_DOWN) { input_report_key(ts->input_dev,BTN_TOUCH,0); syn_flag = 1; touch_state[i] = TOUCH_UP; gt801printk("SINGLTOUCH_MODE up\n"); } } else { x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]); y= (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]); if (ts->swap_xy) swap(x, y); if (verify_coord(ts,&x,&y)) goto out; if (touch_state[i] == TOUCH_UP) { gt801printk("SINGLTOUCH_MODE down\n"); input_report_key(ts->input_dev,BTN_TOUCH,1); touch_state[i] = TOUCH_DOWN; } gt801printk("input_report_abs(%d/%d)\n",x,y); input_report_abs(ts->input_dev,ABS_X,x ); input_report_abs(ts->input_dev,ABS_Y,y ); syn_flag = 1; } #else for(i=0; i<bufLen; i+=TOUCH_REG_NUM) { if(buf[i+ptpressure] == 0){ gt801printk("%s:buf=%d touch up\n",__FUNCTION__,buf[i+ptpressure]); if (touch_state[touch_state_index] == TOUCH_DOWN) { gt801printk("%s:%d touch up\n",__FUNCTION__,i); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0); //Finger Size input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0); //Touch Size input_mt_sync(ts->input_dev); syn_flag =1; touch_state[touch_state_index] = TOUCH_UP; } } else{ x = ((( ((unsigned short)buf[i+ptxh] )<< 8) ) | buf[i+ptxl]); y = (((((unsigned short)buf[i+ptyh] )<< 8) )| buf[i+ptyl]); /* adjust the x and y to proper value added by [email protected]*/ x = 480-x; if(y < 800){ y = 800-y; } if (ts->swap_xy){ swap(x, y); } if (verify_coord(ts,&x,&y));//goto out; gt801printk("input_report_abs--%d-%d-(%d/%d)\n", i,touch_state_index, x, y); input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 1); //Finger Size input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5); //Touch Size input_mt_sync(ts->input_dev); syn_flag = 1; touch_state[touch_state_index] = TOUCH_DOWN; } touch_state_index++; } #endif if(syn_flag){ input_sync(ts->input_dev); } out: if (ts->use_irq) { enable_irq(ts->client->irq); } return; }
static int AMI306_Report_Value(int iEnable) { int controlbuf[AMI306_CB_LENGTH]; struct ami306_i2c_data *data = i2c_get_clientdata(ami306_i2c_client); int report_enable = 0; if( !iEnable ) return -1; read_lock(&ami306mid_data.ctrllock); memcpy(controlbuf, &ami306mid_data.controldata[0], sizeof(controlbuf)); read_unlock(&ami306mid_data.ctrllock); if(controlbuf[AMI306_CB_ACTIVESENSORS] & AMIT_BIT_ACCELEROMETER) { input_report_abs(data->input_dev, ABS_X, ami306mid_data.na.x);/* x-axis raw acceleration */ input_report_abs(data->input_dev, ABS_Y, ami306mid_data.na.y);/* y-axis raw acceleration */ input_report_abs(data->input_dev, ABS_Z, ami306mid_data.na.z);/* z-axis raw acceleration */ report_enable = 1; } if(controlbuf[AMI306_CB_ACTIVESENSORS] & AMIT_BIT_MAGNETIC_FIELD) { input_report_abs(data->input_dev, ABS_HAT0X, ami306mid_data.nm.x); /* x-axis of raw magnetic vector */ input_report_abs(data->input_dev, ABS_HAT0Y, ami306mid_data.nm.y); /* y-axis of raw magnetic vector */ input_report_abs(data->input_dev, ABS_BRAKE, ami306mid_data.nm.z); /* z-axis of raw magnetic vector */ input_report_abs(data->input_dev, ABS_WHEEL, ami306mid_data.status);/* status of magnetic sensor */ report_enable = 1; } if(controlbuf[AMI306_CB_ACTIVESENSORS] & AMIT_BIT_ORIENTATION) { input_report_abs(data->input_dev, ABS_RX, ami306mid_data.yaw); /* yaw */ input_report_abs(data->input_dev, ABS_RY, ami306mid_data.pitch);/* pitch */ input_report_abs(data->input_dev, ABS_RZ, ami306mid_data.roll);/* roll */ input_report_abs(data->input_dev, ABS_RUDDER, ami306mid_data.status);/* status of orientation sensor */ report_enable = 1; } #if 0 if(controlbuf[AMI306_CB_ACTIVESENSORS] & AMIT_BIT_GYROSCOPE) { input_report_abs(data->input_dev, ABS_HAT1X, ami306mid_data.gyro.x);/* x-axis of gyro sensor */ input_report_abs(data->input_dev, ABS_HAT1Y, ami306mid_data.gyro.y);/* y-axis of gyro sensor */ input_report_abs(data->input_dev, ABS_THROTTLE, ami306mid_data.gyro.z);/* z-axis of gyro sensor */ report_enable = 1; } #endif if (AMI306_DEBUG_DEV_DEBOUNCE & ami306_debug_mask) { AMID("yaw: %d, pitch: %d, roll: %d\n", ami306mid_data.yaw, ami306mid_data.pitch, ami306mid_data.roll); AMID("nax: %d, nay: %d, naz: %d\n", ami306mid_data.na.x, ami306mid_data.na.y, ami306mid_data.na.z); AMID("nmx: %d, nmy: %d, nmz: %d\n", ami306mid_data.nm.x, ami306mid_data.nm.y, ami306mid_data.nm.z); AMID("mag_status: %d\n", ami306mid_data.status); } if (report_enable) input_sync(data->input_dev); return 0; }
/* * This function translates the native event packets to linux input event * packets. Some packets coming from serial are not touchscreen related. In * this case we send them off to be processed elsewhere. */ static void h3600ts_process_packet(struct h3600_dev *ts) { struct input_dev *dev = ts->dev; static int touched = 0; int key, down = 0; switch (ts->event) { /* Buttons - returned as a single byte 7 6 5 4 3 2 1 0 S x x x N N N N S switch state ( 0=pressed 1=released) x Unused. NNNN switch number 0-15 Note: This is true for non interrupt generated key events. */ case KEYBD_ID: down = (ts->buf[0] & 0x80) ? 0 : 1; switch (ts->buf[0] & 0x7f) { case H3600_SCANCODE_RECORD: key = KEY_RECORD; break; case H3600_SCANCODE_CALENDAR: key = KEY_PROG1; break; case H3600_SCANCODE_CONTACTS: key = KEY_PROG2; break; case H3600_SCANCODE_Q: key = KEY_Q; break; case H3600_SCANCODE_START: key = KEY_PROG3; break; case H3600_SCANCODE_UP: key = KEY_UP; break; case H3600_SCANCODE_RIGHT: key = KEY_RIGHT; break; case H3600_SCANCODE_LEFT: key = KEY_LEFT; break; case H3600_SCANCODE_DOWN: key = KEY_DOWN; break; default: key = 0; } if (key) input_report_key(dev, key, down); break; /* * Native touchscreen event data is formatted as shown below:- * * +-------+-------+-------+-------+ * | Xmsb | Xlsb | Ymsb | Ylsb | * +-------+-------+-------+-------+ * byte 0 1 2 3 */ case TOUCHS_ID: if (!touched) { input_report_key(dev, BTN_TOUCH, 1); touched = 1; } if (ts->len) { unsigned short x, y; x = ts->buf[0]; x <<= 8; x += ts->buf[1]; y = ts->buf[2]; y <<= 8; y += ts->buf[3]; input_report_abs(dev, ABS_X, x); input_report_abs(dev, ABS_Y, y); } else { input_report_key(dev, BTN_TOUCH, 0); touched = 0; } break; default: /* Send a non input event elsewhere */ break; } input_sync(dev); }
static void gp2a_work_func_light(struct work_struct *work) { struct sensor_data *data = container_of((struct delayed_work *)work, struct sensor_data, work); int adc=0; state_type level_state = LIGHT_INIT; int lux = 0; static int old_lux = 0; /* read adc data from s5p110 */ adc = lightsensor_get_adcvalue(); if(adc >= 1643)//(adc >= 1050) { level_state = LIGHT_LEVEL5; buffering = 5; } else if(adc >= 1576 && adc < 1643)//(adc >= 800 && adc < 1050) { if(buffering == 5) { level_state = LIGHT_LEVEL5; buffering = 5; } else if((buffering == 1)||(buffering == 2)||(buffering == 3)||(buffering == 4)) { level_state = LIGHT_LEVEL4; buffering = 4; } } else if(adc >= 1159 && adc < 1576)//(adc >= 750 && adc < 800) { level_state = LIGHT_LEVEL4; buffering = 4; } else if(adc >= 1104 && adc < 1159)//(adc >= 560 && adc < 750) { if((buffering == 4)||(buffering == 5)) { level_state = LIGHT_LEVEL4; buffering = 4; } else if((buffering == 1)||(buffering == 2)||(buffering == 3)) { level_state = LIGHT_LEVEL3; buffering = 3; } } else if(adc >= 462 && adc < 1104)//(adc >= 550 && adc < 560) { level_state = LIGHT_LEVEL3; buffering = 3; } else if(adc >= 430 && adc < 462)//(adc >= 370 && adc < 550) { if((buffering == 3)||(buffering == 4)||(buffering == 5)) { level_state = LIGHT_LEVEL3; buffering = 3; } else if((buffering == 1)||(buffering == 2)) { level_state = LIGHT_LEVEL2; buffering = 2; } } else if(adc >= 94 && adc < 430)//(adc >= 270 && adc < 370) { level_state = LIGHT_LEVEL2; buffering = 2; } else if(adc >= 86 && adc < 94)//(adc >= 200 && adc < 270) { if((buffering == 2)||(buffering == 3)||(buffering == 4)||(buffering == 5)) { level_state = LIGHT_LEVEL2; buffering = 2; } else if(buffering == 1) { level_state = LIGHT_LEVEL1; buffering = 1; } } else if(adc < 86)//(adc < 200) { level_state = LIGHT_LEVEL1; buffering = 1; } cur_state = level_state; #ifdef MDNIE_TUNINGMODE_FOR_BACKLIGHT if(autobrightness_mode) { if((pre_val!=1)&&(current_gamma_value == 24)&&(level_state == LIGHT_LEVEL5)&&(current_mDNIe_UI == mDNIe_UI_MODE)) { mDNIe_Mode_set_for_backlight(pmDNIe_Gamma_set[1]); pre_val = 1; gprintk("mDNIe_Mode_set_for_backlight - pmDNIe_Gamma_set[1]\n" ); } } #endif lux = StateToLux(cur_state); data->light_data= cur_adc_value; if(data->testmode == 1) { input_report_abs(this_data, ABS_Y, adc); input_sync(this_data); //gprintk("testmode : adc(%d), lux(%d), cur_state(%d) \n", adc, lux, cur_state); } else { if(old_lux != lux) { old_lux = lux; input_report_abs(this_data, ABS_X, lux); input_sync(this_data); gprintk("realmode : adc(%d), lux(%d), cur_state(%d) \n", adc, lux, cur_state); } } schedule_delayed_work(&data->work, msecs_to_jiffies(data->delay)); }
static void atp_complete(struct urb* urb, struct pt_regs* regs) { int x, y, x_z, y_z, x_f, y_f; int retval, i, j; struct atp *dev = urb->context; switch (urb->status) { case 0: /* success */ break; case -EOVERFLOW: if(!dev->overflowwarn) { printk("appletouch: OVERFLOW with data " "length %d, actual length is %d\n", dev->datalen, dev->urb->actual_length); dev->overflowwarn = 1; } case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: /* This urb is terminated, clean up */ dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); return; default: dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); goto exit; } /* drop incomplete datasets */ if (dev->urb->actual_length != dev->datalen) { dprintk("appletouch: incomplete data package" " (first byte: %d, length: %d).\n", dev->data[0], dev->urb->actual_length); goto exit; } /* reorder the sensors values */ if (atp_is_geyser_3(dev)) { memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); /* * The values are laid out like this: * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ... * '-' is an unused value. */ /* read X values */ for (i = 0, j = 19; i < 20; i += 2, j += 3) { dev->xy_cur[i] = dev->data[j + 1]; dev->xy_cur[i + 1] = dev->data[j + 2]; } /* read Y values */ for (i = 0, j = 1; i < 9; i += 2, j += 3) { dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1]; dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2]; } } else if (atp_is_geyser_2(dev)) { memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); /* * The values are laid out like this: * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ... * '-' is an unused value. */ /* read X values */ for (i = 0, j = 19; i < 20; i += 2, j += 3) { dev->xy_cur[i] = dev->data[j]; dev->xy_cur[i + 1] = dev->data[j + 1]; } /* read Y values */ for (i = 0, j = 1; i < 9; i += 2, j += 3) { dev->xy_cur[ATP_XSENSORS + i] = dev->data[j]; dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 1]; } } else { for (i = 0; i < 8; i++) { /* X values */ dev->xy_cur[i ] = dev->data[5 * i + 2]; dev->xy_cur[i + 8] = dev->data[5 * i + 4]; dev->xy_cur[i + 16] = dev->data[5 * i + 42]; if (i < 2) dev->xy_cur[i + 24] = dev->data[5 * i + 44]; /* Y values */ dev->xy_cur[i + 26] = dev->data[5 * i + 1]; dev->xy_cur[i + 34] = dev->data[5 * i + 3]; } } dbg_dump("sample", dev->xy_cur); if (!dev->valid) { /* first sample */ dev->valid = 1; dev->x_old = dev->y_old = -1; memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */ goto exit; /* 17" Powerbooks have extra X sensors */ for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { if (!dev->xy_cur[i]) continue; printk("appletouch: 17\" model detected.\n"); if(atp_is_geyser_2(dev)) input_set_abs_params(dev->input, ABS_X, 0, (20 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); else input_set_abs_params(dev->input, ABS_X, 0, (ATP_XSENSORS - 1) * ATP_XFACT - 1, ATP_FUZZ, 0); break; } goto exit; } for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { /* accumulate the change */ signed char change = dev->xy_old[i] - dev->xy_cur[i]; dev->xy_acc[i] -= change; /* prevent down drifting */ if (dev->xy_acc[i] < 0) dev->xy_acc[i] = 0; } memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); dbg_dump("accumulator", dev->xy_acc); x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, ATP_XFACT, &x_z, &x_f); y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, ATP_YFACT, &y_z, &y_f); if (x && y) { if (dev->x_old != -1) { x = (dev->x_old * 3 + x) >> 2; y = (dev->y_old * 3 + y) >> 2; dev->x_old = x; dev->y_old = y; if (debug > 1) printk("appletouch: X: %3d Y: %3d " "Xz: %3d Yz: %3d\n", x, y, x_z, y_z); input_report_key(dev->input, BTN_TOUCH, 1); input_report_abs(dev->input, ABS_X, x); input_report_abs(dev->input, ABS_Y, y); input_report_abs(dev->input, ABS_PRESSURE, min(ATP_PRESSURE, x_z + y_z)); atp_report_fingers(dev->input, max(x_f, y_f)); } dev->x_old = x; dev->y_old = y; }
static void cypress_ts_work_func(struct work_struct *work) { int ret = 0; int retry = 20; int finger2=0; int x1 = 0, y1 = 0, flick_direction = 0, report_direction = 0, gesture = 0, pressure = 0, pinch_value = 0,x2 = 0, y2 = 0; uint8_t buf[15]; struct cypress_ts_data *ts = container_of(work, struct cypress_ts_data, work); //ret = cypress_i2c_read(ts->client, 0x00, buf, 14); //ZTE_XUKE_CRDB00517999,BEGIN while (retry-- > 0) { ret = cypress_i2c_read(ts->client, 0x00, buf, 14); /* go to sleep */ //printk("wly2: %d,%d, %x\n", ret, retry,buf[0]); if (ret >= 0) break; msleep(10); } //ZTE_XUKE_CRDB00517999,END //ZTE_WLY_CRDB00512790,BEGIN if (ret < 0) { printk(KERN_ERR "cypress_ts_work_func: cypress_i2c_read failed, go to poweroff.\n"); gpio_direction_output(GPIO_TOUCH_EN_OUT, 0); msleep(200); gpio_direction_output(GPIO_TOUCH_EN_OUT, 1); msleep(200); } buf[14] =0; //ZTE_WLY_CRDB00512790,END if (0 == firmware_version)firmware_version = buf[12]; //printk("cypress_ts_work_func,buf[0] =%d\n", buf[0]); /*ZTE_TOUCH_WLY_006, @2010-04-14,begin*/ if(buf[0] == 0x80) cypress_i2c_write(ts->client, 0x0b, 0x80); else pressure = 255; x1=buf[2] | (uint16_t)(buf[1] & 0x03) << 8; y1=buf[4] | (uint16_t)(buf[3] & 0x03) << 8; x2=buf[6] | (uint16_t)(buf[5] & 0x03) << 8; y2=buf[8] | (uint16_t)(buf[7] & 0x03) << 8; if(buf[0] == 0x82) finger2=1; #ifdef TOUCHSCREEN_DUPLICATED_FILTER ret = duplicated_filter(ts, x1,y1,x2,y2, finger2, pressure); if (ret == 0) { /* printk("%s: duplicated_filter\n", __func__); */ #endif if (((buf[0] == 0x81)&&(x1 == x2)&&(y1 == y2))||finger2 ||(pressure == 0)) { input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, pressure); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 10); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x1); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y1); input_mt_sync(ts->input_dev); } if(finger2) { input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, pressure); input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 10); input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x2); input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y2); input_mt_sync(ts->input_dev); } input_sync(ts->input_dev); #ifdef TOUCHSCREEN_DUPLICATED_FILTER } #endif /*ZTE_TOUCH_WLY_006, @2010-04-14,end*/ #ifdef CYPRESS_GESTURE//ZTE_TOUCH_ZT_002 if(buf[14]) { flick_direction = buf[9]; gesture = buf[13]; cypress_i2c_write(ts->client, 0x0e, 0); } // ZTE_PINCH_WLY_001,BEGIN //if(( 0x48 == buf[9])||( 0x49 == buf[9]))pinch_value = buf[9]; if( 0x48 == buf[9])pinch_value = PINCH_VALUE; if( 0x49 == buf[9])pinch_value = -PINCH_VALUE; // ZTE_PINCH_WLY_001,END /*ZTE_TOUCH_WLY_006, @2010-04-14,begin*/ //printk("wly : pinch_value= %d, pressure=%d\n", buf[9],pressure); report_direction = judge_flick_direction(flick_direction); /*input_report_abs(ts->input_dev, EVENT_FLICK, report_direction); input_report_abs(ts->input_dev, EVENT_SINGLE_CLICK, (gesture & SINGLE_CLICK)); input_report_abs(ts->input_dev, EVENT_EARLY_TAP, (gesture & EARLY_TAP) >> 3); input_report_abs(ts->input_dev, EVENT_TAP_HOLD, (gesture & TAP_AND_HOLD) >> 1); input_report_abs(ts->input_dev, EVENT_PRESS, (gesture & PRESS) >> 5);*/ input_report_abs(ts->input_dev, EVENT_PINCH, pinch_value); input_sync(ts->input_dev); #endif //input_report_key(ts->input_dev, BTN_TOUCH, !!pressure); //input_sync(ts->input_dev); //ZTE_SET_BIT_WLY_0518,BEGIN if (ts->use_irq) enable_irq(ts->client->irq); //ZTE_SET_BIT_WLY_0518,END }
static void ltr558_schedwork(struct work_struct *work){ int als_ps_status; int interrupt, newdata; int final_prox_val; int final_lux_val; als_ps_status = ltr558_i2c_read_reg(LTR558_ALS_PS_STATUS); interrupt = als_ps_status & 10; newdata = als_ps_status & 5 ; LTRDBG("interrupt [%d] newdata [%d]\n", interrupt, newdata); switch (interrupt){ case 2: // PS interrupt if ((newdata == 1) | (newdata == 5)){ final_prox_val = ltr558_ps_read(); if(final_prox_val < 0){ LTRERR("read P-sensor data fail\n"); goto out; } LTRDBG("final_prox_val [%d]\n", final_prox_val); if (final_prox_val >= 0x214){ P_L_printk("ltr558 OBJECT_IS_DETECTED\n"); input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_DETECTED); if (ltr558_set_p_range(P_RANGE_2)){ LTRERR("set P-sensor to range 2 fail\n"); } }else if (final_prox_val < 0x214){ P_L_printk("ltr558 OBJECT_IS_NOT_DETECTED\n"); input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_NOT_DETECTED); if (ltr558_set_p_range(P_RANGE_1)){ LTRERR("set P-sensor to range 1 fail\n"); } } } break; case 8: // ALS interrupt if ((newdata == 4) | (newdata == 5)){ final_lux_val = ltr558_als_read(); if(final_lux_val < 0){ LTRERR("read L-sensor data fail\n"); goto out; } input_report_abs(ltr558_data->ltr558_input, ABS_MISC, final_lux_val); LTRDBG("final_lux_val [%d]\n", final_lux_val); } break; case 10: // Both interrupt if ((newdata == 1) | (newdata == 5)){ final_prox_val = ltr558_ps_read(); if(final_prox_val < 0){ LTRERR("read P-sensor data fail\n"); goto read_als; } LTRDBG("final_prox_val [%d]\n", final_prox_val); if (final_prox_val >= 0x214){ input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_DETECTED); if (ltr558_set_p_range(P_RANGE_2)){ LTRERR("set P-sensor to range 2 fail\n"); } }else if (final_prox_val <0x214){ input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_NOT_DETECTED); if (ltr558_set_p_range(P_RANGE_1)){ LTRERR("set P-sensor to range 2 fail\n"); } } } read_als: if ((newdata == 4) | (newdata == 5)){ final_lux_val = ltr558_als_read(); if(final_lux_val < 0){ LTRERR("read L-sensor data fail\n"); goto out; } input_report_abs(ltr558_data->ltr558_input, ABS_MISC, final_lux_val); LTRDBG("final_lux_val [%d]\n", final_lux_val); } break; } out: input_sync(ltr558_data->ltr558_input); enable_irq(ltr558_data->ltr558_irq); }
static int gp2a_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct input_dev *input_dev; struct gp2a_data *gp2a; struct gp2a_platform_data *pdata = client->dev.platform_data; pr_info("==============================\n"); pr_info("========= GP2A =======\n"); pr_info("==============================\n"); if (!pdata) { pr_err("%s: missing pdata!\n", __func__); return ret; } /* if (!pdata->power || !pdata->light_adc_value) { pr_err("%s: incomplete pdata!\n", __func__); return ret; } */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s: i2c functionality check failed!\n", __func__); return ret; } gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); if (!gp2a) { pr_err("%s: failed to alloc memory for module data\n", __func__); return -ENOMEM; } #if defined(CONFIG_OPTICAL_WAKE_ENABLE) if (system_rev >= 0x03) { pr_info("GP2A Reset GPIO = GPX0(1) (rev%02d)\n", system_rev); gp2a->enable_wakeup = true; } else { pr_info("GP2A Reset GPIO = GPL0(6) (rev%02d)\n", system_rev); gp2a->enable_wakeup = false; } #else gp2a->enable_wakeup = false; #endif gp2a->pdata = pdata; gp2a->i2c_client = client; i2c_set_clientdata(client, gp2a); /* wake lock init */ wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); mutex_init(&gp2a->power_mutex); mutex_init(&gp2a->adc_mutex); ret = gp2a_setup_irq(gp2a); if (ret) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } /* allocate proximity input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); goto err_input_allocate_device_proximity; } gp2a->proximity_input_dev = input_dev; input_set_drvdata(input_dev, gp2a); input_dev->name = "proximity_sensor"; input_set_capability(input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0); gp2a_dbgmsg("registering proximity input device\n"); ret = input_register_device(input_dev); if (ret < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_register_device_proximity; } ret = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_proximity; } /* hrtimer settings. we poll for light values using a timer. */ hrtimer_init(&gp2a->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); gp2a->light_poll_delay = ns_to_ktime(LIGHT_TIMER_PERIOD_MS * NSEC_PER_MSEC); gp2a->timer.function = gp2a_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ gp2a->wq = create_singlethread_workqueue("gp2a_wq"); if (!gp2a->wq) { ret = -ENOMEM; pr_err("%s: could not create workqueue\n", __func__); goto err_create_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&gp2a->work_light, gp2a_work_func_light); #ifdef GP2A_MODE_B /* this is the thread function we run on the work queue */ INIT_WORK(&gp2a->work_proximity, gp2a_work_func_proximity); #endif /* allocate lightsensor-level input_device */ input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s: could not allocate input device\n", __func__); ret = -ENOMEM; goto err_input_allocate_device_light; } input_set_drvdata(input_dev, gp2a); input_dev->name = "light_sensor"; input_set_capability(input_dev, EV_ABS, ABS_MISC); input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0); gp2a_dbgmsg("registering lightsensor-level input device\n"); ret = input_register_device(input_dev); if (ret < 0) { pr_err("%s: could not register input device\n", __func__); input_free_device(input_dev); goto err_input_register_device_light; } gp2a->light_input_dev = input_dev; ret = sysfs_create_group(&input_dev->dev.kobj, &light_attribute_group); if (ret) { pr_err("%s: could not create sysfs group\n", __func__); goto err_sysfs_create_group_light; } /* alloc platform device for adc client */ pdev_gp2a_adc = platform_device_alloc("gp2a-adc", -1); if (!pdev_gp2a_adc) { pr_err("%s: could not allocation pdev_gp2a_adc.\n", __func__); ret = -ENOMEM; goto err_platform_allocate_device_adc; } /* Register adc client */ gp2a->padc = s3c_adc_register(pdev_gp2a_adc, NULL, NULL, 0); if (IS_ERR(gp2a->padc)) { dev_err(&pdev_gp2a_adc->dev, "cannot register adc\n"); ret = PTR_ERR(gp2a->padc); goto err_platform_register_device_adc; } /* set sysfs for light sensor */ ret = misc_register(&light_device); if (ret) pr_err(KERN_ERR "misc_register failed - light\n"); gp2a->lightsensor_class = class_create(THIS_MODULE, "lightsensor"); if (IS_ERR(gp2a->lightsensor_class)) pr_err("Failed to create class(lightsensor)!\n"); gp2a->switch_cmd_dev = device_create(gp2a->lightsensor_class, NULL, 0, NULL, "switch_cmd"); if (IS_ERR(gp2a->switch_cmd_dev)) pr_err("Failed to create device(switch_cmd_dev)!\n"); if (device_create_file(gp2a->switch_cmd_dev, &dev_attr_lightsensor_file_illuminance) < 0) pr_err("Failed to create device file(%s)!\n", dev_attr_lightsensor_file_illuminance.attr.name); dev_set_drvdata(gp2a->switch_cmd_dev, gp2a); /* new sysfs */ ret = sensors_register(gp2a->light_dev, gp2a, light_sensor_attrs, "light_sensor"); if (ret) { pr_err("%s: cound not register light sensor device(%d).\n", __func__, ret); goto out_light_sensor_register_failed; } ret = sensors_register(gp2a->proximity_dev, gp2a, proximity_sensor_attrs, "proximity_sensor"); if (ret) { pr_err("%s: cound not register proximity sensor device(%d).\n", __func__, ret); goto out_proximity_sensor_register_failed; } /* set initial proximity value as 1 */ gp2a->prox_value = 1; input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1); input_sync(gp2a->proximity_input_dev); gp2a->adc_total = 0; goto done; /* error, unwind it all */ out_light_sensor_register_failed: sensors_unregister(gp2a->light_dev); out_proximity_sensor_register_failed: sensors_unregister(gp2a->proximity_dev); err_sysfs_create_group_light: input_unregister_device(gp2a->light_input_dev); err_input_register_device_light: err_input_allocate_device_light: destroy_workqueue(gp2a->wq); err_platform_allocate_device_adc: platform_device_unregister(pdev_gp2a_adc); err_platform_register_device_adc: s3c_adc_release(gp2a->padc); err_create_workqueue: sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: input_unregister_device(gp2a->proximity_input_dev); err_input_register_device_proximity: err_input_allocate_device_proximity: free_irq(gp2a->irq, 0); gpio_free(gp2a->pdata->p_out); err_setup_irq: mutex_destroy(&gp2a->adc_mutex); mutex_destroy(&gp2a->power_mutex); wake_lock_destroy(&gp2a->prx_wake_lock); kfree(gp2a); done: return ret; }
/* report trackpad data as logical trackpad state */ static int report_tp_state(struct bcm5974 *dev, int size) { const struct bcm5974_config *c = &dev->cfg; const struct tp_finger *f; struct input_dev *input = dev->input; int raw_p, raw_w, raw_x, raw_y, raw_n, i; int ptest, origin, ibt = 0, nmin = 0, nmax = 0; int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) return -EIO; /* finger data, le16-aligned */ f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); raw_n = (size - c->tp_offset) / SIZEOF_FINGER; /* always track the first finger; when detached, start over */ if (raw_n) { /* report raw trackpad data */ for (i = 0; i < raw_n; i++) report_finger_data(input, c, &f[i]); raw_p = raw2int(f->force_major); raw_w = raw2int(f->size_major); raw_x = raw2int(f->abs_x); raw_y = raw2int(f->abs_y); // dprintk(9, // "bcm5974: " // "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", ; ptest = int2bound(&c->p, raw_p); origin = raw2int(f->origin); /* while tracking finger still valid, count all fingers */ if (ptest > PRESSURE_LOW && origin) { abs_p = ptest; abs_w = int2bound(&c->w, raw_w); abs_x = int2bound(&c->x, raw_x - c->x.devmin); abs_y = int2bound(&c->y, c->y.devmax - raw_y); while (raw_n--) { ptest = int2bound(&c->p, raw2int(f->force_major)); if (ptest > PRESSURE_LOW) nmax++; if (ptest > PRESSURE_HIGH) nmin++; f++; } } } /* set the integrated button if applicable */ if (c->tp_type == TYPE2) ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); if (dev->fingers < nmin) dev->fingers = nmin; if (dev->fingers > nmax) dev->fingers = nmax; input_report_key(input, BTN_TOUCH, dev->fingers > 0); input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); input_report_abs(input, ABS_PRESSURE, abs_p); input_report_abs(input, ABS_TOOL_WIDTH, abs_w); if (abs_p) { input_report_abs(input, ABS_X, abs_x); input_report_abs(input, ABS_Y, abs_y); // dprintk(8, // "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " // "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, ; } /* type 2 reports button events via ibt only */ if (c->tp_type == TYPE2) input_report_key(input, BTN_LEFT, ibt); input_sync(input); return 0; }
/* * URB callback routine. Called when we get IRQ reports from the * digitizer. * * This bridges the USB and input device worlds. It generates events * on the input device based on the USB reports. */ static void gtco_urb_callback(struct urb *urbinfo) { struct gtco *device = urbinfo->context; struct input_dev *inputdev; int rc; u32 val = 0; s8 valsigned = 0; char le_buffer[2]; inputdev = device->inputdevice; /* Was callback OK? */ if (urbinfo->status == -ECONNRESET || urbinfo->status == -ENOENT || urbinfo->status == -ESHUTDOWN) { /* Shutdown is occurring. Return and don't queue up any more */ return; } if (urbinfo->status != 0) { /* * Some unknown error. Hopefully temporary. Just go and * requeue an URB */ goto resubmit; } /* * Good URB, now process */ /* PID dependent when we interpret the report */ if (inputdev->id.product == PID_1000 || inputdev->id.product == PID_1001 || inputdev->id.product == PID_1002) { /* * Switch on the report ID * Conveniently, the reports have more information, the higher * the report number. We can just fall through the case * statements if we start with the highest number report */ switch (device->buffer[0]) { case 5: /* Pressure is 9 bits */ val = ((u16)(device->buffer[8]) << 1); val |= (u16)(device->buffer[7] >> 7); input_report_abs(inputdev, ABS_PRESSURE, device->buffer[8]); /* Mask out the Y tilt value used for pressure */ device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); /* Fall thru */ case 4: /* Tilt */ /* Sign extend these 7 bit numbers. */ if (device->buffer[6] & 0x40) device->buffer[6] |= 0x80; if (device->buffer[7] & 0x40) device->buffer[7] |= 0x80; valsigned = (device->buffer[6]); input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned); valsigned = (device->buffer[7]); input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); /* Fall thru */ case 2: case 3: /* Convert buttons, only 5 bits possible */ val = (device->buffer[5]) & MASK_BUTTON; /* We don't apply any meaning to the bitmask, just report */ input_event(inputdev, EV_MSC, MSC_SERIAL, val); /* Fall thru */ case 1: /* All reports have X and Y coords in the same place */ val = get_unaligned_le16(&device->buffer[1]); input_report_abs(inputdev, ABS_X, val); val = get_unaligned_le16(&device->buffer[3]); input_report_abs(inputdev, ABS_Y, val); /* Ditto for proximity bit */ val = device->buffer[5] & MASK_INRANGE ? 1 : 0; input_report_abs(inputdev, ABS_DISTANCE, val); /* Report 1 is an exception to how we handle buttons */ /* Buttons are an index, not a bitmask */ if (device->buffer[0] == 1) { /* * Convert buttons, 5 bit index * Report value of index set as one, * the rest as 0 */ val = device->buffer[5] & MASK_BUTTON; dbg("======>>>>>>REPORT 1: val 0x%X(%d)", val, val); /* * We don't apply any meaning to the button * index, just report it */ input_event(inputdev, EV_MSC, MSC_SERIAL, val); } break; case 7: /* Menu blocks */ input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); break; } } /* Other pid class */ if (inputdev->id.product == PID_400 || inputdev->id.product == PID_401) { /* Report 2 */ if (device->buffer[0] == 2) { /* Menu blocks */ input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); } /* Report 1 */ if (device->buffer[0] == 1) { char buttonbyte; /* IF X max > 64K, we still a bit from the y report */ if (device->max_X > 0x10000) { val = (u16)(((u16)(device->buffer[2] << 8)) | (u8)device->buffer[1]); val |= (u32)(((u8)device->buffer[3] & 0x1) << 16); input_report_abs(inputdev, ABS_X, val); le_buffer[0] = (u8)((u8)(device->buffer[3]) >> 1); le_buffer[0] |= (u8)((device->buffer[3] & 0x1) << 7); le_buffer[1] = (u8)(device->buffer[4] >> 1); le_buffer[1] |= (u8)((device->buffer[5] & 0x1) << 7); val = get_unaligned_le16(le_buffer); input_report_abs(inputdev, ABS_Y, val); /* * Shift the button byte right by one to * make it look like the standard report */ buttonbyte = device->buffer[5] >> 1; } else {
static void touch_timer_fire(unsigned long data) { unsigned long data0; unsigned long data1; int updown; #ifdef CONFIG_ANDROID int x,y; #endif /* CONFIG_ANDROID */ data0 = readl(ts_base+S3C_ADCDAT0); data1 = readl(ts_base+S3C_ADCDAT1); updown = (!(data0 & S3C_ADCDAT0_UPDOWN)) && (!(data1 & S3C_ADCDAT1_UPDOWN)); if (updown) { if (ts->count) { #ifdef CONFIG_TOUCHSCREEN_S3C_DEBUG { struct timeval tv; do_gettimeofday(&tv); printk(KERN_INFO "T: %06d, X: %03ld, Y: %03ld\n", (int)tv.tv_usec, ts->xp, ts->yp); } #endif #ifdef CONFIG_ANDROID x=(int) ts->xp/ts->count; y=(int) ts->yp/ts->count; #if defined(CONFIG_FB_S3C_LTE480WV) || defined(CONFIG_FB_S3C_UTLCD7B) y = 4000 - y; #endif /* CONFIG_FB_S3C_LTE480WV */ input_report_abs(ts->dev, ABS_X, x); input_report_abs(ts->dev, ABS_Y, y); input_report_abs(ts->dev, ABS_Z, 0); input_report_key(ts->dev, BTN_TOUCH, 1); input_sync(ts->dev); #else /* CONFIG_ANDROID */ input_report_abs(ts->dev, ABS_X, ts->xp); input_report_abs(ts->dev, ABS_Y, ts->yp); input_report_key(ts->dev, BTN_TOUCH, 1); input_report_abs(ts->dev, ABS_PRESSURE, 1); input_sync(ts->dev); #endif /* CONFIG_ANDROID */ } ts->xp = 0; ts->yp = 0; ts->count = 0; writel(S3C_ADCTSC_PULL_UP_DISABLE | AUTOPST, ts_base+S3C_ADCTSC); writel(readl(ts_base+S3C_ADCCON) | S3C_ADCCON_ENABLE_START, ts_base+S3C_ADCCON); } else { ts->count = 0; #ifdef CONFIG_ANDROID input_report_abs(ts->dev, ABS_X, ts->xp); input_report_abs(ts->dev, ABS_Y, ts->yp); input_report_abs(ts->dev, ABS_Z, 0); #endif /* CONFIG_ANDROID */ input_report_key(ts->dev, BTN_TOUCH, 0); #ifndef CONFIG_ANDROID input_report_abs(ts->dev, ABS_PRESSURE, 0); #endif /* !CONFIG_ANDROID */ input_sync(ts->dev); writel(WAIT4INT(0), ts_base+S3C_ADCTSC); } }
static ssize_t proximity_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct gp2a_data *data = dev_get_drvdata(dev); int value = 0; char input; int err = 0; int16_t thrd; u8 reg; err = kstrtoint(buf, 10, &value); if (err) { pr_err("%s, kstrtoint failed.", __func__); goto done; } if (value != 0 && value != 1) goto done; pr_info("%s, %d value = %d\n", __func__, __LINE__, value); if (data->proximity_enabled && !value) { /* Prox power off */ disable_irq(data->irq); proximity_onoff(0, data); disable_irq_wake(data->irq); //if (data->pdata->led_on) // data->pdata->led_on(false); } if (!data->proximity_enabled && value) { /* prox power on */ //if (data->pdata->led_on) // data->pdata->led_on(true); usleep_range(1000, 1100); proximity_onoff(1, data); err = proximity_open_calibration(data); if (err < 0 && err != -ENOENT) pr_err("%s: proximity_open_offset() failed\n", __func__); else { thrd = gp2a_reg[3][1]+(data->offset_value); THR_REG_LSB(thrd, reg); gp2a_i2c_write(data, gp2a_reg[3][0], ®); THR_REG_MSB(thrd, reg); gp2a_i2c_write(data, gp2a_reg[4][0], ®); thrd = gp2a_reg[5][1]+(data->offset_value); THR_REG_LSB(thrd, reg); gp2a_i2c_write(data, gp2a_reg[5][0], ®); THR_REG_MSB(thrd, reg); gp2a_i2c_write(data, gp2a_reg[6][0], ®); } enable_irq_wake(data->irq); msleep(160); input = gpio_get_value_cansleep(data->pdata->p_out); if (input == 0) { input_report_abs(data->proximity_input_dev, ABS_DISTANCE, 1); input_sync(data->proximity_input_dev); } enable_irq(data->irq); } data->proximity_enabled = value; done: return count; }