input: misc: Invensense MPU 5.0.1 driver
[linux-2.6.git] / drivers / input / misc / mpu / inv_slave_bma250.c
1 /*
2 * Copyright (C) 2012 Invensense, Inc.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 */
14
15 /**
16  *  @addtogroup  DRIVERS
17  *  @brief       Hardware drivers.
18  *
19  *  @{
20  *      @file    inv_slave_bma250.c
21  *      @brief   A sysfs device driver for Invensense devices
22  *      @details This file is part of inv_gyro driver code
23  *
24  */
25
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/slab.h>
29 #include <linux/i2c.h>
30 #include <linux/err.h>
31 #include <linux/delay.h>
32 #include <linux/sysfs.h>
33 #include <linux/jiffies.h>
34 #include <linux/irq.h>
35 #include <linux/interrupt.h>
36 #include <linux/kfifo.h>
37 #include <linux/poll.h>
38 #include <linux/miscdevice.h>
39 #include <linux/spinlock.h>
40
41 #include "inv_gyro.h"
42 #define BMA250_CHIP_ID                  3
43 #define BMA250_RANGE_SET                0
44 #define BMA250_BW_SET                   4
45
46 /* range and bandwidth */
47
48 #define BMA250_RANGE_2G                 0
49 #define BMA250_RANGE_4G                 1
50 #define BMA250_RANGE_8G                 2
51 #define BMA250_RANGE_16G                3
52
53
54 #define BMA250_BW_7_81HZ        0x08
55 #define BMA250_BW_15_63HZ       0x09
56 #define BMA250_BW_31_25HZ       0x0A
57 #define BMA250_BW_62_50HZ       0x0B
58 #define BMA250_BW_125HZ         0x0C
59 #define BMA250_BW_250HZ         0x0D
60 #define BMA250_BW_500HZ         0x0E
61 #define BMA250_BW_1000HZ        0x0F
62
63 /*      register definitions */
64 #define BMA250_CHIP_ID_REG                      0x00
65 #define BMA250_VERSION_REG                      0x01
66 #define BMA250_X_AXIS_LSB_REG                   0x02
67 #define BMA250_X_AXIS_MSB_REG                   0x03
68 #define BMA250_Y_AXIS_LSB_REG                   0x04
69 #define BMA250_Y_AXIS_MSB_REG                   0x05
70 #define BMA250_Z_AXIS_LSB_REG                   0x06
71 #define BMA250_Z_AXIS_MSB_REG                   0x07
72 #define BMA250_TEMP_RD_REG                      0x08
73 #define BMA250_STATUS1_REG                      0x09
74 #define BMA250_STATUS2_REG                      0x0A
75 #define BMA250_STATUS_TAP_SLOPE_REG             0x0B
76 #define BMA250_STATUS_ORIENT_HIGH_REG           0x0C
77 #define BMA250_RANGE_SEL_REG                    0x0F
78 #define BMA250_BW_SEL_REG                       0x10
79 #define BMA250_MODE_CTRL_REG                    0x11
80 #define BMA250_LOW_NOISE_CTRL_REG               0x12
81 #define BMA250_DATA_CTRL_REG                    0x13
82 #define BMA250_RESET_REG                        0x14
83 #define BMA250_INT_ENABLE1_REG                  0x16
84 #define BMA250_INT_ENABLE2_REG                  0x17
85 #define BMA250_INT1_PAD_SEL_REG                 0x19
86 #define BMA250_INT_DATA_SEL_REG                 0x1A
87 #define BMA250_INT2_PAD_SEL_REG                 0x1B
88 #define BMA250_INT_SRC_REG                      0x1E
89 #define BMA250_INT_SET_REG                      0x20
90 #define BMA250_INT_CTRL_REG                     0x21
91 #define BMA250_LOW_DURN_REG                     0x22
92 #define BMA250_LOW_THRES_REG                    0x23
93 #define BMA250_LOW_HIGH_HYST_REG                0x24
94 #define BMA250_HIGH_DURN_REG                    0x25
95 #define BMA250_HIGH_THRES_REG                   0x26
96 #define BMA250_SLOPE_DURN_REG                   0x27
97 #define BMA250_SLOPE_THRES_REG                  0x28
98 #define BMA250_TAP_PARAM_REG                    0x2A
99 #define BMA250_TAP_THRES_REG                    0x2B
100 #define BMA250_ORIENT_PARAM_REG                 0x2C
101 #define BMA250_THETA_BLOCK_REG                  0x2D
102 #define BMA250_THETA_FLAT_REG                   0x2E
103 #define BMA250_FLAT_HOLD_TIME_REG               0x2F
104 #define BMA250_STATUS_LOW_POWER_REG             0x31
105 #define BMA250_SELF_TEST_REG                    0x32
106 #define BMA250_EEPROM_CTRL_REG                  0x33
107 #define BMA250_SERIAL_CTRL_REG                  0x34
108 #define BMA250_CTRL_UNLOCK_REG                  0x35
109 #define BMA250_OFFSET_CTRL_REG                  0x36
110 #define BMA250_OFFSET_PARAMS_REG                0x37
111 #define BMA250_OFFSET_FILT_X_REG                0x38
112 #define BMA250_OFFSET_FILT_Y_REG                0x39
113 #define BMA250_OFFSET_FILT_Z_REG                0x3A
114 #define BMA250_OFFSET_UNFILT_X_REG              0x3B
115 #define BMA250_OFFSET_UNFILT_Y_REG              0x3C
116 #define BMA250_OFFSET_UNFILT_Z_REG              0x3D
117 #define BMA250_SPARE_0_REG                      0x3E
118 #define BMA250_SPARE_1_REG                      0x3F
119
120 /* mode settings */
121
122 #define BMA250_MODE_NORMAL      0
123 #define BMA250_MODE_LOWPOWER    1
124 #define BMA250_MODE_SUSPEND     2
125
126 struct bma_property {
127         int range;
128         int bandwidth;
129         int mode;
130 };
131
132 static struct bma_property bma_static_property = {
133         .range = BMA250_RANGE_SET,
134         .bandwidth = BMA250_BW_SET,
135         .mode = BMA250_MODE_SUSPEND
136 };
137
138 static int bma250_set_bandwidth(struct inv_gyro_state_s *st, unsigned char BW)
139 {
140         int res = 0;
141         unsigned char data;
142         int Bandwidth = 0;
143         if (BW >= 8)
144                 return -1;
145         switch (BW) {
146         case 0:
147                 Bandwidth = BMA250_BW_7_81HZ;
148                 break;
149         case 1:
150                 Bandwidth = BMA250_BW_15_63HZ;
151                 break;
152         case 2:
153                 Bandwidth = BMA250_BW_31_25HZ;
154                 break;
155         case 3:
156                 Bandwidth = BMA250_BW_62_50HZ;
157                 break;
158         case 4:
159                 Bandwidth = BMA250_BW_125HZ;
160                 break;
161         case 5:
162                 Bandwidth = BMA250_BW_250HZ;
163                 break;
164         case 6:
165                 Bandwidth = BMA250_BW_500HZ;
166                 break;
167         case 7:
168                 Bandwidth = BMA250_BW_1000HZ;
169                 break;
170         default:
171                 break;
172         }
173         res = inv_secondary_read(BMA250_BW_SEL_REG, 1, &data);
174         if (res)
175                 return res;
176         data &= 0xe0;
177         data |= Bandwidth;
178         res = inv_secondary_write(BMA250_BW_SEL_REG, data);
179         return res;
180 }
181
182 static int bma250_set_range(struct inv_gyro_state_s *st, unsigned char Range)
183 {
184         int res = 0;
185         unsigned char orig, data = 0;
186         if (Range >= 4)
187                 return -1;
188         switch (Range) {
189         case 0:
190                 data  = 3;
191                 break;
192         case 1:
193                 data  = 5;
194                 break;
195         case 2:
196                 data  = 8;
197                 break;
198         case 3:
199                 data  = 12;
200                 break;
201         default:
202                 break;
203         }
204         res = inv_secondary_read(BMA250_RANGE_SEL_REG, 1, &orig);
205         if (res)
206                 return res;
207         orig &= 0xf0;
208         data |= orig;
209         res = inv_secondary_write(BMA250_RANGE_SEL_REG, data);
210         bma_static_property.range = Range;
211         return res;
212 }
213
214 static int setup_slave_bma250(struct inv_gyro_state_s *st)
215 {
216         int result;
217         unsigned char data[4];
218         result = set_3050_bypass(st, 1);
219         if (result)
220                 return result;
221         /*read secondary i2c ID register */
222         result = inv_secondary_read(0, 2, data);
223         if (result)
224                 return result;
225         if (BMA250_CHIP_ID != data[0])
226                 return result;
227         result = set_3050_bypass(st, 0);
228         if (result)
229                 return result;
230         /*AUX(accel), slave address is set inside set_3050_bypass*/
231         /* bma250 x axis LSB register address is 2 */
232         result = inv_i2c_single_write(st, 0x18, BMA250_X_AXIS_LSB_REG);
233         return result;
234 }
235
236 static int bma250_set_mode(struct inv_gyro_state_s *st, unsigned char Mode)
237 {
238         int res = 0;
239         unsigned char data = 0;
240
241         if (Mode >= 3)
242                 return -1;
243         res = inv_secondary_read(BMA250_MODE_CTRL_REG, 1, &data);
244         if (res)
245                 return res;
246         data &= 0x3F;
247         switch (Mode) {
248         case BMA250_MODE_NORMAL:
249                 break;
250         case BMA250_MODE_LOWPOWER:
251                 data |= 0x40;
252                 break;
253         case BMA250_MODE_SUSPEND:
254                 data |= 0x80;
255                 break;
256         default:
257                 break;
258         }
259         res = inv_secondary_write(BMA250_MODE_CTRL_REG, data);
260         bma_static_property.mode = Mode;
261         return res;
262 }
263 static int suspend_slave_bma250(struct inv_gyro_state_s *st)
264 {
265         int result;
266         if (bma_static_property.mode == BMA250_MODE_SUSPEND)
267                 return 0;
268         /*set to bypass mode */
269         result = set_3050_bypass(st, 1);
270         if (result)
271                 return result;
272         bma250_set_mode(st, BMA250_MODE_SUSPEND);
273         /* no need to recover to non-bypass mode because we need it now */
274         return result;
275 }
276 static int resume_slave_bma250(struct inv_gyro_state_s *st)
277 {
278         int result;
279         if (bma_static_property.mode == BMA250_MODE_NORMAL)
280                 return 0;
281         /*set to bypass mode */
282         result = set_3050_bypass(st, 1);
283         if (result)
284                 return result;
285         bma250_set_mode(st, BMA250_MODE_NORMAL);
286         /* recover bypass mode */
287         result = set_3050_bypass(st, 0);
288         return result;
289 }
290 static int combine_data_slave_bma250(unsigned char *in, short *out)
291 {
292         out[0] = (in[0] | (in[1]<<8));
293         out[1] = (in[2] | (in[3]<<8));
294         out[2] = (in[4] | (in[5]<<8));
295         return 0;
296 }
297 static int get_mode_slave_bma250(struct inv_gyro_state_s *st)
298 {
299         if (bma_static_property.mode == BMA250_MODE_SUSPEND)
300                 return 0;
301         else if (bma_static_property.mode == BMA250_MODE_NORMAL)
302                 return 1;
303         return -1;
304 };
305 /**
306  *  set_lpf_bma250() - set lpf value
307  */
308
309 static int set_lpf_bma250(struct inv_gyro_state_s *st, int rate)
310 {
311         short hz[8] = {1000, 500, 250, 125, 62, 31, 15, 7};
312         int   d[8] = {7, 6, 5, 4, 3, 2, 1, 0};
313         int i, h, data, result;
314         h = (rate >> 1);
315         i = 0;
316         while ((h < hz[i]) && (i < 8))
317                 i++;
318         data = d[i];
319
320         result = set_3050_bypass(st, 1);
321         if (result)
322                 return result;
323         result = bma250_set_bandwidth(st, (unsigned char) data);
324         result |= set_3050_bypass(st, 0);
325
326         return result;
327 }
328 /**
329  *  set_fs_bma250() - set range value
330  */
331
332 static int set_fs_bma250(struct inv_gyro_state_s *st, int fs)
333 {
334         int result;
335         result = set_3050_bypass(st, 1);
336         if (result)
337                 return result;
338         result = bma250_set_range(st, (unsigned char) fs);
339         result |= set_3050_bypass(st, 0);
340         if (result)
341                 return -EINVAL;
342         return result;
343 }
344
345 static struct inv_mpu_slave slave_bma250 = {
346         .suspend = suspend_slave_bma250,
347         .resume  = resume_slave_bma250,
348         .setup   = setup_slave_bma250,
349         .combine_data = combine_data_slave_bma250,
350         .get_mode = get_mode_slave_bma250,
351         .set_lpf = set_lpf_bma250,
352         .set_fs  = set_fs_bma250
353 };
354
355 int inv_register_bma250_slave(struct inv_gyro_state_s *st)
356 {
357         st->mpu_slave = &slave_bma250;
358         return 0;
359 }
360 /**
361  *  @}
362  */
363