IT技术互动交流平台

rk3288的SDK修复cm3218光敏驱动bug

来源:IT165收集  发布日期:2015-03-31 20:16:48

瑞芯的Android 4.4的SDK中kernel的补丁如下:

diff --git a/arch/arm/boot/dts/rk3288-tb_8846.dts b/arch/arm/boot/dts/rk3288-tb_8846.dts
index c92d973..850fd42 100644
--- a/arch/arm/boot/dts/rk3288-tb_8846.dts
+++ b/arch/arm/boot/dts/rk3288-tb_8846.dts
@@ -533,6 +533,15 @@
        status = "okay";
    };

+    sensor@48 {
+        compatible = "light_cm3218";
+        reg = <0x48>;
+        type = <SENSOR_TYPE_LIGHT>;
+        irq-gpio = <&gpio8 GPIO_A3 IRQ_TYPE_EDGE_FALLING>;
+        irq_enable = <0>;
+        poll_delay_ms = <30>;
+        layout = <1>;
+    };
 };

 &i2c2 {
diff --git a/drivers/i2c/busses/i2c-rockchip.c b/drivers/i2c/busses/i2c-rockchip.c
index 3f64ff0..db28071 100644
--- a/drivers/i2c/busses/i2c-rockchip.c
+++ b/drivers/i2c/busses/i2c-rockchip.c
@@ -716,12 +716,17 @@ static int rockchip_i2c_doxfer(struct rockchip_i2c *i2c,

    i2c_writel(I2C_IPD_ALL_CLEAN, i2c->regs + I2C_IPD);
    rockchip_i2c_disable_irq(i2c);
-   rockchip_i2c_disable(i2c);
    spin_unlock_irqrestore(&i2c->lock, flags);

-   if (error == -EAGAIN)
-       i2c_dbg(i2c->dev, "No ack(complete_what: 0x%x), Maybe slave(addr: 0x%04x) not exist or abnormal power-on\n",
+   if (error == -EAGAIN){
+       i2c_dbg(i2c->dev, 
+                "No ack(complete_what: 0x%x), Maybe slave(addr: 0x%04x) not exist or abnormal power-on\n",
            i2c->complete_what, i2c->addr);
+        rockchip_i2c_send_stop(i2c);
+        msleep(5);
+    }
+
+   rockchip_i2c_disable(i2c);
    return error;
 }

diff --git a/drivers/input/sensors/lsensor/cm3218.c b/drivers/input/sensors/lsensor/cm3218.c
index b6201d6..8eee009 100644
--- a/drivers/input/sensors/lsensor/cm3218.c
+++ b/drivers/input/sensors/lsensor/cm3218.c
@@ -119,39 +119,46 @@ static int cm3218_read(struct i2c_client *client, u8 reg)
 }

 /****************operate according to sensor chip:start************/
+static int cm3218_read_lux(struct i2c_client *client, int *lux)
+{
+   int lux_data;
+
+   lux_data = cm3218_read(client, CM3218_REG_ADDR_ALS);
+   if (lux_data < 0) {
+       dev_err(&client->dev, "Error in reading Lux DATA\n");
+       return lux_data;
+   }
+
+   dev_vdbg(&client->dev, "lux = %u\n", lux_data);
+
+   if (lux_data < 0)
+       return lux_data;
+
+   *lux  = lux_data * LENSFACTOR;
+   *lux /= 1000;
+
+   return 0;
+}

 static int sensor_active(struct i2c_client *client, int enable, int rate)
 {
-   struct sensor_private_data *sensor =
-       (struct sensor_private_data *) i2c_get_clientdata(client);  
-   int result = 0;
-   int status = 0;
-   
-   sensor->client->addr = sensor->ops->ctrl_reg;   
-   sensor->ops->ctrl_data = cm3218_read(client,sensor->client->addr);
-   
-   //register setting according to chip datasheet      
-   if(!enable)
-   {   
-       status = CM3218_CMD_ALS_SD; //cm3218    
-       sensor->ops->ctrl_data |= status;   
-   }
-   else
-   {
-       status = ~CM3218_CMD_ALS_SD;    //cm3218
-       sensor->ops->ctrl_data &= status;
+   int status;
+
+   if (!enable) {  
+       status = cm3218_write(client, CM3218_REG_ADDR_CMD,0x0001);
+   } else {
+       status = cm3218_write(client, CM3218_REG_ADDR_CMD,0x0000);
    }

-   DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
-   result = cm3218_write(client,sensor->client->addr, sensor->ops->ctrl_data);
-   if(result)
+   if (status)
        printk("%s:fail to active sensor\n",__func__);
-   
-   return result;

+   return status;
 }

-
+/*
+ * cm3218 device initialization.
+ */
 static int sensor_init(struct i2c_client *client)
 {
    int status, i;
@@ -159,21 +166,24 @@ static int sensor_init(struct i2c_client *client)
        (struct sensor_private_data *) i2c_get_clientdata(client);

    for (i = 0; i < 5; i++) {
-       status = cm3218_write(client, CM3218_REG_ADDR_CMD,
-               CM3218_CMD_ALS_SD);
+        /* shut down */
+       status = cm3218_write(client, CM3218_REG_ADDR_CMD, CM3218_CMD_ALS_SD);
        if (status >= 0)
            break;
+        /* Clear interrupt */
        cm3218_read_ara(client);
    }

+    /* power on (1T, HS, interrupt disable) */
    status = cm3218_write(client, CM3218_REG_ADDR_CMD, CM3218_DEFAULT_CMD);
    if (status < 0) {
        dev_err(&client->dev, "Init CM3218 CMD fails\n");
        return status;
    }

-   if(sensor->pdata->irq_enable)
-   {
+    /* enable interrupt */
+   if(sensor->pdata->irq_enable){
+
        status = cm3218_write(client, CM3218_REG_ADDR_CMD, CM3218_DEFAULT_CMD | CM3218_CMD_ALS_INT_EN);
        if (status < 0) {
            dev_err(&client->dev, "Init CM3218 CMD fails\n");
@@ -181,9 +191,7 @@ static int sensor_init(struct i2c_client *client)
        }
    }

-   /* Clean interrupt status */
-   cm3218_read(client, CM3218_REG_ADDR_STATUS);
-   
+
    return status;
 }

@@ -224,25 +232,7 @@ report:
    return index;
 }

-static int cm3218_read_lux(struct i2c_client *client, int *lux)
-{
-   int lux_data;
-
-   lux_data = cm3218_read(client, CM3218_REG_ADDR_ALS);
-   if (lux_data < 0) {
-       dev_err(&client->dev, "Error in reading Lux DATA\n");
-       return lux_data;
-   }
-
-   dev_vdbg(&client->dev, "lux = %u\n", lux_data);

-   if (lux_data < 0)
-       return lux_data;
-
-   *lux  = lux_data * LENSFACTOR;
-   *lux /= 1000;
-   return 0;
-}

 static int sensor_report_value(struct i2c_client *client)
 {
@@ -254,14 +244,14 @@ static int sensor_report_value(struct i2c_client *client)
    cm3218_read_lux(client,&result);

    index = light_report_value(sensor->input_dev, result);
+
    DBG("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, result,index);

-   if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
-   {
-       
+    /* read sensor intterupt status register */
+   if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0)){
+
        result= sensor_read_reg(client, sensor->ops->int_status_reg);
-       if(result)
-       {
+       if(result){
            printk("%s:fail to clear sensor int status,ret=0x%x\n",__func__,result);
        }
    }
@@ -272,17 +262,17 @@ static int sensor_report_value(struct i2c_client *client)

 struct sensor_operate light_cm3218_ops = {
    .name               = "cm3218",
-   .type               = SENSOR_TYPE_LIGHT,    //sensor type and it should be correct
-   .id_i2c             = LIGHT_ID_CM3218,  //i2c id number
-   .read_reg           = CM3218_REG_ADDR_ALS,  //read data
-   .read_len           = 2,            //data length
-   .id_reg             = SENSOR_UNKNOW_DATA,   //read device id from this register
-   .id_data            = SENSOR_UNKNOW_DATA,   //device id
-   .precision          = 16,           //8 bits
-   .ctrl_reg           = CM3218_REG_ADDR_CMD,  //enable or disable 
-   .int_status_reg         = CM3218_REG_ADDR_STATUS,   //intterupt status register
-   .range              = {0,65535},        //range
-   .brightness                                        ={10,255},                          // brightness
+   .type               = SENSOR_TYPE_LIGHT, /* sensor type and it should be correct */
+   .id_i2c             = LIGHT_ID_CM3218, /* i2c id number */
+   .read_reg           = CM3218_REG_ADDR_ALS, /* read data */
+   .read_len           = 2, /* data length */
+   .id_reg             = SENSOR_UNKNOW_DATA, /* read device id from this register */
+   .id_data            = SENSOR_UNKNOW_DATA, /* device id */
+   .precision          = 16, /* 8 bits */
+   .ctrl_reg           = CM3218_REG_ADDR_CMD, /* enable or disable */
+   .int_status_reg         = SENSOR_UNKNOW_DATA, /* intterupt status register */
+   .range              = {0,65535}, /* range */
+   .brightness         ={10,255}, /* brightness */
    .trig               = SENSOR_UNKNOW_DATA,
    .active             = sensor_active,
    .init               = sensor_init,
@@ -291,7 +281,7 @@ struct sensor_operate light_cm3218_ops = {

 /****************operate according to sensor chip:end************/

-//function name should not be changed
+/* function name should not be changed */
 static struct sensor_operate *light_get_ops(void)
 {
    return &light_cm3218_ops;
@@ -317,5 +307,3 @@ static void __exit light_cm3218_exit(void)

 module_init(light_cm3218_init);
 module_exit(light_cm3218_exit);
-
-
diff --git a/drivers/input/sensors/sensor-dev.c b/drivers/input/sensors/sensor-dev.c
index 960d44f..68ab664 100755
--- a/drivers/input/sensors/sensor-dev.c
+++ b/drivers/input/sensors/sensor-dev.c
@@ -2113,9 +2113,9 @@ static const struct i2c_device_id sensor_id[] = {
    /*light sensor*/
    {"lightsensor", LIGHT_ID_ALL},
    {"light_cm3217", LIGHT_ID_CM3217},
-   {"light_cm3218", LIGHT_ID_CM3218},
-   {"light_cm3232", LIGHT_ID_CM3232},
-   {"light_al3006", LIGHT_ID_AL3006},
+    {"light_cm3218", LIGHT_ID_CM3218},
+    {"light_cm3232", LIGHT_ID_CM3232},
+    {"light_al3006", LIGHT_ID_AL3006},
    {"ls_stk3171", LIGHT_ID_STK3171},
    {"ls_isl29023", LIGHT_ID_ISL29023},
    {"ls_ap321xx", LIGHT_ID_AP321XX},
@@ -2162,8 +2162,9 @@ static struct of_device_id sensor_dt_ids[] = {
    ^M
    /*light sensor*/
    { .compatible = "light_cm3217" },
-   { .compatible = "light_cm3232" },
-   { .compatible = "light_al3006" },
+    { .compatible = "light_cm3218" },
+    { .compatible = "light_cm3232" },
+    { .compatible = "light_al3006" },
    { .compatible = "ls_stk3171" },
    { .compatible = "ls_ap321xx" },
 ^M
diff --git a/include/linux/sensor-dev.h b/include/linux/sensor-dev.h
index 16e916f..6c21fcd 100755
--- a/include/linux/sensor-dev.h
+++ b/include/linux/sensor-dev.h
@@ -80,7 +80,7 @@ enum sensor_id {
 ^M
    LIGHT_ID_ALL,
    LIGHT_ID_CM3217,
-   LIGHT_ID_CM3218,
+   LIGHT_ID_CM3218, /* ID = 46 */^M
    LIGHT_ID_CM3232,
    LIGHT_ID_AL3006,
    LIGHT_ID_STK3171,

延伸阅读:

  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规