staging: iio: new invensence mpu6050/6500 driver
[firefly-linux-kernel-4.4.55.git] / drivers / staging / iio / imu / inv_mpu / inv_mpu3050_iio.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_mpu3050_iio.c
21  *      @brief   A sysfs device driver for Invensense devices
22  *      @details This file is part of invensense mpu driver code
23  */
24
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/i2c.h>
29 #include <linux/err.h>
30 #include <linux/delay.h>
31 #include <linux/sysfs.h>
32 #include <linux/jiffies.h>
33 #include <linux/irq.h>
34 #include <linux/interrupt.h>
35 #include <linux/kfifo.h>
36 #include <linux/poll.h>
37 #include <linux/miscdevice.h>
38 #include <linux/spinlock.h>
39
40 #include "inv_mpu_iio.h"
41 #define MPU3050_NACK_MIN_TIME (2 * 1000)
42 #define MPU3050_NACK_MAX_TIME (3 * 1000)
43
44 #define MPU3050_ONE_MPU_TIME 20
45 #define MPU3050_BOGUS_ADDR  0x7F
46 int __attribute__((weak)) inv_register_mpu3050_slave(struct inv_mpu_iio_s *st)
47 {
48         return 0;
49 }
50
51 int set_3050_bypass(struct inv_mpu_iio_s *st, bool enable)
52 {
53         struct inv_reg_map_s *reg;
54         int result;
55         u8 b;
56
57         reg = &st->reg;
58         result = inv_i2c_read(st, reg->user_ctrl, 1, &b);
59         if (result)
60                 return result;
61         if (((b & BIT_3050_AUX_IF_EN) == 0) && enable)
62                 return 0;
63         if ((b & BIT_3050_AUX_IF_EN) && (enable == 0))
64                 return 0;
65         b &= ~BIT_3050_AUX_IF_EN;
66         if (!enable) {
67                 b |= BIT_3050_AUX_IF_EN;
68                 result = inv_i2c_single_write(st, reg->user_ctrl, b);
69                 return result;
70         } else {
71                 /* Coming out of I2C is tricky due to several erratta.  Do not
72                 * modify this algorithm
73                 */
74                 /*
75                 * 1) wait for the right time and send the command to change
76                 * the aux i2c slave address to an invalid address that will
77                 * get nack'ed
78                 *
79                 * 0x00 is broadcast.  0x7F is unlikely to be used by any aux.
80                 */
81                 result = inv_i2c_single_write(st, REG_3050_SLAVE_ADDR,
82                                                 MPU3050_BOGUS_ADDR);
83                 if (result)
84                         return result;
85                 /*
86                 * 2) wait enough time for a nack to occur, then go into
87                 *    bypass mode:
88                 */
89                 usleep_range(MPU3050_NACK_MIN_TIME, MPU3050_NACK_MAX_TIME);
90                 result = inv_i2c_single_write(st, reg->user_ctrl, b);
91                 if (result)
92                         return result;
93                 /*
94                 * 3) wait for up to one MPU cycle then restore the slave
95                 *    address
96                 */
97                 msleep(MPU3050_ONE_MPU_TIME);
98
99                 result = inv_i2c_single_write(st, REG_3050_SLAVE_ADDR,
100                         st->plat_data.secondary_i2c_addr);
101                 if (result)
102                         return result;
103
104                 result = inv_i2c_single_write(st, reg->user_ctrl,
105                                 (b | BIT_3050_AUX_IF_RST));
106                 if (result)
107                         return result;
108                 usleep_range(MPU3050_NACK_MIN_TIME, MPU3050_NACK_MAX_TIME);
109         }
110         return 0;
111 }
112
113 void inv_setup_reg_mpu3050(struct inv_reg_map_s *reg)
114 {
115         reg->fifo_en         = REG_3050_FIFO_EN;
116         reg->sample_rate_div = REG_3050_SAMPLE_RATE_DIV;
117         reg->lpf             = REG_3050_LPF;
118         reg->fifo_count_h    = REG_3050_FIFO_COUNT_H;
119         reg->fifo_r_w        = REG_3050_FIFO_R_W;
120         reg->user_ctrl       = REG_3050_USER_CTRL;
121         reg->pwr_mgmt_1      = REG_3050_PWR_MGMT_1;
122         reg->raw_gyro        = REG_3050_RAW_GYRO;
123         reg->raw_accl        = REG_3050_AUX_XOUT_H;
124         reg->temperature     = REG_3050_TEMPERATURE;
125         reg->int_enable      = REG_3050_INT_ENABLE;
126         reg->int_status      = REG_3050_INT_STATUS;
127 }
128
129 int inv_switch_3050_gyro_engine(struct inv_mpu_iio_s *st, bool en)
130 {
131         struct inv_reg_map_s *reg;
132         u8 data, p;
133         int result;
134         reg = &st->reg;
135         if (en) {
136                 data = INV_CLK_PLL;
137                 p = (BITS_3050_POWER1 | data);
138                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
139                 if (result)
140                         return result;
141                 p = (BITS_3050_POWER2 | data);
142                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
143                 if (result)
144                         return result;
145                 p = data;
146                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
147                 msleep(SENSOR_UP_TIME);
148         } else {
149                 p = BITS_3050_GYRO_STANDBY;
150                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
151         }
152
153         return result;
154 }
155
156 int inv_switch_3050_accl_engine(struct inv_mpu_iio_s *st, bool en)
157 {
158         int result;
159         if (NULL == st->mpu_slave)
160                 return -EPERM;
161         if (en)
162                 result = st->mpu_slave->resume(st);
163         else
164                 result = st->mpu_slave->suspend(st);
165
166         return result;
167 }
168
169 /**
170  *  inv_init_config_mpu3050() - Initialize hardware, disable FIFO.
171  *  @st:        Device driver instance.
172  *  Initial configuration:
173  *  FSR: +/- 2000DPS
174  *  DLPF: 42Hz
175  *  FIFO rate: 50Hz
176  *  Clock source: Gyro PLL
177  */
178 int inv_init_config_mpu3050(struct iio_dev *indio_dev)
179 {
180         struct inv_reg_map_s *reg;
181         int result;
182         u8 data;
183         struct inv_mpu_iio_s *st = iio_priv(indio_dev);
184
185         if (st->chip_config.is_asleep)
186                 return -EPERM;
187         /*reading AUX VDDIO register */
188         result = inv_i2c_read(st, REG_3050_AUX_VDDIO, 1, &data);
189         if (result)
190                 return result;
191         data &= ~BIT_3050_VDDIO;
192         if (st->plat_data.level_shifter)
193                 data |= BIT_3050_VDDIO;
194         result = inv_i2c_single_write(st, REG_3050_AUX_VDDIO, data);
195         if (result)
196                 return result;
197
198         reg = &st->reg;
199         /*2000dps full scale range*/
200         result = inv_i2c_single_write(st, reg->lpf,
201                                 (INV_FSR_2000DPS << GYRO_CONFIG_FSR_SHIFT)
202                                 | INV_FILTER_42HZ);
203         if (result)
204                 return result;
205         st->chip_config.fsr = INV_FSR_2000DPS;
206         st->chip_config.lpf = INV_FILTER_42HZ;
207         result = inv_i2c_single_write(st, reg->sample_rate_div,
208                                         ONE_K_HZ/INIT_FIFO_RATE - 1);
209         if (result)
210                 return result;
211         st->chip_config.fifo_rate = INIT_FIFO_RATE;
212         st->chip_config.new_fifo_rate = INIT_FIFO_RATE;
213         st->irq_dur_ns            = INIT_DUR_TIME;
214         if ((SECONDARY_SLAVE_TYPE_ACCEL == st->plat_data.sec_slave_type) &&
215                 st->mpu_slave) {
216                 result = st->mpu_slave->setup(st);
217                 if (result)
218                         return result;
219                 result = st->mpu_slave->set_fs(st, INV_FS_02G);
220                 if (result)
221                         return result;
222                 result = st->mpu_slave->set_lpf(st, INIT_FIFO_RATE);
223                 if (result)
224                         return result;
225         }
226
227         return 0;
228 }
229
230 /**
231  *  set_power_mpu3050() - set power of mpu3050.
232  *  @st:        Device driver instance.
233  *  @power_on:  on/off
234  */
235 int set_power_mpu3050(struct inv_mpu_iio_s *st, bool power_on)
236 {
237         struct inv_reg_map_s *reg;
238         u8 data, p;
239         int result;
240         reg = &st->reg;
241         if (power_on) {
242                 data = 0;
243         } else {
244                 if (st->mpu_slave) {
245                         result = st->mpu_slave->suspend(st);
246                         if (result)
247                                 return result;
248                 }
249                 data = BIT_SLEEP;
250         }
251         if (st->chip_config.gyro_enable) {
252                 p = (BITS_3050_POWER1 | INV_CLK_PLL);
253                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
254                 if (result)
255                         return result;
256
257                 p = (BITS_3050_POWER2 | INV_CLK_PLL);
258                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
259                 if (result)
260                         return result;
261
262                 p = INV_CLK_PLL;
263                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
264                 if (result)
265                         return result;
266         } else {
267                 data |= (BITS_3050_GYRO_STANDBY | INV_CLK_INTERNAL);
268                 result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data);
269                 if (result)
270                         return result;
271         }
272         if (power_on) {
273                 msleep(POWER_UP_TIME);
274                 if (st->mpu_slave) {
275                         result = st->mpu_slave->resume(st);
276                         if (result)
277                                 return result;
278                 }
279         }
280         st->chip_config.is_asleep = !power_on;
281
282         return 0;
283 }
284 /**
285  *  @}
286  */
287