• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  $License:
3    Copyright 2011 InvenSense, Inc.
4 
5  Licensed under the Apache License, Version 2.0 (the "License");
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16   $
17  */
18 
19 /******************************************************************************
20  *
21  * $Id: mldl_cfg_mpu.c 5653 2011-06-16 21:06:55Z nroyer $
22  *
23  *****************************************************************************/
24 
25 /**
26  *  @addtogroup MLDL
27  *
28  *  @{
29  *      @file   mldl_cfg_mpu.c
30  *      @brief  The Motion Library Driver Layer.
31  */
32 
33 /* ------------------ */
34 /* - Include Files. - */
35 /* ------------------ */
36 
37 #include <stddef.h>
38 #include "mldl_cfg.h"
39 #include "mlsl.h"
40 #include "mpu.h"
41 
42 #ifdef LINUX
43 #include <sys/ioctl.h>
44 #endif
45 
46 #include "log.h"
47 #undef MPL_LOG_TAG
48 #define MPL_LOG_TAG "MPL-mldl_cfg_mpu:"
49 
50 /* --------------------- */
51 /* -    Variables.     - */
52 /* --------------------- */
53 
54 
55 /* ---------------------- */
56 /* -  Static Functions. - */
57 /* ---------------------- */
mpu_print_cfg(struct mldl_cfg * mldl_cfg)58 void mpu_print_cfg(struct mldl_cfg * mldl_cfg)
59 {
60     struct mpu_platform_data   *pdata   = mldl_cfg->pdata;
61     struct ext_slave_platform_data *accel   = &mldl_cfg->pdata->accel;
62     struct ext_slave_platform_data *compass = &mldl_cfg->pdata->compass;
63     struct ext_slave_platform_data *pressure = &mldl_cfg->pdata->pressure;
64 
65     MPL_LOGD("mldl_cfg.addr             = %02x\n", mldl_cfg->addr);
66     MPL_LOGD("mldl_cfg.int_config       = %02x\n", mldl_cfg->int_config);
67     MPL_LOGD("mldl_cfg.ext_sync         = %02x\n", mldl_cfg->ext_sync);
68     MPL_LOGD("mldl_cfg.full_scale       = %02x\n", mldl_cfg->full_scale);
69     MPL_LOGD("mldl_cfg.lpf              = %02x\n", mldl_cfg->lpf);
70     MPL_LOGD("mldl_cfg.clk_src          = %02x\n", mldl_cfg->clk_src);
71     MPL_LOGD("mldl_cfg.divider          = %02x\n", mldl_cfg->divider);
72     MPL_LOGD("mldl_cfg.dmp_enable       = %02x\n", mldl_cfg->dmp_enable);
73     MPL_LOGD("mldl_cfg.fifo_enable      = %02x\n", mldl_cfg->fifo_enable);
74     MPL_LOGD("mldl_cfg.dmp_cfg1         = %02x\n", mldl_cfg->dmp_cfg1);
75     MPL_LOGD("mldl_cfg.dmp_cfg2         = %02x\n", mldl_cfg->dmp_cfg2);
76     MPL_LOGD("mldl_cfg.offset_tc[0]     = %02x\n", mldl_cfg->offset_tc[0]);
77     MPL_LOGD("mldl_cfg.offset_tc[1]     = %02x\n", mldl_cfg->offset_tc[1]);
78     MPL_LOGD("mldl_cfg.offset_tc[2]     = %02x\n", mldl_cfg->offset_tc[2]);
79     MPL_LOGD("mldl_cfg.silicon_revision = %02x\n", mldl_cfg->silicon_revision);
80     MPL_LOGD("mldl_cfg.product_id       = %02x\n", mldl_cfg->product_id);
81     MPL_LOGD("mldl_cfg.gyro_sens_trim   = %02x\n", mldl_cfg->gyro_sens_trim);
82 #if defined CONFIG_MPU_SENSORS_MPU6050A2 || defined CONFIG_MPU_SENSORS_MPU6050B1
83     MPL_LOGD("mldl_cfg.accel_sens_trim   = %02x\n", mldl_cfg->accel_sens_trim);
84 #endif
85 
86     if (mldl_cfg->accel) {
87         MPL_LOGD("slave_accel->suspend      = %p\n", mldl_cfg->accel->suspend);
88         MPL_LOGD("slave_accel->resume       = %p\n", mldl_cfg->accel->resume);
89         MPL_LOGD("slave_accel->read         = %p\n", mldl_cfg->accel->read);
90         MPL_LOGD("slave_accel->type         = %02x\n", mldl_cfg->accel->type);
91         MPL_LOGD("slave_accel->read_reg     = %02x\n",
92                  mldl_cfg->accel->read_reg);
93         MPL_LOGD("slave_accel->read_len     = %02x\n",
94                  mldl_cfg->accel->read_len);
95         MPL_LOGD("slave_accel->endian       = %02x\n", mldl_cfg->accel->endian);
96         MPL_LOGD("slave_accel->range.mantissa= %02x\n", (int)mldl_cfg->accel->range.mantissa);
97         MPL_LOGD("slave_accel->range.fraction= %02x\n", (int)mldl_cfg->accel->range.fraction);
98     } else {
99         MPL_LOGD("slave_accel               = NULL\n");
100     }
101 
102     if (mldl_cfg->compass) {
103         MPL_LOGD("slave_compass->suspend    = %p\n", mldl_cfg->compass->suspend);
104         MPL_LOGD("slave_compass->resume     = %p\n", mldl_cfg->compass->resume);
105         MPL_LOGD("slave_compass->read       = %p\n", mldl_cfg->compass->read);
106         MPL_LOGD("slave_compass->type       = %02x\n", mldl_cfg->compass->type);
107         MPL_LOGD("slave_compass->read_reg   = %02x\n",
108                  mldl_cfg->compass->read_reg);
109         MPL_LOGD("slave_compass->read_len   = %02x\n",
110                  mldl_cfg->compass->read_len);
111         MPL_LOGD("slave_compass->endian     = %02x\n", mldl_cfg->compass->endian);
112         MPL_LOGD("slave_compass->range.mantissa= %02x\n", (int)mldl_cfg->compass->range.mantissa);
113         MPL_LOGD("slave_compass->range.fraction= %02x\n", (int)mldl_cfg->compass->range.fraction);
114     } else {
115         MPL_LOGD("slave_compass             = NULL\n");
116     }
117 
118     if (mldl_cfg->pressure) {
119         MPL_LOGD("slave_pressure->suspend    = %p\n", mldl_cfg->pressure->suspend);
120         MPL_LOGD("slave_pressure->resume     = %p\n", mldl_cfg->pressure->resume);
121         MPL_LOGD("slave_pressure->read       = %p\n", mldl_cfg->pressure->read);
122         MPL_LOGD("slave_pressure->type       = %02x\n", mldl_cfg->pressure->type);
123         MPL_LOGD("slave_pressure->read_reg   = %02x\n",
124                  mldl_cfg->pressure->read_reg);
125         MPL_LOGD("slave_pressure->read_len   = %02x\n",
126                  mldl_cfg->pressure->read_len);
127         MPL_LOGD("slave_pressure->endian     = %02x\n", mldl_cfg->pressure->endian);
128         MPL_LOGD("slave_pressure->range.mantissa= %02x\n", (int)mldl_cfg->pressure->range.mantissa);
129         MPL_LOGD("slave_pressure->range.fraction= %02x\n", (int)mldl_cfg->pressure->range.fraction);
130     } else {
131         MPL_LOGD("slave_pressure             = NULL\n");
132     }
133 
134     MPL_LOGD("accel->get_slave_descr    = %p\n",accel->get_slave_descr);
135     MPL_LOGD("accel->adapt_num          = %02x\n", accel->adapt_num);
136     MPL_LOGD("accel->bus                = %02x\n", accel->bus);
137     MPL_LOGD("accel->address            = %02x\n", accel->address);
138     MPL_LOGD("accel->orientation        = \n"
139              "                            %2d %2d %2d\n"
140              "                            %2d %2d %2d\n"
141              "                            %2d %2d %2d\n",
142              accel->orientation[0],accel->orientation[1],accel->orientation[2],
143              accel->orientation[3],accel->orientation[4],accel->orientation[5],
144              accel->orientation[6],accel->orientation[7],accel->orientation[8]);
145     MPL_LOGD("compass->get_slave_descr  = %p\n",compass->get_slave_descr);
146     MPL_LOGD("compass->adapt_num        = %02x\n", compass->adapt_num);
147     MPL_LOGD("compass->bus              = %02x\n", compass->bus);
148     MPL_LOGD("compass->address          = %02x\n", compass->address);
149     MPL_LOGD("compass->orientation      = \n"
150              "                            %2d %2d %2d\n"
151              "                            %2d %2d %2d\n"
152              "                            %2d %2d %2d\n",
153              compass->orientation[0],compass->orientation[1],compass->orientation[2],
154              compass->orientation[3],compass->orientation[4],compass->orientation[5],
155              compass->orientation[6],compass->orientation[7],compass->orientation[8]);
156     MPL_LOGD("pressure->get_slave_descr  = %p\n",pressure->get_slave_descr);
157     MPL_LOGD("pressure->adapt_num        = %02x\n", pressure->adapt_num);
158     MPL_LOGD("pressure->bus              = %02x\n", pressure->bus);
159     MPL_LOGD("pressure->address          = %02x\n", pressure->address);
160     MPL_LOGD("pressure->orientation      = \n"
161              "                            %2d %2d %2d\n"
162              "                            %2d %2d %2d\n"
163              "                            %2d %2d %2d\n",
164              pressure->orientation[0],pressure->orientation[1],pressure->orientation[2],
165              pressure->orientation[3],pressure->orientation[4],pressure->orientation[5],
166              pressure->orientation[6],pressure->orientation[7],pressure->orientation[8]);
167 
168     MPL_LOGD("pdata->int_config         = %02x\n", pdata->int_config);
169     MPL_LOGD("pdata->level_shifter      = %02x\n", pdata->level_shifter);
170     MPL_LOGD("pdata->orientation        = \n"
171              "                            %2d %2d %2d\n"
172              "                            %2d %2d %2d\n"
173              "                            %2d %2d %2d\n",
174              pdata->orientation[0],pdata->orientation[1],pdata->orientation[2],
175              pdata->orientation[3],pdata->orientation[4],pdata->orientation[5],
176              pdata->orientation[6],pdata->orientation[7],pdata->orientation[8]);
177 
178     MPL_LOGD("Struct sizes: mldl_cfg: %zu, "
179              "ext_slave_descr:%zu, mpu_platform_data:%zu: RamOffset: %zu\n",
180              sizeof(struct mldl_cfg), sizeof(struct ext_slave_descr),
181              sizeof(struct mpu_platform_data),
182              offsetof(struct mldl_cfg, ram));
183 }
184 
185 /******************************************************************************
186  ******************************************************************************
187  * Exported functions
188  ******************************************************************************
189  *****************************************************************************/
190 
191 /**
192  * Initializes the pdata structure to defaults.
193  *
194  * Opens the device to read silicon revision, product id and whoami.  Leaves
195  * the device in suspended state for low power.
196  *
197  * @param mldl_cfg handle to the config structure
198  * @param mlsl_handle handle to the mpu serial layer
199  * @param accel_handle handle to the accel serial layer
200  * @param compass_handle handle to the compass serial layer
201  * @param pressure_handle handle to the pressure serial layer
202  *
203  * @return INV_SUCCESS if silicon revision, product id and woami are supported
204  *         by this software.
205  */
inv_mpu_open(struct mldl_cfg * mldl_cfg,void * mlsl_handle,void * accel_handle,void * compass_handle,void * pressure_handle)206 int inv_mpu_open(struct mldl_cfg *mldl_cfg,
207                  void *mlsl_handle,
208                  void *accel_handle,
209                  void *compass_handle,
210                  void *pressure_handle)
211 {
212     int result;
213     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_GET_MPU_CONFIG, mldl_cfg);
214     if (result) {
215         LOG_RESULT_LOCATION(result);
216         return result;
217     }
218 
219     result = inv_mpu_suspend(mldl_cfg, mlsl_handle, NULL, NULL, NULL,
220                              INV_ALL_SENSORS);
221     if (result) {
222         LOG_RESULT_LOCATION(result);
223         return result;
224     }
225     return result;
226 }
227 
228 /**
229  * Stub for driver close.  Just verify that the devices are suspended
230  *
231  * @param mldl_cfg handle to the config structure
232  * @param mlsl_handle handle to the mpu serial layer
233  * @param accel_handle handle to the accel serial layer
234  * @param compass_handle handle to the compass serial layer
235  * @param pressure_handle handle to the compass serial layer
236  *
237  * @return INV_SUCCESS or non-zero error code
238  */
inv_mpu_close(struct mldl_cfg * mldl_cfg,void * mlsl_handle,void * accel_handle,void * compass_handle,void * pressure_handle)239 int inv_mpu_close(struct mldl_cfg *mldl_cfg,
240 		  void *mlsl_handle,
241 		  void *accel_handle,
242 		  void *compass_handle,
243 		  void *pressure_handle)
244 {
245     int result = INV_SUCCESS;
246 
247     result = inv_mpu_suspend(mldl_cfg, mlsl_handle, NULL, NULL, NULL,
248                              INV_ALL_SENSORS);
249     return result;
250 }
251 
inv_mpu_resume(struct mldl_cfg * mldl_cfg,void * mlsl_handle,void * accel_handle,void * compass_handle,void * pressure_handle,unsigned long sensors)252 int inv_mpu_resume(struct mldl_cfg* mldl_cfg,
253                    void *mlsl_handle,
254                    void *accel_handle,
255                    void *compass_handle,
256                    void *pressure_handle,
257                    unsigned long sensors)
258 {
259     int result;
260 
261     mldl_cfg->requested_sensors = sensors;
262     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_SET_MPU_CONFIG, mldl_cfg);
263     if (result) {
264         LOG_RESULT_LOCATION(result);
265         return result;
266     }
267     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_RESUME, NULL);
268     if (result) {
269         LOG_RESULT_LOCATION(result);
270         return result;
271     }
272     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_GET_MPU_CONFIG, mldl_cfg);
273     if (result) {
274         LOG_RESULT_LOCATION(result);
275         return result;
276     }
277     //MPL_LOGI("%s: Resuming to %04lx\n", __func__, mldl_cfg->requested_sensors);
278 
279     return result;
280 }
281 
282 
inv_mpu_suspend(struct mldl_cfg * mldl_cfg,void * mlsl_handle,void * accel_handle,void * compass_handle,void * pressure_handle,unsigned long sensors)283 int inv_mpu_suspend(struct mldl_cfg *mldl_cfg,
284           	    void *mlsl_handle,
285                     void *accel_handle,
286                     void *compass_handle,
287                     void *pressure_handle,
288                     unsigned long sensors)
289 {
290     int result;
291     unsigned long requested = mldl_cfg->requested_sensors;
292 
293     mldl_cfg->requested_sensors = (~sensors) & INV_ALL_SENSORS;
294     //MPL_LOGI("%s: suspending sensors to %04lx\n", __func__,
295     //         mldl_cfg->requested_sensors);
296 
297     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_SET_MPU_CONFIG, mldl_cfg);
298     if (result) {
299         LOG_RESULT_LOCATION(result);
300         return result;
301     }
302     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_SUSPEND, NULL);
303     if (result) {
304         LOG_RESULT_LOCATION(result);
305         return result;
306     }
307     result = ioctl((int)(uintptr_t)mlsl_handle, MPU_GET_MPU_CONFIG, mldl_cfg);
308     if (result) {
309         LOG_RESULT_LOCATION(result);
310         return result;
311     }
312 
313     mldl_cfg->requested_sensors = requested;
314     //MPL_LOGI("%s: Will resume next to %04lx\n", __func__, requested);
315 
316     return result;
317 }
318 
319 /**
320  * Send slave configuration information
321  *
322  * @param mldl_cfg pointer to the mldl configuration structure
323  * @param gyro_handle handle to the gyro sensor
324  * @param slave_handle handle to the slave sensor
325  * @param slave slave description
326  * @param pdata slave platform data
327  * @param data where to store the read data
328  *
329  * @return 0 or non-zero error code
330  */
inv_mpu_slave_read(struct mldl_cfg * mldl_cfg,void * gyro_handle,void * slave_handle,struct ext_slave_descr * slave,struct ext_slave_platform_data * pdata,unsigned char * data)331 int inv_mpu_slave_read(struct mldl_cfg *mldl_cfg,
332 		void *gyro_handle,
333 		void *slave_handle,
334 		struct ext_slave_descr *slave,
335 		struct ext_slave_platform_data *pdata,
336 		unsigned char *data)
337 {
338     int result;
339     if (!mldl_cfg || !gyro_handle || !data || !slave) {
340         LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER);
341         return INV_ERROR_INVALID_PARAMETER;
342     }
343 
344     switch (slave->type) {
345     case EXT_SLAVE_TYPE_ACCELEROMETER:
346         result = ioctl((int)(uintptr_t)gyro_handle, MPU_READ_ACCEL, data);
347         break;
348     case EXT_SLAVE_TYPE_COMPASS:
349         result = ioctl((int)(uintptr_t)gyro_handle, MPU_READ_COMPASS, data);
350         break;
351     case EXT_SLAVE_TYPE_PRESSURE:
352         result = ioctl((int)(uintptr_t)gyro_handle, MPU_READ_PRESSURE, data);
353         break;
354     default:
355         LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER);
356         return INV_ERROR_INVALID_PARAMETER;
357         break;
358     }
359 
360     return result;
361 }
362 
363 /**
364  * Send slave configuration information
365  *
366  * @param mldl_cfg pointer to the mldl configuration structure
367  * @param gyro_handle handle to the gyro sensor
368  * @param slave_handle handle to the slave sensor
369  * @param data the data being sent
370  * @param slave slave description
371  * @param pdata slave platform data
372  *
373  * @return 0 or non-zero error code
374  */
inv_mpu_slave_config(struct mldl_cfg * mldl_cfg,void * gyro_handle,void * slave_handle,struct ext_slave_config * data,struct ext_slave_descr * slave,struct ext_slave_platform_data * pdata)375 int inv_mpu_slave_config(struct mldl_cfg *mldl_cfg,
376                      void *gyro_handle,
377                      void *slave_handle,
378                      struct ext_slave_config *data,
379                      struct ext_slave_descr *slave,
380                      struct ext_slave_platform_data *pdata)
381 {
382     int result;
383     if (!mldl_cfg || !data || !slave || !pdata || !slave) {
384         LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER);
385         return INV_ERROR_INVALID_PARAMETER;
386     }
387 
388     switch (slave->type) {
389     case EXT_SLAVE_TYPE_ACCELEROMETER:
390         result = ioctl((int)(uintptr_t)gyro_handle, MPU_CONFIG_ACCEL, data);
391         if (result) {
392             LOG_RESULT_LOCATION(result);
393             return result;
394         }
395         break;
396     case EXT_SLAVE_TYPE_COMPASS:
397         result = ioctl((int)(uintptr_t)gyro_handle, MPU_CONFIG_COMPASS, data);
398         if (result) {
399             LOG_RESULT_LOCATION(result);
400             return result;
401         }
402         break;
403     case EXT_SLAVE_TYPE_PRESSURE:
404         result = ioctl((int)(uintptr_t)gyro_handle, MPU_CONFIG_PRESSURE, data);
405         if (result) {
406             LOG_RESULT_LOCATION(result);
407             return result;
408         }
409         break;
410     default:
411         LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER);
412         return INV_ERROR_INVALID_PARAMETER;
413         break;
414     }
415 
416     return result;
417 }
418 
419 /**
420  * Request slave configuration information
421  *
422  * Use this specifically after requesting a slave configuration to see what the
423  * slave accually accepted.
424  *
425  * @param mldl_cfg pointer to the mldl configuration structure
426  * @param gyro_handle handle to the gyro sensor
427  * @param slave_handle handle to the slave sensor
428  * @param data the data being requested.
429  * @param slave slave description
430  * @param pdata slave platform data
431  *
432  * @return 0 or non-zero error code
433  */
inv_mpu_get_slave_config(struct mldl_cfg * mldl_cfg,void * gyro_handle,void * slave_handle,struct ext_slave_config * data,struct ext_slave_descr * slave,struct ext_slave_platform_data * pdata)434 int inv_mpu_get_slave_config(struct mldl_cfg *mldl_cfg,
435                          void *gyro_handle,
436                          void *slave_handle,
437                          struct ext_slave_config *data,
438                          struct ext_slave_descr *slave,
439                          struct ext_slave_platform_data *pdata)
440 {
441     int result;
442     if (!mldl_cfg || !data || !slave) {
443         LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER);
444         return INV_ERROR_INVALID_PARAMETER;
445     }
446     switch (slave->type) {
447     case EXT_SLAVE_TYPE_ACCELEROMETER:
448         result = ioctl((int)(uintptr_t)gyro_handle, MPU_GET_CONFIG_ACCEL, data);
449         if (result) {
450             LOG_RESULT_LOCATION(result);
451             return result;
452         }
453         break;
454     case EXT_SLAVE_TYPE_COMPASS:
455         result = ioctl((int)(uintptr_t)gyro_handle, MPU_GET_CONFIG_COMPASS, data);
456         if (result) {
457             LOG_RESULT_LOCATION(result);
458             return result;
459         }
460         break;
461     case EXT_SLAVE_TYPE_PRESSURE:
462         result = ioctl((int)(uintptr_t)gyro_handle, MPU_GET_CONFIG_PRESSURE, data);
463         if (result) {
464             LOG_RESULT_LOCATION(result);
465             return result;
466         }
467         break;
468     default:
469         LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER);
470         return INV_ERROR_INVALID_PARAMETER;
471         break;
472     }
473     return result;
474 }
475 /**
476  *@}
477  */
478