diff options
Diffstat (limited to 'drivers/misc/inv_mpu')
52 files changed, 0 insertions, 21045 deletions
diff --git a/drivers/misc/inv_mpu/Kconfig b/drivers/misc/inv_mpu/Kconfig deleted file mode 100644 index 060b79f..0000000 --- a/drivers/misc/inv_mpu/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -config MPU_SENSORS_GYRO - tristate "MPU6050 built in gyroscope" - depends on MPU_SENSORS_MPU6050 - -config MPU_SENSORS_TIMERIRQ - tristate "Timer IRQ" - depends on MPU_SENSORS_MPU6050 - help - If you say yes here you get access to the timerirq device handle which - can be used to select on. This can be used instead of IRQ's, sleeping, - or timer threads. Reading from this device returns the same type of - information as reading from the MPU and slave IRQ's. - -config MPU_SENSORS_DEBUG - bool "MPU6050 MPU debug" - depends on MPU_SENSORS_TIMERIRQ - help - If you say yes here you get extra debug messages from the MPU6050 - and other slave sensors. - -config MPU_SENSORS_CORE - tristate "Sensors core" - - diff --git a/drivers/misc/inv_mpu/Makefile b/drivers/misc/inv_mpu/Makefile deleted file mode 100644 index c129cf2..0000000 --- a/drivers/misc/inv_mpu/Makefile +++ /dev/null @@ -1,22 +0,0 @@ - -# Kernel makefile for motions sensors -# - -# MPU - -obj-$(CONFIG_MPU_SENSORS_MPU6050) += mpu6050.o -mpu6050-objs += mpuirq.o \ - slaveirq.o \ - mpu-dev.o \ - mlsl-kernel.o \ - mldl_cfg.o \ - mldl_print_cfg.o \ - sensors_core.o \ - accel/mpu6050.o \ - compass/ak8975.o - -EXTRA_CFLAGS += -Idrivers/misc/inv_mpu -EXTRA_CFLAGS += -D__C99_DESIGNATED_INITIALIZER -EXTRA_CFLAGS += -DINV_CACHE_DMP=1 - -obj-$(CONFIG_MPU_SENSORS_TIMERIRQ)+= timerirq.o diff --git a/drivers/misc/inv_mpu/README b/drivers/misc/inv_mpu/README deleted file mode 100644 index ce592c8..0000000 --- a/drivers/misc/inv_mpu/README +++ /dev/null @@ -1,104 +0,0 @@ -Kernel driver mpu -===================== - -Supported chips: - * InvenSense IMU3050 - Prefix: 'mpu3050' - Datasheet: - PS-MPU-3000A-00.2.4b.pdf - -Author: InvenSense <http://invensense.com> - -Description ------------ -The mpu is a motion processor unit that controls the mpu3050 gyroscope, a slave -accelerometer, a compass and a pressure sensor. This document describes how to -install the driver into a Linux kernel. - -Sysfs entries -------------- -/dev/mpu -/dev/mpuirq -/dev/accelirq -/dev/compassirq -/dev/pressureirq - -General Remarks MPU3050 ------------------------ -* Valid addresses for the MPU3050 is 0x68. -* Accelerometer must be on the secondary I2C bus for MPU3050, the - magnetometer must be on the primary bus and pressure sensor must - be on the primary bus. - -Programming the chip using /dev/mpu ----------------------------------- -Programming of MPU3050 is done by first opening the /dev/mpu file and -then performing a series of IOCTLS on the handle returned. The IOCTL codes can -be found in mpu.h. Typically this is done by the mllite library in user -space. - -Board and Platform Data ------------------------ - -In order for the driver to work, board and platform data specific to the device -needs to be added to the board file. A mpu_platform_data structure must -be created and populated and set in the i2c_board_info_structure. For details -of each structure member see mpu.h. All values below are simply an example and -should be modified for your platform. - -#include <linux/mpu.h> - -static struct mpu_platform_data mpu3050_data = { - .int_config = 0x10, - .orientation = { -1, 0, 0, - 0, 1, 0, - 0, 0, -1 }, -}; - -/* accel */ -static struct ext_slave_platform_data inv_mpu_kxtf9_data = { - .bus = EXT_SLAVE_BUS_SECONDARY, - .orientation = { -1, 0, 0, - 0, 1, 0, - 0, 0, -1 }, -}; -/* compass */ -static struct ext_slave_platform_data inv_mpu_ak8975_data = { - .bus = EXT_SLAVE_BUS_PRIMARY, - .orientation = { 1, 0, 0, - 0, 1, 0, - 0, 0, 1 }, -}; - -static struct i2c_board_info __initdata panda_inv_mpu_i2c4_boardinfo[] = { - { - I2C_BOARD_INFO("mpu3050", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &mpu3050_data, - }, - { - I2C_BOARD_INFO("kxtf9", 0x0F), - .irq = (IH_GPIO_BASE + ACCEL_IRQ_GPIO), - .platform_data = &inv_mpu_kxtf9_data - }, - { - I2C_BOARD_INFO("ak8975", 0x0E), - .irq = (IH_GPIO_BASE + COMPASS_IRQ_GPIO), - .platform_data = &inv_mpu_ak8975_data, - }, -}; - -Typically the IRQ is a GPIO input pin and needs to be configured properly. If -in the above example GPIO 168 corresponds to IRQ 299, the following should be -done as well: - -#define MPU_GPIO_IRQ 168 - - gpio_request(MPU_GPIO_IRQ,"MPUIRQ"); - gpio_direction_input(MPU_GPIO_IRQ) - -Dynamic Debug -============= - -The mpu3050 makes use of dynamic debug. For details on how to use this -refer to Documentation/dynamic-debug-howto.txt diff --git a/drivers/misc/inv_mpu/accel/Kconfig b/drivers/misc/inv_mpu/accel/Kconfig deleted file mode 100644 index 8e24177..0000000 --- a/drivers/misc/inv_mpu/accel/Kconfig +++ /dev/null @@ -1,133 +0,0 @@ -menuconfig MPU_SENSORS_ACCEL - bool "Accelerometer Slave Sensors" - default n - ---help--- - Say Y here to get to see options for device drivers for various - accelerometrs for integration with the MPU3050 or MPU6050 driver. - This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if MPU_SENSORS_ACCEL - -config MPU_SENSORS_ADXL34X - bool "ADI adxl34x" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the ADI adxl345 or adxl346 accelerometers. - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_BMA222 - bool "Bosch BMA222" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Bosch BMA222 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_BMA150 - bool "Bosch BMA150" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Bosch BMA150 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_BMA250 - bool "Bosch BMA250" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Bosch BMA250 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_KXSD9 - bool "Kionix KXSD9" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Kionix KXSD9 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_KXTF9 - bool "Kionix KXTF9" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Kionix KXFT9 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_LIS331DLH - bool "ST lis331dlh" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the ST lis331dlh accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_LIS3DH - bool "ST lis3dh" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the ST lis3dh accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_LSM303DLX_A - bool "ST lsm303dlx" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the ST lsm303dlh and lsm303dlm accelerometers - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_MMA8450 - bool "Freescale mma8450" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Freescale mma8450 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_MMA845X - bool "Freescale mma8451/8452/8453" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the Freescale mma8451/8452/8453 accelerometer - This support is for integration with the MPU3050 gyroscope device - driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -config MPU_SENSORS_BUILTIN_ACCEL - bool "MPU6050 built in accelerometer" - depends on MPU_SENSORS_MPU6050B1 || MPU_SENSORS_MPU6050A2 - help - This enables support for the MPU6050 built in accelerometer. - This the built in support for integration with the MPU6050 gyroscope - device driver. This is the only accelerometer supported with the - MPU6050. Specifying another accelerometer in the board file will - result in runtime errors. - -endif diff --git a/drivers/misc/inv_mpu/accel/Makefile b/drivers/misc/inv_mpu/accel/Makefile deleted file mode 100644 index 1f0f5be..0000000 --- a/drivers/misc/inv_mpu/accel/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# -# Accel Slaves to MPUxxxx -# -obj-$(CONFIG_MPU_SENSORS_ADXL34X) += inv_mpu_adxl34x.o -inv_mpu_adxl34x-objs += adxl34x.o - -obj-$(CONFIG_MPU_SENSORS_BMA150) += inv_mpu_bma150.o -inv_mpu_bma150-objs += bma150.o - -obj-$(CONFIG_MPU_SENSORS_KXTF9) += inv_mpu_kxtf9.o -inv_mpu_kxtf9-objs += kxtf9.o - -obj-$(CONFIG_MPU_SENSORS_BMA222) += inv_mpu_bma222.o -inv_mpu_bma222-objs += bma222.o - -obj-$(CONFIG_MPU_SENSORS_BMA250) += inv_mpu_bma250.o -inv_mpu_bma250-objs += bma250.o - -obj-$(CONFIG_MPU_SENSORS_KXSD9) += inv_mpu_kxsd9.o -inv_mpu_kxsd9-objs += kxsd9.o - -obj-$(CONFIG_MPU_SENSORS_LIS331DLH) += inv_mpu_lis331.o -inv_mpu_lis331-objs += lis331.o - -obj-$(CONFIG_MPU_SENSORS_LIS3DH) += inv_mpu_lis3dh.o -inv_mpu_lis3dh-objs += lis3dh.o - -obj-$(CONFIG_MPU_SENSORS_LSM303DLX_A) += inv_mpu_lsm303dlx_a.o -inv_mpu_lsm303dlx_a-objs += lsm303dlx_a.o - -obj-$(CONFIG_MPU_SENSORS_MMA8450) += inv_mpu_mma8450.o -inv_mpu_mma8450-objs += mma8450.o - -obj-$(CONFIG_MPU_SENSORS_MMA845X) += inv_mpu_mma845x.o -inv_mpu_mma845x-objs += mma845x.o - -EXTRA_CFLAGS += -Idrivers/misc/inv_mpu -EXTRA_CFLAGS += -D__C99_DESIGNATED_INITIALIZER diff --git a/drivers/misc/inv_mpu/accel/adxl34x.c b/drivers/misc/inv_mpu/accel/adxl34x.c deleted file mode 100644 index f2bff8a..0000000 --- a/drivers/misc/inv_mpu/accel/adxl34x.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - $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 adxl34x.c - * @brief Accelerometer setup and handling methods for AD adxl345 and - * adxl346. - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -/* -------------------------------------------------------------------------- */ - -/* registers */ -#define ADXL34X_ODR_REG (0x2C) -#define ADXL34X_PWR_REG (0x2D) -#define ADXL34X_DATAFORMAT_REG (0x31) - -/* masks */ -#define ADXL34X_ODR_MASK (0x0F) -#define ADXL34X_PWR_SLEEP_MASK (0x04) -#define ADXL34X_PWR_MEAS_MASK (0x08) -#define ADXL34X_DATAFORMAT_JUSTIFY_MASK (0x04) -#define ADXL34X_DATAFORMAT_FSR_MASK (0x03) - -/* -------------------------------------------------------------------------- */ - -struct adxl34x_config { - unsigned int odr; /** < output data rate in mHz */ - unsigned int fsr; /** < full scale range mg */ - unsigned int fsr_reg_mask; /** < register setting for fsr */ -}; - -struct adxl34x_private_data { - struct adxl34x_config suspend; /** < suspend configuration */ - struct adxl34x_config resume; /** < resume configuration */ -}; - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct adxl34x_config *config, - int apply, - long odr) -{ - int result = INV_SUCCESS; - unsigned char new_odr_mask; - - /* ADXL346 (Rev. A) pages 13, 24 */ - if (odr >= 3200000) { - new_odr_mask = 0x0F; - config->odr = 3200000; - } else if (odr >= 1600000) { - new_odr_mask = 0x0E; - config->odr = 1600000; - } else if (odr >= 800000) { - new_odr_mask = 0x0D; - config->odr = 800000; - } else if (odr >= 400000) { - new_odr_mask = 0x0C; - config->odr = 400000; - } else if (odr >= 200000) { - new_odr_mask = 0x0B; - config->odr = 200000; - } else if (odr >= 100000) { - new_odr_mask = 0x0A; - config->odr = 100000; - } else if (odr >= 50000) { - new_odr_mask = 0x09; - config->odr = 50000; - } else if (odr >= 25000) { - new_odr_mask = 0x08; - config->odr = 25000; - } else if (odr >= 12500) { - new_odr_mask = 0x07; - config->odr = 12500; - } else if (odr >= 6250) { - new_odr_mask = 0x06; - config->odr = 6250; - } else if (odr >= 3130) { - new_odr_mask = 0x05; - config->odr = 3130; - } else if (odr >= 1560) { - new_odr_mask = 0x04; - config->odr = 1560; - } else if (odr >= 780) { - new_odr_mask = 0x03; - config->odr = 780; - } else if (odr >= 390) { - new_odr_mask = 0x02; - config->odr = 390; - } else if (odr >= 200) { - new_odr_mask = 0x01; - config->odr = 200; - } else { - new_odr_mask = 0x00; - config->odr = 100; - } - - if (apply) { - unsigned char reg_odr; - result = inv_serial_read(mlsl_handle, pdata->address, - ADXL34X_ODR_REG, 1, ®_odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - reg_odr &= ~ADXL34X_ODR_MASK; - reg_odr |= new_odr_mask; - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_ODR_REG, reg_odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGV("ODR: %d mHz\n", config->odr); - } - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range in milli gees (mg). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct adxl34x_config *config, - int apply, - long fsr) -{ - int result = INV_SUCCESS; - - if (fsr <= 2000) { - config->fsr_reg_mask = 0x00; - config->fsr = 2000; - } else if (fsr <= 4000) { - config->fsr_reg_mask = 0x01; - config->fsr = 4000; - } else if (fsr <= 8000) { - config->fsr_reg_mask = 0x02; - config->fsr = 8000; - } else { /* 8001 -> oo */ - config->fsr_reg_mask = 0x03; - config->fsr = 16000; - } - - if (apply) { - unsigned char reg_df; - result = inv_serial_read(mlsl_handle, pdata->address, - ADXL34X_DATAFORMAT_REG, 1, ®_df); - reg_df &= ~ADXL34X_DATAFORMAT_FSR_MASK; - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_DATAFORMAT_REG, - reg_df | config->fsr_reg_mask); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGV("FSR: %d mg\n", config->fsr); - } - return result; -} - -/** - * @brief facility to retrieve the device configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to store the returned configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct adxl34x_private_data *private_data = - (struct adxl34x_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_IRQ_SUSPEND: - case MPU_SLAVE_CONFIG_IRQ_RESUME: - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -/** - * @brief device configuration facility. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to the configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct adxl34x_private_data *private_data = - (struct adxl34x_private_data *)(pdata->private_data); - - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return adxl34x_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return adxl34x_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return adxl34x_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return adxl34x_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - case MPU_SLAVE_CONFIG_IRQ_RESUME: - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - return INV_SUCCESS; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - - /* - struct adxl34x_config *suspend_config = - &((struct adxl34x_private_data *)pdata->private_data)->suspend; - - result = adxl34x_set_odr(mlsl_handle, pdata, suspend_config, - true, suspend_config->odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; -} - result = adxl34x_set_fsr(mlsl_handle, pdata, suspend_config, - true, suspend_config->fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; -} - */ - - /* - Page 25 - When clearing the sleep bit, it is recommended that the part - be placed into standby mode and then set back to measurement mode - with a subsequent write. - This is done to ensure that the device is properly biased if sleep - mode is manually disabled; otherwise, the first few samples of data - after the sleep bit is cleared may have additional noise, - especially if the device was asleep when the bit was cleared. */ - - /* go in standy-by mode (suspends measurements) */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_PWR_REG, ADXL34X_PWR_MEAS_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* and then in sleep */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_PWR_REG, - ADXL34X_PWR_MEAS_MASK | ADXL34X_PWR_SLEEP_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - struct adxl34x_config *resume_config = - &((struct adxl34x_private_data *)pdata->private_data)->resume; - unsigned char reg; - - /* - Page 25 - When clearing the sleep bit, it is recommended that the part - be placed into standby mode and then set back to measurement mode - with a subsequent write. - This is done to ensure that the device is properly biased if sleep - mode is manually disabled; otherwise, the first few samples of data - after the sleep bit is cleared may have additional noise, - especially if the device was asleep when the bit was cleared. */ - - /* remove sleep, but leave in stand-by */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_PWR_REG, ADXL34X_PWR_MEAS_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = adxl34x_set_odr(mlsl_handle, pdata, resume_config, - true, resume_config->odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* - -> FSR - -> Justiy bit for Big endianess - -> resulution to 10 bits - */ - reg = ADXL34X_DATAFORMAT_JUSTIFY_MASK; - reg |= resume_config->fsr_reg_mask; - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_DATAFORMAT_REG, reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* go in measurement mode */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_PWR_REG, 0x00); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* DATA_FORMAT: full resolution of +/-2g; data is left justified */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - 0x31, reg); - - return result; -} - -/** - * @brief one-time device driver initialization function. - * If the driver is built as a kernel module, this function will be - * called when the module is loaded in the kernel. - * If the driver is built-in in the kernel, this function will be - * called at boot time. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - long range; - - struct adxl34x_private_data *private_data; - private_data = (struct adxl34x_private_data *) - kzalloc(sizeof(struct adxl34x_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - result = adxl34x_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = adxl34x_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - range = range_fixedpoint_to_long_mg(slave->range); - result = adxl34x_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - result = adxl34x_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = adxl34x_suspend(mlsl_handle, slave, pdata); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief one-time device driver exit function. - * If the driver is built as a kernel module, this function will be - * called when the module is removed from the kernel. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int adxl34x_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 struct ext_slave_descr adxl34x_descr = { - .init = adxl34x_init, - .exit = adxl34x_exit, - .suspend = adxl34x_suspend, - .resume = adxl34x_resume, - .read = adxl34x_read, - .config = adxl34x_config, - .get_config = adxl34x_get_config, - .name = "adxl34x", /* 5 or 6 */ - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_ADXL34X, - .read_reg = 0x32, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *adxl34x_get_slave_descr(void) -{ - return &adxl34x_descr; -} - -/* -------------------------------------------------------------------------- */ -struct adxl34x_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int adxl34x_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct adxl34x_mod_private_data *private_data; - int result = 0; - - 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; - 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, - adxl34x_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 adxl34x_mod_remove(struct i2c_client *client) -{ - struct adxl34x_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, - adxl34x_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id adxl34x_mod_id[] = { - { "adxl34x", ACCEL_ID_ADXL34X }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, adxl34x_mod_id); - -static struct i2c_driver adxl34x_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = adxl34x_mod_probe, - .remove = adxl34x_mod_remove, - .id_table = adxl34x_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "adxl34x_mod", - }, - .address_list = normal_i2c, -}; - -static int __init adxl34x_mod_init(void) -{ - int res = i2c_add_driver(&adxl34x_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "adxl34x_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit adxl34x_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&adxl34x_mod_driver); -} - -module_init(adxl34x_mod_init); -module_exit(adxl34x_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate ADXL34X sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("adxl34x_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/bma150.c b/drivers/misc/inv_mpu/accel/bma150.c deleted file mode 100644 index c35f43a..0000000 --- a/drivers/misc/inv_mpu/accel/bma150.c +++ /dev/null @@ -1,776 +0,0 @@ -/* - $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 bma150.c - * @brief Accelerometer setup and handling methods for Bosch BMA150. - */ - -/* -------------------------------------------------------------------------- */ -#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 <linux/mpu.h> -#include "mlsl.h" -#include "mldl_cfg.h" - -/* -------------------------------------------------------------------------- */ -/* registers */ -#define BMA150_CTRL_REG (0x14) -#define BMA150_INT_REG (0x15) -#define BMA150_PWR_REG (0x0A) - -/* masks */ -#define BMA150_CTRL_MASK (0x18) -#define BMA150_CTRL_MASK_ODR (0xF8) -#define BMA150_CTRL_MASK_FSR (0xE7) -#define BMA150_INT_MASK_WUP (0xF8) -#define BMA150_INT_MASK_IRQ (0xDF) -#define BMA150_PWR_MASK_SLEEP (0x01) -#define BMA150_PWR_MASK_SOFT_RESET (0x02) - -/* -------------------------------------------------------------------------- */ -struct bma150_config { - unsigned int odr; /** < output data rate mHz */ - unsigned int fsr; /** < full scale range mgees */ - unsigned int irq_type; /** < type of IRQ, see bma150_set_irq */ - unsigned char ctrl_reg; /** < control register value */ - unsigned char int_reg; /** < interrupt control register value */ -}; - -struct bma150_private_data { - struct bma150_config suspend; /** < suspend configuration */ - struct bma150_config resume; /** < resume configuration */ -}; - -/** - * @brief Simply disables the IRQ since it is not usable on BMA150 devices. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * configuration to apply to, suspend or resume - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param irq_type - * the type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - * The only supported IRQ type is MPU_SLAVE_IRQ_TYPE_NONE which - * corresponds to disabling the IRQ completely. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma150_config *config, - int apply, - long irq_type) -{ - int result = INV_SUCCESS; - - if (irq_type != MPU_SLAVE_IRQ_TYPE_NONE) - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - - config->irq_type = MPU_SLAVE_IRQ_TYPE_NONE; - config->int_reg = 0x00; - - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_CTRL_REG, config->ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_INT_REG, config->int_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma150_config *config, - int apply, - long odr) -{ - unsigned char odr_bits = 0; - unsigned char wup_bits = 0; - int result = INV_SUCCESS; - - if (odr > 100000) { - config->odr = 190000; - odr_bits = 0x03; - } else if (odr > 50000) { - config->odr = 100000; - odr_bits = 0x02; - } else if (odr > 25000) { - config->odr = 50000; - odr_bits = 0x01; - } else if (odr > 0) { - config->odr = 25000; - odr_bits = 0x00; - } else { - config->odr = 0; - wup_bits = 0x00; - } - - config->int_reg &= BMA150_INT_MASK_WUP; - config->ctrl_reg &= BMA150_CTRL_MASK_ODR; - config->ctrl_reg |= odr_bits; - - MPL_LOGV("ODR: %d\n", config->odr); - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_CTRL_REG, config->ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_INT_REG, config->int_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma150_config *config, - int apply, - long fsr) -{ - unsigned char fsr_bits; - int result = INV_SUCCESS; - - if (fsr <= 2048) { - fsr_bits = 0x00; - config->fsr = 2048; - } else if (fsr <= 4096) { - fsr_bits = 0x08; - config->fsr = 4096; - } else { - fsr_bits = 0x10; - config->fsr = 8192; - } - - config->ctrl_reg &= BMA150_CTRL_MASK_FSR; - config->ctrl_reg |= fsr_bits; - - MPL_LOGV("FSR: %d\n", config->fsr); - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_CTRL_REG, config->ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_CTRL_REG, config->ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @brief one-time device driver initialization function. - * If the driver is built as a kernel module, this function will be - * called when the module is loaded in the kernel. - * If the driver is built-in in the kernel, this function will be - * called at boot time. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char reg; - long range; - - struct bma150_private_data *private_data; - private_data = (struct bma150_private_data *) - kzalloc(sizeof(struct bma150_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_PWR_REG, BMA150_PWR_MASK_SOFT_RESET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); - - result = inv_serial_read(mlsl_handle, pdata->address, - BMA150_CTRL_REG, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - private_data->resume.ctrl_reg = reg; - private_data->suspend.ctrl_reg = reg; - - result = inv_serial_read(mlsl_handle, pdata->address, - BMA150_INT_REG, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - private_data->resume.int_reg = reg; - private_data->suspend.int_reg = reg; - - result = bma150_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma150_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - range = range_fixedpoint_to_long_mg(slave->range); - result = bma150_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - result = bma150_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = bma150_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma150_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_PWR_REG, BMA150_PWR_MASK_SLEEP); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief one-time device driver exit function. - * If the driver is built as a kernel module, this function will be - * called when the module is removed from the kernel. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -/** - * @brief device configuration facility. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to the configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct bma150_private_data *private_data = - (struct bma150_private_data *)(pdata->private_data); - - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return bma150_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return bma150_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return bma150_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return bma150_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return bma150_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return bma150_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - return INV_SUCCESS; -} - -/** - * @brief facility to retrieve the device configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to store the returned configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct bma150_private_data *private_data = - (struct bma150_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_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 INV_SUCCESS; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char ctrl_reg; - unsigned char int_reg; - - struct bma150_private_data *private_data = - (struct bma150_private_data *)(pdata->private_data); - - ctrl_reg = private_data->suspend.ctrl_reg; - int_reg = private_data->suspend.int_reg; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_PWR_REG, BMA150_PWR_MASK_SOFT_RESET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_CTRL_REG, ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_INT_REG, int_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_PWR_REG, BMA150_PWR_MASK_SLEEP); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char ctrl_reg; - unsigned char int_reg; - - struct bma150_private_data *private_data = - (struct bma150_private_data *)(pdata->private_data); - - ctrl_reg = private_data->resume.ctrl_reg; - int_reg = private_data->resume.int_reg; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_PWR_REG, BMA150_PWR_MASK_SOFT_RESET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_CTRL_REG, ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_INT_REG, int_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA150_PWR_REG, 0x00); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma150_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - return inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, data); -} - -static struct ext_slave_descr bma150_descr = { - .init = bma150_init, - .exit = bma150_exit, - .suspend = bma150_suspend, - .resume = bma150_resume, - .read = bma150_read, - .config = bma150_config, - .get_config = bma150_get_config, - .name = "bma150", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_BMA150, - .read_reg = 0x02, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *bma150_get_slave_descr(void) -{ - return &bma150_descr; -} - -/* -------------------------------------------------------------------------- */ - -/* Platform data for the MPU */ -struct bma150_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int bma150_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct bma150_mod_private_data *private_data; - int result = 0; - - 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; - 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, - bma150_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 bma150_mod_remove(struct i2c_client *client) -{ - struct bma150_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, - bma150_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id bma150_mod_id[] = { - { "bma150", ACCEL_ID_BMA150 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, bma150_mod_id); - -static struct i2c_driver bma150_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = bma150_mod_probe, - .remove = bma150_mod_remove, - .id_table = bma150_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "bma150_mod", - }, - .address_list = normal_i2c, -}; - -static int __init bma150_mod_init(void) -{ - int res = i2c_add_driver(&bma150_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "bma150_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit bma150_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&bma150_mod_driver); -} - -module_init(bma150_mod_init); -module_exit(bma150_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate BMA150 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("bma150_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/bma222.c b/drivers/misc/inv_mpu/accel/bma222.c deleted file mode 100644 index e9fc99b..0000000 --- a/drivers/misc/inv_mpu/accel/bma222.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - $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 bma222.c - * @brief Accelerometer setup and handling methods for Bosch BMA222. - */ - -/* ------------------ */ -/* - Include Files. - */ -/* ------------------ */ - -#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 <linux/mpu.h> -#include "mlsl.h" -#include "mldl_cfg.h" - -/* -------------------------------------------------------------------------- */ - -#define BMA222_STATUS_REG (0x0A) -#define BMA222_FSR_REG (0x0F) -#define ADXL34X_ODR_REG (0x10) -#define BMA222_PWR_REG (0x11) -#define BMA222_SOFTRESET_REG (0x14) - -#define BMA222_STATUS_RDY_MASK (0x80) -#define BMA222_FSR_MASK (0x0F) -#define BMA222_ODR_MASK (0x1F) -#define BMA222_PWR_SLEEP_MASK (0x80) -#define BMA222_PWR_AWAKE_MASK (0x00) -#define BMA222_SOFTRESET_MASK (0xB6) -#define BMA222_SOFTRESET_MASK (0xB6) - -/* -------------------------------------------------------------------------- */ - -struct bma222_config { - unsigned int odr; /** < output data rate in mHz */ - unsigned int fsr; /** < full scale range mg */ -}; - -struct bma222_private_data { - struct bma222_config suspend; /** < suspend configuration */ - struct bma222_config resume; /** < resume configuration */ -}; - - -/* -------------------------------------------------------------------------- */ - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma222_config *config, - int apply, - long odr) -{ - int result = INV_SUCCESS; - unsigned char reg_odr; - - if (odr >= 1000000) { - reg_odr = 0x0F; - config->odr = 1000000; - } else if (odr >= 500000) { - reg_odr = 0x0E; - config->odr = 500000; - } else if (odr >= 250000) { - reg_odr = 0x0D; - config->odr = 250000; - } else if (odr >= 125000) { - reg_odr = 0x0C; - config->odr = 125000; - } else if (odr >= 62500) { - reg_odr = 0x0B; - config->odr = 62500; - } else if (odr >= 32000) { - reg_odr = 0x0A; - config->odr = 32000; - } else if (odr >= 16000) { - reg_odr = 0x09; - config->odr = 16000; - } else { - reg_odr = 0x08; - config->odr = 8000; - } - - if (apply) { - MPL_LOGV("ODR: %d\n", config->odr); - result = inv_serial_single_write(mlsl_handle, pdata->address, - ADXL34X_ODR_REG, reg_odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma222_config *config, - int apply, - long fsr) -{ - int result = INV_SUCCESS; - unsigned char reg_fsr_mask; - - if (fsr <= 2000) { - reg_fsr_mask = 0x03; - config->fsr = 2000; - } else if (fsr <= 4000) { - reg_fsr_mask = 0x05; - config->fsr = 4000; - } else if (fsr <= 8000) { - reg_fsr_mask = 0x08; - config->fsr = 8000; - } else { /* 8001 -> oo */ - reg_fsr_mask = 0x0C; - config->fsr = 16000; - } - - if (apply) { - MPL_LOGV("FSR: %d\n", config->fsr); - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA222_FSR_REG, reg_fsr_mask); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @brief one-time device driver initialization function. - * If the driver is built as a kernel module, this function will be - * called when the module is loaded in the kernel. - * If the driver is built-in in the kernel, this function will be - * called at boot time. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - - struct bma222_private_data *private_data; - private_data = (struct bma222_private_data *) - kzalloc(sizeof(struct bma222_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA222_SOFTRESET_REG, BMA222_SOFTRESET_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); - - result = bma222_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma222_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = bma222_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, 2000); - result = bma222_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, 2000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA222_PWR_REG, BMA222_PWR_SLEEP_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief one-time device driver exit function. - * If the driver is built as a kernel module, this function will be - * called when the module is removed from the kernel. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - - -/** - * @brief facility to retrieve the device configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to store the returned configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct bma222_private_data *private_data = - (struct bma222_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_IRQ_SUSPEND: - case MPU_SLAVE_CONFIG_IRQ_RESUME: - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -/** - * @brief device configuration facility. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to the configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct bma222_private_data *private_data = - (struct bma222_private_data *)(pdata->private_data); - - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return bma222_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return bma222_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return bma222_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return bma222_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - case MPU_SLAVE_CONFIG_IRQ_RESUME: - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - return INV_SUCCESS; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - struct bma222_config *suspend_config = - &((struct bma222_private_data *)pdata->private_data)->suspend; - - result = bma222_set_odr(mlsl_handle, pdata, suspend_config, - true, suspend_config->odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma222_set_fsr(mlsl_handle, pdata, suspend_config, - true, suspend_config->fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA222_PWR_REG, BMA222_PWR_SLEEP_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - msleep(3); /* 3 ms powerup time maximum */ - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - struct bma222_config *resume_config = - &((struct bma222_private_data *)pdata->private_data)->resume; - - /* Soft reset */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA222_SOFTRESET_REG, BMA222_SOFTRESET_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(10); - - result = bma222_set_odr(mlsl_handle, pdata, resume_config, - true, resume_config->odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma222_set_fsr(mlsl_handle, pdata, resume_config, - true, resume_config->fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma222_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - 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 - return INV_ERROR_ACCEL_DATA_NOT_READY; -} - -static struct ext_slave_descr bma222_descr = { - .init = bma222_init, - .exit = bma222_exit, - .suspend = bma222_suspend, - .resume = bma222_resume, - .read = bma222_read, - .config = bma222_config, - .get_config = bma222_get_config, - .name = "bma222", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_BMA222, - .read_reg = 0x02, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *bma222_get_slave_descr(void) -{ - return &bma222_descr; -} - -/* -------------------------------------------------------------------------- */ - -struct bma222_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int bma222_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct bma222_mod_private_data *private_data; - int result = 0; - - 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; - 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, - bma222_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 bma222_mod_remove(struct i2c_client *client) -{ - struct bma222_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, - bma222_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id bma222_mod_id[] = { - { "bma222", ACCEL_ID_BMA222 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, bma222_mod_id); - -static struct i2c_driver bma222_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = bma222_mod_probe, - .remove = bma222_mod_remove, - .id_table = bma222_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "bma222_mod", - }, - .address_list = normal_i2c, -}; - -static int __init bma222_mod_init(void) -{ - int res = i2c_add_driver(&bma222_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "bma222_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit bma222_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&bma222_mod_driver); -} - -module_init(bma222_mod_init); -module_exit(bma222_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate BMA222 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("bma222_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/bma250.c b/drivers/misc/inv_mpu/accel/bma250.c deleted file mode 100644 index 6a245f4..0000000 --- a/drivers/misc/inv_mpu/accel/bma250.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - $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 bma250.c - * @brief Accelerometer setup and handling methods for Bosch BMA250. - */ - -/* -------------------------------------------------------------------------- */ - -#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 <linux/mpu.h> -#include "mlsl.h" -#include "mldl_cfg.h" - -/* -------------------------------------------------------------------------- */ - -/* registers */ -#define BMA250_STATUS_REG (0x0A) -#define BMA250_FSR_REG (0x0F) -#define BMA250_ODR_REG (0x10) -#define BMA250_PWR_REG (0x11) -#define BMA250_SOFTRESET_REG (0x14) -#define BMA250_INT_TYPE_REG (0x17) -#define BMA250_INT_DST_REG (0x1A) -#define BMA250_INT_SRC_REG (0x1E) - -/* masks */ -#define BMA250_STATUS_RDY_MASK (0x80) -#define BMA250_FSR_MASK (0x0F) -#define BMA250_ODR_MASK (0x1F) -#define BMA250_PWR_SLEEP_MASK (0x80) -#define BMA250_PWR_AWAKE_MASK (0x00) -#define BMA250_SOFTRESET_MASK (0xB6) -#define BMA250_INT_TYPE_MASK (0x10) -#define BMA250_INT_DST_1_MASK (0x01) -#define BMA250_INT_DST_2_MASK (0x80) -#define BMA250_INT_SRC_MASK (0x00) - -/* -------------------------------------------------------------------------- */ - -struct bma250_config { - unsigned int odr; /** < output data rate in mHz */ - unsigned int fsr; /** < full scale range mg */ - unsigned char irq_type; -}; - -struct bma250_private_data { - struct bma250_config suspend; /** < suspend configuration */ - struct bma250_config resume; /** < resume configuration */ -}; - -/* -------------------------------------------------------------------------- */ -/** - * @brief Sets the IRQ to fire when one of the IRQ events occur. - * Threshold and duration will not be used unless the type is MOT or - * NMOT. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * configuration to apply to, suspend or resume - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param irq_type - * the type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma250_config *config, - int apply, long irq_type) -{ - int result = INV_SUCCESS; - unsigned char irqtype_reg; - unsigned char irqdst_reg; - unsigned char irqsrc_reg; - - switch (irq_type) { - case MPU_SLAVE_IRQ_TYPE_DATA_READY: - /* data ready int. */ - irqtype_reg = BMA250_INT_TYPE_MASK; - /* routed to interrupt pin 1 */ - irqdst_reg = BMA250_INT_DST_1_MASK; - /* from filtered data */ - irqsrc_reg = BMA250_INT_SRC_MASK; - break; - /* unfinished - case MPU_SLAVE_IRQ_TYPE_MOTION: - reg1 = 0x00; - reg2 = config->mot_int1_cfg; - reg3 = ; - break; - */ - case MPU_SLAVE_IRQ_TYPE_NONE: - irqtype_reg = 0x00; - irqdst_reg = 0x00; - irqsrc_reg = 0x00; - break; - default: - return INV_ERROR_INVALID_PARAMETER; - break; - } - - config->irq_type = (unsigned char)irq_type; - - if (apply) { - /* select the type of interrupt to use */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_INT_TYPE_REG, irqtype_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* select to which interrupt pin to route it to */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_INT_DST_REG, irqdst_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* select whether the interrupt works off filtered or - unfiltered data */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_INT_SRC_REG, irqsrc_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma250_config *config, - int apply, - long odr) -{ - int result = INV_SUCCESS; - unsigned char reg_odr; - - /* Table uses bandwidth which is half the sample rate */ - odr = odr >> 1; - if (odr >= 1000000) { - reg_odr = 0x0F; - config->odr = 2000000; - } else if (odr >= 500000) { - reg_odr = 0x0E; - config->odr = 1000000; - } else if (odr >= 250000) { - reg_odr = 0x0D; - config->odr = 500000; - } else if (odr >= 125000) { - reg_odr = 0x0C; - config->odr = 250000; - } else if (odr >= 62500) { - reg_odr = 0x0B; - config->odr = 125000; - } else if (odr >= 31250) { - reg_odr = 0x0A; - config->odr = 62500; - } else if (odr >= 15630) { - reg_odr = 0x09; - config->odr = 31250; - } else { - reg_odr = 0x08; - config->odr = 15630; - } - - if (apply) { - MPL_LOGV("ODR: %d\n", config->odr); - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_ODR_REG, reg_odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct bma250_config *config, - int apply, - long fsr) -{ - int result = INV_SUCCESS; - unsigned char reg_fsr_mask; - - if (fsr <= 2000) { - reg_fsr_mask = 0x03; - config->fsr = 2000; - } else if (fsr <= 4000) { - reg_fsr_mask = 0x05; - config->fsr = 4000; - } else if (fsr <= 8000) { - reg_fsr_mask = 0x08; - config->fsr = 8000; - } else { /* 8001 -> oo */ - reg_fsr_mask = 0x0C; - config->fsr = 16000; - } - - if (apply) { - MPL_LOGV("FSR: %d\n", config->fsr); - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_FSR_REG, reg_fsr_mask); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @brief one-time device driver initialization function. - * If the driver is built as a kernel module, this function will be - * called when the module is loaded in the kernel. - * If the driver is built-in in the kernel, this function will be - * called at boot time. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - long range; - - struct bma250_private_data *private_data; - private_data = kzalloc(sizeof(struct bma250_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_SOFTRESET_REG, BMA250_SOFTRESET_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); - - result = bma250_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma250_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - range = range_fixedpoint_to_long_mg(slave->range); - result = bma250_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - result = bma250_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = bma250_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma250_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_PWR_REG, BMA250_PWR_SLEEP_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief one-time device driver exit function. - * If the driver is built as a kernel module, this function will be - * called when the module is removed from the kernel. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -/** - * @brief device configuration facility. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to the configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct bma250_private_data *private_data = - (struct bma250_private_data *)(pdata->private_data); - - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return bma250_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return bma250_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return bma250_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return bma250_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return bma250_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return bma250_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - return INV_SUCCESS; -} - -/** - * @brief facility to retrieve the device configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to store the returned configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct bma250_private_data *private_data = - (struct bma250_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_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 INV_SUCCESS; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - struct bma250_config *suspend_config = - &((struct bma250_private_data *)pdata->private_data)->suspend; - - result = bma250_set_odr(mlsl_handle, pdata, suspend_config, - true, suspend_config->odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma250_set_fsr(mlsl_handle, pdata, suspend_config, - true, suspend_config->fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma250_set_irq(mlsl_handle, pdata, suspend_config, - true, suspend_config->irq_type); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_PWR_REG, BMA250_PWR_SLEEP_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - msleep(3); /* 3 ms powerup time maximum */ - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - struct bma250_config *resume_config = - &((struct bma250_private_data *)pdata->private_data)->resume; - - result = bma250_set_odr(mlsl_handle, pdata, resume_config, - true, resume_config->odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma250_set_fsr(mlsl_handle, pdata, resume_config, - true, resume_config->fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = bma250_set_irq(mlsl_handle, pdata, resume_config, - true, resume_config->irq_type); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write(mlsl_handle, pdata->address, - BMA250_PWR_REG, BMA250_PWR_AWAKE_MASK); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int bma250_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - result = inv_serial_read(mlsl_handle, pdata->address, - BMA250_STATUS_REG, 1, data); - if (1) { /* KLP - workaroud for small data ready window */ - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, data); - return result; - } else - return INV_ERROR_ACCEL_DATA_NOT_READY; -} - -static struct ext_slave_descr bma250_descr = { - .init = bma250_init, - .exit = bma250_exit, - .suspend = bma250_suspend, - .resume = bma250_resume, - .read = bma250_read, - .config = bma250_config, - .get_config = bma250_get_config, - .name = "bma250", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_BMA250, - .read_reg = 0x02, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *bma250_get_slave_descr(void) -{ - return &bma250_descr; -} - -/* -------------------------------------------------------------------------- */ - -/* Platform data for the MPU */ -struct bma250_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int bma250_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct bma250_mod_private_data *private_data; - int result = 0; - - 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; - 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, - bma250_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 bma250_mod_remove(struct i2c_client *client) -{ - struct bma250_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, - bma250_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id bma250_mod_id[] = { - { "bma250", ACCEL_ID_BMA250 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, bma250_mod_id); - -static struct i2c_driver bma250_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = bma250_mod_probe, - .remove = bma250_mod_remove, - .id_table = bma250_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "bma250_mod", - }, - .address_list = normal_i2c, -}; - -static int __init bma250_mod_init(void) -{ - int res = i2c_add_driver(&bma250_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "bma250_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit bma250_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&bma250_mod_driver); -} - -module_init(bma250_mod_init); -module_exit(bma250_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate BMA250 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("bma250_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/cma3000.c b/drivers/misc/inv_mpu/accel/cma3000.c deleted file mode 100644 index 496d1f2..0000000 --- a/drivers/misc/inv_mpu/accel/cma3000.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - $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 Accelerometer setup and handling methods for VTI CMA3000. - * - * @{ - * @file cma3000.c - * @brief Accelerometer setup and handling methods for VTI CMA3000 - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -/* -------------------------------------------------------------------------- */ - -static int cma3000_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - /* RAM reset */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, 0x1d, 0xcd); - return result; -} - -static int cma3000_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - - return INV_SUCCESS; -} - -static int cma3000_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->reg, slave->len, data); - return result; -} - -static struct ext_slave_descr cma3000_descr = { - .init = NULL, - .exit = NULL, - .suspend = cma3000_suspend, - .resume = cma3000_resume, - .read = cma3000_read, - .config = NULL, - .get_config = NULL, - .name = "cma3000", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ID_INVALID, - .read_reg = 0x06, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {2, 0}, - .trigger = NULL, - -}; - -static -struct ext_slave_descr *cma3000_get_slave_descr(void) -{ - return &cma3000_descr; -} - -/* -------------------------------------------------------------------------- */ - -struct cma3000_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int cma3000_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct cma3000_mod_private_data *private_data; - int result = 0; - - 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; - 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, - cma3000_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 cma3000_mod_remove(struct i2c_client *client) -{ - struct cma3000_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, - cma3000_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id cma3000_mod_id[] = { - { "cma3000", ACCEL_ID_CMA3000 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, cma3000_mod_id); - -static struct i2c_driver cma3000_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = cma3000_mod_probe, - .remove = cma3000_mod_remove, - .id_table = cma3000_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "cma3000_mod", - }, - .address_list = normal_i2c, -}; - -static int __init cma3000_mod_init(void) -{ - int res = i2c_add_driver(&cma3000_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "cma3000_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit cma3000_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&cma3000_mod_driver); -} - -module_init(cma3000_mod_init); -module_exit(cma3000_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate CMA3000 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("cma3000_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/kxsd9.c b/drivers/misc/inv_mpu/accel/kxsd9.c deleted file mode 100644 index 5cb4eaf..0000000 --- a/drivers/misc/inv_mpu/accel/kxsd9.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - $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 Accelerometer setup and handling methods for Kionix KXSD9. - * - * @{ - * @file kxsd9.c - * @brief Accelerometer setup and handling methods for Kionix KXSD9. - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -/* -------------------------------------------------------------------------- */ - -static int kxsd9_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - /* CTRL_REGB: low-power standby mode */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, 0x0d, 0x0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -/* full scale setting - register and mask */ -#define ACCEL_KIONIX_CTRL_REG (0x0C) -#define ACCEL_KIONIX_CTRL_MASK (0x3) - -static int kxsd9_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char reg; - - /* Full Scale */ - reg = 0x0; - reg &= ~ACCEL_KIONIX_CTRL_MASK; - reg |= 0x00; - if (slave->range.mantissa == 4) { /* 4g scale = 4.9951 */ - reg |= 0x2; - slave->range.fraction = 9951; - } else if (slave->range.mantissa == 7) { /* 6g scale = 7.5018 */ - reg |= 0x1; - slave->range.fraction = 5018; - } else if (slave->range.mantissa == 9) { /* 8g scale = 9.9902 */ - reg |= 0x0; - slave->range.fraction = 9902; - } else { - slave->range.mantissa = 2; /* 2g scale = 2.5006 */ - slave->range.fraction = 5006; - reg |= 0x3; - } - reg |= 0xC0; /* 100Hz LPF */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_KIONIX_CTRL_REG, reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* normal operation */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, 0x0d, 0x40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return INV_SUCCESS; -} - -static int kxsd9_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 struct ext_slave_descr kxsd9_descr = { - .init = NULL, - .exit = NULL, - .suspend = kxsd9_suspend, - .resume = kxsd9_resume, - .read = kxsd9_read, - .config = NULL, - .get_config = NULL, - .name = "kxsd9", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_KXSD9, - .read_reg = 0x00, - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {2, 5006}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *kxsd9_get_slave_descr(void) -{ - return &kxsd9_descr; -} - -/* -------------------------------------------------------------------------- */ -struct kxsd9_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int kxsd9_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct kxsd9_mod_private_data *private_data; - int result = 0; - - 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; - 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, - kxsd9_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 kxsd9_mod_remove(struct i2c_client *client) -{ - struct kxsd9_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, - kxsd9_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id kxsd9_mod_id[] = { - { "kxsd9", ACCEL_ID_KXSD9 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, kxsd9_mod_id); - -static struct i2c_driver kxsd9_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = kxsd9_mod_probe, - .remove = kxsd9_mod_remove, - .id_table = kxsd9_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "kxsd9_mod", - }, - .address_list = normal_i2c, -}; - -static int __init kxsd9_mod_init(void) -{ - int res = i2c_add_driver(&kxsd9_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "kxsd9_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit kxsd9_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&kxsd9_mod_driver); -} - -module_init(kxsd9_mod_init); -module_exit(kxsd9_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate KXSD9 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("kxsd9_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/kxtf9.c b/drivers/misc/inv_mpu/accel/kxtf9.c deleted file mode 100644 index 80776f2..0000000 --- a/drivers/misc/inv_mpu/accel/kxtf9.c +++ /dev/null @@ -1,841 +0,0 @@ -/* - $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 Accelerometer setup and handling methods for Kionix KXTF9. - * - * @{ - * @file kxtf9.c - * @brief Accelerometer setup and handling methods for Kionix KXTF9. -*/ - -/* -------------------------------------------------------------------------- */ - -#undef MPL_LOG_NDEBUG -#define MPL_LOG_NDEBUG 1 - -#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-acc" - -#define KXTF9_XOUT_HPF_L (0x00) /* 0000 0000 */ -#define KXTF9_XOUT_HPF_H (0x01) /* 0000 0001 */ -#define KXTF9_YOUT_HPF_L (0x02) /* 0000 0010 */ -#define KXTF9_YOUT_HPF_H (0x03) /* 0000 0011 */ -#define KXTF9_ZOUT_HPF_L (0x04) /* 0001 0100 */ -#define KXTF9_ZOUT_HPF_H (0x05) /* 0001 0101 */ -#define KXTF9_XOUT_L (0x06) /* 0000 0110 */ -#define KXTF9_XOUT_H (0x07) /* 0000 0111 */ -#define KXTF9_YOUT_L (0x08) /* 0000 1000 */ -#define KXTF9_YOUT_H (0x09) /* 0000 1001 */ -#define KXTF9_ZOUT_L (0x0A) /* 0001 1010 */ -#define KXTF9_ZOUT_H (0x0B) /* 0001 1011 */ -#define KXTF9_ST_RESP (0x0C) /* 0000 1100 */ -#define KXTF9_WHO_AM_I (0x0F) /* 0000 1111 */ -#define KXTF9_TILT_POS_CUR (0x10) /* 0001 0000 */ -#define KXTF9_TILT_POS_PRE (0x11) /* 0001 0001 */ -#define KXTF9_INT_SRC_REG1 (0x15) /* 0001 0101 */ -#define KXTF9_INT_SRC_REG2 (0x16) /* 0001 0110 */ -#define KXTF9_STATUS_REG (0x18) /* 0001 1000 */ -#define KXTF9_INT_REL (0x1A) /* 0001 1010 */ -#define KXTF9_CTRL_REG1 (0x1B) /* 0001 1011 */ -#define KXTF9_CTRL_REG2 (0x1C) /* 0001 1100 */ -#define KXTF9_CTRL_REG3 (0x1D) /* 0001 1101 */ -#define KXTF9_INT_CTRL_REG1 (0x1E) /* 0001 1110 */ -#define KXTF9_INT_CTRL_REG2 (0x1F) /* 0001 1111 */ -#define KXTF9_INT_CTRL_REG3 (0x20) /* 0010 0000 */ -#define KXTF9_DATA_CTRL_REG (0x21) /* 0010 0001 */ -#define KXTF9_TILT_TIMER (0x28) /* 0010 1000 */ -#define KXTF9_WUF_TIMER (0x29) /* 0010 1001 */ -#define KXTF9_TDT_TIMER (0x2B) /* 0010 1011 */ -#define KXTF9_TDT_H_THRESH (0x2C) /* 0010 1100 */ -#define KXTF9_TDT_L_THRESH (0x2D) /* 0010 1101 */ -#define KXTF9_TDT_TAP_TIMER (0x2E) /* 0010 1110 */ -#define KXTF9_TDT_TOTAL_TIMER (0x2F) /* 0010 1111 */ -#define KXTF9_TDT_LATENCY_TIMER (0x30) /* 0011 0000 */ -#define KXTF9_TDT_WINDOW_TIMER (0x31) /* 0011 0001 */ -#define KXTF9_WUF_THRESH (0x5A) /* 0101 1010 */ -#define KXTF9_TILT_ANGLE (0x5C) /* 0101 1100 */ -#define KXTF9_HYST_SET (0x5F) /* 0101 1111 */ - -#define KXTF9_MAX_DUR (0xFF) -#define KXTF9_MAX_THS (0xFF) -#define KXTF9_THS_COUNTS_P_G (32) - -/* -------------------------------------------------------------------------- */ - -struct kxtf9_config { - unsigned long odr; /* Output data rate mHz */ - unsigned int fsr; /* full scale range mg */ - unsigned int ths; /* Motion no-motion thseshold mg */ - unsigned int dur; /* Motion no-motion duration ms */ - unsigned int irq_type; - unsigned char reg_ths; - unsigned char reg_dur; - unsigned char reg_odr; - unsigned char reg_int_cfg1; - unsigned char reg_int_cfg2; - unsigned char ctrl_reg1; -}; - -struct kxtf9_private_data { - struct kxtf9_config suspend; - struct kxtf9_config resume; -}; - -static int kxtf9_set_ths(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct kxtf9_config *config, int apply, long ths) -{ - int result = INV_SUCCESS; - if ((ths * KXTF9_THS_COUNTS_P_G / 1000) > KXTF9_MAX_THS) - ths = (long)(KXTF9_MAX_THS * 1000) / KXTF9_THS_COUNTS_P_G; - - if (ths < 0) - ths = 0; - - config->ths = ths; - config->reg_ths = (unsigned char) - ((long)(ths * KXTF9_THS_COUNTS_P_G) / 1000); - MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_WUF_THRESH, - config->reg_ths); - return result; -} - -static int kxtf9_set_dur(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct kxtf9_config *config, int apply, long dur) -{ - int result = INV_SUCCESS; - long reg_dur = (dur * config->odr) / 1000000L; - config->dur = dur; - - if (reg_dur > KXTF9_MAX_DUR) - reg_dur = KXTF9_MAX_DUR; - - config->reg_dur = (unsigned char)reg_dur; - MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_WUF_TIMER, - (unsigned char)reg_dur); - return result; -} - -/** - * Sets the IRQ to fire when one of the IRQ events occur. Threshold and - * duration will not be used uless the type is MOT or NMOT. - * - * @param config configuration to apply to, suspend or resume - * @param irq_type The type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - */ -static int kxtf9_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct kxtf9_config *config, int apply, long irq_type) -{ - int result = INV_SUCCESS; - struct kxtf9_private_data *private_data = pdata->private_data; - - config->irq_type = (unsigned char)irq_type; - config->ctrl_reg1 &= ~0x22; - if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - config->ctrl_reg1 |= 0x20; - config->reg_int_cfg1 = 0x38; - config->reg_int_cfg2 = 0x00; - } else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) { - config->ctrl_reg1 |= 0x02; - if ((unsigned long)config == - (unsigned long)&private_data->suspend) - config->reg_int_cfg1 = 0x34; - else - config->reg_int_cfg1 = 0x24; - config->reg_int_cfg2 = 0xE0; - } else { - config->reg_int_cfg1 = 0x00; - config->reg_int_cfg2 = 0x00; - } - - if (apply) { - /* Must clear bit 7 before writing new configuration */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, 0x40); - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_INT_CTRL_REG1, - config->reg_int_cfg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_INT_CTRL_REG2, - config->reg_int_cfg2); - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, - config->ctrl_reg1); - } - MPL_LOGV("CTRL_REG1: %lx, INT_CFG1: %lx, INT_CFG2: %lx\n", - (unsigned long)config->ctrl_reg1, - (unsigned long)config->reg_int_cfg1, - (unsigned long)config->reg_int_cfg2); - - return result; -} - -/** - * Set the Output data rate for the particular configuration - * - * @param config Config to modify with new ODR - * @param odr Output data rate in units of 1/1000Hz - */ -static int kxtf9_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct kxtf9_config *config, int apply, long odr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - /* Data sheet says there is 12.5 hz, but that seems to produce a single - * correct data value, thus we remove it from the table */ - if (odr > 400000L) { - config->odr = 800000L; - bits = 0x06; - } else if (odr > 200000L) { - config->odr = 400000L; - bits = 0x05; - } else if (odr > 100000L) { - config->odr = 200000L; - bits = 0x04; - } else if (odr > 50000) { - config->odr = 100000L; - bits = 0x03; - } else if (odr > 25000) { - config->odr = 50000; - bits = 0x02; - } else if (odr != 0) { - config->odr = 25000; - bits = 0x01; - } else { - config->odr = 0; - bits = 0; - } - - if (odr != 0) - config->ctrl_reg1 |= 0x80; - else - config->ctrl_reg1 &= ~0x80; - - config->reg_odr = bits; - kxtf9_set_dur(mlsl_handle, pdata, config, apply, config->dur); - MPL_LOGV("ODR: %ld, 0x%02x\n", config->odr, (int)config->ctrl_reg1); - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_DATA_CTRL_REG, - config->reg_odr); - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, 0x40); - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, - config->ctrl_reg1); - } - return result; -} - -/** - * Set the full scale range of the accels - * - * @param config pointer to configuration - * @param fsr requested full scale range - */ -static int kxtf9_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct kxtf9_config *config, int apply, long fsr) -{ - int result = INV_SUCCESS; - - config->ctrl_reg1 = (config->ctrl_reg1 & 0xE7); - if (fsr <= 2000) { - config->fsr = 2000; - config->ctrl_reg1 |= 0x00; - } else if (fsr <= 4000) { - config->fsr = 4000; - config->ctrl_reg1 |= 0x08; - } else { - config->fsr = 8000; - config->ctrl_reg1 |= 0x10; - } - - MPL_LOGV("FSR: %d\n", config->fsr); - if (apply) { - /* Must clear bit 7 before writing new configuration */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, 0x40); - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, - config->ctrl_reg1); - } - return result; -} - -static int kxtf9_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char data; - struct kxtf9_private_data *private_data = pdata->private_data; - - /* Wake up */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, 0x40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* INT_CTRL_REG1: */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_INT_CTRL_REG1, - private_data->suspend.reg_int_cfg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* WUF_THRESH: */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_WUF_THRESH, - private_data->suspend.reg_ths); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* DATA_CTRL_REG */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_DATA_CTRL_REG, - private_data->suspend.reg_odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* WUF_TIMER */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_WUF_TIMER, - private_data->suspend.reg_dur); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Normal operation */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, - private_data->suspend.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(mlsl_handle, pdata->address, - KXTF9_INT_REL, 1, &data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/* full scale setting - register and mask */ -#define ACCEL_KIONIX_CTRL_REG (0x1b) -#define ACCEL_KIONIX_CTRL_MASK (0x18) - -static int kxtf9_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char data; - struct kxtf9_private_data *private_data = pdata->private_data; - - /* Wake up */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, 0x40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* INT_CTRL_REG1: */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_INT_CTRL_REG1, - private_data->resume.reg_int_cfg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* WUF_THRESH: */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_WUF_THRESH, - private_data->resume.reg_ths); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* DATA_CTRL_REG */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_DATA_CTRL_REG, - private_data->resume.reg_odr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* WUF_TIMER */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_WUF_TIMER, - private_data->resume.reg_dur); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Normal operation */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, - private_data->resume.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(mlsl_handle, pdata->address, - KXTF9_INT_REL, 1, &data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return INV_SUCCESS; -} - -static int kxtf9_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - - struct kxtf9_private_data *private_data; - int result = INV_SUCCESS; - - private_data = (struct kxtf9_private_data *) - kzalloc(sizeof(struct kxtf9_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - /* RAM reset */ - /* Fastest Reset */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG1, 0x40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Fastest Reset */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_DATA_CTRL_REG, 0x36); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Reset */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - KXTF9_CTRL_REG3, 0xcd); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(2); - - pdata->private_data = private_data; - - private_data->resume.ctrl_reg1 = 0xC0; - private_data->suspend.ctrl_reg1 = 0x40; - - result = kxtf9_set_dur(mlsl_handle, pdata, &private_data->suspend, - false, 1000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = kxtf9_set_dur(mlsl_handle, pdata, &private_data->resume, - false, 2540); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = kxtf9_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 50000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = kxtf9_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000L); - - result = kxtf9_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, 2000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = kxtf9_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, 2000); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = kxtf9_set_ths(mlsl_handle, pdata, &private_data->suspend, - false, 80); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = kxtf9_set_ths(mlsl_handle, pdata, &private_data->resume, - false, 40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = kxtf9_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = kxtf9_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int kxtf9_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static int kxtf9_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct kxtf9_private_data *private_data = pdata->private_data; - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return kxtf9_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return kxtf9_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return kxtf9_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return kxtf9_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_THS: - return kxtf9_set_ths(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_THS: - return kxtf9_set_ths(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_DUR: - return kxtf9_set_dur(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_DUR: - return kxtf9_set_dur(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return kxtf9_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return kxtf9_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static int kxtf9_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct kxtf9_private_data *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 INV_SUCCESS; -} - -static int kxtf9_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result; - unsigned char reg; - result = inv_serial_read(mlsl_handle, pdata->address, - KXTF9_INT_SRC_REG2, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (!(reg & 0x10)) - return INV_ERROR_ACCEL_DATA_NOT_READY; - - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static struct ext_slave_descr kxtf9_descr = { - .init = kxtf9_init, - .exit = kxtf9_exit, - .suspend = kxtf9_suspend, - .resume = kxtf9_resume, - .read = kxtf9_read, - .config = kxtf9_config, - .get_config = kxtf9_get_config, - .name = "kxtf9", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_KXTF9, - .read_reg = 0x06, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *kxtf9_get_slave_descr(void) -{ - return &kxtf9_descr; -} - -/* -------------------------------------------------------------------------- */ -struct kxtf9_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int kxtf9_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct kxtf9_mod_private_data *private_data; - int result = 0; - - 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; - 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, - kxtf9_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 kxtf9_mod_remove(struct i2c_client *client) -{ - struct kxtf9_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, - kxtf9_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id kxtf9_mod_id[] = { - { "kxtf9", ACCEL_ID_KXTF9 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, kxtf9_mod_id); - -static struct i2c_driver kxtf9_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = kxtf9_mod_probe, - .remove = kxtf9_mod_remove, - .id_table = kxtf9_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "kxtf9_mod", - }, - .address_list = normal_i2c, -}; - -static int __init kxtf9_mod_init(void) -{ - int res = i2c_add_driver(&kxtf9_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "kxtf9_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit kxtf9_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&kxtf9_mod_driver); -} - -module_init(kxtf9_mod_init); -module_exit(kxtf9_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate KXTF9 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("kxtf9_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/lis331.c b/drivers/misc/inv_mpu/accel/lis331.c deleted file mode 100644 index bcbec25..0000000 --- a/drivers/misc/inv_mpu/accel/lis331.c +++ /dev/null @@ -1,745 +0,0 @@ -/* - $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 lis331.c - * @brief Accelerometer setup and handling methods for ST LIS331DLH. - */ - -/* -------------------------------------------------------------------------- */ - -#undef MPL_LOG_NDEBUG -#define MPL_LOG_NDEBUG 1 - -#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-acc" - -/* full scale setting - register & mask */ -#define LIS331DLH_CTRL_REG1 (0x20) -#define LIS331DLH_CTRL_REG2 (0x21) -#define LIS331DLH_CTRL_REG3 (0x22) -#define LIS331DLH_CTRL_REG4 (0x23) -#define LIS331DLH_CTRL_REG5 (0x24) -#define LIS331DLH_HP_FILTER_RESET (0x25) -#define LIS331DLH_REFERENCE (0x26) -#define LIS331DLH_STATUS_REG (0x27) -#define LIS331DLH_OUT_X_L (0x28) -#define LIS331DLH_OUT_X_H (0x29) -#define LIS331DLH_OUT_Y_L (0x2a) -#define LIS331DLH_OUT_Y_H (0x2b) -#define LIS331DLH_OUT_Z_L (0x2b) -#define LIS331DLH_OUT_Z_H (0x2d) - -#define LIS331DLH_INT1_CFG (0x30) -#define LIS331DLH_INT1_SRC (0x31) -#define LIS331DLH_INT1_THS (0x32) -#define LIS331DLH_INT1_DURATION (0x33) - -#define LIS331DLH_INT2_CFG (0x34) -#define LIS331DLH_INT2_SRC (0x35) -#define LIS331DLH_INT2_THS (0x36) -#define LIS331DLH_INT2_DURATION (0x37) - -/* CTRL_REG1 */ -#define LIS331DLH_CTRL_MASK (0x30) -#define LIS331DLH_SLEEP_MASK (0x20) -#define LIS331DLH_PWR_MODE_NORMAL (0x20) - -#define LIS331DLH_MAX_DUR (0x7F) - - -/* -------------------------------------------------------------------------- */ - -struct lis331dlh_config { - unsigned int odr; - unsigned int fsr; /* full scale range mg */ - unsigned int ths; /* Motion no-motion thseshold mg */ - unsigned int dur; /* Motion no-motion duration ms */ - unsigned char reg_ths; - unsigned char reg_dur; - unsigned char ctrl_reg1; - unsigned char irq_type; - unsigned char mot_int1_cfg; -}; - -struct lis331dlh_private_data { - struct lis331dlh_config suspend; - struct lis331dlh_config resume; -}; - -/* -------------------------------------------------------------------------- */ -static int lis331dlh_set_ths(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis331dlh_config *config, - int apply, long ths) -{ - int result = INV_SUCCESS; - if ((unsigned int)ths >= config->fsr) - ths = (long)config->fsr - 1; - - if (ths < 0) - ths = 0; - - config->ths = ths; - config->reg_ths = (unsigned char)(long)((ths * 128L) / (config->fsr)); - MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_THS, - config->reg_ths); - return result; -} - -static int lis331dlh_set_dur(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis331dlh_config *config, - int apply, long dur) -{ - int result = INV_SUCCESS; - long reg_dur = (dur * config->odr) / 1000000L; - config->dur = dur; - - if (reg_dur > LIS331DLH_MAX_DUR) - reg_dur = LIS331DLH_MAX_DUR; - - config->reg_dur = (unsigned char)reg_dur; - MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_DURATION, - (unsigned char)reg_dur); - return result; -} - -/** - * Sets the IRQ to fire when one of the IRQ events occur. Threshold and - * duration will not be used uless the type is MOT or NMOT. - * - * @param config configuration to apply to, suspend or resume - * @param irq_type The type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - */ -static int lis331dlh_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis331dlh_config *config, - int apply, long irq_type) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - - config->irq_type = (unsigned char)irq_type; - if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x02; - reg2 = 0x00; - } else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x00; - reg2 = config->mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG3, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_CFG, reg2); - } - - return result; -} - -/** - * Set the Output data rate for the particular configuration - * - * @param config Config to modify with new ODR - * @param odr Output data rate in units of 1/1000Hz - */ -static int lis331dlh_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis331dlh_config *config, - int apply, long odr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - /* normal power modes */ - if (odr > 400000) { - config->odr = 1000000; - bits = LIS331DLH_PWR_MODE_NORMAL | 0x18; - } else if (odr > 100000) { - config->odr = 400000; - bits = LIS331DLH_PWR_MODE_NORMAL | 0x10; - } else if (odr > 50000) { - config->odr = 100000; - bits = LIS331DLH_PWR_MODE_NORMAL | 0x08; - } else if (odr > 10000) { - config->odr = 50000; - bits = LIS331DLH_PWR_MODE_NORMAL | 0x00; - /* low power modes */ - } else if (odr > 5000) { - config->odr = 10000; - bits = 0xC0; - } else if (odr > 2000) { - config->odr = 5000; - bits = 0xA0; - } else if (odr > 1000) { - config->odr = 2000; - bits = 0x80; - } else if (odr > 500) { - config->odr = 1000; - bits = 0x60; - } else if (odr > 0) { - config->odr = 500; - bits = 0x40; - } else { - config->odr = 0; - bits = 0; - } - - config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0x7); - lis331dlh_set_dur(mlsl_handle, pdata, config, apply, config->dur); - MPL_LOGV("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG1, - config->ctrl_reg1); - return result; -} - -/** - * Set the full scale range of the accels - * - * @param config pointer to configuration - * @param fsr requested full scale range - */ -static int lis331dlh_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis331dlh_config *config, - int apply, long fsr) -{ - unsigned char reg1 = 0x40; - int result = INV_SUCCESS; - - if (fsr <= 2048) { - config->fsr = 2048; - } else if (fsr <= 4096) { - reg1 |= 0x30; - config->fsr = 4096; - } else { - reg1 |= 0x10; - config->fsr = 8192; - } - - lis331dlh_set_ths(mlsl_handle, pdata, config, apply, config->ths); - MPL_LOGV("FSR: %d\n", config->fsr); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG4, reg1); - - return result; -} - -static int lis331dlh_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - struct lis331dlh_private_data *private_data = - (struct lis331dlh_private_data *)(pdata->private_data); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG1, - private_data->suspend.ctrl_reg1); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG2, 0x0f); - reg1 = 0x40; - if (private_data->suspend.fsr == 8192) - reg1 |= 0x30; - else if (private_data->suspend.fsr == 4096) - reg1 |= 0x10; - /* else bits [4..5] are already zero */ - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG4, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_THS, - private_data->suspend.reg_ths); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_DURATION, - private_data->suspend.reg_dur); - - if (private_data->suspend.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x02; - reg2 = 0x00; - } else if (private_data->suspend.irq_type == - MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x00; - reg2 = private_data->suspend.mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG3, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_CFG, reg2); - result = inv_serial_read(mlsl_handle, pdata->address, - LIS331DLH_HP_FILTER_RESET, 1, ®1); - return result; -} - -static int lis331dlh_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - struct lis331dlh_private_data *private_data = - (struct lis331dlh_private_data *)(pdata->private_data); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG1, - private_data->resume.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(6); - - /* Full Scale */ - reg1 = 0x40; - if (private_data->resume.fsr == 8192) - reg1 |= 0x30; - else if (private_data->resume.fsr == 4096) - reg1 |= 0x10; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG4, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Configure high pass filter */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG2, 0x0F); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x02; - reg2 = 0x00; - } else if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x00; - reg2 = private_data->resume.mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_CTRL_REG3, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_THS, - private_data->resume.reg_ths); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_DURATION, - private_data->resume.reg_dur); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS331DLH_INT1_CFG, reg2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(mlsl_handle, pdata->address, - LIS331DLH_HP_FILTER_RESET, 1, ®1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int lis331dlh_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - result = inv_serial_read(mlsl_handle, pdata->address, - LIS331DLH_STATUS_REG, 1, data); - if (data[0] & 0x0F) { - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, - data); - return result; - } else - return INV_ERROR_ACCEL_DATA_NOT_READY; -} - -static int lis331dlh_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - struct lis331dlh_private_data *private_data; - long range; - private_data = (struct lis331dlh_private_data *) - kzalloc(sizeof(struct lis331dlh_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - private_data->resume.ctrl_reg1 = 0x37; - private_data->suspend.ctrl_reg1 = 0x47; - private_data->resume.mot_int1_cfg = 0x95; - private_data->suspend.mot_int1_cfg = 0x2a; - - lis331dlh_set_odr(mlsl_handle, pdata, &private_data->suspend, false, 0); - lis331dlh_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - - range = range_fixedpoint_to_long_mg(slave->range); - lis331dlh_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - lis331dlh_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - - lis331dlh_set_ths(mlsl_handle, pdata, &private_data->suspend, - false, 80); - lis331dlh_set_ths(mlsl_handle, pdata, &private_data->resume, false, 40); - - - lis331dlh_set_dur(mlsl_handle, pdata, &private_data->suspend, - false, 1000); - lis331dlh_set_dur(mlsl_handle, pdata, &private_data->resume, - false, 2540); - - lis331dlh_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - lis331dlh_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - return INV_SUCCESS; -} - -static int lis331dlh_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static int lis331dlh_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct lis331dlh_private_data *private_data = pdata->private_data; - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return lis331dlh_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return lis331dlh_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return lis331dlh_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return lis331dlh_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_THS: - return lis331dlh_set_ths(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_THS: - return lis331dlh_set_ths(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_DUR: - return lis331dlh_set_dur(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_DUR: - return lis331dlh_set_dur(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return lis331dlh_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return lis331dlh_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - default: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static int lis331dlh_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct lis331dlh_private_data *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: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static struct ext_slave_descr lis331dlh_descr = { - .init = lis331dlh_init, - .exit = lis331dlh_exit, - .suspend = lis331dlh_suspend, - .resume = lis331dlh_resume, - .read = lis331dlh_read, - .config = lis331dlh_config, - .get_config = lis331dlh_get_config, - .name = "lis331dlh", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_LIS331, - .read_reg = (0x28 | 0x80), /* 0x80 for burst reads */ - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {2, 480}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *lis331_get_slave_descr(void) -{ - return &lis331dlh_descr; -} - -/* -------------------------------------------------------------------------- */ -struct lis331_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int lis331_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct lis331_mod_private_data *private_data; - int result = 0; - - 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; - 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, - lis331_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 lis331_mod_remove(struct i2c_client *client) -{ - struct lis331_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, - lis331_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id lis331_mod_id[] = { - { "lis331", ACCEL_ID_LIS331 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, lis331_mod_id); - -static struct i2c_driver lis331_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = lis331_mod_probe, - .remove = lis331_mod_remove, - .id_table = lis331_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "lis331_mod", - }, - .address_list = normal_i2c, -}; - -static int __init lis331_mod_init(void) -{ - int res = i2c_add_driver(&lis331_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "lis331_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit lis331_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&lis331_mod_driver); -} - -module_init(lis331_mod_init); -module_exit(lis331_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate LIS331 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("lis331_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/lis3dh.c b/drivers/misc/inv_mpu/accel/lis3dh.c deleted file mode 100644 index 27206e4..0000000 --- a/drivers/misc/inv_mpu/accel/lis3dh.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - $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 lis3dh.c - * @brief Accelerometer setup and handling methods for ST LIS3DH. - */ - -/* -------------------------------------------------------------------------- */ - -#undef MPL_LOG_NDEBUG -#define MPL_LOG_NDEBUG 0 - -#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-acc" - -/* full scale setting - register & mask */ -#define LIS3DH_CTRL_REG1 (0x20) -#define LIS3DH_CTRL_REG2 (0x21) -#define LIS3DH_CTRL_REG3 (0x22) -#define LIS3DH_CTRL_REG4 (0x23) -#define LIS3DH_CTRL_REG5 (0x24) -#define LIS3DH_CTRL_REG6 (0x25) -#define LIS3DH_REFERENCE (0x26) -#define LIS3DH_STATUS_REG (0x27) -#define LIS3DH_OUT_X_L (0x28) -#define LIS3DH_OUT_X_H (0x29) -#define LIS3DH_OUT_Y_L (0x2a) -#define LIS3DH_OUT_Y_H (0x2b) -#define LIS3DH_OUT_Z_L (0x2c) -#define LIS3DH_OUT_Z_H (0x2d) - -#define LIS3DH_INT1_CFG (0x30) -#define LIS3DH_INT1_SRC (0x31) -#define LIS3DH_INT1_THS (0x32) -#define LIS3DH_INT1_DURATION (0x33) - -#define LIS3DH_MAX_DUR (0x7F) - -/* -------------------------------------------------------------------------- */ - -struct lis3dh_config { - unsigned long odr; - unsigned int fsr; /* full scale range mg */ - unsigned int ths; /* Motion no-motion thseshold mg */ - unsigned int dur; /* Motion no-motion duration ms */ - unsigned char reg_ths; - unsigned char reg_dur; - unsigned char ctrl_reg1; - unsigned char irq_type; - unsigned char mot_int1_cfg; -}; - -struct lis3dh_private_data { - struct lis3dh_config suspend; - struct lis3dh_config resume; -}; - -/* -------------------------------------------------------------------------- */ - -static int lis3dh_set_ths(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis3dh_config *config, int apply, long ths) -{ - int result = INV_SUCCESS; - if ((unsigned int)ths > 1000 * config->fsr) - ths = (long)1000 * config->fsr; - - if (ths < 0) - ths = 0; - - config->ths = ths; - config->reg_ths = (unsigned char)(long)((ths * 128L) / (config->fsr)); - MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_THS, - config->reg_ths); - return result; -} - -static int lis3dh_set_dur(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis3dh_config *config, int apply, long dur) -{ - int result = INV_SUCCESS; - long reg_dur = (dur * config->odr) / 1000000L; - config->dur = dur; - - if (reg_dur > LIS3DH_MAX_DUR) - reg_dur = LIS3DH_MAX_DUR; - - config->reg_dur = (unsigned char)reg_dur; - MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_DURATION, - (unsigned char)reg_dur); - return result; -} - -/** - * Sets the IRQ to fire when one of the IRQ events occur. Threshold and - * duration will not be used uless the type is MOT or NMOT. - * - * @param config configuration to apply to, suspend or resume - * @param irq_type The type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - */ -static int lis3dh_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis3dh_config *config, - int apply, long irq_type) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - - config->irq_type = (unsigned char)irq_type; - if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x10; - reg2 = 0x00; - } else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x40; - reg2 = config->mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG3, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_CFG, reg2); - } - - return result; -} - -/** - * Set the Output data rate for the particular configuration - * - * @param config Config to modify with new ODR - * @param odr Output data rate in units of 1/1000Hz - */ -static int lis3dh_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis3dh_config *config, int apply, long odr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - if (odr > 400000L) { - config->odr = 1250000L; - bits = 0x90; - } else if (odr > 200000L) { - config->odr = 400000L; - bits = 0x70; - } else if (odr > 100000L) { - config->odr = 200000L; - bits = 0x60; - } else if (odr > 50000) { - config->odr = 100000L; - bits = 0x50; - } else if (odr > 25000) { - config->odr = 50000; - bits = 0x40; - } else if (odr > 10000) { - config->odr = 25000; - bits = 0x30; - } else if (odr > 1000) { - config->odr = 10000; - bits = 0x20; - } else if (odr > 500) { - config->odr = 1000; - bits = 0x10; - } else { - config->odr = 0; - bits = 0; - } - - config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0xf); - lis3dh_set_dur(mlsl_handle, pdata, config, apply, config->dur); - MPL_LOGV("ODR: %ld, 0x%02x\n", config->odr, (int)config->ctrl_reg1); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG1, - config->ctrl_reg1); - return result; -} - -/** - * Set the full scale range of the accels - * - * @param config pointer to configuration - * @param fsr requested full scale range - */ -static int lis3dh_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lis3dh_config *config, int apply, long fsr) -{ - int result = INV_SUCCESS; - unsigned char reg1 = 0x48; - - if (fsr <= 2048) { - config->fsr = 2048; - } else if (fsr <= 4096) { - reg1 |= 0x10; - config->fsr = 4096; - } else if (fsr <= 8192) { - reg1 |= 0x20; - config->fsr = 8192; - } else { - reg1 |= 0x30; - config->fsr = 16348; - } - - lis3dh_set_ths(mlsl_handle, pdata, config, apply, config->ths); - MPL_LOGV("FSR: %d\n", config->fsr); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG4, reg1); - - return result; -} - -static int lis3dh_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - struct lis3dh_private_data *private_data = pdata->private_data; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG1, - private_data->suspend.ctrl_reg1); - - reg1 = 0x48; - if (private_data->suspend.fsr == 16384) - reg1 |= 0x30; - else if (private_data->suspend.fsr == 8192) - reg1 |= 0x20; - else if (private_data->suspend.fsr == 4096) - reg1 |= 0x10; - else if (private_data->suspend.fsr == 2048) - reg1 |= 0x00; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG4, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_THS, - private_data->suspend.reg_ths); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_DURATION, - private_data->suspend.reg_dur); - - if (private_data->suspend.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x10; - reg2 = 0x00; - } else if (private_data->suspend.irq_type == - MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x40; - reg2 = private_data->suspend.mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG3, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_CFG, reg2); - result = inv_serial_read(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG6, 1, ®1); - - return result; -} - -static int lis3dh_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char reg1; - unsigned char reg2; - struct lis3dh_private_data *private_data = pdata->private_data; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG1, - private_data->resume.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(6); - - /* Full Scale */ - reg1 = 0x48; - if (private_data->suspend.fsr == 16384) - reg1 |= 0x30; - else if (private_data->suspend.fsr == 8192) - reg1 |= 0x20; - else if (private_data->suspend.fsr == 4096) - reg1 |= 0x10; - else if (private_data->suspend.fsr == 2048) - reg1 |= 0x00; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG4, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x10; - reg2 = 0x00; - } else if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x40; - reg2 = private_data->resume.mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG3, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_THS, - private_data->resume.reg_ths); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_DURATION, - private_data->resume.reg_dur); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_INT1_CFG, reg2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG6, 1, ®1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int lis3dh_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - result = inv_serial_read(mlsl_handle, pdata->address, - LIS3DH_STATUS_REG, 1, data); - if (data[0] & 0x0F) { - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, - data); - return result; - } else - return INV_ERROR_ACCEL_DATA_NOT_READY; -} - -static int lis3dh_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - long range; - struct lis3dh_private_data *private_data; - private_data = (struct lis3dh_private_data *) - kzalloc(sizeof(struct lis3dh_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - private_data->resume.ctrl_reg1 = 0x67; - private_data->suspend.ctrl_reg1 = 0x18; - private_data->resume.mot_int1_cfg = 0x95; - private_data->suspend.mot_int1_cfg = 0x2a; - - lis3dh_set_odr(mlsl_handle, pdata, &private_data->suspend, false, 0); - lis3dh_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000L); - - range = range_fixedpoint_to_long_mg(slave->range); - lis3dh_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - lis3dh_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - - lis3dh_set_ths(mlsl_handle, pdata, &private_data->suspend, - false, 80); - lis3dh_set_ths(mlsl_handle, pdata, &private_data->resume, - false, 40); - - lis3dh_set_dur(mlsl_handle, pdata, &private_data->suspend, - false, 1000); - lis3dh_set_dur(mlsl_handle, pdata, &private_data->resume, - false, 2540); - - lis3dh_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - lis3dh_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LIS3DH_CTRL_REG1, 0x07); - msleep(6); - - return INV_SUCCESS; -} - -static int lis3dh_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static int lis3dh_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct lis3dh_private_data *private_data = pdata->private_data; - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return lis3dh_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return lis3dh_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return lis3dh_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return lis3dh_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_THS: - return lis3dh_set_ths(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_THS: - return lis3dh_set_ths(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_DUR: - return lis3dh_set_dur(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_DUR: - return lis3dh_set_dur(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return lis3dh_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return lis3dh_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, *((long *)data->data)); - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - return INV_SUCCESS; -} - -static int lis3dh_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct lis3dh_private_data *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 INV_SUCCESS; -} - -static struct ext_slave_descr lis3dh_descr = { - .init = lis3dh_init, - .exit = lis3dh_exit, - .suspend = lis3dh_suspend, - .resume = lis3dh_resume, - .read = lis3dh_read, - .config = lis3dh_config, - .get_config = lis3dh_get_config, - .name = "lis3dh", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_LIS3DH, - .read_reg = 0x28 | 0x80, /* 0x80 for burst reads */ - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {2, 480}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *lis3dh_get_slave_descr(void) -{ - return &lis3dh_descr; -} - -/* -------------------------------------------------------------------------- */ -struct lis3dh_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int lis3dh_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct lis3dh_mod_private_data *private_data; - int result = 0; - - 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; - 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, - lis3dh_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 lis3dh_mod_remove(struct i2c_client *client) -{ - struct lis3dh_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, - lis3dh_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id lis3dh_mod_id[] = { - { "lis3dh", ACCEL_ID_LIS3DH }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, lis3dh_mod_id); - -static struct i2c_driver lis3dh_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = lis3dh_mod_probe, - .remove = lis3dh_mod_remove, - .id_table = lis3dh_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "lis3dh_mod", - }, - .address_list = normal_i2c, -}; - -static int __init lis3dh_mod_init(void) -{ - int res = i2c_add_driver(&lis3dh_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "lis3dh_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit lis3dh_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&lis3dh_mod_driver); -} - -module_init(lis3dh_mod_init); -module_exit(lis3dh_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate LIS3DH sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("lis3dh_mod"); - -/* - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/lsm303dlx_a.c b/drivers/misc/inv_mpu/accel/lsm303dlx_a.c deleted file mode 100644 index 576282a..0000000 --- a/drivers/misc/inv_mpu/accel/lsm303dlx_a.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - $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 lsm303dlx_a.c - * @brief Accelerometer setup and handling methods for ST LSM303DLH - * or LSM303DLM accel. - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -/* -------------------------------------------------------------------------- */ - -/* full scale setting - register & mask */ -#define LSM303DLx_CTRL_REG1 (0x20) -#define LSM303DLx_CTRL_REG2 (0x21) -#define LSM303DLx_CTRL_REG3 (0x22) -#define LSM303DLx_CTRL_REG4 (0x23) -#define LSM303DLx_CTRL_REG5 (0x24) -#define LSM303DLx_HP_FILTER_RESET (0x25) -#define LSM303DLx_REFERENCE (0x26) -#define LSM303DLx_STATUS_REG (0x27) -#define LSM303DLx_OUT_X_L (0x28) -#define LSM303DLx_OUT_X_H (0x29) -#define LSM303DLx_OUT_Y_L (0x2a) -#define LSM303DLx_OUT_Y_H (0x2b) -#define LSM303DLx_OUT_Z_L (0x2b) -#define LSM303DLx_OUT_Z_H (0x2d) - -#define LSM303DLx_INT1_CFG (0x30) -#define LSM303DLx_INT1_SRC (0x31) -#define LSM303DLx_INT1_THS (0x32) -#define LSM303DLx_INT1_DURATION (0x33) - -#define LSM303DLx_INT2_CFG (0x34) -#define LSM303DLx_INT2_SRC (0x35) -#define LSM303DLx_INT2_THS (0x36) -#define LSM303DLx_INT2_DURATION (0x37) - -#define LSM303DLx_CTRL_MASK (0x30) -#define LSM303DLx_SLEEP_MASK (0x20) -#define LSM303DLx_PWR_MODE_NORMAL (0x20) - -#define LSM303DLx_MAX_DUR (0x7F) - -/* -------------------------------------------------------------------------- */ - -struct lsm303dlx_a_config { - unsigned int odr; - unsigned int fsr; /** < full scale range mg */ - unsigned int ths; /** < Motion no-motion thseshold mg */ - unsigned int dur; /** < Motion no-motion duration ms */ - unsigned char reg_ths; - unsigned char reg_dur; - unsigned char ctrl_reg1; - unsigned char irq_type; - unsigned char mot_int1_cfg; -}; - -struct lsm303dlx_a_private_data { - struct lsm303dlx_a_config suspend; - struct lsm303dlx_a_config resume; -}; - -/* -------------------------------------------------------------------------- */ - -static int lsm303dlx_a_set_ths(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lsm303dlx_a_config *config, - int apply, - long ths) -{ - int result = INV_SUCCESS; - if ((unsigned int) ths >= config->fsr) - ths = (long) config->fsr - 1; - - if (ths < 0) - ths = 0; - - config->ths = ths; - config->reg_ths = (unsigned char)(long)((ths * 128L) / (config->fsr)); - MPL_LOGV("THS: %d, 0x%02x\n", config->ths, (int)config->reg_ths); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_THS, - config->reg_ths); - return result; -} - -static int lsm303dlx_a_set_dur(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lsm303dlx_a_config *config, - int apply, - long dur) -{ - int result = INV_SUCCESS; - long reg_dur = (dur * config->odr) / 1000000L; - config->dur = dur; - - if (reg_dur > LSM303DLx_MAX_DUR) - reg_dur = LSM303DLx_MAX_DUR; - - config->reg_dur = (unsigned char) reg_dur; - MPL_LOGV("DUR: %d, 0x%02x\n", config->dur, (int)config->reg_dur); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_DURATION, - (unsigned char)reg_dur); - return result; -} - -/** - * Sets the IRQ to fire when one of the IRQ events occur. Threshold and - * duration will not be used uless the type is MOT or NMOT. - * - * @param config configuration to apply to, suspend or resume - * @param irq_type The type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - */ -static int lsm303dlx_a_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lsm303dlx_a_config *config, - int apply, - long irq_type) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - - config->irq_type = (unsigned char)irq_type; - if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x02; - reg2 = 0x00; - } else if (irq_type == MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x00; - reg2 = config->mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG3, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_CFG, reg2); - } - - return result; -} - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lsm303dlx_a_config *config, - int apply, - long odr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - /* normal power modes */ - if (odr > 400000) { - config->odr = 1000000; - bits = LSM303DLx_PWR_MODE_NORMAL | 0x18; - } else if (odr > 100000) { - config->odr = 400000; - bits = LSM303DLx_PWR_MODE_NORMAL | 0x10; - } else if (odr > 50000) { - config->odr = 100000; - bits = LSM303DLx_PWR_MODE_NORMAL | 0x08; - } else if (odr > 10000) { - config->odr = 50000; - bits = LSM303DLx_PWR_MODE_NORMAL | 0x00; - /* low power modes */ - } else if (odr > 5000) { - config->odr = 10000; - bits = 0xC0; - } else if (odr > 2000) { - config->odr = 5000; - bits = 0xA0; - } else if (odr > 1000) { - config->odr = 2000; - bits = 0x80; - } else if (odr > 500) { - config->odr = 1000; - bits = 0x60; - } else if (odr > 0) { - config->odr = 500; - bits = 0x40; - } else { - config->odr = 0; - bits = 0; - } - - config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0x7); - lsm303dlx_a_set_dur(mlsl_handle, pdata, config, apply, config->dur); - MPL_LOGV("ODR: %d, 0x%02x\n", config->odr, (int)config->ctrl_reg1); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG1, - config->ctrl_reg1); - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct lsm303dlx_a_config *config, - int apply, - long fsr) -{ - unsigned char reg1 = 0x40; - int result = INV_SUCCESS; - - if (fsr <= 2048) { - config->fsr = 2048; - } else if (fsr <= 4096) { - reg1 |= 0x30; - config->fsr = 4096; - } else { - reg1 |= 0x10; - config->fsr = 8192; - } - - lsm303dlx_a_set_ths(mlsl_handle, pdata, - config, apply, config->ths); - MPL_LOGV("FSR: %d\n", config->fsr); - if (apply) - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG4, reg1); - - return result; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - struct lsm303dlx_a_private_data *private_data = - (struct lsm303dlx_a_private_data *)(pdata->private_data); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG1, - private_data->suspend.ctrl_reg1); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG2, 0x0f); - reg1 = 0x40; - if (private_data->suspend.fsr == 8192) - reg1 |= 0x30; - else if (private_data->suspend.fsr == 4096) - reg1 |= 0x10; - /* else bits [4..5] are already zero */ - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG4, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_THS, - private_data->suspend.reg_ths); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_DURATION, - private_data->suspend.reg_dur); - - if (private_data->suspend.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x02; - reg2 = 0x00; - } else if (private_data->suspend.irq_type == - MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x00; - reg2 = private_data->suspend.mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG3, reg1); - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_CFG, reg2); - result = inv_serial_read(mlsl_handle, pdata->address, - LSM303DLx_HP_FILTER_RESET, 1, ®1); - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - struct lsm303dlx_a_private_data *private_data = - (struct lsm303dlx_a_private_data *)(pdata->private_data); - - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG1, - private_data->resume.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(6); - - /* Full Scale */ - reg1 = 0x40; - if (private_data->resume.fsr == 8192) - reg1 |= 0x30; - else if (private_data->resume.fsr == 4096) - reg1 |= 0x10; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG4, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Configure high pass filter */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG2, 0x0F); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (private_data->resume.irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x02; - reg2 = 0x00; - } else if (private_data->resume.irq_type == - MPU_SLAVE_IRQ_TYPE_MOTION) { - reg1 = 0x00; - reg2 = private_data->resume.mot_int1_cfg; - } else { - reg1 = 0x00; - reg2 = 0x00; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_CTRL_REG3, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_THS, - private_data->resume.reg_ths); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_DURATION, - private_data->resume.reg_dur); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - LSM303DLx_INT1_CFG, reg2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(mlsl_handle, pdata->address, - LSM303DLx_HP_FILTER_RESET, 1, ®1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - result = inv_serial_read(mlsl_handle, pdata->address, - LSM303DLx_STATUS_REG, 1, data); - if (data[0] & 0x0F) { - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, data); - return result; - } else - return INV_ERROR_ACCEL_DATA_NOT_READY; -} - -/** - * @brief one-time device driver initialization function. - * If the driver is built as a kernel module, this function will be - * called when the module is loaded in the kernel. - * If the driver is built-in in the kernel, this function will be - * called at boot time. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - long range; - struct lsm303dlx_a_private_data *private_data; - private_data = (struct lsm303dlx_a_private_data *) - kzalloc(sizeof(struct lsm303dlx_a_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - private_data->resume.ctrl_reg1 = 0x37; - private_data->suspend.ctrl_reg1 = 0x47; - private_data->resume.mot_int1_cfg = 0x95; - private_data->suspend.mot_int1_cfg = 0x2a; - - lsm303dlx_a_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - lsm303dlx_a_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - - range = range_fixedpoint_to_long_mg(slave->range); - lsm303dlx_a_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - lsm303dlx_a_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - - lsm303dlx_a_set_ths(mlsl_handle, pdata, &private_data->suspend, - false, 80); - lsm303dlx_a_set_ths(mlsl_handle, pdata, &private_data->resume, - false, 40); - - lsm303dlx_a_set_dur(mlsl_handle, pdata, &private_data->suspend, - false, 1000); - lsm303dlx_a_set_dur(mlsl_handle, pdata, &private_data->resume, - false, 2540); - - lsm303dlx_a_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - lsm303dlx_a_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - return INV_SUCCESS; -} - -/** - * @brief one-time device driver exit function. - * If the driver is built as a kernel module, this function will be - * called when the module is removed from the kernel. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -/** - * @brief device configuration facility. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to the configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct lsm303dlx_a_private_data *private_data = pdata->private_data; - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return lsm303dlx_a_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return lsm303dlx_a_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return lsm303dlx_a_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return lsm303dlx_a_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_THS: - return lsm303dlx_a_set_ths(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_THS: - return lsm303dlx_a_set_ths(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_DUR: - return lsm303dlx_a_set_dur(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_DUR: - return lsm303dlx_a_set_dur(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return lsm303dlx_a_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return lsm303dlx_a_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - default: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -/** - * @brief facility to retrieve the device configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to store the returned configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int lsm303dlx_a_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct lsm303dlx_a_private_data *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: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static struct ext_slave_descr lsm303dlx_a_descr = { - .init = lsm303dlx_a_init, - .exit = lsm303dlx_a_exit, - .suspend = lsm303dlx_a_suspend, - .resume = lsm303dlx_a_resume, - .read = lsm303dlx_a_read, - .config = lsm303dlx_a_config, - .get_config = lsm303dlx_a_get_config, - .name = "lsm303dlx_a", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_LSM303DLX, - .read_reg = (0x28 | 0x80), /* 0x80 for burst reads */ - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {2, 480}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *lsm303dlx_a_get_slave_descr(void) -{ - return &lsm303dlx_a_descr; -} - -/* -------------------------------------------------------------------------- */ -struct lsm303dlx_a_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int lsm303dlx_a_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct lsm303dlx_a_mod_private_data *private_data; - int result = 0; - - 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; - 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, - lsm303dlx_a_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 lsm303dlx_a_mod_remove(struct i2c_client *client) -{ - struct lsm303dlx_a_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, - lsm303dlx_a_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id lsm303dlx_a_mod_id[] = { - { "lsm303dlx", ACCEL_ID_LSM303DLX }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, lsm303dlx_a_mod_id); - -static struct i2c_driver lsm303dlx_a_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = lsm303dlx_a_mod_probe, - .remove = lsm303dlx_a_mod_remove, - .id_table = lsm303dlx_a_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "lsm303dlx_a_mod", - }, - .address_list = normal_i2c, -}; - -static int __init lsm303dlx_a_mod_init(void) -{ - int res = i2c_add_driver(&lsm303dlx_a_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "lsm303dlx_a_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit lsm303dlx_a_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&lsm303dlx_a_mod_driver); -} - -module_init(lsm303dlx_a_mod_init); -module_exit(lsm303dlx_a_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate LSM303DLX_A sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("lsm303dlx_a_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/mma8450.c b/drivers/misc/inv_mpu/accel/mma8450.c deleted file mode 100644 index f698ee9..0000000 --- a/drivers/misc/inv_mpu/accel/mma8450.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - $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 mma8450.c - * @brief Accelerometer setup and handling methods for Freescale MMA8450. - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -/* full scale setting - register & mask */ -#define ACCEL_MMA8450_XYZ_DATA_CFG (0x16) - -#define ACCEL_MMA8450_CTRL_REG1 (0x38) -#define ACCEL_MMA8450_CTRL_REG2 (0x39) -#define ACCEL_MMA8450_CTRL_REG4 (0x3B) -#define ACCEL_MMA8450_CTRL_REG5 (0x3C) - -#define ACCEL_MMA8450_CTRL_REG (0x38) -#define ACCEL_MMA8450_CTRL_MASK (0x03) - -#define ACCEL_MMA8450_SLEEP_MASK (0x03) - -/* -------------------------------------------------------------------------- */ - -struct mma8450_config { - unsigned int odr; - unsigned int fsr; /** < full scale range mg */ - unsigned int ths; /** < Motion no-motion thseshold mg */ - unsigned int dur; /** < Motion no-motion duration ms */ - unsigned char reg_ths; - unsigned char reg_dur; - unsigned char ctrl_reg1; - unsigned char irq_type; - unsigned char mot_int1_cfg; -}; - -struct mma8450_private_data { - struct mma8450_config suspend; - struct mma8450_config resume; -}; - - -/* -------------------------------------------------------------------------- */ - -static int mma8450_set_ths(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma8450_config *config, - int apply, - long ths) -{ - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; -} - -static int mma8450_set_dur(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma8450_config *config, - int apply, - long dur) -{ - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; -} - -/** - * @brief Sets the IRQ to fire when one of the IRQ events occur. - * Threshold and duration will not be used unless the type is MOT or - * NMOT. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * configuration to apply to, suspend or resume - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param irq_type - * the type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma8450_config *config, - int apply, - long irq_type) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - unsigned char reg3; - - config->irq_type = (unsigned char)irq_type; - if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x01; - reg2 = 0x01; - reg3 = 0x07; - } else if (irq_type == MPU_SLAVE_IRQ_TYPE_NONE) { - reg1 = 0x00; - reg2 = 0x00; - reg3 = 0x00; - } else { - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - } - - if (apply) { - /* XYZ_DATA_CFG: event flag enabled on Z axis */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_XYZ_DATA_CFG, reg3); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG4, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG5, reg2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - return result; -} - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma8450_config *config, - int apply, - long odr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - if (odr > 200000) { - config->odr = 400000; - bits = 0x00; - } else if (odr > 100000) { - config->odr = 200000; - bits = 0x04; - } else if (odr > 50000) { - config->odr = 100000; - bits = 0x08; - } else if (odr > 25000) { - config->odr = 50000; - bits = 0x0C; - } else if (odr > 12500) { - config->odr = 25000; - bits = 0x40; /* Sleep -> Auto wake mode */ - } else if (odr > 1563) { - config->odr = 12500; - bits = 0x10; - } else if (odr > 0) { - config->odr = 1563; - bits = 0x14; - } else { - config->ctrl_reg1 = 0; /* Set FS1.FS2 to Standby */ - config->odr = 0; - bits = 0; - } - - config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0x3); - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, config->ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGV("ODR: %d mHz, 0x%02x\n", - config->odr, (int)config->ctrl_reg1); - } - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma8450_config *config, - int apply, - long fsr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - if (fsr <= 2000) { - bits = 0x01; - config->fsr = 2000; - } else if (fsr <= 4000) { - bits = 0x02; - config->fsr = 4000; - } else { - bits = 0x03; - config->fsr = 8000; - } - - config->ctrl_reg1 = bits | (config->ctrl_reg1 & 0xFC); - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, config->ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGV("FSR: %d mg\n", config->fsr); - } - return result; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - struct mma8450_private_data *private_data = pdata->private_data; - - if (private_data->suspend.fsr == 4000) - slave->range.mantissa = 4; - else if (private_data->suspend.fsr == 8000) - slave->range.mantissa = 8; - else - slave->range.mantissa = 2; - slave->range.fraction = 0; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (private_data->suspend.ctrl_reg1) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, - private_data->suspend.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - result = mma8450_set_irq(mlsl_handle, pdata, - &private_data->suspend, - true, private_data->suspend.irq_type); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - struct mma8450_private_data *private_data = pdata->private_data; - - /* Full Scale */ - if (private_data->resume.fsr == 4000) - slave->range.mantissa = 4; - else if (private_data->resume.fsr == 8000) - slave->range.mantissa = 8; - else - slave->range.mantissa = 2; - slave->range.fraction = 0; - - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (private_data->resume.ctrl_reg1) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA8450_CTRL_REG1, - private_data->resume.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - result = mma8450_set_irq(mlsl_handle, pdata, - &private_data->resume, - true, private_data->resume.irq_type); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, unsigned char *data) -{ - int result; - unsigned char local_data[4]; /* Status register + 3 bytes data */ - result = inv_serial_read(mlsl_handle, pdata->address, - 0x00, sizeof(local_data), local_data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - memcpy(data, &local_data[1], (slave->read_len) - 1); - - MPL_LOGV("Data Not Ready: %02x %02x %02x %02x\n", - local_data[0], local_data[1], - local_data[2], local_data[3]); - - return result; -} - -/** - * @brief one-time device driver initialization function. - * If the driver is built as a kernel module, this function will be - * called when the module is loaded in the kernel. - * If the driver is built-in in the kernel, this function will be - * called at boot time. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - struct mma8450_private_data *private_data; - private_data = (struct mma8450_private_data *) - kzalloc(sizeof(struct mma8450_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - mma8450_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - mma8450_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - mma8450_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, 2000); - mma8450_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, 2000); - mma8450_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, - MPU_SLAVE_IRQ_TYPE_NONE); - mma8450_set_irq(mlsl_handle, pdata, &private_data->resume, - false, - MPU_SLAVE_IRQ_TYPE_NONE); - return INV_SUCCESS; -} - -/** - * @brief one-time device driver exit function. - * If the driver is built as a kernel module, this function will be - * called when the module is removed from the kernel. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -/** - * @brief device configuration facility. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to the configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct mma8450_private_data *private_data = pdata->private_data; - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return mma8450_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return mma8450_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return mma8450_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return mma8450_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_THS: - return mma8450_set_ths(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_THS: - return mma8450_set_ths(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_DUR: - return mma8450_set_dur(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_DUR: - return mma8450_set_dur(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return mma8450_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return mma8450_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - default: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -/** - * @brief facility to retrieve the device configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a pointer to store the returned configuration data structure. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma8450_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct mma8450_private_data *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: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static struct ext_slave_descr mma8450_descr = { - .init = mma8450_init, - .exit = mma8450_exit, - .suspend = mma8450_suspend, - .resume = mma8450_resume, - .read = mma8450_read, - .config = mma8450_config, - .get_config = mma8450_get_config, - .name = "mma8450", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_MMA8450, - .read_reg = 0x00, - .read_len = 4, - .endian = EXT_SLAVE_FS8_BIG_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *mma8450_get_slave_descr(void) -{ - return &mma8450_descr; -} - -/* -------------------------------------------------------------------------- */ -struct mma8450_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int mma8450_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct mma8450_mod_private_data *private_data; - int result = 0; - - 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; - 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, - mma8450_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 mma8450_mod_remove(struct i2c_client *client) -{ - struct mma8450_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, - mma8450_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id mma8450_mod_id[] = { - { "mma8450", ACCEL_ID_MMA8450 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, mma8450_mod_id); - -static struct i2c_driver mma8450_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = mma8450_mod_probe, - .remove = mma8450_mod_remove, - .id_table = mma8450_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "mma8450_mod", - }, - .address_list = normal_i2c, -}; - -static int __init mma8450_mod_init(void) -{ - int res = i2c_add_driver(&mma8450_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "mma8450_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit mma8450_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&mma8450_mod_driver); -} - -module_init(mma8450_mod_init); -module_exit(mma8450_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate MMA8450 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("mma8450_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/mma845x.c b/drivers/misc/inv_mpu/accel/mma845x.c deleted file mode 100644 index 5f62b22..0000000 --- a/drivers/misc/inv_mpu/accel/mma845x.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - $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 mma845x.c - * @brief Accelerometer setup and handling methods for Freescale MMA845X - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -#define ACCEL_MMA845X_XYZ_DATA_CFG (0x0E) -#define ACCEL_MMA845X_CTRL_REG1 (0x2A) -#define ACCEL_MMA845X_CTRL_REG4 (0x2D) -#define ACCEL_MMA845X_CTRL_REG5 (0x2E) - -#define ACCEL_MMA845X_SLEEP_MASK (0x01) - -/* full scale setting - register & mask */ -#define ACCEL_MMA845X_CFG_REG (0x0E) -#define ACCEL_MMA845X_CTRL_MASK (0x03) - -/* -------------------------------------------------------------------------- */ - -struct mma845x_config { - unsigned int odr; - unsigned int fsr; /** < full scale range mg */ - unsigned int ths; /** < Motion no-motion thseshold mg */ - unsigned int dur; /** < Motion no-motion duration ms */ - unsigned char reg_ths; - unsigned char reg_dur; - unsigned char ctrl_reg1; - unsigned char irq_type; - unsigned char mot_int1_cfg; -}; - -struct mma845x_private_data { - struct mma845x_config suspend; - struct mma845x_config resume; -}; - -/* -------------------------------------------------------------------------- */ - -static int mma845x_set_ths(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma845x_config *config, - int apply, - long ths) -{ - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; -} - -static int mma845x_set_dur(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma845x_config *config, - int apply, - long dur) -{ - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; -} - -/** - * @brief Sets the IRQ to fire when one of the IRQ events occur. - * Threshold and duration will not be used unless the type is MOT or - * NMOT. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * configuration to apply to, suspend or resume - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param irq_type - * the type of IRQ. Valid values are - * - MPU_SLAVE_IRQ_TYPE_NONE - * - MPU_SLAVE_IRQ_TYPE_MOTION - * - MPU_SLAVE_IRQ_TYPE_DATA_READY - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma845x_set_irq(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma845x_config *config, - int apply, - long irq_type) -{ - int result = INV_SUCCESS; - unsigned char reg1; - unsigned char reg2; - - config->irq_type = (unsigned char)irq_type; - if (irq_type == MPU_SLAVE_IRQ_TYPE_DATA_READY) { - reg1 = 0x01; - reg2 = 0x01; - } else if (irq_type == MPU_SLAVE_IRQ_TYPE_NONE) { - reg1 = 0x00; - reg2 = 0x00; - } else { - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - } - - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA845X_CTRL_REG4, reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA845X_CTRL_REG5, reg2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - return result; -} - -/** - * @brief Set the output data rate for the particular configuration. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * Config to modify with new ODR. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param odr - * Output data rate in units of 1/1000Hz (mHz). - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma845x_set_odr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma845x_config *config, - int apply, - long odr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - if (odr > 400000) { - config->odr = 800000; - bits = 0x01; - } else if (odr > 200000) { - config->odr = 400000; - bits = 0x09; - } else if (odr > 100000) { - config->odr = 200000; - bits = 0x11; - } else if (odr > 50000) { - config->odr = 100000; - bits = 0x19; - } else if (odr > 12500) { - config->odr = 50000; - bits = 0x21; - } else if (odr > 6250) { - config->odr = 12500; - bits = 0x29; - } else if (odr > 1560) { - config->odr = 6250; - bits = 0x31; - } else if (odr > 0) { - config->odr = 1560; - bits = 0x39; - } else { - config->ctrl_reg1 = 0; /* Set FS1.FS2 to Standby */ - config->odr = 0; - bits = 0; - } - - config->ctrl_reg1 = bits; - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA845X_CTRL_REG1, - config->ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGV("ODR: %d mHz, 0x%02x\n", config->odr, - (int)config->ctrl_reg1); - } - return result; -} - -/** - * @brief Set the full scale range of the accels - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param pdata - * a pointer to the slave platform data. - * @param config - * pointer to configuration. - * @param apply - * whether to apply immediately or save the settings to be applied - * at the next resume. - * @param fsr - * requested full scale range. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma845x_set_fsr(void *mlsl_handle, - struct ext_slave_platform_data *pdata, - struct mma845x_config *config, - int apply, - long fsr) -{ - unsigned char bits; - int result = INV_SUCCESS; - - if (fsr <= 2000) { - bits = 0x00; - config->fsr = 2000; - } else if (fsr <= 4000) { - bits = 0x01; - config->fsr = 4000; - } else { - bits = 0x02; - config->fsr = 8000; - } - - if (apply) { - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA845X_XYZ_DATA_CFG, - bits); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGV("FSR: %d mg\n", config->fsr); - } - return result; -} - -/** - * @brief suspends the device to put it in its lowest power mode. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma845x_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - struct mma845x_private_data *private_data = pdata->private_data; - - /* Full Scale */ - if (private_data->suspend.fsr == 4000) - slave->range.mantissa = 4; - else if (private_data->suspend.fsr == 8000) - slave->range.mantissa = 8; - else - slave->range.mantissa = 2; - - slave->range.fraction = 0; - - result = mma845x_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - true, private_data->suspend.fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA845X_CTRL_REG1, - private_data->suspend.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief resume the device in the proper power state given the configuration - * chosen. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma845x_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - struct mma845x_private_data *private_data = pdata->private_data; - - /* Full Scale */ - if (private_data->resume.fsr == 4000) - slave->range.mantissa = 4; - else if (private_data->resume.fsr == 8000) - slave->range.mantissa = 8; - else - slave->range.mantissa = 2; - - slave->range.fraction = 0; - - result = mma845x_set_fsr(mlsl_handle, pdata, - &private_data->resume, - true, private_data->resume.fsr); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(mlsl_handle, pdata->address, - ACCEL_MMA845X_CTRL_REG1, - private_data->resume.ctrl_reg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -/** - * @brief read the sensor data from the device. - * - * @param mlsl_handle - * the handle to the serial channel the device is connected to. - * @param slave - * a pointer to the slave descriptor data structure. - * @param pdata - * a pointer to the slave platform data. - * @param data - * a buffer to store the data read. - * - * @return INV_SUCCESS if successful or a non-zero error code. - */ -static int mma845x_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, unsigned char *data) -{ - int result; - unsigned char local_data[7]; /* Status register + 6 bytes data */ - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, sizeof(local_data), - local_data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - memcpy(data, &local_data[1], slave->read_len); - return result; -} - -static int mma845x_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - long range; - struct mma845x_private_data *private_data; - private_data = (struct mma845x_private_data *) - kzalloc(sizeof(struct mma845x_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - pdata->private_data = private_data; - - mma845x_set_odr(mlsl_handle, pdata, &private_data->suspend, - false, 0); - mma845x_set_odr(mlsl_handle, pdata, &private_data->resume, - false, 200000); - - range = range_fixedpoint_to_long_mg(slave->range); - mma845x_set_fsr(mlsl_handle, pdata, &private_data->suspend, - false, range); - mma845x_set_fsr(mlsl_handle, pdata, &private_data->resume, - false, range); - - mma845x_set_irq(mlsl_handle, pdata, &private_data->suspend, - false, MPU_SLAVE_IRQ_TYPE_NONE); - mma845x_set_irq(mlsl_handle, pdata, &private_data->resume, - false, MPU_SLAVE_IRQ_TYPE_NONE); - return INV_SUCCESS; -} - -static int mma845x_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static int mma845x_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct mma845x_private_data *private_data = pdata->private_data; - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_CONFIG_ODR_SUSPEND: - return mma845x_set_odr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_ODR_RESUME: - return mma845x_set_odr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_SUSPEND: - return mma845x_set_fsr(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_FSR_RESUME: - return mma845x_set_fsr(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_THS: - return mma845x_set_ths(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_THS: - return mma845x_set_ths(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_MOT_DUR: - return mma845x_set_dur(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_NMOT_DUR: - return mma845x_set_dur(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_SUSPEND: - return mma845x_set_irq(mlsl_handle, pdata, - &private_data->suspend, - data->apply, - *((long *)data->data)); - case MPU_SLAVE_CONFIG_IRQ_RESUME: - return mma845x_set_irq(mlsl_handle, pdata, - &private_data->resume, - data->apply, - *((long *)data->data)); - default: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static int mma845x_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct mma845x_private_data *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: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - -static struct ext_slave_descr mma845x_descr = { - .init = mma845x_init, - .exit = mma845x_exit, - .suspend = mma845x_suspend, - .resume = mma845x_resume, - .read = mma845x_read, - .config = mma845x_config, - .get_config = mma845x_get_config, - .name = "mma845x", - .type = EXT_SLAVE_TYPE_ACCEL, - .id = ACCEL_ID_MMA845X, - .read_reg = 0x00, - .read_len = 6, - .endian = EXT_SLAVE_FS16_BIG_ENDIAN, - .range = {2, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *mma845x_get_slave_descr(void) -{ - return &mma845x_descr; -} - -/* -------------------------------------------------------------------------- */ -struct mma845x_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int mma845x_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct mma845x_mod_private_data *private_data; - int result = 0; - - 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; - 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, - mma845x_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 mma845x_mod_remove(struct i2c_client *client) -{ - struct mma845x_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, - mma845x_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id mma845x_mod_id[] = { - { "mma845x", ACCEL_ID_MMA845X }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, mma845x_mod_id); - -static struct i2c_driver mma845x_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = mma845x_mod_probe, - .remove = mma845x_mod_remove, - .id_table = mma845x_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "mma845x_mod", - }, - .address_list = normal_i2c, -}; - -static int __init mma845x_mod_init(void) -{ - int res = i2c_add_driver(&mma845x_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "mma845x_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit mma845x_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&mma845x_mod_driver); -} - -module_init(mma845x_mod_init); -module_exit(mma845x_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate MMA845X sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("mma845x_mod"); - - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/mpu6050.c b/drivers/misc/inv_mpu/accel/mpu6050.c deleted file mode 100644 index 114164e..0000000 --- a/drivers/misc/inv_mpu/accel/mpu6050.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - $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_411.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; - - return 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); - } - - 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(20); - - 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; - int x, y, z; - - result = inv_serial_read(mlsl_handle, pdata->address, - slave->read_reg, slave->read_len, data); -#if 1 - if (slave->read_len == 6) { - /* - pr_info("\n mantis_read cal x: %d y: %d z: %d\", - cal_data.x, cal_data.y, cal_data.z); - - x = (s16)((data[0] <<8) |data[1]); - y = (s16)((data[2] <<8) |data[3]); - z = (s16)((data[4] <<8) |data[5]); - - pr_info("mantis_read RAW x: %d y: %d z: %d", x, y, z); - */ - x = (s16)((data[0] << 8) | data[1]) - cal_data.x; - y = (s16)((data[2] << 8) | data[3]) - cal_data.y; - z = (s16)((data[4] << 8) | data[5]) - cal_data.z; - - /* - pr_info("mantis_read CAL x: %d y: %d z: %d", x, y, z); - */ - - data[0] = (x & 0xff00) >> 8; - data[1] = ((x << 4) >> 4) & 0xff; - data[2] = (y & 0xff00) >> 8; - data[3] = ((y << 4) >> 4) & 0xff; - data[4] = (z & 0xff00) >> 8; - data[5] = ((z << 4) >> 4) & 0xff; -/* - x = (s16)((data[0] <<8) |data[1]); - y = (s16)((data[2] <<8) |data[3]); - z = (s16)((data[4] <<8) |data[5]); - - pr_info("mantis_read CHK x: %d y: %d z: %d", x, y, z); -*/ - } -#endif - 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; -} - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/accel/mpu6050.h b/drivers/misc/inv_mpu/accel/mpu6050.h deleted file mode 100644 index a779255..0000000 --- a/drivers/misc/inv_mpu/accel/mpu6050.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - $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/>. - $ - */ - - -#ifndef __MPU6050_H__ -#define __MPU6050_H__ - -#include <linux/mpu_411.h> - -struct ext_slave_descr *mpu6050_get_slave_descr(void); - -#endif diff --git a/drivers/misc/inv_mpu/compass/Kconfig b/drivers/misc/inv_mpu/compass/Kconfig deleted file mode 100644 index 0881d8d..0000000 --- a/drivers/misc/inv_mpu/compass/Kconfig +++ /dev/null @@ -1,94 +0,0 @@ -menuconfig INV_SENSORS_MPU6050_COMPASS - bool "Compass Slave Sensors" - default y - ---help--- - Say Y here to get to see options for device drivers for various - compasses. This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if INV_SENSORS_MPU6050_COMPASS - -config MPU_SENSORS_MPU6050_AK8975 - tristate "AKM ak8975" - help - This enables support for the AKM ak8975 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_MPU6050_AK8972 - tristate "AKM ak8972" - help - This enables support for the AKM ak8972 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_MPU6050_MMC314X - tristate "MEMSIC mmc314x" - help - This enables support for the MEMSIC mmc314x 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_MPU6050_LSM303DLX_M - tristate "ST lsm303dlx" - help - This enables support for the ST lsm303dlh and lsm303dlm compasses - 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_MPU6050_MMC314XMS - tristate "MEMSIC mmc314xMS" - help - This enables support for the MEMSIC mmc314xMS 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_MPU6050_YAS529 - tristate "Yamaha yas529" - depends on INPUT_YAS_MAGNETOMETER - help - This enables support for the Yamaha yas529 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_MPU6050_YAS530 - tristate "Yamaha yas530" - help - This enables support for the Yamaha yas530 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_MPU6050_HSCDTD002B - tristate "Alps hscdtd002b" - help - This enables support for the Alps hscdtd002b 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_MPU6050_HSCDTD004A - tristate "Alps hscdtd004a" - help - This enables support for the Alps hscdtd004a 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. - -endif diff --git a/drivers/misc/inv_mpu/compass/Makefile b/drivers/misc/inv_mpu/compass/Makefile deleted file mode 100644 index 5533d84..0000000 --- a/drivers/misc/inv_mpu/compass/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Compass Slaves MPUxxxx -# - -obj-$(CONFIG_MPU_SENSORS_MPU6050_LSM303DLX_M) += inv_mpu_lsm303dlx_m.o -inv_mpu_lsm303dlx_m-objs += lsm303dlx_m.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_MMC314X) += inv_mpu_mmc314x.o -inv_mpu_mmc314x-objs += mmc314x.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_YAS529) += inv_mpu_yas529.o -inv_mpu_yas529-objs += yas529-kernel.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_YAS530_411) += inv_mpu_yas530.o -inv_mpu_yas530-objs += yas530.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_HSCDTD002B) += inv_mpu_hscdtd002b.o -inv_mpu_hscdtd002b-objs += hscdtd002b.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_HSCDTD004A) += inv_mpu_hscdtd004a.o -inv_mpu_hscdtd004a-objs += hscdtd004a.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_AK8975) += inv_mpu_ak8975.o -inv_mpu_ak8975-objs += ak8975.o - -obj-$(CONFIG_MPU_SENSORS_MPU6050_AK8972) += inv_mpu_ak8972.o -inv_mpu_ak8972-objs += ak8972.o - -EXTRA_CFLAGS += -Idrivers/misc/inv_mpu -EXTRA_CFLAGS += -D__C99_DESIGNATED_INITIALIZER diff --git a/drivers/misc/inv_mpu/compass/ak8972.c b/drivers/misc/inv_mpu/compass/ak8972.c deleted file mode 100644 index 7eb15b4..0000000 --- a/drivers/misc/inv_mpu/compass/ak8972.c +++ /dev/null @@ -1,499 +0,0 @@ -/* - $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 ak8972.c - * @brief Magnetometer setup and handling methods for the AKM AK8972 compass device. - */ - -/* -------------------------------------------------------------------------- */ - -#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" - -/* -------------------------------------------------------------------------- */ -#define AK8972_REG_ST1 (0x02) -#define AK8972_REG_HXL (0x03) -#define AK8972_REG_ST2 (0x09) - -#define AK8972_REG_CNTL (0x0A) -#define AK8972_REG_ASAX (0x10) -#define AK8972_REG_ASAY (0x11) -#define AK8972_REG_ASAZ (0x12) - -#define AK8972_CNTL_MODE_POWER_DOWN (0x00) -#define AK8972_CNTL_MODE_SINGLE_MEASUREMENT (0x01) -#define AK8972_CNTL_MODE_FUSE_ROM_ACCESS (0x0f) - -/* -------------------------------------------------------------------------- */ -struct ak8972_config { - char asa[COMPASS_NUM_AXES]; /* axis sensitivity adjustment */ -}; - -struct ak8972_private_data { - struct ak8972_config init; -}; - -/* -------------------------------------------------------------------------- */ -static int ak8972_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char serial_data[COMPASS_NUM_AXES]; - - struct ak8972_private_data *private_data; - private_data = (struct ak8972_private_data *) - kzalloc(sizeof(struct ak8972_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - AK8972_REG_CNTL, - AK8972_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, - AK8972_REG_CNTL, - AK8972_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, - AK8972_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, - AK8972_REG_CNTL, - AK8972_CNTL_MODE_POWER_DOWN); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - udelay(100); - return INV_SUCCESS; -} - -static int ak8972_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static int ak8972_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, - AK8972_REG_CNTL, - AK8972_CNTL_MODE_POWER_DOWN); - msleep(1); /* wait at least 100us */ - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int ak8972_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, - AK8972_REG_CNTL, - AK8972_CNTL_MODE_SINGLE_MEASUREMENT); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int ak8972_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, AK8972_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 != 0x00) { - result = inv_serial_single_write( - mlsl_handle, pdata->address, - AK8972_REG_CNTL, AK8972_CNTL_MODE_SINGLE_MEASUREMENT); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - return status; -} - -static int ak8972_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 ak8972_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct ak8972_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 ak8972_read_trigger = { - /*.reg = */ 0x0A, - /*.value = */ 0x01 -}; - -static struct ext_slave_descr ak8972_descr = { - .init = ak8972_init, - .exit = ak8972_exit, - .suspend = ak8972_suspend, - .resume = ak8972_resume, - .read = ak8972_read, - .config = ak8972_config, - .get_config = ak8972_get_config, - .name = "ak8972", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_AK8972, - .read_reg = 0x01, - .read_len = 9, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {39321, 6000}, - .trigger = &ak8972_read_trigger, -}; - -static -struct ext_slave_descr *ak8972_get_slave_descr(void) -{ - return &ak8972_descr; -} - -/* -------------------------------------------------------------------------- */ -struct ak8972_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int ak8972_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct ak8972_mod_private_data *private_data; - int result = 0; - - 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; - 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, - ak8972_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 ak8972_mod_remove(struct i2c_client *client) -{ - struct ak8972_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, - ak8972_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id ak8972_mod_id[] = { - { "ak8972", COMPASS_ID_AK8972 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ak8972_mod_id); - -static struct i2c_driver ak8972_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = ak8972_mod_probe, - .remove = ak8972_mod_remove, - .id_table = ak8972_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "ak8972_mod", - }, - .address_list = normal_i2c, -}; - -static int __init ak8972_mod_init(void) -{ - int res = i2c_add_driver(&ak8972_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "ak8972_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit ak8972_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&ak8972_mod_driver); -} - -module_init(ak8972_mod_init); -module_exit(ak8972_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate AK8972 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("ak8972_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/ak8975.c b/drivers/misc/inv_mpu/compass/ak8975.c deleted file mode 100644 index b8dea1b..0000000 --- a/drivers/misc/inv_mpu/compass/ak8975.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - $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 ak8975.c - * @brief Magnetometer setup and handling methods for the AKM AK8975, - * AKM AK8975B, and AKM AK8975C 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" - -/* -------------------------------------------------------------------------- */ -#define AK8975_REG_ST1 (0x02) -#define AK8975_REG_HXL (0x03) -#define AK8975_REG_ST2 (0x09) - -#define AK8975_REG_CNTL (0x0A) -#define AK8975_REG_ASAX (0x10) -#define AK8975_REG_ASAY (0x11) -#define AK8975_REG_ASAZ (0x12) - -#define AK8975_CNTL_MODE_POWER_DOWN (0x10) -#define AK8975_CNTL_MODE_SINGLE_MEASUREMENT (0x11) -#define AK8975_CNTL_MODE_FUSE_ROM_ACCESS (0x1f) - -/* -------------------------------------------------------------------------- */ -struct ak8975_config { - char asa[COMPASS_NUM_AXES]; /* axis sensitivity adjustment */ -}; - -struct ak8975_private_data { - struct ak8975_config init; -}; - -/* -------------------------------------------------------------------------- */ -static int ak8975_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char serial_data[COMPASS_NUM_AXES]; - - struct ak8975_private_data *private_data; - private_data = (struct ak8975_private_data *) - kzalloc(sizeof(struct ak8975_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - AK8975_REG_CNTL, - AK8975_CNTL_MODE_POWER_DOWN); - if (result) { - LOG_RESULT_LOCATION(result); - kfree(private_data); - return result; - } - /* Wait at least 100us */ - udelay(100); - - result = inv_serial_single_write(mlsl_handle, pdata->address, - AK8975_REG_CNTL, - AK8975_CNTL_MODE_FUSE_ROM_ACCESS); - if (result) { - LOG_RESULT_LOCATION(result); - kfree(private_data); - return result; - } - - /* Wait at least 200us */ - udelay(200); - - result = inv_serial_read(mlsl_handle, pdata->address, - AK8975_REG_ASAX, - COMPASS_NUM_AXES, serial_data); - if (result) { - LOG_RESULT_LOCATION(result); - kfree(private_data); - 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, - AK8975_REG_CNTL, - AK8975_CNTL_MODE_POWER_DOWN); - if (result) { - LOG_RESULT_LOCATION(result); - kfree(private_data); - return result; - } - - udelay(100); - return INV_SUCCESS; -} - -static int ak8975_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static int ak8975_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, - AK8975_REG_CNTL, - AK8975_CNTL_MODE_POWER_DOWN); - msleep(20); /* wait at least 100us */ - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int ak8975_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, - AK8975_REG_CNTL, - AK8975_CNTL_MODE_SINGLE_MEASUREMENT); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return result; -} - -static int ak8975_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, AK8975_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 != 0x00) { - result = inv_serial_single_write( - mlsl_handle, pdata->address, - AK8975_REG_CNTL, AK8975_CNTL_MODE_SINGLE_MEASUREMENT); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - return status; -} - -static int ak8975_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 ak8975_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - struct ak8975_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 ak8975_read_trigger = { - /*.reg = */ 0x0A, - /*.value = */ 0x01 -}; - -static struct ext_slave_descr ak8975_descr = { - .init = ak8975_init, - .exit = ak8975_exit, - .suspend = ak8975_suspend, - .resume = ak8975_resume, - .read = ak8975_read, - .config = ak8975_config, - .get_config = ak8975_get_config, - .name = "ak8975", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_AK8975, - .read_reg = 0x01, - .read_len = 10, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {9830, 4000}, - .trigger = &ak8975_read_trigger, -}; - -static -struct ext_slave_descr *ak8975_get_slave_descr(void) -{ - return &ak8975_descr; -} - -/* -------------------------------------------------------------------------- */ -struct ak8975_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -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; - - 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; - 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, - ak8975_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 ak8975_mod_remove(struct i2c_client *client) -{ - struct ak8975_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, - ak8975_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id ak8975_mod_id[] = { - { "ak8975_mod", COMPASS_ID_AK8975 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, ak8975_mod_id); - -static struct i2c_driver ak8975_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = ak8975_mod_probe, - .remove = ak8975_mod_remove, - .id_table = ak8975_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "ak8975_mod", - }, - .address_list = normal_i2c, -}; - -static int __init ak8975_mod_init(void) -{ - int res = i2c_add_driver(&ak8975_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "ak8975_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit ak8975_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&ak8975_mod_driver); -} - -module_init(ak8975_mod_init); -module_exit(ak8975_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate AK8975 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("ak8975_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/hscdtd002b.c b/drivers/misc/inv_mpu/compass/hscdtd002b.c deleted file mode 100644 index 4f6013c..0000000 --- a/drivers/misc/inv_mpu/compass/hscdtd002b.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - $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 hscdtd002b.c - * @brief Magnetometer setup and handling methods for Alps HSCDTD002B - * compass. - */ - -/* -------------------------------------------------------------------------- */ - -#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" - -/* -------------------------------------------------------------------------- */ -#define COMPASS_HSCDTD002B_STAT (0x18) -#define COMPASS_HSCDTD002B_CTRL1 (0x1B) -#define COMPASS_HSCDTD002B_CTRL2 (0x1C) -#define COMPASS_HSCDTD002B_CTRL3 (0x1D) -#define COMPASS_HSCDTD002B_DATAX (0x10) - -/* -------------------------------------------------------------------------- */ -static int hscdtd002b_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - /* Power mode: stand-by */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_CTRL1, 0x00); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); /* turn-off time */ - - return result; -} - -static int hscdtd002b_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - /* Soft reset */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_CTRL3, 0x80); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Force state; Power mode: active */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_CTRL1, 0x82); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Data ready enable */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_CTRL2, 0x08); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); /* turn-on time */ - - return result; -} - -static int hscdtd002b_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - unsigned char stat; - int result = INV_SUCCESS; - int status = INV_SUCCESS; - - /* Read status reg. to check if data is ready */ - result = - inv_serial_read(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_STAT, 1, &stat); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (stat & 0x40) { - result = - inv_serial_read(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_DATAX, 6, - (unsigned char *)data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - status = INV_SUCCESS; - } else if (stat & 0x20) { - status = INV_ERROR_COMPASS_DATA_OVERFLOW; - } else { - status = INV_ERROR_COMPASS_DATA_NOT_READY; - } - /* trigger next measurement read */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD002B_CTRL3, 0x40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return status; -} - -static struct ext_slave_descr hscdtd002b_descr = { - .init = NULL, - .exit = NULL, - .suspend = hscdtd002b_suspend, - .resume = hscdtd002b_resume, - .read = hscdtd002b_read, - .config = NULL, - .get_config = NULL, - .name = "hscdtd002b", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_HSCDTD002B, - .read_reg = 0x10, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {9830, 4000}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *hscdtd002b_get_slave_descr(void) -{ - return &hscdtd002b_descr; -} - -/* -------------------------------------------------------------------------- */ -struct hscdtd002b_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int hscdtd002b_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct hscdtd002b_mod_private_data *private_data; - int result = 0; - - 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; - 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, - hscdtd002b_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 hscdtd002b_mod_remove(struct i2c_client *client) -{ - struct hscdtd002b_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, - hscdtd002b_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id hscdtd002b_mod_id[] = { - { "hscdtd002b", COMPASS_ID_HSCDTD002B }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, hscdtd002b_mod_id); - -static struct i2c_driver hscdtd002b_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = hscdtd002b_mod_probe, - .remove = hscdtd002b_mod_remove, - .id_table = hscdtd002b_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "hscdtd002b_mod", - }, - .address_list = normal_i2c, -}; - -static int __init hscdtd002b_mod_init(void) -{ - int res = i2c_add_driver(&hscdtd002b_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "hscdtd002b_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit hscdtd002b_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&hscdtd002b_mod_driver); -} - -module_init(hscdtd002b_mod_init); -module_exit(hscdtd002b_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate HSCDTD002B sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("hscdtd002b_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/hscdtd004a.c b/drivers/misc/inv_mpu/compass/hscdtd004a.c deleted file mode 100644 index f091559..0000000 --- a/drivers/misc/inv_mpu/compass/hscdtd004a.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - $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 hscdtd004a.c - * @brief Magnetometer setup and handling methods for Alps HSCDTD004A - * compass. - */ - -/* -------------------------------------------------------------------------- */ - -#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" - -/* -------------------------------------------------------------------------- */ -#define COMPASS_HSCDTD004A_STAT (0x18) -#define COMPASS_HSCDTD004A_CTRL1 (0x1B) -#define COMPASS_HSCDTD004A_CTRL2 (0x1C) -#define COMPASS_HSCDTD004A_CTRL3 (0x1D) -#define COMPASS_HSCDTD004A_DATAX (0x10) - -/* -------------------------------------------------------------------------- */ - -static int hscdtd004a_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - /* Power mode: stand-by */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_CTRL1, 0x00); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); /* turn-off time */ - - return result; -} - -static int hscdtd004a_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char data1, data2[2]; - - result = inv_serial_read(mlsl_handle, pdata->address, 0xf, 1, &data1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(mlsl_handle, pdata->address, 0xd, 2, data2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (data1 != 0x49 || data2[0] != 0x45 || data2[1] != 0x54) { - LOG_RESULT_LOCATION(INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED); - return INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED; - } - return result; -} - -static int hscdtd004a_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - /* Soft reset */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_CTRL3, 0x80); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Normal state; Power mode: active */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_CTRL1, 0x82); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Data ready enable */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_CTRL2, 0x7C); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(1); /* turn-on time */ - return result; -} - -static int hscdtd004a_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - unsigned char stat; - int result = INV_SUCCESS; - int status = INV_SUCCESS; - - /* Read status reg. to check if data is ready */ - result = - inv_serial_read(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_STAT, 1, &stat); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (stat & 0x48) { - result = - inv_serial_read(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_DATAX, 6, - (unsigned char *)data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - status = INV_SUCCESS; - } else if (stat & 0x68) { - status = INV_ERROR_COMPASS_DATA_OVERFLOW; - } else { - status = INV_ERROR_COMPASS_DATA_NOT_READY; - } - /* trigger next measurement read */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - COMPASS_HSCDTD004A_CTRL3, 0x40); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return status; - -} - -static struct ext_slave_descr hscdtd004a_descr = { - .init = hscdtd004a_init, - .exit = NULL, - .suspend = hscdtd004a_suspend, - .resume = hscdtd004a_resume, - .read = hscdtd004a_read, - .config = NULL, - .get_config = NULL, - .name = "hscdtd004a", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_HSCDTD004A, - .read_reg = 0x10, - .read_len = 6, - .endian = EXT_SLAVE_LITTLE_ENDIAN, - .range = {9830, 4000}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *hscdtd004a_get_slave_descr(void) -{ - return &hscdtd004a_descr; -} - -/* -------------------------------------------------------------------------- */ -struct hscdtd004a_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int hscdtd004a_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct hscdtd004a_mod_private_data *private_data; - int result = 0; - - 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; - 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, - hscdtd004a_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 hscdtd004a_mod_remove(struct i2c_client *client) -{ - struct hscdtd004a_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, - hscdtd004a_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id hscdtd004a_mod_id[] = { - { "hscdtd004a", COMPASS_ID_HSCDTD004A }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, hscdtd004a_mod_id); - -static struct i2c_driver hscdtd004a_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = hscdtd004a_mod_probe, - .remove = hscdtd004a_mod_remove, - .id_table = hscdtd004a_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "hscdtd004a_mod", - }, - .address_list = normal_i2c, -}; - -static int __init hscdtd004a_mod_init(void) -{ - int res = i2c_add_driver(&hscdtd004a_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "hscdtd004a_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit hscdtd004a_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&hscdtd004a_mod_driver); -} - -module_init(hscdtd004a_mod_init); -module_exit(hscdtd004a_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate HSCDTD004A sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("hscdtd004a_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/lsm303dlx_m.c b/drivers/misc/inv_mpu/compass/lsm303dlx_m.c deleted file mode 100644 index 32f8cdd..0000000 --- a/drivers/misc/inv_mpu/compass/lsm303dlx_m.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - $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 lsm303dlx_m.c - * @brief Magnetometer setup and handling methods for ST LSM303 - * compass. - * This magnetometer device is part of a combo chip with the - * ST LIS331DLH accelerometer and the logic in entirely based - * on the Honeywell HMC5883 magnetometer. - */ - -/* -------------------------------------------------------------------------- */ - -#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" - -/* -------------------------------------------------------------------------- */ -enum LSM_REG { - LSM_REG_CONF_A = 0x0, - LSM_REG_CONF_B = 0x1, - LSM_REG_MODE = 0x2, - LSM_REG_X_M = 0x3, - LSM_REG_X_L = 0x4, - LSM_REG_Z_M = 0x5, - LSM_REG_Z_L = 0x6, - LSM_REG_Y_M = 0x7, - LSM_REG_Y_L = 0x8, - LSM_REG_STATUS = 0x9, - LSM_REG_ID_A = 0xA, - LSM_REG_ID_B = 0xB, - LSM_REG_ID_C = 0xC -}; - -enum LSM_CONF_A { - LSM_CONF_A_DRATE_MASK = 0x1C, - LSM_CONF_A_DRATE_0_75 = 0x00, - LSM_CONF_A_DRATE_1_5 = 0x04, - LSM_CONF_A_DRATE_3 = 0x08, - LSM_CONF_A_DRATE_7_5 = 0x0C, - LSM_CONF_A_DRATE_15 = 0x10, - LSM_CONF_A_DRATE_30 = 0x14, - LSM_CONF_A_DRATE_75 = 0x18, - LSM_CONF_A_MEAS_MASK = 0x3, - LSM_CONF_A_MEAS_NORM = 0x0, - LSM_CONF_A_MEAS_POS = 0x1, - LSM_CONF_A_MEAS_NEG = 0x2 -}; - -enum LSM_CONF_B { - LSM_CONF_B_GAIN_MASK = 0xE0, - LSM_CONF_B_GAIN_0_9 = 0x00, - LSM_CONF_B_GAIN_1_2 = 0x20, - LSM_CONF_B_GAIN_1_9 = 0x40, - LSM_CONF_B_GAIN_2_5 = 0x60, - LSM_CONF_B_GAIN_4_0 = 0x80, - LSM_CONF_B_GAIN_4_6 = 0xA0, - LSM_CONF_B_GAIN_5_5 = 0xC0, - LSM_CONF_B_GAIN_7_9 = 0xE0 -}; - -enum LSM_MODE { - LSM_MODE_MASK = 0x3, - LSM_MODE_CONT = 0x0, - LSM_MODE_SINGLE = 0x1, - LSM_MODE_IDLE = 0x2, - LSM_MODE_SLEEP = 0x3 -}; - -/* -------------------------------------------------------------------------- */ - -static int lsm303dlx_m_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, - LSM_REG_MODE, LSM_MODE_SLEEP); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(3); - - return result; -} - -static int lsm303dlx_m_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - /* Use single measurement mode. Start at sleep state. */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - LSM_REG_MODE, LSM_MODE_SLEEP); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Config normal measurement */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - LSM_REG_CONF_A, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Adjust gain to 320 LSB/Gauss */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - LSM_REG_CONF_B, LSM_CONF_B_GAIN_5_5); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -static int lsm303dlx_m_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - unsigned char stat; - int result = INV_SUCCESS; - short axis_fixed; - - /* Read status reg. to check if data is ready */ - result = - inv_serial_read(mlsl_handle, pdata->address, LSM_REG_STATUS, 1, - &stat); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (stat & 0x01) { - result = - inv_serial_read(mlsl_handle, pdata->address, - LSM_REG_X_M, 6, (unsigned char *)data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /*drop data if overflows */ - if ((data[0] == 0xf0) || (data[2] == 0xf0) - || (data[4] == 0xf0)) { - /* trigger next measurement read */ - result = - inv_serial_single_write(mlsl_handle, - pdata->address, - LSM_REG_MODE, - LSM_MODE_SINGLE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return INV_ERROR_COMPASS_DATA_OVERFLOW; - } - /* convert to fixed point and apply sensitivity correction for - Z-axis */ - axis_fixed = - (short)((unsigned short)data[5] + - (unsigned short)data[4] * 256); - /* scale up by 1.125 (36/32) approximate of 1.122 (320/285) */ - if (slave->id == COMPASS_ID_LSM303DLM) { - /* NOTE/IMPORTANT: - lsm303dlm compass axis definition doesn't - respect the right hand rule. We invert - the sign of the Z axis to fix that. */ - axis_fixed = (short)(-1 * axis_fixed * 36); - } else { - axis_fixed = (short)(axis_fixed * 36); - } - data[4] = axis_fixed >> 8; - data[5] = axis_fixed & 0xFF; - - axis_fixed = - (short)((unsigned short)data[3] + - (unsigned short)data[2] * 256); - axis_fixed = (short)(axis_fixed * 32); - data[2] = axis_fixed >> 8; - data[3] = axis_fixed & 0xFF; - - axis_fixed = - (short)((unsigned short)data[1] + - (unsigned short)data[0] * 256); - axis_fixed = (short)(axis_fixed * 32); - data[0] = axis_fixed >> 8; - data[1] = axis_fixed & 0xFF; - - /* trigger next measurement read */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - LSM_REG_MODE, LSM_MODE_SINGLE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return INV_SUCCESS; - } else { - /* trigger next measurement read */ - result = - inv_serial_single_write(mlsl_handle, pdata->address, - LSM_REG_MODE, LSM_MODE_SINGLE); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return INV_ERROR_COMPASS_DATA_NOT_READY; - } -} - -static struct ext_slave_descr lsm303dlx_m_descr = { - .init = NULL, - .exit = NULL, - .suspend = lsm303dlx_m_suspend, - .resume = lsm303dlx_m_resume, - .read = lsm303dlx_m_read, - .config = NULL, - .get_config = NULL, - .name = "lsm303dlx_m", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = ID_INVALID, - .read_reg = 0x06, - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {10240, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *lsm303dlx_m_get_slave_descr(void) -{ - return &lsm303dlx_m_descr; -} - -/* -------------------------------------------------------------------------- */ -struct lsm303dlx_m_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static const struct i2c_device_id lsm303dlx_m_mod_id[] = { - { "lsm303dlh", COMPASS_ID_LSM303DLH }, - { "lsm303dlm", COMPASS_ID_LSM303DLM }, - {} -}; -MODULE_DEVICE_TABLE(i2c, lsm303dlx_m_mod_id); - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int lsm303dlx_m_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct lsm303dlx_m_mod_private_data *private_data; - int result = 0; - - dev_info(&client->adapter->dev, "%s: %s\n", __func__, devid->name); - lsm303dlx_m_descr.id = devid->driver_data; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - result = -ENODEV; - goto out_no_free; - } - - pdata = client->dev.platform_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, - lsm303dlx_m_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 lsm303dlx_m_mod_remove(struct i2c_client *client) -{ - struct lsm303dlx_m_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, - lsm303dlx_m_get_slave_descr); - - kfree(private_data); - return 0; -} - -static struct i2c_driver lsm303dlx_m_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = lsm303dlx_m_mod_probe, - .remove = lsm303dlx_m_mod_remove, - .id_table = lsm303dlx_m_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "lsm303dlx_m_mod", - }, - .address_list = normal_i2c, -}; - -static int __init lsm303dlx_m_mod_init(void) -{ - int res = i2c_add_driver(&lsm303dlx_m_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "lsm303dlx_m_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit lsm303dlx_m_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&lsm303dlx_m_mod_driver); -} - -module_init(lsm303dlx_m_mod_init); -module_exit(lsm303dlx_m_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate lsm303dlx_m sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("lsm303dlx_m_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/mmc314x.c b/drivers/misc/inv_mpu/compass/mmc314x.c deleted file mode 100644 index 786fadc..0000000 --- a/drivers/misc/inv_mpu/compass/mmc314x.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - $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 mmc314x.c - * @brief Magnetometer setup and handling methods for the - * MEMSIC MMC314x compass. - */ - -/* -------------------------------------------------------------------------- */ - -#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" - -/* -------------------------------------------------------------------------- */ - -static int reset_int = 1000; -static int read_count = 1; -static char reset_mode; /* in Z-init section */ - -/* -------------------------------------------------------------------------- */ -#define MMC314X_REG_ST (0x00) -#define MMC314X_REG_X_MSB (0x01) - -#define MMC314X_CNTL_MODE_WAKE_UP (0x01) -#define MMC314X_CNTL_MODE_SET (0x02) -#define MMC314X_CNTL_MODE_RESET (0x04) - -/* -------------------------------------------------------------------------- */ - -static int mmc314x_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - return result; -} - -static int mmc314x_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - - int result; - result = - inv_serial_single_write(mlsl_handle, pdata->address, - MMC314X_REG_ST, MMC314X_CNTL_MODE_RESET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(10); - result = - inv_serial_single_write(mlsl_handle, pdata->address, - MMC314X_REG_ST, MMC314X_CNTL_MODE_SET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(10); - read_count = 1; - return INV_SUCCESS; -} - -static int mmc314x_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result, ii; - short tmp[3]; - unsigned char tmpdata[6]; - - if (read_count > 1000) - read_count = 1; - - result = - inv_serial_read(mlsl_handle, pdata->address, MMC314X_REG_X_MSB, - 6, (unsigned char *)data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - for (ii = 0; ii < 6; ii++) - tmpdata[ii] = data[ii]; - - for (ii = 0; ii < 3; ii++) { - tmp[ii] = (short)((tmpdata[2 * ii] << 8) + tmpdata[2 * ii + 1]); - tmp[ii] = tmp[ii] - 4096; - tmp[ii] = tmp[ii] * 16; - } - - for (ii = 0; ii < 3; ii++) { - data[2 * ii] = (unsigned char)(tmp[ii] >> 8); - data[2 * ii + 1] = (unsigned char)(tmp[ii]); - } - - if (read_count % reset_int == 0) { - if (reset_mode) { - result = - inv_serial_single_write(mlsl_handle, - pdata->address, - MMC314X_REG_ST, - MMC314X_CNTL_MODE_RESET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - reset_mode = 0; - return INV_ERROR_COMPASS_DATA_NOT_READY; - } else { - result = - inv_serial_single_write(mlsl_handle, - pdata->address, - MMC314X_REG_ST, - MMC314X_CNTL_MODE_SET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - reset_mode = 1; - read_count++; - return INV_ERROR_COMPASS_DATA_NOT_READY; - } - } - result = - inv_serial_single_write(mlsl_handle, pdata->address, - MMC314X_REG_ST, MMC314X_CNTL_MODE_WAKE_UP); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - read_count++; - - return INV_SUCCESS; -} - -static struct ext_slave_descr mmc314x_descr = { - .init = NULL, - .exit = NULL, - .suspend = mmc314x_suspend, - .resume = mmc314x_resume, - .read = mmc314x_read, - .config = NULL, - .get_config = NULL, - .name = "mmc314x", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_MMC314X, - .read_reg = 0x01, - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {400, 0}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *mmc314x_get_slave_descr(void) -{ - return &mmc314x_descr; -} - -/* -------------------------------------------------------------------------- */ -struct mmc314x_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int mmc314x_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct mmc314x_mod_private_data *private_data; - int result = 0; - - 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; - 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, - mmc314x_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 mmc314x_mod_remove(struct i2c_client *client) -{ - struct mmc314x_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, - mmc314x_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id mmc314x_mod_id[] = { - { "mmc314x", COMPASS_ID_MMC314X }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, mmc314x_mod_id); - -static struct i2c_driver mmc314x_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = mmc314x_mod_probe, - .remove = mmc314x_mod_remove, - .id_table = mmc314x_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "mmc314x_mod", - }, - .address_list = normal_i2c, -}; - -static int __init mmc314x_mod_init(void) -{ - int res = i2c_add_driver(&mmc314x_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "mmc314x_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit mmc314x_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&mmc314x_mod_driver); -} - -module_init(mmc314x_mod_init); -module_exit(mmc314x_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate MMC314X sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("mmc314x_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/yas529-kernel.c b/drivers/misc/inv_mpu/compass/yas529-kernel.c deleted file mode 100644 index f53223f..0000000 --- a/drivers/misc/inv_mpu/compass/yas529-kernel.c +++ /dev/null @@ -1,611 +0,0 @@ -/* - $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/>. - $ - */ - -/* -------------------------------------------------------------------------- */ - -#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-acc" - -/*----- YAMAHA YAS529 Registers ------*/ -enum YAS_REG { - YAS_REG_CMDR = 0x00, /* 000 < 5 */ - YAS_REG_XOFFSETR = 0x20, /* 001 < 5 */ - YAS_REG_Y1OFFSETR = 0x40, /* 010 < 5 */ - YAS_REG_Y2OFFSETR = 0x60, /* 011 < 5 */ - YAS_REG_ICOILR = 0x80, /* 100 < 5 */ - YAS_REG_CAL = 0xA0, /* 101 < 5 */ - YAS_REG_CONFR = 0xC0, /* 110 < 5 */ - YAS_REG_DOUTR = 0xE0 /* 111 < 5 */ -}; - -/* -------------------------------------------------------------------------- */ - -static long a1; -static long a2; -static long a3; -static long a4; -static long a5; -static long a6; -static long a7; -static long a8; -static long a9; - -/* -------------------------------------------------------------------------- */ -static int yas529_sensor_i2c_write(struct i2c_adapter *i2c_adap, - unsigned char address, - unsigned int len, unsigned char *data) -{ - struct i2c_msg msgs[1]; - int res; - - if (NULL == data || NULL == i2c_adap) - return -EINVAL; - - msgs[0].addr = address; - msgs[0].flags = 0; /* write */ - msgs[0].buf = (unsigned char *)data; - msgs[0].len = len; - - res = i2c_transfer(i2c_adap, msgs, 1); - if (res < 1) - return res; - else - return 0; -} - -static int yas529_sensor_i2c_read(struct i2c_adapter *i2c_adap, - unsigned char address, - unsigned char reg, - unsigned int len, unsigned char *data) -{ - struct i2c_msg msgs[2]; - int res; - - if (NULL == data || NULL == i2c_adap) - return -EINVAL; - - msgs[0].addr = address; - msgs[0].flags = I2C_M_RD; - msgs[0].buf = data; - msgs[0].len = len; - - res = i2c_transfer(i2c_adap, msgs, 1); - if (res < 1) - return res; - else - return 0; -} - -static int yas529_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - return result; -} - -static int yas529_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - unsigned char dummyData[1] = { 0 }; - unsigned char dummyRegister = 0; - unsigned char rawData[6]; - unsigned char calData[9]; - - short xoffset, y1offset, y2offset; - short d2, d3, d4, d5, d6, d7, d8, d9; - - /* YAS529 Application Manual MS-3C - Section 4.4.5 */ - /* =============================================== */ - /* Step 1 - register initialization */ - /* zero initialization coil register - "100 00 000" */ - dummyData[0] = YAS_REG_ICOILR | 0x00; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* zero config register - "110 00 000" */ - dummyData[0] = YAS_REG_CONFR | 0x00; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Step 2 - initialization coil operation */ - dummyData[0] = YAS_REG_ICOILR | 0x11; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x01; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x12; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x02; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x13; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x03; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x14; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x04; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x15; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x05; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x16; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x06; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x17; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x07; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x10; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_ICOILR | 0x00; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Step 3 - rough offset measurement */ - /* Config register - Measurements results - "110 00 000" */ - dummyData[0] = YAS_REG_CONFR | 0x00; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Measurements command register - Rough offset measurement - - "000 00001" */ - dummyData[0] = YAS_REG_CMDR | 0x01; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(2); /* wait at least 1.5ms */ - - /* Measurement data read */ - result = - yas529_sensor_i2c_read(mlsl_handle, pdata->address, - dummyRegister, 6, rawData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - xoffset = - (short)((unsigned short)rawData[5] + - ((unsigned short)rawData[4] & 0x7) * 256) - 5; - if (xoffset < 0) - xoffset = 0; - y1offset = - (short)((unsigned short)rawData[3] + - ((unsigned short)rawData[2] & 0x7) * 256) - 5; - if (y1offset < 0) - y1offset = 0; - y2offset = - (short)((unsigned short)rawData[1] + - ((unsigned short)rawData[0] & 0x7) * 256) - 5; - if (y2offset < 0) - y2offset = 0; - - /* Step 4 - rough offset setting */ - /* Set rough offset register values */ - dummyData[0] = YAS_REG_XOFFSETR | xoffset; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_Y1OFFSETR | y1offset; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - dummyData[0] = YAS_REG_Y2OFFSETR | y2offset; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* CAL matrix read (first read is invalid) */ - /* Config register - CAL register read - "110 01 000" */ - dummyData[0] = YAS_REG_CONFR | 0x08; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* CAL data read */ - result = - yas529_sensor_i2c_read(mlsl_handle, pdata->address, - dummyRegister, 9, calData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Config register - CAL register read - "110 01 000" */ - dummyData[0] = YAS_REG_CONFR | 0x08; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* CAL data read */ - result = - yas529_sensor_i2c_read(mlsl_handle, pdata->address, - dummyRegister, 9, calData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Calculate coefficients of the sensitivity correction matrix */ - a1 = 100; - d2 = (calData[0] & 0xFC) >> 2; /* [71..66] 6bit */ - a2 = (short)(d2 - 32); - /* [65..62] 4bit */ - d3 = ((calData[0] & 0x03) << 2) | ((calData[1] & 0xC0) >> 6); - a3 = (short)(d3 - 8); - d4 = (calData[1] & 0x3F); /* [61..56] 6bit */ - a4 = (short)(d4 - 32); - d5 = (calData[2] & 0xFC) >> 2; /* [55..50] 6bit */ - a5 = (short)(d5 - 32) + 70; - /* [49..44] 6bit */ - d6 = ((calData[2] & 0x03) << 4) | ((calData[3] & 0xF0) >> 4); - a6 = (short)(d6 - 32); - /* [43..38] 6bit */ - d7 = ((calData[3] & 0x0F) << 2) | ((calData[4] & 0xC0) >> 6); - a7 = (short)(d7 - 32); - d8 = (calData[4] & 0x3F); /* [37..32] 6bit */ - a8 = (short)(d8 - 32); - d9 = (calData[5] & 0xFE) >> 1; /* [31..25] 7bit */ - a9 = (short)(d9 - 64) + 130; - - return result; -} - -static int yas529_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - unsigned char stat; - unsigned char rawData[6]; - unsigned char dummyData[1] = { 0 }; - unsigned char dummyRegister = 0; - int result = INV_SUCCESS; - short SX, SY1, SY2, SY, SZ; - short row1fixed, row2fixed, row3fixed; - - /* Config register - Measurements results - "110 00 000" */ - dummyData[0] = YAS_REG_CONFR | 0x00; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Measurements command register - Normal magnetic field measurement - - "000 00000" */ - dummyData[0] = YAS_REG_CMDR | 0x00; - result = - yas529_sensor_i2c_write(mlsl_handle, pdata->address, 1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - msleep(10); - /* Measurement data read */ - result = - yas529_sensor_i2c_read(mlsl_handle, pdata->address, - dummyRegister, 6, (unsigned char *)&rawData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - stat = rawData[0] & 0x80; - if (stat == 0x00) { - /* Extract raw data */ - SX = (short)((unsigned short)rawData[5] + - ((unsigned short)rawData[4] & 0x7) * 256); - SY1 = - (short)((unsigned short)rawData[3] + - ((unsigned short)rawData[2] & 0x7) * 256); - SY2 = - (short)((unsigned short)rawData[1] + - ((unsigned short)rawData[0] & 0x7) * 256); - if ((SX <= 1) || (SY1 <= 1) || (SY2 <= 1)) - return INV_ERROR_COMPASS_DATA_UNDERFLOW; - if ((SX >= 1024) || (SY1 >= 1024) || (SY2 >= 1024)) - return INV_ERROR_COMPASS_DATA_OVERFLOW; - /* Convert to XYZ axis */ - SX = -1 * SX; - SY = SY2 - SY1; - SZ = SY1 + SY2; - - /* Apply sensitivity correction matrix */ - row1fixed = (short)((a1 * SX + a2 * SY + a3 * SZ) >> 7) * 41; - row2fixed = (short)((a4 * SX + a5 * SY + a6 * SZ) >> 7) * 41; - row3fixed = (short)((a7 * SX + a8 * SY + a9 * SZ) >> 7) * 41; - - data[0] = row1fixed >> 8; - data[1] = row1fixed & 0xFF; - data[2] = row2fixed >> 8; - data[3] = row2fixed & 0xFF; - data[4] = row3fixed >> 8; - data[5] = row3fixed & 0xFF; - - return INV_SUCCESS; - } else { - return INV_ERROR_COMPASS_DATA_NOT_READY; - } -} - -static struct ext_slave_descr yas529_descr = { - .init = NULL, - .exit = NULL, - .suspend = yas529_suspend, - .resume = yas529_resume, - .read = yas529_read, - .config = NULL, - .get_config = NULL, - .name = "yas529", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_YAS529, - .read_reg = 0x06, - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {19660, 8000}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *yas529_get_slave_descr(void) -{ - return &yas529_descr; -} - -/* -------------------------------------------------------------------------- */ -struct yas529_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int yas529_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct yas529_mod_private_data *private_data; - int result = 0; - - 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; - 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, - yas529_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 yas529_mod_remove(struct i2c_client *client) -{ - struct yas529_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, - yas529_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id yas529_mod_id[] = { - { "yas529", COMPASS_ID_YAS529 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, yas529_mod_id); - -static struct i2c_driver yas529_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = yas529_mod_probe, - .remove = yas529_mod_remove, - .id_table = yas529_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "yas529_mod", - }, - .address_list = normal_i2c, -}; - -static int __init yas529_mod_init(void) -{ - int res = i2c_add_driver(&yas529_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "yas529_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit yas529_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&yas529_mod_driver); -} - -module_init(yas529_mod_init); -module_exit(yas529_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate YAS529 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("yas529_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/yas530.c b/drivers/misc/inv_mpu/compass/yas530.c deleted file mode 100644 index 263990f..0000000 --- a/drivers/misc/inv_mpu/compass/yas530.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - $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 yas530.c - * @brief Magnetometer setup and handling methods for Yamaha YAS530 - * compass when used in a user-space solution (no kernel driver). - */ - -/* -------------------------------------------------------------------------- */ - -#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/module.h> -#include <linux/delay.h> -#include "mpu-dev.h" - -#include "log.h" -#include <linux/mpu_411.h> -#include "mlsl.h" -#include "mldl_cfg.h" -#undef MPL_LOG_TAG -#define MPL_LOG_TAG "MPL-compass" - -/* -------------------------------------------------------------------------- */ -#define YAS530_REGADDR_DEVICE_ID (0x80) -#define YAS530_REGADDR_ACTUATE_INIT_COIL (0x81) -#define YAS530_REGADDR_MEASURE_COMMAND (0x82) -#define YAS530_REGADDR_CONFIG (0x83) -#define YAS530_REGADDR_MEASURE_INTERVAL (0x84) -#define YAS530_REGADDR_OFFSET_X (0x85) -#define YAS530_REGADDR_OFFSET_Y1 (0x86) -#define YAS530_REGADDR_OFFSET_Y2 (0x87) -#define YAS530_REGADDR_TEST1 (0x88) -#define YAS530_REGADDR_TEST2 (0x89) -#define YAS530_REGADDR_CAL (0x90) -#define YAS530_REGADDR_MEASURE_DATA (0xb0) - -/* -------------------------------------------------------------------------- */ -static int Cx, Cy1, Cy2; -static int /*a1, */ a2, a3, a4, a5, a6, a7, a8, a9; -static int k; - -static unsigned char dx, dy1, dy2; -static unsigned char d2, d3, d4, d5, d6, d7, d8, d9, d0; -static unsigned char dck; - -/* -------------------------------------------------------------------------- */ - -static int set_hardware_offset(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - char offset_x, char offset_y1, char offset_y2) -{ - char data; - int result = INV_SUCCESS; - - data = offset_x & 0x3f; - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_OFFSET_X, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - data = offset_y1 & 0x3f; - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_OFFSET_Y1, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - data = offset_y2 & 0x3f; - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_OFFSET_Y2, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -static int set_measure_command(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - int ldtc, int fors, int dlymes) -{ - int result = INV_SUCCESS; - - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_MEASURE_COMMAND, 0x01); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -static int measure_normal(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - int *busy, unsigned short *t, - unsigned short *x, unsigned short *y1, - unsigned short *y2) -{ - unsigned char data[8]; - unsigned short b, to, xo, y1o, y2o; - int result; - ktime_t sleeptime; - result = set_measure_command(mlsl_handle, slave, pdata, 0, 0, 0); - sleeptime = ktime_set(0, 2 * NSEC_PER_MSEC); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_hrtimeout(&sleeptime, HRTIMER_MODE_REL); - - result = inv_serial_read(mlsl_handle, pdata->address, - YAS530_REGADDR_MEASURE_DATA, 8, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - b = (data[0] >> 7) & 0x01; - to = ((data[0] << 2) & 0x1fc) | ((data[1] >> 6) & 0x03); - xo = ((data[2] << 5) & 0xfe0) | ((data[3] >> 3) & 0x1f); - y1o = ((data[4] << 5) & 0xfe0) | ((data[5] >> 3) & 0x1f); - y2o = ((data[6] << 5) & 0xfe0) | ((data[7] >> 3) & 0x1f); - - *busy = b; - *t = to; - *x = xo; - *y1 = y1o; - *y2 = y2o; - - return result; -} - -static int check_offset(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - char offset_x, char offset_y1, char offset_y2, - int *flag_x, int *flag_y1, int *flag_y2) -{ - int result; - int busy; - short t, x, y1, y2; - - result = set_hardware_offset(mlsl_handle, slave, pdata, - offset_x, offset_y1, offset_y2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = measure_normal(mlsl_handle, slave, pdata, - &busy, &t, &x, &y1, &y2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - *flag_x = 0; - *flag_y1 = 0; - *flag_y2 = 0; - - if (x > 2048) - *flag_x = 1; - if (y1 > 2048) - *flag_y1 = 1; - if (y2 > 2048) - *flag_y2 = 1; - if (x < 2048) - *flag_x = -1; - if (y1 < 2048) - *flag_y1 = -1; - if (y2 < 2048) - *flag_y2 = -1; - - return result; -} - -static int measure_and_set_offset(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - char *offset) -{ - int i; - int result = INV_SUCCESS; - char offset_x = 0, offset_y1 = 0, offset_y2 = 0; - int flag_x = 0, flag_y1 = 0, flag_y2 = 0; - static const int correct[5] = { 16, 8, 4, 2, 1 }; - - for (i = 0; i < 5; i++) { - result = check_offset(mlsl_handle, slave, pdata, - offset_x, offset_y1, offset_y2, - &flag_x, &flag_y1, &flag_y2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (flag_x) - offset_x += flag_x * correct[i]; - if (flag_y1) - offset_y1 += flag_y1 * correct[i]; - if (flag_y2) - offset_y2 += flag_y2 * correct[i]; - } - - result = set_hardware_offset(mlsl_handle, slave, pdata, - offset_x, offset_y1, offset_y2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - offset[0] = offset_x; - offset[1] = offset_y1; - offset[2] = offset_y2; - - return result; -} - -static void coordinate_conversion(short x, short y1, short y2, short t, - int32_t *xo, int32_t *yo, int32_t *zo) -{ - int32_t sx, sy1, sy2, sy, sz; - int32_t hx, hy, hz; - - sx = x - (Cx * t) / 100; - sy1 = y1 - (Cy1 * t) / 100; - sy2 = y2 - (Cy2 * t) / 100; - - sy = sy1 - sy2; - sz = -sy1 - sy2; - - hx = k * ((100 * sx + a2 * sy + a3 * sz) / 10); - hy = k * ((a4 * sx + a5 * sy + a6 * sz) / 10); - hz = k * ((a7 * sx + a8 * sy + a9 * sz) / 10); - - *xo = hx; - *yo = hy; - *zo = hz; -} - -static int yas530_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - return result; -} - -static int yas530_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - unsigned char dummyData = 0x00; - char offset[3] = { 0, 0, 0 }; - unsigned char data[16]; - unsigned char read_reg[1]; - - /* =============================================== */ - - /* Step 1 - Test register initialization */ - dummyData = 0x00; - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_TEST1, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = - inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_TEST2, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Device ID read */ - result = inv_serial_read(mlsl_handle, pdata->address, - YAS530_REGADDR_DEVICE_ID, 1, read_reg); - - /*Step 2 Read the CAL register */ - /* CAL data read */ - result = inv_serial_read(mlsl_handle, pdata->address, - YAS530_REGADDR_CAL, 16, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* CAL data Second Read */ - result = inv_serial_read(mlsl_handle, pdata->address, - YAS530_REGADDR_CAL, 16, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /*Cal data */ - dx = data[0]; - dy1 = data[1]; - dy2 = data[2]; - d2 = (data[3] >> 2) & 0x03f; - d3 = ((data[3] << 2) & 0x0c) | ((data[4] >> 6) & 0x03); - d4 = data[4] & 0x3f; - d5 = (data[5] >> 2) & 0x3f; - d6 = ((data[5] << 4) & 0x30) | ((data[6] >> 4) & 0x0f); - d7 = ((data[6] << 3) & 0x78) | ((data[7] >> 5) & 0x07); - d8 = ((data[7] << 1) & 0x3e) | ((data[8] >> 7) & 0x01); - d9 = ((data[8] << 1) & 0xfe) | ((data[9] >> 7) & 0x01); - d0 = (data[9] >> 2) & 0x1f; - dck = ((data[9] << 1) & 0x06) | ((data[10] >> 7) & 0x01); - - /*Correction Data */ - Cx = (int)dx * 6 - 768; - Cy1 = (int)dy1 * 6 - 768; - Cy2 = (int)dy2 * 6 - 768; - a2 = (int)d2 - 32; - a3 = (int)d3 - 8; - a4 = (int)d4 - 32; - a5 = (int)d5 + 38; - a6 = (int)d6 - 32; - a7 = (int)d7 - 64; - a8 = (int)d8 - 32; - a9 = (int)d9; - k = (int)d0 + 10; - - /*Obtain the [49:47] bits */ - dck &= 0x07; - - /*Step 3 : Storing the CONFIG with the CLK value */ - dummyData = 0x00 | (dck << 2); - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_CONFIG, dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /*Step 4 : Set Acquisition Interval Register */ - dummyData = 0x00; - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_MEASURE_INTERVAL, - dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /*Step 5 : Reset Coil */ - dummyData = 0x00; - result = inv_serial_single_write(mlsl_handle, pdata->address, - YAS530_REGADDR_ACTUATE_INIT_COIL, - dummyData); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Offset Measurement and Set */ - result = measure_and_set_offset(mlsl_handle, slave, pdata, offset); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - return result; -} - -static int yas530_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - - int busy; - short t, x, y1, y2; - int32_t xyz[3]; - short rawfixed[3]; - - result = measure_normal(mlsl_handle, slave, pdata, - &busy, &t, &x, &y1, &y2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - coordinate_conversion(x, y1, y2, t, &xyz[0], &xyz[1], &xyz[2]); - - rawfixed[0] = (short)(xyz[0] / 100); - rawfixed[1] = (short)(xyz[1] / 100); - rawfixed[2] = (short)(xyz[2] / 100); - - data[0] = rawfixed[0] >> 8; - data[1] = rawfixed[0] & 0xFF; - data[2] = rawfixed[1] >> 8; - data[3] = rawfixed[1] & 0xFF; - data[4] = rawfixed[2] >> 8; - data[5] = rawfixed[2] & 0xFF; - - if (busy) - return INV_ERROR_COMPASS_DATA_NOT_READY; - return result; -} - -static int yas530_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - int result = INV_SUCCESS; - //struct yas530_private_data *private_data = pdata->private_data; - - switch (data->key) - { - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - } - return result; -} - -static struct ext_slave_descr yas530_descr = { - .init = NULL, - .exit = NULL, - .suspend = yas530_suspend, - .resume = yas530_resume, - .read = yas530_read, - .config = NULL, - .get_config = yas530_get_config, - .name = "yas530", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_YAS530, - .read_reg = 0x06, - .read_len = 6, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {3276, 8001}, - .trigger = NULL, -}; - -static -struct ext_slave_descr *yas530_get_slave_descr(void) -{ - return &yas530_descr; -} - -/* -------------------------------------------------------------------------- */ -struct yas530_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int yas530_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct yas530_mod_private_data *private_data; - int result = 0; - - 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; - 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, - yas530_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 yas530_mod_remove(struct i2c_client *client) -{ - struct yas530_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, - yas530_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id yas530_mod_id[] = { - { "yas530", COMPASS_ID_YAS530 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, yas530_mod_id); - -static struct i2c_driver yas530_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = yas530_mod_probe, - .remove = yas530_mod_remove, - .id_table = yas530_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "yas530_mod", - }, - .address_list = normal_i2c, -}; - -static int __init yas530_mod_init(void) -{ - int res = i2c_add_driver(&yas530_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "yas530_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit yas530_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&yas530_mod_driver); -} - -module_init(yas530_mod_init); -module_exit(yas530_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate YAS530 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("yas530_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/yas530_ext.c b/drivers/misc/inv_mpu/compass/yas530_ext.c deleted file mode 100644 index 7a64258..0000000 --- a/drivers/misc/inv_mpu/compass/yas530_ext.c +++ /dev/null @@ -1,288 +0,0 @@ -#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/module.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" - -struct yas530_ext_private_data { - int flags; - char offsets[3]; - const int *correction_matrix; -}; - - -extern int geomagnetic_api_read(int *xyz, int *raw, int *xy1y2, int *accuracy); -extern int geomagnetic_api_resume(void); -extern int geomagnetic_api_suspend(void); - - -static int yas530_ext_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - geomagnetic_api_suspend(); - - return result; -} - - -static int yas530_ext_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - - struct yas530_ext_private_data *private_data = pdata->private_data; - - geomagnetic_api_resume(); - - return result; -} - -static int yas530_ext_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result = INV_SUCCESS; - int raw[3] = {0,}; - int xyz[3] = {0,}; - int accuracy = 0; - int i = 0; - short xyz_scaled[3] = {0,}; - - geomagnetic_api_read(xyz, raw, NULL, &accuracy); - - xyz_scaled[0] = (short)(xyz[0]/100); - xyz_scaled[1] = (short)(xyz[1]/100); - xyz_scaled[2] = (short)(xyz[2]/100); - - data[0] = xyz_scaled[0] >> 8; - data[1] = xyz_scaled[0] & 0xFF; - data[2] = xyz_scaled[1] >> 8; - data[3] = xyz_scaled[1] & 0xFF; - data[4] = xyz_scaled[2] >> 8; - data[5] = xyz_scaled[2] & 0xFF; - data[6] = (unsigned char)accuracy; - - - return result; - -} - -static int yas530_ext_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - int result = INV_SUCCESS; - struct yas530_private_data *private_data = pdata->private_data; - - - return result; - -} - - -static int yas530_ext_get_config(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config *data) -{ - int result = INV_SUCCESS; - struct yas530_ext_private_data *private_data = pdata->private_data; - - switch (data->key) - { - default: - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - } - return result; -} - -static int yas530_ext_init(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - - struct yas530_ext_private_data *private_data; - int result = INV_SUCCESS; - char offset[3] = {0, 0, 0}; - - private_data = (struct yas530_ext_private_data *) - kzalloc(sizeof(struct yas530_ext_private_data), GFP_KERNEL); - - if (!private_data) - return INV_ERROR_MEMORY_EXAUSTED; - - private_data->correction_matrix = pdata->private_data; - - pdata->private_data = private_data; - - return result; -} - -static int yas530_ext_exit(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - kfree(pdata->private_data); - return INV_SUCCESS; -} - -static struct ext_slave_descr yas530_ext_descr = { - .init = yas530_ext_init, - .exit = yas530_ext_exit, - .suspend = yas530_ext_suspend, - .resume = yas530_ext_resume, - .read = yas530_ext_read, - .config = yas530_ext_config, - .get_config = yas530_ext_get_config, - .name = "yas530ext", - .type = EXT_SLAVE_TYPE_COMPASS, - .id = COMPASS_ID_YAS530_EXT, - .read_reg = 0x06, - .read_len = 7, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {3276, 8001}, - .trigger = NULL, -}; - - -struct ext_slave_descr *yas530_ext_get_slave_descr(void) -{ - return &yas530_ext_descr; -} - -/* -------------------------------------------------------------------------- */ -struct yas530_ext_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int yas530_ext_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct yas530_ext_mod_private_data *private_data; - int result = 0; - - 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; - 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, - yas530_ext_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 yas530_ext_mod_remove(struct i2c_client *client) -{ - struct yas530_ext_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, - yas530_ext_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id yas530_ext_mod_id[] = { - { "yas530ext", COMPASS_ID_YAS530_EXT}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, yas530_ext_mod_id); - -static struct i2c_driver yas530_ext_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = yas530_ext_mod_probe, - .remove = yas530_ext_mod_remove, - .id_table = yas530_ext_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "yas530_ext_mod", - }, - .address_list = normal_i2c, -}; - -static int __init yas530_ext_mod_init(void) -{ - int res = i2c_add_driver(&yas530_ext_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "yas530_ext_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit yas530_ext_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&yas530_ext_mod_driver); -} - -module_init(yas530_ext_mod_init); -module_exit(yas530_ext_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate YAS530 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("yas530_ext_mod"); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/compass/yas530_ext.h b/drivers/misc/inv_mpu/compass/yas530_ext.h deleted file mode 100644 index 0c343ec..0000000 --- a/drivers/misc/inv_mpu/compass/yas530_ext.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - $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/>. - $ - */ - - -#ifndef __YAS530_EXT_H__ -#define __YAS530_EXT_H__ - -#include <linux/mpu.h> - -struct ext_slave_descr *yas530_ext_get_slave_descr(void); - -#endif diff --git a/drivers/misc/inv_mpu/log.h b/drivers/misc/inv_mpu/log.h deleted file mode 100644 index 5630602e..0000000 --- a/drivers/misc/inv_mpu/log.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - $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/>. - $ - */ - -/* - * This file incorporates work covered by the following copyright and - * permission notice: - * - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * C/C++ logging functions. See the logging documentation for API details. - * - * We'd like these to be available from C code (in case we import some from - * somewhere), so this has a C interface. - * - * The output will be correct when the log file is shared between multiple - * threads and/or multiple processes so long as the operating system - * supports O_APPEND. These calls have mutex-protected data structures - * and so are NOT reentrant. Do not use MPL_LOG in a signal handler. - */ -#ifndef _LIBS_CUTILS_MPL_LOG_H -#define _LIBS_CUTILS_MPL_LOG_H - -#include "mltypes.h" -#include <stdarg.h> - - -#include <linux/kernel.h> - - -/* --------------------------------------------------------------------- */ - -/* - * Normally we strip MPL_LOGV (VERBOSE messages) from release builds. - * You can modify this (for example with "#define MPL_LOG_NDEBUG 0" - * at the top of your source file) to change that behavior. - */ -#ifndef MPL_LOG_NDEBUG -#ifdef NDEBUG -#define MPL_LOG_NDEBUG 1 -#else -#define MPL_LOG_NDEBUG 0 -#endif -#endif - -#define MPL_LOG_UNKNOWN MPL_LOG_VERBOSE -#define MPL_LOG_DEFAULT KERN_DEFAULT -#define MPL_LOG_VERBOSE KERN_CONT -#define MPL_LOG_DEBUG KERN_NOTICE -#define MPL_LOG_INFO KERN_INFO -#define MPL_LOG_WARN KERN_WARNING -#define MPL_LOG_ERROR KERN_ERR -#define MPL_LOG_SILENT MPL_LOG_VERBOSE - - - -/* - * This is the local tag used for the following simplified - * logging macros. You can change this preprocessor definition - * before using the other macros to change the tag. - */ -#ifndef MPL_LOG_TAG -#define MPL_LOG_TAG -#endif - -/* --------------------------------------------------------------------- */ - -/* - * Simplified macro to send a verbose log message using the current MPL_LOG_TAG. - */ -#ifndef MPL_LOGV -#if MPL_LOG_NDEBUG -#define MPL_LOGV(fmt, ...) \ - do { \ - if (0) \ - MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__);\ - } while (0) -#else -#define MPL_LOGV(fmt, ...) MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) -#endif -#endif - -#ifndef CONDITION -#define CONDITION(cond) ((cond) != 0) -#endif - -#ifndef MPL_LOGV_IF -#if MPL_LOG_NDEBUG -#define MPL_LOGV_IF(cond, fmt, ...) \ - do { if (0) MPL_LOG(fmt, ##__VA_ARGS__); } while (0) -#else -#define MPL_LOGV_IF(cond, fmt, ...) \ - ((CONDITION(cond)) \ - ? MPL_LOG(LOG_VERBOSE, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ - : (void)0) -#endif -#endif - -/* - * Simplified macro to send a debug log message using the current MPL_LOG_TAG. - */ -#ifndef MPL_LOGD -#define MPL_LOGD(fmt, ...) MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) -#endif - -#ifndef MPL_LOGD_IF -#define MPL_LOGD_IF(cond, fmt, ...) \ - ((CONDITION(cond)) \ - ? MPL_LOG(LOG_DEBUG, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ - : (void)0) -#endif - -/* - * Simplified macro to send an info log message using the current MPL_LOG_TAG. - */ -#ifndef MPL_LOGI -#define MPL_LOGI(fmt, ...) pr_info(KERN_INFO MPL_LOG_TAG fmt, ##__VA_ARGS__) -#endif - -#ifndef MPL_LOGI_IF -#define MPL_LOGI_IF(cond, fmt, ...) \ - ((CONDITION(cond)) \ - ? MPL_LOG(LOG_INFO, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ - : (void)0) -#endif - -/* - * Simplified macro to send a warning log message using the current MPL_LOG_TAG. - */ -#ifndef MPL_LOGW -#define MPL_LOGW(fmt, ...) printk(KERN_WARNING MPL_LOG_TAG fmt, ##__VA_ARGS__) -#endif - -#ifndef MPL_LOGW_IF -#define MPL_LOGW_IF(cond, fmt, ...) \ - ((CONDITION(cond)) \ - ? MPL_LOG(LOG_WARN, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ - : (void)0) -#endif - -/* - * Simplified macro to send an error log message using the current MPL_LOG_TAG. - */ -#ifndef MPL_LOGE -#define MPL_LOGE(fmt, ...) printk(KERN_ERR MPL_LOG_TAG fmt, ##__VA_ARGS__) -#endif - -#ifndef MPL_LOGE_IF -#define MPL_LOGE_IF(cond, fmt, ...) \ - ((CONDITION(cond)) \ - ? MPL_LOG(LOG_ERROR, MPL_LOG_TAG, fmt, ##__VA_ARGS__) \ - : (void)0) -#endif - -/* --------------------------------------------------------------------- */ - -/* - * Log a fatal error. If the given condition fails, this stops program - * execution like a normal assertion, but also generating the given message. - * It is NOT stripped from release builds. Note that the condition test - * is -inverted- from the normal assert() semantics. - */ -#define MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ...) \ - ((CONDITION(cond)) \ - ? ((void)android_printAssert(#cond, MPL_LOG_TAG, \ - fmt, ##__VA_ARGS__)) \ - : (void)0) - -#define MPL_LOG_ALWAYS_FATAL(fmt, ...) \ - (((void)android_printAssert(NULL, MPL_LOG_TAG, fmt, ##__VA_ARGS__))) - -/* - * Versions of MPL_LOG_ALWAYS_FATAL_IF and MPL_LOG_ALWAYS_FATAL that - * are stripped out of release builds. - */ -#if MPL_LOG_NDEBUG -#define MPL_LOG_FATAL_IF(cond, fmt, ...) \ - do { \ - if (0) \ - MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__); \ - } while (0) -#define MPL_LOG_FATAL(fmt, ...) \ - do { \ - if (0) \ - MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) \ - } while (0) -#else -#define MPL_LOG_FATAL_IF(cond, fmt, ...) \ - MPL_LOG_ALWAYS_FATAL_IF(cond, fmt, ##__VA_ARGS__) -#define MPL_LOG_FATAL(fmt, ...) \ - MPL_LOG_ALWAYS_FATAL(fmt, ##__VA_ARGS__) -#endif - -/* - * Assertion that generates a log message when the assertion fails. - * Stripped out of release builds. Uses the current MPL_LOG_TAG. - */ -#define MPL_LOG_ASSERT(cond, fmt, ...) \ - MPL_LOG_FATAL_IF(!(cond), fmt, ##__VA_ARGS__) - -/* --------------------------------------------------------------------- */ - -/* - * Basic log message macro. - * - * Example: - * MPL_LOG(MPL_LOG_WARN, NULL, "Failed with error %d", errno); - * - * The second argument may be NULL or "" to indicate the "global" tag. - */ -#ifndef MPL_LOG -#define MPL_LOG(priority, tag, fmt, ...) \ - MPL_LOG_PRI(priority, tag, fmt, ##__VA_ARGS__) -#endif - -/* - * Log macro that allows you to specify a number for the priority. - */ -#ifndef MPL_LOG_PRI -#define MPL_LOG_PRI(priority, tag, fmt, ...) \ - pr_debug(MPL_##priority tag fmt, ##__VA_ARGS__) -#endif - -/* - * Log macro that allows you to pass in a varargs ("args" is a va_list). - */ -#ifndef MPL_LOG_PRI_VA -/* not allowed in the Kernel because there is no dev_dbg that takes a va_list */ -#endif - -/* --------------------------------------------------------------------- */ - -/* - * =========================================================================== - * - * The stuff in the rest of this file should not be used directly. - */ - -int _MLPrintLog(int priority, const char *tag, const char *fmt, ...); -int _MLPrintVaLog(int priority, const char *tag, const char *fmt, va_list args); -/* Final implementation of actual writing to a character device */ -int _MLWriteLog(const char *buf, int buflen); - -static inline void __print_result_location(int result, - const char *file, - const char *func, int line) -{ - MPL_LOGE("%s|%s|%d returning %d\n", file, func, line, result); -} - -#define LOG_RESULT_LOCATION(condition) \ - do { \ - __print_result_location((int)(condition), __FILE__, \ - __func__, __LINE__); \ - } while (0) - - -#endif /* _LIBS_CUTILS_MPL_LOG_H */ diff --git a/drivers/misc/inv_mpu/mldl_cfg.c b/drivers/misc/inv_mpu/mldl_cfg.c deleted file mode 100644 index e2d9900..0000000 --- a/drivers/misc/inv_mpu/mldl_cfg.c +++ /dev/null @@ -1,1913 +0,0 @@ -/* - $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 MLDL - * - * @{ - * @file mldl_cfg.c - * @brief The Motion Library Driver Layer. - */ - -/* -------------------------------------------------------------------------- */ -#include <linux/delay.h> -#include <linux/slab.h> - -#include <stddef.h> - -#include "mldl_cfg.h" -#include <linux/mpu_411.h> -#include "mpu6050b1.h" - -#include "mlsl.h" -#include "mldl_print_cfg.h" -#include "log.h" -#undef MPL_LOG_TAG -#define MPL_LOG_TAG "mldl_cfg:" - -/* -------------------------------------------------------------------------- */ - -#define SLEEP 0 -#define WAKE_UP 7 -#define RESET 1 -#define STANDBY 1 - -/* -------------------------------------------------------------------------- */ - -/** - * @brief Stop the DMP running - * - * @return INV_SUCCESS or non-zero error code - */ -static int dmp_stop(struct mldl_cfg *mldl_cfg, void *gyro_handle) -{ - unsigned char user_ctrl_reg; - int result; - - if (mldl_cfg->inv_mpu_state->status & MPU_DMP_IS_SUSPENDED) - return INV_SUCCESS; - - result = inv_serial_read(gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, 1, &user_ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - user_ctrl_reg = (user_ctrl_reg & (~BIT_FIFO_EN)) | BIT_FIFO_RST; - user_ctrl_reg = (user_ctrl_reg & (~BIT_DMP_EN)) | BIT_DMP_RST; - - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, user_ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - mldl_cfg->inv_mpu_state->status |= MPU_DMP_IS_SUSPENDED; - - return result; -} - -/** - * @brief Starts the DMP running - * - * @return INV_SUCCESS or non-zero error code - */ -static int dmp_start(struct mldl_cfg *mldl_cfg, void *mlsl_handle) -{ - unsigned char user_ctrl_reg; - int result; - - if ((!(mldl_cfg->inv_mpu_state->status & MPU_DMP_IS_SUSPENDED) && - mldl_cfg->mpu_gyro_cfg->dmp_enable) - || - ((mldl_cfg->inv_mpu_state->status & MPU_DMP_IS_SUSPENDED) && - !mldl_cfg->mpu_gyro_cfg->dmp_enable)) - return INV_SUCCESS; - - result = inv_serial_read(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, 1, &user_ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, - ((user_ctrl_reg & (~BIT_FIFO_EN)) - | BIT_FIFO_RST)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, user_ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_read(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, 1, &user_ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - user_ctrl_reg |= BIT_DMP_EN; - - if (mldl_cfg->mpu_gyro_cfg->fifo_enable) - user_ctrl_reg |= BIT_FIFO_EN; - else - user_ctrl_reg &= ~BIT_FIFO_EN; - - user_ctrl_reg |= BIT_DMP_RST; - - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, user_ctrl_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - mldl_cfg->inv_mpu_state->status &= ~MPU_DMP_IS_SUSPENDED; - - return result; -} - -/** - * @brief enables/disables the I2C bypass to an external device - * connected to MPU's secondary I2C bus. - * @param enable - * Non-zero to enable pass through. - * @return INV_SUCCESS if successful, a non-zero error code otherwise. - */ -static int mpu6050b1_set_i2c_bypass(struct mldl_cfg *mldl_cfg, - void *mlsl_handle, unsigned char enable) -{ - unsigned char reg; - int result; - unsigned char status = mldl_cfg->inv_mpu_state->status; - if ((status & MPU_GYRO_IS_BYPASSED && enable) || - (!(status & MPU_GYRO_IS_BYPASSED) && !enable)) - return INV_SUCCESS; - - /*---- get current 'USER_CTRL' into b ----*/ - result = inv_serial_read(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (!enable) { - /* setting int_config with the property flag BIT_BYPASS_EN - should be done by the setup functions */ - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_INT_PIN_CFG, - (mldl_cfg->pdata->int_config & ~(BIT_BYPASS_EN))); - if (!(reg & BIT_I2C_MST_EN)) { - result = - inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, - (reg | BIT_I2C_MST_EN)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - } else if (enable) { - if (reg & BIT_AUX_IF_EN) { - result = - inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_USER_CTRL, - (reg & (~BIT_I2C_MST_EN))); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /***************************************** - * To avoid hanging the bus we must sleep until all - * slave transactions have been completed. - * 24 bytes max slave reads - * +1 byte possible extra write - * +4 max slave address - * --- - * 33 Maximum bytes - * x9 Approximate bits per byte - * --- - * 297 bits. - * 2.97 ms minimum @ 100kbps - * 0.75 ms minimum @ 400kbps. - *****************************************/ - msleep(20); - } - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_INT_PIN_CFG, - (mldl_cfg->pdata->int_config | BIT_BYPASS_EN)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - if (enable) - mldl_cfg->inv_mpu_state->status |= MPU_GYRO_IS_BYPASSED; - else - mldl_cfg->inv_mpu_state->status &= ~MPU_GYRO_IS_BYPASSED; - - return result; -} - - - - -/** - * @brief enables/disables the I2C bypass to an external device - * connected to MPU's secondary I2C bus. - * @param enable - * Non-zero to enable pass through. - * @return INV_SUCCESS if successful, a non-zero error code otherwise. - */ -static int mpu_set_i2c_bypass(struct mldl_cfg *mldl_cfg, void *mlsl_handle, - unsigned char enable) -{ - return mpu6050b1_set_i2c_bypass(mldl_cfg, mlsl_handle, enable); -} - - -#define NUM_OF_PROD_REVS (ARRAY_SIZE(prod_rev_map)) - -/* NOTE : when not indicated, product revision - is considered an 'npp'; non production part */ - -/* produces an unique identifier for each device based on the - combination of product version and product revision */ -struct prod_rev_map_t { - unsigned short mpl_product_key; - unsigned char silicon_rev; - unsigned short gyro_trim; - unsigned short accel_trim; -}; - -/* NOTE: product entries are in chronological order */ -static struct prod_rev_map_t prod_rev_map[] = { - /* prod_ver = 0 */ - {MPL_PROD_KEY(0, 1), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 2), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 3), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 4), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 5), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 6), MPU_SILICON_REV_A2, 131, 16384}, /* (A2/C2-1) */ - /* prod_ver = 1, forced to 0 for MPU6050 A2 */ - {MPL_PROD_KEY(0, 7), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 8), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 9), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 10), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 11), MPU_SILICON_REV_A2, 131, 16384}, /* (A2/D2-1) */ - {MPL_PROD_KEY(0, 12), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 13), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 14), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 15), MPU_SILICON_REV_A2, 131, 16384}, - {MPL_PROD_KEY(0, 27), MPU_SILICON_REV_A2, 131, 16384}, /* (A2/D4) */ - /* prod_ver = 1 */ - {MPL_PROD_KEY(1, 16), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/D2-1) */ - {MPL_PROD_KEY(1, 17), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/D2-2) */ - {MPL_PROD_KEY(1, 18), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/D2-3) */ - {MPL_PROD_KEY(1, 19), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/D2-4) */ - {MPL_PROD_KEY(1, 20), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/D2-5) */ - {MPL_PROD_KEY(1, 28), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/D4) */ - {MPL_PROD_KEY(1, 1), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/E1-1) */ - {MPL_PROD_KEY(1, 2), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/E1-2) */ - {MPL_PROD_KEY(1, 3), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/E1-3) */ - {MPL_PROD_KEY(1, 4), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/E1-4) */ - {MPL_PROD_KEY(1, 5), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/E1-5) */ - {MPL_PROD_KEY(1, 6), MPU_SILICON_REV_B1, 131, 16384}, /* (B1/E1-6) */ - /* prod_ver = 2 */ - {MPL_PROD_KEY(2, 7), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E1-1) */ - {MPL_PROD_KEY(2, 8), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E1-2) */ - {MPL_PROD_KEY(2, 9), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E1-3) */ - {MPL_PROD_KEY(2, 10), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E1-4) */ - {MPL_PROD_KEY(2, 11), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E1-5) */ - {MPL_PROD_KEY(2, 12), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E1-6) */ - {MPL_PROD_KEY(2, 29), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/D4) */ - /* prod_ver = 3 */ - {MPL_PROD_KEY(3, 30), MPU_SILICON_REV_B1, 131, 16384}, /* (B2/E2) */ - /* prod_ver = 4 */ - {MPL_PROD_KEY(4, 31), MPU_SILICON_REV_B1, 131, 8192}, /* (B2/F1) */ - {MPL_PROD_KEY(4, 1), MPU_SILICON_REV_B1, 131, 8192}, /* (B3/F1) */ - {MPL_PROD_KEY(4, 3), MPU_SILICON_REV_B1, 131, 8192}, /* (B4/F1) */ - /* prod_ver = 5 */ - {MPL_PROD_KEY(6, 19), MPU_SILICON_REV_B1, 131, 16384}, /* (B5/E2) */ - /* prod_ver = 7 */ - {MPL_PROD_KEY(7, 19), MPU_SILICON_REV_B1, 131, 16384}, /* (B5/E2) */ - /* prod_ver = 8 */ - {MPL_PROD_KEY(8, 19), MPU_SILICON_REV_B1, 131, 16384}, /* (B5/E2) */ - {MPL_PROD_KEY(40, 19), MPU_SILICON_REV_B1, 131, 16384} /* (B5/E2) */ -}; - -/** - * @internal - * @brief Inverse lookup of the index of an MPL product key . - * @param key - * the MPL product indentifier also referred to as 'key'. - * @return the index position of the key in the array, -1 if not found. - */ -short index_of_key(unsigned short key) -{ - int i; - pr_info("%s", __func__); - for (i = 0; i < NUM_OF_PROD_REVS; i++) - if (prod_rev_map[i].mpl_product_key == key) - return (short)i; - return -1; -} - -/** - * @internal - * @brief Get the product revision and version for MPU6050 and - * extract all per-part specific information. - * The product version number is read from the PRODUCT_ID register in - * user space register map. - * The product revision number is in read from OTP bank 0, ADDR6[7:2]. - * These 2 numbers, combined, provide an unique key to be used to - * retrieve some per-device information such as the silicon revision - * and the gyro and accel sensitivity trim values. - * - * @param mldl_cfg - * a pointer to the mldl config data structure. - * @param mlsl_handle - * an file handle to the serial communication device the - * device is connected to. - * - * @return 0 on success, a non-zero error code otherwise. - */ -static int inv_get_silicon_rev_mpu6050( - struct mldl_cfg *mldl_cfg, void *mlsl_handle) -{ - int result; - unsigned char prod_ver = 0x00, prod_rev = 0x00; - unsigned char bank = - (BIT_PRFTCH_EN | BIT_CFG_USER_BANK | MPU_MEM_OTP_BANK_0); - unsigned short memAddr = ((bank << 8) | 0x06); - unsigned short key; - short index; - struct mpu_chip_info *mpu_chip_info = mldl_cfg->mpu_chip_info; - - result = inv_serial_read(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PRODUCT_ID, 1, &prod_ver); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_serial_read_mem(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - memAddr, 1, &prod_rev); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - prod_rev >>= 2; - - /* clean the prefetch and cfg user bank bits */ - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_BANK_SEL, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - key = MPL_PROD_KEY(prod_ver, prod_rev); - if (key == 0) { - MPL_LOGE("Product id read as 0 " - "indicates device is either " - "incompatible or an MPU3050\n"); - return INV_ERROR_INVALID_MODULE; - } - pr_info("%s key=%d", __func__, key); - index = index_of_key(key); - if (index == -1 || index >= NUM_OF_PROD_REVS) { - MPL_LOGE("Unsupported product key %d in MPL\n", key); - return INV_ERROR_INVALID_MODULE; - } - /* check MPL is compiled for this device */ - if (prod_rev_map[index].silicon_rev != MPU_SILICON_REV_B1) { - MPL_LOGE("MPL compiled for MPU6050B1 support " - "but device is not MPU6050B1 (%d)\n", key); - return INV_ERROR_INVALID_MODULE; - } - - mpu_chip_info->product_id = prod_ver; - mpu_chip_info->product_revision = prod_rev; - mpu_chip_info->silicon_revision = prod_rev_map[index].silicon_rev; - mpu_chip_info->gyro_sens_trim = prod_rev_map[index].gyro_trim; - mpu_chip_info->accel_sens_trim = prod_rev_map[index].accel_trim; - - return result; -} -#define inv_get_silicon_rev inv_get_silicon_rev_mpu6050 - - -/** - * @brief Enable / Disable the use MPU's secondary I2C interface level - * shifters. - * When enabled the secondary I2C interface to which the external - * device is connected runs at VDD voltage (main supply). - * When disabled the 2nd interface runs at VDDIO voltage. - * See the device specification for more details. - * - * @note using this API may produce unpredictable results, depending on how - * the MPU and slave device are setup on the target platform. - * Use of this API should entirely be restricted to system - * integrators. Once the correct value is found, there should be no - * need to change the level shifter at runtime. - * - * @pre Must be called after inv_serial_start(). - * @note Typically called before inv_dmp_open(). - * - * @param[in] enable: - * 0 to run at VDDIO (default), - * 1 to run at VDD. - * - * @return INV_SUCCESS if successfull, a non-zero error code otherwise. - */ -static int inv_mpu_set_level_shifter_bit(struct mldl_cfg *mldl_cfg, - void *mlsl_handle, unsigned char enable) -{ - int result; - unsigned char regval; - - result = inv_serial_read(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_YG_OFFS_TC, 1, ®val); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (enable) - regval |= BIT_I2C_MST_VDDIO; - - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_YG_OFFS_TC, regval); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - return INV_SUCCESS; -} - - -/** - * @internal - * @brief MPU6050 B1 power management functions. - * @param mldl_cfg - * a pointer to the internal mldl_cfg data structure. - * @param mlsl_handle - * a file handle to the serial device used to communicate - * with the MPU6050 B1 device. - * @param reset - * 1 to reset hardware. - * @param sensors - * Bitfield of sensors to leave on - * - * @return 0 on success, a non-zero error code on error. - */ -static int mpu60xx_pwr_mgmt(struct mldl_cfg *mldl_cfg, - void *mlsl_handle, - unsigned int reset, unsigned long sensors) -{ - unsigned char pwr_mgmt[2]; - unsigned char pwr_mgmt_prev[2]; - int result; - int sleep = !(sensors & (INV_THREE_AXIS_GYRO | INV_THREE_AXIS_ACCEL - | INV_DMP_PROCESSOR)); - - if (reset) { - MPL_LOGI("Reset MPU6050 B1\n"); - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PWR_MGMT_1, BIT_H_RESET); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - mldl_cfg->inv_mpu_state->status &= ~MPU_GYRO_IS_BYPASSED; - msleep(20); - } - - /* NOTE : reading both PWR_MGMT_1 and PWR_MGMT_2 for efficiency because - they are accessible even when the device is powered off */ - result = inv_serial_read(mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PWR_MGMT_1, 2, pwr_mgmt_prev); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - pwr_mgmt[0] = pwr_mgmt_prev[0]; - pwr_mgmt[1] = pwr_mgmt_prev[1]; - - if (sleep) { - mldl_cfg->inv_mpu_state->status |= MPU_DEVICE_IS_SUSPENDED; - pwr_mgmt[0] |= BIT_SLEEP; - } else { - mldl_cfg->inv_mpu_state->status &= ~MPU_DEVICE_IS_SUSPENDED; - pwr_mgmt[0] &= ~BIT_SLEEP; - } - if (pwr_mgmt[0] != pwr_mgmt_prev[0]) { - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PWR_MGMT_1, pwr_mgmt[0]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - pwr_mgmt[1] &= ~(BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG); - if (!(sensors & INV_X_GYRO)) - pwr_mgmt[1] |= BIT_STBY_XG; - if (!(sensors & INV_Y_GYRO)) - pwr_mgmt[1] |= BIT_STBY_YG; - if (!(sensors & INV_Z_GYRO)) - pwr_mgmt[1] |= BIT_STBY_ZG; - - if (pwr_mgmt[1] != pwr_mgmt_prev[1]) { - result = inv_serial_single_write( - mlsl_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PWR_MGMT_2, pwr_mgmt[1]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - if ((pwr_mgmt[1] & (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)) == - (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)) { - mldl_cfg->inv_mpu_state->status |= MPU_GYRO_IS_SUSPENDED; - } else { - mldl_cfg->inv_mpu_state->status &= ~MPU_GYRO_IS_SUSPENDED; - } - - return INV_SUCCESS; -} - - -/** - * @brief sets the clock source for the gyros. - * @param mldl_cfg - * a pointer to the struct mldl_cfg data structure. - * @param gyro_handle - * an handle to the serial device the gyro is assigned to. - * @return ML_SUCCESS if successful, a non-zero error code otherwise. - */ -static int mpu_set_clock_source(void *gyro_handle, struct mldl_cfg *mldl_cfg) -{ - int result; - unsigned char cur_clk_src; - unsigned char reg; - - /* clock source selection */ - result = inv_serial_read(gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PWR_MGM, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - cur_clk_src = reg & BITS_CLKSEL; - reg &= ~BITS_CLKSEL; - - - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_PWR_MGM, mldl_cfg->mpu_gyro_cfg->clk_src | reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* ERRATA: - workaroud to switch from any MPU_CLK_SEL_PLLGYROx to - MPU_CLK_SEL_INTERNAL and XGyro is powered up: - 1) Select INT_OSC - 2) PD XGyro - 3) PU XGyro - */ - if ((cur_clk_src == MPU_CLK_SEL_PLLGYROX - || cur_clk_src == MPU_CLK_SEL_PLLGYROY - || cur_clk_src == MPU_CLK_SEL_PLLGYROZ) - && mldl_cfg->mpu_gyro_cfg->clk_src == MPU_CLK_SEL_INTERNAL - && mldl_cfg->inv_mpu_cfg->requested_sensors & INV_X_GYRO) { - unsigned char first_result = INV_SUCCESS; - mldl_cfg->inv_mpu_cfg->requested_sensors &= ~INV_X_GYRO; - result = mpu60xx_pwr_mgmt( - mldl_cfg, gyro_handle, - false, mldl_cfg->inv_mpu_cfg->requested_sensors); - ERROR_CHECK_FIRST(first_result, result); - mldl_cfg->inv_mpu_cfg->requested_sensors |= INV_X_GYRO; - result = mpu60xx_pwr_mgmt( - mldl_cfg, gyro_handle, - false, mldl_cfg->inv_mpu_cfg->requested_sensors); - ERROR_CHECK_FIRST(first_result, result); - result = first_result; - } - return result; -} - -/** - * Configures the MPU I2C Master - * - * @mldl_cfg Handle to the configuration data - * @gyro_handle handle to the gyro communictation interface - * @slave Can be Null if turning off the slave - * @slave_pdata Can be null if turning off the slave - * @slave_id enum ext_slave_type to determine which index to use - * - * - * This fucntion configures the slaves by: - * 1) Setting up the read - * a) Read Register - * b) Read Length - * 2) Set up the data trigger (MPU6050 only) - * a) Set trigger write register - * b) Set Trigger write value - * 3) Set up the divider (MPU6050 only) - * 4) Set the slave bypass mode depending on slave - * - * returns INV_SUCCESS or non-zero error code - */ - -static int mpu_set_slave_mpu60xx(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *slave_pdata, - int slave_id) -{ - int result; - unsigned char reg; - /* Slave values */ - unsigned char slave_reg; - unsigned char slave_len; - unsigned char slave_endian; - unsigned char slave_address; - /* Which MPU6050 registers to use */ - unsigned char addr_reg; - unsigned char reg_reg; - unsigned char ctrl_reg; - /* Which MPU6050 registers to use for the trigger */ - unsigned char addr_trig_reg; - unsigned char reg_trig_reg; - unsigned char ctrl_trig_reg; - - unsigned char bits_slave_delay = 0; - /* Divide down rate for the Slave, from the mpu rate */ - unsigned char d0_trig_reg; - unsigned char delay_ctrl_orig; - unsigned char delay_ctrl; - long divider; - - if (NULL == slave || NULL == slave_pdata) { - slave_reg = 0; - slave_len = 0; - slave_endian = 0; - slave_address = 0; - } else { - slave_reg = slave->read_reg; - slave_len = slave->read_len; - slave_endian = slave->endian; - slave_address = slave_pdata->address; - slave_address |= BIT_I2C_READ; - } - - switch (slave_id) { - case EXT_SLAVE_TYPE_ACCEL: - addr_reg = MPUREG_I2C_SLV1_ADDR; - reg_reg = MPUREG_I2C_SLV1_REG; - ctrl_reg = MPUREG_I2C_SLV1_CTRL; - addr_trig_reg = 0; - reg_trig_reg = 0; - ctrl_trig_reg = 0; - bits_slave_delay = BIT_SLV1_DLY_EN; - break; - case EXT_SLAVE_TYPE_COMPASS: - addr_reg = MPUREG_I2C_SLV0_ADDR; - reg_reg = MPUREG_I2C_SLV0_REG; - ctrl_reg = MPUREG_I2C_SLV0_CTRL; - addr_trig_reg = MPUREG_I2C_SLV2_ADDR; - reg_trig_reg = MPUREG_I2C_SLV2_REG; - ctrl_trig_reg = MPUREG_I2C_SLV2_CTRL; - d0_trig_reg = MPUREG_I2C_SLV2_DO; - bits_slave_delay = BIT_SLV2_DLY_EN | BIT_SLV0_DLY_EN; - break; - case EXT_SLAVE_TYPE_PRESSURE: - addr_reg = MPUREG_I2C_SLV3_ADDR; - reg_reg = MPUREG_I2C_SLV3_REG; - ctrl_reg = MPUREG_I2C_SLV3_CTRL; - addr_trig_reg = MPUREG_I2C_SLV4_ADDR; - reg_trig_reg = MPUREG_I2C_SLV4_REG; - ctrl_trig_reg = MPUREG_I2C_SLV4_CTRL; - bits_slave_delay = BIT_SLV4_DLY_EN | BIT_SLV3_DLY_EN; - break; - default: - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - }; - - /* return if this slave has already been set */ - if ((slave_address && - ((mldl_cfg->inv_mpu_state->i2c_slaves_enabled & bits_slave_delay) - == bits_slave_delay)) || - (!slave_address && - (mldl_cfg->inv_mpu_state->i2c_slaves_enabled & bits_slave_delay) == - 0)) - return 0; - - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, true); - - /* Address */ - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - addr_reg, slave_address); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - /* Register */ - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - reg_reg, slave_reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Length, byte swapping, grouping & enable */ - if (slave_len > BITS_SLV_LENG) { - MPL_LOGW("Limiting slave burst read length to " - "the allowed maximum (15B, req. %d)\n", slave_len); - slave_len = BITS_SLV_LENG; - return INV_ERROR_INVALID_CONFIGURATION; - } - reg = slave_len; - if (slave_endian == EXT_SLAVE_LITTLE_ENDIAN) { - reg |= BIT_SLV_BYTE_SW; - if (slave_reg & 1) - reg |= BIT_SLV_GRP; - } - if (slave_address) - reg |= BIT_SLV_ENABLE; - - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - ctrl_reg, reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Trigger */ - if (addr_trig_reg) { - /* If slave address is 0 this clears the trigger */ - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - addr_trig_reg, - slave_address & ~BIT_I2C_READ); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - if (slave && slave->trigger && reg_trig_reg) { - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - reg_trig_reg, - slave->trigger->reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - ctrl_trig_reg, - BIT_SLV_ENABLE | 0x01); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - d0_trig_reg, - slave->trigger->value); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } else if (ctrl_trig_reg) { - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - ctrl_trig_reg, 0x00); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - /* Data rate */ - if (slave) { - struct ext_slave_config config; - long data; - config.key = MPU_SLAVE_CONFIG_ODR_RESUME; - config.len = sizeof(long); - config.apply = false; - config.data = &data; - if (!(slave->get_config)) - return INV_ERROR_INVALID_CONFIGURATION; - - result = slave->get_config(NULL, slave, slave_pdata, &config); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - MPL_LOGI("Slave %d ODR: %ld Hz\n", slave_id, data / 1000); - divider = ((1000 * inv_mpu_get_sampling_rate_hz( - mldl_cfg->mpu_gyro_cfg)) - / data) - 1; - } else { - divider = 0; - } - - result = inv_serial_read(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - MPUREG_I2C_MST_DELAY_CTRL, - 1, &delay_ctrl_orig); - delay_ctrl = delay_ctrl_orig; - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (divider > 0 && divider <= MASK_I2C_MST_DLY) { - result = inv_serial_read(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - MPUREG_I2C_SLV4_CTRL, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if ((reg & MASK_I2C_MST_DLY) && - ((long)(reg & MASK_I2C_MST_DLY) != - (divider & MASK_I2C_MST_DLY))) { - MPL_LOGW("Changing slave divider: %ld to %ld\n", - (long)(reg & MASK_I2C_MST_DLY), - (divider & MASK_I2C_MST_DLY)); - - } - reg |= (unsigned char)(divider & MASK_I2C_MST_DLY); - result = inv_serial_single_write(gyro_handle, - mldl_cfg->mpu_chip_info->addr, - MPUREG_I2C_SLV4_CTRL, - reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - delay_ctrl |= bits_slave_delay; - } else { - delay_ctrl &= ~(bits_slave_delay); - } - if (delay_ctrl != delay_ctrl_orig) { - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_I2C_MST_DELAY_CTRL, - delay_ctrl); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - if (slave_address) - mldl_cfg->inv_mpu_state->i2c_slaves_enabled |= - bits_slave_delay; - else - mldl_cfg->inv_mpu_state->i2c_slaves_enabled &= - ~bits_slave_delay; - - return result; -} - -static int mpu_set_slave(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *slave_pdata, - int slave_id) -{ - return mpu_set_slave_mpu60xx(mldl_cfg, gyro_handle, slave, - slave_pdata, slave_id); -} -/** - * Check to see if the gyro was reset by testing a couple of registers known - * to change on reset. - * - * @mldl_cfg mldl configuration structure - * @gyro_handle handle used to communicate with the gyro - * - * @return INV_SUCCESS or non-zero error code - */ -static int mpu_was_reset(struct mldl_cfg *mldl_cfg, void *gyro_handle) -{ - int result = INV_SUCCESS; - unsigned char reg; - - result = inv_serial_read(gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_DMP_CFG_2, 1, ®); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (mldl_cfg->mpu_gyro_cfg->dmp_cfg2 != reg) - return true; - - if (0 != mldl_cfg->mpu_gyro_cfg->dmp_cfg1) - return false; - - /* Inconclusive assume it was reset */ - return true; -} - - -int inv_mpu_set_firmware(struct mldl_cfg *mldl_cfg, void *mlsl_handle, - const unsigned char *data, int size) -{ - int bank, offset, write_size; - int result; - unsigned char read[MPU_MEM_BANK_SIZE]; - - if (mldl_cfg->inv_mpu_state->status & MPU_DEVICE_IS_SUSPENDED) { -#if INV_CACHE_DMP == 1 - memcpy(mldl_cfg->mpu_ram->ram, data, size); - return INV_SUCCESS; -#else - LOG_RESULT_LOCATION(INV_ERROR_MEMORY_SET); - return INV_ERROR_MEMORY_SET; -#endif - } - - if (!(mldl_cfg->inv_mpu_state->status & MPU_DMP_IS_SUSPENDED)) { - LOG_RESULT_LOCATION(INV_ERROR_MEMORY_SET); - return INV_ERROR_MEMORY_SET; - } - /* Write and verify memory */ - for (bank = 0; size > 0; bank++, - size -= write_size, - data += write_size) { - if (size > MPU_MEM_BANK_SIZE) - write_size = MPU_MEM_BANK_SIZE; - else - write_size = size; - - result = inv_serial_write_mem(mlsl_handle, - mldl_cfg->mpu_chip_info->addr, - ((bank << 8) | 0x00), - write_size, - data); - if (result) { - LOG_RESULT_LOCATION(result); - MPL_LOGE("Write mem error in bank %d\n", bank); - return result; - } -#if 0 - result = inv_serial_read_mem(mlsl_handle, - mldl_cfg->mpu_chip_info->addr, - ((bank << 8) | 0x00), - write_size, - read); - if (result) { - LOG_RESULT_LOCATION(result); - MPL_LOGE("Read mem error in bank %d\n", bank); - return result; - } - -#define ML_SKIP_CHECK 38 - for (offset = 0; offset < write_size; offset++) { - /* skip the register memory locations */ - if (bank == 0 && offset < ML_SKIP_CHECK) - continue; - if (data[offset] != read[offset]) { - result = INV_ERROR_SERIAL_WRITE; - break; - } - } -#endif - if (result != INV_SUCCESS) { - LOG_RESULT_LOCATION(result); - MPL_LOGE("Read data mismatch at bank %d, offset %d\n", - bank, offset); - return result; - } - } - return INV_SUCCESS; -} - -static int gyro_resume(struct mldl_cfg *mldl_cfg, void *gyro_handle, - unsigned long sensors) -{ - int result; - int ii; - unsigned char reg; - unsigned char regs[7]; - - /* Wake up the part */ - result = mpu60xx_pwr_mgmt(mldl_cfg, gyro_handle, false, sensors); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Always set the INT_ENABLE and DIVIDER as the Accel Only mode for 6050 - can set these too */ - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_INT_ENABLE, (mldl_cfg->mpu_gyro_cfg->int_config)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_SMPLRT_DIV, mldl_cfg->mpu_gyro_cfg->divider); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (!(mldl_cfg->inv_mpu_state->status & MPU_GYRO_NEEDS_CONFIG) && - !mpu_was_reset(mldl_cfg, gyro_handle)) { - return INV_SUCCESS; - } - - /* Configure the MPU */ - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = mpu_set_clock_source(gyro_handle, mldl_cfg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - reg = MPUREG_GYRO_CONFIG_VALUE(0, 0, 0, - mldl_cfg->mpu_gyro_cfg->full_scale); - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_GYRO_CONFIG, reg); - reg = MPUREG_CONFIG_VALUE(mldl_cfg->mpu_gyro_cfg->ext_sync, - mldl_cfg->mpu_gyro_cfg->lpf); - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_CONFIG, reg); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_DMP_CFG_1, mldl_cfg->mpu_gyro_cfg->dmp_cfg1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_DMP_CFG_2, mldl_cfg->mpu_gyro_cfg->dmp_cfg2); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Write and verify memory */ -#if INV_CACHE_DMP != 0 - inv_mpu_set_firmware(mldl_cfg, gyro_handle, - mldl_cfg->mpu_ram->ram, mldl_cfg->mpu_ram->length); -#endif - - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_XG_OFFS_TC, - ((mldl_cfg->mpu_offsets->tc[0] << 1) & BITS_XG_OFFS_TC)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - regs[0] = ((mldl_cfg->mpu_offsets->tc[1] << 1) & BITS_YG_OFFS_TC); - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_YG_OFFS_TC, regs[0]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_single_write( - gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_ZG_OFFS_TC, - ((mldl_cfg->mpu_offsets->tc[2] << 1) & BITS_ZG_OFFS_TC)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - regs[0] = MPUREG_X_OFFS_USRH; - for (ii = 0; ii < ARRAY_SIZE(mldl_cfg->mpu_offsets->gyro); ii++) { - regs[1 + ii * 2] = - (unsigned char)(mldl_cfg->mpu_offsets->gyro[ii] >> 8) - & 0xff; - regs[1 + ii * 2 + 1] = - (unsigned char)(mldl_cfg->mpu_offsets->gyro[ii] & 0xff); - } - result = inv_serial_write(gyro_handle, mldl_cfg->mpu_chip_info->addr, - 7, regs); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Configure slaves */ - result = inv_mpu_set_level_shifter_bit(mldl_cfg, gyro_handle, - mldl_cfg->pdata->level_shifter); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - mldl_cfg->inv_mpu_state->status &= ~MPU_GYRO_NEEDS_CONFIG; - - return result; -} - -int gyro_config(void *mlsl_handle, - struct mldl_cfg *mldl_cfg, - struct ext_slave_config *data) -{ - struct mpu_gyro_cfg *mpu_gyro_cfg = mldl_cfg->mpu_gyro_cfg; - struct mpu_chip_info *mpu_chip_info = mldl_cfg->mpu_chip_info; - struct mpu_offsets *mpu_offsets = mldl_cfg->mpu_offsets; - int ii; - - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_INT_CONFIG: - mpu_gyro_cfg->int_config = *((__u8 *)data->data); - break; - case MPU_SLAVE_EXT_SYNC: - mpu_gyro_cfg->ext_sync = *((__u8 *)data->data); - break; - case MPU_SLAVE_FULL_SCALE: - mpu_gyro_cfg->full_scale = *((__u8 *)data->data); - break; - case MPU_SLAVE_LPF: - mpu_gyro_cfg->lpf = *((__u8 *)data->data); - break; - case MPU_SLAVE_CLK_SRC: - mpu_gyro_cfg->clk_src = *((__u8 *)data->data); - break; - case MPU_SLAVE_DIVIDER: - mpu_gyro_cfg->divider = *((__u8 *)data->data); - break; - case MPU_SLAVE_DMP_ENABLE: - mpu_gyro_cfg->dmp_enable = *((__u8 *)data->data); - break; - case MPU_SLAVE_FIFO_ENABLE: - mpu_gyro_cfg->fifo_enable = *((__u8 *)data->data); - break; - case MPU_SLAVE_DMP_CFG1: - mpu_gyro_cfg->dmp_cfg1 = *((__u8 *)data->data); - break; - case MPU_SLAVE_DMP_CFG2: - mpu_gyro_cfg->dmp_cfg2 = *((__u8 *)data->data); - break; - case MPU_SLAVE_TC: - for (ii = 0; ii < GYRO_NUM_AXES; ii++) - mpu_offsets->tc[ii] = ((__u8 *)data->data)[ii]; - break; - case MPU_SLAVE_GYRO: - for (ii = 0; ii < GYRO_NUM_AXES; ii++) - mpu_offsets->gyro[ii] = ((__u16 *)data->data)[ii]; - break; - case MPU_SLAVE_ADDR: - mpu_chip_info->addr = *((__u8 *)data->data); - break; - case MPU_SLAVE_PRODUCT_REVISION: - mpu_chip_info->product_revision = *((__u8 *)data->data); - break; - case MPU_SLAVE_SILICON_REVISION: - mpu_chip_info->silicon_revision = *((__u8 *)data->data); - break; - case MPU_SLAVE_PRODUCT_ID: - mpu_chip_info->product_id = *((__u8 *)data->data); - break; - case MPU_SLAVE_GYRO_SENS_TRIM: - mpu_chip_info->gyro_sens_trim = *((__u16 *)data->data); - break; - case MPU_SLAVE_ACCEL_SENS_TRIM: - mpu_chip_info->accel_sens_trim = *((__u16 *)data->data); - break; - case MPU_SLAVE_RAM: - if (data->len != mldl_cfg->mpu_ram->length) - return INV_ERROR_INVALID_PARAMETER; - - memcpy(mldl_cfg->mpu_ram->ram, data->data, data->len); - break; - default: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - mldl_cfg->inv_mpu_state->status |= MPU_GYRO_NEEDS_CONFIG; - return INV_SUCCESS; -} - -int gyro_get_config(void *mlsl_handle, - struct mldl_cfg *mldl_cfg, - struct ext_slave_config *data) -{ - struct mpu_gyro_cfg *mpu_gyro_cfg = mldl_cfg->mpu_gyro_cfg; - struct mpu_chip_info *mpu_chip_info = mldl_cfg->mpu_chip_info; - struct mpu_offsets *mpu_offsets = mldl_cfg->mpu_offsets; - int ii; - - if (!data->data) - return INV_ERROR_INVALID_PARAMETER; - - switch (data->key) { - case MPU_SLAVE_INT_CONFIG: - *((__u8 *)data->data) = mpu_gyro_cfg->int_config; - break; - case MPU_SLAVE_EXT_SYNC: - *((__u8 *)data->data) = mpu_gyro_cfg->ext_sync; - break; - case MPU_SLAVE_FULL_SCALE: - *((__u8 *)data->data) = mpu_gyro_cfg->full_scale; - break; - case MPU_SLAVE_LPF: - *((__u8 *)data->data) = mpu_gyro_cfg->lpf; - break; - case MPU_SLAVE_CLK_SRC: - *((__u8 *)data->data) = mpu_gyro_cfg->clk_src; - break; - case MPU_SLAVE_DIVIDER: - *((__u8 *)data->data) = mpu_gyro_cfg->divider; - break; - case MPU_SLAVE_DMP_ENABLE: - *((__u8 *)data->data) = mpu_gyro_cfg->dmp_enable; - break; - case MPU_SLAVE_FIFO_ENABLE: - *((__u8 *)data->data) = mpu_gyro_cfg->fifo_enable; - break; - case MPU_SLAVE_DMP_CFG1: - *((__u8 *)data->data) = mpu_gyro_cfg->dmp_cfg1; - break; - case MPU_SLAVE_DMP_CFG2: - *((__u8 *)data->data) = mpu_gyro_cfg->dmp_cfg2; - break; - case MPU_SLAVE_TC: - for (ii = 0; ii < GYRO_NUM_AXES; ii++) - ((__u8 *)data->data)[ii] = mpu_offsets->tc[ii]; - break; - case MPU_SLAVE_GYRO: - for (ii = 0; ii < GYRO_NUM_AXES; ii++) - ((__u16 *)data->data)[ii] = mpu_offsets->gyro[ii]; - break; - case MPU_SLAVE_ADDR: - *((__u8 *)data->data) = mpu_chip_info->addr; - break; - case MPU_SLAVE_PRODUCT_REVISION: - *((__u8 *)data->data) = mpu_chip_info->product_revision; - break; - case MPU_SLAVE_SILICON_REVISION: - *((__u8 *)data->data) = mpu_chip_info->silicon_revision; - break; - case MPU_SLAVE_PRODUCT_ID: - *((__u8 *)data->data) = mpu_chip_info->product_id; - break; - case MPU_SLAVE_GYRO_SENS_TRIM: - *((__u16 *)data->data) = mpu_chip_info->gyro_sens_trim; - break; - case MPU_SLAVE_ACCEL_SENS_TRIM: - *((__u16 *)data->data) = mpu_chip_info->accel_sens_trim; - break; - case MPU_SLAVE_RAM: - if (data->len != mldl_cfg->mpu_ram->length) - return INV_ERROR_INVALID_PARAMETER; - - memcpy(data->data, mldl_cfg->mpu_ram->ram, data->len); - break; - default: - LOG_RESULT_LOCATION(INV_ERROR_FEATURE_NOT_IMPLEMENTED); - return INV_ERROR_FEATURE_NOT_IMPLEMENTED; - }; - - return INV_SUCCESS; -} - - -/******************************************************************************* - ******************************************************************************* - * Exported functions - ******************************************************************************* - ******************************************************************************/ - -/** - * Initializes the pdata structure to defaults. - * - * Opens the device to read silicon revision, product id and whoami. - * - * @mldl_cfg - * The internal device configuration data structure. - * @mlsl_handle - * The serial communication handle. - * - * @return INV_SUCCESS if silicon revision, product id and woami are supported - * by this software. - */ -int inv_mpu_open(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - void *compass_handle, void *pressure_handle) -{ - int result; - void *slave_handle[EXT_SLAVE_NUM_TYPES]; - int ii; - - /* Default is Logic HIGH, pushpull, latch disabled, anyread to clear */ - ii = 0; - mldl_cfg->inv_mpu_cfg->ignore_system_suspend = false; - mldl_cfg->mpu_gyro_cfg->int_config = BIT_DMP_INT_EN; - mldl_cfg->mpu_gyro_cfg->clk_src = MPU_CLK_SEL_PLLGYROZ; - mldl_cfg->mpu_gyro_cfg->lpf = MPU_FILTER_42HZ; - mldl_cfg->mpu_gyro_cfg->full_scale = MPU_FS_2000DPS; - mldl_cfg->mpu_gyro_cfg->divider = 4; - mldl_cfg->mpu_gyro_cfg->dmp_enable = 1; - mldl_cfg->mpu_gyro_cfg->fifo_enable = 1; - mldl_cfg->mpu_gyro_cfg->ext_sync = 0; - mldl_cfg->mpu_gyro_cfg->dmp_cfg1 = 0; - mldl_cfg->mpu_gyro_cfg->dmp_cfg2 = 0; - mldl_cfg->inv_mpu_state->status = - MPU_DMP_IS_SUSPENDED | - MPU_GYRO_IS_SUSPENDED | - MPU_ACCEL_IS_SUSPENDED | - MPU_COMPASS_IS_SUSPENDED | - MPU_PRESSURE_IS_SUSPENDED | - MPU_DEVICE_IS_SUSPENDED; - mldl_cfg->inv_mpu_state->i2c_slaves_enabled = 0; - - slave_handle[EXT_SLAVE_TYPE_GYROSCOPE] = gyro_handle; - slave_handle[EXT_SLAVE_TYPE_ACCEL] = accel_handle; - slave_handle[EXT_SLAVE_TYPE_COMPASS] = compass_handle; - slave_handle[EXT_SLAVE_TYPE_PRESSURE] = pressure_handle; - - if (mldl_cfg->mpu_chip_info->addr == 0) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - /* - * Reset, - * Take the DMP out of sleep, and - * read the product_id, sillicon rev and whoami - */ - mldl_cfg->inv_mpu_state->status &= ~MPU_GYRO_IS_BYPASSED; - result = mpu60xx_pwr_mgmt(mldl_cfg, gyro_handle, true, - INV_THREE_AXIS_GYRO); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - result = inv_get_silicon_rev(mldl_cfg, gyro_handle); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Get the factory temperature compensation offsets */ - result = inv_serial_read(gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_XG_OFFS_TC, 1, - &mldl_cfg->mpu_offsets->tc[0]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_YG_OFFS_TC, 1, - &mldl_cfg->mpu_offsets->tc[1]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_serial_read(gyro_handle, mldl_cfg->mpu_chip_info->addr, - MPUREG_ZG_OFFS_TC, 1, - &mldl_cfg->mpu_offsets->tc[2]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Into bypass mode before sleeping and calling the slaves init */ - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, true); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = inv_mpu_set_level_shifter_bit(mldl_cfg, gyro_handle, - mldl_cfg->pdata->level_shifter); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - for (ii = 0; ii < GYRO_NUM_AXES; ii++) { - mldl_cfg->mpu_offsets->tc[ii] = - (mldl_cfg->mpu_offsets->tc[ii] & BITS_XG_OFFS_TC) >> 1; - } - -#if INV_CACHE_DMP != 0 - result = mpu60xx_pwr_mgmt(mldl_cfg, gyro_handle, false, 0); -#endif - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - - return result; - -} - -/** - * Close the mpu interface - * - * @mldl_cfg pointer to the configuration structure - * @mlsl_handle pointer to the serial layer handle - * - * @return INV_SUCCESS or non-zero error code - */ -int inv_mpu_close(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle) -{ - return 0; -} - -/** - * @brief resume the MPU device and all the other sensor - * devices from their low power state. - * - * @mldl_cfg - * pointer to the configuration structure - * @gyro_handle - * the main file handle to the MPU device. - * @accel_handle - * an handle to the accelerometer device, if sitting - * onto a separate bus. Can match mlsl_handle if - * the accelerometer device operates on the same - * primary bus of MPU. - * @compass_handle - * an handle to the compass device, if sitting - * onto a separate bus. Can match mlsl_handle if - * the compass device operates on the same - * primary bus of MPU. - * @pressure_handle - * an handle to the pressure sensor device, if sitting - * onto a separate bus. Can match mlsl_handle if - * the pressure sensor device operates on the same - * primary bus of MPU. - * @resume_gyro - * whether resuming the gyroscope device is - * actually needed (if the device supports low power - * mode of some sort). - * @resume_accel - * whether resuming the accelerometer device is - * actually needed (if the device supports low power - * mode of some sort). - * @resume_compass - * whether resuming the compass device is - * actually needed (if the device supports low power - * mode of some sort). - * @resume_pressure - * whether resuming the pressure sensor device is - * actually needed (if the device supports low power - * mode of some sort). - * @return INV_SUCCESS or a non-zero error code. - */ -int inv_mpu_resume(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle, - unsigned long sensors) -{ - int result = INV_SUCCESS; - int ii; - bool resume_slave[EXT_SLAVE_NUM_TYPES]; - bool resume_dmp = sensors & INV_DMP_PROCESSOR; - void *slave_handle[EXT_SLAVE_NUM_TYPES]; - resume_slave[EXT_SLAVE_TYPE_GYROSCOPE] = - (sensors & (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO)); - resume_slave[EXT_SLAVE_TYPE_ACCEL] = - sensors & INV_THREE_AXIS_ACCEL; - resume_slave[EXT_SLAVE_TYPE_COMPASS] = - sensors & INV_THREE_AXIS_COMPASS; - resume_slave[EXT_SLAVE_TYPE_PRESSURE] = - sensors & INV_THREE_AXIS_PRESSURE; - - slave_handle[EXT_SLAVE_TYPE_GYROSCOPE] = gyro_handle; - slave_handle[EXT_SLAVE_TYPE_ACCEL] = accel_handle; - slave_handle[EXT_SLAVE_TYPE_COMPASS] = compass_handle; - slave_handle[EXT_SLAVE_TYPE_PRESSURE] = pressure_handle; - - mldl_print_cfg(mldl_cfg); - - /* Skip the Gyro since slave[EXT_SLAVE_TYPE_GYROSCOPE] is NULL */ - for (ii = EXT_SLAVE_TYPE_ACCEL; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (resume_slave[ii] && - ((!mldl_cfg->slave[ii]) || - (!mldl_cfg->slave[ii]->resume))) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - } - - if ((resume_slave[EXT_SLAVE_TYPE_GYROSCOPE] || resume_dmp) - && ((mldl_cfg->inv_mpu_state->status & MPU_GYRO_IS_SUSPENDED) || - (mldl_cfg->inv_mpu_state->status & MPU_GYRO_NEEDS_CONFIG))) { - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = dmp_stop(mldl_cfg, gyro_handle); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = gyro_resume(mldl_cfg, gyro_handle, sensors); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!mldl_cfg->slave[ii] || - !mldl_cfg->pdata_slave[ii] || - !resume_slave[ii] || - !(mldl_cfg->inv_mpu_state->status & (1 << ii))) - continue; - - if (EXT_SLAVE_BUS_SECONDARY == - mldl_cfg->pdata_slave[ii]->bus) { - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, - true); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - result = mldl_cfg->slave[ii]->resume(slave_handle[ii], - mldl_cfg->slave[ii], - mldl_cfg->pdata_slave[ii]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - mldl_cfg->inv_mpu_state->status &= ~(1 << ii); - } - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (resume_dmp && - !(mldl_cfg->inv_mpu_state->status & (1 << ii)) && - mldl_cfg->pdata_slave[ii] && - EXT_SLAVE_BUS_SECONDARY == mldl_cfg->pdata_slave[ii]->bus) { - result = mpu_set_slave(mldl_cfg, - gyro_handle, - mldl_cfg->slave[ii], - mldl_cfg->pdata_slave[ii], - mldl_cfg->slave[ii]->type); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - } - /* Turn on the master i2c iterface if necessary */ - if (resume_dmp) { - result = mpu_set_i2c_bypass( - mldl_cfg, gyro_handle, - !(mldl_cfg->inv_mpu_state->i2c_slaves_enabled)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* Now start */ - result = dmp_start(mldl_cfg, gyro_handle); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - mldl_cfg->inv_mpu_cfg->requested_sensors = sensors; - - return result; -} - -/** - * @brief suspend the MPU device and all the other sensor - * devices into their low power state. - * @mldl_cfg - * a pointer to the struct mldl_cfg internal data - * structure. - * @gyro_handle - * the main file handle to the MPU device. - * @accel_handle - * an handle to the accelerometer device, if sitting - * onto a separate bus. Can match gyro_handle if - * the accelerometer device operates on the same - * primary bus of MPU. - * @compass_handle - * an handle to the compass device, if sitting - * onto a separate bus. Can match gyro_handle if - * the compass device operates on the same - * primary bus of MPU. - * @pressure_handle - * an handle to the pressure sensor device, if sitting - * onto a separate bus. Can match gyro_handle if - * the pressure sensor device operates on the same - * primary bus of MPU. - * @accel - * whether suspending the accelerometer device is - * actually needed (if the device supports low power - * mode of some sort). - * @compass - * whether suspending the compass device is - * actually needed (if the device supports low power - * mode of some sort). - * @pressure - * whether suspending the pressure sensor device is - * actually needed (if the device supports low power - * mode of some sort). - * @return INV_SUCCESS or a non-zero error code. - */ -int inv_mpu_suspend(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle, - unsigned long sensors) -{ - int result = INV_SUCCESS; - int ii; - struct ext_slave_descr **slave = mldl_cfg->slave; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - bool suspend_dmp = ((sensors & INV_DMP_PROCESSOR) == INV_DMP_PROCESSOR); - bool suspend_slave[EXT_SLAVE_NUM_TYPES]; - void *slave_handle[EXT_SLAVE_NUM_TYPES]; - - suspend_slave[EXT_SLAVE_TYPE_GYROSCOPE] = - ((sensors & (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO)) - == (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO)); - suspend_slave[EXT_SLAVE_TYPE_ACCEL] = - ((sensors & INV_THREE_AXIS_ACCEL) == INV_THREE_AXIS_ACCEL); - suspend_slave[EXT_SLAVE_TYPE_COMPASS] = - ((sensors & INV_THREE_AXIS_COMPASS) == INV_THREE_AXIS_COMPASS); - suspend_slave[EXT_SLAVE_TYPE_PRESSURE] = - ((sensors & INV_THREE_AXIS_PRESSURE) == - INV_THREE_AXIS_PRESSURE); - - slave_handle[EXT_SLAVE_TYPE_GYROSCOPE] = gyro_handle; - slave_handle[EXT_SLAVE_TYPE_ACCEL] = accel_handle; - slave_handle[EXT_SLAVE_TYPE_COMPASS] = compass_handle; - slave_handle[EXT_SLAVE_TYPE_PRESSURE] = pressure_handle; - - if (suspend_dmp) { - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - result = dmp_stop(mldl_cfg, gyro_handle); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - /* Gyro */ - if (suspend_slave[EXT_SLAVE_TYPE_GYROSCOPE]) { - result = mpu60xx_pwr_mgmt(mldl_cfg, gyro_handle, false, - ((~sensors) & INV_ALL_SENSORS)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - bool is_suspended = mldl_cfg->inv_mpu_state->status & (1 << ii); - if (!slave[ii] || !pdata_slave[ii] || - is_suspended || !suspend_slave[ii]) - continue; - - if (EXT_SLAVE_BUS_SECONDARY == pdata_slave[ii]->bus) { - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - result = slave[ii]->suspend(slave_handle[ii], - slave[ii], - pdata_slave[ii]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - if (EXT_SLAVE_BUS_SECONDARY == pdata_slave[ii]->bus) { - result = mpu_set_slave(mldl_cfg, gyro_handle, - NULL, NULL, - slave[ii]->type); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - mldl_cfg->inv_mpu_state->status |= (1 << ii); - } - - /* Re-enable the i2c master if there are configured slaves and DMP */ - if (!suspend_dmp) { - result = mpu_set_i2c_bypass( - mldl_cfg, gyro_handle, - !(mldl_cfg->inv_mpu_state->i2c_slaves_enabled)); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - mldl_cfg->inv_mpu_cfg->requested_sensors = (~sensors) & INV_ALL_SENSORS; - - return result; -} - -int inv_mpu_slave_read(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *slave_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result; - int bypass_result; - int remain_bypassed = true; - - if (NULL == slave || NULL == slave->read) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_CONFIGURATION); - return INV_ERROR_INVALID_CONFIGURATION; - } - - if ((EXT_SLAVE_BUS_SECONDARY == pdata->bus) - && (!(mldl_cfg->inv_mpu_state->status & MPU_GYRO_IS_BYPASSED))) { - remain_bypassed = false; - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - result = slave->read(slave_handle, slave, pdata, data); - - if (!remain_bypassed) { - bypass_result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 0); - if (bypass_result) { - LOG_RESULT_LOCATION(bypass_result); - return bypass_result; - } - } - return result; -} - -int inv_mpu_slave_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *slave_handle, - struct ext_slave_config *data, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - int remain_bypassed = true; - - if (NULL == slave || NULL == slave->config) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_CONFIGURATION); - return INV_ERROR_INVALID_CONFIGURATION; - } - - if (data->apply && (EXT_SLAVE_BUS_SECONDARY == pdata->bus) - && (!(mldl_cfg->inv_mpu_state->status & MPU_GYRO_IS_BYPASSED))) { - remain_bypassed = false; - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - result = slave->config(slave_handle, slave, pdata, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (!remain_bypassed) { - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -int inv_mpu_get_slave_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *slave_handle, - struct ext_slave_config *data, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - int remain_bypassed = true; - - if (NULL == slave || NULL == slave->get_config) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_CONFIGURATION); - return INV_ERROR_INVALID_CONFIGURATION; - } - - if (data->apply && (EXT_SLAVE_BUS_SECONDARY == pdata->bus) - && (!(mldl_cfg->inv_mpu_state->status & MPU_GYRO_IS_BYPASSED))) { - remain_bypassed = false; - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 1); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - - result = slave->get_config(slave_handle, slave, pdata, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - if (!remain_bypassed) { - result = mpu_set_i2c_bypass(mldl_cfg, gyro_handle, 0); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - } - return result; -} - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/mldl_cfg.h b/drivers/misc/inv_mpu/mldl_cfg.h deleted file mode 100644 index 1d676a9..0000000 --- a/drivers/misc/inv_mpu/mldl_cfg.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - $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 MLDL - * - * @{ - * @file mldl_cfg.h - * @brief The Motion Library Driver Layer Configuration header file. - */ - -#ifndef __MLDL_CFG_H__ -#define __MLDL_CFG_H__ - -#include "mltypes.h" -#include "mlsl.h" -#include <linux/mpu_411.h> -#include "mpu6050b1.h" - -#include "log.h" - -/************************************************************************* - * Sensors Bit definitions - *************************************************************************/ - -#define INV_X_GYRO (0x0001) -#define INV_Y_GYRO (0x0002) -#define INV_Z_GYRO (0x0004) -#define INV_DMP_PROCESSOR (0x0008) - -#define INV_X_ACCEL (0x0010) -#define INV_Y_ACCEL (0x0020) -#define INV_Z_ACCEL (0x0040) - -#define INV_X_COMPASS (0x0080) -#define INV_Y_COMPASS (0x0100) -#define INV_Z_COMPASS (0x0200) - -#define INV_X_PRESSURE (0x0300) -#define INV_Y_PRESSURE (0x0800) -#define INV_Z_PRESSURE (0x1000) - -#define INV_TEMPERATURE (0x2000) -#define INV_TIME (0x4000) - -#define INV_THREE_AXIS_GYRO (0x000F) -#define INV_THREE_AXIS_ACCEL (0x0070) -#define INV_THREE_AXIS_COMPASS (0x0380) -#define INV_THREE_AXIS_PRESSURE (0x1C00) - -#define INV_FIVE_AXIS (0x007B) -#define INV_SIX_AXIS_GYRO_ACCEL (0x007F) -#define INV_SIX_AXIS_ACCEL_COMPASS (0x03F0) -#define INV_NINE_AXIS (0x03FF) -#define INV_ALL_SENSORS (0x7FFF) - -#define MPL_PROD_KEY(ver, rev) (ver * 100 + rev) - -/* -------------------------------------------------------------------------- */ -struct mpu_ram { - __u16 length; - __u8 *ram; -}; - -struct mpu_gyro_cfg { - __u8 int_config; - __u8 ext_sync; - __u8 full_scale; - __u8 lpf; - __u8 clk_src; - __u8 divider; - __u8 dmp_enable; - __u8 fifo_enable; - __u8 dmp_cfg1; - __u8 dmp_cfg2; -}; - -/* Offset registers that can be calibrated */ -struct mpu_offsets { - __u8 tc[GYRO_NUM_AXES]; - __u16 gyro[GYRO_NUM_AXES]; -}; - -/* Chip related information that can be read and verified */ -struct mpu_chip_info { - __u8 addr; - __u8 product_revision; - __u8 silicon_revision; - __u8 product_id; - __u16 gyro_sens_trim; - /* Only used for MPU6050 */ - __u16 accel_sens_trim; -}; - - -struct inv_mpu_cfg { - __u32 requested_sensors; - __u8 ignore_system_suspend; -}; - -#define MPU_GYRO_IS_SUSPENDED (0x01 << EXT_SLAVE_TYPE_GYROSCOPE) -#define MPU_ACCEL_IS_SUSPENDED (0x01 << EXT_SLAVE_TYPE_ACCEL) -#define MPU_COMPASS_IS_SUSPENDED (0x01 << EXT_SLAVE_TYPE_COMPASS) -#define MPU_PRESSURE_IS_SUSPENDED (0x01 << EXT_SLAVE_TYPE_PRESSURE) -#define MPU_GYRO_IS_BYPASSED (0x10) -#define MPU_DMP_IS_SUSPENDED (0x20) -#define MPU_GYRO_NEEDS_CONFIG (0x40) -#define MPU_DEVICE_IS_SUSPENDED (0x80) - -/* Driver related state information */ -struct inv_mpu_state { - __u8 status; - /* 0-1 for 3050, bitfield of BIT_SLVx_DLY_EN, x = [0..4] */ - __u8 i2c_slaves_enabled; -}; - -/* Platform data for the MPU */ -struct mldl_cfg { - struct mpu_ram *mpu_ram; - struct mpu_gyro_cfg *mpu_gyro_cfg; - struct mpu_offsets *mpu_offsets; - struct mpu_chip_info *mpu_chip_info; - - /* MPU Related stored status and info */ - struct inv_mpu_cfg *inv_mpu_cfg; - struct inv_mpu_state *inv_mpu_state; - - /* Slave related information */ - struct ext_slave_descr *slave[EXT_SLAVE_NUM_TYPES]; - /* Platform Data */ - struct mpu_platform_data *pdata; - struct ext_slave_platform_data *pdata_slave[EXT_SLAVE_NUM_TYPES]; -}; - -/* -------------------------------------------------------------------------- */ - -int inv_mpu_open(struct mldl_cfg *mldl_cfg, - void *mlsl_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle); -int inv_mpu_close(struct mldl_cfg *mldl_cfg, - void *mlsl_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle); -int inv_mpu_resume(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle, - unsigned long sensors); -int inv_mpu_suspend(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - void *compass_handle, - void *pressure_handle, - unsigned long sensors); -int inv_mpu_set_firmware(struct mldl_cfg *mldl_cfg, - void *mlsl_handle, - const unsigned char *data, - int size); - -/* -------------------------------------------------------------------------- */ -/* Slave Read functions */ -int inv_mpu_slave_read(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *slave_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data); -static inline int inv_mpu_read_accel(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, unsigned char *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_slave_read( - mldl_cfg, gyro_handle, accel_handle, - mldl_cfg->slave[EXT_SLAVE_TYPE_ACCEL], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_ACCEL], - data); -} - -static inline int inv_mpu_read_compass(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *compass_handle, - unsigned char *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_slave_read( - mldl_cfg, gyro_handle, compass_handle, - mldl_cfg->slave[EXT_SLAVE_TYPE_COMPASS], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_COMPASS], - data); -} - -static inline int inv_mpu_read_pressure(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *pressure_handle, - unsigned char *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_slave_read( - mldl_cfg, gyro_handle, pressure_handle, - mldl_cfg->slave[EXT_SLAVE_TYPE_PRESSURE], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_PRESSURE], - data); -} - -int gyro_config(void *mlsl_handle, - struct mldl_cfg *mldl_cfg, - struct ext_slave_config *data); - -/* Slave Config functions */ -int inv_mpu_slave_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *slave_handle, - struct ext_slave_config *data, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata); -static inline int inv_mpu_config_accel(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - struct ext_slave_config *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_slave_config( - mldl_cfg, gyro_handle, accel_handle, data, - mldl_cfg->slave[EXT_SLAVE_TYPE_ACCEL], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_ACCEL]); -} - -static inline int inv_mpu_config_compass(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *compass_handle, - struct ext_slave_config *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_slave_config( - mldl_cfg, gyro_handle, compass_handle, data, - mldl_cfg->slave[EXT_SLAVE_TYPE_COMPASS], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_COMPASS]); -} - -static inline int inv_mpu_config_pressure(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *pressure_handle, - struct ext_slave_config *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_slave_config( - mldl_cfg, gyro_handle, pressure_handle, data, - mldl_cfg->slave[EXT_SLAVE_TYPE_PRESSURE], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_PRESSURE]); -} - -int gyro_get_config(void *mlsl_handle, - struct mldl_cfg *mldl_cfg, - struct ext_slave_config *data); - -/* Slave get config functions */ -int inv_mpu_get_slave_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *slave_handle, - struct ext_slave_config *data, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata); - -static inline int inv_mpu_get_accel_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *accel_handle, - struct ext_slave_config *data) -{ - if (!mldl_cfg) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_get_slave_config( - mldl_cfg, gyro_handle, accel_handle, data, - mldl_cfg->slave[EXT_SLAVE_TYPE_ACCEL], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_ACCEL]); -} - -static inline int inv_mpu_get_compass_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *compass_handle, - struct ext_slave_config *data) -{ - if (!mldl_cfg || !(mldl_cfg->pdata)) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_get_slave_config( - mldl_cfg, gyro_handle, compass_handle, data, - mldl_cfg->slave[EXT_SLAVE_TYPE_COMPASS], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_COMPASS]); -} - -static inline int inv_mpu_get_pressure_config(struct mldl_cfg *mldl_cfg, - void *gyro_handle, - void *pressure_handle, - struct ext_slave_config *data) -{ - if (!mldl_cfg || !(mldl_cfg->pdata)) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - return inv_mpu_get_slave_config( - mldl_cfg, gyro_handle, pressure_handle, data, - mldl_cfg->slave[EXT_SLAVE_TYPE_PRESSURE], - mldl_cfg->pdata_slave[EXT_SLAVE_TYPE_PRESSURE]); -} - -/* -------------------------------------------------------------------------- */ - -static inline -long inv_mpu_get_sampling_rate_hz(struct mpu_gyro_cfg *gyro_cfg) -{ - if (((gyro_cfg->lpf) == 0) || ((gyro_cfg->lpf) == 7)) - return 8000L / (gyro_cfg->divider + 1); - else - return 1000L / (gyro_cfg->divider + 1); -} - -static inline -long inv_mpu_get_sampling_period_us(struct mpu_gyro_cfg *gyro_cfg) -{ - if (((gyro_cfg->lpf) == 0) || ((gyro_cfg->lpf) == 7)) - return (long) (1000000L * (gyro_cfg->divider + 1)) / 8000L; - else - return (long) (1000000L * (gyro_cfg->divider + 1)) / 1000L; -} - -#endif /* __MLDL_CFG_H__ */ - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/mldl_print_cfg.c b/drivers/misc/inv_mpu/mldl_print_cfg.c deleted file mode 100644 index 78d4090..0000000 --- a/drivers/misc/inv_mpu/mldl_print_cfg.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - $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 MLDL - * - * @{ - * @file mldl_print_cfg.c - * @brief The Motion Library Driver Layer. - */ - -#include <stddef.h> -#include "mldl_cfg.h" -#include "mlsl.h" -#include <linux/mpu_411.h> - -#include "log.h" -#undef MPL_LOG_TAG -#define MPL_LOG_TAG "mldl_print_cfg:" - -#undef MPL_LOG_NDEBUG -#define MPL_LOG_NDEBUG 1 - -void mldl_print_cfg(struct mldl_cfg *mldl_cfg) -{ - struct mpu_gyro_cfg *mpu_gyro_cfg = mldl_cfg->mpu_gyro_cfg; - struct mpu_offsets *mpu_offsets = mldl_cfg->mpu_offsets; - struct mpu_chip_info *mpu_chip_info = mldl_cfg->mpu_chip_info; - struct inv_mpu_cfg *inv_mpu_cfg = mldl_cfg->inv_mpu_cfg; - struct inv_mpu_state *inv_mpu_state = mldl_cfg->inv_mpu_state; - struct ext_slave_descr **slave = mldl_cfg->slave; - struct mpu_platform_data *pdata = mldl_cfg->pdata; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - /* mpu_gyro_cfg */ - 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]); - MPL_LOGV("tc[2] = %02x\n", mpu_offsets->tc[2]); - MPL_LOGV("gyro[0] = %04x\n", mpu_offsets->gyro[0]); - MPL_LOGV("gyro[1] = %04x\n", mpu_offsets->gyro[1]); - MPL_LOGV("gyro[2] = %04x\n", mpu_offsets->gyro[2]); - - /* mpu_chip_info */ - MPL_LOGV("addr = %02x\n", mldl_cfg->mpu_chip_info->addr); - - MPL_LOGV("silicon_revision = %02x\n", mpu_chip_info->silicon_revision); - 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", - inv_mpu_cfg->ignore_system_suspend); - MPL_LOGV("status = %04x\n", inv_mpu_state->status); - MPL_LOGV("i2c_slaves_enabled= %04x\n", - inv_mpu_state->i2c_slaves_enabled); - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!slave[ii]) - continue; - MPL_LOGV("SLAVE %d:\n", ii); - MPL_LOGV(" suspend = %02x\n", (int)slave[ii]->suspend); - MPL_LOGV(" resume = %02x\n", (int)slave[ii]->resume); - MPL_LOGV(" read = %02x\n", (int)slave[ii]->read); - MPL_LOGV(" type = %02x\n", slave[ii]->type); - MPL_LOGV(" reg = %02x\n", slave[ii]->read_reg); - MPL_LOGV(" len = %02x\n", slave[ii]->read_len); - MPL_LOGV(" endian = %02x\n", slave[ii]->endian); - MPL_LOGV(" range.mantissa= %02x\n", - slave[ii]->range.mantissa); - MPL_LOGV(" range.fraction= %02x\n", - slave[ii]->range.fraction); - } - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - continue; - MPL_LOGV("PDATA_SLAVE[%d]\n", ii); - MPL_LOGV(" irq = %02x\n", pdata_slave[ii]->irq); - MPL_LOGV(" adapt_num = %02x\n", pdata_slave[ii]->adapt_num); - MPL_LOGV(" bus = %02x\n", pdata_slave[ii]->bus); - MPL_LOGV(" address = %02x\n", pdata_slave[ii]->address); - MPL_LOGV(" orientation=\n" - " %2d %2d %2d\n" - " %2d %2d %2d\n" - " %2d %2d %2d\n", - pdata_slave[ii]->orientation[0], - pdata_slave[ii]->orientation[1], - pdata_slave[ii]->orientation[2], - pdata_slave[ii]->orientation[3], - pdata_slave[ii]->orientation[4], - pdata_slave[ii]->orientation[5], - pdata_slave[ii]->orientation[6], - pdata_slave[ii]->orientation[7], - pdata_slave[ii]->orientation[8]); - } - - MPL_LOGV("pdata->int_config = %02x\n", pdata->int_config); - MPL_LOGV("pdata->level_shifter = %02x\n", pdata->level_shifter); - MPL_LOGV("pdata->orientation =\n" - " %2d %2d %2d\n" - " %2d %2d %2d\n" - " %2d %2d %2d\n", - pdata->orientation[0], pdata->orientation[1], - pdata->orientation[2], pdata->orientation[3], - pdata->orientation[4], pdata->orientation[5], - pdata->orientation[6], pdata->orientation[7], - pdata->orientation[8]); -} diff --git a/drivers/misc/inv_mpu/mldl_print_cfg.h b/drivers/misc/inv_mpu/mldl_print_cfg.h deleted file mode 100644 index 2e19114..0000000 --- a/drivers/misc/inv_mpu/mldl_print_cfg.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - $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 mldl_print_cfg.h - * @brief - * - * - */ -#ifndef __MLDL_PRINT_CFG__ -#define __MLDL_PRINT_CFG__ - -#include "mldl_cfg.h" - - -void mldl_print_cfg(struct mldl_cfg *mldl_cfg); - -#endif /* __MLDL_PRINT_CFG__ */ diff --git a/drivers/misc/inv_mpu/mlsl-kernel.c b/drivers/misc/inv_mpu/mlsl-kernel.c deleted file mode 100644 index f1c228f..0000000 --- a/drivers/misc/inv_mpu/mlsl-kernel.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - $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/>. - $ - */ - -#include "mlsl.h" -#include <linux/i2c.h> -#include "log.h" -#include "mpu6050b1.h" - -static int inv_i2c_write(struct i2c_adapter *i2c_adap, - unsigned char address, - unsigned int len, unsigned char const *data) -{ - struct i2c_msg msgs[1]; - int res; - - if (!data || !i2c_adap) { - LOG_RESULT_LOCATION(-EINVAL); - return -EINVAL; - } - - msgs[0].addr = address; - msgs[0].flags = 0; /* write */ - msgs[0].buf = (unsigned char *)data; - msgs[0].len = len; - - res = i2c_transfer(i2c_adap, msgs, 1); - 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, - unsigned char address, - unsigned char reg, unsigned char value) -{ - unsigned char data[2]; - - data[0] = reg; - data[1] = value; - return inv_i2c_write(i2c_adap, address, 2, data); -} - -static int inv_i2c_read(struct i2c_adapter *i2c_adap, - unsigned char address, unsigned char reg, - unsigned int len, unsigned char *data) -{ - struct i2c_msg msgs[2]; - int res; - - if (!data || !i2c_adap) { - LOG_RESULT_LOCATION(-EINVAL); - return -EINVAL; - } - - msgs[0].addr = address; - msgs[0].flags = 0; /* write */ - msgs[0].buf = ® - msgs[0].len = 1; - - msgs[1].addr = address; - msgs[1].flags = I2C_M_RD; - msgs[1].buf = data; - msgs[1].len = len; - - res = i2c_transfer(i2c_adap, msgs, 2); - 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, - unsigned char mpu_addr, - unsigned short mem_addr, - unsigned int len, unsigned char *data) -{ - unsigned char bank[2]; - unsigned char addr[2]; - unsigned char buf; - - struct i2c_msg msgs[4]; - int res; - - if (!data || !i2c_adap) { - LOG_RESULT_LOCATION(-EINVAL); - return -EINVAL; - } - - bank[0] = MPUREG_BANK_SEL; - bank[1] = mem_addr >> 8; - - addr[0] = MPUREG_MEM_START_ADDR; - addr[1] = mem_addr & 0xFF; - - buf = MPUREG_MEM_R_W; - - /* write message */ - msgs[0].addr = mpu_addr; - msgs[0].flags = 0; - msgs[0].buf = bank; - msgs[0].len = sizeof(bank); - - msgs[1].addr = mpu_addr; - msgs[1].flags = 0; - msgs[1].buf = addr; - msgs[1].len = sizeof(addr); - - msgs[2].addr = mpu_addr; - msgs[2].flags = 0; - msgs[2].buf = &buf; - msgs[2].len = 1; - - msgs[3].addr = mpu_addr; - msgs[3].flags = I2C_M_RD; - msgs[3].buf = data; - msgs[3].len = len; - - res = i2c_transfer(i2c_adap, msgs, 4); - if (res != 4) { - if (res >= 0) - res = -EIO; - LOG_RESULT_LOCATION(res); - return res; - } else - return 0; -} - -static int mpu_memory_write(struct i2c_adapter *i2c_adap, - unsigned char mpu_addr, - unsigned short mem_addr, - unsigned int len, unsigned char const *data) -{ - unsigned char bank[2]; - unsigned char addr[2]; - unsigned char buf[513]; - - struct i2c_msg msgs[3]; - int res; - - if (!data || !i2c_adap) { - LOG_RESULT_LOCATION(-EINVAL); - return -EINVAL; - } - if (len >= (sizeof(buf) - 1)) { - LOG_RESULT_LOCATION(-ENOMEM); - return -ENOMEM; - } - - bank[0] = MPUREG_BANK_SEL; - bank[1] = mem_addr >> 8; - - addr[0] = MPUREG_MEM_START_ADDR; - addr[1] = mem_addr & 0xFF; - - buf[0] = MPUREG_MEM_R_W; - memcpy(buf + 1, data, len); - - /* write message */ - msgs[0].addr = mpu_addr; - msgs[0].flags = 0; - msgs[0].buf = bank; - msgs[0].len = sizeof(bank); - - msgs[1].addr = mpu_addr; - msgs[1].flags = 0; - msgs[1].buf = addr; - msgs[1].len = sizeof(addr); - - msgs[2].addr = mpu_addr; - msgs[2].flags = 0; - msgs[2].buf = (unsigned char *)buf; - msgs[2].len = len + 1; - - res = i2c_transfer(i2c_adap, msgs, 3); - if (res != 3) { - if (res >= 0) - res = -EIO; - LOG_RESULT_LOCATION(res); - return res; - } else - return 0; -} - -int inv_serial_single_write( - void *sl_handle, - unsigned char slave_addr, - unsigned char register_addr, - unsigned char data) -{ - return inv_i2c_write_register((struct i2c_adapter *)sl_handle, - slave_addr, register_addr, data); -} -EXPORT_SYMBOL(inv_serial_single_write); - -int inv_serial_write( - void *sl_handle, - unsigned char slave_addr, - unsigned short length, - unsigned char const *data) -{ - int result; - const unsigned short data_length = length - 1; - const unsigned char start_reg_addr = data[0]; - unsigned char i2c_write[SERIAL_MAX_TRANSFER_SIZE + 1]; - unsigned short bytes_written = 0; - - while (bytes_written < data_length) { - unsigned short this_len = min(SERIAL_MAX_TRANSFER_SIZE, - data_length - bytes_written); - if (bytes_written == 0) { - result = inv_i2c_write((struct i2c_adapter *) - sl_handle, slave_addr, - 1 + this_len, data); - } else { - /* manually increment register addr between chunks */ - i2c_write[0] = start_reg_addr + bytes_written; - memcpy(&i2c_write[1], &data[1 + bytes_written], - this_len); - result = inv_i2c_write((struct i2c_adapter *) - sl_handle, slave_addr, - 1 + this_len, i2c_write); - } - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - bytes_written += this_len; - } - return 0; -} -EXPORT_SYMBOL(inv_serial_write); - -int inv_serial_read( - void *sl_handle, - unsigned char slave_addr, - unsigned char register_addr, - unsigned short length, - unsigned char *data) -{ - int result; - unsigned short bytes_read = 0; - - if ((slave_addr & 0x7E) == DEFAULT_MPU_SLAVEADDR - && (register_addr == MPUREG_FIFO_R_W || - register_addr == MPUREG_MEM_R_W)) { - LOG_RESULT_LOCATION(INV_ERROR_INVALID_PARAMETER); - return INV_ERROR_INVALID_PARAMETER; - } - - while (bytes_read < length) { - unsigned short this_len = - min(SERIAL_MAX_TRANSFER_SIZE, length - bytes_read); - result = inv_i2c_read((struct i2c_adapter *)sl_handle, - slave_addr, register_addr + bytes_read, - this_len, &data[bytes_read]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - bytes_read += this_len; - } - return 0; -} -EXPORT_SYMBOL(inv_serial_read); - -int inv_serial_write_mem( - void *sl_handle, - unsigned char slave_addr, - unsigned short mem_addr, - unsigned short length, - unsigned char const *data) -{ - int result; - unsigned short bytes_written = 0; - - if ((mem_addr & 0xFF) + length > MPU_MEM_BANK_SIZE) { - pr_err("memory read length (%d B) extends beyond its" - " limits (%d) if started at location %d\n", length, - MPU_MEM_BANK_SIZE, mem_addr & 0xFF); - return INV_ERROR_INVALID_PARAMETER; - } - while (bytes_written < length) { - unsigned short this_len = - min(SERIAL_MAX_TRANSFER_SIZE, length - bytes_written); - result = mpu_memory_write((struct i2c_adapter *)sl_handle, - slave_addr, mem_addr + bytes_written, - this_len, &data[bytes_written]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - bytes_written += this_len; - } - return 0; -} -EXPORT_SYMBOL(inv_serial_write_mem); - -int inv_serial_read_mem( - void *sl_handle, - unsigned char slave_addr, - unsigned short mem_addr, - unsigned short length, - unsigned char *data) -{ - int result; - unsigned short bytes_read = 0; - - if ((mem_addr & 0xFF) + length > MPU_MEM_BANK_SIZE) { - printk - ("memory read length (%d B) extends beyond its limits (%d) " - "if started at location %d\n", length, - MPU_MEM_BANK_SIZE, mem_addr & 0xFF); - return INV_ERROR_INVALID_PARAMETER; - } - while (bytes_read < length) { - unsigned short this_len = - min(SERIAL_MAX_TRANSFER_SIZE, length - bytes_read); - result = - mpu_memory_read((struct i2c_adapter *)sl_handle, - slave_addr, mem_addr + bytes_read, - this_len, &data[bytes_read]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - bytes_read += this_len; - } - return 0; -} -EXPORT_SYMBOL(inv_serial_read_mem); - -int inv_serial_write_fifo( - void *sl_handle, - unsigned char slave_addr, - unsigned short length, - unsigned char const *data) -{ - int result; - unsigned char i2c_write[SERIAL_MAX_TRANSFER_SIZE + 1]; - unsigned short bytes_written = 0; - - if (length > FIFO_HW_SIZE) { - printk(KERN_ERR - "maximum fifo write length is %d\n", FIFO_HW_SIZE); - return INV_ERROR_INVALID_PARAMETER; - } - while (bytes_written < length) { - unsigned short this_len = - min(SERIAL_MAX_TRANSFER_SIZE, length - bytes_written); - i2c_write[0] = MPUREG_FIFO_R_W; - memcpy(&i2c_write[1], &data[bytes_written], this_len); - result = inv_i2c_write((struct i2c_adapter *)sl_handle, - slave_addr, this_len + 1, i2c_write); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - bytes_written += this_len; - } - return 0; -} -EXPORT_SYMBOL(inv_serial_write_fifo); - -int inv_serial_read_fifo( - void *sl_handle, - unsigned char slave_addr, - unsigned short length, - unsigned char *data) -{ - int result; - unsigned short bytes_read = 0; - - if (length > FIFO_HW_SIZE) { - printk(KERN_ERR - "maximum fifo read length is %d\n", FIFO_HW_SIZE); - return INV_ERROR_INVALID_PARAMETER; - } - while (bytes_read < length) { - unsigned short this_len = - min(SERIAL_MAX_TRANSFER_SIZE, length - bytes_read); - result = inv_i2c_read((struct i2c_adapter *)sl_handle, - slave_addr, MPUREG_FIFO_R_W, this_len, - &data[bytes_read]); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - bytes_read += this_len; - } - - return 0; -} -EXPORT_SYMBOL(inv_serial_read_fifo); - -/** - * @} - */ diff --git a/drivers/misc/inv_mpu/mlsl.h b/drivers/misc/inv_mpu/mlsl.h deleted file mode 100644 index 3fc6be9..0000000 --- a/drivers/misc/inv_mpu/mlsl.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - $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/>. - $ - */ - -#ifndef __MLSL_H__ -#define __MLSL_H__ - -/** - * @defgroup MLSL - * @brief Motion Library - Serial Layer. - * The Motion Library System Layer provides the Motion Library - * with the communication interface to the hardware. - * - * The communication interface is assumed to support serial - * transfers in burst of variable length up to - * SERIAL_MAX_TRANSFER_SIZE. - * The default value for SERIAL_MAX_TRANSFER_SIZE is 128 bytes. - * Transfers of length greater than SERIAL_MAX_TRANSFER_SIZE, will - * be subdivided in smaller transfers of length <= - * SERIAL_MAX_TRANSFER_SIZE. - * The SERIAL_MAX_TRANSFER_SIZE definition can be modified to - * overcome any host processor transfer size limitation down to - * 1 B, the minimum. - * An higher value for SERIAL_MAX_TRANSFER_SIZE will favor - * performance and efficiency while requiring higher resource usage - * (mostly buffering). A smaller value will increase overhead and - * decrease efficiency but allows to operate with more resource - * constrained processor and master serial controllers. - * The SERIAL_MAX_TRANSFER_SIZE definition can be found in the - * mlsl.h header file and master serial controllers. - * The SERIAL_MAX_TRANSFER_SIZE definition can be found in the - * mlsl.h header file. - * - * @{ - * @file mlsl.h - * @brief The Motion Library System Layer. - * - */ - -#include "mltypes.h" -#include <linux/mpu_411.h> - - -/* acceleration data */ -struct acc_data { - s16 x; - s16 y; - s16 z; -}; - -/* - * NOTE : to properly support Yamaha compass reads, - * the max transfer size should be at least 9 B. - * Length in bytes, typically a power of 2 >= 2 - */ -#define SERIAL_MAX_TRANSFER_SIZE 128 - - -/** - * inv_serial_single_write() - used to write a single byte of data. - * @sl_handle pointer to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @register_addr Register address to write. - * @data Single byte of data to write. - * - * It is called by the MPL to write a single byte of data to the MPU. - * - * returns INV_SUCCESS if successful, a non-zero error code otherwise. - */ -int inv_serial_single_write( - void *sl_handle, - unsigned char slave_addr, - unsigned char register_addr, - unsigned char data); - -/** - * inv_serial_write() - used to write multiple bytes of data to registers. - * @sl_handle a file handle to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @register_addr Register address to write. - * @length Length of burst of data. - * @data Pointer to block of data. - * - * returns INV_SUCCESS if successful, a non-zero error code otherwise. - */ -int inv_serial_write( - void *sl_handle, - unsigned char slave_addr, - unsigned short length, - unsigned char const *data); - -/** - * inv_serial_read() - used to read multiple bytes of data from registers. - * @sl_handle a file handle to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @register_addr Register address to read. - * @length Length of burst of data. - * @data Pointer to block of data. - * - * returns INV_SUCCESS == 0 if successful; a non-zero error code otherwise. - */ -int inv_serial_read( - void *sl_handle, - unsigned char slave_addr, - unsigned char register_addr, - unsigned short length, - unsigned char *data); - -/** - * inv_serial_read_mem() - used to read multiple bytes of data from the memory. - * This should be sent by I2C or SPI. - * - * @sl_handle a file handle to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @mem_addr The location in the memory to read from. - * @length Length of burst data. - * @data Pointer to block of data. - * - * returns INV_SUCCESS == 0 if successful; a non-zero error code otherwise. - */ -int inv_serial_read_mem( - void *sl_handle, - unsigned char slave_addr, - unsigned short mem_addr, - unsigned short length, - unsigned char *data); - -/** - * inv_serial_write_mem() - used to write multiple bytes of data to the memory. - * @sl_handle a file handle to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @mem_addr The location in the memory to write to. - * @length Length of burst data. - * @data Pointer to block of data. - * - * returns INV_SUCCESS == 0 if successful; a non-zero error code otherwise. - */ -int inv_serial_write_mem( - void *sl_handle, - unsigned char slave_addr, - unsigned short mem_addr, - unsigned short length, - unsigned char const *data); - -/** - * inv_serial_read_fifo() - used to read multiple bytes of data from the fifo. - * @sl_handle a file handle to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @length Length of burst of data. - * @data Pointer to block of data. - * - * returns INV_SUCCESS == 0 if successful; a non-zero error code otherwise. - */ -int inv_serial_read_fifo( - void *sl_handle, - unsigned char slave_addr, - unsigned short length, - unsigned char *data); - -/** - * inv_serial_write_fifo() - used to write multiple bytes of data to the fifo. - * @sl_handle a file handle to the serial device used for the communication. - * @slave_addr I2C slave address of device. - * @length Length of burst of data. - * @data Pointer to block of data. - * - * returns INV_SUCCESS == 0 if successful; a non-zero error code otherwise. - */ -int inv_serial_write_fifo( - void *sl_handle, - unsigned char slave_addr, - unsigned short length, - unsigned char const *data); - -/** - * @} - */ -#endif /* __MLSL_H__ */ diff --git a/drivers/misc/inv_mpu/mltypes.h b/drivers/misc/inv_mpu/mltypes.h deleted file mode 100644 index a249f93..0000000 --- a/drivers/misc/inv_mpu/mltypes.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - $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 MLERROR - * @brief Definition of the error codes used within the MPL and - * returned to the user. - * Every function tries to return a meaningful error code basing - * on the occuring error condition. The error code is numeric. - * - * The available error codes and their associated values are: - * - (0) INV_SUCCESS - * - (32) INV_ERROR - * - (22 / EINVAL) INV_ERROR_INVALID_PARAMETER - * - (1 / EPERM) INV_ERROR_FEATURE_NOT_ENABLED - * - (36) INV_ERROR_FEATURE_NOT_IMPLEMENTED - * - (38) INV_ERROR_DMP_NOT_STARTED - * - (39) INV_ERROR_DMP_STARTED - * - (40) INV_ERROR_NOT_OPENED - * - (41) INV_ERROR_OPENED - * - (19 / ENODEV) INV_ERROR_INVALID_MODULE - * - (12 / ENOMEM) INV_ERROR_MEMORY_EXAUSTED - * - (44) INV_ERROR_DIVIDE_BY_ZERO - * - (45) INV_ERROR_ASSERTION_FAILURE - * - (46) INV_ERROR_FILE_OPEN - * - (47) INV_ERROR_FILE_READ - * - (48) INV_ERROR_FILE_WRITE - * - (49) INV_ERROR_INVALID_CONFIGURATION - * - (52) INV_ERROR_SERIAL_CLOSED - * - (53) INV_ERROR_SERIAL_OPEN_ERROR - * - (54) INV_ERROR_SERIAL_READ - * - (55) INV_ERROR_SERIAL_WRITE - * - (56) INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED - * - (57) INV_ERROR_SM_TRANSITION - * - (58) INV_ERROR_SM_IMPROPER_STATE - * - (62) INV_ERROR_FIFO_OVERFLOW - * - (63) INV_ERROR_FIFO_FOOTER - * - (64) INV_ERROR_FIFO_READ_COUNT - * - (65) INV_ERROR_FIFO_READ_DATA - * - (72) INV_ERROR_MEMORY_SET - * - (82) INV_ERROR_LOG_MEMORY_ERROR - * - (83) INV_ERROR_LOG_OUTPUT_ERROR - * - (92) INV_ERROR_OS_BAD_PTR - * - (93) INV_ERROR_OS_BAD_HANDLE - * - (94) INV_ERROR_OS_CREATE_FAILED - * - (95) INV_ERROR_OS_LOCK_FAILED - * - (102) INV_ERROR_COMPASS_DATA_OVERFLOW - * - (103) INV_ERROR_COMPASS_DATA_UNDERFLOW - * - (104) INV_ERROR_COMPASS_DATA_NOT_READY - * - (105) INV_ERROR_COMPASS_DATA_ERROR - * - (107) INV_ERROR_CALIBRATION_LOAD - * - (108) INV_ERROR_CALIBRATION_STORE - * - (109) INV_ERROR_CALIBRATION_LEN - * - (110) INV_ERROR_CALIBRATION_CHECKSUM - * - (111) INV_ERROR_ACCEL_DATA_OVERFLOW - * - (112) INV_ERROR_ACCEL_DATA_UNDERFLOW - * - (113) INV_ERROR_ACCEL_DATA_NOT_READY - * - (114) INV_ERROR_ACCEL_DATA_ERROR - * - * The available warning codes and their associated values are: - * - (115) INV_WARNING_MOTION_RACE - * - (116) INV_WARNING_QUAT_TRASHED - * - * @{ - * @file mltypes.h - * @} - */ - -#ifndef MLTYPES_H -#define MLTYPES_H - -#include <linux/types.h> -#include <asm-generic/errno-base.h> - - - - -/*--------------------------- - * ML Defines - *--------------------------*/ - -#ifndef NULL -#define NULL 0 -#endif - -/* - ML Errors. - */ -#define ERROR_NAME(x) (#x) -#define ERROR_CHECK_FIRST(first, x) \ - { if (INV_SUCCESS == first) first = x; } - -#define INV_SUCCESS (0) -/* Generic Error code. Proprietary Error Codes only */ -#define INV_ERROR_BASE (0x20) -#define INV_ERROR (INV_ERROR_BASE) - -/* Compatibility and other generic error codes */ -#define INV_ERROR_INVALID_PARAMETER (EINVAL) -#define INV_ERROR_FEATURE_NOT_ENABLED (EPERM) -#define INV_ERROR_FEATURE_NOT_IMPLEMENTED (INV_ERROR_BASE + 4) -#define INV_ERROR_DMP_NOT_STARTED (INV_ERROR_BASE + 6) -#define INV_ERROR_DMP_STARTED (INV_ERROR_BASE + 7) -#define INV_ERROR_NOT_OPENED (INV_ERROR_BASE + 8) -#define INV_ERROR_OPENED (INV_ERROR_BASE + 9) -#define INV_ERROR_INVALID_MODULE (ENODEV) -#define INV_ERROR_MEMORY_EXAUSTED (ENOMEM) -#define INV_ERROR_DIVIDE_BY_ZERO (INV_ERROR_BASE + 12) -#define INV_ERROR_ASSERTION_FAILURE (INV_ERROR_BASE + 13) -#define INV_ERROR_FILE_OPEN (INV_ERROR_BASE + 14) -#define INV_ERROR_FILE_READ (INV_ERROR_BASE + 15) -#define INV_ERROR_FILE_WRITE (INV_ERROR_BASE + 16) -#define INV_ERROR_INVALID_CONFIGURATION (INV_ERROR_BASE + 17) - -/* Serial Communication */ -#define INV_ERROR_SERIAL_CLOSED (INV_ERROR_BASE + 20) -#define INV_ERROR_SERIAL_OPEN_ERROR (INV_ERROR_BASE + 21) -#define INV_ERROR_SERIAL_READ (INV_ERROR_BASE + 22) -#define INV_ERROR_SERIAL_WRITE (INV_ERROR_BASE + 23) -#define INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED (INV_ERROR_BASE + 24) - -/* SM = State Machine */ -#define INV_ERROR_SM_TRANSITION (INV_ERROR_BASE + 25) -#define INV_ERROR_SM_IMPROPER_STATE (INV_ERROR_BASE + 26) - -/* Fifo */ -#define INV_ERROR_FIFO_OVERFLOW (INV_ERROR_BASE + 30) -#define INV_ERROR_FIFO_FOOTER (INV_ERROR_BASE + 31) -#define INV_ERROR_FIFO_READ_COUNT (INV_ERROR_BASE + 32) -#define INV_ERROR_FIFO_READ_DATA (INV_ERROR_BASE + 33) - -/* Memory & Registers, Set & Get */ -#define INV_ERROR_MEMORY_SET (INV_ERROR_BASE + 40) - -#define INV_ERROR_LOG_MEMORY_ERROR (INV_ERROR_BASE + 50) -#define INV_ERROR_LOG_OUTPUT_ERROR (INV_ERROR_BASE + 51) - -/* OS interface errors */ -#define INV_ERROR_OS_BAD_PTR (INV_ERROR_BASE + 60) -#define INV_ERROR_OS_BAD_HANDLE (INV_ERROR_BASE + 61) -#define INV_ERROR_OS_CREATE_FAILED (INV_ERROR_BASE + 62) -#define INV_ERROR_OS_LOCK_FAILED (INV_ERROR_BASE + 63) - -/* Compass errors */ -#define INV_ERROR_COMPASS_DATA_OVERFLOW (INV_ERROR_BASE + 70) -#define INV_ERROR_COMPASS_DATA_UNDERFLOW (INV_ERROR_BASE + 71) -#define INV_ERROR_COMPASS_DATA_NOT_READY (INV_ERROR_BASE + 72) -#define INV_ERROR_COMPASS_DATA_ERROR (INV_ERROR_BASE + 73) - -/* Load/Store calibration */ -#define INV_ERROR_CALIBRATION_LOAD (INV_ERROR_BASE + 75) -#define INV_ERROR_CALIBRATION_STORE (INV_ERROR_BASE + 76) -#define INV_ERROR_CALIBRATION_LEN (INV_ERROR_BASE + 77) -#define INV_ERROR_CALIBRATION_CHECKSUM (INV_ERROR_BASE + 78) - -/* Accel errors */ -#define INV_ERROR_ACCEL_DATA_OVERFLOW (INV_ERROR_BASE + 79) -#define INV_ERROR_ACCEL_DATA_UNDERFLOW (INV_ERROR_BASE + 80) -#define INV_ERROR_ACCEL_DATA_NOT_READY (INV_ERROR_BASE + 81) -#define INV_ERROR_ACCEL_DATA_ERROR (INV_ERROR_BASE + 82) - -/* No Motion Warning States */ -#define INV_WARNING_MOTION_RACE (INV_ERROR_BASE + 83) -#define INV_WARNING_QUAT_TRASHED (INV_ERROR_BASE + 84) -#define INV_WARNING_GYRO_MAG (INV_ERROR_BASE + 85) - -#ifdef INV_USE_LEGACY_NAMES -#define ML_SUCCESS INV_SUCCESS -#define ML_ERROR INV_ERROR -#define ML_ERROR_INVALID_PARAMETER INV_ERROR_INVALID_PARAMETER -#define ML_ERROR_FEATURE_NOT_ENABLED INV_ERROR_FEATURE_NOT_ENABLED -#define ML_ERROR_FEATURE_NOT_IMPLEMENTED INV_ERROR_FEATURE_NOT_IMPLEMENTED -#define ML_ERROR_DMP_NOT_STARTED INV_ERROR_DMP_NOT_STARTED -#define ML_ERROR_DMP_STARTED INV_ERROR_DMP_STARTED -#define ML_ERROR_NOT_OPENED INV_ERROR_NOT_OPENED -#define ML_ERROR_OPENED INV_ERROR_OPENED -#define ML_ERROR_INVALID_MODULE INV_ERROR_INVALID_MODULE -#define ML_ERROR_MEMORY_EXAUSTED INV_ERROR_MEMORY_EXAUSTED -#define ML_ERROR_DIVIDE_BY_ZERO INV_ERROR_DIVIDE_BY_ZERO -#define ML_ERROR_ASSERTION_FAILURE INV_ERROR_ASSERTION_FAILURE -#define ML_ERROR_FILE_OPEN INV_ERROR_FILE_OPEN -#define ML_ERROR_FILE_READ INV_ERROR_FILE_READ -#define ML_ERROR_FILE_WRITE INV_ERROR_FILE_WRITE -#define ML_ERROR_INVALID_CONFIGURATION INV_ERROR_INVALID_CONFIGURATION -#define ML_ERROR_SERIAL_CLOSED INV_ERROR_SERIAL_CLOSED -#define ML_ERROR_SERIAL_OPEN_ERROR INV_ERROR_SERIAL_OPEN_ERROR -#define ML_ERROR_SERIAL_READ INV_ERROR_SERIAL_READ -#define ML_ERROR_SERIAL_WRITE INV_ERROR_SERIAL_WRITE -#define ML_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED \ - INV_ERROR_SERIAL_DEVICE_NOT_RECOGNIZED -#define ML_ERROR_SM_TRANSITION INV_ERROR_SM_TRANSITION -#define ML_ERROR_SM_IMPROPER_STATE INV_ERROR_SM_IMPROPER_STATE -#define ML_ERROR_FIFO_OVERFLOW INV_ERROR_FIFO_OVERFLOW -#define ML_ERROR_FIFO_FOOTER INV_ERROR_FIFO_FOOTER -#define ML_ERROR_FIFO_READ_COUNT INV_ERROR_FIFO_READ_COUNT -#define ML_ERROR_FIFO_READ_DATA INV_ERROR_FIFO_READ_DATA -#define ML_ERROR_MEMORY_SET INV_ERROR_MEMORY_SET -#define ML_ERROR_LOG_MEMORY_ERROR INV_ERROR_LOG_MEMORY_ERROR -#define ML_ERROR_LOG_OUTPUT_ERROR INV_ERROR_LOG_OUTPUT_ERROR -#define ML_ERROR_OS_BAD_PTR INV_ERROR_OS_BAD_PTR -#define ML_ERROR_OS_BAD_HANDLE INV_ERROR_OS_BAD_HANDLE -#define ML_ERROR_OS_CREATE_FAILED INV_ERROR_OS_CREATE_FAILED -#define ML_ERROR_OS_LOCK_FAILED INV_ERROR_OS_LOCK_FAILED -#define ML_ERROR_COMPASS_DATA_OVERFLOW INV_ERROR_COMPASS_DATA_OVERFLOW -#define ML_ERROR_COMPASS_DATA_UNDERFLOW INV_ERROR_COMPASS_DATA_UNDERFLOW -#define ML_ERROR_COMPASS_DATA_NOT_READY INV_ERROR_COMPASS_DATA_NOT_READY -#define ML_ERROR_COMPASS_DATA_ERROR INV_ERROR_COMPASS_DATA_ERROR -#define ML_ERROR_CALIBRATION_LOAD INV_ERROR_CALIBRATION_LOAD -#define ML_ERROR_CALIBRATION_STORE INV_ERROR_CALIBRATION_STORE -#define ML_ERROR_CALIBRATION_LEN INV_ERROR_CALIBRATION_LEN -#define ML_ERROR_CALIBRATION_CHECKSUM INV_ERROR_CALIBRATION_CHECKSUM -#define ML_ERROR_ACCEL_DATA_OVERFLOW INV_ERROR_ACCEL_DATA_OVERFLOW -#define ML_ERROR_ACCEL_DATA_UNDERFLOW INV_ERROR_ACCEL_DATA_UNDERFLOW -#define ML_ERROR_ACCEL_DATA_NOT_READY INV_ERROR_ACCEL_DATA_NOT_READY -#define ML_ERROR_ACCEL_DATA_ERROR INV_ERROR_ACCEL_DATA_ERROR -#endif - -/* For Linux coding compliance */ - -#endif /* MLTYPES_H */ diff --git a/drivers/misc/inv_mpu/mpu-dev.c b/drivers/misc/inv_mpu/mpu-dev.c deleted file mode 100644 index c025f50..0000000 --- a/drivers/misc/inv_mpu/mpu-dev.c +++ /dev/null @@ -1,2348 +0,0 @@ -/* - $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/>. - $ - */ -#include <linux/i2c.h> -#include <linux/i2c-dev.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/stat.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/signal.h> -#include <linux/miscdevice.h> -#include <linux/slab.h> -#include <linux/version.h> -#include <linux/pm.h> -#include <linux/mutex.h> -#include <linux/suspend.h> -#include <linux/poll.h> -#include <linux/delay.h> - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/uaccess.h> -#include <linux/io.h> - -#include "mpuirq.h" -#include "slaveirq.h" -#include "mlsl.h" -#include "mldl_cfg.h" -#include <linux/mpu_411.h> - -#include "accel/mpu6050.h" -#include "mpu-dev.h" - - -#ifdef CONFIG_INPUT_YAS_MAGNETOMETER -#include "compass/yas530_ext.h" -#endif - -#include <linux/akm8975.h> - -#ifdef CONFIG_HAS_EARLYSUSPEND -#include <linux/earlysuspend.h> -#endif - -#define MAG_VENDOR "AKM" -#define MAG_PART_ID "AK8963C" -#define MPU_VENDOR "INVENSENSE" -#define MPU_PART_ID "MPU-6050" - -#define MPU_EARLY_SUSPEND_IN_DRIVER 1 - - -#define CALIBRATION_FILE_PATH "/efs/calibration_data" -#define CALIBRATION_DATA_AMOUNT 100 - -struct acc_data cal_data = {0, 0, 0}; - - - -/* Platform data for the MPU */ -struct mpu_private_data { - struct miscdevice dev; - struct i2c_client *client; - - /* mldl_cfg data */ - struct mldl_cfg mldl_cfg; - struct mpu_ram mpu_ram; - struct mpu_gyro_cfg mpu_gyro_cfg; - struct mpu_offsets mpu_offsets; - struct mpu_chip_info mpu_chip_info; - struct inv_mpu_cfg inv_mpu_cfg; - struct inv_mpu_state inv_mpu_state; - - struct mutex mutex; - wait_queue_head_t mpu_event_wait; - struct completion completion; - struct timer_list timeout; - struct notifier_block nb; - struct mpuirq_data mpu_pm_event; - int response_timeout; - unsigned long event; - int pid; - struct module *slave_modules[EXT_SLAVE_NUM_TYPES]; - struct { - atomic_t enable; - unsigned char is_activated; - unsigned char turned_by_mpu_accel; - } mpu_accel; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; -#endif -}; - -static struct i2c_client *this_client; - -#define IDEAL_X 0 -#define IDEAL_Y 0 -#define IDEAL_Z -1024 -/*#define CAL_DIV 8*/ -static int CAL_DIV = 8; - -struct mpu_private_data *mpu_data; - -void mpu_accel_enable_set(int enable) -{ - - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - if (enable) { - mpu->mpu_accel.is_activated = - !(mldl_cfg->inv_mpu_state->status - & MPU_ACCEL_IS_SUSPENDED); - - (void)inv_mpu_resume(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - INV_THREE_AXIS_ACCEL); - - mpu->mpu_accel.turned_by_mpu_accel = 1; - } else { - if (!mpu->mpu_accel.is_activated - && mpu->mpu_accel.turned_by_mpu_accel) { - - (void)inv_mpu_suspend(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - INV_THREE_AXIS_ACCEL); - - mpu->mpu_accel.turned_by_mpu_accel = 0; - } - } - - atomic_set(&mpu->mpu_accel.enable, enable); -} - -int read_accel_raw_xyz(struct acc_data *acc) -{ - s16 x, y, z; - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - int retval = 0; - unsigned char data[6]; - - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - - retval = inv_serial_read(slave_adapter[EXT_SLAVE_TYPE_ACCEL], - 0x68, 0x3B, 6, data); - - if (mldl_cfg->mpu_chip_info->accel_sens_trim == 16384) - CAL_DIV = 16; - x = (s16)((data[0] << 8) | data[1])/CAL_DIV; - y = (s16)((data[2] << 8) | data[3])/CAL_DIV; - z = (s16)((data[4] << 8) | data[5])/CAL_DIV; - - acc->x = x; - - acc->y = y; - - acc->z = z; - - /* - pr_info("read_accel_raw_xyz acc x: %d y: %d z: %d", - acc->x,acc->y,acc->z); - */ - return 0; -} - -static int accel_open_calibration(void) -{ - struct file *cal_filp = NULL; - int err = 0; - mm_segment_t old_fs; - - old_fs = get_fs(); - set_fs(KERNEL_DS); - - cal_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666); - if (IS_ERR(cal_filp)) { - pr_err("%s: Can't open calibration file", __func__); - set_fs(old_fs); - err = PTR_ERR(cal_filp); - return err; - } - - err = cal_filp->f_op->read(cal_filp, - (char *)&cal_data, 3 * sizeof(s16), &cal_filp->f_pos); - if (err != 3 * sizeof(s16)) { - pr_err("%s: Can't read the cal data from file", __func__); - err = -EIO; - } - - pr_info("%s: (%u,%u,%u)", __func__, - cal_data.x, cal_data.y, cal_data.z); - - filp_close(cal_filp, current->files); - set_fs(old_fs); - - return err; -} - -static int accel_do_calibrate(int enable) -{ - struct acc_data data = { 0, }; - struct file *cal_filp = NULL; - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - /* struct i2c_client *client = mpu->client; */ - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - - int sum[3] = { 0, }; - int err = 0; - int i; - mm_segment_t old_fs; - - /* mutex_lock(&mpu->mutex); */ - mpu_accel_enable_set(1); - msleep(20); - - for (i = 0; i < CALIBRATION_DATA_AMOUNT; i++) { - err = read_accel_raw_xyz(&data); - if (err < 0) { - pr_err("%s: accel_read_accel_raw_xyz() " - "failed in the %dth loop", __func__, i); - return err; - } - - sum[0] += data.x; - sum[1] += data.y; - sum[2] += data.z; - } - - mpu_accel_enable_set(0); - msleep(20); - /* mutex_unlock(&mpu->mutex); */ - - if (mldl_cfg->mpu_chip_info->accel_sens_trim == 16384) - CAL_DIV = 16; - - if (enable) { - cal_data.x = ((sum[0] / CALIBRATION_DATA_AMOUNT) - - IDEAL_X)*CAL_DIV; - cal_data.y = ((sum[1] / CALIBRATION_DATA_AMOUNT) - - IDEAL_Y)*CAL_DIV; - cal_data.z = ((sum[2] / CALIBRATION_DATA_AMOUNT) - - IDEAL_Z)*CAL_DIV; - } else { - cal_data.x = 0; - cal_data.y = 0; - cal_data.z = 0; - } - - pr_info("%s: cal data (%d,%d,%d)", __func__, - cal_data.x, cal_data.y, cal_data.z); - - old_fs = get_fs(); - set_fs(KERNEL_DS); - - cal_filp = filp_open(CALIBRATION_FILE_PATH, - O_CREAT | O_TRUNC | O_WRONLY, 0666); - if (IS_ERR(cal_filp)) { - pr_err("%s: Can't open calibration file", __func__); - set_fs(old_fs); - err = PTR_ERR(cal_filp); - return err; - } - - err = cal_filp->f_op->write(cal_filp, - (char *)&cal_data, 3 * sizeof(s16), &cal_filp->f_pos); - if (err != 3 * sizeof(s16)) { - pr_err("%s: Can't write the cal data to file", __func__); - err = -EIO; - } - - filp_close(cal_filp, current->files); - set_fs(old_fs); - - return err; -} - -static void mpu_pm_timeout(u_long data) -{ - struct mpu_private_data *mpu = (struct mpu_private_data *)data; - struct i2c_client *client = mpu->client; - dev_dbg(&client->adapter->dev, "%s", __func__); - complete(&mpu->completion); -} -#if 0 -static int mpu_pm_notifier_callback(struct notifier_block *nb, - unsigned long event, void *unused) -{ - struct mpu_private_data *mpu = - container_of(nb, struct mpu_private_data, nb); - struct i2c_client *client = mpu->client; - struct timeval event_time; - dev_dbg(&client->adapter->dev, "%s: %ld", __func__, event); - - /* Prevent the file handle from being closed before we initialize - the completion event */ - pr_info("[%s] event = %ld", __func__, event); - mutex_lock(&mpu->mutex); - if (!(mpu->pid) || - (event != PM_SUSPEND_PREPARE && event != PM_POST_SUSPEND)) { - mutex_unlock(&mpu->mutex); - return NOTIFY_OK; - } - - if (event == PM_SUSPEND_PREPARE) - mpu->event = MPU_PM_EVENT_SUSPEND_PREPARE; - if (event == PM_POST_SUSPEND) - mpu->event = MPU_PM_EVENT_POST_SUSPEND; - - do_gettimeofday(&event_time); - mpu->mpu_pm_event.interruptcount++; - mpu->mpu_pm_event.irqtime = - (((long long)event_time.tv_sec) << 32) + event_time.tv_usec; - mpu->mpu_pm_event.data_type = MPUIRQ_DATA_TYPE_PM_EVENT; - mpu->mpu_pm_event.data = mpu->event; - - if (mpu->response_timeout > 0) { - mpu->timeout.expires = jiffies + mpu->response_timeout * HZ; - add_timer(&mpu->timeout); - } - INIT_COMPLETION(mpu->completion); - mutex_unlock(&mpu->mutex); - - wake_up_interruptible(&mpu->mpu_event_wait); - wait_for_completion(&mpu->completion); - del_timer_sync(&mpu->timeout); - dev_dbg(&client->adapter->dev, "%s: %ld DONE", __func__, event); - return NOTIFY_OK; -} -#endif -static int mpu_early_notifier_callback(struct mpu_private_data *mpu, - unsigned long event, void *unused) -{ - struct i2c_client *client = mpu->client; - struct timeval event_time; - dev_dbg(&client->adapter->dev, "%s: %s", __func__, - (event == MPU_PM_EVENT_SUSPEND_PREPARE) ? - "MPU_PM_EVENT_SUSPEND_PREPARE" : "MPU_PM_EVENT_POST_SUSPEND"); - - /* Prevent the file handle from being closed before we initialize - the completion event */ - pr_info("[%s] event = %ld", __func__, event); - mutex_lock(&mpu->mutex); - if (!(mpu->pid) || - (event != PM_SUSPEND_PREPARE && event != PM_POST_SUSPEND)) { - mutex_unlock(&mpu->mutex); - return NOTIFY_OK; - } - - if (event == PM_SUSPEND_PREPARE) - mpu->event = MPU_PM_EVENT_SUSPEND_PREPARE; - if (event == PM_POST_SUSPEND) - mpu->event = MPU_PM_EVENT_POST_SUSPEND; - - do_gettimeofday(&event_time); - mpu->mpu_pm_event.interruptcount++; - mpu->mpu_pm_event.irqtime = - (((long long)event_time.tv_sec) << 32) + event_time.tv_usec; - mpu->mpu_pm_event.data_type = MPUIRQ_DATA_TYPE_PM_EVENT; - mpu->mpu_pm_event.data = mpu->event; - - if (mpu->response_timeout > 0) { - mpu->timeout.expires = jiffies + mpu->response_timeout * HZ; - add_timer(&mpu->timeout); - } - INIT_COMPLETION(mpu->completion); - mutex_unlock(&mpu->mutex); - - wake_up_interruptible(&mpu->mpu_event_wait); - wait_for_completion(&mpu->completion); - del_timer_sync(&mpu->timeout); - dev_dbg(&client->adapter->dev, "%s: %s DONE", __func__, - (event == MPU_PM_EVENT_SUSPEND_PREPARE) ? - "MPU_PM_EVENT_SUSPEND_PREPARE" : "MPU_PM_EVENT_POST_SUSPEND"); - return NOTIFY_OK; -} - -static int mpu_dev_open(struct inode *inode, struct file *file) -{ - struct mpu_private_data *mpu = - container_of(file->private_data, struct mpu_private_data, dev); - struct i2c_client *client = mpu->client; - int result; - int ii; - dev_dbg(&client->adapter->dev, "%s", __func__); - dev_dbg(&client->adapter->dev, "current->pid %d", current->pid); - - accel_open_calibration(); - - result = mutex_lock_interruptible(&mpu->mutex); - if (mpu->pid) { - mutex_unlock(&mpu->mutex); - return -EBUSY; - } - mpu->pid = current->pid; - - /* Reset the sensors to the default */ - if (result) { - dev_err(&client->adapter->dev, - "%s: mutex_lock_interruptible returned %d", - __func__, result); - return result; - } - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) - __module_get(mpu->slave_modules[ii]); - - mutex_unlock(&mpu->mutex); - return 0; -} - -/* close function - called when the "file" /dev/mpu is closed in userspace */ -static int mpu_release(struct inode *inode, struct file *file) -{ - struct mpu_private_data *mpu = - container_of(file->private_data, struct mpu_private_data, dev); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - int result = 0; - int ii; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - mutex_lock(&mpu->mutex); - mldl_cfg->inv_mpu_cfg->requested_sensors = 0; - result = inv_mpu_suspend(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - INV_ALL_SENSORS); - mpu->pid = 0; - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) - module_put(mpu->slave_modules[ii]); - - mutex_unlock(&mpu->mutex); - complete(&mpu->completion); - dev_dbg(&client->adapter->dev, "mpu_release"); - - return result; -} - -/* read function called when from /dev/mpu is read. Read from the FIFO */ -static ssize_t mpu_read(struct file *file, - char __user *buf, size_t count, loff_t *offset) -{ - struct mpu_private_data *mpu = - container_of(file->private_data, struct mpu_private_data, dev); - struct i2c_client *client = mpu->client; - size_t len = sizeof(mpu->mpu_pm_event) + sizeof(unsigned long); - int err; - - if (!mpu->event && (!(file->f_flags & O_NONBLOCK))) - wait_event_interruptible(mpu->mpu_event_wait, mpu->event); - - if (!mpu->event || !buf - || count < sizeof(mpu->mpu_pm_event)) - return 0; - - err = copy_to_user(buf, &mpu->mpu_pm_event, sizeof(mpu->mpu_pm_event)); - if (err) { - dev_err(&client->adapter->dev, - "Copy to user returned %d", err); - return -EFAULT; - } - mpu->event = 0; - return len; -} - -static unsigned int mpu_poll(struct file *file, struct poll_table_struct *poll) -{ - struct mpu_private_data *mpu = - container_of(file->private_data, struct mpu_private_data, dev); - int mask = 0; - - poll_wait(file, &mpu->mpu_event_wait, poll); - if (mpu->event) - mask |= POLLIN | POLLRDNORM; - return mask; -} - -static int mpu_dev_ioctl_get_ext_slave_platform_data( - struct i2c_client *client, - struct ext_slave_platform_data __user *arg) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(client); - struct ext_slave_platform_data *pdata_slave; - struct ext_slave_platform_data local_pdata_slave; - - if (copy_from_user(&local_pdata_slave, arg, sizeof(local_pdata_slave))) - return -EFAULT; - - if (local_pdata_slave.type >= EXT_SLAVE_NUM_TYPES) - return -EINVAL; - - pdata_slave = mpu->mldl_cfg.pdata_slave[local_pdata_slave.type]; - /* All but private data and irq_data */ - if (!pdata_slave) - return -ENODEV; - if (copy_to_user(arg, pdata_slave, sizeof(*pdata_slave))) - return -EFAULT; - return 0; -} - -static int mpu_dev_ioctl_get_mpu_platform_data( - struct i2c_client *client, - struct mpu_platform_data __user *arg) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(client); - struct mpu_platform_data *pdata = mpu->mldl_cfg.pdata; - - if (copy_to_user(arg, pdata, sizeof(*pdata))) - return -EFAULT; - return 0; -} - -static int mpu_dev_ioctl_get_ext_slave_descr( - struct i2c_client *client, - struct ext_slave_descr __user *arg) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(client); - struct ext_slave_descr *slave; - struct ext_slave_descr local_slave; - - if (copy_from_user(&local_slave, arg, sizeof(local_slave))) - return -EFAULT; - - if (local_slave.type >= EXT_SLAVE_NUM_TYPES) - return -EINVAL; - - slave = mpu->mldl_cfg.slave[local_slave.type]; - /* All but private data and irq_data */ - if (!slave) - return -ENODEV; - if (copy_to_user(arg, slave, sizeof(*slave))) - return -EFAULT; - return 0; -} - - -/** - * slave_config() - Pass a requested slave configuration to the slave sensor - * - * @adapter the adaptor to use to communicate with the slave - * @mldl_cfg the mldl configuration structuer - * @slave pointer to the slave descriptor - * @usr_config The configuration to pass to the slave sensor - * - * returns 0 or non-zero error code - */ -static int inv_mpu_config(struct mldl_cfg *mldl_cfg, - void *gyro_adapter, - struct ext_slave_config __user *usr_config) -{ - int retval = 0; - struct ext_slave_config config; - - retval = copy_from_user(&config, usr_config, sizeof(config)); - if (retval) - return -EFAULT; - - if (config.len && config.data) { - void *data; - data = kmalloc(config.len, GFP_KERNEL); - if (!data) - return -ENOMEM; - - retval = copy_from_user(data, - (void __user *)config.data, config.len); - if (retval) { - retval = -EFAULT; - kfree(data); - return retval; - } - config.data = data; - } - retval = gyro_config(gyro_adapter, mldl_cfg, &config); - kfree(config.data); - return retval; -} - -static int inv_mpu_get_config(struct mldl_cfg *mldl_cfg, - void *gyro_adapter, - struct ext_slave_config __user *usr_config) -{ - int retval = 0; - struct ext_slave_config config; - void *user_data; - - retval = copy_from_user(&config, usr_config, sizeof(config)); - if (retval) - return -EFAULT; - - user_data = config.data; - if (config.len && config.data) { - void *data; - data = kmalloc(config.len, GFP_KERNEL); - if (!data) - return -ENOMEM; - - retval = copy_from_user(data, - (void __user *)config.data, config.len); - if (retval) { - retval = -EFAULT; - kfree(data); - return retval; - } - config.data = data; - } - retval = gyro_get_config(gyro_adapter, mldl_cfg, &config); - if (!retval) - retval = copy_to_user((unsigned char __user *)user_data, - config.data, config.len); - kfree(config.data); - return retval; -} - -static int slave_config(struct mldl_cfg *mldl_cfg, - void *gyro_adapter, - void *slave_adapter, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config __user *usr_config) -{ - int retval = 0; - struct ext_slave_config config; - if ((!slave) || (!slave->config)) - return -ENODEV; - - retval = copy_from_user(&config, usr_config, sizeof(config)); - if (retval) - return -EFAULT; - - if (config.len && config.data) { - void *data; - data = kmalloc(config.len, GFP_KERNEL); - if (!data) - return -ENOMEM; - - retval = copy_from_user(data, - (void __user *)config.data, config.len); - if (retval) { - retval = -EFAULT; - kfree(data); - return retval; - } - config.data = data; - } - retval = inv_mpu_slave_config(mldl_cfg, gyro_adapter, slave_adapter, - &config, slave, pdata); - kfree(config.data); - return retval; -} - -static int slave_get_config(struct mldl_cfg *mldl_cfg, - void *gyro_adapter, - void *slave_adapter, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - struct ext_slave_config __user *usr_config) -{ - int retval = 0; - struct ext_slave_config config; - void *user_data; - if (!(slave) || !(slave->get_config)) - return -ENODEV; - - retval = copy_from_user(&config, usr_config, sizeof(config)); - if (retval) - return -EFAULT; - - user_data = config.data; - if (config.len && config.data) { - void *data; - data = kmalloc(config.len, GFP_KERNEL); - if (!data) - return -ENOMEM; - - retval = copy_from_user(data, - (void __user *)config.data, config.len); - if (retval) { - retval = -EFAULT; - kfree(data); - return retval; - } - config.data = data; - } - retval = inv_mpu_get_slave_config(mldl_cfg, gyro_adapter, - slave_adapter, &config, slave, pdata); - if (retval) { - kfree(config.data); - return retval; - } - retval = copy_to_user((unsigned char __user *)user_data, - config.data, config.len); - kfree(config.data); - return retval; -} - -static int inv_slave_read(struct mldl_cfg *mldl_cfg, - void *gyro_adapter, - void *slave_adapter, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - void __user *usr_data) -{ - int retval; - unsigned char *data; - data = kzalloc(slave->read_len, GFP_KERNEL); - if (!data) - return -EFAULT; - - retval = inv_mpu_slave_read(mldl_cfg, gyro_adapter, slave_adapter, - slave, pdata, data); - - if ((!retval) && - (copy_to_user((unsigned char __user *)usr_data, - data, slave->read_len))) - retval = -EFAULT; - - kfree(data); - return retval; -} - -static int mpu_handle_mlsl(void *sl_handle, - unsigned char addr, - unsigned int cmd, - struct mpu_read_write __user *usr_msg) -{ - int retval = 0; - struct mpu_read_write msg; - unsigned char *user_data; - retval = copy_from_user(&msg, usr_msg, sizeof(msg)); - if (retval) - return -EFAULT; - - user_data = msg.data; - if (msg.length && msg.data) { - unsigned char *data; - data = kmalloc(msg.length, GFP_KERNEL); - if (!data) - return -ENOMEM; - - retval = copy_from_user(data, - (void __user *)msg.data, msg.length); - if (retval) { - retval = -EFAULT; - kfree(data); - return retval; - } - msg.data = data; - } else { - return -EPERM; - } - - switch (cmd) { - case MPU_READ: - retval = inv_serial_read(sl_handle, addr, - (unsigned char)msg.address, msg.length, msg.data); - break; - case MPU_WRITE: - retval = inv_serial_write(sl_handle, addr, - msg.length, msg.data); - break; - case MPU_READ_MEM: - retval = inv_serial_read_mem(sl_handle, addr, - msg.address, msg.length, msg.data); - break; - case MPU_WRITE_MEM: - retval = inv_serial_write_mem(sl_handle, addr, - msg.address, msg.length, - msg.data); - break; - case MPU_READ_FIFO: - retval = inv_serial_read_fifo(sl_handle, addr, - msg.length, msg.data); - break; - case MPU_WRITE_FIFO: - retval = inv_serial_write_fifo(sl_handle, addr, - msg.length, msg.data); - break; - - }; - if (retval) { - dev_err(&((struct i2c_adapter *)sl_handle)->dev, - "%s: i2c %d error %d", - __func__, cmd, retval); - kfree(msg.data); - return retval; - } - retval = copy_to_user((unsigned char __user *)user_data, - msg.data, msg.length); - kfree(msg.data); - return retval; -} - -/* ioctl - I/O control */ -static long mpu_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct mpu_private_data *mpu = - container_of(file->private_data, struct mpu_private_data, dev); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - int retval = 0; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_descr **slave = mldl_cfg->slave; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - 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(&client->adapter->dev, - "%s: mutex_lock_interruptible returned %d", - __func__, retval); - return retval; - } - - switch (cmd) { - case MPU_GET_EXT_SLAVE_PLATFORM_DATA: - retval = mpu_dev_ioctl_get_ext_slave_platform_data( - client, - (struct ext_slave_platform_data __user *)arg); - break; - case MPU_GET_MPU_PLATFORM_DATA: - retval = mpu_dev_ioctl_get_mpu_platform_data( - client, - (struct mpu_platform_data __user *)arg); - break; - case MPU_GET_EXT_SLAVE_DESCR: - retval = mpu_dev_ioctl_get_ext_slave_descr( - client, - (struct ext_slave_descr __user *)arg); - break; - case MPU_READ: - case MPU_WRITE: - case MPU_READ_MEM: - case MPU_WRITE_MEM: - case MPU_READ_FIFO: - case MPU_WRITE_FIFO: - retval = mpu_handle_mlsl( - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - mldl_cfg->mpu_chip_info->addr, cmd, - (struct mpu_read_write __user *)arg); - break; - case MPU_CONFIG_GYRO: - retval = inv_mpu_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - (struct ext_slave_config __user *)arg); - break; - case MPU_CONFIG_ACCEL: - retval = slave_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave[EXT_SLAVE_TYPE_ACCEL], - pdata_slave[EXT_SLAVE_TYPE_ACCEL], - (struct ext_slave_config __user *)arg); - break; - case MPU_CONFIG_COMPASS: - retval = slave_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave[EXT_SLAVE_TYPE_COMPASS], - pdata_slave[EXT_SLAVE_TYPE_COMPASS], - (struct ext_slave_config __user *)arg); - break; - case MPU_CONFIG_PRESSURE: - retval = slave_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - slave[EXT_SLAVE_TYPE_PRESSURE], - pdata_slave[EXT_SLAVE_TYPE_PRESSURE], - (struct ext_slave_config __user *)arg); - break; - case MPU_GET_CONFIG_GYRO: - retval = inv_mpu_get_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - (struct ext_slave_config __user *)arg); - break; - case MPU_GET_CONFIG_ACCEL: - retval = slave_get_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave[EXT_SLAVE_TYPE_ACCEL], - pdata_slave[EXT_SLAVE_TYPE_ACCEL], - (struct ext_slave_config __user *)arg); - break; - case MPU_GET_CONFIG_COMPASS: - retval = slave_get_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave[EXT_SLAVE_TYPE_COMPASS], - pdata_slave[EXT_SLAVE_TYPE_COMPASS], - (struct ext_slave_config __user *)arg); - break; - case MPU_GET_CONFIG_PRESSURE: - retval = slave_get_config( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - slave[EXT_SLAVE_TYPE_PRESSURE], - pdata_slave[EXT_SLAVE_TYPE_PRESSURE], - (struct ext_slave_config __user *)arg); - break; - case MPU_SUSPEND: - retval = inv_mpu_suspend( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - arg); - break; - case MPU_RESUME: - retval = inv_mpu_resume( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - arg); - break; - case MPU_PM_EVENT_HANDLED: - dev_dbg(&client->adapter->dev, "%s: %d", __func__, cmd); - complete(&mpu->completion); - break; - case MPU_READ_ACCEL: - retval = inv_slave_read( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave[EXT_SLAVE_TYPE_ACCEL], - pdata_slave[EXT_SLAVE_TYPE_ACCEL], - (unsigned char __user *)arg); - break; - case MPU_READ_COMPASS: - retval = inv_slave_read( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave[EXT_SLAVE_TYPE_COMPASS], - pdata_slave[EXT_SLAVE_TYPE_COMPASS], - (unsigned char __user *)arg); - break; - case MPU_READ_PRESSURE: - retval = inv_slave_read( - mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - slave[EXT_SLAVE_TYPE_PRESSURE], - pdata_slave[EXT_SLAVE_TYPE_PRESSURE], - (unsigned char __user *)arg); - break; - case MPU_GET_REQUESTED_SENSORS: - if (copy_to_user( - (__u32 __user *)arg, - &mldl_cfg->inv_mpu_cfg->requested_sensors, - sizeof(mldl_cfg->inv_mpu_cfg->requested_sensors))) - retval = -EFAULT; - break; - case MPU_SET_REQUESTED_SENSORS: - mldl_cfg->inv_mpu_cfg->requested_sensors = arg; - break; - case MPU_GET_IGNORE_SYSTEM_SUSPEND: - if (copy_to_user( - (unsigned char __user *)arg, - &mldl_cfg->inv_mpu_cfg->ignore_system_suspend, - sizeof(mldl_cfg->inv_mpu_cfg->ignore_system_suspend))) - retval = -EFAULT; - break; - case MPU_SET_IGNORE_SYSTEM_SUSPEND: - mldl_cfg->inv_mpu_cfg->ignore_system_suspend = arg; - break; - case MPU_GET_MLDL_STATUS: - if (copy_to_user( - (unsigned char __user *)arg, - &mldl_cfg->inv_mpu_state->status, - sizeof(mldl_cfg->inv_mpu_state->status))) - retval = -EFAULT; - break; - case MPU_GET_I2C_SLAVES_ENABLED: - if (copy_to_user( - (unsigned char __user *)arg, - &mldl_cfg->inv_mpu_state->i2c_slaves_enabled, - sizeof(mldl_cfg->inv_mpu_state->i2c_slaves_enabled))) - retval = -EFAULT; - break; - case MPU_READ_ACCEL_OFFSET: - { - - retval = copy_to_user((signed short __user *)arg, - &cal_data, sizeof(cal_data)); - if (INV_SUCCESS != retval) { - dev_err(&client->adapter->dev, - "%s: cmd %x, arg %lu", - __func__, cmd, arg); - } - } - break; - default: - dev_err(&client->adapter->dev, - "%s: Unknown cmd %x, arg %lu", - __func__, cmd, arg); - retval = -EINVAL; - }; - - mutex_unlock(&mpu->mutex); - dev_dbg(&client->adapter->dev, "%s: %08x, %08lx, %d", - __func__, cmd, arg, retval); - - if (retval > 0) - retval = -retval; - - return retval; -} - -#ifdef CONFIG_HAS_EARLYSUSPEND -void mpu_dev_early_suspend(struct early_suspend *h) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(this_client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - pr_info("----------\n%s\n----------", __func__); - - mpu_early_notifier_callback(mpu, PM_SUSPEND_PREPARE, NULL); - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = this_client->adapter; - mutex_lock(&mpu->mutex); - if (!mldl_cfg->inv_mpu_cfg->ignore_system_suspend) { - (void)inv_mpu_suspend(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - INV_ALL_SENSORS); - } - mutex_unlock(&mpu->mutex); -} - -void mpu_dev_early_resume(struct early_suspend *h) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(this_client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - pr_info("----------\n%s\n----------", __func__); - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = this_client->adapter; - - mutex_lock(&mpu->mutex); - if (mpu->pid && !mldl_cfg->inv_mpu_cfg->ignore_system_suspend) { - (void)inv_mpu_resume(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - mldl_cfg->inv_mpu_cfg->requested_sensors); - } - mutex_unlock(&mpu->mutex); - mpu_early_notifier_callback(mpu, PM_POST_SUSPEND, NULL); -} -#endif - - -void mpu_shutdown(struct i2c_client *client) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - mutex_lock(&mpu->mutex); - (void)inv_mpu_suspend(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - INV_ALL_SENSORS); - mutex_unlock(&mpu->mutex); - dev_dbg(&client->adapter->dev, "%s", __func__); -} - -int mpu_dev_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - pr_info("----------\n%s\n----------", __func__); - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - mutex_lock(&mpu->mutex); - if (!mldl_cfg->inv_mpu_cfg->ignore_system_suspend) { - dev_dbg(&client->adapter->dev, - "%s: suspending on event %d", __func__, mesg.event); - (void)inv_mpu_suspend(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - INV_ALL_SENSORS); - } else { - dev_dbg(&client->adapter->dev, - "%s: Already suspended %d", __func__, mesg.event); - } - mutex_unlock(&mpu->mutex); - return 0; -} - -int mpu_dev_resume(struct i2c_client *client) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - pr_info("----------\n%s\n----------", __func__); - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - mutex_lock(&mpu->mutex); - if (mpu->pid && !mldl_cfg->inv_mpu_cfg->ignore_system_suspend) { - (void)inv_mpu_resume(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - mldl_cfg->inv_mpu_cfg->requested_sensors); - dev_dbg(&client->adapter->dev, - "%s for pid %d", __func__, mpu->pid); - } - mutex_unlock(&mpu->mutex); - return 0; -} - -/* define which file operations are supported */ -static const struct file_operations mpu_fops = { - .owner = THIS_MODULE, - .read = mpu_read, - .poll = mpu_poll, - .unlocked_ioctl = mpu_dev_ioctl, - .open = mpu_dev_open, - .release = mpu_release, -}; - -int inv_mpu_register_slave(struct module *slave_module, - struct i2c_client *slave_client, - struct ext_slave_platform_data *slave_pdata, - struct ext_slave_descr *(*get_slave_descr)(void)) -{ - struct mpu_private_data *mpu = mpu_data; - struct mldl_cfg *mldl_cfg; - struct ext_slave_descr *slave_descr; - struct ext_slave_platform_data **pdata_slave; - char *irq_name = NULL; - int result = 0; - - if (!slave_client || !slave_pdata || !get_slave_descr) - return -EINVAL; - - if (!mpu) { - dev_err(&slave_client->adapter->dev, - "%s: Null mpu_private_data", __func__); - return -EINVAL; - } - mldl_cfg = &mpu->mldl_cfg; - pdata_slave = mldl_cfg->pdata_slave; - slave_descr = get_slave_descr(); - - if (!slave_descr) { - dev_err(&slave_client->adapter->dev, - "%s: Null ext_slave_descr", __func__); - return -EINVAL; - } - - mutex_lock(&mpu->mutex); - if (mpu->pid) { - mutex_unlock(&mpu->mutex); - return -EBUSY; - } - - if (pdata_slave[slave_descr->type]) { - result = -EBUSY; - goto out_unlock_mutex; - } - - slave_pdata->address = slave_client->addr; - slave_pdata->irq = slave_client->irq; - slave_pdata->adapt_num = i2c_adapter_id(slave_client->adapter); - - dev_info(&slave_client->adapter->dev, - "%s: +%s Type %d: Addr: %2x IRQ: %2d, Adapt: %2d", - __func__, - slave_descr->name, - slave_descr->type, - slave_pdata->address, - slave_pdata->irq, - slave_pdata->adapt_num); - - switch (slave_descr->type) { - case EXT_SLAVE_TYPE_ACCEL: - irq_name = "accelirq"; - break; - case EXT_SLAVE_TYPE_COMPASS: - irq_name = "compassirq"; - break; - case EXT_SLAVE_TYPE_PRESSURE: - irq_name = "pressureirq"; - break; - default: - irq_name = "none"; - }; - if (slave_descr->init) { - result = slave_descr->init(slave_client->adapter, - slave_descr, - slave_pdata); - if (result) { - dev_err(&slave_client->adapter->dev, - "%s init failed %d", - slave_descr->name, result); - goto out_unlock_mutex; - } - } - - 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); - - if (!result && irq_name && (slave_pdata->irq > 0)) { - int warn_result; - dev_info(&slave_client->adapter->dev, - "Installing %s irq using %d", - irq_name, - slave_pdata->irq); - warn_result = slaveirq_init(slave_client->adapter, - slave_pdata, irq_name); - if (result) - dev_warn(&slave_client->adapter->dev, - "%s irq assigned error: %d", - slave_descr->name, warn_result); - } else { - dev_warn(&slave_client->adapter->dev, - "%s irq not assigned: %d %d %d", - slave_descr->name, - result, (int)irq_name, slave_pdata->irq); - } - - return result; -} -EXPORT_SYMBOL(inv_mpu_register_slave); - -void inv_mpu_unregister_slave(struct i2c_client *slave_client, - struct ext_slave_platform_data *slave_pdata, - struct ext_slave_descr *(*get_slave_descr)(void)) -{ - struct mpu_private_data *mpu = mpu_data; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct ext_slave_descr *slave_descr; - int result; - - dev_info(&slave_client->adapter->dev, "%s\n", __func__); - - if (!slave_client || !slave_pdata || !get_slave_descr) - return; - - if (slave_pdata->irq) - slaveirq_exit(slave_pdata); - - slave_descr = get_slave_descr(); - if (!slave_descr) - return; - - mutex_lock(&mpu->mutex); - - if (slave_descr->exit) { - result = slave_descr->exit(slave_client->adapter, - slave_descr, - slave_pdata); - if (result) - dev_err(&slave_client->adapter->dev, - "Accel exit failed %d\n", result); - } - mldl_cfg->slave[slave_descr->type] = NULL; - mldl_cfg->pdata_slave[slave_descr->type] = NULL; - mpu->slave_modules[slave_descr->type] = NULL; - - mutex_unlock(&mpu->mutex); - -} -EXPORT_SYMBOL(inv_mpu_unregister_slave); - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static const struct i2c_device_id mpu_id[] = { - {"mpu3050", 0}, - {"mpu6050", 0}, - {"mpu6050_no_accel", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, mpu_id); - -static int mpu6050_factory_on(struct i2c_client *client) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(this_client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - int prev_gyro_suspended = 0; - - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - pr_info("----------\n%s\n----------", __func__); - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - mutex_lock(&mpu->mutex); - if (1) { - (void)inv_mpu_resume(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - slave_adapter[EXT_SLAVE_TYPE_PRESSURE], - mldl_cfg->inv_mpu_cfg->requested_sensors); - } - mutex_unlock(&mpu->mutex); - return prev_gyro_suspended; -} - -static ssize_t mpu6050_power_on(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int count = 0; - - dev_dbg(dev, "this_client = %d\n", (int)this_client); - count = sprintf(buf, "%d\n", (this_client != NULL ? 1 : 0)); - - return count; -} - -static ssize_t mpu6050_get_temp(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int count = 0; - short int temperature = 0; - unsigned char data[2]; - struct mpu_private_data *mpu = - (struct mpu_private_data *)i2c_get_clientdata(this_client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = this_client->adapter; - - mpu6050_factory_on(this_client); - - /* MPUREG_TEMP_OUT_H, */ /* 27 0x1b */ - /* MPUREG_TEMP_OUT_L, */ /* 28 0x1c */ - /* TEMP_OUT_H/L: 16-bit temperature data (2's complement data format) */ - inv_serial_read(slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - DEFAULT_MPU_SLAVEADDR, - MPUREG_TEMP_OUT_H, - 2, - data); - temperature = (short) (((data[0]) << 8) | data[1]); - temperature = (((temperature + 521) / 340) + 35); - pr_info("read temperature = %d\n", temperature); - - count = sprintf(buf, "%d\n", temperature); - - return count; -} - -static ssize_t mpu6050_acc_read(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - s16 x, y, z; - int count = 0; - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - int retval = 0; - unsigned char data[6]; - - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - - /* mutex_lock(&mpu->mutex); */ - mpu_accel_enable_set(1); - msleep(20); - retval = inv_serial_read(slave_adapter[EXT_SLAVE_TYPE_ACCEL], - 0x68, 0x3B, 6, data); - - x = (s16)(((data[0] << 8) | data[1]) - cal_data.x);/*CAL_DIV;*/ - y = (s16)(((data[2] << 8) | data[3]) - cal_data.y);/*CAL_DIV;*/ - z = (s16)(((data[4] << 8) | data[5]) - cal_data.z);/*CAL_DIV;*/ - - z *= -1; - - pr_info("mpu6050_acc_read x: %d y: %d z: %d", y, x, z); - mpu_accel_enable_set(0); - msleep(20); - /* mutex_unlock(&mpu->mutex); */ - - count = sprintf(buf, "%d, %d, %d\n", y, x, z); - - return count; -} - -static ssize_t accel_calibration_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - - int count = 0; - - pr_info(" accel_calibration_show %d %d %d", - cal_data.x, cal_data.y, cal_data.z); - - count = sprintf(buf, "%d %d %d\n", cal_data.x, cal_data.y, cal_data.z); - return count; -} - -static ssize_t accel_calibration_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t size) -{ - bool do_calib; - int err; - int count = 0; - char str[11]; - - if (sysfs_streq(buf, "1")) - do_calib = true; - else if (sysfs_streq(buf, "0")) - do_calib = false; - else { - pr_debug("%s: invalid value %d", __func__, *buf); - return -EINVAL; - } - - err = accel_do_calibrate(do_calib); - if (err < 0) - pr_err("%s: accel_do_calibrate() failed", __func__); - - pr_info("accel_calibration_show :%d %d %d", - cal_data.x, cal_data.y, cal_data.z); - if (err > 0) - err = 0; - count = sprintf(str, "%d\n", err); - - strcpy(str, buf); - return count; -} - -static ssize_t mpu_vendor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", MPU_VENDOR); -} - -static ssize_t mpu_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", MPU_PART_ID); -} - -static int akm8975_wait_for_data_ready(struct i2c_adapter *sl_adapter) -{ - int err; - u8 buf; - int count = 10; - - while (1) { - msleep(20); - err = inv_serial_read(sl_adapter, 0x0C, - AK8975_REG_ST1, sizeof(buf), &buf); - if (err) { - pr_err("%s: read data over i2c failed\n", __func__); - return -EIO; - } - - if (buf&0x1) - break; - - count--; - if (!count) - break; - } - return 0; - -} - -static ssize_t ak8975_adc(struct device *dev, - struct device_attribute *attr, char *strbuf) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - - - u8 buf[8]; - s16 x, y, z; - int err, success; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - - pr_info("%s %s", __func__, client->name); - - mutex_lock(&mpu->mutex); - - /* start ADC conversion */ - err = inv_serial_single_write(slave_adapter[EXT_SLAVE_TYPE_COMPASS], - 0x0C, AK8975_REG_CNTL, AK8975_MODE_SNG_MEASURE); - - if (err) - pr_err("ak8975_adc write err:%d\n", err); - - /* wait for ADC conversion to complete */ - - err = akm8975_wait_for_data_ready - (slave_adapter[EXT_SLAVE_TYPE_COMPASS]); - if (err) { - pr_err("%s: wait for data ready failed\n", __func__); - return err; - } - - msleep(20);/*msleep(10);*/ - /* get the value and report it */ - err = inv_serial_read(slave_adapter[EXT_SLAVE_TYPE_COMPASS], 0x0C, - AK8975_REG_ST1, sizeof(buf), buf); - - if (err) { - pr_err("%s: read data over i2c failed %d\n", __func__, err); - mutex_unlock(&mpu->mutex); - return -EIO; - } - mutex_unlock(&mpu->mutex); - - /* buf[0] is status1, buf[7] is status2 */ - if ((buf[0] == 0) | (buf[7] == 1)) - success = 0; - else - success = 1; - - x = buf[1] | (buf[2] << 8); - y = buf[3] | (buf[4] << 8); - z = buf[5] | (buf[6] << 8); - - pr_err("%s: raw x = %d, y = %d, z = %d\n", __func__, x, y, z); - - return snprintf(strbuf, PAGE_SIZE, "%s, %d, %d, %d\n", - (success ? "OK" : "NG"), x, y, z); -} - -static ssize_t ak8975_check_cntl(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - - int ii, err; - u8 data; - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - mutex_lock(&mpu->mutex); - err = inv_serial_single_write(slave_adapter[EXT_SLAVE_TYPE_COMPASS], - 0x0C, AK8975_REG_CNTL, - AK8975_MODE_POWER_DOWN); - - if (err) { - pr_err("ak8975_adc write err:%d\n", err); - mutex_unlock(&mpu->mutex); - return -EIO; - } - err = inv_serial_read(slave_adapter[EXT_SLAVE_TYPE_COMPASS], 0x0C, - AK8975_REG_CNTL, sizeof(data), &data); - if (err) { - pr_err("%s: read data over i2c failed %d\n", __func__, err); - mutex_unlock(&mpu->mutex); - return -EIO; - } - mutex_unlock(&mpu->mutex); - - return snprintf(buf, PAGE_SIZE, "%s\n", - data == AK8975_MODE_POWER_DOWN ? "OK" : "NG"); - -} - -static ssize_t akm8975_rawdata_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - - short x = 0, y = 0, z = 0; - int err; - u8 data[8]; - - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - - mutex_lock(&mpu->mutex); - err = inv_serial_single_write(slave_adapter[EXT_SLAVE_TYPE_COMPASS], - 0x0C, AK8975_REG_CNTL, - AK8975_MODE_SNG_MEASURE); - - if (err) { - pr_err("ak8975_adc write err:%d\n", err); - mutex_unlock(&mpu->mutex); - goto done; - - } - - err = akm8975_wait_for_data_ready - (slave_adapter[EXT_SLAVE_TYPE_COMPASS]); - if (err) { - mutex_unlock(&mpu->mutex); - goto done; - } - - /* get the value and report it */ - err = inv_serial_read(slave_adapter[EXT_SLAVE_TYPE_COMPASS], 0x0C, - AK8975_REG_ST1, sizeof(data), data); - - if (err) { - pr_err("%s: read data over i2c failed %d\n", __func__, err); - mutex_unlock(&mpu->mutex); - return -EIO; - } - - mutex_unlock(&mpu->mutex); - - if (err) { - pr_err("%s: failed to read %d bytes of mag data\n", - __func__, sizeof(data)); - goto done; - } - - if (data[0] & 0x01) { - x = (data[2] << 8) + data[1]; - y = (data[4] << 8) + data[3]; - z = (data[6] << 8) + data[5]; - } else - pr_err("%s: invalid raw data(st1 = %d)\n", - __func__, data[0] & 0x01); - -done: - return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n", x, y, z); -} - -struct ak8975_config { - char asa[COMPASS_NUM_AXES]; /* axis sensitivity adjustment */ -}; - -struct ak8975_private_data { - struct ak8975_config init; -}; -static ssize_t ak8975c_get_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int success; - - struct ak8975_private_data *private_data = - (struct ak8975_private_data *) - pdata_slave[EXT_SLAVE_TYPE_COMPASS]->private_data; - if ((private_data->init.asa[0] == 0) | - (private_data->init.asa[0] == 0xff) | - (private_data->init.asa[1] == 0) | - (private_data->init.asa[1] == 0xff) | - (private_data->init.asa[2] == 0) | - (private_data->init.asa[2] == 0xff)) - success = 0; - else - success = 1; - - return snprintf(buf, PAGE_SIZE, "%s\n", (success ? "OK" : "NG")); - -} - -int ak8975c_selftest(struct i2c_adapter *slave_adapter, - struct ak8975_private_data *private_data, int *sf) -{ - int err; - u8 data; - u8 buf[6]; - int count = 20; - s16 x, y, z; - - /* set ATSC self test bit to 1 */ - err = inv_serial_single_write(slave_adapter, 0x0C, - AK8975_REG_ASTC, 0x40); - - /* start self test */ - err = inv_serial_single_write(slave_adapter, 0x0C, - AK8975_REG_CNTL, AK8975_MODE_SELF_TEST); - - /* wait for data ready */ - while (1) { - msleep(20); - err = inv_serial_read(slave_adapter, 0x0C, - AK8975_REG_ST1, sizeof(data), &data); - - if (data == 1) - break; - count--; - if (!count) - break; - } - err = inv_serial_read(slave_adapter, 0x0C, - AK8975_REG_HXL, sizeof(buf), buf); - - /* set ATSC self test bit to 0 */ - err = inv_serial_single_write(slave_adapter, 0x0C, - AK8975_REG_ASTC, 0x00); - - x = buf[0] | (buf[1] << 8); - y = buf[2] | (buf[3] << 8); - z = buf[4] | (buf[5] << 8); - - /* Hadj = (H*(Asa+128))/256 */ - x = (x*(private_data->init.asa[0] + 128)) >> 8; - y = (y*(private_data->init.asa[1] + 128)) >> 8; - z = (z*(private_data->init.asa[2] + 128)) >> 8; - - pr_info("%s: self test x = %d, y = %d, z = %d\n", - __func__, x, y, z); - if ((x >= -200) && (x <= 200)) - pr_info("%s: x passed self test, expect -200<=x<=200\n", - __func__); - else - pr_info("%s: x failed self test, expect -200<=x<=200\n", - __func__); - if ((y >= -200) && (y <= 200)) - pr_info("%s: y passed self test, expect -200<=y<=200\n", - __func__); - else - pr_info("%s: y failed self test, expect -200<=y<=200\n", - __func__); - if ((z >= -3200) && (z <= -800)) - pr_info("%s: z passed self test, expect -3200<=z<=-800\n", - __func__); - else - pr_info("%s: z failed self test, expect -3200<=z<=-800\n", - __func__); - - sf[0] = x; - sf[1] = y; - sf[2] = z; - - if (((x >= -200) && (x <= 200)) && - ((y >= -200) && (y <= 200)) && - ((z >= -3200) && (z <= -800))) - return 1; - else - return 0; -} - -static ssize_t ak8975c_get_selftest(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct mpu_private_data *mpu = - (struct mpu_private_data *) i2c_get_clientdata(this_client); - struct i2c_client *client = mpu->client; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - struct ak8975_private_data *private_data = - (struct ak8975_private_data *) - pdata_slave[EXT_SLAVE_TYPE_COMPASS]->private_data; - int ii, success; - int sf[3] = {0,}; - int retry = 3; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - do { - retry--; - success = ak8975c_selftest( - slave_adapter[EXT_SLAVE_TYPE_COMPASS], - private_data, sf); - if (success) - break; - } while (retry > 0); - - return snprintf(buf, PAGE_SIZE, "%d, %d, %d, %d\n", - success, sf[0], sf[1], sf[2]); -} - -static ssize_t akm_vendor_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", MAG_VENDOR); -} - -static ssize_t akm_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", MAG_PART_ID); -} - -static DEVICE_ATTR(power_on, S_IRUGO, mpu6050_power_on, NULL); -static DEVICE_ATTR(temperature, S_IRUGO, mpu6050_get_temp, NULL); - -static DEVICE_ATTR(calibration, S_IRUGO | S_IWUSR, - accel_calibration_show, accel_calibration_store); - -static DEVICE_ATTR(raw_data, S_IRUGO, mpu6050_acc_read, NULL); - -static DEVICE_ATTR(vendor, S_IRUGO, mpu_vendor_show, NULL); -static DEVICE_ATTR(name, S_IRUGO, mpu_name_show, NULL); - - -static DEVICE_ATTR(adc, S_IRUGO, ak8975_adc, NULL); - -static DEVICE_ATTR(dac, S_IRUGO, ak8975_check_cntl, NULL); -static DEVICE_ATTR(status, S_IRUGO, ak8975c_get_status, NULL); -static DEVICE_ATTR(selftest, S_IRUGO, ak8975c_get_selftest, NULL); - -static struct device_attribute dev_attr_mag_rawdata = - __ATTR(raw_data, S_IRUGO, akm8975_rawdata_show, NULL); - -static struct device_attribute dev_attr_mag_vendor = - __ATTR(vendor, S_IRUGO, akm_vendor_show, NULL); - -static struct device_attribute dev_attr_mag_name = - __ATTR(name, S_IRUGO, akm_name_show, NULL); - -static struct device_attribute *gyro_sensor_attrs[] = { - &dev_attr_power_on, - &dev_attr_temperature, - &dev_attr_vendor, - &dev_attr_name, - NULL, -}; - -static struct device_attribute *accel_sensor_attrs[] = { - &dev_attr_raw_data, - &dev_attr_calibration, - &dev_attr_vendor, - &dev_attr_name, - NULL, -}; - -static struct device_attribute *magnetic_sensor_attrs[] = { - &dev_attr_adc, - &dev_attr_mag_rawdata, - &dev_attr_dac, - &dev_attr_status, - &dev_attr_selftest, - &dev_attr_mag_vendor, - &dev_attr_mag_name, - NULL, -}; - -int mpu_probe(struct i2c_client *client, const struct i2c_device_id *devid) -{ - struct mpu_platform_data *pdata; - struct mpu_private_data *mpu; - struct mldl_cfg *mldl_cfg; - struct device *gyro_sensor_device = NULL; - struct device *accel_sensor_device = NULL; - struct device *magnetic_sensor_device = NULL; - int res = 0; - int ii; - - pr_info("===========\n%s\n===========", __func__); - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - res = -ENODEV; - goto out_check_functionality_failed; - } - - mpu = kzalloc(sizeof(struct mpu_private_data), GFP_KERNEL); - if (!mpu) { - res = -ENOMEM; - goto out_alloc_data_failed; - } - mldl_cfg = &mpu->mldl_cfg; - mldl_cfg->mpu_ram = &mpu->mpu_ram; - mldl_cfg->mpu_gyro_cfg = &mpu->mpu_gyro_cfg; - mldl_cfg->mpu_offsets = &mpu->mpu_offsets; - mldl_cfg->mpu_chip_info = &mpu->mpu_chip_info; - mldl_cfg->inv_mpu_cfg = &mpu->inv_mpu_cfg; - mldl_cfg->inv_mpu_state = &mpu->inv_mpu_state; - - mldl_cfg->mpu_ram->length = MPU_MEM_NUM_RAM_BANKS * MPU_MEM_BANK_SIZE; - mldl_cfg->mpu_ram->ram = kzalloc(mldl_cfg->mpu_ram->length, GFP_KERNEL); - if (!mldl_cfg->mpu_ram->ram) { - res = -ENOMEM; - goto out_alloc_ram_failed; - } - mpu_data = mpu; - i2c_set_clientdata(client, mpu); - this_client = client; - mpu->client = client; - - init_waitqueue_head(&mpu->mpu_event_wait); - mutex_init(&mpu->mutex); - init_completion(&mpu->completion); - - - mpu->response_timeout = 1; /* Seconds */ - mpu->timeout.function = mpu_pm_timeout; - mpu->timeout.data = (u_long) mpu; - init_timer(&mpu->timeout); -#if 0 - mpu->nb.notifier_call = mpu_pm_notifier_callback; - mpu->nb.priority = 0; - res = register_pm_notifier(&mpu->nb); - if (res) { - dev_err(&client->adapter->dev, - "Unable to register pm_notifier %d", res); - goto out_register_pm_notifier_failed; - } -#endif - pdata = (struct mpu_platform_data *)client->dev.platform_data; - if (!pdata) { - dev_warn(&client->adapter->dev, - "Missing platform data for mpu"); - } - mldl_cfg->pdata = pdata; - - mldl_cfg->mpu_chip_info->addr = client->addr; - res = inv_mpu_open(&mpu->mldl_cfg, client->adapter, NULL, NULL, NULL); - - if (res) { - dev_err(&client->adapter->dev, - "Unable to open %s %d", MPU_NAME, res); - res = -ENODEV; - goto out_whoami_failed; - } - - mpu->dev.minor = MISC_DYNAMIC_MINOR; - mpu->dev.name = "mpu"; - mpu->dev.fops = &mpu_fops; - res = misc_register(&mpu->dev); - if (res < 0) { - dev_err(&client->adapter->dev, - "ERROR: misc_register returned %d", res); - goto out_misc_register_failed; - } - - if (client->irq) { - dev_info(&client->adapter->dev, - "Installing irq using %d", client->irq); - res = mpuirq_init(client, mldl_cfg); - if (res) - goto out_mpuirq_failed; - } else { - dev_warn(&client->adapter->dev, - "Missing %s IRQ", 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] = pdata->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; - } - } - - res = sensors_register(gyro_sensor_device, NULL, gyro_sensor_attrs, - "gyro_sensor"); - if (res) { - pr_err("%s: cound not register gyro sensor device(%d).", - __func__, res); - goto out_sensor_register_failed; - } - - res = sensors_register(accel_sensor_device, NULL, accel_sensor_attrs, - "accelerometer_sensor"); - if (res) { - pr_err("%s: cound not register accelerometer " \ - "sensor device(%d).", - __func__, res); - goto out_sensor_register_failed; - } - - res = sensors_register(magnetic_sensor_device, NULL, - magnetic_sensor_attrs, "magnetic_sensor"); - if (res) { - pr_err("%s: cound not register magnetic sensor device(%d).", - __func__, res); - goto out_sensor_register_failed; - } - -#ifdef CONFIG_HAS_EARLYSUSPEND - mpu->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; - mpu->early_suspend.suspend = mpu_dev_early_suspend; - mpu->early_suspend.resume = mpu_dev_early_resume; - register_early_suspend(&mpu->early_suspend); -#endif - - return res; - -out_sensor_register_failed: -out_slave_pdata_kzalloc_failed: - if (client->irq) - mpuirq_exit(); -out_mpuirq_failed: - misc_deregister(&mpu->dev); -out_misc_register_failed: - inv_mpu_close(&mpu->mldl_cfg, client->adapter, NULL, NULL, NULL); -out_whoami_failed: - unregister_pm_notifier(&mpu->nb); -#if 0 -out_register_pm_notifier_failed: -#endif - kfree(mldl_cfg->mpu_ram->ram); - mpu_data = NULL; -out_alloc_ram_failed: - kfree(mpu); -out_alloc_data_failed: -out_check_functionality_failed: - dev_err(&client->adapter->dev, "%s failed %d", __func__, res); - return res; - -} - -static int mpu_remove(struct i2c_client *client) -{ - struct mpu_private_data *mpu = i2c_get_clientdata(client); - struct i2c_adapter *slave_adapter[EXT_SLAVE_NUM_TYPES]; - struct mldl_cfg *mldl_cfg = &mpu->mldl_cfg; - struct ext_slave_platform_data **pdata_slave = mldl_cfg->pdata_slave; - int ii; - - for (ii = 0; ii < EXT_SLAVE_NUM_TYPES; ii++) { - if (!pdata_slave[ii]) - slave_adapter[ii] = NULL; - else - slave_adapter[ii] = - i2c_get_adapter(pdata_slave[ii]->adapt_num); - } - - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE] = client->adapter; - dev_dbg(&client->adapter->dev, "%s", __func__); - - inv_mpu_close(mldl_cfg, - slave_adapter[EXT_SLAVE_TYPE_GYROSCOPE], - slave_adapter[EXT_SLAVE_TYPE_ACCEL], - 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(); - - misc_deregister(&mpu->dev); - - unregister_pm_notifier(&mpu->nb); - - kfree(mpu->mldl_cfg.mpu_ram->ram); - kfree(mpu); - - return 0; -} - -static struct i2c_driver mpu_driver = { - .class = I2C_CLASS_HWMON, - .probe = mpu_probe, - .remove = mpu_remove, - .id_table = mpu_id, - .driver = { - .owner = THIS_MODULE, - .name = MPU_NAME, - }, - .address_list = normal_i2c, - .shutdown = mpu_shutdown, /* optional */ - .suspend = mpu_dev_suspend, /* optional */ - .resume = mpu_dev_resume, /* optional */ - -}; - -static int __init mpu_init(void) -{ - int res = i2c_add_driver(&mpu_driver); - pr_info("%s: Probe name %s", __func__, MPU_NAME); - if (res) - pr_err("%s failed", __func__); - return res; -} - -static void __exit mpu_exit(void) -{ - pr_info("%s", __func__); - i2c_del_driver(&mpu_driver); -} - -module_init(mpu_init); -module_exit(mpu_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("User space character device interface for MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS(MPU_NAME); diff --git a/drivers/misc/inv_mpu/mpu-dev.h b/drivers/misc/inv_mpu/mpu-dev.h deleted file mode 100644 index 0b352c9..0000000 --- a/drivers/misc/inv_mpu/mpu-dev.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - $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/>. - $ - */ - - -#ifndef __MPU_DEV_H__ -#define __MPU_DEV_H__ - -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/mpu_411.h> - -int inv_mpu_register_slave(struct module *slave_module, - struct i2c_client *client, - struct ext_slave_platform_data *pdata, - struct ext_slave_descr *(*slave_descr)(void)); - -void inv_mpu_unregister_slave(struct i2c_client *client, - struct ext_slave_platform_data *pdata, - struct ext_slave_descr *(*slave_descr)(void)); - -extern signed short gAccelOffset[3]; -extern struct class *sensors_class; -extern int sensors_register(struct device *dev, void * drvdata, - struct device_attribute *attributes[], char *name); - -#endif diff --git a/drivers/misc/inv_mpu/mpu6050b1.h b/drivers/misc/inv_mpu/mpu6050b1.h deleted file mode 100644 index c486784..0000000 --- a/drivers/misc/inv_mpu/mpu6050b1.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - $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 "mpu6050" -#define DEFAULT_MPU_SLAVEADDR 0x68 -extern struct acc_data cal_data; - - -/*==== 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_ */ diff --git a/drivers/misc/inv_mpu/mpuirq.c b/drivers/misc/inv_mpu/mpuirq.c deleted file mode 100644 index 2a850fa..0000000 --- a/drivers/misc/inv_mpu/mpuirq.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - $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/>. - $ - */ -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/stat.h> -#include <linux/irq.h> -#include <linux/signal.h> -#include <linux/miscdevice.h> -#include <linux/i2c.h> -#include <linux/i2c-dev.h> -#include <linux/poll.h> - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/uaccess.h> -#include <linux/io.h> - -#include <linux/mpu_411.h> -#include "mpuirq.h" -#include "mldl_cfg.h" - -#define MPUIRQ_NAME "mpuirq" - -/* function which gets accel data and sends it to MPU */ - -DECLARE_WAIT_QUEUE_HEAD(mpuirq_wait); - -struct mpuirq_dev_data { - struct i2c_client *mpu_client; - struct miscdevice *dev; - int irq; - int pid; - int accel_divider; - int data_ready; - int timeout; -}; - -static struct mpuirq_dev_data mpuirq_dev_data; -static struct mpuirq_data mpuirq_data; -static char *interface = MPUIRQ_NAME; - -static int mpuirq_open(struct inode *inode, struct file *file) -{ - dev_dbg(mpuirq_dev_data.dev->this_device, - "%s current->pid %d\n", __func__, current->pid); - mpuirq_dev_data.pid = current->pid; - file->private_data = &mpuirq_dev_data; - return 0; -} - -/* close function - called when the "file" /dev/mpuirq is closed in userspace */ -static int mpuirq_release(struct inode *inode, struct file *file) -{ - dev_dbg(mpuirq_dev_data.dev->this_device, "mpuirq_release\n"); - return 0; -} - -/* read function called when from /dev/mpuirq is read */ -static ssize_t mpuirq_read(struct file *file, - char *buf, size_t count, loff_t *ppos) -{ - int len, err; - struct mpuirq_dev_data *p_mpuirq_dev_data = file->private_data; - - if (!mpuirq_dev_data.data_ready && - mpuirq_dev_data.timeout && (!(file->f_flags & O_NONBLOCK))) { - wait_event_interruptible_timeout(mpuirq_wait, - mpuirq_dev_data.data_ready, - mpuirq_dev_data.timeout); - } - - if (mpuirq_dev_data.data_ready && NULL != buf - && count >= sizeof(mpuirq_data)) { - err = copy_to_user(buf, &mpuirq_data, sizeof(mpuirq_data)); - mpuirq_data.data_type = 0; - } else { - return 0; - } - if (err != 0) { - dev_err(p_mpuirq_dev_data->dev->this_device, - "Copy to user returned %d\n", err); - return -EFAULT; - } - mpuirq_dev_data.data_ready = 0; - len = sizeof(mpuirq_data); - return len; -} - -unsigned int mpuirq_poll(struct file *file, struct poll_table_struct *poll) -{ - int mask = 0; - - poll_wait(file, &mpuirq_wait, poll); - if (mpuirq_dev_data.data_ready) - mask |= POLLIN | POLLRDNORM; - return mask; -} - -/* ioctl - I/O control */ -static long mpuirq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int retval = 0; - int data; - - switch (cmd) { - case MPUIRQ_SET_TIMEOUT: - mpuirq_dev_data.timeout = arg; - break; - - case MPUIRQ_GET_INTERRUPT_CNT: - data = mpuirq_data.interruptcount - 1; - if (mpuirq_data.interruptcount > 1) - mpuirq_data.interruptcount = 1; - - if (copy_to_user((int *)arg, &data, sizeof(int))) - return -EFAULT; - break; - case MPUIRQ_GET_IRQ_TIME: - if (copy_to_user((int *)arg, &mpuirq_data.irqtime, - sizeof(mpuirq_data.irqtime))) - return -EFAULT; - mpuirq_data.irqtime = 0; - break; - case MPUIRQ_SET_FREQUENCY_DIVIDER: - mpuirq_dev_data.accel_divider = arg; - break; - default: - retval = -EINVAL; - } - return retval; -} - -static irqreturn_t mpuirq_handler(int irq, void *dev_id) -{ - static int mycount; - struct timeval irqtime; - mycount++; - - mpuirq_data.interruptcount++; - - /* wake up (unblock) for reading data from userspace */ - /* and ignore first interrupt generated in module init */ - mpuirq_dev_data.data_ready = 1; - - do_gettimeofday(&irqtime); - mpuirq_data.irqtime = (((long long)irqtime.tv_sec) << 32); - mpuirq_data.irqtime += irqtime.tv_usec; - mpuirq_data.data_type = MPUIRQ_DATA_TYPE_MPU_IRQ; - mpuirq_data.data = 0; - - wake_up_interruptible(&mpuirq_wait); - - return IRQ_HANDLED; - -} - -/* define which file operations are supported */ -const struct file_operations mpuirq_fops = { - .owner = THIS_MODULE, - .read = mpuirq_read, - .poll = mpuirq_poll, - - .unlocked_ioctl = mpuirq_ioctl, - .open = mpuirq_open, - .release = mpuirq_release, -}; - -static struct miscdevice mpuirq_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = MPUIRQ_NAME, - .fops = &mpuirq_fops, -}; - -int mpuirq_init(struct i2c_client *mpu_client, struct mldl_cfg *mldl_cfg) -{ - - int res; - - mpuirq_dev_data.mpu_client = mpu_client; - - dev_info(&mpu_client->adapter->dev, - "Module Param interface = %s\n", interface); - - mpuirq_dev_data.irq = mpu_client->irq; - mpuirq_dev_data.pid = 0; - mpuirq_dev_data.accel_divider = -1; - mpuirq_dev_data.data_ready = 0; - mpuirq_dev_data.timeout = 0; - mpuirq_dev_data.dev = &mpuirq_device; - - if (mpuirq_dev_data.irq) { - unsigned long flags; - if (BIT_ACTL_LOW == ((mldl_cfg->pdata->int_config) & BIT_ACTL)) - flags = IRQF_TRIGGER_FALLING; - else - flags = IRQF_TRIGGER_RISING; - - flags |= IRQF_SHARED; - res = - request_irq(mpuirq_dev_data.irq, mpuirq_handler, flags, - interface, &mpuirq_dev_data.irq); - - /* mpu_irq Interrupt isr enable */ - if (mldl_cfg->pdata && mldl_cfg->pdata->enable_irq_handler) - mldl_cfg->pdata->enable_irq_handler(); - if (res) { - dev_err(&mpu_client->adapter->dev, - "myirqtest: cannot register IRQ %d\n", - mpuirq_dev_data.irq); - } else { - res = misc_register(&mpuirq_device); - if (res < 0) { - dev_err(&mpu_client->adapter->dev, - "misc_register returned %d\n", res); - free_irq(mpuirq_dev_data.irq, - &mpuirq_dev_data.irq); - } - } - - } else { - res = 0; - } - - return res; -} - -void mpuirq_exit(void) -{ - if (mpuirq_dev_data.irq > 0) - free_irq(mpuirq_dev_data.irq, &mpuirq_dev_data.irq); - - dev_info(mpuirq_device.this_device, "Unregistering %s\n", MPUIRQ_NAME); - misc_deregister(&mpuirq_device); - - return; -} - -module_param(interface, charp, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(interface, "The Interface name"); diff --git a/drivers/misc/inv_mpu/mpuirq.h b/drivers/misc/inv_mpu/mpuirq.h deleted file mode 100644 index 3348071..0000000 --- a/drivers/misc/inv_mpu/mpuirq.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - $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/>. - $ - */ - -#ifndef __MPUIRQ__ -#define __MPUIRQ__ - -#include <linux/i2c-dev.h> -#include <linux/time.h> -#include <linux/ioctl.h> -#include "mldl_cfg.h" - -#define MPUIRQ_SET_TIMEOUT _IOW(MPU_IOCTL, 0x40, unsigned long) -#define MPUIRQ_GET_INTERRUPT_CNT _IOR(MPU_IOCTL, 0x41, unsigned long) -#define MPUIRQ_GET_IRQ_TIME _IOR(MPU_IOCTL, 0x42, struct timeval) -#define MPUIRQ_SET_FREQUENCY_DIVIDER _IOW(MPU_IOCTL, 0x43, unsigned long) - -void mpuirq_exit(void); -int mpuirq_init(struct i2c_client *mpu_client, struct mldl_cfg *mldl_cfg); - -#endif diff --git a/drivers/misc/inv_mpu/pressure/Kconfig b/drivers/misc/inv_mpu/pressure/Kconfig deleted file mode 100644 index 9fe7763..0000000 --- a/drivers/misc/inv_mpu/pressure/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -menuconfig: INV_SENSORS_PRESSURE - bool "Pressure Sensor Slaves" - depends on INV_SENSORS - default y - help - Select y to see a list of supported pressure sensors that can be - integrated with the MPUxxxx set of motion processors. - -if INV_SENSORS_PRESSURE - -config MPU_SENSORS_BMA085_411 - tristate "Bosch BMA085" - help - This enables support for the Bosch bma085 pressure sensor - This support is for integration with the MPU3050 or MPU6050 gyroscope - device driver. Only one accelerometer can be registered at a time. - Specifying more that one accelerometer in the board file will result - in runtime errors. - -endif diff --git a/drivers/misc/inv_mpu/pressure/Makefile b/drivers/misc/inv_mpu/pressure/Makefile deleted file mode 100644 index a69ee3a..0000000 --- a/drivers/misc/inv_mpu/pressure/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Pressure Slaves to MPUxxxx -# -obj-$(CONFIG_MPU_SENSORS_BMA085_411) += inv_mpu_bma085.o -inv_mpu_bma085-objs += bma085.o - -EXTRA_CFLAGS += -Idrivers/misc/inv_mpu -EXTRA_CFLAGS += -D__C99_DESIGNATED_INITIALIZER diff --git a/drivers/misc/inv_mpu/pressure/bma085.c b/drivers/misc/inv_mpu/pressure/bma085.c deleted file mode 100644 index 696d2b6..0000000 --- a/drivers/misc/inv_mpu/pressure/bma085.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - $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 ACCELDL (Motion Library - Pressure Driver Layer) - * @brief Provides the interface to setup and handle a pressure - * connected to the secondary I2C interface of the gyroscope. - * - * @{ - * @file bma085.c - * @brief Pressure setup and handling methods. - */ - -/* ------------------ */ -/* - Include Files. - */ -/* ------------------ */ - -#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 <linux/mpu.h> -#include "mlsl.h" -#include "log.h" - -/* - * this structure holds all device specific calibration parameters - */ -struct bmp085_calibration_param_t { - short ac1; - short ac2; - short ac3; - unsigned short ac4; - unsigned short ac5; - unsigned short ac6; - short b1; - short b2; - short mb; - short mc; - short md; - long param_b5; -}; - -struct bmp085_calibration_param_t cal_param; - -#define PRESSURE_BMA085_PARAM_MG 3038 /* calibration parameter */ -#define PRESSURE_BMA085_PARAM_MH -7357 /* calibration parameter */ -#define PRESSURE_BMA085_PARAM_MI 3791 /* calibration parameter */ - -/********************************************* - * Pressure Initialization Functions - *********************************************/ - -static int bma085_suspend(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result = INV_SUCCESS; - return result; -} - -#define PRESSURE_BMA085_PROM_START_ADDR (0xAA) -#define PRESSURE_BMA085_PROM_DATA_LEN (22) -#define PRESSURE_BMP085_CTRL_MEAS_REG (0xF4) -/* temperature measurent */ -#define PRESSURE_BMP085_T_MEAS (0x2E) -/* pressure measurement; oversampling_setting */ -#define PRESSURE_BMP085_P_MEAS_OSS_0 (0x34) -#define PRESSURE_BMP085_P_MEAS_OSS_1 (0x74) -#define PRESSURE_BMP085_P_MEAS_OSS_2 (0xB4) -#define PRESSURE_BMP085_P_MEAS_OSS_3 (0xF4) -#define PRESSURE_BMP085_ADC_OUT_MSB_REG (0xF6) -#define PRESSURE_BMP085_ADC_OUT_LSB_REG (0xF7) - -static int bma085_resume(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata) -{ - int result; - unsigned char data[PRESSURE_BMA085_PROM_DATA_LEN]; - - result = - inv_serial_read(mlsl_handle, pdata->address, - PRESSURE_BMA085_PROM_START_ADDR, - PRESSURE_BMA085_PROM_DATA_LEN, data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - - /* parameters AC1-AC6 */ - cal_param.ac1 = (data[0] << 8) | data[1]; - cal_param.ac2 = (data[2] << 8) | data[3]; - cal_param.ac3 = (data[4] << 8) | data[5]; - cal_param.ac4 = (data[6] << 8) | data[7]; - cal_param.ac5 = (data[8] << 8) | data[9]; - cal_param.ac6 = (data[10] << 8) | data[11]; - - /* parameters B1,B2 */ - cal_param.b1 = (data[12] << 8) | data[13]; - cal_param.b2 = (data[14] << 8) | data[15]; - - /* parameters MB,MC,MD */ - cal_param.mb = (data[16] << 8) | data[17]; - cal_param.mc = (data[18] << 8) | data[19]; - cal_param.md = (data[20] << 8) | data[21]; - - return result; -} - -static int bma085_read(void *mlsl_handle, - struct ext_slave_descr *slave, - struct ext_slave_platform_data *pdata, - unsigned char *data) -{ - int result; - long pressure, x1, x2, x3, b3, b6; - unsigned long b4, b7; - unsigned long up; - unsigned short ut; - short oversampling_setting = 0; - short temperature; - long divisor; - - /* get temprature */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - PRESSURE_BMP085_CTRL_MEAS_REG, - PRESSURE_BMP085_T_MEAS); - msleep(5); - result = - inv_serial_read(mlsl_handle, pdata->address, - PRESSURE_BMP085_ADC_OUT_MSB_REG, 2, - (unsigned char *)data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - ut = (data[0] << 8) | data[1]; - - x1 = (((long) ut - (long)cal_param.ac6) * (long)cal_param.ac5) >> 15; - divisor = x1 + cal_param.md; - if (!divisor) - return INV_ERROR_DIVIDE_BY_ZERO; - - x2 = ((long)cal_param.mc << 11) / (x1 + cal_param.md); - cal_param.param_b5 = x1 + x2; - /* temperature in 0.1 degree C */ - temperature = (short)((cal_param.param_b5 + 8) >> 4); - - /* get pressure */ - result = inv_serial_single_write(mlsl_handle, pdata->address, - PRESSURE_BMP085_CTRL_MEAS_REG, - PRESSURE_BMP085_P_MEAS_OSS_0); - msleep(5); - result = - inv_serial_read(mlsl_handle, pdata->address, - PRESSURE_BMP085_ADC_OUT_MSB_REG, 2, - (unsigned char *)data); - if (result) { - LOG_RESULT_LOCATION(result); - return result; - } - up = (((unsigned long) data[0] << 8) | ((unsigned long) data[1])); - - b6 = cal_param.param_b5 - 4000; - /* calculate B3 */ - x1 = (b6*b6) >> 12; - x1 *= cal_param.b2; - x1 >>= 11; - - x2 = (cal_param.ac2*b6); - x2 >>= 11; - - x3 = x1 + x2; - - b3 = (((((long)cal_param.ac1) * 4 + x3) - << oversampling_setting) + 2) >> 2; - - /* calculate B4 */ - x1 = (cal_param.ac3 * b6) >> 13; - x2 = (cal_param.b1 * ((b6*b6) >> 12)) >> 16; - x3 = ((x1 + x2) + 2) >> 2; - b4 = (cal_param.ac4 * (unsigned long) (x3 + 32768)) >> 15; - if (!b4) - return INV_ERROR; - - b7 = ((unsigned long)(up - b3) * (50000>>oversampling_setting)); - if (b7 < 0x80000000) - pressure = (b7 << 1) / b4; - else - pressure = (b7 / b4) << 1; - - x1 = pressure >> 8; - x1 *= x1; - x1 = (x1 * PRESSURE_BMA085_PARAM_MG) >> 16; - x2 = (pressure * PRESSURE_BMA085_PARAM_MH) >> 16; - /* pressure in Pa */ - pressure += (x1 + x2 + PRESSURE_BMA085_PARAM_MI) >> 4; - - data[0] = (unsigned char)(pressure >> 16); - data[1] = (unsigned char)(pressure >> 8); - data[2] = (unsigned char)(pressure & 0xFF); - - return result; -} - -static struct ext_slave_descr bma085_descr = { - .init = NULL, - .exit = NULL, - .suspend = bma085_suspend, - .resume = bma085_resume, - .read = bma085_read, - .config = NULL, - .get_config = NULL, - .name = "bma085", - .type = EXT_SLAVE_TYPE_PRESSURE, - .id = PRESSURE_ID_BMA085, - .read_reg = 0xF6, - .read_len = 3, - .endian = EXT_SLAVE_BIG_ENDIAN, - .range = {0, 0}, -}; - -static -struct ext_slave_descr *bma085_get_slave_descr(void) -{ - return &bma085_descr; -} - -/* Platform data for the MPU */ -struct bma085_mod_private_data { - struct i2c_client *client; - struct ext_slave_platform_data *pdata; -}; - -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -static int bma085_mod_probe(struct i2c_client *client, - const struct i2c_device_id *devid) -{ - struct ext_slave_platform_data *pdata; - struct bma085_mod_private_data *private_data; - int result = 0; - - 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; - 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, - bma085_get_slave_descr); - if (result) { - dev_err(&client->adapter->dev, - "Slave registration failed: %s, %d\n", - devid->name, result); - goto out_free_memory; - } - - 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 bma085_mod_remove(struct i2c_client *client) -{ - struct bma085_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, - bma085_get_slave_descr); - - kfree(private_data); - return 0; -} - -static const struct i2c_device_id bma085_mod_id[] = { - { "bma085", PRESSURE_ID_BMA085 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, bma085_mod_id); - -static struct i2c_driver bma085_mod_driver = { - .class = I2C_CLASS_HWMON, - .probe = bma085_mod_probe, - .remove = bma085_mod_remove, - .id_table = bma085_mod_id, - .driver = { - .owner = THIS_MODULE, - .name = "bma085_mod", - }, - .address_list = normal_i2c, -}; - -static int __init bma085_mod_init(void) -{ - int res = i2c_add_driver(&bma085_mod_driver); - pr_info("%s: Probe name %s\n", __func__, "bma085_mod"); - if (res) - pr_err("%s failed\n", __func__); - return res; -} - -static void __exit bma085_mod_exit(void) -{ - pr_info("%s\n", __func__); - i2c_del_driver(&bma085_mod_driver); -} - -module_init(bma085_mod_init); -module_exit(bma085_mod_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Driver to integrate BMA085 sensor with the MPU"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("bma085_mod"); -/** - * @} -**/ diff --git a/drivers/misc/inv_mpu/sensors_core.c b/drivers/misc/inv_mpu/sensors_core.c deleted file mode 100644 index b652631..0000000 --- a/drivers/misc/inv_mpu/sensors_core.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Universal sensors core class - * - * Author : Ryunkyun Park <ryun.park@samsung.com> - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/err.h> -/* #include <linux/sensors_core.h> */ - -struct class *sensors_class; -static atomic_t sensor_count; -static DEFINE_MUTEX(sensors_mutex); - -/** - * Create sysfs interface - */ -static void set_sensor_attr(struct device *dev, - struct device_attribute *attributes[]) -{ - int i; - - for (i = 0; attributes[i] != NULL; i++) { - if ((device_create_file(dev, attributes[i])) < 0) { - pr_info("[SENSOR CORE] fail!!! device_create_file" \ - "( dev, attributes[%d] )\n", i); - } - } -} - -int sensors_register(struct device *dev, void *drvdata, - struct device_attribute *attributes[], char *name) -{ - int ret = 0; - - if (!sensors_class) { - sensors_class = class_create(THIS_MODULE, "sensors"); - if (IS_ERR(sensors_class)) - return PTR_ERR(sensors_class); - } - - mutex_lock(&sensors_mutex); - - dev = device_create(sensors_class, NULL, 0, drvdata, "%s", name); - - if (IS_ERR(dev)) { - ret = PTR_ERR(dev); - pr_err("[SENSORS CORE] device_create failed! [%d]\n", ret); - return ret; - } - - set_sensor_attr(dev, attributes); - - atomic_inc(&sensor_count); - - mutex_unlock(&sensors_mutex); - - return 0; -} - -void sensors_unregister(struct device *dev) -{ - /* TODO : Unregister device */ -} - -static int __init sensors_class_init(void) -{ - pr_info("[SENSORS CORE] sensors_class_init\n"); - sensors_class = class_create(THIS_MODULE, "sensors"); - - if (IS_ERR(sensors_class)) - return PTR_ERR(sensors_class); - - atomic_set(&sensor_count, 0); - sensors_class->dev_uevent = NULL; - - return 0; -} - -static void __exit sensors_class_exit(void) -{ - class_destroy(sensors_class); -} - -EXPORT_SYMBOL_GPL(sensors_register); -EXPORT_SYMBOL_GPL(sensors_unregister); - -/* exported for the APM Power driver, APM emulation */ -EXPORT_SYMBOL_GPL(sensors_class); - -subsys_initcall(sensors_class_init); -module_exit(sensors_class_exit); - -MODULE_DESCRIPTION("Universal sensors core class"); -MODULE_AUTHOR("Ryunkyun Park <ryun.park@samsung.com>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/misc/inv_mpu/slaveirq.c b/drivers/misc/inv_mpu/slaveirq.c deleted file mode 100644 index fdabcdd..0000000 --- a/drivers/misc/inv_mpu/slaveirq.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - $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/>. - $ - */ -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/stat.h> -#include <linux/irq.h> -#include <linux/signal.h> -#include <linux/miscdevice.h> -#include <linux/i2c.h> -#include <linux/i2c-dev.h> -#include <linux/poll.h> - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/uaccess.h> -#include <linux/io.h> -#include <linux/wait.h> -#include <linux/slab.h> - -#include <linux/mpu_411.h> -#include "slaveirq.h" -#include "mldl_cfg.h" - -/* function which gets slave data and sends it to SLAVE */ - -struct slaveirq_dev_data { - struct miscdevice dev; - struct i2c_client *slave_client; - struct mpuirq_data data; - wait_queue_head_t slaveirq_wait; - int irq; - int pid; - int data_ready; - int timeout; -}; - -/* The following depends on patch fa1f68db6ca7ebb6fc4487ac215bffba06c01c28 - * drivers: misc: pass miscdevice pointer via file private data - */ -static int slaveirq_open(struct inode *inode, struct file *file) -{ - /* Device node is availabe in the file->private_data, this is - * exactly what we want so we leave it there */ - struct slaveirq_dev_data *data = - container_of(file->private_data, struct slaveirq_dev_data, dev); - - dev_dbg(data->dev.this_device, - "%s current->pid %d\n", __func__, current->pid); - data->pid = current->pid; - return 0; -} - -static int slaveirq_release(struct inode *inode, struct file *file) -{ - struct slaveirq_dev_data *data = - container_of(file->private_data, struct slaveirq_dev_data, dev); - dev_dbg(data->dev.this_device, "slaveirq_release\n"); - return 0; -} - -/* read function called when from /dev/slaveirq is read */ -static ssize_t slaveirq_read(struct file *file, - char *buf, size_t count, loff_t *ppos) -{ - int len, err; - struct slaveirq_dev_data *data = - container_of(file->private_data, struct slaveirq_dev_data, dev); - - if (!data->data_ready && data->timeout && - !(file->f_flags & O_NONBLOCK)) { - wait_event_interruptible_timeout(data->slaveirq_wait, - data->data_ready, - data->timeout); - } - - if (data->data_ready && NULL != buf && count >= sizeof(data->data)) { - err = copy_to_user(buf, &data->data, sizeof(data->data)); - data->data.data_type = 0; - } else { - return 0; - } - if (err != 0) { - dev_err(data->dev.this_device, - "Copy to user returned %d\n", err); - return -EFAULT; - } - data->data_ready = 0; - len = sizeof(data->data); - return len; -} - -static unsigned int slaveirq_poll(struct file *file, - struct poll_table_struct *poll) -{ - int mask = 0; - struct slaveirq_dev_data *data = - container_of(file->private_data, struct slaveirq_dev_data, dev); - - poll_wait(file, &data->slaveirq_wait, poll); - if (data->data_ready) - mask |= POLLIN | POLLRDNORM; - return mask; -} - -/* ioctl - I/O control */ -static long slaveirq_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int retval = 0; - int tmp; - struct slaveirq_dev_data *data = - container_of(file->private_data, struct slaveirq_dev_data, dev); - - switch (cmd) { - case SLAVEIRQ_SET_TIMEOUT: - data->timeout = arg; - break; - - case SLAVEIRQ_GET_INTERRUPT_CNT: - tmp = data->data.interruptcount - 1; - if (data->data.interruptcount > 1) - data->data.interruptcount = 1; - - if (copy_to_user((int *)arg, &tmp, sizeof(int))) - return -EFAULT; - break; - case SLAVEIRQ_GET_IRQ_TIME: - if (copy_to_user((int *)arg, &data->data.irqtime, - sizeof(data->data.irqtime))) - return -EFAULT; - data->data.irqtime = 0; - break; - default: - retval = -EINVAL; - } - return retval; -} - -static irqreturn_t slaveirq_handler(int irq, void *dev_id) -{ - struct slaveirq_dev_data *data = (struct slaveirq_dev_data *)dev_id; - static int mycount; - struct timeval irqtime; - mycount++; - - data->data.interruptcount++; - - /* wake up (unblock) for reading data from userspace */ - data->data_ready = 1; - - do_gettimeofday(&irqtime); - data->data.irqtime = (((long long)irqtime.tv_sec) << 32); - data->data.irqtime += irqtime.tv_usec; - data->data.data_type |= 1; - - wake_up_interruptible(&data->slaveirq_wait); - - return IRQ_HANDLED; - -} - -/* define which file operations are supported */ -static const struct file_operations slaveirq_fops = { - .owner = THIS_MODULE, - .read = slaveirq_read, - .poll = slaveirq_poll, - -#if HAVE_COMPAT_IOCTL - .compat_ioctl = slaveirq_ioctl, -#endif -#if HAVE_UNLOCKED_IOCTL - .unlocked_ioctl = slaveirq_ioctl, -#endif - .open = slaveirq_open, - .release = slaveirq_release, -}; - -int slaveirq_init(struct i2c_adapter *slave_adapter, - struct ext_slave_platform_data *pdata, char *name) -{ - - int res; - struct slaveirq_dev_data *data; - - if (!pdata->irq) - return -EINVAL; - - pdata->irq_data = kzalloc(sizeof(*data), GFP_KERNEL); - data = (struct slaveirq_dev_data *)pdata->irq_data; - if (!data) - return -ENOMEM; - - data->dev.minor = MISC_DYNAMIC_MINOR; - data->dev.name = name; - data->dev.fops = &slaveirq_fops; - data->irq = pdata->irq; - data->pid = 0; - data->data_ready = 0; - data->timeout = 0; - - init_waitqueue_head(&data->slaveirq_wait); - - res = request_irq(data->irq, slaveirq_handler, - IRQF_TRIGGER_RISING | IRQF_SHARED, - data->dev.name, data); - - if (res) { - dev_err(&slave_adapter->dev, - "myirqtest: cannot register IRQ %d\n", data->irq); - goto out_request_irq; - } - - res = misc_register(&data->dev); - if (res < 0) { - dev_err(&slave_adapter->dev, - "misc_register returned %d\n", res); - goto out_misc_register; - } - - return res; - -out_misc_register: - free_irq(data->irq, data); -out_request_irq: - kfree(pdata->irq_data); - pdata->irq_data = NULL; - - return res; -} - -void slaveirq_exit(struct ext_slave_platform_data *pdata) -{ - struct slaveirq_dev_data *data = pdata->irq_data; - - if (!pdata->irq_data || data->irq <= 0) - return; - - dev_info(data->dev.this_device, "Unregistering %s\n", data->dev.name); - - free_irq(data->irq, data); - misc_deregister(&data->dev); - kfree(pdata->irq_data); - pdata->irq_data = NULL; -} diff --git a/drivers/misc/inv_mpu/slaveirq.h b/drivers/misc/inv_mpu/slaveirq.h deleted file mode 100644 index 6926634..0000000 --- a/drivers/misc/inv_mpu/slaveirq.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - $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/>. - $ - */ - -#ifndef __SLAVEIRQ__ -#define __SLAVEIRQ__ - -#include <linux/i2c-dev.h> - -#include <linux/mpu.h> -#include "mpuirq.h" - -#define SLAVEIRQ_SET_TIMEOUT _IOW(MPU_IOCTL, 0x50, unsigned long) -#define SLAVEIRQ_GET_INTERRUPT_CNT _IOR(MPU_IOCTL, 0x51, unsigned long) -#define SLAVEIRQ_GET_IRQ_TIME _IOR(MPU_IOCTL, 0x52, unsigned long) - -void slaveirq_exit(struct ext_slave_platform_data *pdata); -int slaveirq_init(struct i2c_adapter *slave_adapter, - struct ext_slave_platform_data *pdata, char *name); - -#endif diff --git a/drivers/misc/inv_mpu/timerirq.c b/drivers/misc/inv_mpu/timerirq.c deleted file mode 100644 index b7b0b1e..0000000 --- a/drivers/misc/inv_mpu/timerirq.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - $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/>. - $ - */ -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/stat.h> -#include <linux/signal.h> -#include <linux/miscdevice.h> -#include <linux/i2c.h> -#include <linux/i2c-dev.h> -#include <linux/poll.h> - -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/uaccess.h> -#include <linux/io.h> -#include <linux/timer.h> -#include <linux/slab.h> - -#include <linux/mpu_411.h> -#include "mltypes.h" -#include "timerirq.h" - -/* function which gets timer data and sends it to TIMER */ -struct timerirq_data { - int pid; - int data_ready; - int run; - int timeout; - unsigned long period; - struct mpuirq_data data; - struct completion timer_done; - wait_queue_head_t timerirq_wait; - struct timer_list timer; - struct miscdevice *dev; -}; - -static struct miscdevice *timerirq_dev_data; - -static void timerirq_handler(unsigned long arg) -{ - struct timerirq_data *data = (struct timerirq_data *)arg; - struct timeval irqtime; - - data->data.interruptcount++; - - data->data_ready = 1; - - do_gettimeofday(&irqtime); - 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); - - wake_up_interruptible(&data->timerirq_wait); - - if (data->run) - mod_timer(&data->timer, - jiffies + msecs_to_jiffies(data->period)); - else - complete(&data->timer_done); -} - -static int start_timerirq(struct timerirq_data *data) -{ - dev_dbg(data->dev->this_device, - "%s current->pid %d\n", __func__, current->pid); - - /* Timer already running... success */ - if (data->run) - return 0; - - /* Don't allow a period of 0 since this would fire constantly */ - if (!data->period) - return -EINVAL; - - data->run = true; - data->data_ready = false; - - init_completion(&data->timer_done); - setup_timer(&data->timer, timerirq_handler, (unsigned long)data); - - return mod_timer(&data->timer, - jiffies + msecs_to_jiffies(data->period)); -} - -static int stop_timerirq(struct timerirq_data *data) -{ - dev_dbg(data->dev->this_device, - "%s current->pid %lx\n", __func__, (unsigned long)data); - - if (data->run) { - data->run = false; - mod_timer(&data->timer, jiffies + 1); - wait_for_completion(&data->timer_done); - } - return 0; -} - -/* The following depends on patch fa1f68db6ca7ebb6fc4487ac215bffba06c01c28 - * drivers: misc: pass miscdevice pointer via file private data - */ -static int timerirq_open(struct inode *inode, struct file *file) -{ - /* Device node is availabe in the file->private_data, this is - * exactly what we want so we leave it there */ - struct miscdevice *dev_data = file->private_data; - struct timerirq_data *data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->dev = dev_data; - file->private_data = data; - data->pid = current->pid; - init_waitqueue_head(&data->timerirq_wait); - - dev_dbg(data->dev->this_device, - "%s current->pid %d\n", __func__, current->pid); - return 0; -} - -static int timerirq_release(struct inode *inode, struct file *file) -{ - struct timerirq_data *data = file->private_data; - dev_dbg(data->dev->this_device, "timerirq_release\n"); - if (data->run) - stop_timerirq(data); - kfree(data); - return 0; -} - -/* read function called when from /dev/timerirq is read */ -static ssize_t timerirq_read(struct file *file, - char *buf, size_t count, loff_t *ppos) -{ - int len, err; - struct timerirq_data *data = file->private_data; - - if (!data->data_ready && data->timeout && - !(file->f_flags & O_NONBLOCK)) { - wait_event_interruptible_timeout(data->timerirq_wait, - data->data_ready, - data->timeout); - } - - if (data->data_ready && NULL != buf && count >= sizeof(data->data)) { - err = copy_to_user(buf, &data->data, sizeof(data->data)); - data->data.data_type = 0; - } else { - return 0; - } - if (err != 0) { - dev_err(data->dev->this_device, - "Copy to user returned %d\n", err); - return -EFAULT; - } - data->data_ready = 0; - len = sizeof(data->data); - return len; -} - -static unsigned int timerirq_poll(struct file *file, - struct poll_table_struct *poll) -{ - int mask = 0; - struct timerirq_data *data = file->private_data; - - poll_wait(file, &data->timerirq_wait, poll); - if (data->data_ready) - mask |= POLLIN | POLLRDNORM; - return mask; -} - -/* ioctl - I/O control */ -static long timerirq_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - int retval = 0; - int tmp; - struct timerirq_data *data = file->private_data; - - dev_dbg(data->dev->this_device, - "%s current->pid %d, %d, %ld\n", - __func__, current->pid, cmd, arg); - - if (!data) - return -EFAULT; - - switch (cmd) { - case TIMERIRQ_SET_TIMEOUT: - data->timeout = arg; - break; - case TIMERIRQ_GET_INTERRUPT_CNT: - tmp = data->data.interruptcount - 1; - if (data->data.interruptcount > 1) - data->data.interruptcount = 1; - - if (copy_to_user((int *)arg, &tmp, sizeof(int))) - return -EFAULT; - break; - case TIMERIRQ_START: - data->period = arg; - retval = start_timerirq(data); - break; - case TIMERIRQ_STOP: - retval = stop_timerirq(data); - break; - default: - retval = -EINVAL; - } - return retval; -} - -/* define which file operations are supported */ -static const struct file_operations timerirq_fops = { - .owner = THIS_MODULE, - .read = timerirq_read, - .poll = timerirq_poll, - -#if HAVE_COMPAT_IOCTL - .compat_ioctl = timerirq_ioctl, -#endif -#if HAVE_UNLOCKED_IOCTL - .unlocked_ioctl = timerirq_ioctl, -#endif - .open = timerirq_open, - .release = timerirq_release, -}; - -static int __init timerirq_init(void) -{ - - int res; - static struct miscdevice *data; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - timerirq_dev_data = data; - data->minor = MISC_DYNAMIC_MINOR; - data->name = "timerirq"; - data->fops = &timerirq_fops; - - res = misc_register(data); - if (res < 0) { - dev_err(data->this_device, "misc_register returned %d\n", res); - return res; - } - - return res; -} - -module_init(timerirq_init); - -static void __exit timerirq_exit(void) -{ - struct miscdevice *data = timerirq_dev_data; - - dev_info(data->this_device, "Unregistering %s\n", data->name); - - misc_deregister(data); - kfree(data); - - timerirq_dev_data = NULL; -} - -module_exit(timerirq_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Timer IRQ device driver."); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("timerirq"); diff --git a/drivers/misc/inv_mpu/timerirq.h b/drivers/misc/inv_mpu/timerirq.h deleted file mode 100644 index f69f07a..0000000 --- a/drivers/misc/inv_mpu/timerirq.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - $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/>. - $ - */ - -#ifndef __TIMERIRQ__ -#define __TIMERIRQ__ - -#include <linux/mpu.h> - -#define TIMERIRQ_SET_TIMEOUT _IOW(MPU_IOCTL, 0x60, unsigned long) -#define TIMERIRQ_GET_INTERRUPT_CNT _IOW(MPU_IOCTL, 0x61, unsigned long) -#define TIMERIRQ_START _IOW(MPU_IOCTL, 0x62, unsigned long) -#define TIMERIRQ_STOP _IO(MPU_IOCTL, 0x63) - -#endif |