• 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,

  • 相关阅读:
    30个Python常用极简代码,拿走就用
    如果只写一行代码能实现什么?看完我彻底服了
    面试官问我:用了HTTPS就安全了吗?用了HTTPS会被抓包吗?我竟然回答不上来......
    程序员常见的口头禅
    没有心仪的offer,要不要找一个工作先凑合?
    微信新出“拍了拍”功能!
    UVa 340 Master-Mind Hints
    UVa 575 Skew Binary 歪斜二进制
    UVa 10250 The Other Two Trees
    UVa 10106 Product
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5356320.html
Copyright © 2020-2023  润新知