Chinaunix首页 | 论坛 | 博客
  • 博客访问: 50811
  • 博文数量: 19
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 105
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-27 15:16
个人简介

长期潜藏于CSDN http://blog.csdn.net/npjocj

文章分类
文章存档

2013年(1)

2012年(18)

我的朋友

分类:

2012-11-21 14:59:59

离写上一篇博文已经又过了一个星期啦,每天忙的几乎没时间写,趁着今天放假,继续写,补充完整。
接着上一节的,调用该驱动的probe函数,下面咱们就看看probe函数做了些啥事?
static int __devinit isa1200_probe(struct i2c_client *client,
   const struct i2c_device_id *id)
{
 struct isa1200_chip *haptic;
 struct isa1200_platform_data *pdata;
 /*取出client的平台数据*/
 pdata = client->dev.platform_data;
 /*如果平台数据的dev_setup不空的话,则调用该函数*/
 if (pdata->dev_setup) {
  ret = pdata->dev_setup(true);
 }
 
 /*分配一个isa1200_chip结构体变量,并赋值*/
 haptic = kzalloc(sizeof(struct isa1200_chip), GFP_KERNEL);
 haptic->client = client;
 haptic->enable = 0;
 haptic->pdata = pdata;
 
 /*调用pdata的power_on函数*/
 if (pdata->power_on) {
  ret = pdata->power_on(1);
  }
 
 /*继续初始化haptic变量*/
 spin_lock_init(&haptic->lock);
 INIT_WORK(&haptic->work, isa1200_chip_work);
 hrtimer_init(&haptic->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 haptic->timer.function = isa1200_vib_timer_func;
 /*register with timed output class*/
 haptic->dev.name = pdata->name;
 haptic->dev.get_time = isa1200_chip_get_time;
 haptic->dev.enable = isa1200_chip_enable;
 ret = timed_output_dev_register(&haptic->dev);
 
 /*把初始化好的haptic变量挂到client的驱动数据指针上*/
 i2c_set_clientdata(client, haptic);
 
 /*判断gpio是否可用?*/
 ret = gpio_is_valid(pdata->hap_en_gpio);
 if (ret) {
  /*如果可用,则请求该gpio*/
  ret = gpio_request(pdata->hap_en_gpio, "haptic_gpio");
 }
 ret = isa1200_setup(client);//设置client
 return ret;
}
下面主要看isa1200_setup(client);看都做了些神马?
static int isa1200_setup(struct i2c_client *client)
{
  /*取出刚才设置的client的driver data*/
  struct isa1200_chip *haptic = i2c_get_clientdata(client);
 
  /*提取pdata里面的值,并进行加工*/
  value = (haptic->pdata->smart_en << 3) |
  (haptic->pdata->is_erm << 5) |
  (haptic->pdata->ext_clk_en << 7);
 
  /*然后发送到client对应的控制器*/
  isa1200_write_reg(client, ISA1200_HCTRL1, value);
 /*继续组合值,这都是硬件寄存器相关的,就不细分啦*/
 if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
  temp = haptic->pdata->pwm_fd.pwm_div;
  value = ((temp >> 7) - 1);
 } 
 value |= (haptic->pdata->mode_ctrl << 3) |
  (haptic->pdata->overdrive_high << 5) |
  (haptic->pdata->overdrive_en << 5) |
  (haptic->pdata->chip_en << 7);
 
 /*把上面组合好的值发送到对应的client的寄存器中*/
 rc = isa1200_write_reg(client, ISA1200_HCTRL0, value);
}
下面最重要的要出场啦,这也是I2C的核心:
是啥呢?isa1200_write_reg(client, ISA1200_HCTRL0, value);函数,是怎么通信的呢?
static int isa1200_write_reg(struct i2c_client *client, int reg, u8 value)
{
 int ret;
 ret = i2c_smbus_write_byte_data(client, reg, value);
 return ret;
}
继续跟踪:
s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value)
{
 union i2c_smbus_data data;
 data.byte = value;
 return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
         I2C_SMBUS_WRITE, command,
         I2C_SMBUS_BYTE_DATA, &data);
}
看了半天还没出来,真是犹抱琵琶半遮面,终于要露脸啦:
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
     char read_write, u8 command, int protocol,
     union i2c_smbus_data *data)
{
 unsigned long orig_jiffies;
 int try;
 s32 res;
 flags &= I2C_M_TEN | I2C_CLIENT_PEC;
 
 if (adapter->algo->smbus_xfer) {
  rt_mutex_lock(&adapter->bus_lock);
  /* Retry automatically on arbitration loss */
  orig_jiffies = jiffies;
  for (res = 0, try = 0; try <= adapter->retries; try++) {
   res = adapter->algo->smbus_xfer(adapter, addr, flags,
       read_write, command,
       protocol, data);//这个是调用总线的算法中得函数
   if (res != -EAGAIN)
    break;
   if (time_after(jiffies,
           orig_jiffies + adapter->timeout))
    break;
  }
  rt_mutex_unlock(&adapter->bus_lock);
 } 
 return res;
}
上面总结下:I2C通信是,cpu调用I2C控制器的传输函数,这个根据控制器的不同要重写该函数,发往对应client的地址。进行通信。
上面说了半天,各个寄存器都设置好啦,马达已经处于就绪状态,但是怎么操作呢,接口呢,貌似一路走来,没有碰到给外部提供的接口,下一篇博文,就要去找找给上层提供的接口。

阅读(1021) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~