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\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,
rk3288的SDK修复cm3218光敏驱动bug的更多相关文章
- 服务器cpu过高修复:操作系统内核bug导致
服务器cpu过高修复:操作系统内核bug导致修改系统内核参数/etc/sysctl.conf添加下面2条参数:vm.dirty_background_ratio=5vm.dirty_ratio=10
- 解决由于显卡驱动BUG导致桌面右键卡顿的问题:bat文件源码
@ ECHO OFF%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe&q ...
- 一个MySQL-JDBC驱动bug引起的血案……
问题背景 公司是做电商系统的,整个系统搭建在华为云上.系统设计的时候,考虑到后续的用户和订单数量比较大,需要使用一些大数据库的组件.关系型数据库这块,考虑到后续数据量的快速增长,不是直接写入MySQL ...
- 一个MySQL JDBC驱动bug引起的血案
1.1 问题背景 公司是做电商系统的,整个系统搭建在华为云上.系统设计的时候,考虑到后续的用户和订单数量比较大,需要使用一些大数据库的组件.关系型数据库这块,考虑到后续数据量的快速增长,不是 ...
- ux.form.field.TreePicker 扩展,修复火狐不能展开bug
/** * A Picker field that contains a tree panel on its popup, enabling selection of tree nodes. * 动态 ...
- duilib修复ActiveXUI控件bug,以支持flash透明动态背景
转载请说明原出处,谢谢~~ 昨天在QQ控件里和同学说起QQ2013登陆窗体的开发,从界面角度考虑,单单一个登陆界面是很容易做出来的.腾讯公司为了 防止各种盗号行为可谓煞费苦心,QQ2013采用了动态背 ...
- mac系统下修复第三方Python包bug
发现问题 今天在github上fork了CI 3.x的中文手册,按照README文档一步步进行Sphinx和相关工具的安装,最终build生成html版手册.操作到第6步执行`make html`的时 ...
- Scrum立会报告+燃尽图(十一月十九日总第二十七次):功能开发与修复上一阶段bug
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
- Scrum立会报告+燃尽图(十一月十七日总第二十五次):设计调查问卷;修复上一阶段bug
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
随机推荐
- Fody
Fody https://github.com/Fody/Fody/ 有空还要看下怎么实现的.
- UVa 10622 (gcd 分解质因数) Perfect P-th Powers
题意: 对于32位有符号整数x,将其写成x = bp的形式,求p可能的最大值. 分析: 将x分解质因数,然后求所有指数的gcd即可. 对于负数还要再处理一下,负数求得的p必须是奇数才行. #inclu ...
- poj2001 Shortest Prefixes (trie)
读入建立一棵字母树,并且每到一个节点就增加这个节点的覆盖数. 然后再重新扫一遍,一旦碰到某个覆盖数为1就是这个单词的最短前缀了. 不知为何下面的程序一直有bug……不知是读入的问题? type nod ...
- 在 Azure 中使用公用 IP 创建多 NIC VM
Russ Slaten 2014年 11 月 18日下午 4点 我们最近宣布了支持具有多个网络接口控制器 (NIC) 的虚拟机 (VM).我仍在努力了解此功能适用的所有新场景,但首先,我希望亲自测试 ...
- uboot环境变量与内核MTD分区关系
uboot 与系统内核中MTD分区的关系: 分区只是内核的概念,就是说A-B地址放内核,C-D地址放文件系统,(也就是规定哪个地址区间放内核或者文件系统)等等. 1:在内核MTD中可以定义分区A~B, ...
- CSS换行:word-wrap、word-break和text-wrap区别
一.word-wrap:允许对长的不可分割的单词进行分割并换行到下一行.(中英文处理效果一样) word-wrap有两个取值: 1.word-wrap: normal:只在允许的断字点换行(浏览器保持 ...
- 用python的numpy作线性拟合、多项式拟合、对数拟合
转自:http://blog.itpub.net/12199764/viewspace-1743145/ 项目中有涉及趋势预测的工作,整理一下这3种拟合方法:1.线性拟合-使用mathimport m ...
- 关于Java线程
1 概念 通常来说,我们编写的Java代码是以进程的形式来运行的,所编写的代码就是“程序”,而执行中的程序就是“进程”.进程是系统进行资源分配和调度的独立单位. 线程是位于进程的下一级,是系统中的最小 ...
- Windows下Android SDK Manage下载速度缓慢的解决方法
在SDK Manager下Tools->Options打开了SDK Manager的Settings,选中“Force https://… sources to be fetched using ...
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7. 怎么调用别的程序集的方法示例 8. [is declared in another module ...