zoukankan      html  css  js  c++  java
  • rk3288的SDK修复cm3218光敏驱动bug

    瑞芯的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
    ",
    +   if (error == -EAGAIN){
    +       i2c_dbg(i2c->dev, 
    +                "No ack(complete_what: 0x%x), Maybe slave(addr: 0x%04x) not exist or abnormal power-on
    ",
                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
    ");
    +       return lux_data;
    +   }
    +
    +   dev_vdbg(&client->dev, "lux = %u
    ", 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
    ",__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
    ",__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
    ");
            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
    ");
    @@ -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
    ");
    -       return lux_data;
    -   }
    -
    -   dev_vdbg(&client->dev, "lux = %u
    ", 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
    ",__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
    ",__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,

  • 相关阅读:
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    449. Serialize and Deserialize BST
    114. Flatten Binary Tree to Linked List
    199. Binary Tree Right Side View
    173. Binary Search Tree Iterator
    98. Validate Binary Search Tree
    965. Univalued Binary Tree
    589. N-ary Tree Preorder Traversal
    eclipse设置总结
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5356320.html
Copyright © 2011-2022 走看看