Advertisement
Guest User

msm_ts.c for ZTE Racer with some changes by deadlink

a guest
Dec 4th, 2011
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.36 KB | None | 0 0
  1. #include <linux/delay.h>
  2. #include <linux/device.h>
  3. #include <linux/init.h>
  4. #include <linux/input.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/io.h>
  7. #include <linux/module.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/mfd/marimba-tsadc.h>
  10. #include <linux/pm.h>
  11.  
  12. #if defined(CONFIG_HAS_EARLYSUSPEND)
  13. #include <linux/earlysuspend.h>
  14. #endif
  15.  
  16. #include <mach/msm_ts.h>
  17. #include <linux/jiffies.h>  
  18.  
  19.  
  20. #define     TSSC_CTL            0x100
  21. #define     TSSC_CTL_PENUP_IRQ  (1 << 12)
  22. #define     TSSC_CTL_DATA_FLAG  (1 << 11)
  23. #define     TSSC_CTL_DEBOUNCE_EN    (1 << 6)
  24. #define     TSSC_CTL_EN_AVERAGE (1 << 5)
  25. #define     TSSC_CTL_MODE_MASTER    (3 << 3)
  26. #define     TSSC_CTL_SW_RESET   (1 << 2)
  27. #define     TSSC_CTL_ENABLE     (1 << 0)
  28. #define     TSSC_OPN            0x104
  29. #define     TSSC_OPN_NOOP       0x00
  30. #define     TSSC_OPN_4WIRE_X    0x01
  31. #define     TSSC_OPN_4WIRE_Y    0x02
  32. #define     TSSC_OPN_4WIRE_Z1   0x03
  33. #define     TSSC_OPN_4WIRE_Z2   0x04
  34. #define     TSSC_SAMPLING_INT       0x108
  35. #define     TSSC_STATUS         0x10c
  36. #define     TSSC_AVG_12         0x110
  37. #define     TSSC_AVG_34         0x114
  38. #define     TSSC_SAMPLE(op,samp)        ((0x118 + ((op & 0x3) * 0x20)) + ((samp & 0x7) * 0x4))
  39. #define     TSSC_TEST_1         0x198
  40. #define     TSSC_TEST_1_EN_GATE_DEBOUNCE (1 << 2)
  41. #define     TSSC_TEST_2         0x19c
  42. #define     TS_PENUP_TIMEOUT_MS 20
  43.  
  44. struct msm_ts {
  45.     struct msm_ts_platform_data *pdata;
  46.     struct input_dev        *input_dev;
  47.     void __iomem            *tssc_base;
  48.     uint32_t            ts_down:1;
  49.     uint32_t            zoomhack;
  50.     struct ts_virt_key      *vkey_down;
  51.  
  52.     unsigned int            sample_irq;
  53.     unsigned int            pen_up_irq;
  54.  
  55. #if defined(CONFIG_HAS_EARLYSUSPEND)
  56.     struct early_suspend        early_suspend;
  57. #endif
  58.     struct device           *dev;
  59.     struct timer_list timer;
  60. };
  61.  
  62. static uint32_t msm_tsdebug;
  63. module_param_named(tsdebug, msm_tsdebug, uint, 0664);
  64.  
  65. // values from pointercal (stock 2.2.2)
  66. static int32_t msm_tscal_xscale = 17388;
  67. static int32_t msm_tscal_xoffset = -871728;
  68. static int32_t msm_tscal_yscale = 25403;
  69. static int32_t msm_tscal_yoffset = 45240;
  70. static int32_t msm_tscal_gesture_pressure = 1375; // optimized value
  71. static int32_t msm_tscal_gesture_blindspot = 30;
  72. static int32_t msm_tscal_pressure_limit = 200;
  73. static int32_t msm_haptic_feedback = 1;
  74. static int32_t msm_virtual_key_pressed = 0; // if virtual key pressed
  75. static int32_t msm_zoomhack_enabled = 1; // enable zoomhack
  76. static int32_t msm_tscal_min_jump = 30; // for dejitter
  77. static int32_t msm_tscal_max_jump = 70; // for variance
  78.  
  79. module_param_named(tscal_xscale, msm_tscal_xscale, int, 0664);
  80. module_param_named(tscal_xoffset, msm_tscal_xoffset, int, 0664);
  81. module_param_named(tscal_yscale, msm_tscal_yscale, int, 0664);
  82. module_param_named(tscal_yoffset, msm_tscal_yoffset, int, 0664);
  83. module_param_named(tscal_gesture_pressure, msm_tscal_gesture_pressure, int, 0664);
  84. module_param_named(tscal_gesture_blindspot, msm_tscal_gesture_blindspot, int, 0664);
  85. module_param_named(tscal_pressure_limit, msm_tscal_pressure_limit, int, 0664);
  86. module_param_named(virtual_key_pressed, msm_virtual_key_pressed, int, 0664);
  87. module_param_named(zoomhack_enabled, msm_zoomhack_enabled, int, 0664);
  88. module_param_named(haptic_feedback, msm_haptic_feedback, int, 0664);
  89.  
  90.  
  91. // for dejitter
  92. int last_x = 0;
  93. int last_y = 0;
  94. unsigned int last_z = 0;
  95. // for variance
  96. int noise = 0;
  97.  
  98.  
  99. #define tssc_readl(t, a)    (readl(((t)->tssc_base) + (a)))
  100. #define tssc_writel(t, v, a)    do {writel(v, ((t)->tssc_base) + (a));} while(0)
  101.  
  102.  
  103.  
  104. static int sqr (int x)
  105. {
  106.     return x * x;
  107. }
  108.  
  109. static void setup_next_sample(struct msm_ts *ts)
  110. {
  111.     uint32_t tmp;
  112.     tmp = ((7 << 7) | TSSC_CTL_DEBOUNCE_EN | TSSC_CTL_EN_AVERAGE |
  113.            TSSC_CTL_MODE_MASTER | TSSC_CTL_ENABLE);
  114.  
  115.     tssc_writel(ts, tmp, TSSC_CTL);
  116. }
  117.  
  118. #ifndef CONFIG_TOUCHSCREEN_VIRTUAL_KEYS
  119. static struct ts_virt_key *find_virt_key(struct msm_ts *ts,
  120.                      struct msm_ts_virtual_keys *vkeys,
  121.                      uint32_t val)
  122. {
  123.     int i;
  124.  
  125.     if (!vkeys)
  126.         return NULL;
  127.  
  128.     for (i = 0; i < vkeys->num_keys; ++i)
  129.         if ((val >= vkeys->keys[i].min) && (val <= vkeys->keys[i].max))
  130.             return &vkeys->keys[i];
  131.     return NULL;
  132. }
  133. #endif
  134.  
  135.  
  136. static void ts_timer(unsigned long arg)
  137. {
  138.     struct msm_ts *ts = (struct msm_ts *)arg;
  139.     input_report_key(ts->input_dev, BTN_TOUCH, 0);
  140.     input_sync(ts->input_dev);
  141. }
  142.  
  143. static irqreturn_t msm_ts_irq(int irq, void *dev_id)
  144. {
  145.     struct msm_ts *ts = dev_id;
  146.     struct msm_ts_platform_data *pdata = ts->pdata;
  147.  
  148.     uint32_t tssc_avg12, tssc_avg34, tssc_status, tssc_ctl;
  149.     int x, y, z1, z2;
  150.     int was_down;
  151.     int down;
  152.     int z=0;
  153.     del_timer_sync(&ts->timer);
  154.     tssc_ctl = tssc_readl(ts, TSSC_CTL);
  155.     tssc_status = tssc_readl(ts, TSSC_STATUS);
  156.     tssc_avg12 = tssc_readl(ts, TSSC_AVG_12);
  157.     tssc_avg34 = tssc_readl(ts, TSSC_AVG_34);
  158.  
  159.     setup_next_sample(ts);
  160.  
  161.     x = tssc_avg12 & 0xffff;
  162.     y = tssc_avg12 >> 16;
  163.     z1 = tssc_avg34 & 0xffff;
  164.     z2 = tssc_avg34 >> 16;
  165.  
  166.     down = !(tssc_ctl & TSSC_CTL_PENUP_IRQ);
  167.     was_down = ts->ts_down;
  168.     ts->ts_down = down;
  169.  
  170.     /* no valid data */
  171.     if (down && !(tssc_ctl & TSSC_CTL_DATA_FLAG))
  172.         return IRQ_HANDLED;
  173.  
  174.     if (msm_tsdebug & 2)
  175.         printk("%s: down=%d, x=%d, y=%d, z1=%d, z2=%d, status %x\n",
  176.                __func__, down, x, y, z1, z2, tssc_status);
  177.     if (down)
  178.     {
  179.         z = ( ( z2 - z1 - 2)*x) / ( z1 + 2 );
  180.         z = ( 2500 - z ) * 1000 / ( 2500 - 900 );
  181.         if (z <= 0) z = 255;
  182.     }
  183.  
  184.     /* invert the inputs if necessary */
  185.     if (pdata->inv_x) x = pdata->inv_x - x;
  186.     if (pdata->inv_y) y = pdata->inv_y - y;
  187.     if (x < 0) x = 0;
  188.     if (y < 0) y = 0;
  189.     x = (x*msm_tscal_xscale + msm_tscal_xoffset + 32768)/65536;
  190.     y = (y*msm_tscal_yscale + msm_tscal_yoffset + 32768)/65536;
  191.  
  192.  
  193. #ifndef CONFIG_TOUCHSCREEN_VIRTUAL_KEYS
  194.     if (!was_down && down) {
  195.         struct ts_virt_key *vkey = NULL;
  196.  
  197.         if (pdata->vkeys_y && (y > pdata->virt_y_start))
  198.             vkey = find_virt_key(ts, pdata->vkeys_y, x);
  199.         if (!vkey && ts->pdata->vkeys_x && (x > pdata->virt_x_start))
  200.             vkey = find_virt_key(ts, pdata->vkeys_x, y);
  201.  
  202.         if (vkey) {
  203.             WARN_ON(ts->vkey_down != NULL);
  204.             if(msm_tsdebug)
  205.                 printk("%s: virtual key down %d\n", __func__,
  206.                        vkey->key);
  207.             ts->vkey_down = vkey;
  208.             input_report_key(ts->input_dev, vkey->key, 1);
  209.             input_sync(ts->input_dev);
  210.             msm_virtual_key_pressed = 1;                      
  211.             return IRQ_HANDLED;
  212.         }
  213.     } else if (ts->vkey_down != NULL) {
  214.         if (!down) {
  215.             if(msm_tsdebug)
  216.                 printk("%s: virtual key up %d\n", __func__,
  217.                        ts->vkey_down->key);
  218.             input_report_key(ts->input_dev, ts->vkey_down->key, 0);
  219.             input_sync(ts->input_dev);
  220.             msm_virtual_key_pressed = 0;            
  221.             ts->vkey_down = NULL;
  222.         }
  223.         return IRQ_HANDLED;
  224.     }
  225. #endif
  226.     // filtering
  227.     if (last_x != 0 && last_y != 0) {
  228.         int dist = sqr (x - last_x) + sqr (y - last_y);
  229.  
  230.         // variance
  231.         if (noise > 1) {
  232.             if (dist > msm_tscal_max_jump) {
  233.                 // its fast moove
  234.                 noise = 0;
  235.             } else {
  236.                 // its realy noise!
  237.                 // nothing to do
  238.             }
  239.                
  240.         } else if (x < 3 || dist > msm_tscal_max_jump) {
  241.                 // maybe its noise
  242.                 noise++;
  243.                 // reset new position
  244.                 x = last_x;
  245.                 y = last_y;
  246.                 z = last_z;
  247.         }
  248.  
  249.         // dejitter
  250.         if (dist < msm_tscal_min_jump) {
  251.             x = last_x;
  252.             y = last_y;
  253.             z = last_z;
  254.         }
  255.         if (noise != 2) {
  256.             last_x = x;
  257.             last_y = y;
  258.             last_z = z;
  259.         }
  260.     }
  261.     if (down) {
  262.         if(z > (msm_tscal_gesture_pressure - msm_tscal_gesture_blindspot) && z < msm_tscal_gesture_pressure) {  // blind spot (1101-1199)
  263.             down = 0;
  264.             ts->zoomhack = 1;      
  265.         } else if(z>=msm_tscal_gesture_pressure && msm_zoomhack_enabled == 1) { // Pinch zoom emulation & pinch rotation emulation if zoomhack enabled
  266.             if(!ts->zoomhack) {         // Flush real position to avoid jumpiness
  267.                 down = 0;
  268.                 ts->zoomhack = 1;
  269.             }
  270.             else {
  271.                 int pinch_radius = (y+1)/2;         // Base pinch radius on y position
  272.                 int pinch_x = x - 120;              // Get x offset
  273.  
  274.                 int pinch_y = int_sqrt(pinch_radius*pinch_radius - pinch_x*pinch_x);    // Make sure pinch distance is the same even
  275.                                                     // if we move x around. Pythagoras is our friend.
  276.                 if(pinch_y>1000) pinch_y = 0;
  277.        
  278.                 // Finger1
  279.                             input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 255);
  280.                             input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5);
  281.                             input_report_abs(ts->input_dev, ABS_MT_POSITION_X, 120 + pinch_x);
  282.                             input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, 175 - pinch_y);
  283.                             input_mt_sync(ts->input_dev);
  284.                 // Finger2
  285.                             input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 255);
  286.                             input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 5);
  287.                             input_report_abs(ts->input_dev, ABS_MT_POSITION_X, 120 - pinch_x);
  288.                             input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, 175 + pinch_y);
  289.                             input_mt_sync(ts->input_dev);
  290.             }
  291.         } else {
  292.             if(ts->zoomhack) {  // Flush faked positions to avoid jumpiness
  293.                 down = 0;
  294.                 ts->zoomhack = 0;
  295.             } else {
  296.                 // Filter
  297.                 if (z > 400) {
  298.                     input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, (z+1)/2);
  299.                     input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, 10);
  300.                     input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
  301.                     input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
  302.                     input_mt_sync(ts->input_dev);
  303.                 }
  304.             }
  305.         }
  306.     }
  307.     //if (NOISE_COUNT == 0) {
  308.         input_report_key(ts->input_dev, BTN_TOUCH, down);
  309.         input_sync(ts->input_dev);
  310.     //}
  311.  
  312.     if (30 == irq)mod_timer(&ts->timer,jiffies + msecs_to_jiffies(TS_PENUP_TIMEOUT_MS));
  313.     return IRQ_HANDLED;
  314. }
  315.  
  316. static int __devinit msm_ts_hw_init(struct msm_ts *ts)
  317. {
  318.     setup_next_sample(ts);
  319.  
  320.     return 0;
  321. }
  322.  
  323. #ifdef CONFIG_PM
  324. static int
  325. msm_ts_suspend(struct device *dev)
  326. {
  327.     struct msm_ts *ts =  dev_get_drvdata(dev);
  328.     uint32_t val;
  329.  
  330.     disable_irq(ts->sample_irq);
  331.     disable_irq(ts->pen_up_irq);
  332.     val = tssc_readl(ts, TSSC_CTL);
  333.     val &= ~TSSC_CTL_ENABLE;
  334.     tssc_writel(ts, val, TSSC_CTL);
  335.  
  336.     return 0;
  337. }
  338.  
  339. static int
  340. msm_ts_resume(struct device *dev)
  341. {
  342.     struct msm_ts *ts =  dev_get_drvdata(dev);
  343.  
  344.     msm_ts_hw_init(ts);
  345.  
  346.     enable_irq(ts->sample_irq);
  347.     enable_irq(ts->pen_up_irq);
  348.  
  349.     return 0;
  350. }
  351.  
  352. static struct dev_pm_ops msm_touchscreen_pm_ops = {
  353. #ifndef CONFIG_HAS_EARLYSUSPEND
  354.     .suspend    = msm_ts_suspend,
  355.     .resume     = msm_ts_resume,
  356. #endif
  357. };
  358. #endif
  359.  
  360. #ifdef CONFIG_HAS_EARLYSUSPEND
  361. static void msm_ts_early_suspend(struct early_suspend *h)
  362. {
  363.     struct msm_ts *ts = container_of(h, struct msm_ts, early_suspend);
  364.  
  365.     msm_ts_suspend(ts->dev);
  366. }
  367.  
  368. static void msm_ts_late_resume(struct early_suspend *h)
  369. {
  370.     struct msm_ts *ts = container_of(h, struct msm_ts, early_suspend);
  371.  
  372.     msm_ts_resume(ts->dev);
  373. }
  374. #endif
  375.  
  376. #if defined(CONFIG_TOUCHSCREEN_VIRTUAL_KEYS)
  377. #define virtualkeys virtualkeys.msm-touchscreen
  378. #if defined(CONFIG_MACH_MOONCAKE)
  379. static const char ts_keys_size[] = "0x01:102:0:320:80:50:0x01:139:80:320:80:50:0x01:158:160:320:80:50";
  380. #elif defined(CONFIG_MACH_V9)
  381. static const char ts_keys_size[] = "0x01:102:70:850:60:50:0x01:139:230:850:60:50:0x01:158:390:850:60:50";
  382. #endif
  383.  
  384. static ssize_t virtualkeys_show(struct device *dev,
  385.         struct device_attribute *attr, char *buf)
  386. {
  387.     sprintf(buf,"%s\n",ts_keys_size);
  388.     printk("wly:%s\n",__FUNCTION__);
  389.     return strlen(ts_keys_size)+2;
  390. }
  391. static DEVICE_ATTR(virtualkeys, 0664, virtualkeys_show, NULL);
  392. extern struct kobject *android_touch_kobj;
  393. static struct kobject * virtual_key_kobj;
  394. static int ts_key_report_init(void)
  395. {
  396.     int ret;
  397.     virtual_key_kobj = kobject_get(android_touch_kobj);
  398.     if (virtual_key_kobj == NULL) {
  399.         virtual_key_kobj = kobject_create_and_add("board_properties", NULL);
  400.         if (virtual_key_kobj == NULL) {
  401.             printk(KERN_ERR "%s: subsystem_register failed\n", __func__);
  402.             ret = -ENOMEM;
  403.             return ret;
  404.         }
  405.     }
  406.     ret = sysfs_create_file(virtual_key_kobj, &dev_attr_virtualkeys.attr);
  407.     if (ret) {
  408.         printk(KERN_ERR "%s: sysfs_create_file failed\n", __func__);
  409.         return ret;
  410.     }
  411.  
  412.     return 0;
  413. }
  414. #endif
  415.  
  416. static int __devinit msm_ts_probe(struct platform_device *pdev)
  417. {
  418.     struct msm_ts_platform_data *pdata = pdev->dev.platform_data;
  419.     struct msm_ts *ts;
  420.     struct resource *tssc_res;
  421.     struct resource *irq1_res;
  422.     struct resource *irq2_res;
  423.     int err = 0;
  424. #ifndef CONFIG_TOUCHSCREEN_VIRTUAL_KEYS
  425.     int i;
  426. #endif
  427.     tssc_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tssc");
  428.     irq1_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc1");
  429.     irq2_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "tssc2");
  430.  
  431.     if (!tssc_res || !irq1_res || !irq2_res) {
  432.         pr_err("%s: required resources not defined\n", __func__);
  433.         return -ENODEV;
  434.     }
  435.  
  436.     if (pdata == NULL) {
  437.         pr_err("%s: missing platform_data\n", __func__);
  438.         return -ENODEV;
  439.     }
  440.  
  441.     ts = kzalloc(sizeof(struct msm_ts), GFP_KERNEL);
  442.     if (ts == NULL) {
  443.         pr_err("%s: No memory for struct msm_ts\n", __func__);
  444.         return -ENOMEM;
  445.     }
  446.     ts->pdata = pdata;
  447.     ts->dev   = &pdev->dev;
  448.  
  449.     ts->sample_irq = irq1_res->start;
  450.     ts->pen_up_irq = irq2_res->start;
  451.  
  452.     ts->tssc_base = ioremap(tssc_res->start, resource_size(tssc_res));
  453.     if (ts->tssc_base == NULL) {
  454.         pr_err("%s: Can't ioremap region (0x%08x - 0x%08x)\n", __func__,
  455.                (uint32_t)tssc_res->start, (uint32_t)tssc_res->end);
  456.         err = -ENOMEM;
  457.         goto err_ioremap_tssc;
  458.     }
  459.  
  460.     ts->input_dev = input_allocate_device();
  461.     if (ts->input_dev == NULL) {
  462.         pr_err("failed to allocate touchscreen input device\n");
  463.         err = -ENOMEM;
  464.         goto err_alloc_input_dev;
  465.     }
  466.     ts->input_dev->name = "msm-touchscreen";
  467.     ts->input_dev->dev.parent = &pdev->dev;
  468.  
  469.     input_set_drvdata(ts->input_dev, ts);
  470.  
  471.     input_set_capability(ts->input_dev, EV_KEY, BTN_TOUCH);
  472.     set_bit(EV_ABS, ts->input_dev->evbit);
  473.  
  474.     input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, pdata->min_x, pdata->max_x, 0, 0);
  475.     input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, pdata->min_y, pdata->max_y, 0, 0);
  476.     input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, pdata->min_press, pdata->max_press, 0, 0);
  477.     input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
  478.  
  479. #ifndef CONFIG_TOUCHSCREEN_VIRTUAL_KEYS
  480.     for (i = 0; pdata->vkeys_x && (i < pdata->vkeys_x->num_keys); ++i)
  481.         input_set_capability(ts->input_dev, EV_KEY,
  482.                      pdata->vkeys_x->keys[i].key);
  483.     for (i = 0; pdata->vkeys_y && (i < pdata->vkeys_y->num_keys); ++i)
  484.         input_set_capability(ts->input_dev, EV_KEY,
  485.                      pdata->vkeys_y->keys[i].key);
  486. #endif
  487.  
  488.     err = input_register_device(ts->input_dev);
  489.     if (err != 0) {
  490.         pr_err("%s: failed to register input device\n", __func__);
  491.         goto err_input_dev_reg;
  492.     }
  493.  
  494.     setup_timer(&ts->timer, ts_timer, (unsigned long)ts);
  495.     msm_ts_hw_init(ts);
  496.  
  497.     err = request_irq(ts->sample_irq, msm_ts_irq,
  498.               (irq1_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
  499.               "msm_touchscreen", ts);
  500.     if (err != 0) {
  501.         pr_err("%s: Cannot register irq1 (%d)\n", __func__, err);
  502.         goto err_request_irq1;
  503.     }
  504.  
  505.     err = request_irq(ts->pen_up_irq, msm_ts_irq,
  506.               (irq2_res->flags & ~IORESOURCE_IRQ) | IRQF_DISABLED,
  507.               "msm_touchscreen", ts);
  508.     if (err != 0) {
  509.         pr_err("%s: Cannot register irq2 (%d)\n", __func__, err);
  510.         goto err_request_irq2;
  511.     }
  512.  
  513.     platform_set_drvdata(pdev, ts);
  514.  
  515. #ifdef CONFIG_HAS_EARLYSUSPEND
  516.     ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN +
  517.                         TSSC_SUSPEND_LEVEL;
  518.     ts->early_suspend.suspend = msm_ts_early_suspend;
  519.     ts->early_suspend.resume = msm_ts_late_resume;
  520.     register_early_suspend(&ts->early_suspend);
  521. #endif
  522.  
  523.     pr_info("%s: tssc_base=%p irq1=%d irq2=%d\n", __func__,
  524.         ts->tssc_base, (int)ts->sample_irq, (int)ts->pen_up_irq);
  525.  
  526. #if defined(CONFIG_TOUCHSCREEN_VIRTUAL_KEYS)
  527.     ts_key_report_init();
  528. #endif
  529.     return 0;
  530.  
  531. err_request_irq2:
  532.     free_irq(ts->sample_irq, ts);
  533.  
  534. err_request_irq1:
  535.     /* disable the tssc */
  536.     tssc_writel(ts, TSSC_CTL_ENABLE, TSSC_CTL);
  537.  
  538. err_input_dev_reg:
  539.     input_set_drvdata(ts->input_dev, NULL);
  540.     input_free_device(ts->input_dev);
  541.  
  542. err_alloc_input_dev:
  543.     iounmap(ts->tssc_base);
  544.  
  545. err_ioremap_tssc:
  546.     kfree(ts);
  547.     return err;
  548. }
  549.  
  550. static struct platform_driver msm_touchscreen_driver = {
  551.     .driver = {
  552.         .name = "msm_touchscreen",
  553.         .owner = THIS_MODULE,
  554. #ifdef CONFIG_PM
  555.         .pm = &msm_touchscreen_pm_ops,
  556. #endif
  557.     },
  558.     .probe      = msm_ts_probe,
  559. };
  560.  
  561. static int __init msm_ts_init(void)
  562. {
  563.     return platform_driver_register(&msm_touchscreen_driver);
  564. }
  565.  
  566. static void __exit msm_ts_exit(void)
  567. {
  568.     platform_driver_unregister(&msm_touchscreen_driver);
  569. }
  570.  
  571. module_init(msm_ts_init);
  572. module_exit(msm_ts_exit);
  573. MODULE_DESCRIPTION("Qualcomm MSM/QSD Touchscreen controller driver");
  574. MODULE_LICENSE("GPL");
  575. MODULE_ALIAS("platform:msm_touchscreen");
  576.  
  577.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement