fix sensors include file err
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / pressure / pr_ms5607.c
1 /* drivers/input/sensors/pressure/ms5607.c\r
2  *\r
3  * Copyright (C) 2012-2015 ROCKCHIP.\r
4  * Author: luowei <lw@rock-chips.com>\r
5  *\r
6  * This software is licensed under the terms of the GNU General Public\r
7  * License version 2, as published by the Free Software Foundation, and\r
8  * may be copied, distributed, and modified under those terms.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  */\r
16 #include <linux/interrupt.h>\r
17 #include <linux/i2c.h>\r
18 #include <linux/slab.h>\r
19 #include <linux/irq.h>\r
20 #include <linux/miscdevice.h>\r
21 #include <linux/gpio.h>\r
22 #include <asm/uaccess.h>\r
23 #include <asm/atomic.h>\r
24 #include <linux/delay.h>\r
25 #include <linux/input.h>\r
26 #include <linux/workqueue.h>\r
27 #include <linux/freezer.h>\r
28 #include <linux/of_gpio.h>\r
29 #ifdef CONFIG_HAS_EARLYSUSPEND\r
30 #include <linux/earlysuspend.h>\r
31 #endif\r
32 #include <linux/sensor-dev.h>\r
33 \r
34 \r
35 #define CMD_RESET   0x1E  // ADC reset command \r
36 #define CMD_ADC_READ 0x00  // ADC read command \r
37 #define CMD_ADC_CONV 0x40  // ADC conversion command \r
38 #define CMD_ADC_D1   0x00    // ADC D1 conversion \r
39 #define CMD_ADC_D2   0x10    // ADC D2 conversion \r
40 #define CMD_ADC_256  0x00    // ADC OSR=256 \r
41 #define CMD_ADC_512  0x02    // ADC OSR=512 \r
42 #define CMD_ADC_1024 0x04    // ADC OSR=1024 \r
43 #define CMD_ADC_2048 0x06    // ADC OSR=2048 \r
44 #define CMD_ADC_4096 0x08    // ADC OSR=4096 \r
45 #define CMD_PROM_RD  0xA0  // Prom read command \r
46 \r
47 \r
48 /****************operate according to sensor chip:start************/\r
49 \r
50 static int C[8] = {0};\r
51 int g_ms5607_temp;\r
52 int g_ms5607_pr_status;\r
53 \r
54 #if defined(CONFIG_TMP_MS5607)\r
55 extern int g_ms5607_temp_status;\r
56 #else\r
57 static int g_ms5607_temp_status = SENSOR_OFF;\r
58 #endif\r
59 \r
60 \r
61 static int sensor_active(struct i2c_client *client, int enable, int rate)\r
62 {\r
63         int result = 0;\r
64         int i = 0;\r
65         char prom[16];\r
66 \r
67         if((enable) && (g_ms5607_temp_status == SENSOR_OFF))\r
68         {\r
69                 result = sensor_write_reg_normal(client, CMD_RESET);\r
70                 if(result)              \r
71                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
72 \r
73                 //Read PROM (128 bit of calibration words)  \r
74                 memset(prom, 0, 16);\r
75                 prom[0]= CMD_PROM_RD;//CMD_PROM_RD;   \r
76                 for(i=0; i<8; i++)\r
77                 {\r
78                         prom[i*2]= CMD_PROM_RD + i*2;\r
79                         result = sensor_rx_data(client, &prom[i*2], 2);\r
80                         if(result)\r
81                         {\r
82                                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
83                                 return result;\r
84                         }\r
85                 }\r
86 \r
87                 for (i=0;i<8;i++) \r
88                 {\r
89                         C[i] = prom[2*i] << 8 | prom[2*i + 1];\r
90                         //printk("prom[%d]=0x%x,prom[%d]=0x%x",2*i,prom[2*i],(2*i + 1),prom[2*i + 1]);\r
91                         //printk("\nC[%d]=%d,",i+1,C[i]);\r
92                 } \r
93 \r
94         }\r
95         \r
96         g_ms5607_pr_status = enable;\r
97         \r
98         return result;\r
99 }\r
100 \r
101 static int sensor_init(struct i2c_client *client)\r
102 {       \r
103         struct sensor_private_data *sensor =\r
104             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
105         int result = 0;\r
106         \r
107         result = sensor->ops->active(client,0,0);\r
108         if(result)\r
109         {\r
110                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
111                 return result;\r
112         }\r
113         \r
114         sensor->status_cur = SENSOR_OFF;\r
115         g_ms5607_pr_status = sensor->status_cur;\r
116         \r
117         //Reset\r
118         //result = sensor_write_reg_normal(client, CMD_RESET);\r
119         //if(result)            \r
120         //printk("%s:line=%d,error\n",__func__,__LINE__);       \r
121     \r
122         return result;\r
123 }\r
124 \r
125 \r
126 static int pressure_report_value(struct input_dev *input, int data)\r
127 {\r
128         //get pressure, high and temperature from register data\r
129 \r
130         input_report_abs(input, ABS_PRESSURE, data);\r
131         input_sync(input);\r
132         \r
133         return 0;\r
134 }\r
135 \r
136 \r
137 static int sensor_report_value(struct i2c_client *client)\r
138 {\r
139         struct sensor_private_data *sensor =\r
140             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
141     \r
142         int result = 0;\r
143         char buffer[3]; \r
144         char index = 0;\r
145         unsigned int  D1=0, D2=0;\r
146 \r
147         int T2 = 0;\r
148         long long OFF = 0;      // offset at actual temperature \r
149         long long SENS = 0;     // sensitivity at actual temperature \r
150         int dT = 0;             // difference between actual and measured temperature\r
151         long long OFF2 = 0;\r
152         long long SENS2 = 0;\r
153         int P = 0;              // compensated pressure value \r
154 \r
155 \r
156         memset(buffer, 0, 3);\r
157         if(sensor->ops->read_len < 3)   //sensor->ops->read_len = 3\r
158         {\r
159                 printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
160                 return -1;\r
161         }\r
162 \r
163         //D1 conversion\r
164         sensor_write_reg_normal(client,  CMD_ADC_CONV + CMD_ADC_D1 + CMD_ADC_4096);\r
165         msleep(10);\r
166 \r
167         memset(buffer, 0, 3);\r
168         buffer[0] = CMD_ADC_READ;\r
169         result = sensor_rx_data(client, &buffer[0], 3);\r
170         if(result)\r
171         {\r
172                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
173                 return result;\r
174         }\r
175 \r
176         D1 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];\r
177         DBG("\nD1=%d :buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D1,buffer[0],buffer[1],buffer[2]);\r
178 \r
179         //D2 conversion\r
180         sensor_write_reg_normal(client,  CMD_ADC_CONV + CMD_ADC_D2 + CMD_ADC_4096);\r
181         msleep(10);\r
182 \r
183         memset(buffer, 0, 3);\r
184         buffer[0] = CMD_ADC_READ;\r
185         result = sensor_rx_data(client, &buffer[0], 3);\r
186         if(result)\r
187         {\r
188                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
189                 return result;\r
190         }\r
191 \r
192         D2 = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];\r
193         DBG("D2=%d:buffer[0]=0x%x,buffer[1]=0x%x,buffer2]=0x%x\n",D2,buffer[0],buffer[1],buffer[2]);\r
194 \r
195         dT = D2 - ((unsigned int)C[5] << 8);\r
196 \r
197         g_ms5607_temp = (int)(2000 + ((long long)dT * C[6] >> 23));\r
198 \r
199         OFF = ((unsigned long long)C[2] << 17) + (C[4] * (long long)dT >> 6);\r
200 \r
201         SENS = ((long long)C[1] << 16) + (C[3] * (long long)dT >> 7);\r
202 \r
203         /*calcualte 2nd order pressure and temperature (BP5607 2nd order algorithm)*/\r
204         if (g_ms5607_temp < -4000 || g_ms5607_temp > 8500)\r
205         {\r
206                 printk("%s:temperature is error\n",__func__);\r
207                 return -1;\r
208         }\r
209 \r
210         if (g_ms5607_temp < 2000)\r
211         {\r
212                 int tmp;\r
213                 tmp = (g_ms5607_temp - 2000) * (g_ms5607_temp - 2000);\r
214 \r
215                 T2 = (int)((long long)(dT * dT) >> 31);\r
216                 OFF2 = (((long long)tmp * 61)*((long long)tmp * 61)) >> 4;\r
217                 SENS2 = (long long)((tmp*tmp) << 1);\r
218 \r
219                 if (g_ms5607_temp < -1500)\r
220                 {\r
221                         tmp = (g_ms5607_temp + 1500) * (g_ms5607_temp + 1500);\r
222                         OFF2 += 15 * tmp;\r
223                         SENS2 += 8 * tmp;\r
224                 }\r
225         }\r
226         else\r
227         {\r
228                 T2=0;\r
229                 OFF2 = 0;\r
230                 SENS2 = 0;\r
231         }\r
232 \r
233         g_ms5607_temp -= T2;\r
234         OFF -= OFF2;\r
235         SENS -= SENS2;    \r
236         P = (int)((((D1 * SENS) >> 21) - OFF) >> 15);\r
237 \r
238         index = pressure_report_value(sensor->input_dev, P);\r
239 \r
240         DBG("%s:pressure=%d,temperature=%d\n",__func__,P,g_ms5607_temp);\r
241         \r
242         return result;\r
243 }\r
244 \r
245 struct sensor_operate pressure_ms5607_ops = {\r
246         .name                           = "pr_ms5607",\r
247         .type                           = SENSOR_TYPE_PRESSURE, //sensor type and it should be correct\r
248         .id_i2c                         = PRESSURE_ID_MS5607,   //i2c id number\r
249         .read_reg                       = SENSOR_UNKNOW_DATA,   //read data\r
250         .read_len                       = 3,                    //data length\r
251         .id_reg                         = SENSOR_UNKNOW_DATA,   //read device id from this register\r
252         .id_data                        = SENSOR_UNKNOW_DATA,   //device id\r
253         .precision                      = 24,                   //8 bits\r
254         .ctrl_reg                       = SENSOR_UNKNOW_DATA,   //enable or disable \r
255         .int_status_reg                 = SENSOR_UNKNOW_DATA,   //intterupt status register\r
256         .range                          = {100,65535},          //range\r
257         .brightness                     = {10,255},             //brightness\r
258         .trig                           = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,                \r
259         .active                         = sensor_active,        \r
260         .init                           = sensor_init,\r
261         .report                         = sensor_report_value,\r
262 };\r
263 \r
264 /****************operate according to sensor chip:end************/\r
265 \r
266 //function name should not be changed\r
267 static struct sensor_operate *pressure_get_ops(void)\r
268 {\r
269         return &pressure_ms5607_ops;\r
270 }\r
271 \r
272 \r
273 static int __init pressure_ms5607_init(void)\r
274 {\r
275         struct sensor_operate *ops = pressure_get_ops();\r
276         int result = 0;\r
277         int type = ops->type;\r
278         result = sensor_register_slave(type, NULL, NULL, pressure_get_ops);\r
279         return result;\r
280 }\r
281 \r
282 static void __exit pressure_ms5607_exit(void)\r
283 {\r
284         struct sensor_operate *ops = pressure_get_ops();\r
285         int type = ops->type;\r
286         sensor_unregister_slave(type, NULL, NULL, pressure_get_ops);\r
287 }\r
288 \r
289 \r
290 module_init(pressure_ms5607_init);\r
291 module_exit(pressure_ms5607_exit);\r
292 \r