Home | History | Annotate | Download | only in mllite
      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 /* ---------------------- */
     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      = %02x\n", (int)mldl_cfg->accel->suspend);
     88         MPL_LOGD("slave_accel->resume       = %02x\n", (int)mldl_cfg->accel->resume);
     89         MPL_LOGD("slave_accel->read         = %02x\n", (int)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    = %02x\n", (int)mldl_cfg->compass->suspend);
    104         MPL_LOGD("slave_compass->resume     = %02x\n", (int)mldl_cfg->compass->resume);
    105         MPL_LOGD("slave_compass->read       = %02x\n", (int)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    = %02x\n", (int)mldl_cfg->pressure->suspend);
    120         MPL_LOGD("slave_pressure->resume     = %02x\n", (int)mldl_cfg->pressure->resume);
    121         MPL_LOGD("slave_pressure->read       = %02x\n", (int)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    = %x\n",(unsigned int) 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  = %x\n",(unsigned int) 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  = %x\n",(unsigned int) 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: %d, "
    179              "ext_slave_descr:%d, mpu_platform_data:%d: RamOffset: %d\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  */
    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)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  */
    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 
    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)mlsl_handle, MPU_SET_MPU_CONFIG, mldl_cfg);
    263     if (result) {
    264         LOG_RESULT_LOCATION(result);
    265         return result;
    266     }
    267     result = ioctl((int)mlsl_handle, MPU_RESUME, NULL);
    268     if (result) {
    269         LOG_RESULT_LOCATION(result);
    270         return result;
    271     }
    272     result = ioctl((int)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 
    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)mlsl_handle, MPU_SET_MPU_CONFIG, mldl_cfg);
    298     if (result) {
    299         LOG_RESULT_LOCATION(result);
    300         return result;
    301     }
    302     result = ioctl((int)mlsl_handle, MPU_SUSPEND, NULL);
    303     if (result) {
    304         LOG_RESULT_LOCATION(result);
    305         return result;
    306     }
    307     result = ioctl((int)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  */
    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)gyro_handle, MPU_READ_ACCEL, data);
    347         break;
    348     case EXT_SLAVE_TYPE_COMPASS:
    349         result = ioctl((int)gyro_handle, MPU_READ_COMPASS, data);
    350         break;
    351     case EXT_SLAVE_TYPE_PRESSURE:
    352         result = ioctl((int)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  */
    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)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)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)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  */
    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)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)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)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