OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4434|回复: 8

其他板子的 i2c 驱动代码套路很不一样,懵逼了不会写了

[复制链接]

15

主题

68

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-9-10
在线时间
104 小时
发表于 2020-8-3 22:05:55 | 显示全部楼层 |阅读模式
25金钱
是这样的,我有一块 exynos4412的开发板, 屏幕的触摸芯片是 I2C 接口的FT5406芯片,开发板的系统内核是 linux 4.14。 我看到这个芯片的驱动写得就和正点原子的 I2C 驱动很不一样, 也不能参照着正点原子的应用代码来写应用层了。 大家来看看这个格式的驱动应该怎么写应用层 ??

  1. /*
  2. * drivers/input/touchscreen/ft5x0x_ts.c
  3. *
  4. * FocalTech ft5x0x TouchScreen driver.
  5. *
  6. * Copyright (c) 2010 Focal tech Ltd.
  7. *
  8. * This software is licensed under the terms of the GNU General Public
  9. * License version 2, as published by the Free Software Foundation, and
  10. * may be copied, distributed, and modified under those terms.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. * GNU General Public License for more details.
  16. *
  17. */

  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/i2c.h>
  21. #include <linux/input.h>
  22. #include <linux/delay.h>
  23. #include <linux/slab.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/irq.h>
  26. #include <linux/gpio.h>
  27. #include <linux/platform_device.h>
  28. #ifdef CONFIG_HAS_EARLYSUSPEND
  29. #include <linux/earlysuspend.h>
  30. #endif

  31. #include <linux/regulator/consumer.h>

  32. #include <linux/of_gpio.h>

  33. #include "ft5x06_ts.h"

  34. /* NOTE: support mulititouch only */
  35. #ifdef CONFIG_ANDROID_PARANOID_NETWORK        //CONFIG_STAGING        //in linux Qt single report
  36. #define CONFIG_FT5X0X_MULTITOUCH                1
  37. #endif

  38. int TOUCH_MAX_X = 1024;
  39. int TOUCH_MAX_Y = 768;

  40. #if defined(CONFIG_LVDS_7_0_800x1280)
  41. int type = 1;
  42. #elif defined(CONFIG_LVDS_9_7_1024x768)
  43. int type = 0;
  44. #elif defined(CONFIG_RGB_7_0_1024x600)
  45. int type = 3;
  46. #elif defined(CONFIG_RGB_5_0_800x480)
  47. int type = 4;
  48. #endif




  49. static int swap_xy = 0;
  50. static int scal_xy = 0;

  51. int touch_size = 0;        //0:1024*768 or 1:1280*800
  52. /*---------------------------------------------------------
  53. * Chip I/O operations
  54. */

  55. static int ft5x0x_i2c_rxdata(struct i2c_client *this_client, char *rxdata, int length) {
  56.         int ret;
  57.         struct i2c_msg msgs[] = {
  58.                 {
  59.                         .addr        = this_client->addr,
  60.                         .flags        = 0,
  61.                         .len        = 1,
  62.                         .buf        = rxdata,
  63.                 },
  64.                 {
  65.                         .addr        = this_client->addr,
  66.                         .flags        = I2C_M_RD,
  67.                         .len        = length,
  68.                         .buf        = rxdata,
  69.                 },
  70.         };

  71.         ret = i2c_transfer(this_client->adapter, msgs, 2);
  72.         if (ret < 0)
  73.                 pr_err("%s: i2c read error: %d\n", __func__, ret);

  74.         return ret;
  75. }

  76. static int ft5x0x_read_reg(struct i2c_client *this_client, u8 addr, u8 *pdata)
  77. {
  78.         u8 buf[4] = { 0 };
  79.         struct i2c_msg msgs[] = {
  80.                 {
  81.                         .addr        = this_client->addr,
  82.                         .flags        = 0,
  83.                         .len        = 1,
  84.                         .buf        = buf,
  85.                 },
  86.                 {
  87.                         .addr        = this_client->addr,
  88.                         .flags        = I2C_M_RD,
  89.                         .len        = 1,
  90.                         .buf        = buf,
  91.                 },
  92.         };
  93.         int ret;

  94.         buf[0] = addr;

  95.         ret = i2c_transfer(this_client->adapter, msgs, 2);
  96.         if (ret < 0) {
  97.                 pr_err("read reg (0x%02x) error, %d\n", addr, ret);
  98.         } else {
  99.                 *pdata = buf[0];
  100.         }

  101.         return ret;
  102. }

  103. static int ft5x0x_read_fw_ver(struct ft5x0x_ts_data *ts, unsigned char *val)
  104. {
  105.         int ret;

  106.         *val = 0xff;
  107.         ret = ft5x0x_read_reg(ts->client, FT5X0X_REG_FIRMID, val);
  108.         if (*val == 0x06) {
  109. #if 0
  110.                 swap_xy = 1;
  111.                 scal_xy = 1;
  112. #endif
  113.         } else {
  114.                 /* TODO: Add support for other version */
  115.         }

  116.         return ret;
  117. }


  118. /*---------------------------------------------------------
  119. * Touch core support
  120. */

  121. static void ft5x0x_ts_report(struct ft5x0x_ts_data *ts) {
  122.         struct ft5x0x_event *event = &ts->event;
  123.         int x, y;
  124.         int i = 0;

  125. #ifdef CONFIG_FT5X0X_MULTITOUCH
  126.         for (i = 0; i < event->touch_point; i++) {
  127.                 if(touch_size != 1)
  128.                         event->x[i] = ts->screen_max_x - event->x[i];
  129.                 //event->y[i] = ts->screen_max_y - event->y[i];
  130. #ifdef CONFIG_PRODUCT_SHENDAO
  131.                 event->y[i] = ts->screen_max_y - event->y[i];
  132. #endif
  133.                
  134.                 if (swap_xy) {
  135.                         x = event->y[i];
  136.                         y = event->x[i];
  137.                 } else {
  138.                         x = event->x[i];
  139.                         y = event->y[i];
  140.                 }

  141.                 if (scal_xy) {
  142.                         x = (x * ts->screen_max_x) / TOUCH_MAX_X;
  143.                         y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
  144.                 }
  145.        
  146.                 if(0 == touch_size)
  147.                 {
  148.                         x = ts->screen_max_x - x;
  149.                 }       

  150.                 printk("x = %d, y = %d\n", x, y);
  151.                 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
  152.                 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
  153.                 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 64);
  154.                 input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i);
  155.                 input_mt_sync(ts->input_dev);


  156. /*
  157.                 //printk("x = %d, y = %d\n", x, y);
  158.                 input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
  159.                 input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);

  160.                 input_report_abs(ts->input_dev, ABS_MT_PRESSURE, event->pressure);
  161.                 input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure);
  162.                 input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, i);

  163.                 input_mt_sync(ts->input_dev);
  164. */
  165.         }
  166. #else
  167.         if (event->touch_point == 1) {
  168.                 if (swap_xy) {
  169.                         x = event->y[i];
  170.                         y = event->x[i];
  171.                 } else {
  172.                         x = event->x[i];
  173.                         y = event->y[i];
  174.                 }

  175.                 if (scal_xy) {
  176.                         x = (x * ts->screen_max_x) / TOUCH_MAX_X;
  177.                         y = (y * ts->screen_max_y) / TOUCH_MAX_Y;
  178.                 }

  179.                 input_report_abs(ts->input_dev, ABS_X, x);
  180.                 input_report_abs(ts->input_dev, ABS_Y, y);
  181.                 input_report_abs(ts->input_dev, ABS_PRESSURE, event->pressure);
  182.         }

  183.         input_report_key(ts->input_dev, BTN_TOUCH, 1);
  184. #endif

  185.         input_sync(ts->input_dev);
  186. }

  187. static void ft5x0x_ts_release(struct ft5x0x_ts_data *ts) {
  188. #ifdef CONFIG_FT5X0X_MULTITOUCH
  189. #if 0
  190.         /* NOT needed for ICS */
  191.         input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0);
  192. #endif
  193.         input_mt_sync(ts->input_dev);
  194. #else
  195.         input_report_abs(ts->input_dev, ABS_PRESSURE, 0);
  196.         input_report_key(ts->input_dev, BTN_TOUCH, 0);
  197. #endif

  198.         input_sync(ts->input_dev);
  199. }

  200. static int ft5x0x_read_data(struct ft5x0x_ts_data *ts) {
  201.         struct ft5x0x_event *event = &ts->event;
  202.         u8 buf[64] = { 0 };
  203.         int ret;

  204. #ifdef CONFIG_FT5X0X_MULTITOUCH
  205.         ret = ft5x0x_i2c_rxdata(ts->client, buf, 63);
  206. #else
  207.         ret = ft5x0x_i2c_rxdata(ts->client, buf, 7);
  208. #endif
  209.         if (ret < 0) {
  210.                 printk("%s: read touch data failed, %d\n", __func__, ret);
  211.                 return ret;
  212.         }

  213.         memset(event, 0, sizeof(struct ft5x0x_event));

  214.         event->touch_point = buf[2] & 0x0F;

  215.         if (!event->touch_point) {
  216.                 ft5x0x_ts_release(ts);
  217.                 return 1;
  218.         }
  219.         //printk("point = %d\n", event->touch_point);
  220. #ifdef CONFIG_FT5X0X_MULTITOUCH
  221.         switch (event->touch_point) {
  222.                 case 10:
  223.                         event->x[9] = (s16)(buf[57] & 0x0F)<<8 | (s16)buf[58];
  224.                         event->y[9] = (s16)(buf[59] & 0x0F)<<8 | (s16)buf[60];
  225.                 case 9:
  226.                         event->x[8] = (s16)(buf[51] & 0x0F)<<8 | (s16)buf[52];
  227.                         event->y[8] = (s16)(buf[53] & 0x0F)<<8 | (s16)buf[54];
  228.                 case 8:
  229.                         event->x[7] = (s16)(buf[45] & 0x0F)<<8 | (s16)buf[46];
  230.                         event->y[7] = (s16)(buf[47] & 0x0F)<<8 | (s16)buf[48];
  231.                 case 7:
  232.                         event->x[6] = (s16)(buf[39] & 0x0F)<<8 | (s16)buf[40];
  233.                         event->y[6] = (s16)(buf[41] & 0x0F)<<8 | (s16)buf[42];
  234.                 case 6:
  235.                         event->x[5] = (s16)(buf[33] & 0x0F)<<8 | (s16)buf[34];
  236.                         event->y[5] = (s16)(buf[35] & 0x0F)<<8 | (s16)buf[36];
  237.                 case 5:
  238.                         event->x[4] = (s16)(buf[0x1b] & 0x0F)<<8 | (s16)buf[0x1c];
  239.                         event->y[4] = (s16)(buf[0x1d] & 0x0F)<<8 | (s16)buf[0x1e];
  240.                 case 4:
  241.                         event->x[3] = (s16)(buf[0x15] & 0x0F)<<8 | (s16)buf[0x16];
  242.                         event->y[3] = (s16)(buf[0x17] & 0x0F)<<8 | (s16)buf[0x18];
  243.                         //printk("x:%d, y:%d\n", event->x[3], event->y[3]);
  244.                 case 3:
  245.                         event->x[2] = (s16)(buf[0x0f] & 0x0F)<<8 | (s16)buf[0x10];
  246.                         event->y[2] = (s16)(buf[0x11] & 0x0F)<<8 | (s16)buf[0x12];
  247.                         //printk("x:%d, y:%d\n", event->x[2], event->y[2]);
  248.                 case 2:
  249.                         event->x[1] = (s16)(buf[0x09] & 0x0F)<<8 | (s16)buf[0x0a];
  250.                         event->y[1] = (s16)(buf[0x0b] & 0x0F)<<8 | (s16)buf[0x0c];
  251.                         //printk("x:%d, y:%d\n", event->x[1], event->y[1]);
  252.                 case 1:
  253.                         event->x[0] = (s16)(buf[0x03] & 0x0F)<<8 | (s16)buf[0x04];
  254.                         event->y[0] = (s16)(buf[0x05] & 0x0F)<<8 | (s16)buf[0x06];
  255.                         //printk("x:%d, y:%d\n", event->x[0], event->y[0]);
  256.                         break;
  257.                 default:
  258.                         printk("%s: invalid touch data, %d\n", __func__, event->touch_point);
  259.                         return -1;
  260.         }
  261. #else
  262.         if (event->touch_point == 1) {
  263.                 event->x[0] = (s16)(buf[0x03] & 0x0F)<<8 | (s16)buf[0x04];
  264.                 event->y[0] = (s16)(buf[0x05] & 0x0F)<<8 | (s16)buf[0x06];
  265.         }
  266. #endif

  267.         event->pressure = 200;

  268.         return 0;
  269. }

  270. static void ft5x0x_ts_pen_irq_work(struct work_struct *work) {
  271.         struct ft5x0x_ts_data *ts = container_of(work, struct ft5x0x_ts_data, work);

  272.         if (!ft5x0x_read_data(ts)) {
  273.                 ft5x0x_ts_report(ts);
  274.         }

  275.         enable_irq(ts->client->irq);
  276. }

  277. static irqreturn_t ft5x0x_ts_interrupt(int irq, void *dev_id) {
  278.         struct ft5x0x_ts_data *ts = dev_id;

  279.         //printk("%s(%d)\n", __FUNCTION__, __LINE__);

  280.         disable_irq_nosync(ts->client->irq);

  281.         if (!work_pending(&ts->work)) {
  282.                 queue_work(ts->queue, &ts->work);
  283.         }

  284.         return IRQ_HANDLED;
  285. }


  286. /*---------------------------------------------------------
  287. * I2C client driver functions
  288. */

  289. #ifdef CONFIG_HAS_EARLYSUSPEND
  290. static void ft5x0x_ts_suspend(struct early_suspend *handler)
  291. {
  292. #if 1
  293.         struct ft5x0x_ts_data *ts;

  294.         ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);

  295.         disable_irq(ts->client->irq);
  296.         flush_workqueue(ts->queue);
  297.         cancel_work_sync(&ts->work);
  298.         //flush_workqueue(ts->queue);

  299.         //ft5x0x_set_reg(FT5X0X_REG_PMODE, PMODE_HIBERNATE);
  300. #endif
  301. #if 0
  302.         if( IS_ERR_OR_NULL(dc33v_tp) )
  303.         {
  304.                 printk( "error on dc33_tp regulator disable : tp_regulator is null\n");
  305.                 //return;
  306.         }
  307.         else
  308.         {
  309.                 regulator_force_disable(dc33v_tp);
  310.         }
  311. #endif
  312.         printk("ft5x0x_ts: suspended\n");
  313. }

  314. static void ft5x0x_ts_resume(struct early_suspend *handler)
  315. {
  316.         struct ft5x0x_ts_data *ts;

  317.         ts = container_of(handler, struct ft5x0x_ts_data, early_suspend);
  318. #if 1
  319.         /* Wakeup: output_L --> 100ms --> output_H --> 100ms */
  320.         enable_irq(ts->client->irq);
  321. #endif

  322.         printk("ft5x0x_ts: resumed\n");
  323. }
  324. #endif

  325. static int ft5x0x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
  326. {
  327.         struct device_node *np = client->dev.of_node;
  328.         struct ft5x0x_i2c_platform_data *pdata;
  329.         struct ft5x0x_ts_data *ts;
  330.         struct input_dev *input_dev;
  331.         unsigned char val;
  332.         int err = -EINVAL;

  333.         printk("\n\r\n\r\n\r\n\r\n\r  static int ft5x0x_ts_probe(struct i2c_client *client  \n\r\n\r\n\r\n\r\n\r");

  334.         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  335.                 err = -ENODEV;
  336.                 goto exit_check_functionality_failed;
  337.         }

  338.         ts = kzalloc(sizeof(*ts), GFP_KERNEL);
  339.         if (!ts) {
  340.                 err = -ENOMEM;
  341.                 goto exit_alloc_data_failed;
  342.         }

  343.         //printk("****** ft5x: client irq = %d\n", client->irq);
  344. #if defined(CONFIG_LVDS_7_0_800x1280)
  345.         ts->screen_max_x = 800;//768;//800;//800;//1024;
  346.         ts->screen_max_y = 1280;//1024;//1280;//600;
  347.         ts->pressure_max = 255;
  348. #elif defined(CONFIG_LVDS_9_7_1024x768)
  349.         ts->screen_max_x = 768;//768;//800;//800;//1024;
  350.         ts->screen_max_y = 1024;//1024;//1280;//600;
  351.         ts->pressure_max = 255;
  352. #elif defined(CONFIG_RGB_7_0_1024x600)
  353.         ts->screen_max_x = 1024;//768;//800;//800;//1024;
  354.         ts->screen_max_y = 600;//1024;//1280;//600;
  355.         ts->pressure_max = 255;
  356. #elif defined(CONFIG_RGB_5_0_800x480)
  357.         ts->screen_max_x = 800;//768;//800;//800;//1024;
  358.         ts->screen_max_y = 480;//1024;//1280;//600;
  359.         ts->pressure_max = 255;
  360. #endif

  361.         ts->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
  362.         if (ts->reset_gpio == -EPROBE_DEFER)
  363.                 return ts->reset_gpio;
  364.         if (ts->reset_gpio < 0) {
  365.                 dev_err(&client->dev, "error acquiring reset gpio: %d\n",
  366.                          ts->reset_gpio);
  367.                 return ts->reset_gpio;
  368.         }
  369.        
  370.         err = devm_gpio_request_one(&client->dev, ts->reset_gpio, 0,
  371.                                        "reset-gpios");
  372.         if(err) {
  373.                 dev_err(&client->dev, "error requesting reset gpio: %d\n",err);
  374.                 return err;
  375.         }
  376.        
  377.         gpio_set_value(ts->reset_gpio, 0);
  378.         mdelay(200);
  379.         gpio_set_value(ts->reset_gpio, 1);
  380.         msleep(300);

  381.         INIT_WORK(&ts->work, ft5x0x_ts_pen_irq_work);

  382.         ts->client = client;
  383.         ts->gpio_irq = client->irq;
  384.         i2c_set_clientdata(client, ts);

  385.         ts->queue = create_singlethread_workqueue(dev_name(&client->dev));
  386.         if (!ts->queue) {
  387.                 err = -ESRCH;
  388.                 goto exit_create_singlethread;
  389.         }

  390.         input_dev = input_allocate_device();
  391.         if (!input_dev) {
  392.                 err = -ENOMEM;
  393.                 dev_err(&client->dev, "failed to allocate input device\n");
  394.                 goto exit_input_dev_alloc_failed;
  395.         }

  396.         ts->input_dev = input_dev;

  397.         set_bit(EV_SYN, input_dev->evbit);
  398.         set_bit(EV_ABS, input_dev->evbit);
  399.         set_bit(EV_KEY, input_dev->evbit);

  400. #ifdef CONFIG_FT5X0X_MULTITOUCH

  401.         input_set_abs_params(input_dev, ABS_MT_POSITION_X,0, ts->screen_max_x, 0, 0);
  402.         input_set_abs_params(input_dev, ABS_MT_POSITION_Y,0, ts->screen_max_y, 0, 0);

  403.         input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 100, 0, 0);
  404.         input_set_abs_params(input_dev, ABS_MT_TRACKING_ID,0, FT5X0X_PT_MAX, 0, 0);

  405.         set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

  406. /*

  407.         set_bit(ABS_MT_TRACKING_ID, input_dev->absbit);
  408.         set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
  409.         set_bit(ABS_MT_WIDTH_MAJOR, input_dev->absbit);
  410.         set_bit(ABS_MT_POSITION_X, input_dev->absbit);
  411.         set_bit(ABS_MT_POSITION_Y, input_dev->absbit);

  412.         input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ts->screen_max_x, 0, 0);
  413.         input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ts->screen_max_y, 0, 0);
  414.         input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, ts->pressure_max, 0, 0);
  415.         input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, 200, 0, 0);
  416.         input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, FT5X0X_PT_MAX, 0, 0);
  417. */
  418. #else
  419.         set_bit(ABS_X, input_dev->absbit);
  420.         set_bit(ABS_Y, input_dev->absbit);
  421.         set_bit(ABS_PRESSURE, input_dev->absbit);
  422.         set_bit(BTN_TOUCH, input_dev->keybit);

  423.         input_set_abs_params(input_dev, ABS_X, 0, ts->screen_max_x, 0, 0);
  424.         input_set_abs_params(input_dev, ABS_Y, 0, ts->screen_max_y, 0, 0);
  425.         input_set_abs_params(input_dev, ABS_PRESSURE, 0, ts->pressure_max, 0 , 0);
  426. #endif

  427.         input_dev->name = FT5X0X_NAME;
  428.         input_dev->id.bustype = BUS_I2C;
  429.         input_dev->id.vendor = 0x12FA;
  430.         input_dev->id.product = 0x2143;
  431.         input_dev->id.version = 0x0100;

  432.         err = input_register_device(input_dev);
  433.         if (err) {
  434.                 input_free_device(input_dev);
  435.                 dev_err(&client->dev, "failed to register input device %s, %d\n",
  436.                                 dev_name(&client->dev), err);
  437.                 goto exit_input_dev_alloc_failed;
  438.         }

  439.         msleep(3);

  440.         unsigned int i = 0;
  441.         printk("read fw ver %d...\n", i++);
  442.         err = ft5x0x_read_fw_ver(ts, &val);

  443.         if (err < 0) {
  444.                 dev_err(&client->dev, "chip not found\n");
  445.                 goto exit_irq_request_failed;
  446.         }

  447.         err = request_irq(client->irq, ft5x0x_ts_interrupt,
  448.                         IRQ_TYPE_EDGE_FALLING /*IRQF_TRIGGER_FALLING*/, "ft5x0x_ts", ts);
  449.         if (err < 0) {
  450.                 dev_err(&client->dev, "Request IRQ %d failed, %d\n", client->irq, err);
  451.                 goto exit_irq_request_failed;
  452.         }

  453.         disable_irq(client->irq);

  454.         dev_info(&client->dev, "Firmware version 0x%02x\n", val);

  455. #ifdef CONFIG_HAS_EARLYSUSPEND
  456.         ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;//EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;
  457.         ts->early_suspend.suspend = ft5x0x_ts_suspend;
  458.         ts->early_suspend.resume = ft5x0x_ts_resume;
  459.         register_early_suspend(&ts->early_suspend);
  460. #endif

  461.         enable_irq(client->irq);

  462.         dev_info(&client->dev, "FocalTech ft5x0x TouchScreen initialized\n");
  463.         return 0;

  464. exit_irq_request_failed:
  465.         input_unregister_device(input_dev);

  466. exit_input_dev_alloc_failed:
  467.         cancel_work_sync(&ts->work);
  468.         destroy_workqueue(ts->queue);

  469. exit_create_singlethread:
  470.         i2c_set_clientdata(client, NULL);

  471. exit_no_pdata:
  472.         kfree(ts);

  473. exit_alloc_data_failed:
  474. exit_check_functionality_failed:
  475.         dev_err(&client->dev, "probe ft5x0x TouchScreen failed, %d\n", err);

  476.         return err;
  477. }

  478. static int ft5x0x_ts_remove(struct i2c_client *client) {
  479.         struct ft5x0x_ts_data *ts = i2c_get_clientdata(client);

  480. #ifdef CONFIG_HAS_EARLYSUSPEND
  481.         unregister_early_suspend(&ts->early_suspend);
  482. #endif

  483.         if (client->irq) {
  484.                 free_irq(client->irq, ts);
  485.         }

  486.         cancel_work_sync(&ts->work);
  487.         destroy_workqueue(ts->queue);

  488.         i2c_set_clientdata(client, NULL);
  489.         input_unregister_device(ts->input_dev);
  490.         if (ts->input_dev)
  491.                 kfree(ts->input_dev);

  492.         kfree(ts);

  493.         return 0;
  494. }

  495. static const struct i2c_device_id ft5x0x_ts_id[] = {
  496.         { FT5X0X_NAME, 0 },
  497.         { }
  498. };

  499. MODULE_DEVICE_TABLE(i2c, ft5x0x_ts_id);

  500. #ifdef CONFIG_OF
  501. static const struct of_device_id ft5x0x_of_match[] = {
  502.         { .compatible = "edt,edt-ft5406" },
  503.         { /* sentinel */ }
  504. };
  505. MODULE_DEVICE_TABLE(of, ft5x0x_of_match);
  506. #endif

  507. static struct i2c_driver ft5x0x_ts_driver = {
  508.         .probe                = ft5x0x_ts_probe,
  509.         .remove                = ft5x0x_ts_remove,
  510.         .id_table        = ft5x0x_ts_id,
  511.         .driver        = {
  512.                 .name        = FT5X0X_NAME,
  513.                 .owner        = THIS_MODULE,
  514.                 .of_match_table = of_match_ptr(ft5x0x_of_match),
  515.         },
  516. };

  517. static int __init ft5x0x_ts_init(void)
  518. {
  519.         int ret;

  520.         printk("\n\r\n\r\n\r\n\r\n\r\n\r  static int __init ft5x0x_ts_init(void)  \n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r  ");

  521.         if(0x00 == type)  //9.7
  522.         {
  523.                 TOUCH_MAX_X = 1024;
  524.                 TOUCH_MAX_Y = 768;

  525. #ifdef CONFIG_VT        //for Ubuntu
  526.                 touch_size = 1;
  527.                 scal_xy = 1;
  528. #else
  529.                 touch_size = 1;//0;
  530.                 scal_xy = 1;
  531. #endif
  532.         }
  533.         else if(0x01 == type) //7.0
  534.         {
  535.                 TOUCH_MAX_X = 1280;
  536.                 TOUCH_MAX_Y = 800;
  537. #ifdef CONFIG_VT        //for Ubuntu
  538.                 TOUCH_MAX_X = 800;//1280;
  539.                 TOUCH_MAX_Y = 1280;//800;

  540.                 scal_xy = 1;
  541.                 touch_size = 0;
  542. #else
  543.                 touch_size = 0;//1;
  544. #endif
  545.         }
  546.         else if(0x02 == type)  //4.3
  547.         {
  548.                 ;
  549.         }
  550.         else if(0x03 == type)   //1024x600
  551.         {
  552.                 TOUCH_MAX_X = 1024;
  553.                 TOUCH_MAX_Y = 600;

  554.                 touch_size = 0;//0;
  555.                 scal_xy = 0;
  556.         }
  557.         else if(0x04 == type)   //800x480
  558.         {
  559.                 TOUCH_MAX_X = 800;
  560.                 TOUCH_MAX_Y = 480;

  561.                 touch_size = 0;
  562.                 scal_xy = 0;
  563.         }

  564.         if(1 == touch_size)
  565.         {
  566.                 swap_xy = 1;
  567.         }
  568.         else
  569.         {
  570.                 swap_xy = 0;
  571.         }

  572.         return i2c_add_driver(&ft5x0x_ts_driver);
  573. }

  574. static void __exit ft5x0x_ts_exit(void)
  575. {
  576.         i2c_del_driver(&ft5x0x_ts_driver);
  577. }

  578. late_initcall(ft5x0x_ts_init);
  579. module_exit(ft5x0x_ts_exit);


  580. MODULE_AUTHOR("<wenfs@Focaltech-systems.com>");
  581. MODULE_DESCRIPTION("FocalTech ft5x0x TouchScreen driver");
  582. MODULE_LICENSE("GPL");
复制代码


最佳答案

查看完整内容[请看2#楼]

连续硬杠了好几天,终于用最基础的方式读到了I2C的数据,总算迈过去了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

68

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-9-10
在线时间
104 小时
 楼主| 发表于 2020-8-3 22:05:56 | 显示全部楼层
无忧花开 发表于 2020-8-6 17:36
都差不多的,只是你不会用
要是理解了就会用了,还是先看看教程,跟着教程先学一下,举一反三

连续硬杠了好几天,终于用最基础的方式读到了I2C的数据,总算迈过去了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2020-8-5 00:34:13 | 显示全部楼层
帮顶
回复

使用道具 举报

15

主题

68

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-9-10
在线时间
104 小时
 楼主| 发表于 2020-8-5 15:30:02 | 显示全部楼层

linux的东西还是复杂, 做着做着全懵了
回复

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2179
金钱
2179
注册时间
2018-8-27
在线时间
258 小时
发表于 2020-8-6 09:30:50 | 显示全部楼层
lccpcc 发表于 2020-8-5 15:30
linux的东西还是复杂, 做着做着全懵了

你都没理解
森罗万象
回复

使用道具 举报

15

主题

68

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-9-10
在线时间
104 小时
 楼主| 发表于 2020-8-6 13:59:37 | 显示全部楼层

初学者是这样了,也没找到什么好的书或者教程,我的开发板也不是正点原子的,发现不同人写的i2c驱动是五花八门,各种套路都有  。  我这开发板上面有关i2c总线的都是FT5406,声卡WM8960,还有一个PMU也是用I2C的。这些东西的驱动一个比一个复杂。这个FT5406的还牵扯到了那些input的东西。而我只是想要一个简单的驱动,能在应用层读写寄存器的就行
回复

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2179
金钱
2179
注册时间
2018-8-27
在线时间
258 小时
发表于 2020-8-6 14:11:27 | 显示全部楼层
lccpcc 发表于 2020-8-6 13:59
初学者是这样了,也没找到什么好的书或者教程,我的开发板也不是正点原子的,发现不同人写的i2c驱动是五 ...

你学驱动跟板子没关系  只是你不会学而已
森罗万象
回复

使用道具 举报

15

主题

68

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2016-9-10
在线时间
104 小时
 楼主| 发表于 2020-8-6 17:23:32 | 显示全部楼层
xiaotaotao 发表于 2020-8-6 14:11
你学驱动跟板子没关系  只是你不会学而已

这个驱动应该怎么改成那种可以在应用层里面用read函数读取寄存器值的那种形式?
回复

使用道具 举报

0

主题

134

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
301
金钱
301
注册时间
2020-5-8
在线时间
20 小时
发表于 2020-8-6 17:36:31 | 显示全部楼层
都差不多的,只是你不会用
要是理解了就会用了,还是先看看教程,跟着教程先学一下,举一反三
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 07:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表