⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsc2003andcs7103.c

📁 TI四线式电阻触摸芯片TSC2003LINUX驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
  ret = kernel_thread(tsc2003ts_thread, d, CLONE_KERNEL);  if (ret >= 0)  {      wait_for_completion(&d->tstask_completion);      ret = 0;   }     up(&d->sem);  return ret;}static void tsc2003_idev_close (struct input_dev *idev){  struct tsc2003_data *d = idev->private;  down_interruptible(&d->sem);  if (d->tstask)    {      send_sig(SIGKILL, d->tstask, 1);      wait_for_completion(&d->tstask_completion);    }  if (timer_pending(&d->penirq_timer))    del_timer(&d->penirq_timer);  up(&d->sem);  return;}#if defined(CONFIG_SYSFS) && defined(CONFIG_SENSORS_TSC2003_SYSFS)static ssize_t show_addr (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->client.addr);}static DEVICE_ATTR(addr, S_IRUGO, show_addr, NULL);static ssize_t show_vbat1 (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->vbat1);}static DEVICE_ATTR(vbat1, S_IRUGO, show_vbat1, NULL);static ssize_t show_vbat2 (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->vbat2);}static DEVICE_ATTR(vbat2, S_IRUGO, show_vbat2, NULL);static ssize_t show_in1 (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->in1);}static DEVICE_ATTR(in1, S_IRUGO, show_in1, NULL);static ssize_t show_in2 (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->in2);}static DEVICE_ATTR(in2, S_IRUGO, show_in2, NULL);static ssize_t show_temp0 (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->temp0);}static DEVICE_ATTR(temp0, S_IRUGO, show_temp0, NULL);static ssize_t show_temp1 (struct device *dev, char *buf){  struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  return sprintf(buf, "%d\n", d->temp1);}static DEVICE_ATTR(temp1, S_IRUGO, show_temp1, NULL);#warning "TODO: this daemon sometimes hangs the touchscreen daemon"#warning "TODO: under periods of heavy touch screen activity."#warning "TODO: Use with caution until the bug is squashed."static int tsc2003s_thread (void *v){  struct tsc2003_data *d = v;  daemonize(DRIVER_NAME "sd");  allow_signal(SIGKILL);  printk(KERN_INFO "%s: address 0x%x\n",         __FUNCTION__, d->client.addr);  while (!signal_pending(current))    {      if (!down_interruptible(&d->sem))        {          if (!timer_pending(&d->penirq_timer))            {              tsc2003_read_vbat1(d, d->pd, &d->vbat1);              tsc2003_read_vbat2(d, d->pd, &d->vbat2);              tsc2003_read_in1(d, d->pd, &d->in1);              tsc2003_read_in2(d, d->pd, &d->in2);              tsc2003_read_temp0(d, d->pd, &d->temp0);              tsc2003_read_temp1(d, d->pd, &d->temp1);            }          up(&d->sem);        }      set_task_state(current, TASK_INTERRUPTIBLE);      schedule_timeout(5 * HZ);    }  do_exit(0);}#endifstatic int tsc2003_detect_irq (struct tsc2003_data *d){	d->penirq = IRQ_GPIO(16);	//PWM0 GPIO	return 0;}/*static int tsc2003_probe (struct device *dev){  //struct platform_device *p = to_platform_device(dev);    struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver);  int ret = 0;    int error;   printk(KERN_ERR "TSC2003: tsc2003_probe probing...\n");   error = tsc2003_detect_irq(d);   if(error)   {	printk(KERN_ERR "TSC2003: IRQ probe failed\n");   }   if (d->penirq)   {      ret = request_irq(d->penirq, tsc2003_penirq, IRQF_TRIGGER_FALLING, DRIVER_NAME, d);      if (!ret)        {          printk(KERN_INFO "%s: irq %d\n", __FUNCTION__, d->penirq);        }       else        {	  printk(KERN_INFO "%s: cannot grab irq %d\n", __FUNCTION__, d->penirq);        }    }#if defined(CONFIG_SYSFS) && defined(CONFIG_SENSORS_TSC2003_SYSFS)  ret = kernel_thread(tsc2003s_thread, d, CLONE_KERNEL);  if (ret >= 0)    ret = 0;  device_create_file(dev, &dev_attr_addr);  device_create_file(dev, &dev_attr_vbat1);  device_create_file(dev, &dev_attr_vbat2);  device_create_file(dev, &dev_attr_in1);  device_create_file(dev, &dev_attr_in2);  device_create_file(dev, &dev_attr_temp0);  device_create_file(dev, &dev_attr_temp1);#endif  return ret;}*/static int tsc2003_driver_register (struct tsc2003_data *data){  struct input_dev *idev;  int ret = 0;  int error;    init_MUTEX(&data->sem);  init_timer(&data->penirq_timer);  data->penirq_timer.data = (unsigned long)data;  data->penirq_timer.function = tsc2003_pen_up;    error = tsc2003_detect_irq(data);   if(error)   {	printk(KERN_ERR "TSC2003: IRQ probe failed\n");   }   if (data->penirq)   {      ret = request_irq(data->penirq, tsc2003_penirq, IRQF_TRIGGER_FALLING, DRIVER_NAME, data);      if (!ret)        {          printk(KERN_INFO "%s: irq %d\n", __FUNCTION__, data->penirq);	  init_completion(&data->tstask_completion);	  init_completion(&data->penirq_completion);        }       else        {	  printk(KERN_ERR "%s: cannot grab irq %d\n", __FUNCTION__, data->penirq);        }    }    idev = input_allocate_device();  data->idev = idev;  idev->private = data;  idev->name = DRIVER_NAME;  idev->evbit[0] = BIT(EV_ABS);  idev->open = tsc2003_idev_open;  idev->close = tsc2003_idev_close;  idev->absbit[LONG(ABS_X)] = BIT(ABS_X);  idev->absbit[LONG(ABS_Y)] = BIT(ABS_Y);  idev->absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE);  input_set_abs_params(idev, ABS_X, 0, ADC_MAX, 0, 0);  input_set_abs_params(idev, ABS_Y, 0, ADC_MAX, 0, 0);  input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0);  if (!ret)  {    input_register_device(idev);        printk(KERN_INFO "tsc2003 - registering input device\n");  }  return ret;}static int tsc2003_i2c_attach_adapter(struct i2c_adapter *adapter){  printk(KERN_INFO "tsc2003 i2c touch screen controller\n");  printk(KERN_INFO "Bill Gatliff <bgat at billgatliff.com\n");  printk(KERN_INFO "Nicholas Chen <nchen at cs.umd.edu>\n");   return i2c_probe(adapter, &addr_data, tsc2003_i2c_detect);}static int tsc2003_i2c_detach_client(struct i2c_client *client){  int err;    struct tsc2003_data *d = i2c_get_clientdata(client);  free_irq(d->penirq,d);  input_unregister_device(d->idev);  if ((err = i2c_detach_client(client))) {    dev_err(&client->dev, "Client deregistration failed, "            "client not detached.\n");    return err;  }  return 0;}static struct i2c_driver tsc2003_driver = {  .driver = {	  .owner        = THIS_MODULE,	  .name         = DRIVER_NAME,   },  .attach_adapter    = tsc2003_i2c_attach_adapter,  .detach_client    = tsc2003_i2c_detach_client,  //  .command              = tsc2003_command,};static int tsc2003_i2c_detect (struct i2c_adapter *adapter, int address, int kind){  struct i2c_client *new_client;  struct tsc2003_data *data;  int err = 0;  const char *name = "";  if (!i2c_check_functionality(adapter,                               I2C_FUNC_SMBUS_BYTE_DATA                               | I2C_FUNC_I2C                               | I2C_FUNC_SMBUS_WORD_DATA))    goto exit;  data = kcalloc(1, sizeof(*data), GFP_KERNEL);  if (!data) {    err = -ENOMEM;    goto exit;  }  new_client = &data->client;  i2c_set_clientdata(new_client, data);  new_client->addr = address;  new_client->adapter = adapter;  new_client->driver = &tsc2003_driver;  new_client->flags = 0;  /* TODO: I'm pretty sure I'm not dealing with kind correctly */  if (kind == 0 /* identification */ || kind < 0 /* detection */)      kind = tsc2003;  if (kind == tsc2003)    name = DRIVER_NAME;  /* try a command, see if we get an ack;     if we do, assume it's our device */  printk(KERN_INFO "%s: probing address 0x%x\n",         __FUNCTION__, address);  err = tsc2003_powerdown(data);  if (err >= 0)    {      strlcpy(new_client->name, name, I2C_NAME_SIZE);      err = i2c_attach_client(new_client);      if (err) goto exit_free;      tsc2003_init_client(new_client);      err = tsc2003_driver_register(data);      if (err < 0) goto exit_free;           printk(KERN_INFO "%s: device address 0x%x attached.\n",             __FUNCTION__, address);      return 0;    }  /* failure to detect when everything else is ok isn't an error */  else err = 0; exit_free:  kfree(new_client); exit:  return err;}static int __init tsc2003_init(void){  return i2c_add_driver(&tsc2003_driver);}static void __exit tsc2003_exit(void){  i2c_del_driver(&tsc2003_driver);}MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>");MODULE_DESCRIPTION("TSC2003 Touch Screen Controller driver");MODULE_LICENSE("GPL");module_init(tsc2003_init);module_exit(tsc2003_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -