TP mster代码分析

这篇博客详细分析了Linux内核中msg21xx触摸屏驱动的probe函数,包括I2C通信、GPIO配置、中断处理、硬件信息获取等关键步骤。通过对i2c_client结构体的处理,实现对硬件设备的初始化和中断请求的注册,同时也涉及到了内核内存分配、中断管理以及设备树解析等方面。
摘要由CSDN通过智能技术生成

static int __devinit msg21xx_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
 int  err = 0;
 int ret = 0;
 int retval = 0;
 int rc =0;
 unsigned char dbbus_tx_data[3];
 int cnt = 0;

 struct msg21xx_ts_data *msg;
 // modified by yangze for hardware devices info (x310) 2013-10-11 begin 
 /* Added by zengguang to increase TP hardware info. (X211) 2013.5.5 */
#ifdef CONFIG_GET_HARDWARE_INFO 
 u8 dbbus_tx_data[3];
 u8 dbbus_rx_data[4]={0}; 
 dbbus_tx_data[0] = 0x53;
 dbbus_tx_data[1] = 0x00;
 dbbus_tx_data[2] = 0x2A;
#endif 
 /* Added by zengguang to increase TP hardware info. (X211) 2013.5.5 */
 // modified by yangze for hardware devices info (x310) 2013-10-11 end

#ifdef __FIRMWARE_UPDATE__
 // struct platform_device *pdev;
#endif
 msg21xx_i2c_client = client;
 TP_DEBUG (" \n"); 
 if (!i2c_check_functionality(msg21xx_i2c_client->adapter, I2C_FUNC_I2C)) //用来判定设配器的能力,函数用于返回algorithm所支持的通信协议,比如I2C_FUNC_I2C,I2C_FUNC_10BIT_ADDR等  及sys/bus/i2c/devices下的设备
 {
  printk("I2C check functionality failed.");
  return -ENODEV;    //没找到I2C设备
 }


#ifdef __CHIP_MSG_2133A__
 dbbus_tx_data[0] = 0x53;
 dbbus_tx_data[1] = 0x00;
 dbbus_tx_data[2] = 0x2A;
#else
 dbbus_tx_data[0] = 0x53;
 dbbus_tx_data[1] = 0x00;
 dbbus_tx_data[2] = 0x74;
#endif
// printk("<0>""111111111 wax->%s\n",__FUNCTION__);
 TP_DEBUG (" i2cseq start\n"); 
#if 1
loop: err = HalTscrCDevWriteI2CSeq(FW_ADDR_MSG20XX_TP, &dbbus_tx_data[0], 3);   //i2c  收发数据
 TP_DEBUG (" i2cseq err is %d\n",err); 
// printk("msg2138 msg21xx_ts_probe err = %d\n",err); 
 if (err < 0) {
  cnt++;
  if (cnt == 5)
   return -ENODEV;
  goto  loop;
 }
 TP_DEBUG (" i2cseq end\n"); 
// printk("<0>""222222222 wax->%s\n",__FUNCTION__);
#endif
 if (msg21xx_i2c_client->dev.of_node) {    //判断设备节点是否存在
  msg = devm_kzalloc(&msg21xx_i2c_client->dev,   //devm_kzalloc:为i2c设备pdev 的私有数据分配内存,长度struct octeon_mdiobus的长度
    sizeof(*msg),
    GFP_KERNEL);  //GFP_KERNEL是内核内存分配时最常用的,无内存可用时可引起休眠。
  if (!msg) {
   dev_err(&msg21xx_i2c_client->dev, "Failed to allocate memory\n");
   return -ENOMEM;
  }
  memset(msg, 0, sizeof(*msg));   

  retval = msg21xx_parse_dt(&msg21xx_i2c_client->dev, msg);
  if (retval)
   return retval;
 } else {
  msg = kzalloc(sizeof(*msg), GFP_KERNEL);  //用kzalloc申请内存的时候, 效果等同于先是用 kmalloc() 申请空间 , 然后用 memset() 来初始化 ,所有申请的元素都被初始化为 0.
 }
 if (gpio_is_valid(msg->irq_gpio))    判断GPIO是否有效,有效返回0
 {
  /* configure touchscreen irq gpio */
  retval = gpio_request(msg->irq_gpio, "msg21xx_irq_gpio");   其原型为 int gpio_request(unsigned gpio, const char *label) 先说说其参数,gpio则为你要申请的哪一个管脚,label则是为其取一个名字。debugfs有效,一个/sys/kernel/debug/gpio文件在那里将被找到
  if (retval)
  {
   printk("unable to request gpio [%d]\n",msg->irq_gpio);
   return retval;
  }
 }

 if (gpio_is_valid(msg->reset_gpio))
 {
  /* configure touchscreen reset out gpio */
  retval = gpio_request(msg->reset_gpio,"msg21xx_reset_gpio");
  if (retval)
  {
   printk("unable to request gpio [%d]\n",msg->reset_gpio);
   return retval;
  }
 }
 msg21xx_irq= gpio_to_irq(msg->irq_gpio); /*Added by liumx for tp irq 2013.11.22*/    // gpio_to_irq()返回的中断编号可以传给request_irq()和free_irq()。内核通过调用该函数将gpio端口转换为中断,在用户空间也有类似方法
 msg->vdd = regulator_get(&msg21xx_i2c_client->dev, "vdd");   //dev 是设备“Vcc”一个字符串代表,校准器(regulator)然后返回一个指针,也是regulator_put(regulator)使用的。
 if (IS_ERR(msg->vdd))
  printk("regulator_get  vdd  fail");
 ret=regulator_set_voltage(msg->vdd, 2850000, 2850000);   //int regulator_set_voltage(regulator, int min_uV, int max_uV);  消费者可以申请提供给它们的电压
 if(ret){
  printk("regulator_set_voltage vdd  fail  ");
  return ret;
 }

 /*
    msg->vcc_i2c = regulator_get(&msg21xx_i2c_client->dev, "vcc_i2c");
    if (IS_ERR(msg->vcc_i2c)) {
    rc = PTR_ERR(msg->vcc_i2c);
    dev_err(&msg21xx_i2c_client->dev,
    "Regulator get failed vcc_i2c rc=%d\n", rc);
    }

    if (regul

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值