Index: linux-2.6.35/drivers/misc/mpu3050/compass/mmc314x.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.35/drivers/misc/mpu3050/compass/mmc314x.c 2010-12-22 14:09:28.000000000 +0800 @@ -0,0 +1,183 @@ +/* + $License: + Copyright (C) 2010 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 - Accelerometer Driver Layer) + * @brief Provides the interface to setup and handle an accelerometers + * connected to the secondary I2C interface of the gyroscope. + * + * @{ + * @file mmc314x.c + * @brief Magnetometer setup and handling methods for ???? compass. + */ + +/* ------------------ */ +/* - Include Files. - */ +/* ------------------ */ + +#ifdef __KERNEL__ +#include <linux/module.h> +#endif + +#include "mpu.h" +#include "mlsl.h" +#include "mlos.h" + +#include <log.h> +#undef MPL_LOG_TAG +#define MPL_LOG_TAG "MPL-compass" + +/* --------------------- */ +/* - Variables. - */ +/* --------------------- */ + +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) + +/***************************************** + Accelerometer Initialization Functions +*****************************************/ + +int mmc314x_suspend(void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata) +{ + int result = ML_SUCCESS; + + return result; +} + +int mmc314x_resume(void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata) +{ + + int result; + result = + MLSLSerialWriteSingle(mlsl_handle, pdata->address, + MMC314X_REG_ST, MMC314X_CNTL_MODE_RESET); + ERROR_CHECK(result); + MLOSSleep(10); + result = + MLSLSerialWriteSingle(mlsl_handle, pdata->address, + MMC314X_REG_ST, MMC314X_CNTL_MODE_SET); + ERROR_CHECK(result); + MLOSSleep(10); + read_count = 1; + return ML_SUCCESS; +} + +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 = + MLSLSerialRead(mlsl_handle, pdata->address, MMC314X_REG_X_MSB, + 6, (unsigned char *) data); + ERROR_CHECK(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 = + MLSLSerialWriteSingle(mlsl_handle, + pdata->address, + MMC314X_REG_ST, + MMC314X_CNTL_MODE_RESET); + ERROR_CHECK(result); + reset_mode = 0; + return ML_ERROR_COMPASS_DATA_NOT_READY; + } else { + result = + MLSLSerialWriteSingle(mlsl_handle, + pdata->address, + MMC314X_REG_ST, + MMC314X_CNTL_MODE_SET); + ERROR_CHECK(result); + reset_mode = 1; + read_count++; + return ML_ERROR_COMPASS_DATA_NOT_READY; + } + } + result = + MLSLSerialWriteSingle(mlsl_handle, pdata->address, + MMC314X_REG_ST, + MMC314X_CNTL_MODE_WAKE_UP); + ERROR_CHECK(result); + read_count++; + + return ML_SUCCESS; +} + +struct ext_slave_descr mmc314x_descr = { + /*.suspend = */ mmc314x_suspend, + /*.resume = */ mmc314x_resume, + /*.read = */ mmc314x_read, + /*.name = */ "mmc314x", + /*.type = */ EXT_SLAVE_TYPE_COMPASS, + /*.id = */ COMPASS_ID_MMC314X, + /*.reg = */ 0x01, + /*.len = */ 6, + /*.endian = */ EXT_SLAVE_BIG_ENDIAN, + /*.range = */ {400, 0}, +}; + +struct ext_slave_descr *mmc314x_get_slave_descr(void) +{ + return &mmc314x_descr; +} + +#ifdef __KERNEL__ +EXPORT_SYMBOL(mmc314x_get_slave_descr); +#endif + +/** + * @} +**/ Index: linux-2.6.35/include/linux/mpu.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.35/include/linux/mpu.h 2010-12-22 22:20:25.000000000 +0800 @@ -0,0 +1,368 @@ +/* + $License: + Copyright (C) 2010 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_H_ +#define __MPU_H_ + +#include <linux/i2c.h> + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#ifdef M_HW +#include "mpu6000.h" +#else +#include "mpu3050.h" +#endif + +#define DRIVER_VERSION "v3.2.0-2" + +/* IOCTL commands for /dev/mpu */ +#define MPU_SET_MPU_CONFIG (0x00) +#define MPU_SET_INT_CONFIG (0x01) +#define MPU_SET_EXT_SYNC (0x02) +#define MPU_SET_FULL_SCALE (0x03) +#define MPU_SET_LPF (0x04) +#define MPU_SET_CLK_SRC (0x05) +#define MPU_SET_DIVIDER (0x06) +#define MPU_SET_LEVEL_SHIFTER (0x07) +#define MPU_SET_DMP_ENABLE (0x08) +#define MPU_SET_FIFO_ENABLE (0x09) +#define MPU_SET_DMP_CFG1 (0x0a) +#define MPU_SET_DMP_CFG2 (0x0b) +#define MPU_SET_OFFSET_TC (0x0c) +#define MPU_SET_RAM (0x0d) + +#define MPU_SET_PLATFORM_DATA (0x0e) + +#define MPU_GET_MPU_CONFIG (0x80) +#define MPU_GET_INT_CONFIG (0x81) +#define MPU_GET_EXT_SYNC (0x82) +#define MPU_GET_FULL_SCALE (0x83) +#define MPU_GET_LPF (0x84) +#define MPU_GET_CLK_SRC (0x85) +#define MPU_GET_DIVIDER (0x86) +#define MPU_GET_LEVEL_SHIFTER (0x87) +#define MPU_GET_DMP_ENABLE (0x88) +#define MPU_GET_FIFO_ENABLE (0x89) +#define MPU_GET_DMP_CFG1 (0x8a) +#define MPU_GET_DMP_CFG2 (0x8b) +#define MPU_GET_OFFSET_TC (0x8c) +#define MPU_GET_RAM (0x8d) + +#define MPU_READ_REGISTER (0x40) +#define MPU_WRITE_REGISTER (0x41) +#define MPU_READ_MEMORY (0x42) +#define MPU_WRITE_MEMORY (0x43) + +#define MPU_SUSPEND (0x44) +#define MPU_RESUME (0x45) +#define MPU_READ_COMPASS (0x46) +#define MPU_READ_ACCEL (0x47) + +/* Structure for the following IOCTL's: + MPU_SET_RAM + MPU_GET_RAM + MPU_READ_REGISTER + MPU_WRITE_REGISTER + MPU_READ_MEMORY + MPU_WRITE_MEMORY +*/ +struct mpu_read_write { + unsigned short address; + unsigned short length; + unsigned char *data; +}; + +/* Structure for the following IOCTL's + MPU_SUSPEND + MPU_RESUME +*/ +struct mpu_suspend_resume { + int gyro; + int accel; + int compass; +}; + +enum ext_slave_type { + EXT_SLAVE_TYPE_GYROSCOPE, + EXT_SLAVE_TYPE_ACCELEROMETER, + EXT_SLAVE_TYPE_COMPASS, + /*EXT_SLAVE_TYPE_PRESSURE, */ + /*EXT_SLAVE_TYPE_TEMPERATURE */ +}; + +enum ext_slave_id { + ID_INVALID = 0, + + ACCEL_ID_LIS331, + ACCEL_ID_LSM303, + ACCEL_ID_KXSD9, + ACCEL_ID_KXTF9, + ACCEL_ID_BMA150, + ACCEL_ID_BMA023 = ACCEL_ID_BMA150, + ACCEL_ID_BMA222, + ACCEL_ID_ADI346, + ACCEL_ID_MMA8450, + ACCEL_ID_MMA8451, + + COMPASS_ID_AKM, + COMPASS_ID_AICHI, + COMPASS_ID_YAS529, + COMPASS_ID_HMC5883, + COMPASS_ID_LSM303, + COMPASS_ID_MMC314X, + COMPASS_ID_HSCDTD002B, + + ACCEL_ID_LIS331_LPP, +}; + +enum ext_slave_endian { + EXT_SLAVE_BIG_ENDIAN, + EXT_SLAVE_LITTLE_ENDIAN, + EXT_SLAVE_FS8_BIG_ENDIAN, + EXT_SLAVE_FS16_BIG_ENDIAN, +}; + +enum ext_slave_bus { + EXT_SLAVE_BUS_INVALID = -1, + EXT_SLAVE_BUS_PRIMARY = 0, + EXT_SLAVE_BUS_SECONDARY = 1 +}; + +int mpu_sysfs_init(struct i2c_client *); +void mpu_sysfs_exit(void); + +/** + * struct ext_slave_platform_data - Platform data for mpu3050 slave devices + * + * @get_slave_descr: Function pointer to retrieve the struct ext_slave_descr + * for this slave + * @adapt_num: the I2C adapter number. + * @bus: the bus the slave is attached to: enum ext_slave_bus + * @address: the I2C slave address of the slave device. + * @orientation: the mounting matrix of the device relative to MPU. + * @private_data: additional data, user customizable. Not touched by the MPU + * driver. + * + * The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct ext_slave_platform_data { + struct ext_slave_descr *(*get_slave_descr) (void); + int adapt_num; + int bus; + unsigned char address; + signed char orientation[9]; + void *private_data; +}; + + +struct tFixPntRange { + long mantissa; + long fraction; +}; + +/** + * struct ext_slave_descr - Description of the slave device for programming + * + * @suspend: function pointer to put the device in suspended state + * @resume: function pointer to put the device in running state + * @read: function that reads the device data + * + * @name: text name of the device + * @type: device type. enum ext_slave_type + * @id: enum ext_slave_id + * @reg: starting register address to retrieve data. + * @len: length in bytes of the sensor data. Should be 6. + * @endian: byte order of the data. enum ext_slave_endian + * @range: full scale range of the slave ouput: struct tFixPntRange + * + * Defines the functions and information about the slave the mpu3050 needs to + * use the slave device. + */ +struct ext_slave_descr { + int (*suspend) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*resume) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata); + int (*read) (void *mlsl_handle, + struct ext_slave_descr *slave, + struct ext_slave_platform_data *pdata, + unsigned char *data); + + char *name; + unsigned char type; + unsigned char id; + unsigned char reg; + unsigned int len; + unsigned char endian; + struct tFixPntRange range; +}; + +/** + * struct mpu3050_platform_data - Platform data for the mpu3050 driver + * @int_config: Bits [7:3] of the int config register. + * @orientation: Orientation matrix of the gyroscope + * @level_shifter: 0: VLogic 1: VDD + * @accel: Accel platform data + * @compass: Compass platform data + * + * Contains platform specific information on how to configure the MPU3050 to + * work on this platform. The orientation matricies are 3x3 rotation matricies + * that are applied to the data to rotate from the mounting orientation to the + * platform orientation. The values must be one of 0, 1, or -1 and each row and + * column should have exactly 1 non-zero value. + */ +struct mpu3050_platform_data { + unsigned char int_config; + signed char orientation[MPU_NUM_AXES * MPU_NUM_AXES]; + unsigned char level_shifter; + struct ext_slave_platform_data accel; + struct ext_slave_platform_data compass; +}; + + +/* + Accelerometer +*/ +#define get_accel_slave_descr NULL + +#ifdef CONFIG_SENSORS_ADXL346 /* ADI accelerometer */ +struct ext_slave_descr *adxl346_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr adxl346_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_BMA023 /* Bosch 023 accelerometer */ +struct ext_slave_descr *bma023_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr bma023_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_BMA150 /* Bosch accelerometer */ +struct ext_slave_descr *bma150_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr bma150_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_BMA222 /* Bosch 222 accelerometer */ +struct ext_slave_descr *bma222_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr bma222_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_KXSD9 /* Kionix accelerometer */ +struct ext_slave_descr *kxsd9_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr kxsd9_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_KXTF9 /* Kionix accelerometer */ +struct ext_slave_descr *kxtf9_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr kxtf9_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_LIS331DLH /* ST accelerometer */ +struct ext_slave_descr *lis331dlh_get_slave_descr(void); +struct ext_slave_descr *lis331dlh_lpp_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr lis331dlh_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_LSM303DLHA /* ST accelerometer */ +struct ext_slave_descr *lsm303dlha_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr lsm303dlha_get_slave_descr +#endif + +/* MPU6000 Accel */ +#if defined(CONFIG_SENSORS_MPU6000) || defined(CONFIG_SENSORS_MPU6000_MODULE) +struct ext_slave_descr *mantis_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr mantis_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_MMA8450 /* Freescale accelerometer */ +struct ext_slave_descr *mma8450_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr mma8450_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_MMA8451 /* Freescale accelerometer */ +struct ext_slave_descr *mma8451_get_slave_descr(void); +#undef get_accel_slave_descr +#define get_accel_slave_descr mma8451_get_slave_descr +#endif + + +/* + Compass +*/ +#define get_compass_slave_descr NULL + +#ifdef CONFIG_SENSORS_AK8975 /* AKM compass */ +struct ext_slave_descr *ak8975_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr ak8975_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_AMI304 /* AICHI Steel compass */ +struct ext_slave_descr *ami304_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr ami304_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_HMC5883 /* Honeywell compass */ +struct ext_slave_descr *hmc5883_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr hmc5883_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_MMC314X /* MEMSIC compass */ +struct ext_slave_descr *mmc314x_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr mmc314x_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_LSM303DLHM /* ST compass */ +struct ext_slave_descr *lsm303dlhm_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr lsm303dlhm_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_YAS529 /* Yamaha compass */ +struct ext_slave_descr *yas529_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr yas529_get_slave_descr +#endif + +#ifdef CONFIG_SENSORS_HSCDTD002B /* Alps compass */ +struct ext_slave_descr *hscdtd002b_get_slave_descr(void); +#undef get_compass_slave_descr +#define get_compass_slave_descr hscdtd002b_get_slave_descr +#endif + +#endif /* __MPU_H_ */ Index: linux-2.6.35/include/linux/mpu6000.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.35/include/linux/mpu6000.h 2010-12-22 14:09:28.000000000 +0800 @@ -0,0 +1,401 @@ + +/* + $License: + Copyright (C) 2010 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 mpu6000.h + * @brief + */ + +#ifndef __MPU6000_H_ +#define __MPU6000_H_ + +#define MPU_NAME "mpu6000" +#define DEFAULT_MPU_SLAVEADDR 0x68 + +/*==== M_HW REGISTER SET ====*/ +enum { + MPUREG_XG_OFFS_TC = 0, + MPUREG_YG_OFFS_TC, + MPUREG_ZG_OFFS_TC, + MPUREG_X_FINE_GAIN, + MPUREG_Y_FINE_GAIN, + MPUREG_Z_FINE_GAIN, + MPUREG_XA_OFFS_H, + MPUREG_XA_OFFS_L_TC, + MPUREG_YA_OFFS_H, + MPUREG_YA_OFFS_L_TC, + MPUREG_ZA_OFFS_H, + MPUREG_ZA_OFFS_L_TC, /* 0xB */ + MPUREG_0C_RSVD, + MPUREG_0D_RSVD, + MPUREG_0E_RSVD, + MPUREG_0F_RSVD, + MPUREG_10_RSVD, + MPUREG_11_RSVD, + MPUREG_12_RSVD, + MPUREG_XG_OFFS_USRH, + MPUREG_XG_OFFS_USRL, + MPUREG_YG_OFFS_USRH, + MPUREG_YG_OFFS_USRL, + MPUREG_ZG_OFFS_USRH, + MPUREG_ZG_OFFS_USRL, + MPUREG_SMPLRT_DIV, /* 0x19 */ + MPUREG_CONFIG, /* 0x1A ==> DLPF_FS_SYNC */ + MPUREG_GYRO_CONFIG, + MPUREG_ACCEL_CONFIG, + MPUREG_ACCEL_FF_THR, + MPUREG_ACCEL_FF_DUR, + MPUREG_ACCEL_MOT_THR, + MPUREG_ACCEL_MOT_DUR, + MPUREG_ACCEL_ZRMOT_THR, + MPUREG_ACCEL_ZRMOT_DUR, + MPUREG_FIFO_EN, /* 0x23 */ + MPUREG_I2C_MST_CTRL, + MPUREG_I2C_SLV0_ADDR, /* 0x25 */ + MPUREG_I2C_SLV0_REG, + MPUREG_I2C_SLV0_CTRL, + MPUREG_I2C_SLV1_ADDR, /* 0x28 */ + MPUREG_I2C_SLV1_REG_PASSWORD, + MPUREG_I2C_SLV1_CTRL, + MPUREG_I2C_SLV2_ADDR, /* 0x2B */ + MPUREG_I2C_SLV2_REG, + MPUREG_I2C_SLV2_CTRL, + MPUREG_I2C_SLV3_ADDR, /* 0x2E */ + MPUREG_I2C_SLV3_REG, + MPUREG_I2C_SLV3_CTRL, + MPUREG_I2C_SLV4_ADDR, /* 0x31 */ + MPUREG_I2C_SLV4_REG, + MPUREG_I2C_SLV4_DO, + MPUREG_I2C_SLV4_CTRL, + MPUREG_I2C_SLV4_DI, + MPUREG_I2C_MST_STATUS, /* 0x36 */ + MPUREG_INT_PIN_CFG, /* 0x37 ==> -* INT_CFG */ + MPUREG_INT_ENABLE, /* 0x38 ==> / */ + MPUREG_DMP_INT_STATUS, /* 0x39 */ + MPUREG_INT_STATUS, /* 0x3A */ + MPUREG_ACCEL_XOUT_H, /* 0x3B */ + MPUREG_ACCEL_XOUT_L, + MPUREG_ACCEL_YOUT_H, + MPUREG_ACCEL_YOUT_L, + MPUREG_ACCEL_ZOUT_H, + MPUREG_ACCEL_ZOUT_L, + MPUREG_TEMP_OUT_H, /* 0x41 */ + MPUREG_TEMP_OUT_L, + MPUREG_GYRO_XOUT_H, /* 0x43 */ + MPUREG_GYRO_XOUT_L, + MPUREG_GYRO_YOUT_H, + MPUREG_GYRO_YOUT_L, + MPUREG_GYRO_ZOUT_H, + MPUREG_GYRO_ZOUT_L, + MPUREG_EXT_SLV_SENS_DATA_00, /* 0x49 */ + MPUREG_EXT_SLV_SENS_DATA_01, + MPUREG_EXT_SLV_SENS_DATA_02, + MPUREG_EXT_SLV_SENS_DATA_03, + MPUREG_EXT_SLV_SENS_DATA_04, + MPUREG_EXT_SLV_SENS_DATA_05, + MPUREG_EXT_SLV_SENS_DATA_06, /* 0x4F */ + MPUREG_EXT_SLV_SENS_DATA_07, + MPUREG_EXT_SLV_SENS_DATA_08, + MPUREG_EXT_SLV_SENS_DATA_09, + MPUREG_EXT_SLV_SENS_DATA_10, + MPUREG_EXT_SLV_SENS_DATA_11, + MPUREG_EXT_SLV_SENS_DATA_12, /* 0x55 */ + MPUREG_EXT_SLV_SENS_DATA_13, + MPUREG_EXT_SLV_SENS_DATA_14, + MPUREG_EXT_SLV_SENS_DATA_15, + MPUREG_EXT_SLV_SENS_DATA_16, + MPUREG_EXT_SLV_SENS_DATA_17, + MPUREG_EXT_SLV_SENS_DATA_18, /* 0x5B */ + MPUREG_EXT_SLV_SENS_DATA_19, + MPUREG_EXT_SLV_SENS_DATA_20, + MPUREG_EXT_SLV_SENS_DATA_21, + MPUREG_EXT_SLV_SENS_DATA_22, + MPUREG_EXT_SLV_SENS_DATA_23, + ACCEL_INTEL_STATUS, /* 0x61 */ + MPUREG_62_RSVD, + MPUREG_63_RSVD, + MPUREG_64_RSVD, + MPUREG_65_RSVD, + MPUREG_66_RSVD, + MPUREG_67_RSVD, + SIGNAL_PATH_RESET, /* 0x68 */ + ACCEL_INTEL_CTRL, /* 0x69 */ + MPUREG_USER_CTRL, /* 0x6A */ + MPUREG_PWR_MGMT_1, /* 0x6B */ + MPUREG_PWR_MGMT_2, + MPUREG_BANK_SEL, /* 0x6D */ + MPUREG_MEM_START_ADDR, /* 0x6E */ + MPUREG_MEM_R_W, /* 0x6F */ + MPUREG_PRGM_STRT_ADDRH, + MPUREG_PRGM_STRT_ADDRL, + MPUREG_FIFO_COUNTH, /* 0x72 */ + MPUREG_FIFO_COUNTL, + MPUREG_FIFO_R_W, /* 0x74 */ + MPUREG_WHOAMI, /* 0x75,117 */ + + NUM_OF_MPU_REGISTERS /* = 0x76,118 */ +}; + +/*==== M_HW 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 +}; + + +/*==== M_HW 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 M_HW ====*/ + +/*---- M_HW '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 +/*---- M_HW 'CONFIG' register (1A) ----*/ +/*NONE 0xC0 */ +#define BITS_EXT_SYNC_SET 0x38 +#define BITS_DLPF_CFG 0x07 +/*---- M_HW '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 */ +/*---- M_HW 'ACCEL_CONFIG' register (1C) ----*/ +#define BITS_ACCEL_FS_SEL 0x18 +#define BITS_ACCEL_HPF 0x07 +/*---- M_HW 'I2C_MST_CTRL' register (24) ----*/ +#define BIT_MULT_MST_DIS 0x80 +#define BIT_WAIT_FOR_ES 0x40 +#define BIT_I2C_MST_VDDIO 0x20 +/*NONE 0x10 */ +#define BITS_I2C_MST_CLK 0x0F +/*---- M_HW 'I2C_SLV?_CTRL' register (27,2A,2D,30) ----*/ +#define BIT_SLV_ENABLE 0x80 +#define BIT_SLV_BYTE_SW 0x40 +/*NONE 0x20 */ +#define BIT_SLV_GRP 0x10 +#define BITS_SLV_LENG 0x0F +/*---- M_HW 'I2C_SLV4_ADDR' register (31) ----*/ +#define BIT_I2C_SLV4_RNW 0x80 +/*---- M_HW 'I2C_SLV4_CTRL' register (34) ----*/ +#define BIT_I2C_SLV4_EN 0x80 +#define BIT_SLV4_DONE_INT_EN 0x40 +/*NONE 0x3F */ +/*---- M_HW 'I2C_MST_STATUS' register (36) ----*/ +#define BIT_PASSTHROUGH 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 +/*---- M_HW '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 +/*---- M_HW '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 +/*---- M_HW '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 +/*---- M_HW '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 +/*---- M_HW 'BANK_SEL' register (6D) ----*/ +#define BIT_PRFTCH_EN 0x40 +#define BIT_CFG_USER_BANK 0x20 +#define BITS_MEM_SEL 0x1f +/*---- M_HW '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 +/*---- M_HW 'PWR_MGMT_1' register (6B) ----*/ +#define BIT_H_RESET 0x80 +#define BITS_PWRSEL 0x70 +#define BIT_WKUP_INT 0x08 +#define BITS_CLKSEL 0x07 +/*---- M_HW 'PWR_MGMT_2' register (6C) ----*/ +#define BITS_LPA_WAKE_CTRL 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 MPU_NUM_AXES (3) /* although it has 6, this refers to the gyros */ + +/*----------------------------------------------------------------------------*/ +/*---- Alternative names to take care of conflicts with current mpu3050.h ----*/ +/*----------------------------------------------------------------------------*/ + +/*-- registers --*/ +#define MPUREG_DLPF_FS_SYNC MPUREG_CONFIG /* 0x1A */ + +#define MPUREG_PRODUCT_ID MPUREG_WHOAMI /* 0x75 HACK!*/ +#define MPUREG_PWR_MGM MPUREG_PWR_MGMT_1 /* 0x6B */ +#define MPUREG_FIFO_EN1 MPUREG_FIFO_EN /* 0x23 */ +#define MPUREG_DMP_CFG_1 MPUREG_PRGM_STRT_ADDRH /* 0x70 */ +#define MPUREG_DMP_CFG_2 MPUREG_PRGM_STRT_ADDRL /* 0x71 */ +#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 */ +#define MPUREG_AUX_SLV_ADDR MPUREG_I2C_SLV0_ADDR /* 0x25 */ +#define MPUREG_ACCEL_BURST_ADDR MPUREG_I2C_SLV0_REG /* 0x26 */ + +/*-- 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 + + + +/*---- M_HW Silicon Revisions ----*/ +#define MPU_SILICON_REV_A1 1 /* M_HW A1 Device */ +#define MPU_SILICON_REV_B1 2 /* M_HW B1 Device */ + +/*---- 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 DLPF_FS_SYNC_VALUE(ext_sync, full_scale, lpf) \ + ((ext_sync << 5) | (full_scale << 3) | lpf) + +#endif /* __IMU6000_H_ */ Index: linux-2.6.35/drivers/misc/mpu3050/mpu-sysfs.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.35/drivers/misc/mpu3050/mpu-sysfs.c 2010-12-22 23:56:32.000000000 +0800 @@ -0,0 +1,335 @@ +#include <linux/i2c.h> +#include <linux/i2c-dev.h> +#include <linux/ctype.h> + +#include "mpu-i2c.h" +#include "mldl_cfg.h" +#include "mpu.h" +#include "accel/bma023.h" + +#include <linux/kobject.h> + +#define COMPASS_PWR_REG 0x1B + +static struct i2c_adapter *accel_adapter; +static struct i2c_adapter *compass_adapter; +static struct ext_slave_descr* accel_slave_descr; +static const char *msg[] = {"off","on"}; +struct i2c_client *this_client; + + +static ssize_t show_driver_version_value(struct device *dev, struct device_attribute *attr, char *buf){ + return sprintf(buf, "%s\n", DRIVER_VERSION); +} +static ssize_t show_gyro_data_value(struct device *dev, struct device_attribute *attr, char *buf){ + unsigned char data[6]; + signed short x, y, z; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_GYRO_XOUT_H, 6, data); + x = data[0]; + x = x<<8 | data[1]; + y = data[2]; + y = y<<8 | data[3]; + z = data[4]; + z = z<<8 | data[5]; + return sprintf(buf, "%d %d %d\n", x, y, z); +} + +static ssize_t show_gyro_x_standby_value(struct device *dev, struct device_attribute *attr, char *buf){ + char data; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + return sprintf(buf, "%s\n", msg[(data&BIT_STBY_XG)?1:0]); +} + +static ssize_t store_gyro_x_standby_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + char data; + if(!count) return count; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + if(buf[0] == '1') + MLSLSerialWriteSingle( this_client->adapter, this_client->addr, MPUREG_PWR_MGM, data | BIT_STBY_XG ); + else if(buf[0] == '0') + MLSLSerialWriteSingle( this_client->adapter, this_client->addr, MPUREG_PWR_MGM, data & ~BIT_STBY_XG); + else + printk("error: invalid command %s for gyro_x_standby\n",buf); + return count; +} + +static ssize_t show_gyro_y_standby_value(struct device *dev, struct device_attribute *attr, char *buf){ + char data; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + return sprintf(buf, "%s\n", msg[(data&BIT_STBY_YG)?1:0]); +} + +static ssize_t store_gyro_y_standby_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + char data; + if(!count) return count; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + if(buf[0] == '1') + MLSLSerialWriteSingle( this_client->adapter, this_client->addr, MPUREG_PWR_MGM, data | BIT_STBY_YG ); + else if(buf[0] == '0') + MLSLSerialWriteSingle( this_client->adapter, this_client->addr, MPUREG_PWR_MGM, data & ~BIT_STBY_YG); + else + printk("error: invalid command %s for gyro_y_standby\n",buf); + return count; +} + +static ssize_t show_gyro_z_standby_value(struct device *dev, struct device_attribute *attr, char *buf){ + char data; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + return sprintf(buf, "%s\n", msg[(data&BIT_STBY_ZG)?1:0]); +} + +static ssize_t store_gyro_z_standby_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + char data; + if(!count) return count; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + if(buf[0] == '1') + MLSLSerialWriteSingle( this_client->adapter, this_client->addr, MPUREG_PWR_MGM, data | BIT_STBY_ZG ); + else if(buf[0] == '0') + MLSLSerialWriteSingle( this_client->adapter, this_client->addr, MPUREG_PWR_MGM, data & ~BIT_STBY_ZG); + else + printk("error: invalid command %s for gyro_z_standby\n",buf); + return count; +} + +static ssize_t show_gyro_power_mode_value(struct device *dev, struct device_attribute *attr, char *buf){ + char data; + MLSLSerialRead(this_client->adapter, this_client->addr, MPUREG_PWR_MGM, 1, &data); + data &= BIT_SLEEP; + return sprintf(buf, "%s\n", data? msg[0] : msg[1]); +} + +static ssize_t store_gyro_power_mode_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + if(!count) return count; + if(buf[0] == '1') + mpu3050_resume(mldl_cfg, this_client->adapter, accel_adapter, compass_adapter, 0, 0); + else if(buf[0] == '0') + mpu3050_suspend(mldl_cfg, this_client->adapter, accel_adapter, compass_adapter, 0, 0); + else + printk("error: invalid command %s for gyro_power_mode\n",buf); + return count; +} + +#ifdef CONFIG_SENSORS_BMA023 +static ssize_t show_accel_name_value(struct device *dev, struct device_attribute *attr, char *buf){ + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + return sprintf(buf, "%s\n", (mldl_cfg->accel) ? mldl_cfg->accel->name : "No Accel"); +} + +static ssize_t show_accel_data_value(struct device *dev, struct device_attribute *attr, char *buf){ + signed short xyz_axes[3]; + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + if(bma023_read_accel_xyz(accel_adapter, mldl_cfg, xyz_axes)) + return sprintf(buf, "Can't get axes data\n"); + return sprintf(buf, "%d,%d,%d\n", xyz_axes[0], xyz_axes[1], xyz_axes[2]); +} + +static ssize_t show_accel_power_mode_value(struct device *dev, struct device_attribute *attr, char *buf){ + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%s\n", bma023_get_power_mode(accel_adapter, mldl_cfg) ? msg[0] : msg[1]); +} + +static ssize_t store_accel_power_mode_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + if(!count && !accel_adapter) return count; + if(buf[0] == '1') + mldl_cfg->accel->resume(accel_adapter, mldl_cfg->accel, &mldl_cfg->pdata->accel); + else if(buf[0] == '0') + mldl_cfg->accel->suspend(accel_adapter, mldl_cfg->accel, &mldl_cfg->pdata->accel); + else + printk("error: invalid command %s for accel_power_mode\n",buf); + return count; +} + +static ssize_t show_accel_bw_value(struct device *dev, struct device_attribute *attr, char *buf){ + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%d Hz\n", bma023_get_bandwidth()); +} + +static ssize_t store_accel_bw_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + int ret; + if(!count && !accel_adapter) return count; + ret = bma023_set_bandwidth(accel_adapter, buf); + if(ret < 0) + printk("accel bw set failed\n"); + return count; +} + +static ssize_t show_accel_range_value(struct device *dev, struct device_attribute *attr, char *buf){ + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%d g\n", bma023_get_range()); +} + +static ssize_t store_accel_range_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + int ret; + if(!count && !accel_adapter) return count; + ret = bma023_set_range(accel_adapter, buf); + if(ret < 0) + printk("accel range set failed\n"); + return count; +} + +static ssize_t show_accel_h_dur_value(struct device *dev, struct device_attribute *ay25ttr, char *buf){ + struct accel_config *aconfig = accel_get_config(); + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%d\n", aconfig->hg_dur); +} + +static ssize_t store_accel_h_dur_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + if(!count && !accel_adapter) return count; + if(bma023_set_hg_duration(accel_adapter, buf) < 0) + printk("accel hg duration set failed\n"); + return count; +} + +static ssize_t show_accel_h_thres_value(struct device *dev, struct device_attribute *attr, char *buf){ + struct accel_config *aconfig = accel_get_config(); + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%d\n", aconfig->hg_thres); +} + +static ssize_t store_accel_h_thres_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + if(!count && !accel_adapter) return count; + if(bma023_set_hg_threshold(accel_adapter, buf) < 0) + printk("accel hg threshold set failed\n"); + return count; +} + +static ssize_t show_accel_l_dur_value(struct device *dev, struct device_attribute *ay25ttr, char *buf){ + struct accel_config *aconfig = accel_get_config(); + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%d\n", aconfig->lg_dur); +} + +static ssize_t store_accel_l_dur_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + if(!count && !accel_adapter) return count; + if(bma023_set_lg_duration(accel_adapter, buf) < 0) + printk("accel lg duration set failed\n"); + return count; +} + +static ssize_t show_accel_l_thres_value(struct device *dev, struct device_attribute *attr, char *buf){ + struct accel_config *aconfig = accel_get_config(); + if(!accel_adapter) + return sprintf(buf, "No Accel\n"); + return sprintf(buf, "%d\n", aconfig->lg_thres); +} + +static ssize_t store_accel_l_thres_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + if(!count && !accel_adapter) return count; + if(bma023_set_lg_threshold(accel_adapter, buf) < 0) + printk("accel lg threshold set failed\n"); + return count; +} +#endif +#ifndef CONFIG_SENSORS_COMPASS_NONE +static ssize_t show_compass_name_value(struct device *dev, struct device_attribute *attr, char *buf){ + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + return sprintf(buf, "%s\n", (mldl_cfg->compass) ? mldl_cfg->compass->name : "No Compass"); +} + +static ssize_t store_compass_power_mode_value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(this_client); + if(!count && !compass_adapter) return count; + if(buf[0] == '1') + mldl_cfg->compass->resume(compass_adapter, mldl_cfg->compass, &mldl_cfg->pdata->compass); + else if(buf[0] == '0') + mldl_cfg->compass->suspend(compass_adapter, mldl_cfg->compass, &mldl_cfg->pdata->compass); + else + printk("error: invalid command %s for compass_power_mode\n",buf); + return count; +} +#endif + +static DEVICE_ATTR(version, S_IRUGO, show_driver_version_value, NULL); +static DEVICE_ATTR(gyro_data, S_IRUGO, show_gyro_data_value, NULL); +static DEVICE_ATTR(gyro_x_standby, S_IRUGO | S_IWUSR, show_gyro_x_standby_value, store_gyro_x_standby_value ); +static DEVICE_ATTR(gyro_y_standby, S_IRUGO | S_IWUSR, show_gyro_y_standby_value, store_gyro_y_standby_value ); +static DEVICE_ATTR(gyro_z_standby, S_IRUGO | S_IWUSR, show_gyro_z_standby_value, store_gyro_z_standby_value ); +static DEVICE_ATTR(gyro_power_mode, S_IRUGO | S_IWUSR, show_gyro_power_mode_value, store_gyro_power_mode_value ); +#ifdef CONFIG_SENSORS_BMA023 +static DEVICE_ATTR(accel_name, S_IRUGO, show_accel_name_value, NULL ); +static DEVICE_ATTR(accel_data, S_IRUGO, show_accel_data_value, NULL); +static DEVICE_ATTR(accel_power_mode, S_IRUGO | S_IWUSR, show_accel_power_mode_value, store_accel_power_mode_value ); +static DEVICE_ATTR(accel_bw, S_IRUGO | S_IWUSR, show_accel_bw_value, store_accel_bw_value ); +static DEVICE_ATTR(accel_range, S_IRUGO | S_IWUSR, show_accel_range_value, store_accel_range_value ); +static DEVICE_ATTR(accel_h_dur, S_IRUGO | S_IWUSR, show_accel_h_dur_value, store_accel_h_dur_value ); +static DEVICE_ATTR(accel_h_thres, S_IRUGO | S_IWUSR, show_accel_h_thres_value, store_accel_h_thres_value ); +static DEVICE_ATTR(accel_l_dur, S_IRUGO | S_IWUSR, show_accel_l_dur_value, store_accel_l_dur_value ); +static DEVICE_ATTR(accel_l_thres, S_IRUGO | S_IWUSR, show_accel_l_thres_value, store_accel_l_thres_value ); +#endif +#ifndef CONFIG_SENSORS_COMPASS_NONE +static DEVICE_ATTR(compass_name, S_IRUGO, show_compass_name_value, NULL ); +static DEVICE_ATTR(compass_power_mode, S_IWUSR, NULL, store_compass_power_mode_value ); +#endif + +static struct attribute *mpu3050_attributes[] = { + &dev_attr_version.attr, + &dev_attr_gyro_data.attr, + &dev_attr_gyro_x_standby.attr, + &dev_attr_gyro_y_standby.attr, + &dev_attr_gyro_z_standby.attr, + &dev_attr_gyro_power_mode.attr, +#ifdef CONFIG_SENSORS_BMA023 + &dev_attr_accel_name.attr, + &dev_attr_accel_data.attr, + &dev_attr_accel_power_mode.attr, + &dev_attr_accel_bw.attr, + &dev_attr_accel_range.attr, + &dev_attr_accel_h_dur.attr, + &dev_attr_accel_h_thres.attr, + &dev_attr_accel_l_dur.attr, + &dev_attr_accel_l_thres.attr, +#endif +#ifndef CONFIG_SENSORS_COMPASS_NONE + &dev_attr_compass_name.attr, + &dev_attr_compass_power_mode.attr, +#endif + NULL +}; + + +static struct attribute_group mpu3050_attribute_group = { + .attrs = mpu3050_attributes +}; + +int mpu_sysfs_init(struct i2c_client *client){ + int res; + struct mldl_cfg *mldl_cfg = + (struct mldl_cfg *) i2c_get_clientdata(client); + this_client = client; + if(mldl_cfg->accel) + accel_adapter = i2c_get_adapter(mldl_cfg->pdata->accel.adapt_num); + if(mldl_cfg->compass) + compass_adapter = i2c_get_adapter(mldl_cfg->pdata->compass.adapt_num); + + accel_slave_descr = get_accel_slave_descr(); + + res = sysfs_create_group(&client->dev.kobj, &mpu3050_attribute_group); + if(res) + return -1; + return 0; +} +EXPORT_SYMBOL(mpu_sysfs_init); + +void mpu_sysfs_exit(void){ + sysfs_remove_group(&this_client->dev.kobj, &mpu3050_attribute_group); +} +EXPORT_SYMBOL(mpu_sysfs_exit); + _______________________________________________ MeeGo-kernel mailing list [email protected] http://lists.meego.com/listinfo/meego-kernel
