tag 标签: android驱动

相关博文
  • 热度 20
    2012-4-18 10:34
    2674 次阅读|
    1 个评论
         static int __devexit ft5x0x_ts_remove(struct i2c_client *client)   {       struct ft5x0x_ts_data *ft5x0x_ts = i2c_get_clientdata(client);      #ifdef CONFIG_HAS_EARLYSUSPEND       unregister_early_suspend(ft5x0x_ts-early_suspend);   #endif       free_irq(client-irq, ft5x0x_ts);       input_unregister_device(ft5x0x_ts-input_dev);       kfree(ft5x0x_ts);       cancel_work_sync(ft5x0x_ts-pen_event_work);       destroy_workqueue(ft5x0x_ts-ts_workqueue);       i2c_set_cleintdata(client, NULL);          return 0;   }       static const struct i2c_device_id  ft5x0x_ts_id[] = {       {FT5X0X_NAME, 0}   };   MODULE_DEVICE_TABLE(i2c, ft5x0x_id);      static struct i2c_driver ft5x0x_ts_driver = {       .probe    = ft5x0x_ts_probe,       .remove   = __devexit_p(ft5x0x_ts_remove),       .id_table = ft5x0x_ts_id,       .driver   = {           .name  = FT5X0X_TS,           .owner = THIS_MODULE,       },   };      static int __init ft5x0x_ts_init(void)   {       int ret;          ret = i2c_add_driver(ft5x0x_ts_driver);          return ret;   }      static void __exit ft5x0x_ts_exit(void)   {       i2c_delete_driver(ft5x0x_ts_driver);   }      module_init(ft5x0x_ts_init);   module_exit(ft5x0x_ts_exit);    
  • 热度 16
    2012-4-18 10:33
    2905 次阅读|
    1 个评论
         static void ft5x0x_ts_pen_irq_work(struct work_struct *work)   {       int ret = -1;          ret = ft5x0x_read_data();       if (ret == 0)           ft5x0x_report_value();   }      static interrupt_r ft5x0x_ts_interrupt(int irq, void *dev_id)   {       struct ft5x0x_ts_data *ft5x0x_ts = dev_id;          if (!work_pending(ft5x0x_ts-pen_irq_work))           queue_work(ft5x0x_ts-ts_workqueue, ft5x0x_ts-pen_irq_work);          return IRQ_HANDLED;   }      #ifdef CONFIG_HAS_EARLYSUSPEND   static void ft5x0x_ts_suspend(struct early_suspend *handler)   {       struct ft5x0x_ts_data *ft5x0x_ts;          ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);       disable_irq(this_client-irq);       cancel_workqueue(ft5x0x_ts-pen_irq_work);       flush_workqueue(ft5x0x_ts-ts_workqueue);          ft5x0x_write_reg(FT5X0X_REG_PMODE, PMODE_MONITOR);          printk(" %s\n", __func__);   }      static void ft5x0x_ts_resume(struct early_suspend *handler)   {       ventana_touchscreen_reset();          enable_irq(this_client-irq);              ft5x0x_write_reg(FT5X0X_REG_PMODE, PMODE_ACTIVE);              printk(" %s\n", __func__);   }   #endif      static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id, *id)   {          int err = 0;       struct ft5x0x_ts_data *ft5x0x_ts;       struct input_dev *input_dev;          if (!i2c_check_functionality(client-adapter, I2C_FUNC_I2C)) {           err = -ENODEV;           goto exit_i2c_check_functionality;       }              ft5x0x_ts = kzalloc(sizeof(ft5x0x_ts_data), GPL_KERNEL);       if (!ft5x0x_ts) {           err = -ENOMEM;           goto exit_alloc_data;       }          this_client = client;          i2c_set_clientdata(client, ft5x0x_ts);          INIT_WORK(ft5x0x_ts-pen_event_work, ft5x0x_ts_pen_irq_work);          ft5x0x_ts-ts_workqueue = create_siglethread_workqueue(dev_name(client-dev));          if (!ft5x0x_ts-ts_workqueue) {           err = -ESRCH;           goto exit_create_siglethread;       }          err = request_irq(client-irq, ft5x0x_ts_interrupt, IRQF_TRIGGER_FALLING, "ft5x0x-irq", ft5x0x_ts);       if (err 0) {           dev_err(client-dev, "ft5x0x_ts_probe: request irq failed\n");           goto exit_irq_request;       }          disable_irq(this_client-irq);          input_dev = input_allocate_device();       if (!input_dev) {           err = -ENOMEM;           dev_err(client-dev, "ft5x0x_ts_probe: failed alloc input device\n");       }          ft5x0x_ts-input_dev = input_dev;          input_dev-name = FT5X0X_NAME;          set_bit(EV_ABS, input_dev-evbit);       set_bit(EV_KEY, input_dev-evbit);       set_bit(BTN_TOUCH, input_dev-keybit);      #ifdef FT5X0X_MULTI_TOUCH       set_bit(ABS_MT_TOUCH_MAJOR, input_dev-absbit);       set_bit(ABS_MT_POSITION_X, input_dev-absbit);       set_bit(ABS_MT_POSITION_Y, input_dev-absbit);       set_bit(ABS_MT_WIDTH_MAJOR, input_dev-absbit);          input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, SCREEN_MAX_X, 0, 0);       input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, SCREEN_MAX_Y, 0, 0);       input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);       input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);   #else       set_bit(ABS_X, input_dev-absbit);       set_bit(ABS_Y, input_dev-absbit);       set_bit(ABS_PRESSURE, input_dev-absbit);       set_bit(BTN_TOUCH, input_dev-keybit);          input_set_abs_params(input_dev, ABS_X, 0, SCREEN_MAX_X, 0, 0);       input_set_abs_params(input_dev, ABS_Y, 0, SCREEN_MAX_Y, 0, 0);       input_set_abs_params(input_dev, ABS_PRESSURE, 0, PRESS_MAX, 0 , 0);          err = input_register_device(input_dev);       if (err) {           dev_err(client-dev, "ft5x0x_ts_probe: failed to register input device: %s\n",                    dev_name(client-dev));           goto exit_input_register_device;       }   #endif      #ifdef CONFIG_HAS_EARLYSUSPEND       ft5x0x_ts-early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;       ft5x0x_ts-early_suspend.suspend = ft5x0x_ts_suspend;       ft5x0x_ts-early_suspend.resume = ft5x0x_ts_resume;       register_early_suspend(ft5x0x_ts-early_suspend);   #endif       msleep(50);          //Get some register information       uc_reg_value = ft5x0x_read_fw_ver();       printk(" Firmware version = 0x%sx\n", uc_reg_value);          //Auto calibration       err = ft5x0x_write_reg(CALIBRATION_REG, 0x00);       if (err)           printk(" Auto calibration failed.\n");       else           printk(" Auto calibration successfully.\n");       //Config the run mode of TPM, reg - 0xa7 : auto calibration - 0x04       ft5x0x_write_reg(FT5X0X_REG_STATE, 0x00);       printk(" Auto calibration during running.\n");          enable_irq(this_client-irq);          return 0;      exit_input_register_device:       input_free_device(input_dev);      exit_alloc_data:       free_irq(client-irq, ft5x0x_ts);      exit_irq_request:      exit_create_siglethread:       i2c_set_clientdata(client, NULL);      exit_alloc_data:      exit_i2c_check_functionality:       return err;      }      
  • 热度 26
    2012-4-18 10:31
    32384 次阅读|
    1 个评论
    view plaincopyprint? static void ft5x0x_ts_release(void)   {       struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);      #ifdef FT5X0X_MULTI_TOUCH       input_report_abs(data-input_dev, ABS_MT_TOUCH_MAJOR, 0);       input_report_abs(data-input_dev, ABS_MT_WIDTH_MAJOR, 0);       input_report_key(data-input_dev, BTN_TOUCH, 0);   #else       input_report_abs(data-input_dev, ABS_PRESSURE, 0);       input_report_key(data-input_dev, BTN_TOUCH, 0);   #endif       input_sync(data-input_dev);   }      static int ft5x0x_read_data(void)   {       struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);       struct ts_event *event = data-event;       u32 buf = {0};       int ret = -1;          #ifdef FT5X0X_MULTI_TOUCH       ret = ft5x0x_i2c_rxdata(buf, 31);   #else       ret = ft5x0x_i2c_rxdata(buf, 7);   #endif       if (ret 0) {           printk("%s read_data i2c_rxdata failed: %d\n", __func__, ret);       }          memset(event, 0, sizeof(struct ts_event));       event-touch_point = buf 0x07;          if (event-touch_point == 0) {           ft5x0x_ts_release();           return 1;       }      #ifdef FT5X0X_MULTI_TOUCH       switch (event-touch_point) {           case 5:               event-x5 = (s16)(buf 0x0F)8 | (s16)buf ;               event-y5 = (s16)(buf 0x0F)8 | (s16)buf ;           case 4:               event-x4 = (s16)(buf 0x0F)8 | (s16)buf ;               event-y4 = (s16)(buf 0x0F)8 | (s16)buf ;           case 3:               event-x3 = (s16)(buf 0x0F)8 | (s16)buf ;               event-y3 = (s16)(buf 0x0F)8 | (s16)buf ;           case 2:               event-x2 = (s16)(buf 0x0F)8 | (s16)buf ;               event-y2 = (s16)(buf 0x0F)8 | (s16)buf ;           case 1:               event-x1 = (s16)(buf 0x0F)8 | (s16)buf ;               event-y1 = (s16)(buf 0x0F)8 | (s16)buf ;               break;           default:               return -1;       }   #else       if (event-touch_point == 1) {            event-x1 = (s16)(buf 0x0F)8 | (s16)buf ;           event-y1 = (s16)(buf 0x0F)8 | (s16)buf ;       }   #endif          event-pressure = 200;          return 0;   }      static void ft5x0x_reprot_value(void)   {       struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);       struct ts_event *event = data-event;      #ifdef FT5X0X_MULTI_TOUCH       switch(event-touch_point) {           case 5:               input_report_abs(data-input_dev, ABS_MT_TOUCH_MAJOR, event-pressure);               input_report_abs(data-input_dev, ABS_MT_POSITION_X,  event-x5);               input_report_abs(data-input_dev, ABS_MT_POSITION_Y,  event-y5);               input_report_abs(data-input_dev, ABS_MT_WIDTH_MAJOR, event-pressure);               input_mt_sync(data-input_dev);           case 4:               input_report_abs(data-input_dev, ABS_MT_TOUCH_MAJOR, event-pressure);               input_report_abs(data-input_dev, ABS_MT_POSITION_X,  event-x4);               input_report_abs(data-input_dev, ABS_MT_POSITION_Y,  event-y4);               input_report_abs(data-input_dev, ABS_MT_WIDTH_MAJOR, event-pressure);               input_mt_sync(data-input_dev);           case 3:               input_report_abs(data-input_dev, ABS_MT_TOUCH_MAJOR, event-pressure);               input_report_abs(data-input_dev, ABS_MT_POSITION_X,  event-x3);               input_report_abs(data-input_dev, ABS_MT_POSITION_Y,  event-y3);               input_report_abs(data-input_dev, ABS_MT_WIDTH_MAJOR, event-pressure);               input_mt_sync(data-input_dev);           case 2:               input_report_abs(data-input_dev, ABS_MT_TOUCH_MAJOR, event-pressure);               input_report_abs(data-input_dev, ABS_MT_POSITION_X,  event-x2);               input_report_abs(data-input_dev, ABS_MT_POSITION_Y,  event-y2);               input_report_abs(data-input_dev, ABS_MT_WIDTH_MAJOR, event-pressure);               input_mt_sync(data-input_dev);           case 1:               input_report_abs(data-input_dev, ABS_MT_TOUCH_MAJOR, event-pressure);               input_report_abs(data-input_dev, ABS_MT_POSITION_X,  event-x1);               input_report_abs(data-input_dev, ABS_MT_POSITION_Y,  event-y1);               input_report_abs(data-input_dev, ABS_MT_WIDTH_MAJOR, event-pressure);               input_mt_sync(data-input_dev);               break;           default:               break;       }   #else       if (event-touch_point == 1) {           input_report_abs(data-input_dev, ABS_X, event-x1);           input_report_abs(data-input_dev, ABS_Y, event-y1);           input_report_abs(data-input_dev, ABS_PRESSURE, event-pressure);       }       input_report_key(data-input_dev, BTN_TOUCH, 1);   #endif          input_sync(data-input_dev);     //摘自:http://blog.csdn.net/sunsea1026/article/details/7415803