mirror of
https://github.com/hardkernel/linux.git
synced 2026-04-10 23:18:10 +09:00
on 977 add mpu config and update mpu code
This commit is contained in:
@@ -303,7 +303,7 @@
|
||||
compatible = "nxp,pcf8563";
|
||||
reg = <0x51>;
|
||||
};
|
||||
|
||||
/*
|
||||
sensor@1d {
|
||||
compatible = "gs_mma8452";
|
||||
reg = <0x1d>;
|
||||
@@ -312,7 +312,9 @@
|
||||
irq_enable = <1>;
|
||||
poll_delay_ms = <30>;
|
||||
layout = <8>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sensor@0d {
|
||||
compatible = "ak8975";
|
||||
reg = <0x0d>;
|
||||
@@ -321,7 +323,9 @@
|
||||
irq_enable = <1>;
|
||||
poll_delay_ms = <30>;
|
||||
layout = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
*/
|
||||
sensor@10 {
|
||||
compatible = "ls_cm3218";
|
||||
reg = <0x10>;
|
||||
@@ -331,7 +335,45 @@
|
||||
poll_delay_ms = <30>;
|
||||
layout = <1>;
|
||||
};
|
||||
|
||||
|
||||
mpu6050:mpu@68{
|
||||
compatible = "mpu6050";
|
||||
reg = <0x68>;
|
||||
mpu-int_config = <0x10>;
|
||||
mpu-level_shifter = <0>;
|
||||
mpu-orientation = <1 0 0 0 1 0 0 0 1>;
|
||||
orientation-x= <1>;
|
||||
orientation-y= <0>;
|
||||
orientation-z= <1>;
|
||||
irq-gpio = <&gpio8 GPIO_A0 IRQ_TYPE_LEVEL_LOW>;
|
||||
mpu-debug = <1>;
|
||||
};
|
||||
/*
|
||||
ak8963:compass@0d{
|
||||
compatible = "ak8963";
|
||||
reg = <0x0d>;
|
||||
compass-bus = <0>;
|
||||
compass-adapt_num = <0>;
|
||||
compass-orientation = <1 0 0 0 1 0 0 0 1>;
|
||||
orientation-x= <0>;
|
||||
orientation-y= <0>;
|
||||
orientation-z= <1>;
|
||||
compass-debug = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
*/
|
||||
ak8975:compass@0d{
|
||||
compatible = "ak8975";
|
||||
reg = <0x0d>;
|
||||
compass-bus = <0>;
|
||||
compass-adapt_num = <0>;
|
||||
compass-orientation = <1 0 0 0 1 0 0 0 1>;
|
||||
orientation-x= <1>;
|
||||
orientation-y= <0>;
|
||||
orientation-z= <1>;
|
||||
compass-debug = <1>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
|
||||
1
drivers/misc/Kconfig
Normal file → Executable file
1
drivers/misc/Kconfig
Normal file → Executable file
@@ -534,6 +534,7 @@ config SRAM
|
||||
source "drivers/misc/c2port/Kconfig"
|
||||
source "drivers/misc/eeprom/Kconfig"
|
||||
source "drivers/misc/cb710/Kconfig"
|
||||
source "drivers/misc/inv_mpu/Kconfig"
|
||||
source "drivers/misc/ti-st/Kconfig"
|
||||
source "drivers/misc/lis3lv02d/Kconfig"
|
||||
source "drivers/misc/carma/Kconfig"
|
||||
|
||||
1
drivers/misc/Makefile
Normal file → Executable file
1
drivers/misc/Makefile
Normal file → Executable file
@@ -53,4 +53,5 @@ obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
|
||||
obj-$(CONFIG_INTEL_MEI) += mei/
|
||||
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
|
||||
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
|
||||
obj-y += inv_mpu/
|
||||
obj-$(CONFIG_SRAM) += sram.o
|
||||
|
||||
1
drivers/misc/inv_mpu/Kconfig
Normal file → Executable file
1
drivers/misc/inv_mpu/Kconfig
Normal file → Executable file
@@ -9,6 +9,7 @@ config MPU_SENSORS_TIMERIRQ
|
||||
menuconfig: INV_SENSORS
|
||||
tristate "Motion Processing Unit"
|
||||
depends on I2C
|
||||
default n
|
||||
|
||||
if INV_SENSORS
|
||||
|
||||
|
||||
0
drivers/misc/inv_mpu/Makefile
Normal file → Executable file
0
drivers/misc/inv_mpu/Makefile
Normal file → Executable file
0
drivers/misc/inv_mpu/README
Normal file → Executable file
0
drivers/misc/inv_mpu/README
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/Kconfig
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/Kconfig
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/Makefile
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/Makefile
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/adxl34x.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/adxl34x.c
Normal file → Executable file
4
drivers/misc/inv_mpu/accel/bma150.c
Normal file → Executable file
4
drivers/misc/inv_mpu/accel/bma150.c
Normal file → Executable file
@@ -25,7 +25,7 @@
|
||||
* @file bma150.c
|
||||
* @brief Accelerometer setup and handling methods for Bosch BMA150.
|
||||
*/
|
||||
#define DEBUG
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
@@ -671,7 +671,7 @@ static int bma150_mod_probe(struct i2c_client *client,
|
||||
struct bma150_mod_private_data *private_data;
|
||||
int result = 0;
|
||||
|
||||
dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);
|
||||
dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name);
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
result = -ENODEV;
|
||||
|
||||
16
drivers/misc/inv_mpu/accel/bma222.c
Normal file → Executable file
16
drivers/misc/inv_mpu/accel/bma222.c
Normal file → Executable file
@@ -51,8 +51,6 @@
|
||||
#define BMA222_PWR_REG (0x11)
|
||||
#define BMA222_SOFTRESET_REG (0x14)
|
||||
|
||||
#define BMA222_INTTERUPTSET_REG (0x17)
|
||||
|
||||
#define BMA222_STATUS_RDY_MASK (0x80)
|
||||
#define BMA222_FSR_MASK (0x0F)
|
||||
#define BMA222_ODR_MASK (0x1F)
|
||||
@@ -337,8 +335,6 @@ static int bma222_get_config(void *mlsl_handle,
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_IRQ_RESUME:
|
||||
//zwp,TODO,need to add irq config???
|
||||
return INV_SUCCESS;
|
||||
default:
|
||||
return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||
};
|
||||
@@ -394,8 +390,6 @@ static int bma222_config(void *mlsl_handle,
|
||||
*((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_IRQ_RESUME:
|
||||
//zwp,TODO,need to add irq config???
|
||||
return INV_SUCCESS;
|
||||
default:
|
||||
return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||
};
|
||||
@@ -512,18 +506,14 @@ static int bma222_read(void *mlsl_handle,
|
||||
unsigned char *data)
|
||||
{
|
||||
int result = INV_SUCCESS;
|
||||
/* result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
BMA222_STATUS_REG, 1, data);
|
||||
if (data[0] & BMA222_STATUS_RDY_MASK) {
|
||||
*/
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
slave->read_reg, slave->read_len, data);
|
||||
|
||||
return result;
|
||||
/* } else{
|
||||
} else
|
||||
return INV_ERROR_ACCEL_DATA_NOT_READY;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
static struct ext_slave_descr bma222_descr = {
|
||||
@@ -565,7 +555,7 @@ static int bma222_mod_probe(struct i2c_client *client,
|
||||
struct ext_slave_platform_data *pdata;
|
||||
struct bma222_mod_private_data *private_data;
|
||||
int result = 0;
|
||||
printk("%s,++++++++++++++++++++\n",__FUNCTION__);
|
||||
|
||||
dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name);
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
|
||||
0
drivers/misc/inv_mpu/accel/bma250.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/bma250.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/cma3000.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/cma3000.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/kxsd9.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/kxsd9.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/lis331.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/lis331.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/lis3dh.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/lis3dh.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/lsm303dlx_a.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/lsm303dlx_a.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/mma8450.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/mma8450.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/mma845x.c
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/mma845x.c
Normal file → Executable file
699
drivers/misc/inv_mpu/accel/mpu6050.c
Executable file
699
drivers/misc/inv_mpu/accel/mpu6050.c
Executable file
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
$License:
|
||||
Copyright (C) 2011 InvenSense Corporation, All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup ACCELDL
|
||||
* @brief Provides the interface to setup and handle an accelerometer.
|
||||
*
|
||||
* @{
|
||||
* @file mpu6050.c
|
||||
* @brief Accelerometer setup and handling methods for Invensense MPU6050
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include "mpu-dev.h"
|
||||
|
||||
#include <log.h>
|
||||
#include <linux/mpu.h>
|
||||
#include "mpu6050b1.h"
|
||||
#include "mlsl.h"
|
||||
#include "mldl_cfg.h"
|
||||
#undef MPL_LOG_TAG
|
||||
#define MPL_LOG_TAG "MPL-acc"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct mpu6050_config {
|
||||
unsigned int odr; /**< output data rate 1/1000 Hz */
|
||||
unsigned int fsr; /**< full scale range mg */
|
||||
unsigned int ths; /**< mot/no-mot thseshold mg */
|
||||
unsigned int dur; /**< mot/no-mot duration ms */
|
||||
unsigned int irq_type; /**< irq type */
|
||||
};
|
||||
|
||||
struct mpu6050_private_data {
|
||||
struct mpu6050_config suspend;
|
||||
struct mpu6050_config resume;
|
||||
struct mldl_cfg *mldl_cfg_ref;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static int mpu6050_set_mldl_cfg_ref(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct mldl_cfg *mldl_cfg_ref)
|
||||
{
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
private_data->mldl_cfg_ref = mldl_cfg_ref;
|
||||
return 0;
|
||||
}
|
||||
static int mpu6050_set_lp_mode(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
unsigned char lpa_freq)
|
||||
{
|
||||
unsigned char b = 0;
|
||||
/* Reducing the duration setting for lp mode */
|
||||
b = 1;
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_MOT_DUR, b);
|
||||
/* Setting the cycle bit and LPA wake up freq */
|
||||
inv_serial_read(mlsl_handle, pdata->address, MPUREG_PWR_MGMT_1, 1,
|
||||
&b);
|
||||
b |= BIT_CYCLE | BIT_PD_PTAT;
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_1,
|
||||
b);
|
||||
inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, 1, &b);
|
||||
b |= lpa_freq & BITS_LPA_WAKE_CTRL;
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, b);
|
||||
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
|
||||
static int mpu6050_set_fp_mode(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
unsigned char b;
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
/* Resetting the cycle bit and LPA wake up freq */
|
||||
inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_1, 1, &b);
|
||||
b &= ~BIT_CYCLE & ~BIT_PD_PTAT;
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_1, b);
|
||||
inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, 1, &b);
|
||||
b &= ~BITS_LPA_WAKE_CTRL;
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, b);
|
||||
/* Resetting the duration setting for fp mode */
|
||||
b = (unsigned char)private_data->suspend.ths / ACCEL_MOT_DUR_LSB;
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_MOT_DUR, b);
|
||||
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
/**
|
||||
* Record the odr for use in computing duration values.
|
||||
*
|
||||
* @param config Config to set, suspend or resume structure
|
||||
* @param odr output data rate in 1/1000 hz
|
||||
*/
|
||||
static int mpu6050_set_odr(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct mpu6050_config *config, long apply, long odr)
|
||||
{
|
||||
int result;
|
||||
unsigned char b;
|
||||
unsigned char lpa_freq = 1; /* Default value */
|
||||
long base;
|
||||
int total_divider;
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
struct mldl_cfg *mldl_cfg_ref =
|
||||
(struct mldl_cfg *)private_data->mldl_cfg_ref;
|
||||
|
||||
if (mldl_cfg_ref) {
|
||||
base = 1000 *
|
||||
inv_mpu_get_sampling_rate_hz(mldl_cfg_ref->mpu_gyro_cfg)
|
||||
* (mldl_cfg_ref->mpu_gyro_cfg->divider + 1);
|
||||
} else {
|
||||
/* have no reference to mldl_cfg => assume base rate is 1000 */
|
||||
base = 1000000L;
|
||||
}
|
||||
|
||||
if (odr != 0) {
|
||||
total_divider = (base / odr) - 1;
|
||||
/* final odr MAY be different from requested odr due to
|
||||
integer truncation */
|
||||
config->odr = base / (total_divider + 1);
|
||||
} else {
|
||||
config->odr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if the DMP and/or gyros are on, don't set the ODR =>
|
||||
the DMP/gyro mldl_cfg->divider setting will handle it */
|
||||
if (apply
|
||||
&& (mldl_cfg_ref &&
|
||||
!(mldl_cfg_ref->inv_mpu_cfg->requested_sensors &
|
||||
INV_DMP_PROCESSOR))) {
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_SMPLRT_DIV,
|
||||
(unsigned char)total_divider);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
MPL_LOGI("ODR : %d mHz\n", config->odr);
|
||||
}
|
||||
/* Decide whether to put accel in LP mode or pull out of LP mode
|
||||
based on the odr. */
|
||||
switch (odr) {
|
||||
case 1000:
|
||||
lpa_freq = BITS_LPA_WAKE_1HZ;
|
||||
break;
|
||||
case 2000:
|
||||
lpa_freq = BITS_LPA_WAKE_2HZ;
|
||||
break;
|
||||
case 10000:
|
||||
lpa_freq = BITS_LPA_WAKE_10HZ;
|
||||
break;
|
||||
case 40000:
|
||||
lpa_freq = BITS_LPA_WAKE_40HZ;
|
||||
break;
|
||||
default:
|
||||
inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_1, 1, &b);
|
||||
b &= BIT_CYCLE;
|
||||
if (b == BIT_CYCLE) {
|
||||
MPL_LOGI(" Accel LP - > FP mode. \n ");
|
||||
mpu6050_set_fp_mode(mlsl_handle, pdata);
|
||||
}
|
||||
}
|
||||
/* If lpa_freq default value was changed, set into LP mode */
|
||||
if (lpa_freq != 1) {
|
||||
MPL_LOGI(" Accel FP - > LP mode. \n ");
|
||||
mpu6050_set_lp_mode(mlsl_handle, pdata, lpa_freq);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_set_fsr(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct mpu6050_config *config, long apply, long fsr)
|
||||
{
|
||||
unsigned char fsr_mask;
|
||||
int result;
|
||||
|
||||
if (fsr <= 2000) {
|
||||
config->fsr = 2000;
|
||||
fsr_mask = 0x00;
|
||||
} else if (fsr <= 4000) {
|
||||
config->fsr = 4000;
|
||||
fsr_mask = 0x08;
|
||||
} else if (fsr <= 8000) {
|
||||
config->fsr = 8000;
|
||||
fsr_mask = 0x10;
|
||||
} else { /* fsr = [8001, oo) */
|
||||
config->fsr = 16000;
|
||||
fsr_mask = 0x18;
|
||||
}
|
||||
|
||||
if (apply) {
|
||||
unsigned char reg;
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_CONFIG, 1, ®);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_CONFIG,
|
||||
reg | fsr_mask);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
MPL_LOGV("FSR: %d\n", config->fsr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_set_irq(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct mpu6050_config *config, long apply,
|
||||
long irq_type)
|
||||
{
|
||||
int result;
|
||||
unsigned char reg_int_cfg;
|
||||
|
||||
/* HACK, no need for interrupts for MPU6050 accel
|
||||
- use of soft interrupt is required */
|
||||
#if 0
|
||||
switch (irq_type) {
|
||||
case MPU_SLAVE_IRQ_TYPE_DATA_READY:
|
||||
config->irq_type = irq_type;
|
||||
reg_int_cfg = BIT_RAW_RDY_EN;
|
||||
break;
|
||||
/* todo: add MOTION, NO_MOTION, and FREEFALL */
|
||||
case MPU_SLAVE_IRQ_TYPE_NONE:
|
||||
/* Do nothing, not even set the interrupt because it is
|
||||
shared with the gyro */
|
||||
config->irq_type = irq_type;
|
||||
return 0;
|
||||
default:
|
||||
return INV_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (apply) {
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_INT_ENABLE,
|
||||
reg_int_cfg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
MPL_LOGV("irq_type: %d\n", config->irq_type);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_set_ths(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *slave,
|
||||
struct mpu6050_config *config, long apply, long ths)
|
||||
{
|
||||
if (ths < 0)
|
||||
ths = 0;
|
||||
|
||||
config->ths = ths;
|
||||
MPL_LOGV("THS: %d\n", config->ths);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_set_dur(void *mlsl_handle,
|
||||
struct ext_slave_platform_data *slave,
|
||||
struct mpu6050_config *config, long apply, long dur)
|
||||
{
|
||||
if (dur < 0)
|
||||
dur = 0;
|
||||
|
||||
config->dur = dur;
|
||||
MPL_LOGV("DUR: %d\n", config->dur);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int mpu6050_init(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
int result;
|
||||
struct mpu6050_private_data *private_data;
|
||||
|
||||
|
||||
private_data = kzalloc(sizeof(*private_data), GFP_KERNEL);
|
||||
|
||||
if (!private_data)
|
||||
return INV_ERROR_MEMORY_EXAUSTED;
|
||||
|
||||
pdata->private_data = private_data;
|
||||
|
||||
result = mpu6050_set_odr(mlsl_handle, pdata, &private_data->suspend,
|
||||
false, 0);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_odr(mlsl_handle, pdata, &private_data->resume,
|
||||
false, 200000);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_fsr(mlsl_handle, pdata, &private_data->suspend,
|
||||
false, 2000);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_fsr(mlsl_handle, pdata, &private_data->resume,
|
||||
false, 2000);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mpu6050_set_irq(mlsl_handle, pdata, &private_data->suspend,
|
||||
false, MPU_SLAVE_IRQ_TYPE_NONE);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_irq(mlsl_handle, pdata, &private_data->resume,
|
||||
false, MPU_SLAVE_IRQ_TYPE_NONE);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mpu6050_set_ths(mlsl_handle, pdata, &private_data->suspend,
|
||||
false, 80);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_ths(mlsl_handle, pdata, &private_data->resume,
|
||||
false, 40);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_dur(mlsl_handle, pdata, &private_data->suspend,
|
||||
false, 1000);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_dur(mlsl_handle, pdata, &private_data->resume,
|
||||
false, 2540);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_exit(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
kfree(pdata->private_data);
|
||||
pdata->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_suspend(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
unsigned char reg;
|
||||
int result;
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
|
||||
result = mpu6050_set_odr(mlsl_handle, pdata, &private_data->suspend,
|
||||
true, private_data->suspend.odr);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mpu6050_set_irq(mlsl_handle, pdata, &private_data->suspend,
|
||||
true, private_data->suspend.irq_type);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, 1, ®);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
reg |= (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA);
|
||||
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, reg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_resume(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
int result;
|
||||
unsigned char reg;
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_1, 1, ®);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (reg & BIT_SLEEP) {
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_1, reg & ~BIT_SLEEP);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
msleep(2);
|
||||
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, 1, ®);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
reg &= ~(BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA);
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_PWR_MGMT_2, reg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* settings */
|
||||
|
||||
result = mpu6050_set_fsr(mlsl_handle, pdata, &private_data->resume,
|
||||
true, private_data->resume.fsr);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_odr(mlsl_handle, pdata, &private_data->resume,
|
||||
true, private_data->resume.odr);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
result = mpu6050_set_irq(mlsl_handle, pdata, &private_data->resume,
|
||||
true, private_data->resume.irq_type);
|
||||
|
||||
/* motion, no_motion */
|
||||
/* TODO : port these in their respective _set_thrs and _set_dur
|
||||
functions and use the APPLY paremeter to apply just like
|
||||
_set_odr, _set_irq, and _set_fsr. */
|
||||
reg = (unsigned char)private_data->suspend.ths / ACCEL_MOT_THR_LSB;
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_MOT_THR, reg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
reg = (unsigned char)
|
||||
ACCEL_ZRMOT_THR_LSB_CONVERSION(private_data->resume.ths);
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_ZRMOT_THR, reg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
reg = (unsigned char)private_data->suspend.ths / ACCEL_MOT_DUR_LSB;
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_MOT_DUR, reg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
reg = (unsigned char)private_data->resume.ths / ACCEL_ZRMOT_DUR_LSB;
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
MPUREG_ACCEL_ZRMOT_DUR, reg);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_read(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
unsigned char *data)
|
||||
{
|
||||
int result;
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
slave->read_reg, slave->read_len, data);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int mpu6050_config(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct ext_slave_config *data)
|
||||
{
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
if (!data->data)
|
||||
return INV_ERROR_INVALID_PARAMETER;
|
||||
|
||||
switch (data->key) {
|
||||
case MPU_SLAVE_CONFIG_ODR_SUSPEND:
|
||||
return mpu6050_set_odr(mlsl_handle, pdata,
|
||||
&private_data->suspend,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_ODR_RESUME:
|
||||
return mpu6050_set_odr(mlsl_handle, pdata,
|
||||
&private_data->resume,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_FSR_SUSPEND:
|
||||
return mpu6050_set_fsr(mlsl_handle, pdata,
|
||||
&private_data->suspend,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_FSR_RESUME:
|
||||
return mpu6050_set_fsr(mlsl_handle, pdata,
|
||||
&private_data->resume,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_MOT_THS:
|
||||
return mpu6050_set_ths(mlsl_handle, pdata,
|
||||
&private_data->suspend,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_NMOT_THS:
|
||||
return mpu6050_set_ths(mlsl_handle, pdata,
|
||||
&private_data->resume,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_MOT_DUR:
|
||||
return mpu6050_set_dur(mlsl_handle, pdata,
|
||||
&private_data->suspend,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_NMOT_DUR:
|
||||
return mpu6050_set_dur(mlsl_handle, pdata,
|
||||
&private_data->resume,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
|
||||
return mpu6050_set_irq(mlsl_handle, pdata,
|
||||
&private_data->suspend,
|
||||
data->apply, *((long *)data->data));
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_IRQ_RESUME:
|
||||
return mpu6050_set_irq(mlsl_handle, pdata,
|
||||
&private_data->resume,
|
||||
data->apply, *((long *)data->data));
|
||||
case MPU_SLAVE_CONFIG_INTERNAL_REFERENCE:
|
||||
return mpu6050_set_mldl_cfg_ref(mlsl_handle, pdata,
|
||||
(struct mldl_cfg *)data->data);
|
||||
break;
|
||||
|
||||
default:
|
||||
return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu6050_get_config(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct ext_slave_config *data)
|
||||
{
|
||||
struct mpu6050_private_data *private_data =
|
||||
(struct mpu6050_private_data *)pdata->private_data;
|
||||
if (!data->data)
|
||||
return INV_ERROR_INVALID_PARAMETER;
|
||||
|
||||
switch (data->key) {
|
||||
case MPU_SLAVE_CONFIG_ODR_SUSPEND:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->suspend.odr;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_ODR_RESUME:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->resume.odr;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_FSR_SUSPEND:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->suspend.fsr;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_FSR_RESUME:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->resume.fsr;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_MOT_THS:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->suspend.ths;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_NMOT_THS:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->resume.ths;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_MOT_DUR:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->suspend.dur;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_NMOT_DUR:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->resume.dur;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->suspend.irq_type;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_IRQ_RESUME:
|
||||
(*(unsigned long *)data->data) =
|
||||
(unsigned long)private_data->resume.irq_type;
|
||||
break;
|
||||
default:
|
||||
return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ext_slave_descr mpu6050_descr = {
|
||||
.init = mpu6050_init,
|
||||
.exit = mpu6050_exit,
|
||||
.suspend = mpu6050_suspend,
|
||||
.resume = mpu6050_resume,
|
||||
.read = mpu6050_read,
|
||||
.config = mpu6050_config,
|
||||
.get_config = mpu6050_get_config,
|
||||
.name = "mpu6050",
|
||||
.type = EXT_SLAVE_TYPE_ACCEL,
|
||||
.id = ACCEL_ID_MPU6050,
|
||||
.read_reg = 0x3B,
|
||||
.read_len = 6,
|
||||
.endian = EXT_SLAVE_BIG_ENDIAN,
|
||||
.range = {2, 0},
|
||||
.trigger = NULL,
|
||||
};
|
||||
|
||||
struct ext_slave_descr *mpu6050_get_slave_descr(void)
|
||||
{
|
||||
return &mpu6050_descr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
0
drivers/misc/inv_mpu/accel/mpu6050.h
Normal file → Executable file
0
drivers/misc/inv_mpu/accel/mpu6050.h
Normal file → Executable file
9
drivers/misc/inv_mpu/compass/Kconfig
Normal file → Executable file
9
drivers/misc/inv_mpu/compass/Kconfig
Normal file → Executable file
@@ -18,6 +18,15 @@ config MPU_SENSORS_AK8975
|
||||
Specifying more that one compass in the board file will result
|
||||
in runtime errors.
|
||||
|
||||
config MPU_SENSORS_AK8963
|
||||
tristate "AKM ak8963"
|
||||
help
|
||||
This enables support for the AKM ak8963 compass
|
||||
This support is for integration with the MPU3050 or MPU6050 gyroscope
|
||||
device driver. Only one compass can be registered at a time.
|
||||
Specifying more that one compass in the board file will result
|
||||
in runtime errors.
|
||||
|
||||
config MPU_SENSORS_AK8972
|
||||
tristate "AKM ak8972"
|
||||
help
|
||||
|
||||
2
drivers/misc/inv_mpu/compass/Makefile
Normal file → Executable file
2
drivers/misc/inv_mpu/compass/Makefile
Normal file → Executable file
@@ -31,6 +31,8 @@ inv_mpu_hscdtd004a-objs += hscdtd004a.o
|
||||
obj-$(CONFIG_MPU_SENSORS_AK8975) += inv_mpu_ak8975.o
|
||||
inv_mpu_ak8975-objs += ak8975.o
|
||||
|
||||
obj-$(CONFIG_MPU_SENSORS_AK8963) += inv_mpu_ak8963.o
|
||||
inv_mpu_ak8963-objs += ak8963.o
|
||||
obj-$(CONFIG_MPU_SENSORS_AK8972) += inv_mpu_ak8972.o
|
||||
inv_mpu_ak8972-objs += ak8972.o
|
||||
|
||||
|
||||
648
drivers/misc/inv_mpu/compass/ak8963.c
Executable file
648
drivers/misc/inv_mpu/compass/ak8963.c
Executable file
@@ -0,0 +1,648 @@
|
||||
/*
|
||||
$License:
|
||||
Copyright (C) 2011 InvenSense Corporation, All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup COMPASSDL
|
||||
*
|
||||
* @{
|
||||
* @file ak8963.c
|
||||
* @brief Magnetometer setup and handling methods for the AKM AK8963,
|
||||
* AKM AK8963B, and AKM AK8963C compass devices.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include "mpu-dev.h"
|
||||
|
||||
#include <log.h>
|
||||
#include <linux/mpu.h>
|
||||
#include "mlsl.h"
|
||||
#include "mldl_cfg.h"
|
||||
#undef MPL_LOG_TAG
|
||||
#define MPL_LOG_TAG "MPL-compass"
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/iio/consumer.h>
|
||||
|
||||
//#include <linux/gpio.h>
|
||||
//#include <mach/gpio.h>
|
||||
//#include <plat/gpio-cfg.h>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#define AK8963_REG_ST1 (0x02)
|
||||
#define AK8963_REG_HXL (0x03)
|
||||
#define AK8963_REG_ST2 (0x09)
|
||||
|
||||
#define AK8963_REG_CNTL (0x0A)
|
||||
#define AK8963_REG_ASAX (0x10)
|
||||
#define AK8963_REG_ASAY (0x11)
|
||||
#define AK8963_REG_ASAZ (0x12)
|
||||
|
||||
//define output bit is 16bit
|
||||
#define AK8963_CNTL_MODE_POWER_DOWN (0x10)
|
||||
#define AK8963_CNTL_MODE_SINGLE_MEASUREMENT (0x11)
|
||||
#define AK8963_CNTL_MODE_FUSE_ROM_ACCESS (0x1f)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
struct ak8963_config {
|
||||
char asa[COMPASS_NUM_AXES]; /* axis sensitivity adjustment */
|
||||
};
|
||||
|
||||
struct ak8963_private_data {
|
||||
struct ak8963_config init;
|
||||
};
|
||||
|
||||
struct ext_slave_platform_data ak8963_data;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static int ak8963_init(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
int result;
|
||||
unsigned char serial_data[COMPASS_NUM_AXES];
|
||||
printk("yemk:ak8963_init\n");
|
||||
struct ak8963_private_data *private_data;
|
||||
private_data = (struct ak8963_private_data *)
|
||||
kzalloc(sizeof(struct ak8963_private_data), GFP_KERNEL);
|
||||
|
||||
if (!private_data)
|
||||
return INV_ERROR_MEMORY_EXAUSTED;
|
||||
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8963_REG_CNTL,
|
||||
AK8963_CNTL_MODE_POWER_DOWN);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
/* Wait at least 100us */
|
||||
udelay(100);
|
||||
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8963_REG_CNTL,
|
||||
AK8963_CNTL_MODE_FUSE_ROM_ACCESS);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Wait at least 200us */
|
||||
udelay(200);
|
||||
|
||||
result = inv_serial_read(mlsl_handle, pdata->address,
|
||||
AK8963_REG_ASAX,
|
||||
COMPASS_NUM_AXES, serial_data);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
pdata->private_data = private_data;
|
||||
|
||||
private_data->init.asa[0] = serial_data[0];
|
||||
private_data->init.asa[1] = serial_data[1];
|
||||
private_data->init.asa[2] = serial_data[2];
|
||||
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8963_REG_CNTL,
|
||||
AK8963_CNTL_MODE_POWER_DOWN);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
printk("yemk:ak8963_init end\n");
|
||||
udelay(100);
|
||||
printk(KERN_ERR "invensense: %s ok\n", __func__);
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
|
||||
static int ak8963_exit(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
kfree(pdata->private_data);
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
|
||||
static int ak8963_suspend(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
int result = INV_SUCCESS;
|
||||
result =
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8963_REG_CNTL,
|
||||
AK8963_CNTL_MODE_POWER_DOWN);
|
||||
msleep(1); /* wait at least 100us */
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ak8963_resume(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata)
|
||||
{
|
||||
int result = INV_SUCCESS;
|
||||
result =
|
||||
inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8963_REG_CNTL,
|
||||
AK8963_CNTL_MODE_SINGLE_MEASUREMENT);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ak8963_read(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata, unsigned char *data)
|
||||
{
|
||||
unsigned char regs[8];
|
||||
unsigned char *stat = ®s[0];
|
||||
unsigned char *stat2 = ®s[7];
|
||||
int result = INV_SUCCESS;
|
||||
int status = INV_SUCCESS;
|
||||
|
||||
result =
|
||||
inv_serial_read(mlsl_handle, pdata->address, AK8963_REG_ST1,
|
||||
8, regs);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Always return the data and the status registers */
|
||||
memcpy(data, ®s[1], 6);
|
||||
data[6] = regs[0];
|
||||
data[7] = regs[7];
|
||||
|
||||
/*
|
||||
* ST : data ready -
|
||||
* Measurement has been completed and data is ready to be read.
|
||||
*/
|
||||
if (*stat & 0x01)
|
||||
status = INV_SUCCESS;
|
||||
|
||||
/*
|
||||
* ST2 : data error -
|
||||
* occurs when data read is started outside of a readable period;
|
||||
* data read would not be correct.
|
||||
* Valid in continuous measurement mode only.
|
||||
* In single measurement mode this error should not occour but we
|
||||
* stil account for it and return an error, since the data would be
|
||||
* corrupted.
|
||||
* DERR bit is self-clearing when ST2 register is read.
|
||||
*/
|
||||
// if (*stat2 & 0x04)
|
||||
// status = INV_ERROR_COMPASS_DATA_ERROR;
|
||||
/*
|
||||
* ST2 : overflow -
|
||||
* the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
|
||||
* This is likely to happen in presence of an external magnetic
|
||||
* disturbance; it indicates, the sensor data is incorrect and should
|
||||
* be ignored.
|
||||
* An error is returned.
|
||||
* HOFL bit clears when a new measurement starts.
|
||||
*/
|
||||
if (*stat2 & 0x08)
|
||||
status = INV_ERROR_COMPASS_DATA_OVERFLOW;
|
||||
/*
|
||||
* ST : overrun -
|
||||
* the previous sample was not fetched and lost.
|
||||
* Valid in continuous measurement mode only.
|
||||
* In single measurement mode this error should not occour and we
|
||||
* don't consider this condition an error.
|
||||
* DOR bit is self-clearing when ST2 or any meas. data register is
|
||||
* read.
|
||||
*/
|
||||
if (*stat & 0x02) {
|
||||
/* status = INV_ERROR_COMPASS_DATA_UNDERFLOW; */
|
||||
status = INV_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* trigger next measurement if:
|
||||
* - stat is non zero;
|
||||
* - if stat is zero and stat2 is non zero.
|
||||
* Won't trigger if data is not ready and there was no error.
|
||||
*/
|
||||
if (*stat != 0x00 || (*stat2 & 0x08) != 0x00 ) {
|
||||
result = inv_serial_single_write(
|
||||
mlsl_handle, pdata->address,
|
||||
AK8963_REG_CNTL, AK8963_CNTL_MODE_SINGLE_MEASUREMENT);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int ak8963_config(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct ext_slave_config *data)
|
||||
{
|
||||
int result;
|
||||
if (!data->data)
|
||||
return INV_ERROR_INVALID_PARAMETER;
|
||||
|
||||
switch (data->key) {
|
||||
case MPU_SLAVE_WRITE_REGISTERS:
|
||||
result = inv_serial_write(mlsl_handle, pdata->address,
|
||||
data->len,
|
||||
(unsigned char *)data->data);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_ODR_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_ODR_RESUME:
|
||||
case MPU_SLAVE_CONFIG_FSR_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_FSR_RESUME:
|
||||
case MPU_SLAVE_CONFIG_MOT_THS:
|
||||
case MPU_SLAVE_CONFIG_NMOT_THS:
|
||||
case MPU_SLAVE_CONFIG_MOT_DUR:
|
||||
case MPU_SLAVE_CONFIG_NMOT_DUR:
|
||||
case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_IRQ_RESUME:
|
||||
default:
|
||||
return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||
};
|
||||
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
|
||||
static int ak8963_get_config(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
struct ext_slave_platform_data *pdata,
|
||||
struct ext_slave_config *data)
|
||||
{
|
||||
struct ak8963_private_data *private_data = pdata->private_data;
|
||||
int result;
|
||||
if (!data->data)
|
||||
return INV_ERROR_INVALID_PARAMETER;
|
||||
|
||||
switch (data->key) {
|
||||
case MPU_SLAVE_READ_REGISTERS:
|
||||
{
|
||||
unsigned char *serial_data =
|
||||
(unsigned char *)data->data;
|
||||
result =
|
||||
inv_serial_read(mlsl_handle, pdata->address,
|
||||
serial_data[0], data->len - 1,
|
||||
&serial_data[1]);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPU_SLAVE_READ_SCALE:
|
||||
{
|
||||
unsigned char *serial_data =
|
||||
(unsigned char *)data->data;
|
||||
serial_data[0] = private_data->init.asa[0];
|
||||
serial_data[1] = private_data->init.asa[1];
|
||||
serial_data[2] = private_data->init.asa[2];
|
||||
result = INV_SUCCESS;
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPU_SLAVE_CONFIG_ODR_SUSPEND:
|
||||
(*(unsigned long *)data->data) = 0;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_ODR_RESUME:
|
||||
(*(unsigned long *)data->data) = 8000;
|
||||
break;
|
||||
case MPU_SLAVE_CONFIG_FSR_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_FSR_RESUME:
|
||||
case MPU_SLAVE_CONFIG_MOT_THS:
|
||||
case MPU_SLAVE_CONFIG_NMOT_THS:
|
||||
case MPU_SLAVE_CONFIG_MOT_DUR:
|
||||
case MPU_SLAVE_CONFIG_NMOT_DUR:
|
||||
case MPU_SLAVE_CONFIG_IRQ_SUSPEND:
|
||||
case MPU_SLAVE_CONFIG_IRQ_RESUME:
|
||||
default:
|
||||
return INV_ERROR_FEATURE_NOT_IMPLEMENTED;
|
||||
};
|
||||
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
|
||||
static struct ext_slave_read_trigger ak8963_read_trigger = {
|
||||
/*.reg = */ 0x0A,
|
||||
/*.value = */ 0x11
|
||||
};
|
||||
|
||||
static struct ext_slave_descr ak8963_descr = {
|
||||
.init = ak8963_init,
|
||||
.exit = ak8963_exit,
|
||||
.suspend = ak8963_suspend,
|
||||
.resume = ak8963_resume,
|
||||
.read = ak8963_read,
|
||||
.config = ak8963_config,
|
||||
.get_config = ak8963_get_config,
|
||||
.name = "ak8963",
|
||||
.type = EXT_SLAVE_TYPE_COMPASS,
|
||||
.id = COMPASS_ID_AK8963,
|
||||
.read_reg = 0x01,
|
||||
.read_len = 10,
|
||||
.endian = EXT_SLAVE_LITTLE_ENDIAN,
|
||||
.range = {9830, 4000},
|
||||
.trigger = &ak8963_read_trigger,
|
||||
};
|
||||
|
||||
static
|
||||
struct ext_slave_descr *ak8963_get_slave_descr(void)
|
||||
{
|
||||
return &ak8963_descr;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
struct ak8963_mod_private_data {
|
||||
struct i2c_client *client;
|
||||
struct ext_slave_platform_data *pdata;
|
||||
};
|
||||
|
||||
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
|
||||
|
||||
static int ak8963_parse_dt(struct i2c_client *client,
|
||||
struct ext_slave_platform_data *data)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np = client->dev.of_node;
|
||||
//enum of_gpio_flags gpioflags;
|
||||
int length = 0,size = 0;
|
||||
struct property *prop;
|
||||
int debug = 1;
|
||||
int i;
|
||||
int orig_x,orig_y,orig_z;
|
||||
u32 orientation[9];
|
||||
|
||||
ret = of_property_read_u32(np,"compass-bus",&data->bus);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get compass-bus error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np,"compass-adapt_num",&data->adapt_num);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get compass-adapt_num error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "compass-orientation", &length);
|
||||
if (!prop){
|
||||
dev_err(&client->dev, "get compass-orientation length error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = length / sizeof(int);
|
||||
|
||||
if((size > 0)&&(size <10)){
|
||||
ret = of_property_read_u32_array(np, "compass-orientation",
|
||||
orientation,
|
||||
size);
|
||||
if(ret<0){
|
||||
dev_err(&client->dev, "get compass-orientation data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
printk(" use default orientation\n");
|
||||
}
|
||||
|
||||
for(i=0;i<9;i++)
|
||||
data->orientation[i]= orientation[i];
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-x",&orig_x);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-x error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_x>0){
|
||||
for(i=0;i<3;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-y",&orig_y);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-y error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_y>0){
|
||||
for(i=3;i<6;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-z",&orig_z);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-z error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_z>0){
|
||||
for(i=6;i<9;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"compass-debug",&debug);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get compass-debug error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(client->addr)
|
||||
data->address=client->addr;
|
||||
else
|
||||
dev_err(&client->dev, "compass-addr error\n");
|
||||
|
||||
if(debug){
|
||||
printk("bus=%d,adapt_num=%d,addr=%x\n",data->bus, \
|
||||
data->adapt_num,data->address);
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
printk("%d ",data->orientation[i]);
|
||||
|
||||
printk("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int ak8963_mod_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *devid)
|
||||
{
|
||||
int ret=0;
|
||||
struct ext_slave_platform_data *pdata;
|
||||
struct ak8963_mod_private_data *private_data;
|
||||
int result = 0;
|
||||
|
||||
ret = ak8963_parse_dt(client,&ak8963_data);
|
||||
if(ret< 0)
|
||||
printk("parse ak8963 dts failed\n");
|
||||
|
||||
dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name);
|
||||
printk("yemk:ak8963_mod_probe\n");
|
||||
//request gpio for COMPASS_RST
|
||||
#if 0
|
||||
if (gpio_request(COMPASS_RST_PIN, "COMPASS_RST")) {
|
||||
pr_err("%s: failed to request gpio for COMPASS_RST\n", __func__);
|
||||
//return -ENODEV;
|
||||
}
|
||||
gpio_direction_output(COMPASS_RST_PIN, 1);
|
||||
#else
|
||||
//if (gpio_request_one(COMPASS_RST_PIN, GPIOF_OUT_INIT_HIGH, "COMPASS_RST")) {
|
||||
// pr_err("%s: failed to request gpio for COMPASS_RST\n", __func__);
|
||||
//return -ENODEV;
|
||||
//}
|
||||
#endif
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
result = -ENODEV;
|
||||
goto out_no_free;
|
||||
}
|
||||
|
||||
pdata = &ak8963_data;
|
||||
if (!pdata) {
|
||||
dev_err(&client->adapter->dev,
|
||||
"Missing platform data for slave %s\n", devid->name);
|
||||
result = -EFAULT;
|
||||
goto out_no_free;
|
||||
}
|
||||
|
||||
private_data = kzalloc(sizeof(*private_data), GFP_KERNEL);
|
||||
if (!private_data) {
|
||||
result = -ENOMEM;
|
||||
goto out_no_free;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, private_data);
|
||||
private_data->client = client;
|
||||
private_data->pdata = pdata;
|
||||
|
||||
result = inv_mpu_register_slave(THIS_MODULE, client, pdata,
|
||||
ak8963_get_slave_descr);
|
||||
printk(KERN_ERR "invensense: in %s, result is %d\n", __func__, result);
|
||||
if (result) {
|
||||
dev_err(&client->adapter->dev,
|
||||
"Slave registration failed: %s, %d\n",
|
||||
devid->name, result);
|
||||
goto out_free_memory;
|
||||
}
|
||||
printk("yemk:ak8963_mod_probe end\n");
|
||||
return result;
|
||||
|
||||
out_free_memory:
|
||||
kfree(private_data);
|
||||
out_no_free:
|
||||
dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static int ak8963_mod_remove(struct i2c_client *client)
|
||||
{
|
||||
struct ak8963_mod_private_data *private_data =
|
||||
i2c_get_clientdata(client);
|
||||
|
||||
dev_dbg(&client->adapter->dev, "%s\n", __func__);
|
||||
inv_mpu_unregister_slave(client, private_data->pdata,
|
||||
ak8963_get_slave_descr);
|
||||
|
||||
kfree(private_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ak8963_mod_id[] = {
|
||||
{ "ak8963", COMPASS_ID_AK8963 },
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, ak8963_mod_id);
|
||||
|
||||
static const struct of_device_id of_mpu_ak8963_match[] = {
|
||||
{ .compatible = "ak8963" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
static struct i2c_driver ak8963_mod_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.probe = ak8963_mod_probe,
|
||||
.remove = ak8963_mod_remove,
|
||||
.id_table = ak8963_mod_id,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ak8963_mod",
|
||||
.of_match_table = of_mpu_ak8963_match,
|
||||
},
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
static int __init ak8963_mod_init(void)
|
||||
{
|
||||
int res = i2c_add_driver(&ak8963_mod_driver);
|
||||
pr_info("%s: Probe name %s\n", __func__, "ak8963_mod");
|
||||
if (res)
|
||||
pr_err("%s failed\n", __func__);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void __exit ak8963_mod_exit(void)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
i2c_del_driver(&ak8963_mod_driver);
|
||||
}
|
||||
|
||||
module_init(ak8963_mod_init);
|
||||
module_exit(ak8963_mod_exit);
|
||||
|
||||
MODULE_AUTHOR("Invensense Corporation");
|
||||
MODULE_DESCRIPTION("Driver to integrate AK8963 sensor with the MPU");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("ak8963_mod");
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
0
drivers/misc/inv_mpu/compass/ak8972.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ak8972.c
Normal file → Executable file
@@ -27,7 +27,6 @@
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#define DEBUG
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
@@ -68,6 +67,8 @@ struct ak8975_private_data {
|
||||
struct ak8975_config init;
|
||||
};
|
||||
|
||||
struct ext_slave_platform_data ak8975_data;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static int ak8975_init(void *mlsl_handle,
|
||||
struct ext_slave_descr *slave,
|
||||
@@ -82,7 +83,7 @@ static int ak8975_init(void *mlsl_handle,
|
||||
|
||||
if (!private_data)
|
||||
return INV_ERROR_MEMORY_EXAUSTED;
|
||||
#if 0
|
||||
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8975_REG_CNTL,
|
||||
AK8975_CNTL_MODE_POWER_DOWN);
|
||||
@@ -100,7 +101,7 @@ static int ak8975_init(void *mlsl_handle,
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wait at least 200us */
|
||||
udelay(200);
|
||||
|
||||
@@ -117,7 +118,7 @@ static int ak8975_init(void *mlsl_handle,
|
||||
private_data->init.asa[0] = serial_data[0];
|
||||
private_data->init.asa[1] = serial_data[1];
|
||||
private_data->init.asa[2] = serial_data[2];
|
||||
#if 0
|
||||
|
||||
result = inv_serial_single_write(mlsl_handle, pdata->address,
|
||||
AK8975_REG_CNTL,
|
||||
AK8975_CNTL_MODE_POWER_DOWN);
|
||||
@@ -125,7 +126,7 @@ static int ak8975_init(void *mlsl_handle,
|
||||
LOG_RESULT_LOCATION(result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
udelay(100);
|
||||
return INV_SUCCESS;
|
||||
}
|
||||
@@ -390,21 +391,139 @@ struct ak8975_mod_private_data {
|
||||
|
||||
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
|
||||
|
||||
static int ak8975_parse_dt(struct i2c_client *client,
|
||||
struct ext_slave_platform_data *data)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np = client->dev.of_node;
|
||||
//enum of_gpio_flags gpioflags;
|
||||
int length = 0,size = 0;
|
||||
struct property *prop;
|
||||
int debug = 1;
|
||||
int i;
|
||||
int orig_x,orig_y,orig_z;
|
||||
u32 orientation[9];
|
||||
|
||||
ret = of_property_read_u32(np,"compass-bus",&data->bus);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get compass-bus error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np,"compass-adapt_num",&data->adapt_num);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get compass-adapt_num error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
prop = of_find_property(np, "compass-orientation", &length);
|
||||
if (!prop){
|
||||
dev_err(&client->dev, "get compass-orientation length error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = length / sizeof(int);
|
||||
|
||||
if((size > 0)&&(size <10)){
|
||||
ret = of_property_read_u32_array(np, "compass-orientation",
|
||||
orientation,
|
||||
size);
|
||||
if(ret<0){
|
||||
dev_err(&client->dev, "get compass-orientation data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
printk(" use default orientation\n");
|
||||
}
|
||||
|
||||
for(i=0;i<9;i++)
|
||||
data->orientation[i]= orientation[i];
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-x",&orig_x);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-x error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_x>0){
|
||||
for(i=0;i<3;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-y",&orig_y);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-y error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_y>0){
|
||||
for(i=3;i<6;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-z",&orig_z);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-z error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_z>0){
|
||||
for(i=6;i<9;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"compass-debug",&debug);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get compass-debug error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(client->addr)
|
||||
data->address=client->addr;
|
||||
else
|
||||
dev_err(&client->dev, "compass-addr error\n");
|
||||
|
||||
if(debug){
|
||||
printk("bus=%d,adapt_num=%d,addr=%x\n",data->bus, \
|
||||
data->adapt_num,data->address);
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
printk("%d ",data->orientation[i]);
|
||||
|
||||
printk("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ak8975_mod_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *devid)
|
||||
{
|
||||
struct ext_slave_platform_data *pdata;
|
||||
struct ak8975_mod_private_data *private_data;
|
||||
int result = 0;
|
||||
int ret;
|
||||
|
||||
dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);
|
||||
|
||||
ret = ak8975_parse_dt(client,&ak8975_data);
|
||||
if(ret< 0)
|
||||
printk("parse ak8975 dts failed\n");
|
||||
dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name);
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
result = -ENODEV;
|
||||
goto out_no_free;
|
||||
}
|
||||
|
||||
pdata = client->dev.platform_data;
|
||||
pdata = &ak8975_data;;
|
||||
if (!pdata) {
|
||||
dev_err(&client->adapter->dev,
|
||||
"Missing platform data for slave %s\n", devid->name);
|
||||
@@ -461,6 +580,11 @@ static const struct i2c_device_id ak8975_mod_id[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, ak8975_mod_id);
|
||||
|
||||
static const struct of_device_id of_mpu_ak8975_match[] = {
|
||||
{ .compatible = "ak8975" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
static struct i2c_driver ak8975_mod_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.probe = ak8975_mod_probe,
|
||||
@@ -469,6 +593,7 @@ static struct i2c_driver ak8975_mod_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ak8975_mod",
|
||||
.of_match_table = of_mpu_ak8975_match,
|
||||
},
|
||||
.address_list = normal_i2c,
|
||||
};
|
||||
|
||||
0
drivers/misc/inv_mpu/compass/ami306.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami306.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami30x.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami30x.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami_hw.h
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami_hw.h
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami_sensor_def.h
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/ami_sensor_def.h
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/hmc5883.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/hmc5883.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/hscdtd002b.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/hscdtd002b.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/hscdtd004a.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/hscdtd004a.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/lsm303dlx_m.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/lsm303dlx_m.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/mmc314x.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/mmc314x.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/yas529-kernel.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/yas529-kernel.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/yas530.c
Normal file → Executable file
0
drivers/misc/inv_mpu/compass/yas530.c
Normal file → Executable file
0
drivers/misc/inv_mpu/log.h
Normal file → Executable file
0
drivers/misc/inv_mpu/log.h
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
2
drivers/misc/inv_mpu/mldl_cfg.h
Normal file → Executable file
2
drivers/misc/inv_mpu/mldl_cfg.h
Normal file → Executable file
@@ -31,7 +31,7 @@
|
||||
#include "mltypes.h"
|
||||
#include "mlsl.h"
|
||||
#include <linux/mpu.h>
|
||||
#include "mpu3050.h"
|
||||
#include "mpu6050b1.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
|
||||
21
drivers/misc/inv_mpu/mldl_print_cfg.c
Normal file → Executable file
21
drivers/misc/inv_mpu/mldl_print_cfg.c
Normal file → Executable file
@@ -50,16 +50,16 @@ void mldl_print_cfg(struct mldl_cfg *mldl_cfg)
|
||||
int ii;
|
||||
|
||||
/* mpu_gyro_cfg */
|
||||
MPL_LOGI("int_config = %02x\n", mpu_gyro_cfg->int_config);
|
||||
MPL_LOGI("ext_sync = %02x\n", mpu_gyro_cfg->ext_sync);
|
||||
MPL_LOGI("full_scale = %02x\n", mpu_gyro_cfg->full_scale);
|
||||
MPL_LOGI("lpf = %02x\n", mpu_gyro_cfg->lpf);
|
||||
MPL_LOGI("clk_src = %02x\n", mpu_gyro_cfg->clk_src);
|
||||
MPL_LOGI("divider = %02x\n", mpu_gyro_cfg->divider);
|
||||
MPL_LOGI("dmp_enable = %02x\n", mpu_gyro_cfg->dmp_enable);
|
||||
MPL_LOGI("fifo_enable = %02x\n", mpu_gyro_cfg->fifo_enable);
|
||||
MPL_LOGI("dmp_cfg1 = %02x\n", mpu_gyro_cfg->dmp_cfg1);
|
||||
MPL_LOGI("dmp_cfg2 = %02x\n", mpu_gyro_cfg->dmp_cfg2);
|
||||
MPL_LOGV("int_config = %02x\n", mpu_gyro_cfg->int_config);
|
||||
MPL_LOGV("ext_sync = %02x\n", mpu_gyro_cfg->ext_sync);
|
||||
MPL_LOGV("full_scale = %02x\n", mpu_gyro_cfg->full_scale);
|
||||
MPL_LOGV("lpf = %02x\n", mpu_gyro_cfg->lpf);
|
||||
MPL_LOGV("clk_src = %02x\n", mpu_gyro_cfg->clk_src);
|
||||
MPL_LOGV("divider = %02x\n", mpu_gyro_cfg->divider);
|
||||
MPL_LOGV("dmp_enable = %02x\n", mpu_gyro_cfg->dmp_enable);
|
||||
MPL_LOGV("fifo_enable = %02x\n", mpu_gyro_cfg->fifo_enable);
|
||||
MPL_LOGV("dmp_cfg1 = %02x\n", mpu_gyro_cfg->dmp_cfg1);
|
||||
MPL_LOGV("dmp_cfg2 = %02x\n", mpu_gyro_cfg->dmp_cfg2);
|
||||
/* mpu_offsets */
|
||||
MPL_LOGV("tc[0] = %02x\n", mpu_offsets->tc[0]);
|
||||
MPL_LOGV("tc[1] = %02x\n", mpu_offsets->tc[1]);
|
||||
@@ -75,6 +75,7 @@ void mldl_print_cfg(struct mldl_cfg *mldl_cfg)
|
||||
MPL_LOGV("product_revision = %02x\n", mpu_chip_info->product_revision);
|
||||
MPL_LOGV("product_id = %02x\n", mpu_chip_info->product_id);
|
||||
MPL_LOGV("gyro_sens_trim = %02x\n", mpu_chip_info->gyro_sens_trim);
|
||||
MPL_LOGV("accel_sens_trim = %02x\n", mpu_chip_info->accel_sens_trim);
|
||||
|
||||
MPL_LOGV("requested_sensors = %04x\n", inv_mpu_cfg->requested_sensors);
|
||||
MPL_LOGV("ignore_system_suspend= %04x\n",
|
||||
|
||||
0
drivers/misc/inv_mpu/mldl_print_cfg.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mldl_print_cfg.h
Normal file → Executable file
@@ -20,7 +20,7 @@
|
||||
#include "mlsl.h"
|
||||
#include <linux/i2c.h>
|
||||
#include "log.h"
|
||||
#include "mpu3050.h"
|
||||
#include "mpu6050b1.h"
|
||||
|
||||
#define MPU_I2C_RATE 100*1000
|
||||
static int inv_i2c_write(struct i2c_adapter *i2c_adap,
|
||||
@@ -42,13 +42,13 @@ static int inv_i2c_write(struct i2c_adapter *i2c_adap,
|
||||
msgs[0].scl_rate = MPU_I2C_RATE;
|
||||
|
||||
res = i2c_transfer(i2c_adap, msgs, 1);
|
||||
if (res == 1)
|
||||
return 0;
|
||||
else if(res == 0)
|
||||
return -EBUSY;
|
||||
else
|
||||
if (res < 1) {
|
||||
if (res == 0)
|
||||
res = -EIO;
|
||||
LOG_RESULT_LOCATION(res);
|
||||
return res;
|
||||
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inv_i2c_write_register(struct i2c_adapter *i2c_adap,
|
||||
@@ -87,13 +87,13 @@ static int inv_i2c_read(struct i2c_adapter *i2c_adap,
|
||||
msgs[1].scl_rate = MPU_I2C_RATE;
|
||||
|
||||
res = i2c_transfer(i2c_adap, msgs, 2);
|
||||
if (res == 2)
|
||||
return 0;
|
||||
else if(res == 0)
|
||||
return -EBUSY;
|
||||
else
|
||||
if (res < 2) {
|
||||
if (res >= 0)
|
||||
res = -EIO;
|
||||
LOG_RESULT_LOCATION(res);
|
||||
return res;
|
||||
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpu_memory_read(struct i2c_adapter *i2c_adap,
|
||||
|
||||
0
drivers/misc/inv_mpu/mlsl.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mlsl.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mltypes.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mltypes.h
Normal file → Executable file
@@ -16,7 +16,6 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
$
|
||||
*/
|
||||
#define DEBUG
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -50,6 +49,66 @@
|
||||
#include "mldl_cfg.h"
|
||||
#include <linux/mpu.h>
|
||||
|
||||
#include "accel/mpu6050.h"
|
||||
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/iio/consumer.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define CAB_NUM 1
|
||||
#define M_CONST 49152
|
||||
//#define MPU6050_CABLIC "/data/mpu6050_cablic.dat"
|
||||
#define MPU6050_CABLIC "/dev/mtd/mtd6"
|
||||
|
||||
static int mpu6050_get = 0;
|
||||
static bool Is_cab=false;
|
||||
static int count_s=0;
|
||||
static int countx=0;
|
||||
static int countx_l=0;
|
||||
static int county=0;
|
||||
static int county_l=0;
|
||||
static int countz=0;
|
||||
static int countz_l=0;
|
||||
static int get_cablic;
|
||||
static int gsensor_clear = 0;
|
||||
|
||||
|
||||
struct cal_data {
|
||||
int valid;
|
||||
long xoffset;
|
||||
long xoffset_l;
|
||||
long xoffset1;
|
||||
long xoffset1_l;
|
||||
long yoffset;
|
||||
long yoffset_l;
|
||||
long yoffset1;
|
||||
long yoffset1_l;
|
||||
long zoffset;
|
||||
long zoffset_l;
|
||||
long zoffset1;
|
||||
long zoffset1_l;
|
||||
// char magic[4];
|
||||
char reser[512];
|
||||
};
|
||||
|
||||
static struct cal_data cablic_arry[CAB_NUM];
|
||||
static struct kobject *android_gsensor_kobj;
|
||||
|
||||
struct mpu6050_in{
|
||||
//struct timer_list sn_timer;
|
||||
struct workqueue_struct *wq;
|
||||
struct delayed_work delay_work;
|
||||
struct work_struct sn_work;
|
||||
};
|
||||
|
||||
/* Platform data for the MPU */
|
||||
struct mpu_private_data {
|
||||
@@ -77,8 +136,8 @@ struct mpu_private_data {
|
||||
struct module *slave_modules[EXT_SLAVE_NUM_TYPES];
|
||||
};
|
||||
|
||||
struct mpu_platform_data mpu_data;
|
||||
struct mpu_private_data *mpu_private_data;
|
||||
static struct i2c_client *this_client;
|
||||
|
||||
static void mpu_pm_timeout(u_long data)
|
||||
{
|
||||
@@ -135,7 +194,7 @@ static int mpu_pm_notifier_callback(struct notifier_block *nb,
|
||||
static int mpu_dev_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct mpu_private_data *mpu =
|
||||
(struct mpu_private_data *) i2c_get_clientdata(this_client);
|
||||
container_of(file->private_data, struct mpu_private_data, dev);
|
||||
struct i2c_client *client = mpu->client;
|
||||
int result;
|
||||
int ii;
|
||||
@@ -148,7 +207,6 @@ static int mpu_dev_open(struct inode *inode, struct file *file)
|
||||
return -EBUSY;
|
||||
}
|
||||
mpu->pid = current->pid;
|
||||
file->private_data = &mpu->dev;
|
||||
|
||||
/* Reset the sensors to the default */
|
||||
if (result) {
|
||||
@@ -356,19 +414,24 @@ static int inv_mpu_get_config(struct mldl_cfg *mldl_cfg,
|
||||
void *user_data;
|
||||
|
||||
retval = copy_from_user(&config, usr_config, sizeof(config));
|
||||
if (retval)
|
||||
if (retval){
|
||||
printk("inv_mpu_get_config----------------------\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
user_data = config.data;
|
||||
if (config.len && config.data) {
|
||||
void *data;
|
||||
data = kmalloc(config.len, GFP_KERNEL);
|
||||
if (!data)
|
||||
if (!data){
|
||||
printk("inv_mpu_get_config----------------------1\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
retval = copy_from_user(data,
|
||||
(void __user *)config.data, config.len);
|
||||
if (retval) {
|
||||
printk("inv_mpu_get_config----------------------2\n");
|
||||
retval = -EFAULT;
|
||||
kfree(data);
|
||||
return retval;
|
||||
@@ -380,6 +443,7 @@ static int inv_mpu_get_config(struct mldl_cfg *mldl_cfg,
|
||||
retval = copy_to_user((unsigned char __user *)user_data,
|
||||
config.data, config.len);
|
||||
kfree(config.data);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -465,6 +529,55 @@ static int slave_get_config(struct mldl_cfg *mldl_cfg,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int mpu6050_load_cablic(const char *addr)
|
||||
{
|
||||
int ret;
|
||||
long fd = sys_open(addr,O_RDONLY,0);
|
||||
printk("yemk:mpu6050_load_cablic\n");
|
||||
if(fd < 0){
|
||||
printk("mpu6050_load_cablic: open file %s\n", MPU6050_CABLIC);
|
||||
return -1;
|
||||
}
|
||||
ret = sys_read(fd,(char __user *)cablic_arry,sizeof(cablic_arry));
|
||||
sys_close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mpu6050_put_cablic(const char *addr)
|
||||
{
|
||||
long fd = sys_open(addr,O_CREAT | O_RDWR | O_TRUNC,0);
|
||||
printk("yemk:mpu6050_put_cablic\n");
|
||||
if(fd<0){
|
||||
printk("mpu6050_put_cablic: open file%s\n",MPU6050_CABLIC);
|
||||
return;
|
||||
}
|
||||
sys_write(fd,(const char __user *)cablic_arry,sizeof(cablic_arry));
|
||||
|
||||
sys_close(fd);
|
||||
}
|
||||
static void mpu_get(struct work_struct *work)
|
||||
{
|
||||
struct mpu6050_in *bat = container_of((work), \
|
||||
struct mpu6050_in, delay_work);
|
||||
|
||||
if(mpu6050_get==1){
|
||||
mpu6050_put_cablic(MPU6050_CABLIC);
|
||||
mpu6050_get=0;
|
||||
}else{
|
||||
if(get_cablic){
|
||||
get_cablic=0;
|
||||
mpu6050_load_cablic(MPU6050_CABLIC);
|
||||
}
|
||||
}
|
||||
|
||||
if(gsensor_clear==1){
|
||||
mpu6050_put_cablic(MPU6050_CABLIC);
|
||||
gsensor_clear=0;
|
||||
}
|
||||
queue_delayed_work(bat ->wq, &bat ->delay_work, msecs_to_jiffies(3000));
|
||||
}
|
||||
|
||||
static int inv_slave_read(struct mldl_cfg *mldl_cfg,
|
||||
void *gyro_adapter,
|
||||
void *slave_adapter,
|
||||
@@ -561,6 +674,125 @@ static int mpu_handle_mlsl(void *sl_handle,
|
||||
kfree(msg.data);
|
||||
return retval;
|
||||
}
|
||||
static int mpu6050_check(unsigned long arg)
|
||||
{
|
||||
char data[6];
|
||||
short int x,y,z;
|
||||
short int zoffs=0,xoffs=0,yoffs=0;
|
||||
|
||||
if(copy_from_user(data, (unsigned char __user *)arg, sizeof(data)))
|
||||
return -EFAULT;
|
||||
|
||||
x = data[0]*256 + data[1];
|
||||
y = data[2]*256 + data[3];
|
||||
z = data[4]*256 + data[5];
|
||||
xoffs = x;
|
||||
yoffs = y;
|
||||
zoffs = z-M_CONST;
|
||||
//printk("yemk1111 cablic_arry[0].zoffset_l=%8ld\n",cablic_arry[0].zoffset_l);
|
||||
if(Is_cab==true){
|
||||
if(zoffs>0){
|
||||
//printk("zheng cablic_arry[0].zoffset=%8ld\n",cablic_arry[0].zoffset);
|
||||
cablic_arry[0].zoffset+=zoffs;
|
||||
countz++;
|
||||
}else{
|
||||
//printk("zheng cablic_arry[0].zoffset_l=%8ld\n",cablic_arry[0].zoffset_l);
|
||||
cablic_arry[0].zoffset_l+=zoffs;
|
||||
countz_l++;
|
||||
}
|
||||
if(xoffs>0){
|
||||
cablic_arry[0].xoffset+=xoffs;
|
||||
countx++;
|
||||
}else{
|
||||
cablic_arry[0].xoffset_l+=xoffs;
|
||||
countx_l++;
|
||||
}
|
||||
if(yoffs>0){
|
||||
cablic_arry[0].yoffset+=yoffs;
|
||||
county++;
|
||||
}else{
|
||||
cablic_arry[0].yoffset_l+=yoffs;
|
||||
county_l++;
|
||||
}
|
||||
count_s++;
|
||||
//printk("yemk2222 z=%d,zoffs=%d\n",z,zoffs);
|
||||
//printk("yemk2222 x=%8ld,xoffs=%8ld\n",x,xoffs);
|
||||
//printk("yemk2222 y=%8ld,yoffs=%8ld\n",y,yoffs);
|
||||
if(count_s==20){
|
||||
//cablic_arry[0].xoffset=cablic_arry[0].xoffset/count_s;
|
||||
//cablic_arry[0].yoffset=cablic_arry[0].yoffset/count_s;
|
||||
//printk("yemk11:cab_check->zoffset=%8ld\n",cablic_arry[0].zoffset);
|
||||
if(countz)
|
||||
cablic_arry[0].zoffset=(cablic_arry[0].zoffset-cablic_arry[0].zoffset1)/countz;
|
||||
if(countz_l)
|
||||
cablic_arry[0].zoffset_l=(cablic_arry[0].zoffset_l-cablic_arry[0].zoffset1_l)/countz_l;
|
||||
if(countx)
|
||||
cablic_arry[0].xoffset=(cablic_arry[0].xoffset-cablic_arry[0].xoffset1)/countx;
|
||||
if(countx_l)
|
||||
cablic_arry[0].xoffset_l=(cablic_arry[0].xoffset_l-cablic_arry[0].xoffset1_l)/countx_l;
|
||||
if(county)
|
||||
cablic_arry[0].yoffset=(cablic_arry[0].yoffset-cablic_arry[0].yoffset1)/county;
|
||||
if(county_l)
|
||||
cablic_arry[0].yoffset_l=(cablic_arry[0].yoffset_l-cablic_arry[0].yoffset1_l)/county_l;
|
||||
//printk("yemk cab_check->zoffset=%8ld,zoffset1=%8ld\n",cablic_arry[0].zoffset,cablic_arry[0].zoffset1);
|
||||
//printk("yemk cab_check->zoffset=%d\n",cablic_arry[0].yoffset);
|
||||
//printk("yemk2222 cab_check->zoffset=%8ld,..%8ld\n",cablic_arry[0].zoffset,cablic_arry[0].zoffset_l);
|
||||
//printk("yemk2222 cab_check->yoffset=%8ld,..%8ld ..%d --%d\n",cablic_arry[0].yoffset,cablic_arry[0].yoffset_l,county,county_l);
|
||||
//printk("yemk2222 cab_check->zoffset=%8ld,..%8ld ..%d --%d\n",cablic_arry[0].zoffset,cablic_arry[0].zoffset_l,countz,countz_l);
|
||||
cablic_arry[0].zoffset1=cablic_arry[0].zoffset;
|
||||
cablic_arry[0].zoffset1_l=cablic_arry[0].zoffset_l;
|
||||
|
||||
cablic_arry[0].xoffset1=cablic_arry[0].xoffset;
|
||||
cablic_arry[0].xoffset1_l=cablic_arry[0].xoffset_l;
|
||||
|
||||
cablic_arry[0].yoffset1=cablic_arry[0].yoffset;
|
||||
cablic_arry[0].yoffset1_l=cablic_arry[0].yoffset_l;
|
||||
|
||||
Is_cab=false;
|
||||
count_s=0;
|
||||
countx=0;
|
||||
countx_l=0;
|
||||
county=0;
|
||||
county_l=0;
|
||||
countz=0;
|
||||
countz_l=0;
|
||||
mpu6050_get=1;
|
||||
cablic_arry[0].valid=7654321;
|
||||
|
||||
}
|
||||
}else{
|
||||
if(cablic_arry[0].valid == 7654321){
|
||||
if(zoffs>=0){
|
||||
//printk("zheng z=%d,zoffs=%d\n",z,zoffs);
|
||||
data[4] = (z-cablic_arry[0].zoffset)/256;
|
||||
data[5] = (z-cablic_arry[0].zoffset)%256;
|
||||
}else{
|
||||
//printk("fu z=%d,zoffs=%d\n",z,zoffs);
|
||||
data[4] = (z-cablic_arry[0].zoffset_l)/256;
|
||||
data[5] = (z-cablic_arry[0].zoffset_l)%256;
|
||||
}
|
||||
|
||||
if(xoffs>=0){
|
||||
data[0] = (x-cablic_arry[0].xoffset)/256;
|
||||
data[1] = (x-cablic_arry[0].xoffset)%256;
|
||||
}else{
|
||||
data[0] = (x-cablic_arry[0].xoffset_l)/256;
|
||||
data[1] = (x-cablic_arry[0].xoffset_l)%256;
|
||||
}
|
||||
|
||||
if(yoffs>=0){
|
||||
data[2] = (y-cablic_arry[0].yoffset)/256;
|
||||
data[3] = (y-cablic_arry[0].yoffset)%256;
|
||||
}else{
|
||||
data[2] = (y-cablic_arry[0].yoffset_l)/256;
|
||||
data[3] = (y-cablic_arry[0].yoffset_l)%256;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(copy_to_user((unsigned char __user *)arg,data, sizeof(data)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ioctl - I/O control */
|
||||
static long mpu_dev_ioctl(struct file *file,
|
||||
@@ -584,15 +816,16 @@ static long mpu_dev_ioctl(struct file *file,
|
||||
i2c_get_adapter(pdata_slave[ii]->adapt_num);
|
||||
}
|
||||
slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter;
|
||||
|
||||
|
||||
retval = mutex_lock_interruptible(&mpu->mutex);
|
||||
if (retval) {
|
||||
dev_err(&this_client->adapter->dev,
|
||||
dev_err(&client->adapter->dev,
|
||||
"%s: mutex_lock_interruptible returned %d\n",
|
||||
__func__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
case MPU_GET_EXT_SLAVE_PLATFORM_DATA:
|
||||
retval = mpu_dev_ioctl_get_ext_slave_platform_data(
|
||||
@@ -659,7 +892,7 @@ static long mpu_dev_ioctl(struct file *file,
|
||||
slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE],
|
||||
(struct ext_slave_config __user *)arg);
|
||||
break;
|
||||
case MPU_GET_CONFIG_ACCEL:
|
||||
case MPU_GET_CONFIG_ACCEL:
|
||||
retval = slave_get_config(
|
||||
mldl_cfg,
|
||||
slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE],
|
||||
@@ -709,6 +942,7 @@ static long mpu_dev_ioctl(struct file *file,
|
||||
complete(&mpu->completion);
|
||||
break;
|
||||
case MPU_READ_ACCEL:
|
||||
//printk("###########MPU_READ_ACCEL\n");
|
||||
retval = inv_slave_read(
|
||||
mldl_cfg,
|
||||
slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE],
|
||||
@@ -716,6 +950,7 @@ static long mpu_dev_ioctl(struct file *file,
|
||||
slave[EXT_SLAVE_TYPE_ACCEL],
|
||||
pdata_slave[EXT_SLAVE_TYPE_ACCEL],
|
||||
(unsigned char __user *)arg);
|
||||
mpu6050_check(arg);
|
||||
break;
|
||||
case MPU_READ_COMPASS:
|
||||
retval = inv_slave_read(
|
||||
@@ -777,9 +1012,8 @@ static long mpu_dev_ioctl(struct file *file,
|
||||
};
|
||||
|
||||
mutex_unlock(&mpu->mutex);
|
||||
|
||||
|
||||
//dev_dbg(&client->adapter->dev, "%s: %08x, %08lx, %d\n",__func__, cmd, arg, retval);
|
||||
dev_dbg(&client->adapter->dev, "%s: %08x, %08lx, %d\n",
|
||||
__func__, cmd, arg, retval);
|
||||
|
||||
if (retval > 0)
|
||||
retval = -retval;
|
||||
@@ -890,13 +1124,7 @@ static const struct file_operations mpu_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = mpu_read,
|
||||
.poll = mpu_poll,
|
||||
#if HAVE_COMPAT_IOCTL
|
||||
.compat_ioctl = mpu_dev_ioctl,
|
||||
#endif
|
||||
#if HAVE_UNLOCKED_IOCTL
|
||||
.unlocked_ioctl = mpu_dev_ioctl,
|
||||
#endif
|
||||
//.unlocked_ioctl = mpu_dev_ioctl,
|
||||
.open = mpu_dev_open,
|
||||
.release = mpu_release,
|
||||
};
|
||||
@@ -943,7 +1171,7 @@ int inv_mpu_register_slave(struct module *slave_module,
|
||||
}
|
||||
|
||||
slave_pdata->address = slave_client->addr;
|
||||
slave_pdata->irq = gpio_to_irq(slave_client->irq);
|
||||
slave_pdata->irq = 0;
|
||||
slave_pdata->adapt_num = i2c_adapter_id(slave_client->adapter);
|
||||
|
||||
dev_info(&slave_client->adapter->dev,
|
||||
@@ -980,12 +1208,35 @@ int inv_mpu_register_slave(struct module *slave_module,
|
||||
}
|
||||
}
|
||||
|
||||
if (slave_descr->type == EXT_SLAVE_TYPE_ACCEL &&
|
||||
slave_descr->id == ACCEL_ID_MPU6050 &&
|
||||
slave_descr->config) {
|
||||
|
||||
/* pass a reference to the mldl_cfg data
|
||||
structure to the mpu6050 accel "class" */
|
||||
struct ext_slave_config config;
|
||||
config.key = MPU_SLAVE_CONFIG_INTERNAL_REFERENCE;
|
||||
config.len = sizeof(struct mldl_cfg *);
|
||||
config.apply = true;
|
||||
config.data = mldl_cfg;
|
||||
result = slave_descr->config(
|
||||
slave_client->adapter, slave_descr,
|
||||
slave_pdata, &config);
|
||||
if (result) {
|
||||
LOG_RESULT_LOCATION(result);
|
||||
goto out_slavedescr_exit;
|
||||
}
|
||||
}
|
||||
pdata_slave[slave_descr->type] = slave_pdata;
|
||||
mpu->slave_modules[slave_descr->type] = slave_module;
|
||||
mldl_cfg->slave[slave_descr->type] = slave_descr;
|
||||
|
||||
goto out_unlock_mutex;
|
||||
|
||||
out_slavedescr_exit:
|
||||
if (slave_descr->exit)
|
||||
slave_descr->exit(slave_client->adapter,
|
||||
slave_descr, slave_pdata);
|
||||
out_unlock_mutex:
|
||||
mutex_unlock(&mpu->mutex);
|
||||
|
||||
@@ -998,14 +1249,14 @@ out_unlock_mutex:
|
||||
warn_result = slaveirq_init(slave_client->adapter,
|
||||
slave_pdata, irq_name);
|
||||
if (result)
|
||||
dev_err(&slave_client->adapter->dev,
|
||||
dev_WARN(&slave_client->adapter->dev,
|
||||
"%s irq assigned error: %d\n",
|
||||
slave_descr->name, warn_result);
|
||||
} else {
|
||||
dev_warn(&slave_client->adapter->dev,
|
||||
/* dev_WARN(&slave_client->adapter->dev,
|
||||
"%s irq not assigned: %d %d %d\n",
|
||||
slave_descr->name,
|
||||
result, (int)irq_name, slave_pdata->irq);
|
||||
result, (int)irq_name, slave_pdata->irq);*/
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1052,6 +1303,130 @@ void inv_mpu_unregister_slave(struct i2c_client *slave_client,
|
||||
}
|
||||
EXPORT_SYMBOL(inv_mpu_unregister_slave);
|
||||
|
||||
static int mpu_parse_dt(struct i2c_client *client,
|
||||
struct mpu_platform_data *data)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np = client->dev.of_node;
|
||||
//enum of_gpio_flags gpioflags;
|
||||
int length = 0,size = 0;
|
||||
struct property *prop;
|
||||
int debug = 1;
|
||||
int i;
|
||||
char mAarray[20];
|
||||
int orig_x,orig_y,orig_z;
|
||||
enum of_gpio_flags irq_flags;
|
||||
int irq_pin;
|
||||
u32 orientation[GYRO_NUM_AXES * GYRO_NUM_AXES];
|
||||
|
||||
|
||||
irq_pin=of_get_named_gpio_flags(np, "irq-gpio", 0, (enum of_gpio_flags *)&irq_flags);
|
||||
if(irq_pin<0){
|
||||
dev_err(&client->dev, "get irq-gpio error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (gpio_request(irq_pin, "mpu-irq")) {
|
||||
dev_err(&client->dev, "mpu irq request failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
client->irq=gpio_to_irq(irq_pin);
|
||||
|
||||
ret = of_property_read_u32(np,"mpu-int_config",&data->int_config);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get mpu-int_config error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np,"mpu-level_shifter",&data->level_shifter);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get mpu-level_shifter error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
prop = of_find_property(np, "mpu-orientation", &length);
|
||||
if (!prop){
|
||||
dev_err(&client->dev, "get mpu-orientation length error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = length / sizeof(u32);
|
||||
|
||||
if((size > 0)&&(size <10)){
|
||||
ret = of_property_read_u32_array(np, "mpu-orientation",
|
||||
orientation,
|
||||
size);
|
||||
|
||||
if(ret<0){
|
||||
dev_err(&client->dev, "get mpu-orientation data error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
else{
|
||||
printk(" use default orientation\n");
|
||||
}
|
||||
|
||||
for(i=0;i<9;i++)
|
||||
data->orientation[i]= orientation[i];
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-x",&orig_x);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-x error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_x>0){
|
||||
for(i=0;i<3;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-y",&orig_y);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-y error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_y>0){
|
||||
for(i=3;i<6;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"orientation-z",&orig_z);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get orientation-z error\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(orig_z>0){
|
||||
for(i=6;i<9;i++)
|
||||
if(data->orientation[i])
|
||||
data->orientation[i]=-1;
|
||||
}
|
||||
|
||||
|
||||
ret = of_property_read_u32(np,"mpu-debug",&debug);
|
||||
if(ret!=0){
|
||||
dev_err(&client->dev, "get mpu-debug error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(debug){
|
||||
printk("int_config=%d,level_shifter=%d,client.addr=%x,client.irq=%x\n",data->int_config, \
|
||||
data->level_shifter,client->addr,client->irq);
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
printk("%d ",data->orientation[i]);
|
||||
printk("\n");
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned short normal_i2c[] = { I2C_CLIENT_END };
|
||||
|
||||
static const struct i2c_device_id mpu_id[] = {
|
||||
@@ -1069,6 +1444,12 @@ int mpu_probe(struct i2c_client *client, const struct i2c_device_id *devid)
|
||||
struct mldl_cfg *mldl_cfg;
|
||||
int res = 0;
|
||||
int ii = 0;
|
||||
int ret = 0;
|
||||
struct mpu6050_in *mpu6050_l;
|
||||
|
||||
ret = mpu_parse_dt(client,&mpu_data);
|
||||
if(ret< 0)
|
||||
printk("parse mpu dts failed\n");
|
||||
|
||||
dev_info(&client->adapter->dev, "%s: %d\n", __func__, ii++);
|
||||
|
||||
@@ -1082,6 +1463,12 @@ int mpu_probe(struct i2c_client *client, const struct i2c_device_id *devid)
|
||||
res = -ENOMEM;
|
||||
goto out_alloc_data_failed;
|
||||
}
|
||||
mpu6050_l = kzalloc(sizeof(*mpu6050_l), GFP_KERNEL);
|
||||
if (!mpu6050_l) {
|
||||
printk("failed to allocate device info data in mpu6050_init\n");
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
mldl_cfg = &mpu->mldl_cfg;
|
||||
mldl_cfg->mpu_ram = &mpu->mpu_ram;
|
||||
mldl_cfg->mpu_gyro_cfg = &mpu->mpu_gyro_cfg;
|
||||
@@ -1098,7 +1485,6 @@ int mpu_probe(struct i2c_client *client, const struct i2c_device_id *devid)
|
||||
}
|
||||
mpu_private_data = mpu;
|
||||
i2c_set_clientdata(client, mpu);
|
||||
this_client = client;
|
||||
mpu->client = client;
|
||||
|
||||
init_waitqueue_head(&mpu->mpu_event_wait);
|
||||
@@ -1118,13 +1504,11 @@ int mpu_probe(struct i2c_client *client, const struct i2c_device_id *devid)
|
||||
"Unable to register pm_notifier %d\n", res);
|
||||
goto out_register_pm_notifier_failed;
|
||||
}
|
||||
|
||||
pdata = (struct mpu_platform_data *)client->dev.platform_data;
|
||||
if (!pdata) {
|
||||
dev_WARN(&client->adapter->dev,
|
||||
"Missing platform data for mpu\n");
|
||||
}
|
||||
mldl_cfg->pdata = pdata;
|
||||
mpu6050_l->wq = create_singlethread_workqueue("mpu6050_invensen");
|
||||
INIT_DELAYED_WORK(&mpu6050_l->delay_work, mpu_get);
|
||||
queue_delayed_work(mpu6050_l->wq, &mpu6050_l->delay_work, msecs_to_jiffies(3000));
|
||||
|
||||
mldl_cfg->pdata = &mpu_data;
|
||||
|
||||
mldl_cfg->mpu_chip_info->addr = client->addr;
|
||||
res = inv_mpu_open(&mpu->mldl_cfg, client->adapter, NULL, NULL, NULL);
|
||||
@@ -1156,8 +1540,34 @@ int mpu_probe(struct i2c_client *client, const struct i2c_device_id *devid)
|
||||
dev_WARN(&client->adapter->dev,
|
||||
"Missing %s IRQ\n", MPU_NAME);
|
||||
}
|
||||
|
||||
if (!strcmp(mpu_id[1].name, devid->name)) {
|
||||
/* Special case to re-use the inv_mpu_register_slave */
|
||||
struct ext_slave_platform_data *slave_pdata;
|
||||
slave_pdata = kzalloc(sizeof(*slave_pdata), GFP_KERNEL);
|
||||
if (!slave_pdata) {
|
||||
res = -ENOMEM;
|
||||
goto out_slave_pdata_kzalloc_failed;
|
||||
}
|
||||
slave_pdata->bus = EXT_SLAVE_BUS_PRIMARY;
|
||||
for (ii = 0; ii < 9; ii++)
|
||||
slave_pdata->orientation[ii] = mpu_data.orientation[ii];
|
||||
res = inv_mpu_register_slave(
|
||||
NULL, client,
|
||||
slave_pdata,
|
||||
mpu6050_get_slave_descr);
|
||||
if (res) {
|
||||
/* if inv_mpu_register_slave fails there are no pointer
|
||||
references to the memory allocated to slave_pdata */
|
||||
kfree(slave_pdata);
|
||||
goto out_slave_pdata_kzalloc_failed;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
out_slave_pdata_kzalloc_failed:
|
||||
if (client->irq)
|
||||
mpuirq_exit();
|
||||
out_mpuirq_failed:
|
||||
misc_deregister(&mpu->dev);
|
||||
out_misc_register_failed:
|
||||
@@ -1201,6 +1611,17 @@ static int mpu_remove(struct i2c_client *client)
|
||||
slave_adapter[EXT_SLAVE_TYPE_COMPASS],
|
||||
slave_adapter[EXT_SLAVE_TYPE_PRESSURE]);
|
||||
|
||||
if (mldl_cfg->slave[EXT_SLAVE_TYPE_ACCEL] &&
|
||||
(mldl_cfg->slave[EXT_SLAVE_TYPE_ACCEL]->id ==
|
||||
ACCEL_ID_MPU6050)) {
|
||||
struct ext_slave_platform_data *slave_pdata =
|
||||
mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_ACCEL];
|
||||
inv_mpu_unregister_slave(
|
||||
client,
|
||||
mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_ACCEL],
|
||||
mpu6050_get_slave_descr);
|
||||
kfree(slave_pdata);
|
||||
}
|
||||
|
||||
if (client->irq)
|
||||
mpuirq_exit();
|
||||
@@ -1215,6 +1636,11 @@ static int mpu_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_mpu_match[] = {
|
||||
{ .compatible = "mpu6050" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
|
||||
static struct i2c_driver mpu_driver = {
|
||||
.class = I2C_CLASS_HWMON,
|
||||
.probe = mpu_probe,
|
||||
@@ -1223,6 +1649,7 @@ static struct i2c_driver mpu_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = MPU_NAME,
|
||||
.of_match_table = of_mpu_match,
|
||||
},
|
||||
.address_list = normal_i2c,
|
||||
.shutdown = mpu_shutdown, /* optional */
|
||||
@@ -1230,11 +1657,87 @@ static struct i2c_driver mpu_driver = {
|
||||
.resume = mpu_dev_resume, /* optional */
|
||||
|
||||
};
|
||||
static ssize_t gsensor_check_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%u\n", Is_cab);
|
||||
}
|
||||
|
||||
static ssize_t gsensor_check_store(struct device *dev,
|
||||
struct device_attribute *attr, char *buf,size_t count)
|
||||
{
|
||||
switch (buf[0]) {
|
||||
case '1':
|
||||
Is_cab=true;
|
||||
break;
|
||||
case '0':
|
||||
Is_cab=false;
|
||||
break;
|
||||
default:
|
||||
Is_cab=false;
|
||||
break;
|
||||
}
|
||||
return count;
|
||||
|
||||
}
|
||||
static ssize_t gsensor_clear_store(struct device *dev,
|
||||
struct device_attribute *attr, char *buf,size_t count)
|
||||
{
|
||||
// char mtddevname[64];
|
||||
// int mtd_index;
|
||||
memset(cablic_arry, 0x00, sizeof(cablic_arry));
|
||||
gsensor_clear = 1;
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(gsensorcheck, 0666, gsensor_check_show, gsensor_check_store);
|
||||
static DEVICE_ATTR(gsensorclear, 0666, NULL, gsensor_clear_store);
|
||||
|
||||
|
||||
static int gsensor_sysfs_init(void)
|
||||
{
|
||||
int ret ;
|
||||
|
||||
android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL);
|
||||
if (android_gsensor_kobj == NULL) {
|
||||
printk(KERN_ERR
|
||||
"mpu6050 gsensor_sysfs_init:"\
|
||||
"subsystem_register failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_gsensorclear.attr); // "gsensorclear"
|
||||
if (ret) {
|
||||
printk(KERN_ERR
|
||||
"mpu6050 gsensor_sysfs_init: gsensorclear"\
|
||||
"sysfs_create_group failed\n");
|
||||
goto err4;
|
||||
}
|
||||
ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_gsensorcheck.attr);
|
||||
if (ret) {
|
||||
printk(KERN_ERR
|
||||
"mpu6050 gsensor_sysfs_init:"\
|
||||
"sysfs_create_group failed\n");
|
||||
goto err4;
|
||||
}
|
||||
return 0 ;
|
||||
err4:
|
||||
kobject_del(android_gsensor_kobj);
|
||||
err:
|
||||
return ret ;
|
||||
}
|
||||
|
||||
static int __init mpu_init(void)
|
||||
{
|
||||
int res = i2c_add_driver(&mpu_driver);
|
||||
pr_info("%s: Probe name %s\n", __func__, MPU_NAME);
|
||||
if (res)
|
||||
pr_err("%s failed\n", __func__);
|
||||
|
||||
memset(cablic_arry, 0x00, sizeof(cablic_arry));
|
||||
get_cablic=1;
|
||||
res=gsensor_sysfs_init();
|
||||
if (res)
|
||||
pr_err("%s failed\n", __func__);
|
||||
return res;
|
||||
|
||||
0
drivers/misc/inv_mpu/mpu-dev.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mpu-dev.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mpu3050.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mpu3050.h
Normal file → Executable file
435
drivers/misc/inv_mpu/mpu6050b1.h
Executable file
435
drivers/misc/inv_mpu/mpu6050b1.h
Executable file
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
$License:
|
||||
Copyright (C) 2011 InvenSense Corporation, All Rights Reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup
|
||||
* @brief
|
||||
*
|
||||
* @{
|
||||
* @file mpu6050.h
|
||||
* @brief
|
||||
*/
|
||||
|
||||
#ifndef __MPU_H_
|
||||
#error Do not include this file directly. Include mpu.h instead.
|
||||
#endif
|
||||
|
||||
#ifndef __MPU6050B1_H_
|
||||
#define __MPU6050B1_H_
|
||||
|
||||
|
||||
#define MPU_NAME "mpu6050B1"
|
||||
#define DEFAULT_MPU_SLAVEADDR 0x68
|
||||
|
||||
/*==== MPU6050B1 REGISTER SET ====*/
|
||||
enum {
|
||||
MPUREG_XG_OFFS_TC = 0, /* 0x00, 0 */
|
||||
MPUREG_YG_OFFS_TC, /* 0x01, 1 */
|
||||
MPUREG_ZG_OFFS_TC, /* 0x02, 2 */
|
||||
MPUREG_X_FINE_GAIN, /* 0x03, 3 */
|
||||
MPUREG_Y_FINE_GAIN, /* 0x04, 4 */
|
||||
MPUREG_Z_FINE_GAIN, /* 0x05, 5 */
|
||||
MPUREG_XA_OFFS_H, /* 0x06, 6 */
|
||||
MPUREG_XA_OFFS_L, /* 0x07, 7 */
|
||||
MPUREG_YA_OFFS_H, /* 0x08, 8 */
|
||||
MPUREG_YA_OFFS_L, /* 0x09, 9 */
|
||||
MPUREG_ZA_OFFS_H, /* 0x0a, 10 */
|
||||
MPUREG_ZA_OFFS_L, /* 0x0B, 11 */
|
||||
MPUREG_PRODUCT_ID, /* 0x0c, 12 */
|
||||
MPUREG_0D_RSVD, /* 0x0d, 13 */
|
||||
MPUREG_0E_RSVD, /* 0x0e, 14 */
|
||||
MPUREG_0F_RSVD, /* 0x0f, 15 */
|
||||
MPUREG_10_RSVD, /* 0x00, 16 */
|
||||
MPUREG_11_RSVD, /* 0x11, 17 */
|
||||
MPUREG_12_RSVD, /* 0x12, 18 */
|
||||
MPUREG_XG_OFFS_USRH, /* 0x13, 19 */
|
||||
MPUREG_XG_OFFS_USRL, /* 0x14, 20 */
|
||||
MPUREG_YG_OFFS_USRH, /* 0x15, 21 */
|
||||
MPUREG_YG_OFFS_USRL, /* 0x16, 22 */
|
||||
MPUREG_ZG_OFFS_USRH, /* 0x17, 23 */
|
||||
MPUREG_ZG_OFFS_USRL, /* 0x18, 24 */
|
||||
MPUREG_SMPLRT_DIV, /* 0x19, 25 */
|
||||
MPUREG_CONFIG, /* 0x1A, 26 */
|
||||
MPUREG_GYRO_CONFIG, /* 0x1b, 27 */
|
||||
MPUREG_ACCEL_CONFIG, /* 0x1c, 28 */
|
||||
MPUREG_ACCEL_FF_THR, /* 0x1d, 29 */
|
||||
MPUREG_ACCEL_FF_DUR, /* 0x1e, 30 */
|
||||
MPUREG_ACCEL_MOT_THR, /* 0x1f, 31 */
|
||||
MPUREG_ACCEL_MOT_DUR, /* 0x20, 32 */
|
||||
MPUREG_ACCEL_ZRMOT_THR, /* 0x21, 33 */
|
||||
MPUREG_ACCEL_ZRMOT_DUR, /* 0x22, 34 */
|
||||
MPUREG_FIFO_EN, /* 0x23, 35 */
|
||||
MPUREG_I2C_MST_CTRL, /* 0x24, 36 */
|
||||
MPUREG_I2C_SLV0_ADDR, /* 0x25, 37 */
|
||||
MPUREG_I2C_SLV0_REG, /* 0x26, 38 */
|
||||
MPUREG_I2C_SLV0_CTRL, /* 0x27, 39 */
|
||||
MPUREG_I2C_SLV1_ADDR, /* 0x28, 40 */
|
||||
MPUREG_I2C_SLV1_REG, /* 0x29, 41 */
|
||||
MPUREG_I2C_SLV1_CTRL, /* 0x2a, 42 */
|
||||
MPUREG_I2C_SLV2_ADDR, /* 0x2B, 43 */
|
||||
MPUREG_I2C_SLV2_REG, /* 0x2c, 44 */
|
||||
MPUREG_I2C_SLV2_CTRL, /* 0x2d, 45 */
|
||||
MPUREG_I2C_SLV3_ADDR, /* 0x2E, 46 */
|
||||
MPUREG_I2C_SLV3_REG, /* 0x2f, 47 */
|
||||
MPUREG_I2C_SLV3_CTRL, /* 0x30, 48 */
|
||||
MPUREG_I2C_SLV4_ADDR, /* 0x31, 49 */
|
||||
MPUREG_I2C_SLV4_REG, /* 0x32, 50 */
|
||||
MPUREG_I2C_SLV4_DO, /* 0x33, 51 */
|
||||
MPUREG_I2C_SLV4_CTRL, /* 0x34, 52 */
|
||||
MPUREG_I2C_SLV4_DI, /* 0x35, 53 */
|
||||
MPUREG_I2C_MST_STATUS, /* 0x36, 54 */
|
||||
MPUREG_INT_PIN_CFG, /* 0x37, 55 */
|
||||
MPUREG_INT_ENABLE, /* 0x38, 56 */
|
||||
MPUREG_DMP_INT_STATUS, /* 0x39, 57 */
|
||||
MPUREG_INT_STATUS, /* 0x3A, 58 */
|
||||
MPUREG_ACCEL_XOUT_H, /* 0x3B, 59 */
|
||||
MPUREG_ACCEL_XOUT_L, /* 0x3c, 60 */
|
||||
MPUREG_ACCEL_YOUT_H, /* 0x3d, 61 */
|
||||
MPUREG_ACCEL_YOUT_L, /* 0x3e, 62 */
|
||||
MPUREG_ACCEL_ZOUT_H, /* 0x3f, 63 */
|
||||
MPUREG_ACCEL_ZOUT_L, /* 0x40, 64 */
|
||||
MPUREG_TEMP_OUT_H, /* 0x41, 65 */
|
||||
MPUREG_TEMP_OUT_L, /* 0x42, 66 */
|
||||
MPUREG_GYRO_XOUT_H, /* 0x43, 67 */
|
||||
MPUREG_GYRO_XOUT_L, /* 0x44, 68 */
|
||||
MPUREG_GYRO_YOUT_H, /* 0x45, 69 */
|
||||
MPUREG_GYRO_YOUT_L, /* 0x46, 70 */
|
||||
MPUREG_GYRO_ZOUT_H, /* 0x47, 71 */
|
||||
MPUREG_GYRO_ZOUT_L, /* 0x48, 72 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_00, /* 0x49, 73 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_01, /* 0x4a, 74 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_02, /* 0x4b, 75 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_03, /* 0x4c, 76 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_04, /* 0x4d, 77 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_05, /* 0x4e, 78 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_06, /* 0x4F, 79 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_07, /* 0x50, 80 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_08, /* 0x51, 81 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_09, /* 0x52, 82 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_10, /* 0x53, 83 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_11, /* 0x54, 84 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_12, /* 0x55, 85 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_13, /* 0x56, 86 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_14, /* 0x57, 87 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_15, /* 0x58, 88 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_16, /* 0x59, 89 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_17, /* 0x5a, 90 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_18, /* 0x5B, 91 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_19, /* 0x5c, 92 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_20, /* 0x5d, 93 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_21, /* 0x5e, 94 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_22, /* 0x5f, 95 */
|
||||
MPUREG_EXT_SLV_SENS_DATA_23, /* 0x60, 96 */
|
||||
MPUREG_ACCEL_INTEL_STATUS, /* 0x61, 97 */
|
||||
MPUREG_62_RSVD, /* 0x62, 98 */
|
||||
MPUREG_I2C_SLV0_DO, /* 0x63, 99 */
|
||||
MPUREG_I2C_SLV1_DO, /* 0x64, 100 */
|
||||
MPUREG_I2C_SLV2_DO, /* 0x65, 101 */
|
||||
MPUREG_I2C_SLV3_DO, /* 0x66, 102 */
|
||||
MPUREG_I2C_MST_DELAY_CTRL, /* 0x67, 103 */
|
||||
MPUREG_SIGNAL_PATH_RESET, /* 0x68, 104 */
|
||||
MPUREG_ACCEL_INTEL_CTRL, /* 0x69, 105 */
|
||||
MPUREG_USER_CTRL, /* 0x6A, 106 */
|
||||
MPUREG_PWR_MGMT_1, /* 0x6B, 107 */
|
||||
MPUREG_PWR_MGMT_2, /* 0x6C, 108 */
|
||||
MPUREG_BANK_SEL, /* 0x6D, 109 */
|
||||
MPUREG_MEM_START_ADDR, /* 0x6E, 100 */
|
||||
MPUREG_MEM_R_W, /* 0x6F, 111 */
|
||||
MPUREG_DMP_CFG_1, /* 0x70, 112 */
|
||||
MPUREG_DMP_CFG_2, /* 0x71, 113 */
|
||||
MPUREG_FIFO_COUNTH, /* 0x72, 114 */
|
||||
MPUREG_FIFO_COUNTL, /* 0x73, 115 */
|
||||
MPUREG_FIFO_R_W, /* 0x74, 116 */
|
||||
MPUREG_WHOAMI, /* 0x75, 117 */
|
||||
|
||||
NUM_OF_MPU_REGISTERS /* = 0x76, 118 */
|
||||
};
|
||||
|
||||
/*==== MPU6050B1 MEMORY ====*/
|
||||
enum MPU_MEMORY_BANKS {
|
||||
MEM_RAM_BANK_0 = 0,
|
||||
MEM_RAM_BANK_1,
|
||||
MEM_RAM_BANK_2,
|
||||
MEM_RAM_BANK_3,
|
||||
MEM_RAM_BANK_4,
|
||||
MEM_RAM_BANK_5,
|
||||
MEM_RAM_BANK_6,
|
||||
MEM_RAM_BANK_7,
|
||||
MEM_RAM_BANK_8,
|
||||
MEM_RAM_BANK_9,
|
||||
MEM_RAM_BANK_10,
|
||||
MEM_RAM_BANK_11,
|
||||
MPU_MEM_NUM_RAM_BANKS,
|
||||
MPU_MEM_OTP_BANK_0 = 16
|
||||
};
|
||||
|
||||
|
||||
/*==== MPU6050B1 parameters ====*/
|
||||
|
||||
#define NUM_REGS (NUM_OF_MPU_REGISTERS)
|
||||
#define START_SENS_REGS (0x3B)
|
||||
#define NUM_SENS_REGS (0x60 - START_SENS_REGS + 1)
|
||||
|
||||
/*---- MPU Memory ----*/
|
||||
#define NUM_BANKS (MPU_MEM_NUM_RAM_BANKS)
|
||||
#define BANK_SIZE (256)
|
||||
#define MEM_SIZE (NUM_BANKS * BANK_SIZE)
|
||||
#define MPU_MEM_BANK_SIZE (BANK_SIZE) /*alternative name */
|
||||
|
||||
#define FIFO_HW_SIZE (1024)
|
||||
|
||||
#define NUM_EXT_SLAVES (4)
|
||||
|
||||
|
||||
/*==== BITS FOR MPU6050B1 ====*/
|
||||
/*---- MPU6050B1 'XG_OFFS_TC' register (0, 1, 2) ----*/
|
||||
#define BIT_PU_SLEEP_MODE 0x80
|
||||
#define BITS_XG_OFFS_TC 0x7E
|
||||
#define BIT_OTP_BNK_VLD 0x01
|
||||
|
||||
#define BIT_I2C_MST_VDDIO 0x80
|
||||
#define BITS_YG_OFFS_TC 0x7E
|
||||
#define BITS_ZG_OFFS_TC 0x7E
|
||||
/*---- MPU6050B1 'FIFO_EN' register (23) ----*/
|
||||
#define BIT_TEMP_OUT 0x80
|
||||
#define BIT_GYRO_XOUT 0x40
|
||||
#define BIT_GYRO_YOUT 0x20
|
||||
#define BIT_GYRO_ZOUT 0x10
|
||||
#define BIT_ACCEL 0x08
|
||||
#define BIT_SLV_2 0x04
|
||||
#define BIT_SLV_1 0x02
|
||||
#define BIT_SLV_0 0x01
|
||||
/*---- MPU6050B1 'CONFIG' register (1A) ----*/
|
||||
/*NONE 0xC0 */
|
||||
#define BITS_EXT_SYNC_SET 0x38
|
||||
#define BITS_DLPF_CFG 0x07
|
||||
/*---- MPU6050B1 'GYRO_CONFIG' register (1B) ----*/
|
||||
/* voluntarily modified label from BITS_FS_SEL to
|
||||
* BITS_GYRO_FS_SEL to avoid confusion with MPU
|
||||
*/
|
||||
#define BITS_GYRO_FS_SEL 0x18
|
||||
/*NONE 0x07 */
|
||||
/*---- MPU6050B1 'ACCEL_CONFIG' register (1C) ----*/
|
||||
#define BITS_ACCEL_FS_SEL 0x18
|
||||
#define BITS_ACCEL_HPF 0x07
|
||||
/*---- MPU6050B1 'I2C_MST_CTRL' register (24) ----*/
|
||||
#define BIT_MULT_MST_EN 0x80
|
||||
#define BIT_WAIT_FOR_ES 0x40
|
||||
#define BIT_SLV_3_FIFO_EN 0x20
|
||||
#define BIT_I2C_MST_PSR 0x10
|
||||
#define BITS_I2C_MST_CLK 0x0F
|
||||
/*---- MPU6050B1 'I2C_SLV?_ADDR' register (27,2A,2D,30) ----*/
|
||||
#define BIT_I2C_READ 0x80
|
||||
#define BIT_I2C_WRITE 0x00
|
||||
#define BITS_I2C_ADDR 0x7F
|
||||
/*---- MPU6050B1 'I2C_SLV?_CTRL' register (27,2A,2D,30) ----*/
|
||||
#define BIT_SLV_ENABLE 0x80
|
||||
#define BIT_SLV_BYTE_SW 0x40
|
||||
#define BIT_SLV_REG_DIS 0x20
|
||||
#define BIT_SLV_GRP 0x10
|
||||
#define BITS_SLV_LENG 0x0F
|
||||
/*---- MPU6050B1 'I2C_SLV4_ADDR' register (31) ----*/
|
||||
#define BIT_I2C_SLV4_RNW 0x80
|
||||
/*---- MPU6050B1 'I2C_SLV4_CTRL' register (34) ----*/
|
||||
#define BIT_I2C_SLV4_EN 0x80
|
||||
#define BIT_SLV4_DONE_INT_EN 0x40
|
||||
#define BIT_SLV4_REG_DIS 0x20
|
||||
#define MASK_I2C_MST_DLY 0x1F
|
||||
/*---- MPU6050B1 'I2C_MST_STATUS' register (36) ----*/
|
||||
#define BIT_PASS_THROUGH 0x80
|
||||
#define BIT_I2C_SLV4_DONE 0x40
|
||||
#define BIT_I2C_LOST_ARB 0x20
|
||||
#define BIT_I2C_SLV4_NACK 0x10
|
||||
#define BIT_I2C_SLV3_NACK 0x08
|
||||
#define BIT_I2C_SLV2_NACK 0x04
|
||||
#define BIT_I2C_SLV1_NACK 0x02
|
||||
#define BIT_I2C_SLV0_NACK 0x01
|
||||
/*---- MPU6050B1 'INT_PIN_CFG' register (37) ----*/
|
||||
#define BIT_ACTL 0x80
|
||||
#define BIT_ACTL_LOW 0x80
|
||||
#define BIT_ACTL_HIGH 0x00
|
||||
#define BIT_OPEN 0x40
|
||||
#define BIT_LATCH_INT_EN 0x20
|
||||
#define BIT_INT_ANYRD_2CLEAR 0x10
|
||||
#define BIT_ACTL_FSYNC 0x08
|
||||
#define BIT_FSYNC_INT_EN 0x04
|
||||
#define BIT_BYPASS_EN 0x02
|
||||
#define BIT_CLKOUT_EN 0x01
|
||||
/*---- MPU6050B1 'INT_ENABLE' register (38) ----*/
|
||||
#define BIT_FF_EN 0x80
|
||||
#define BIT_MOT_EN 0x40
|
||||
#define BIT_ZMOT_EN 0x20
|
||||
#define BIT_FIFO_OVERFLOW_EN 0x10
|
||||
#define BIT_I2C_MST_INT_EN 0x08
|
||||
#define BIT_PLL_RDY_EN 0x04
|
||||
#define BIT_DMP_INT_EN 0x02
|
||||
#define BIT_RAW_RDY_EN 0x01
|
||||
/*---- MPU6050B1 'DMP_INT_STATUS' register (39) ----*/
|
||||
/*NONE 0x80 */
|
||||
/*NONE 0x40 */
|
||||
#define BIT_DMP_INT_5 0x20
|
||||
#define BIT_DMP_INT_4 0x10
|
||||
#define BIT_DMP_INT_3 0x08
|
||||
#define BIT_DMP_INT_2 0x04
|
||||
#define BIT_DMP_INT_1 0x02
|
||||
#define BIT_DMP_INT_0 0x01
|
||||
/*---- MPU6050B1 'INT_STATUS' register (3A) ----*/
|
||||
#define BIT_FF_INT 0x80
|
||||
#define BIT_MOT_INT 0x40
|
||||
#define BIT_ZMOT_INT 0x20
|
||||
#define BIT_FIFO_OVERFLOW_INT 0x10
|
||||
#define BIT_I2C_MST_INT 0x08
|
||||
#define BIT_PLL_RDY_INT 0x04
|
||||
#define BIT_DMP_INT 0x02
|
||||
#define BIT_RAW_DATA_RDY_INT 0x01
|
||||
/*---- MPU6050B1 'MPUREG_I2C_MST_DELAY_CTRL' register (0x67) ----*/
|
||||
#define BIT_DELAY_ES_SHADOW 0x80
|
||||
#define BIT_SLV4_DLY_EN 0x10
|
||||
#define BIT_SLV3_DLY_EN 0x08
|
||||
#define BIT_SLV2_DLY_EN 0x04
|
||||
#define BIT_SLV1_DLY_EN 0x02
|
||||
#define BIT_SLV0_DLY_EN 0x01
|
||||
/*---- MPU6050B1 'BANK_SEL' register (6D) ----*/
|
||||
#define BIT_PRFTCH_EN 0x40
|
||||
#define BIT_CFG_USER_BANK 0x20
|
||||
#define BITS_MEM_SEL 0x1f
|
||||
/*---- MPU6050B1 'USER_CTRL' register (6A) ----*/
|
||||
#define BIT_DMP_EN 0x80
|
||||
#define BIT_FIFO_EN 0x40
|
||||
#define BIT_I2C_MST_EN 0x20
|
||||
#define BIT_I2C_IF_DIS 0x10
|
||||
#define BIT_DMP_RST 0x08
|
||||
#define BIT_FIFO_RST 0x04
|
||||
#define BIT_I2C_MST_RST 0x02
|
||||
#define BIT_SIG_COND_RST 0x01
|
||||
/*---- MPU6050B1 'PWR_MGMT_1' register (6B) ----*/
|
||||
#define BIT_H_RESET 0x80
|
||||
#define BIT_SLEEP 0x40
|
||||
#define BIT_CYCLE 0x20
|
||||
#define BIT_PD_PTAT 0x08
|
||||
#define BITS_CLKSEL 0x07
|
||||
/*---- MPU6050B1 'PWR_MGMT_2' register (6C) ----*/
|
||||
#define BITS_LPA_WAKE_CTRL 0xC0
|
||||
#define BITS_LPA_WAKE_1HZ 0x00
|
||||
#define BITS_LPA_WAKE_2HZ 0x40
|
||||
#define BITS_LPA_WAKE_10HZ 0x80
|
||||
#define BITS_LPA_WAKE_40HZ 0xC0
|
||||
#define BIT_STBY_XA 0x20
|
||||
#define BIT_STBY_YA 0x10
|
||||
#define BIT_STBY_ZA 0x08
|
||||
#define BIT_STBY_XG 0x04
|
||||
#define BIT_STBY_YG 0x02
|
||||
#define BIT_STBY_ZG 0x01
|
||||
|
||||
#define ACCEL_MOT_THR_LSB (32) /* mg */
|
||||
#define ACCEL_MOT_DUR_LSB (1)
|
||||
#define ACCEL_ZRMOT_THR_LSB_CONVERSION(mg) ((mg * 1000) / 255)
|
||||
#define ACCEL_ZRMOT_DUR_LSB (64)
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/*---- Alternative names to take care of conflicts with current mpu3050.h ----*/
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/*-- registers --*/
|
||||
#define MPUREG_DLPF_FS_SYNC MPUREG_CONFIG /* 0x1A */
|
||||
|
||||
#define MPUREG_PWR_MGM MPUREG_PWR_MGMT_1 /* 0x6B */
|
||||
#define MPUREG_FIFO_EN1 MPUREG_FIFO_EN /* 0x23 */
|
||||
#define MPUREG_INT_CFG MPUREG_INT_ENABLE /* 0x38 */
|
||||
#define MPUREG_X_OFFS_USRH MPUREG_XG_OFFS_USRH /* 0x13 */
|
||||
#define MPUREG_WHO_AM_I MPUREG_WHOAMI /* 0x75 */
|
||||
#define MPUREG_23_RSVD MPUREG_EXT_SLV_SENS_DATA_00 /* 0x49 */
|
||||
|
||||
/*-- bits --*/
|
||||
/* 'USER_CTRL' register */
|
||||
#define BIT_AUX_IF_EN BIT_I2C_MST_EN
|
||||
#define BIT_AUX_RD_LENG BIT_I2C_MST_EN
|
||||
#define BIT_IME_IF_RST BIT_I2C_MST_RST
|
||||
#define BIT_GYRO_RST BIT_SIG_COND_RST
|
||||
/* 'INT_ENABLE' register */
|
||||
#define BIT_RAW_RDY BIT_RAW_DATA_RDY_INT
|
||||
#define BIT_MPU_RDY_EN BIT_PLL_RDY_EN
|
||||
/* 'INT_STATUS' register */
|
||||
#define BIT_INT_STATUS_FIFO_OVERLOW BIT_FIFO_OVERFLOW_INT
|
||||
|
||||
/*---- MPU6050 Silicon Revisions ----*/
|
||||
#define MPU_SILICON_REV_A2 1 /* MPU6050A2 Device */
|
||||
#define MPU_SILICON_REV_B1 2 /* MPU6050B1 Device */
|
||||
|
||||
/*---- MPU6050 notable product revisions ----*/
|
||||
#define MPU_PRODUCT_KEY_B1_E1_5 105
|
||||
#define MPU_PRODUCT_KEY_B2_F1 431
|
||||
|
||||
/*---- structure containing control variables used by MLDL ----*/
|
||||
/*---- MPU clock source settings ----*/
|
||||
/*---- MPU filter selections ----*/
|
||||
enum mpu_filter {
|
||||
MPU_FILTER_256HZ_NOLPF2 = 0,
|
||||
MPU_FILTER_188HZ,
|
||||
MPU_FILTER_98HZ,
|
||||
MPU_FILTER_42HZ,
|
||||
MPU_FILTER_20HZ,
|
||||
MPU_FILTER_10HZ,
|
||||
MPU_FILTER_5HZ,
|
||||
MPU_FILTER_2100HZ_NOLPF,
|
||||
NUM_MPU_FILTER
|
||||
};
|
||||
|
||||
enum mpu_fullscale {
|
||||
MPU_FS_250DPS = 0,
|
||||
MPU_FS_500DPS,
|
||||
MPU_FS_1000DPS,
|
||||
MPU_FS_2000DPS,
|
||||
NUM_MPU_FS
|
||||
};
|
||||
|
||||
enum mpu_clock_sel {
|
||||
MPU_CLK_SEL_INTERNAL = 0,
|
||||
MPU_CLK_SEL_PLLGYROX,
|
||||
MPU_CLK_SEL_PLLGYROY,
|
||||
MPU_CLK_SEL_PLLGYROZ,
|
||||
MPU_CLK_SEL_PLLEXT32K,
|
||||
MPU_CLK_SEL_PLLEXT19M,
|
||||
MPU_CLK_SEL_RESERVED,
|
||||
MPU_CLK_SEL_STOP,
|
||||
NUM_CLK_SEL
|
||||
};
|
||||
|
||||
enum mpu_ext_sync {
|
||||
MPU_EXT_SYNC_NONE = 0,
|
||||
MPU_EXT_SYNC_TEMP,
|
||||
MPU_EXT_SYNC_GYROX,
|
||||
MPU_EXT_SYNC_GYROY,
|
||||
MPU_EXT_SYNC_GYROZ,
|
||||
MPU_EXT_SYNC_ACCELX,
|
||||
MPU_EXT_SYNC_ACCELY,
|
||||
MPU_EXT_SYNC_ACCELZ,
|
||||
NUM_MPU_EXT_SYNC
|
||||
};
|
||||
|
||||
#define MPUREG_CONFIG_VALUE(ext_sync, lpf) \
|
||||
((ext_sync << 3) | lpf)
|
||||
|
||||
#define MPUREG_GYRO_CONFIG_VALUE(x_st, y_st, z_st, full_scale) \
|
||||
((x_st ? 0x80 : 0) | \
|
||||
(y_st ? 0x70 : 0) | \
|
||||
(z_st ? 0x60 : 0) | \
|
||||
(full_scale << 3))
|
||||
|
||||
#endif /* __MPU6050_H_ */
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <linux/wait.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <linux/mpu.h>
|
||||
#include "mpuirq.h"
|
||||
#include "mldl_cfg.h"
|
||||
@@ -202,8 +202,8 @@ int mpuirq_init(struct i2c_client *mpu_client, struct mldl_cfg *mldl_cfg)
|
||||
|
||||
dev_info(&mpu_client->adapter->dev,
|
||||
"Module Param interface = %s\n", interface);
|
||||
|
||||
mpuirq_dev_data.irq = gpio_to_irq(mpu_client->irq);
|
||||
|
||||
mpuirq_dev_data.irq = mpu_client->irq;
|
||||
mpuirq_dev_data.pid = 0;
|
||||
mpuirq_dev_data.accel_divider = -1;
|
||||
mpuirq_dev_data.data_ready = 0;
|
||||
@@ -217,10 +217,12 @@ int mpuirq_init(struct i2c_client *mpu_client, struct mldl_cfg *mldl_cfg)
|
||||
else
|
||||
flags = IRQF_TRIGGER_RISING;
|
||||
|
||||
flags |= IRQF_SHARED;
|
||||
res =
|
||||
request_irq(mpuirq_dev_data.irq, mpuirq_handler, flags,
|
||||
interface, &mpuirq_dev_data.irq);
|
||||
flags =IRQF_TRIGGER_RISING;//|= IRQF_SHARED;
|
||||
|
||||
res =devm_request_threaded_irq(&mpu_client->dev, mpuirq_dev_data.irq, NULL, mpuirq_handler, flags|IRQF_ONESHOT, interface, &mpuirq_dev_data.irq);
|
||||
//res =
|
||||
// request_irq(mpuirq_dev_data.irq, mpuirq_handler, flags,
|
||||
// interface, &mpuirq_dev_data.irq);
|
||||
if (res) {
|
||||
dev_err(&mpu_client->adapter->dev,
|
||||
"myirqtest: cannot register IRQ %d\n",
|
||||
|
||||
0
drivers/misc/inv_mpu/mpuirq.h
Normal file → Executable file
0
drivers/misc/inv_mpu/mpuirq.h
Normal file → Executable file
0
drivers/misc/inv_mpu/pressure/Kconfig
Normal file → Executable file
0
drivers/misc/inv_mpu/pressure/Kconfig
Normal file → Executable file
0
drivers/misc/inv_mpu/pressure/Makefile
Normal file → Executable file
0
drivers/misc/inv_mpu/pressure/Makefile
Normal file → Executable file
0
drivers/misc/inv_mpu/pressure/bma085.c
Normal file → Executable file
0
drivers/misc/inv_mpu/pressure/bma085.c
Normal file → Executable file
0
drivers/misc/inv_mpu/slaveirq.h
Normal file → Executable file
0
drivers/misc/inv_mpu/slaveirq.h
Normal file → Executable file
@@ -71,7 +71,7 @@ static void timerirq_handler(unsigned long arg)
|
||||
data->data.irqtime = (((long long)irqtime.tv_sec) << 32);
|
||||
data->data.irqtime += irqtime.tv_usec;
|
||||
data->data.data_type |= 1;
|
||||
|
||||
|
||||
dev_dbg(data->dev->this_device,
|
||||
"%s, %lld, %ld\n", __func__, data->data.irqtime,
|
||||
(unsigned long)data);
|
||||
@@ -207,6 +207,7 @@ static long timerirq_ioctl(struct file *file,
|
||||
"%s current->pid %d, %d, %ld\n",
|
||||
__func__, current->pid, cmd, arg);
|
||||
|
||||
|
||||
if (!data)
|
||||
return -EFAULT;
|
||||
|
||||
|
||||
0
drivers/misc/inv_mpu/timerirq.h
Normal file → Executable file
0
drivers/misc/inv_mpu/timerirq.h
Normal file → Executable file
@@ -153,6 +153,7 @@ enum ext_slave_id {
|
||||
|
||||
COMPASS_ID_AK8975,
|
||||
COMPASS_ID_AK8972,
|
||||
COMPASS_ID_AK8963,
|
||||
COMPASS_ID_AMI30X,
|
||||
COMPASS_ID_AMI306,
|
||||
COMPASS_ID_YAS529,
|
||||
@@ -161,6 +162,7 @@ enum ext_slave_id {
|
||||
COMPASS_ID_LSM303DLH,
|
||||
COMPASS_ID_LSM303DLM,
|
||||
COMPASS_ID_MMC314X,
|
||||
COMPASS_ID_MMC328X,
|
||||
COMPASS_ID_HSCDTD002B,
|
||||
COMPASS_ID_HSCDTD004A,
|
||||
|
||||
@@ -300,8 +302,8 @@ struct ext_slave_descr {
|
||||
* column should have exactly 1 non-zero value.
|
||||
*/
|
||||
struct mpu_platform_data {
|
||||
__u8 int_config;
|
||||
__u8 level_shifter;
|
||||
__u32 int_config;
|
||||
__u32 level_shifter;
|
||||
__s8 orientation[GYRO_NUM_AXES * GYRO_NUM_AXES];
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user