关于Android电阻触摸屏


/* drivers/input/touchscreen/msm_touch.c
 *
 * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/io.h>

#include <mach/msm_touch.h>

/* HW register map */
#define TSSC_CTL_REG      0x100
#define TSSC_SI_REG       0x108
#define TSSC_OPN_REG      0x104
#define TSSC_STATUS_REG   0x10C
#define TSSC_AVG12_REG    0x110

/* status bits */
#define TSSC_STS_OPN_SHIFT 0x6
#define TSSC_STS_OPN_BMSK  0x1C0
#define TSSC_STS_NUMSAMP_SHFT 0x1
#define TSSC_STS_NUMSAMP_BMSK 0x3E

/* CTL bits */
#define TSSC_CTL_EN  (0x1 << 0)
#define TSSC_CTL_SW_RESET (0x1 << 2)
#define TSSC_CTL_MASTER_MODE (0x3 << 3)
#define TSSC_CTL_AVG_EN  (0x1 << 5)
#define TSSC_CTL_DEB_EN  (0x1 << 6)
#define TSSC_CTL_DEB_12_MS (0x2 << 7) /* 1.2 ms */
#define TSSC_CTL_DEB_16_MS (0x3 << 7) /* 1.6 ms */
#define TSSC_CTL_DEB_2_MS (0x4 << 7) /* 2 ms */
#define TSSC_CTL_DEB_3_MS (0x5 << 7) /* 3 ms */
#define TSSC_CTL_DEB_4_MS (0x6 << 7) /* 4 ms */
#define TSSC_CTL_DEB_6_MS (0x7 << 7) /* 6 ms */
#define TSSC_CTL_INTR_FLAG1 (0x1 << 10)
#define TSSC_CTL_DATA  (0x1 << 11)
#define TSSC_CTL_SSBI_CTRL_EN (0x1 << 13)

/* control reg's default state */
#define TSSC_CTL_STATE   ( \
  TSSC_CTL_DEB_12_MS | \
  TSSC_CTL_DEB_EN | \
  TSSC_CTL_AVG_EN | \
  TSSC_CTL_MASTER_MODE | \
  TSSC_CTL_EN)

#define TSSC_NUMBER_OF_OPERATIONS 2
#define TS_PENUP_TIMEOUT_MS 20

#define TS_DRIVER_NAME "msm_touchscreen"

#define X_MAX 1024
#define Y_MAX 1024
#define P_MAX 256

struct ts {
 struct input_dev *input;
 struct timer_list timer;
 int irq;
 unsigned int x_max;
 unsigned int y_max;
};

static void __iomem *virt;
#define TSSC_REG(reg) (virt + TSSC_##reg##_REG)

static void ts_update_pen_state(struct ts *ts, int x, int y, int pressure)
{
 if (pressure) {
  input_report_abs(ts->input, ABS_X, x);
  input_report_abs(ts->input, ABS_Y, y);
  input_report_abs(ts->input, ABS_PRESSURE, pressure);
  input_report_key(ts->input, BTN_TOUCH, !!pressure);
 } else {
  input_report_abs(ts->input, ABS_PRESSURE, 0);
  input_report_key(ts->input, BTN_TOUCH, 0);
 }

 input_sync(ts->input);
}

static void ts_timer(unsigned long arg)
{
 struct ts *ts = (struct ts *)arg;

 ts_update_pen_state(ts, 0, 0, 0);
}

static irqreturn_t ts_interrupt(int irq, void *dev_id)
{
 u32 avgs, x, y, lx, ly;
 u32 num_op, num_samp;
 u32 status;

 struct ts *ts = dev_id;

 status = readl(TSSC_REG(STATUS));
 avgs = readl(TSSC_REG(AVG12));
 x = avgs & 0xFFFF;
 y = avgs >> 16;

 /* For pen down make sure that the data just read is still valid.
  * The DATA bit will still be set if the ARM9 hasn't clobbered
  * the TSSC. If it's not set, then it doesn't need to be cleared
  * here, so just return.
  */
 if (!(readl(TSSC_REG(CTL)) & TSSC_CTL_DATA))
  goto out;

 /* Data has been read, OK to clear the data flag */
 writel(TSSC_CTL_STATE, TSSC_REG(CTL));

 /* Valid samples are indicated by the sample number in the status
  * register being the number of expected samples and the number of
  * samples collected being zero (this check is due to ADC contention).
  */
 num_op = (status & TSSC_STS_OPN_BMSK) >> TSSC_STS_OPN_SHIFT;
 num_samp = (status & TSSC_STS_NUMSAMP_BMSK) >> TSSC_STS_NUMSAMP_SHFT;

 if ((num_op == TSSC_NUMBER_OF_OPERATIONS) && (num_samp == 0)) {
  /* TSSC can do Z axis measurment, but driver doesn't support
   * this yet.
   */

  /*
   * REMOVE THIS:
   * These x, y co-ordinates adjustments will be removed once
   * Android framework adds calibration framework.
   */
#ifdef CONFIG_ANDROID_TOUCHSCREEN_MSM_HACKS
  lx = ts->x_max - x;
  ly = ts->y_max - y;
#else
  lx = x;
  ly = y;
#endif
  ts_update_pen_state(ts, lx, ly, 255);
  /* kick pen up timer - to make sure it expires again(!) */
  mod_timer(&ts->timer,
   jiffies + msecs_to_jiffies(TS_PENUP_TIMEOUT_MS));

 } else
  printk(KERN_INFO "Ignored interrupt: {%3d, %3d},"
    " op = %3d samp = %3d\n",
     x, y, num_op, num_samp);

out:
 return IRQ_HANDLED;
}

static int __devinit ts_probe(struct platform_device *pdev)
{
 int result;
 struct input_dev *input_dev;
 struct resource *res, *ioarea;
 struct ts *ts;
 unsigned int x_max, y_max, pressure_max;
 struct msm_ts_platform_data *pdata = pdev->dev.platform_data;

 /* The primary initialization of the TS Hardware
  * is taken care of by the ADC code on the modem side
  */

 ts = kzalloc(sizeof(struct ts), GFP_KERNEL);
 input_dev = input_allocate_device();
 if (!input_dev || !ts) {
  result = -ENOMEM;
  goto fail_alloc_mem;
 }

 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 if (!res) {
  dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
  result = -ENOENT;
  goto fail_alloc_mem;
 }

 ts->irq = platform_get_irq(pdev, 0);
 if (!ts->irq) {
  dev_err(&pdev->dev, "Could not get IORESOURCE_IRQ\n");
  result = -ENODEV;
  goto fail_alloc_mem;
 }

 ioarea = request_mem_region(res->start, resource_size(res), pdev->name);
 if (!ioarea) {
  dev_err(&pdev->dev, "Could not allocate io region\n");
  result = -EBUSY;
  goto fail_alloc_mem;
 }

 virt = ioremap(res->start, resource_size(res));
 if (!virt) {
  dev_err(&pdev->dev, "Could not ioremap region\n");
  result = -ENOMEM;
  goto fail_ioremap;
 }

 input_dev->name = TS_DRIVER_NAME;
 input_dev->phys = "msm_touch/input0";
 input_dev->id.bustype = BUS_HOST;
 input_dev->id.vendor = 0x0001;
 input_dev->id.product = 0x0002;
 input_dev->id.version = 0x0100;
 input_dev->dev.parent = &pdev->dev;

 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
 input_dev->absbit[BIT_WORD(ABS_MISC)] = BIT_MASK(ABS_MISC);
 input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

 if (pdata) {
  x_max = pdata->x_max ? : X_MAX;
  y_max = pdata->y_max ? : Y_MAX;
  pressure_max = pdata->pressure_max ? : P_MAX;
 } else {
  x_max = X_MAX;
  y_max = Y_MAX;
  pressure_max = P_MAX;
 }

 ts->x_max = x_max;
 ts->y_max = y_max;

 input_set_abs_params(input_dev, ABS_X, 0, x_max, 0, 0);
 input_set_abs_params(input_dev, ABS_Y, 0, y_max, 0, 0);
 input_set_abs_params(input_dev, ABS_PRESSURE, 0, pressure_max, 0, 0);

 result = input_register_device(input_dev);
 if (result)
  goto fail_ip_reg;

 ts->input = input_dev;

 setup_timer(&ts->timer, ts_timer, (unsigned long)ts);
 result = request_irq(ts->irq, ts_interrupt, IRQF_TRIGGER_RISING,
     "touchscreen", ts);
 if (result)
  goto fail_req_irq;

 platform_set_drvdata(pdev, ts);

 return 0;

fail_req_irq:
 input_unregister_device(input_dev);
 input_dev = NULL;
fail_ip_reg:
 iounmap(virt);
fail_ioremap:
 release_mem_region(res->start, resource_size(res));
fail_alloc_mem:
 input_free_device(input_dev);
 kfree(ts);
 return result;
}

static int __devexit ts_remove(struct platform_device *pdev)
{
 struct resource *res;
 struct ts *ts = platform_get_drvdata(pdev);

 free_irq(ts->irq, ts);
 del_timer_sync(&ts->timer);

 input_unregister_device(ts->input);
 iounmap(virt);
 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 release_mem_region(res->start, resource_size(res));
 platform_set_drvdata(pdev, NULL);
 kfree(ts);

 return 0;
}

static struct platform_driver ts_driver = {
 .probe  = ts_probe,
 .remove  = __devexit_p(ts_remove),
 .driver  = {
  .name = TS_DRIVER_NAME,
  .owner = THIS_MODULE,
 },
};

static int __init ts_init(void)
{
 return platform_driver_register(&ts_driver);
}
module_init(ts_init);

static void __exit ts_exit(void)
{
 platform_driver_unregister(&ts_driver);
}
module_exit(ts_exit);

MODULE_DESCRIPTION("MSM Touch Screen driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:msm_touchscreen");

最近开始调试触摸屏这一块,感觉不是很难,但是很多的地方不理解,尤其是为什么按下一次panle后,会产生很多次的中断,造成上传很多的坐标值,这个在本来的触摸屏上没有什么问题,但是要是在屏上做虚拟按键的话就麻烦了。只能按照高通的虚拟键盘的机制做处理了。

但是创建成功之后,生成了键盘的配置文件,按下时还是没有反应。看到打印的log,虚拟按键的配置文件确实是有了,怎么就是没有反应呢?

相关内容