From ebef293011fce5dd2e60d231aa73177c39c4e333 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Fri, 9 Apr 2021 15:00:31 +0800 Subject: [PATCH] Revert "staging: iio: new invensence mpu6050/6500 driver" This reverts commit a3c1d3323d4748bdcd866f9c4fb984b349082cb3. Change-Id: I79bbd4a094c4cc636f58cf75fa886b582b065136 Signed-off-by: Tao Huang --- drivers/staging/iio/imu/inv_mpu/Kconfig | 32 - drivers/staging/iio/imu/inv_mpu/Makefile | 58 - drivers/staging/iio/imu/inv_mpu/README | 603 ----- .../iio/imu/inv_mpu/dmpDefaultMPU6050.c | 350 --- drivers/staging/iio/imu/inv_mpu/dmpKey.h | 569 ----- drivers/staging/iio/imu/inv_mpu/dmpmap.h | 283 --- .../staging/iio/imu/inv_mpu/inv_counters.c | 155 -- .../staging/iio/imu/inv_mpu/inv_counters.h | 73 - .../staging/iio/imu/inv_mpu/inv_mpu3050_iio.c | 287 --- .../staging/iio/imu/inv_mpu/inv_mpu_core.c | 1944 ---------------- drivers/staging/iio/imu/inv_mpu/inv_mpu_hid.c | 303 --- drivers/staging/iio/imu/inv_mpu/inv_mpu_i2c.c | 769 ------- drivers/staging/iio/imu/inv_mpu/inv_mpu_iio.h | 929 -------- .../staging/iio/imu/inv_mpu/inv_mpu_misc.c | 2024 ----------------- .../staging/iio/imu/inv_mpu/inv_mpu_ring.c | 1319 ----------- drivers/staging/iio/imu/inv_mpu/inv_mpu_spi.c | 610 ----- .../staging/iio/imu/inv_mpu/inv_mpu_trigger.c | 120 - .../iio/imu/inv_mpu/inv_slave_bma250.c | 330 --- include/linux/mpu.h | 123 - 19 files changed, 10881 deletions(-) delete mode 100644 drivers/staging/iio/imu/inv_mpu/Kconfig delete mode 100644 drivers/staging/iio/imu/inv_mpu/Makefile delete mode 100644 drivers/staging/iio/imu/inv_mpu/README delete mode 100644 drivers/staging/iio/imu/inv_mpu/dmpDefaultMPU6050.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/dmpKey.h delete mode 100644 drivers/staging/iio/imu/inv_mpu/dmpmap.h delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_counters.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_counters.h delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu3050_iio.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_core.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_hid.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_i2c.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_iio.h delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_misc.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_ring.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_spi.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_mpu_trigger.c delete mode 100644 drivers/staging/iio/imu/inv_mpu/inv_slave_bma250.c delete mode 100755 include/linux/mpu.h diff --git a/drivers/staging/iio/imu/inv_mpu/Kconfig b/drivers/staging/iio/imu/inv_mpu/Kconfig deleted file mode 100644 index 4b548a8cf748..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# inv-mpu-iio driver for Invensense MPU devices and combos -# - -config INV_MPU_IIO - tristate "Invensense MPU devices" - depends on I2C && SYSFS && IIO && IIO_KFIFO_BUF && IIO_TRIGGER && !INV_MPU - default n - help - This driver supports the Invensense MPU devices. - This includes MPU6050/MPU3050/MPU9150/ITG3500/MPU6500/MPU9250. - This driver can be built as a module. The module will be called - inv-mpu-iio. - -config INV_IIO_MPU3050_ACCEL_SLAVE_BMA250 - bool "Invensense MPU3050 slave accelerometer device for bma250" - depends on INV_MPU_IIO - default n - help - This is slave device enable MPU3050 accelerometer slave device. - Right now, it is only bma250. For other acceleromter device, - it can be added to this menu if the proper interface is filled. - There are some interface function to be defined. - -config INV_TESTING - bool "Invensense IIO testing hooks" - depends on INV_MPU_IIO || INV_AMI306_IIO || INV_YAS530 || INV_HUB_IIO - default n - help - This flag enables display of additional testing information from the - Invensense IIO drivers diff --git a/drivers/staging/iio/imu/inv_mpu/Makefile b/drivers/staging/iio/imu/inv_mpu/Makefile deleted file mode 100644 index 6bf1d0369e46..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/Makefile +++ /dev/null @@ -1,58 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for Invensense inv-mpu-iio device. -# - -obj-$(CONFIG_INV_MPU_IIO) += inv-mpu-iio.o - -inv-mpu-iio-objs := inv_mpu_spi.o -inv-mpu-iio-objs += inv_mpu_i2c.o -inv-mpu-iio-objs += inv_mpu_hid.o -inv-mpu-iio-objs += inv_mpu_core.o -inv-mpu-iio-objs += inv_mpu_ring.o -inv-mpu-iio-objs += inv_mpu_trigger.o -inv-mpu-iio-objs += inv_mpu_misc.o -inv-mpu-iio-objs += inv_mpu3050_iio.o -inv-mpu-iio-objs += dmpDefaultMPU6050.o -ifeq ($(CONFIG_INV_TESTING), y) -inv-mpu-iio-objs += inv_counters.o -endif -ifeq ($(VERSION),4) -ifeq ($(PATCHLEVEL),4) -CFLAGS_inv_mpu_core.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_i2c.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_spi.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_hid.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_ring.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_trigger.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_common.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_load_image.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu_misc.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_inv_mpu3050_iio.o += -Idrivers/iio -DINV_KERNEL_3_10 -CFLAGS_dmpDefaultMPU6050.o += -Idrivers/iio -DINV_KERNEL_3_10 -else -CFLAGS_inv_mpu_i2c.o += -Idrivers/staging/iio -CFLAGS_inv_mpu_spi.o += -Idrivers/staging/iio -CFLAGS_inv_mpu_hid.o += -Idrivers/staging/iio -CFLAGS_inv_mpu_core.o += -Idrivers/staging/iio -CFLAGS_inv_mpu_ring.o += -Idrivers/staging/iio -CFLAGS_inv_mpu_trigger.o += -Idrivers/staging/iio -CFLAGS_inv_mpu_misc.o += -Idrivers/staging/iio -CFLAGS_inv_mpu3050_iio.o += -Idrivers/staging/iio -CFLAGS_dmpDefaultMPU6050.o += -Idrivers/staging/iio -endif -endif - -# the Bosch BMA250 driver is added to the inv-mpu device driver because it -# must be connected to an MPU3050 device on the secondary slave bus. -ifeq ($(CONFIG_INV_IIO_MPU3050_ACCEL_SLAVE_BMA250), y) -inv-mpu-iio-objs += inv_slave_bma250.o -ifeq ($(VERSION),4) -ifeq ($(PATCHLEVEL),4) -CFLAGS_inv_slave_bma250.o += -Idrivers/iio -else -CFLAGS_inv_slave_bma250.o += -Idrivers/staging/iio -endif -endif -endif - diff --git a/drivers/staging/iio/imu/inv_mpu/README b/drivers/staging/iio/imu/inv_mpu/README deleted file mode 100644 index 668335e26907..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/README +++ /dev/null @@ -1,603 +0,0 @@ -Kernel driver inv-mpu-iio -Author: Invensense - -Table of Contents: -================== -- Description -- Integrating the Driver in the Linux Kernel -- Board and Platform Data - > Interrupt Pin - > Platform Data -- Board File Modifications for Secondary I2C Configuration - > MPU-6050 + AKM8963 on the secondary I2C interface - > MPU-6500 + AKM8963 on the secondary I2C interface - > MPU-9150 - > MPU-9250 - > MPU-3050 + BMA250 on the secondary I2C interface -- Board File Modifications for Invensense Devices - > MPU-3050 - > ITG-3500 - > MPU-6050 - > MPU-6500 - > MPU-6XXX - > MPU-9150 - > MPU-9250 -- IIO Subsystem - > Communicating with the Driver in Userspace - > ITG-3500 - > MPU-6050 and MPU-6500 - > MPU-9150 - > MPU-9250 - > MPU-3050 + BMA250 on the secondary I2C interface -- Suspend and Resume -- DMP Event -- Motion Event -- Streaming Data to an Userspace Application -- Recommended Sysfs Entry Setup Sequence - > With DMP Firmware - > Without DMP Firmware -- Test Applications - > Running Test Applications with MPU-9150/MPU-6050/MPU-6500/MPU-9250 - > Running Test Applications with MPU-3050/ITG-3500 - - -Description -=========== -This document describes how to install the Invensense device driver into a -Linux kernel. The Invensense driver currently supports the following sensors: -- ITG-3500 -- MPU-6050 -- MPU-9150 -- MPU-6500 -- MPU-9250 -- MPU-3050 -- MPU-6XXX(either MPU6050 or MPU6500, driver to do auto detection) - -The slave address of each device is either 0x68 or 0x69, depending on the AD0 -pin value of the device. Please refer to the appropriate product specification -document for further information regarding the AD0 pin. The driver supports both -addresses. - -The following files are included in this package: -- Kconfig -- Makefile -- inv_mpu_core.c -- inv_mpu_misc.c -- inv_mpu_trigger.c -- inv_mpu3050_iio.c -- inv_mpu_iio.h -- inv_mpu_ring.c -- inv_slave_bma250.c -- dmpDefaultMPU6050.c -- dmpkey.h -- dmpmap.h -- mpu.h - - -Integrating the Driver in the Linux Kernel -========================================== -Please add the files as follows: -- Add mpu.h to "kernel/include/linux". -- Add all other files to drivers/staging/iio/imu/inv_mpu -(another directory is acceptable, but this is the recommended destination) - -In order to see the driver in menuconfig when building the kernel, please -make modifications as shown below: - - modify "drivers/staging/iio/imu/Kconfig" with: - >> source "drivers/staging/iio/imu/inv_mpu/Kconfig" - - modify "drivers/staging/iio/imu/Makefile" with: - >> obj-y += inv_mpu/ - - -Board and Platform Data -======================= -In order to recognize the Invensense device on the I2C bus, the board file must -be modified. -The i2c_board_info instance must be defined as shown below. - -Interrupt Pin -------------- -The hardcoded value of 140 corresponds to the GPIO input pin connected to the -Invensense device's interrupt pin. -This pin will most likely be different for your platform, and the value should -be changed accordingly. - -Platform Data -------------- -The platform data (orientation matrix and secondary bus configurations) must be -modified as show below, according to your particular platform configuration. - -Please note that the MPU-9150 it is treated as a MPU-6050 with AKM8975 on the -device's secondary I2C interface. Thus the secondary I2C address must be -provided. - -Please note that the MPU-9250 it is treated as a MPU-6500 with AKM8963 on the -device's secondary I2C interface. Thus the secondary I2C address must be -provided. - -Board File Modifications for Secondary I2C Configuration -======================================================== -For the Panda Board, the board file can be found at -arch/arm/mach-omap2/board-omap4panda.c. -Please modify the pertinent baord file in your system according to the examples -shown below: - -MPU-6050 + AKM8963 on the secondary I2C interface -------------------------------------------------- -static struct mpu_platform_data gyro_platform_data = { - .int_config = 0x00, - .level_shifter = 0, - .orientation = { -1, 0, 0, - 0, 1, 0, - 0, 0, -1 }, - .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, - .sec_slave_id = COMPASS_ID_AK8963, - .secondary_i2c_addr = 0x0E, - .secondary_orientation = { 0, 1, 0, - 1, 0, 0, - 0, 0, -1 }, -}; - -MPU-6500 + AKM8963 on the secondary I2C interface -------------------------------------------------- -static struct mpu_platform_data gyro_platform_data = { - .int_config = 0x00, - .level_shifter = 0, - .orientation = { -1, 0, 0, - 0, 1, 0, - 0, 0, -1 }, - .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, - .sec_slave_id = COMPASS_ID_AK8963, - .secondary_i2c_addr = 0x0E, - .secondary_orientation = { 0, 1, 0, - 1, 0, 0, - 0, 0, -1 }, -}; - -MPU-9150 --------- -For MPU-9150, please provide the following secondary I2C bus information. - -static struct mpu_platform_data gyro_platform_data = { - .int_config = 0x10, - .level_shifter = 0, - .orientation = { 1, 0, 0, - 0, 1, 0, - 0, 0, 1 }, - .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, - .sec_slave_id = COMPASS_ID_AK8975, - .secondary_i2c_addr = 0x0C, - .secondary_orientation = { 0, 1, 0, - 1, 0, 0, - 0, 0, -1 }, -}; - -MPU-9250 --------- -For MPU-9250, please provide the following secondary I2C bus information. - -static struct mpu_platform_data gyro_platform_data = { - .int_config = 0x00, - .level_shifter = 0, - .orientation = { 1, 0, 0, - 0, 1, 0, - 0, 0, 1 }, - .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, - .sec_slave_id = COMPASS_ID_AK8963, - .secondary_i2c_addr = 0x0C, - .secondary_orientation = { 0, 1, 0, - -1, 0, 0, - 0, 0, 1 }, -}; - -MPU-3050 + BMA250 on the secondary I2C interface ------------------------------------------------- -For BMA250 on the secondary I2C bus, please provide the following information. - -static struct mpu_platform_data gyro_platform_data = { - .int_config = 0x10, - .level_shifter = 0, - .orientation = { -1, 0, 0, - 0, 1, 0, - 0, 0, -1 }, - .sec_slave_type = SECONDARY_SLAVE_TYPE_ACCEL, - .sec_slave_id = ACCEL_ID_BMA250, - .secondary_i2c_addr = 0x18, - .secondary_orientation = { -1, 0, 0, - 0, -1, 0, - 0, 0, 1 }, -}; - - -Board File Modifications for Invensense Devices -=============================================== -For Invensense devices, please provide the i2c init data as shown in the -examples below. - -In the _i2c_init function, the device is registered in the following manner: - - // arch/arm/mach-omap2/board-omap4panda.c - // in static int __init omap4_panda_i2c_init(void) - omap_register_i2c_bus(4, 400, - single_chip_board_info, - ARRAY_SIZE(single_chip_board_info)); - -MPU-3050 --------- -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("mpu3050", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -ITG-3050 --------- -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("itg3500", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -MPU6050 -------- -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("mpu6050", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -MPU6500 -------- -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("mpu6500", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -MPU6XXX -------- -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("mpu6xxx", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -MPU9150 -------- -arch/arm/mach-omap2/board-omap4panda.c -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("mpu9150", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -MPU9250 -------- -arch/arm/mach-omap2/board-omap4panda.c -static struct i2c_board_info __initdata single_chip_board_info[] = { - { - I2C_BOARD_INFO("mpu9250", 0x68), - .irq = (IH_GPIO_BASE + MPUIRQ_GPIO), - .platform_data = &gyro_platform_data, - }, -}; - -IIO subsystem -============= -A successful installation will create the following two new directories under -/sys/bus/iio/devices: - - iio:device0 - - trigger0 - -Also, a new file, "iio:device0", will be created in the /dev/ diretory. -(if you have more than one IIO device, the file will be named "iio:deviceX", -where X is a number) - - -Communicating with the Driver in Userspace ------------------------------------------- -The driver generates several files in sysfs upon installation. -These files are used to communicate with the driver. The files can be found -at /sys/bus/iio/devices/iio:device0 (or ../iio:deviceX as shown above). - -A brief description of the pertinent files for each Invensense device is shown -below: - -ITG-3500 --------- -temperature (Read-only) ---Read temperature data directly from the temperature register. - -sampling_frequency (Read/write) ---Configure the ADC sampling rate and FIFO output rate. - -sampling_frequency_available(read-only) ---show commonly used frequency - -clock_source (Read-only) ---Check which clock-source is used by the chip. - -power_state (Read/write) ---turn on/off the power supply - -self_test (read-only) ---read this entry trigger self test. The return value is D. -D is the success/fail. -For different chip, the result is different for success/fail. -1 means success 0 means fail. The LSB of D is for gyro; the bit -next to LSB of D is for accel. The bit 2 of D is for compass result. - -key (read-only) ---show the key value of this driver. Used by MPL. - -gyro_matrix (read-only) ---show the orientation matrix obtained from the board file. - -MPU-6050 and MPU-6500 ---------------------- -MPU-6050 and MPU-6500 have all sysfs files belonging to ITG-3500 (shown above). -In addition, it has the files below: - -gyro_enable (read/write) ---enable/disable gyro functionality. Affects raw_gyro. Turning this off this - will shut down gyro and save power. - -accl_enable (read/write) ---enable/disable accelerometer functionality. Affects raw_accl. -Turning this off this will shut down accel and save power. - -firmware_loaded (read/write) ---Flag indicating the whether firmware is loaded or not in the DMP engine. -0 means no firmware loaded. 1 means firmware is already loaded . This -flag can only be written as 0. It internally updates to 1. - -dmp_on(read/write) ---This entry controls whether to run DMP or not. -Write 1 to enable DMP and write 0 to disable dmp. -Please note that firmware_loaded must be 1 in order to enable DMP. - -dmp_int_on(read/write) ---This entry controls whether dmp interrupt is on/off. -Please note that firmware_loaded must be 1. -Also, we'd like to remind you that it is sometimes advantageous to -turn interrupts off while the DMP is running. - -dmp_output_rate ---control dmp output rate when dmp is on. - -dmp_event_int_on(read/write) ---This entry controls whether dmp event interrupt is on/off. -Please note that turning this on will turn off the data interrupt. -Interrupts will be generated only when events occur. -This is useful for saving power when the system is waiting for a special event -to wake up. - -dmp_firmware (write only binary file) ---DMP firmware code is loaded into this entry. -If loading is successful, the firmware_loaded flag will be updated to 1. -In order to load new firmware, the firmware_loaded flag must be first set to 0. - -accel_matrix ---orientation matrix for accelerometer. - -quaternion_on ---Turn on/off quaterniion data output. DMP is required for this feature. - -pedometer_time -pedometer_steps, ---Pedometer related entries - -event_tap -event_display_orientation -event_accel_motion -event_smd ---Event related entries. -Please poll these entries to read their values. Direct reads will yield -meaningless results. -Further details are provided in the DMP Events section of this README. - -tap_on ---Controls tap function of DMP - -tap_time -tap_min_count -tap_threshold ---Tap related entries. Controls various parameters of tap function. - -display_orientation_on ---Turn on/off display orientation function of DMP. - -smd_enable -enable SMD(Significant Motion Detection) detection. - -smd_threshold -This set the threshold of the motion when SMD start to be triggered. The -value is in acclerometer counts. - -smd_delay_threshold -This sets the threshold of time after which SMD can be triggered. -The value is in seconds. - -smd_delay_threshold2 -This sets the threshold of time during which SMD can be triggered (after the -smd_delay_threshold timer has expired). -The value is in seconds. - -quaternion_on ---Turn on/off quaterniion data output. DMP is required for this feature. - -Low power accel motion interrupt related settings. -if motion_lpa_on is set, this will disable all engines except accel. Accel will -enter low power mode and the whole chip will be turned on/off at specific frequency. ------------------------------------------------------------------------------ -motion_lpa_duration ---set motion duration. in ms. This means filtered out all the motino interrupts - during this period. - -motion_lpa_threshold ---set motion threshold. in mg. The maximum is 1020mg and resolution is 32mg. - -motion_lpa_on ---turn on/off motion function. - -motion_lpa_freq ---motion lpa frequency. which determines power on/off frequency. ------------------------------------------------------------------------------- -MPU-9150 --------- -MPU-9150 has all of MPU-6050's entries. It also has two additional entries, -described below. - -compass_enable (read/write) ---Enables compass function. - -compass_matrix (read-only) ---Compass orientation matrix - -MPU-3050 with BMA250 on secondary I2C interface ------------------------------------------------ -MPU-3050 with BMA250 on the secondary I2C interface has ever ITG-3500 entry. -It also has two additional entries, shown below: - -accl_matrix - -accl_enable - -Suspend and Resume -=================================================== -The suspend and resume functions are call backs registered to the system -and executed when the system goes in suspend and resumes. -It is enabled when CONFIG_PM is defined. -The current behavior is simple: -- suspend will turn off the chip -- resume will turn on the chip - -However, it is possible for the driver to do more complex things; -for example, leaving pedometers running when system is off. This can save whole -system power while letting pedometer working. Other behaviors are possible -too. - -DMP Event -========= -A DMP Event is an event that is output by the DMP unit within the Invensense -device (MPU). -Only the MPU-6050, MPU-6500, MPU-9250, MPU-9150, MPU-9250 feature the DMP. - -There are four sysfs entries for DMP events: -- event_tap -- event_display_orientation -- event_accel_motion -- event_smd - -These events must be polled before reading. - -The proper method to poll sysfs is as follows: -1. open file. -2. dummy read. -3. poll. -4. once the poll passed, use fopen and fread to read the sysfs entry. -5. interpret the data. - -Streaming Data to an Userspace Application -========================================== -When streaming data to an userspace application, we recommend that you access -gyro/accel/compass data via /dev/iio:device0. - -Please follow the steps below to read data at a constant rate from the driver: - -1. Write a 1 to power_state to turn on the chip. This is the default setting - after installing the driver. -2. Write the desired output rate to fifo_rate. -3. Write 1 to enable to turn on the event. -4. Read /dev/iio:device0 to get a string of gyro/accel/compass data. -5. Parse this string to obtain each gyro/accel/compass element. -6. If dmp firmware code is loaded, use "dmp_on" to enable/disable dmp. -7. If compass is enabled, the output will contain compass data. - - -Recommended Sysfs Entry Setup Senquence -======================================= - -Without DMP Firmware --------------------- -1. Set "power_state" to 1, -2. Set the scale and fifo rate values according to your needs. -3. Set gyro_enable, accel_enable, and compass_enable according to your needs. - For example: - - If you only want gyro data, set accel_enable to 0 (and compass_enable to - 0, if applicable). - - If you only want accel data, set gyro_enable to 0 (and compass_enable to - 0, if applicable). - - If you only want compass data, set gyro_enable to 0 and accel_enable to 0. -4. Set "enable" to 1. -5. You will now get the output that you want. - -With DMP Firmware ------------------ -1. Set "power_state" to 1. -2. Write "0" to firmware_loaded if it is not zero already. -3. Load firmware into "dmp_firmware" as a whole. Don't split the DMP firmware - image. -4. Make sure firmware_loaded is 1 after loading the DMP image. -5. Make appropriate configurations as shown above in the "without DMP firmware" - case. -6. Set dmp_on to 1. -7. Set "enable" to 1. - -Please note that the enable function uses the enable entry under -"/sys/bus/iio/devices/iio:device0/buffer" - -Test Applications -================= -A test application is located under software/simple_apps/mpu_iio. -This application is stand-alone in that it cannot be run concurrently with other -entities trying to access the device node(s) or sysfs entries; in particular, -the - -Running Test Applications with MPU-9150/MPU-6050/MPU-6500/MPU-9250 ---------------------------------------------------------- -To run test applications with MPU-9150, MPU-9250, MPU-6050, or MPU-6500 devices, -please use the following commands: - -1. For tap/display orientation events: - mpu_iio -c 10 -l 3 -p - -2. In addition, to test the motion interrupt (and no_motion on MPU6050) use: - mpu_iio -c 10 -l 3 -p -m - -3. For printing data normally: - mpu_iio -c 10 -l 3 -r - -Running Test Applications with MPU-3050/ITG-3500 ------------------------------------------------- -To run test applications with MPU-3050 or ITG-3500 devices, -please use the following command: - -1. For printing data normally: - mpu_iio -c 10 -l 3 -r - -Please use mpu_iio.c and iio_utils.h as example code for your development -purposes. - -Stress test application -================================= -A stress test application is located under software/simple_apps/stress_iio. -This application simulates HAL's usage calls to the driver. It creates three -threads. One for data read; one for event read; one for sysfs control. -It can run without any parameters or run with some control parameters. Please -see README in the same directories for details. - diff --git a/drivers/staging/iio/imu/inv_mpu/dmpDefaultMPU6050.c b/drivers/staging/iio/imu/inv_mpu/dmpDefaultMPU6050.c deleted file mode 100644 index bcffec97a7cc..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/dmpDefaultMPU6050.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (C) 2012 Invensense, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include "inv_mpu_iio.h" -#include "dmpKey.h" -#include "dmpmap.h" - -#define CFG_LP_QUAT (2500) -#define END_ORIENT_TEMP (2063) -#define CFG_27 (2530) -#define CFG_23 (2533) -#define CFG_PED_ENABLE (2620) -#define CFG_FIFO_ON_EVENT (2475) -#define CFG_PED_INT (2873) -#define END_PREDICTION_UPDATE (1958) -#define X_GRT_Y_TMP (1555) -#define CFG_DR_INT (1029) -#define CFG_AUTH (1035) -#define UPDATE_PROP_ROT (2032) -#define END_COMPARE_Y_X_TMP2 (1652) -#define SKIP_X_GRT_Y_TMP (1556) -#define SKIP_END_COMPARE (1632) -#define FCFG_3 (1087) -#define FCFG_2 (1066) -#define FCFG_1 (1062) -#define END_COMPARE_Y_X_TMP3 (1631) -#define FCFG_7 (1073) -#define FCFG_6 (1105) -#define FLAT_STATE_END (1910) -#define SWING_END_4 (1813) -#define SWING_END_2 (1762) -#define SWING_END_3 (1784) -#define SWING_END_1 (1747) -#define CFG_8 (2506) -#define CFG_15 (2515) -#define CFG_16 (2534) -#define CFG_EXT_GYRO_BIAS (1184) -#define END_COMPARE_Y_X_TMP (1604) -#define DO_NOT_UPDATE_PROP_ROT (2036) -#define CFG_7 (1403) -#define FLAT_STATE_END_TEMP (1880) -#define END_COMPARE_Y_X (1681) -#define SMD_TP2 (1366) -#define SKIP_SWING_END_1 (1748) -#define SKIP_SWING_END_3 (1785) -#define SKIP_SWING_END_2 (1763) -#define SMD_TP1 (1343) -#define TILTG75_START (1869) -#define CFG_6 (2541) -#define TILTL75_END (1866) -#define END_ORIENT (2081) -#define TILTL75_START (1840) -#define CFG_MOTION_BIAS (1405) -#define X_GRT_Y (1605) -#define TEMPLABEL (2105) -#define CFG_DISPLAY_ORIENT_INT (2050) - -#define CFG_GYRO_RAW_DATA (2510) -#define X_GRT_Y_TMP2 (1576) - -#define D_0_22 (22 + 512) -#define D_0_24 (24 + 512) - -#define D_0_36 (36) -#define D_0_52 (52) -#define D_0_96 (96) -#define D_0_104 (104) -#define D_0_108 (108) -#define D_0_163 (163) -#define D_0_188 (188) -#define D_0_192 (192) -#define D_0_224 (224) -#define D_0_228 (228) -#define D_0_232 (232) -#define D_0_236 (236) - -#define D_1_2 (256 + 2) -#define D_1_4 (256 + 4) -#define D_1_8 (256 + 8) -#define D_1_10 (256 + 10) -#define D_1_24 (256 + 24) -#define D_1_28 (256 + 28) -#define D_1_36 (256 + 36) -#define D_1_40 (256 + 40) -#define D_1_44 (256 + 44) -#define D_1_72 (256 + 72) -#define D_1_74 (256 + 74) -#define D_1_79 (256 + 79) -#define D_1_88 (256 + 88) -#define D_1_90 (256 + 90) -#define D_1_92 (256 + 92) -#define D_1_96 (256 + 96) -#define D_1_98 (256 + 98) -#define D_1_106 (256 + 106) -#define D_1_108 (256 + 108) -#define D_1_112 (256 + 112) -#define D_1_128 (256 + 144) -#define D_1_152 (256 + 12) -#define D_1_160 (256 + 160) -#define D_1_176 (256 + 176) -#define D_1_178 (256 + 178) -#define D_1_218 (256 + 218) -#define D_1_232 (256 + 232) -#define D_1_236 (256 + 236) -#define D_1_240 (256 + 240) -#define D_1_244 (256 + 244) -#define D_1_250 (256 + 250) -#define D_1_252 (256 + 252) -#define D_2_12 (512 + 12) -#define D_2_96 (512 + 96) -#define D_2_108 (512 + 108) -#define D_2_208 (512 + 208) -#define D_2_224 (512 + 224) -#define D_2_236 (512 + 236) -#define D_2_244 (512 + 244) -#define D_2_248 (512 + 248) -#define D_2_252 (512 + 252) - -#define CPASS_BIAS_X (35 * 16 + 4) -#define CPASS_BIAS_Y (35 * 16 + 8) -#define CPASS_BIAS_Z (35 * 16 + 12) -#define CPASS_MTX_00 (36 * 16) -#define CPASS_MTX_01 (36 * 16 + 4) -#define CPASS_MTX_02 (36 * 16 + 8) -#define CPASS_MTX_10 (36 * 16 + 12) -#define CPASS_MTX_11 (37 * 16) -#define CPASS_MTX_12 (37 * 16 + 4) -#define CPASS_MTX_20 (37 * 16 + 8) -#define CPASS_MTX_21 (37 * 16 + 12) -#define CPASS_MTX_22 (43 * 16 + 12) -#define D_EXT_GYRO_BIAS_X (61 * 16) -#define D_EXT_GYRO_BIAS_Y (61 * 16 + 4) -#define D_EXT_GYRO_BIAS_Z (61 * 16 + 8) -#define D_ACT0 (40 * 16) -#define D_ACSX (40 * 16 + 4) -#define D_ACSY (40 * 16 + 8) -#define D_ACSZ (40 * 16 + 12) - -#define FLICK_MSG (45 * 16 + 4) -#define FLICK_COUNTER (45 * 16 + 8) -#define FLICK_LOWER (45 * 16 + 12) -#define FLICK_UPPER (46 * 16 + 12) - -#define D_SMD_ENABLE (18 * 16) -#define D_SMD_MOT_THLD (20 * 16) -#define D_SMD_DELAY_THLD (21 * 16 + 4) -#define D_SMD_DELAY2_THLD (21 * 16 + 12) -#define D_SMD_EXE_STATE (22 * 16) -#define D_SMD_DELAY_CNTR (21 * 16) - -#define D_AUTH_OUT (992) -#define D_AUTH_IN (996) -#define D_AUTH_A (1000) -#define D_AUTH_B (1004) - -#define D_PEDSTD_BP_B (768 + 0x1C) -#define D_PEDSTD_HP_A (768 + 0x78) -#define D_PEDSTD_HP_B (768 + 0x7C) -#define D_PEDSTD_BP_A4 (768 + 0x40) -#define D_PEDSTD_BP_A3 (768 + 0x44) -#define D_PEDSTD_BP_A2 (768 + 0x48) -#define D_PEDSTD_BP_A1 (768 + 0x4C) -#define D_PEDSTD_INT_THRSH (768 + 0x68) -#define D_PEDSTD_CLIP (768 + 0x6C) -#define D_PEDSTD_SB (768 + 0x28) -#define D_PEDSTD_SB_TIME (768 + 0x2C) -#define D_PEDSTD_PEAKTHRSH (768 + 0x98) -#define D_PEDSTD_TIML (768 + 0x2A) -#define D_PEDSTD_TIMH (768 + 0x2E) -#define D_PEDSTD_PEAK (768 + 0X94) -#define D_PEDSTD_STEPCTR (768 + 0x60) -#define D_PEDSTD_TIMECTR (964) -#define D_PEDSTD_DECI (768 + 0xA0) - -#define D_HOST_NO_MOT (976) -#define D_ACCEL_BIAS (660) - -#define D_ORIENT_GAP (76) - -#define D_TILT0_H (48) -#define D_TILT0_L (50) -#define D_TILT1_H (52) -#define D_TILT1_L (54) -#define D_TILT2_H (56) -#define D_TILT2_L (58) -#define D_TILT3_H (60) -#define D_TILT3_L (62) - -/* Batch mode */ -#define D_BM_BATCH_CNTR (27 * 16 + 4) -#define D_BM_BATCH_THLD (27 * 16 + 8) -#define D_BM_ENABLE (28 * 16 + 6) -#define D_BM_NUMWORD_TOFILL (28 * 16 + 4) - -static const struct tKeyLabel dmpTConfig[] = { - {KEY_CFG_27, CFG_27}, - {KEY_CFG_23, CFG_23}, - {KEY_CFG_PED_ENABLE, CFG_PED_ENABLE}, - {KEY_CFG_FIFO_ON_EVENT, CFG_FIFO_ON_EVENT}, - {KEY_CFG_DR_INT, CFG_DR_INT}, - {KEY_CFG_AUTH, CFG_AUTH}, - {KEY_FCFG_1, FCFG_1}, - {KEY_FCFG_3, FCFG_3}, - {KEY_FCFG_2, FCFG_2}, - {KEY_CFG_DISPLAY_ORIENT_INT, CFG_DISPLAY_ORIENT_INT}, - {KEY_FCFG_7, FCFG_7}, - {KEY_FCFG_6, FCFG_6}, - {KEY_CFG_8, CFG_8}, - {KEY_CFG_15, CFG_15}, - {KEY_CFG_16, CFG_16}, - {KEY_CFG_EXT_GYRO_BIAS, CFG_EXT_GYRO_BIAS}, - {KEY_CFG_6, CFG_6}, - {KEY_CFG_LP_QUAT, CFG_LP_QUAT}, - {KEY_CFG_7, CFG_7}, - {KEY_CFG_MOTION_BIAS, CFG_MOTION_BIAS}, - {KEY_CFG_DISPLAY_ORIENT_INT, CFG_DISPLAY_ORIENT_INT}, - {KEY_CFG_GYRO_RAW_DATA, CFG_GYRO_RAW_DATA}, - {KEY_D_0_22, D_0_22}, - {KEY_D_0_96, D_0_96}, - {KEY_D_0_104, D_0_104}, - {KEY_D_0_108, D_0_108}, - {KEY_D_1_36, D_1_36}, - {KEY_D_1_40, D_1_40}, - {KEY_D_1_44, D_1_44}, - {KEY_D_1_72, D_1_72}, - {KEY_D_1_74, D_1_74}, - {KEY_D_1_79, D_1_79}, - {KEY_D_1_88, D_1_88}, - {KEY_D_1_90, D_1_90}, - {KEY_D_1_92, D_1_92}, - {KEY_D_1_160, D_1_160}, - {KEY_D_1_176, D_1_176}, - {KEY_D_1_178, D_1_178}, - {KEY_D_1_218, D_1_218}, - {KEY_D_1_232, D_1_232}, - {KEY_D_1_250, D_1_250}, - {KEY_DMP_SH_TH_Y, DMP_SH_TH_Y}, - {KEY_DMP_SH_TH_X, DMP_SH_TH_X}, - {KEY_DMP_SH_TH_Z, DMP_SH_TH_Z}, - {KEY_DMP_ORIENT, DMP_ORIENT}, - {KEY_D_AUTH_OUT, D_AUTH_OUT}, - {KEY_D_AUTH_IN, D_AUTH_IN}, - {KEY_D_AUTH_A, D_AUTH_A}, - {KEY_D_AUTH_B, D_AUTH_B}, - {KEY_CPASS_BIAS_X, CPASS_BIAS_X}, - {KEY_CPASS_BIAS_Y, CPASS_BIAS_Y}, - {KEY_CPASS_BIAS_Z, CPASS_BIAS_Z}, - {KEY_CPASS_MTX_00, CPASS_MTX_00}, - {KEY_CPASS_MTX_01, CPASS_MTX_01}, - {KEY_CPASS_MTX_02, CPASS_MTX_02}, - {KEY_CPASS_MTX_10, CPASS_MTX_10}, - {KEY_CPASS_MTX_11, CPASS_MTX_11}, - {KEY_CPASS_MTX_12, CPASS_MTX_12}, - {KEY_CPASS_MTX_20, CPASS_MTX_20}, - {KEY_CPASS_MTX_21, CPASS_MTX_21}, - {KEY_CPASS_MTX_22, CPASS_MTX_22}, - {KEY_D_ACT0, D_ACT0}, - {KEY_D_ACSX, D_ACSX}, - {KEY_D_ACSY, D_ACSY}, - {KEY_D_ACSZ, D_ACSZ}, - {KEY_FLICK_MSG, FLICK_MSG}, - {KEY_FLICK_COUNTER, FLICK_COUNTER}, - {KEY_FLICK_LOWER, FLICK_LOWER}, - {KEY_FLICK_UPPER, FLICK_UPPER}, - {KEY_D_PEDSTD_BP_B, D_PEDSTD_BP_B}, - {KEY_D_PEDSTD_HP_A, D_PEDSTD_HP_A}, - {KEY_D_PEDSTD_HP_B, D_PEDSTD_HP_B}, - {KEY_D_PEDSTD_BP_A4, D_PEDSTD_BP_A4}, - {KEY_D_PEDSTD_BP_A3, D_PEDSTD_BP_A3}, - {KEY_D_PEDSTD_BP_A2, D_PEDSTD_BP_A2}, - {KEY_D_PEDSTD_BP_A1, D_PEDSTD_BP_A1}, - {KEY_D_PEDSTD_INT_THRSH, D_PEDSTD_INT_THRSH}, - {KEY_D_PEDSTD_CLIP, D_PEDSTD_CLIP}, - {KEY_D_PEDSTD_SB, D_PEDSTD_SB}, - {KEY_D_PEDSTD_SB_TIME, D_PEDSTD_SB_TIME}, - {KEY_D_PEDSTD_PEAKTHRSH, D_PEDSTD_PEAKTHRSH}, - {KEY_D_PEDSTD_TIML, D_PEDSTD_TIML}, - {KEY_D_PEDSTD_TIMH, D_PEDSTD_TIMH}, - {KEY_D_PEDSTD_PEAK, D_PEDSTD_PEAK}, - {KEY_D_PEDSTD_STEPCTR, D_PEDSTD_STEPCTR}, - {KEY_D_PEDSTD_TIMECTR, D_PEDSTD_TIMECTR}, - {KEY_D_PEDSTD_DECI, D_PEDSTD_DECI}, - {KEY_D_HOST_NO_MOT, D_HOST_NO_MOT}, - {KEY_D_ACCEL_BIAS, D_ACCEL_BIAS}, - {KEY_D_ORIENT_GAP, D_ORIENT_GAP}, - {KEY_D_TILT0_H, D_TILT0_H}, - {KEY_D_TILT0_L, D_TILT0_L}, - {KEY_D_TILT1_H, D_TILT1_H}, - {KEY_D_TILT1_L, D_TILT1_L}, - {KEY_D_TILT2_H, D_TILT2_H}, - {KEY_D_TILT2_L, D_TILT2_L}, - {KEY_D_TILT3_H, D_TILT3_H}, - {KEY_D_TILT3_L, D_TILT3_L}, - {KEY_CFG_EXT_GYRO_BIAS_X, D_EXT_GYRO_BIAS_X}, - {KEY_CFG_EXT_GYRO_BIAS_Y, D_EXT_GYRO_BIAS_Y}, - {KEY_CFG_EXT_GYRO_BIAS_Z, D_EXT_GYRO_BIAS_Z}, - {KEY_CFG_PED_INT, CFG_PED_INT}, - {KEY_SMD_ENABLE, D_SMD_ENABLE}, - {KEY_SMD_ACCEL_THLD, D_SMD_MOT_THLD}, - {KEY_SMD_DELAY_THLD, D_SMD_DELAY_THLD}, - {KEY_SMD_DELAY2_THLD, D_SMD_DELAY2_THLD}, - {KEY_SMD_ENABLE_TESTPT1, SMD_TP1}, - {KEY_SMD_ENABLE_TESTPT2, SMD_TP2}, - {KEY_SMD_EXE_STATE, D_SMD_EXE_STATE}, - {KEY_SMD_DELAY_CNTR, D_SMD_DELAY_CNTR}, - {KEY_BM_ENABLE, D_BM_ENABLE}, - {KEY_BM_BATCH_CNTR, D_BM_BATCH_CNTR}, - {KEY_BM_BATCH_THLD, D_BM_BATCH_THLD}, - {KEY_BM_NUMWORD_TOFILL, D_BM_NUMWORD_TOFILL} -}; - -#define NUM_LOCAL_KEYS (ARRAY_SIZE(dmpTConfig) / sizeof(dmpTConfig[0])) - -static struct tKeyLabel keys[NUM_KEYS]; - -unsigned short inv_dmp_get_address(unsigned short key) -{ - static int isSorted; - - if (!isSorted) { - int kk; - for (kk = 0; kk < NUM_KEYS; ++kk) { - keys[kk].addr = 0xffff; - keys[kk].key = kk; - } - for (kk = 0; kk < NUM_LOCAL_KEYS; ++kk) - keys[dmpTConfig[kk].key].addr = dmpTConfig[kk].addr; - isSorted = 1; - } - if (key >= NUM_KEYS) { - pr_err("ERROR!! key not exist=%d!\n", key); - return 0xffff; - } - if (0xffff == keys[key].addr) { - pr_err("ERROR!!key not local=%d!\n", key); - dump_stack(); - } - return keys[key].addr; -} diff --git a/drivers/staging/iio/imu/inv_mpu/dmpKey.h b/drivers/staging/iio/imu/inv_mpu/dmpKey.h deleted file mode 100644 index 4c70ec294a9e..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/dmpKey.h +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright (C) 2012 Invensense, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - * - */ -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file dmpKey.h - * @brief dmp Key definition - * @details This file is part of invensense mpu driver code - * - */ - -#ifndef DMPKEY_H__ -#define DMPKEY_H__ - -#define KEY_CFG_25 (0) -#define KEY_CFG_24 (KEY_CFG_25 + 1) -#define KEY_CFG_26 (KEY_CFG_24 + 1) -#define KEY_CFG_27 (KEY_CFG_26 + 1) -#define KEY_CFG_21 (KEY_CFG_27 + 1) -#define KEY_CFG_20 (KEY_CFG_21 + 1) -#define KEY_CFG_TAP4 (KEY_CFG_20 + 1) -#define KEY_CFG_TAP5 (KEY_CFG_TAP4 + 1) -#define KEY_CFG_TAP6 (KEY_CFG_TAP5 + 1) -#define KEY_CFG_TAP7 (KEY_CFG_TAP6 + 1) -#define KEY_CFG_TAP0 (KEY_CFG_TAP7 + 1) -#define KEY_CFG_TAP1 (KEY_CFG_TAP0 + 1) -#define KEY_CFG_TAP2 (KEY_CFG_TAP1 + 1) -#define KEY_CFG_TAP3 (KEY_CFG_TAP2 + 1) -#define KEY_CFG_TAP_QUANTIZE (KEY_CFG_TAP3 + 1) -#define KEY_CFG_TAP_JERK (KEY_CFG_TAP_QUANTIZE + 1) -#define KEY_CFG_DR_INT (KEY_CFG_TAP_JERK + 1) -#define KEY_CFG_AUTH (KEY_CFG_DR_INT + 1) -#define KEY_CFG_TAP_SAVE_ACCB (KEY_CFG_AUTH + 1) -#define KEY_CFG_TAP_CLEAR_STICKY (KEY_CFG_TAP_SAVE_ACCB + 1) -#define KEY_CFG_FIFO_ON_EVENT (KEY_CFG_TAP_CLEAR_STICKY + 1) -#define KEY_FCFG_ACCEL_INPUT (KEY_CFG_FIFO_ON_EVENT + 1) -#define KEY_FCFG_ACCEL_INIT (KEY_FCFG_ACCEL_INPUT + 1) -#define KEY_CFG_23 (KEY_FCFG_ACCEL_INIT + 1) -#define KEY_FCFG_1 (KEY_CFG_23 + 1) -#define KEY_FCFG_3 (KEY_FCFG_1 + 1) -#define KEY_FCFG_2 (KEY_FCFG_3 + 1) -#define KEY_CFG_3D (KEY_FCFG_2 + 1) -#define KEY_CFG_3B (KEY_CFG_3D + 1) -#define KEY_CFG_3C (KEY_CFG_3B + 1) -#define KEY_FCFG_5 (KEY_CFG_3C + 1) -#define KEY_FCFG_4 (KEY_FCFG_5 + 1) -#define KEY_FCFG_7 (KEY_FCFG_4 + 1) -#define KEY_FCFG_FSCALE (KEY_FCFG_7 + 1) -#define KEY_FCFG_AZ (KEY_FCFG_FSCALE + 1) -#define KEY_FCFG_6 (KEY_FCFG_AZ + 1) -#define KEY_FCFG_LSB4 (KEY_FCFG_6 + 1) -#define KEY_CFG_12 (KEY_FCFG_LSB4 + 1) -#define KEY_CFG_14 (KEY_CFG_12 + 1) -#define KEY_CFG_15 (KEY_CFG_14 + 1) -#define KEY_CFG_16 (KEY_CFG_15 + 1) -#define KEY_CFG_18 (KEY_CFG_16 + 1) -#define KEY_CFG_6 (KEY_CFG_18 + 1) -#define KEY_CFG_7 (KEY_CFG_6 + 1) -#define KEY_CFG_4 (KEY_CFG_7 + 1) -#define KEY_CFG_5 (KEY_CFG_4 + 1) -#define KEY_CFG_2 (KEY_CFG_5 + 1) -#define KEY_CFG_3 (KEY_CFG_2 + 1) -#define KEY_CFG_1 (KEY_CFG_3 + 1) -#define KEY_CFG_EXTERNAL (KEY_CFG_1 + 1) -#define KEY_CFG_8 (KEY_CFG_EXTERNAL + 1) -#define KEY_CFG_9 (KEY_CFG_8 + 1) -#define KEY_CFG_ORIENT_3 (KEY_CFG_9 + 1) -#define KEY_CFG_ORIENT_2 (KEY_CFG_ORIENT_3 + 1) -#define KEY_CFG_ORIENT_1 (KEY_CFG_ORIENT_2 + 1) -#define KEY_CFG_GYRO_SOURCE (KEY_CFG_ORIENT_1 + 1) -#define KEY_CFG_ORIENT_IRQ_1 (KEY_CFG_GYRO_SOURCE + 1) -#define KEY_CFG_ORIENT_IRQ_2 (KEY_CFG_ORIENT_IRQ_1 + 1) -#define KEY_CFG_ORIENT_IRQ_3 (KEY_CFG_ORIENT_IRQ_2 + 1) -#define KEY_FCFG_MAG_VAL (KEY_CFG_ORIENT_IRQ_3 + 1) -#define KEY_FCFG_MAG_MOV (KEY_FCFG_MAG_VAL + 1) -#define KEY_CFG_LP_QUAT (KEY_FCFG_MAG_MOV + 1) -#define KEY_CFG_GYRO_RAW_DATA (KEY_CFG_LP_QUAT + 1) -#define KEY_CFG_EXT_GYRO_BIAS (KEY_CFG_GYRO_RAW_DATA + 1) -#define KEY_CFG_EXT_GYRO_BIAS_X (KEY_CFG_EXT_GYRO_BIAS + 1) -#define KEY_CFG_EXT_GYRO_BIAS_Y (KEY_CFG_EXT_GYRO_BIAS_X + 1) -#define KEY_CFG_EXT_GYRO_BIAS_Z (KEY_CFG_EXT_GYRO_BIAS_Y + 1) -#define KEY_bad_compass (KEY_CFG_EXT_GYRO_BIAS_Z + 1) -#define KEY_COMPASS_CHG_SENSITIVITY (KEY_bad_compass + 1) -#define KEY_CCS_HEADING_THLD (KEY_COMPASS_CHG_SENSITIVITY + 1) -#define KEY_CCS_TIME_THLD (KEY_CCS_HEADING_THLD + 1) -#define KEY_CCS_DOTP_THLD (KEY_CCS_TIME_THLD + 1) -#define KEY_CCS_COMP_CNTR (KEY_CCS_DOTP_THLD + 1) -#define KEY_CFG_NM_DET (KEY_CCS_COMP_CNTR + 1) -#define KEY_SMD_ENABLE (KEY_CFG_NM_DET + 1) -#define KEY_SMD_ACCEL_THLD (KEY_SMD_ENABLE + 1) -#define KEY_SMD_DELAY_THLD (KEY_SMD_ACCEL_THLD + 1) -#define KEY_SMD_DELAY2_THLD (KEY_SMD_DELAY_THLD + 1) -#define KEY_SMD_ENABLE_TESTPT1 (KEY_SMD_DELAY2_THLD + 1) -#define KEY_SMD_ENABLE_TESTPT2 (KEY_SMD_ENABLE_TESTPT1 + 1) -#define KEY_SMD_EXE_STATE (KEY_SMD_ENABLE_TESTPT2 + 1) -#define KEY_SMD_DELAY_CNTR (KEY_SMD_EXE_STATE + 1) - -#define KEY_BREAK (81) -#if KEY_SMD_DELAY_CNTR != KEY_BREAK -#error -#endif - -/* MPU6050 keys */ -#define KEY_CFG_ACCEL_FILTER (KEY_BREAK + 1) -#define KEY_CFG_MOTION_BIAS (KEY_CFG_ACCEL_FILTER + 1) -#define KEY_TEMPLABEL (KEY_CFG_MOTION_BIAS + 1) - -#define KEY_D_0_22 (KEY_TEMPLABEL + 1) -#define KEY_D_0_24 (KEY_D_0_22 + 1) -#define KEY_D_0_36 (KEY_D_0_24 + 1) -#define KEY_D_0_52 (KEY_D_0_36 + 1) -#define KEY_D_0_96 (KEY_D_0_52 + 1) -#define KEY_D_0_104 (KEY_D_0_96 + 1) -#define KEY_D_0_108 (KEY_D_0_104 + 1) -#define KEY_D_0_163 (KEY_D_0_108 + 1) -#define KEY_D_0_188 (KEY_D_0_163 + 1) -#define KEY_D_0_192 (KEY_D_0_188 + 1) -#define KEY_D_0_224 (KEY_D_0_192 + 1) -#define KEY_D_0_228 (KEY_D_0_224 + 1) -#define KEY_D_0_232 (KEY_D_0_228 + 1) -#define KEY_D_0_236 (KEY_D_0_232 + 1) - -#define KEY_DMP_PREVPTAT (KEY_D_0_236 + 1) -#define KEY_D_1_2 (KEY_DMP_PREVPTAT + 1) -#define KEY_D_1_4 (KEY_D_1_2 + 1) -#define KEY_D_1_8 (KEY_D_1_4 + 1) -#define KEY_D_1_10 (KEY_D_1_8 + 1) -#define KEY_D_1_24 (KEY_D_1_10 + 1) -#define KEY_D_1_28 (KEY_D_1_24 + 1) -#define KEY_D_1_36 (KEY_D_1_28 + 1) -#define KEY_D_1_40 (KEY_D_1_36 + 1) -#define KEY_D_1_44 (KEY_D_1_40 + 1) -#define KEY_D_1_72 (KEY_D_1_44 + 1) -#define KEY_D_1_74 (KEY_D_1_72 + 1) -#define KEY_D_1_79 (KEY_D_1_74 + 1) -#define KEY_D_1_88 (KEY_D_1_79 + 1) -#define KEY_D_1_90 (KEY_D_1_88 + 1) -#define KEY_D_1_92 (KEY_D_1_90 + 1) -#define KEY_D_1_96 (KEY_D_1_92 + 1) -#define KEY_D_1_98 (KEY_D_1_96 + 1) -#define KEY_D_1_100 (KEY_D_1_98 + 1) -#define KEY_D_1_106 (KEY_D_1_100 + 1) -#define KEY_D_1_108 (KEY_D_1_106 + 1) -#define KEY_D_1_112 (KEY_D_1_108 + 1) -#define KEY_D_1_128 (KEY_D_1_112 + 1) -#define KEY_D_1_152 (KEY_D_1_128 + 1) -#define KEY_D_1_160 (KEY_D_1_152 + 1) -#define KEY_D_1_168 (KEY_D_1_160 + 1) -#define KEY_D_1_175 (KEY_D_1_168 + 1) -#define KEY_D_1_176 (KEY_D_1_175 + 1) -#define KEY_D_1_178 (KEY_D_1_176 + 1) -#define KEY_D_1_179 (KEY_D_1_178 + 1) -#define KEY_D_1_218 (KEY_D_1_179 + 1) -#define KEY_D_1_232 (KEY_D_1_218 + 1) -#define KEY_D_1_236 (KEY_D_1_232 + 1) -#define KEY_D_1_240 (KEY_D_1_236 + 1) -#define KEY_D_1_244 (KEY_D_1_240 + 1) -#define KEY_D_1_250 (KEY_D_1_244 + 1) -#define KEY_D_1_252 (KEY_D_1_250 + 1) -#define KEY_D_2_12 (KEY_D_1_252 + 1) -#define KEY_D_2_96 (KEY_D_2_12 + 1) -#define KEY_D_2_108 (KEY_D_2_96 + 1) -#define KEY_D_2_208 (KEY_D_2_108 + 1) -#define KEY_FLICK_MSG (KEY_D_2_208 + 1) -#define KEY_FLICK_COUNTER (KEY_FLICK_MSG + 1) -#define KEY_FLICK_LOWER (KEY_FLICK_COUNTER + 1) -#define KEY_CFG_FLICK_IN (KEY_FLICK_LOWER + 1) -#define KEY_FLICK_UPPER (KEY_CFG_FLICK_IN + 1) -#define KEY_CGNOTICE_INTR (KEY_FLICK_UPPER + 1) -#define KEY_D_2_224 (KEY_CGNOTICE_INTR + 1) -#define KEY_D_2_244 (KEY_D_2_224 + 1) -#define KEY_D_2_248 (KEY_D_2_244 + 1) -#define KEY_D_2_252 (KEY_D_2_248 + 1) - -#define KEY_D_GYRO_BIAS_X (KEY_D_2_252 + 1) -#define KEY_D_GYRO_BIAS_Y (KEY_D_GYRO_BIAS_X + 1) -#define KEY_D_GYRO_BIAS_Z (KEY_D_GYRO_BIAS_Y + 1) -#define KEY_D_ACC_BIAS_X (KEY_D_GYRO_BIAS_Z + 1) -#define KEY_D_ACC_BIAS_Y (KEY_D_ACC_BIAS_X + 1) -#define KEY_D_ACC_BIAS_Z (KEY_D_ACC_BIAS_Y + 1) -#define KEY_D_GYRO_ENABLE (KEY_D_ACC_BIAS_Z + 1) -#define KEY_D_ACCEL_ENABLE (KEY_D_GYRO_ENABLE + 1) -#define KEY_D_QUAT_ENABLE (KEY_D_ACCEL_ENABLE + 1) -#define KEY_D_OUTPUT_ENABLE (KEY_D_QUAT_ENABLE + 1) -#define KEY_D_ACCEL_CNTR (KEY_D_OUTPUT_ENABLE + 1) -#define KEY_D_GYRO_CNTR (KEY_D_ACCEL_CNTR + 1) -#define KEY_D_QUAT0_CNTR (KEY_D_GYRO_CNTR + 1) -#define KEY_D_QUAT1_CNTR (KEY_D_QUAT0_CNTR + 1) -#define KEY_D_QUAT2_CNTR (KEY_D_QUAT1_CNTR + 1) -#define KEY_D_CR_TIME_G (KEY_D_QUAT2_CNTR + 1) -#define KEY_D_CR_TIME_A (KEY_D_CR_TIME_G + 1) -#define KEY_D_CR_TIME_Q (KEY_D_CR_TIME_A + 1) -#define KEY_D_CS_TAX (KEY_D_CR_TIME_Q + 1) -#define KEY_D_CS_TAY (KEY_D_CS_TAX + 1) -#define KEY_D_CS_TAZ (KEY_D_CS_TAY + 1) -#define KEY_D_CS_TGX (KEY_D_CS_TAZ + 1) -#define KEY_D_CS_TGY (KEY_D_CS_TGX + 1) -#define KEY_D_CS_TGZ (KEY_D_CS_TGY + 1) -#define KEY_D_CS_TQ0 (KEY_D_CS_TGZ + 1) -#define KEY_D_CS_TQ1 (KEY_D_CS_TQ0 + 1) -#define KEY_D_CS_TQ2 (KEY_D_CS_TQ1 + 1) -#define KEY_D_CS_TQ3 (KEY_D_CS_TQ2 + 1) - -/* Compass keys */ -#define KEY_CPASS_GAIN (KEY_D_CS_TQ3 + 1) -#define KEY_CPASS_BIAS_X (KEY_CPASS_GAIN + 1) -#define KEY_CPASS_BIAS_Y (KEY_CPASS_BIAS_X + 1) -#define KEY_CPASS_BIAS_Z (KEY_CPASS_BIAS_Y + 1) -#define KEY_CPASS_MTX_00 (KEY_CPASS_BIAS_Z + 1) -#define KEY_CPASS_MTX_01 (KEY_CPASS_MTX_00 + 1) -#define KEY_CPASS_MTX_02 (KEY_CPASS_MTX_01 + 1) -#define KEY_CPASS_MTX_10 (KEY_CPASS_MTX_02 + 1) -#define KEY_CPASS_MTX_11 (KEY_CPASS_MTX_10 + 1) -#define KEY_CPASS_MTX_12 (KEY_CPASS_MTX_11 + 1) -#define KEY_CPASS_MTX_20 (KEY_CPASS_MTX_12 + 1) -#define KEY_CPASS_MTX_21 (KEY_CPASS_MTX_20 + 1) -#define KEY_CPASS_MTX_22 (KEY_CPASS_MTX_21 + 1) - -/* Gesture Keys */ -#define KEY_DMP_TAPW_MIN (KEY_CPASS_MTX_22 + 1) -#define KEY_DMP_TAP_THR_X (KEY_DMP_TAPW_MIN + 1) -#define KEY_DMP_TAP_THR_Y (KEY_DMP_TAP_THR_X + 1) -#define KEY_DMP_TAP_THR_Z (KEY_DMP_TAP_THR_Y + 1) -#define KEY_DMP_SH_TH_Y (KEY_DMP_TAP_THR_Z + 1) -#define KEY_DMP_SH_TH_X (KEY_DMP_SH_TH_Y + 1) -#define KEY_DMP_SH_TH_Z (KEY_DMP_SH_TH_X + 1) -#define KEY_DMP_ORIENT (KEY_DMP_SH_TH_Z + 1) -#define KEY_D_ACT0 (KEY_DMP_ORIENT + 1) -#define KEY_D_ACSX (KEY_D_ACT0 + 1) -#define KEY_D_ACSY (KEY_D_ACSX + 1) -#define KEY_D_ACSZ (KEY_D_ACSY + 1) - -#define KEY_X_GRT_Y_TMP (KEY_D_ACSZ + 1) -#define KEY_SKIP_X_GRT_Y_TMP (KEY_X_GRT_Y_TMP + 1) -#define KEY_SKIP_END_COMPARE (KEY_SKIP_X_GRT_Y_TMP + 1) -#define KEY_END_COMPARE_Y_X_TMP2 (KEY_SKIP_END_COMPARE + 1) -#define KEY_CFG_DISPLAY_ORIENT_INT (KEY_END_COMPARE_Y_X_TMP2 + 1) -#define KEY_NO_ORIENT_INTERRUPT (KEY_CFG_DISPLAY_ORIENT_INT + 1) -#define KEY_END_COMPARE_Y_X_TMP (KEY_NO_ORIENT_INTERRUPT + 1) -#define KEY_END_ORIENT_1 (KEY_END_COMPARE_Y_X_TMP + 1) -#define KEY_END_COMPARE_Y_X (KEY_END_ORIENT_1 + 1) -#define KEY_END_ORIENT (KEY_END_COMPARE_Y_X + 1) -#define KEY_X_GRT_Y (KEY_END_ORIENT + 1) -#define KEY_NOT_TIME_MINUS_1 (KEY_X_GRT_Y + 1) -#define KEY_END_COMPARE_Y_X_TMP3 (KEY_NOT_TIME_MINUS_1 + 1) -#define KEY_X_GRT_Y_TMP2 (KEY_END_COMPARE_Y_X_TMP3 + 1) - -/*Shake Keys */ -#define KEY_D_0_64 (KEY_X_GRT_Y_TMP2 + 1) -#define KEY_D_2_4 (KEY_D_0_64 + 1) -#define KEY_D_2_8 (KEY_D_2_4 + 1) -#define KEY_D_2_48 (KEY_D_2_8 + 1) -#define KEY_D_2_92 (KEY_D_2_48 + 1) -#define KEY_D_2_94 (KEY_D_2_92 + 1) -#define KEY_D_2_160 (KEY_D_2_94 + 1) -#define KEY_D_3_180 (KEY_D_2_160 + 1) -#define KEY_D_3_184 (KEY_D_3_180 + 1) -#define KEY_D_3_188 (KEY_D_3_184 + 1) -#define KEY_D_3_208 (KEY_D_3_188 + 1) -#define KEY_D_3_240 (KEY_D_3_208 + 1) -#define KEY_RETRACTION_1 (KEY_D_3_240 + 1) -#define KEY_RETRACTION_2 (KEY_RETRACTION_1 + 1) -#define KEY_RETRACTION_3 (KEY_RETRACTION_2 + 1) -#define KEY_RETRACTION_4 (KEY_RETRACTION_3 + 1) -#define KEY_CFG_SHAKE_INT (KEY_RETRACTION_4 + 1) - -/* Authenticate Keys */ -#define KEY_D_AUTH_OUT (KEY_CFG_SHAKE_INT + 1) -#define KEY_D_AUTH_IN (KEY_D_AUTH_OUT + 1) -#define KEY_D_AUTH_A (KEY_D_AUTH_IN + 1) -#define KEY_D_AUTH_B (KEY_D_AUTH_A + 1) - -/* Pedometer standalone only keys */ -#define KEY_D_PEDSTD_BP_B (KEY_D_AUTH_B + 1) -#define KEY_D_PEDSTD_HP_A (KEY_D_PEDSTD_BP_B + 1) -#define KEY_D_PEDSTD_HP_B (KEY_D_PEDSTD_HP_A + 1) -#define KEY_D_PEDSTD_BP_A4 (KEY_D_PEDSTD_HP_B + 1) -#define KEY_D_PEDSTD_BP_A3 (KEY_D_PEDSTD_BP_A4 + 1) -#define KEY_D_PEDSTD_BP_A2 (KEY_D_PEDSTD_BP_A3 + 1) -#define KEY_D_PEDSTD_BP_A1 (KEY_D_PEDSTD_BP_A2 + 1) -#define KEY_D_PEDSTD_INT_THRSH (KEY_D_PEDSTD_BP_A1 + 1) -#define KEY_D_PEDSTD_CLIP (KEY_D_PEDSTD_INT_THRSH + 1) -#define KEY_D_PEDSTD_SB (KEY_D_PEDSTD_CLIP + 1) -#define KEY_D_PEDSTD_SB_TIME (KEY_D_PEDSTD_SB + 1) -#define KEY_D_PEDSTD_PEAKTHRSH (KEY_D_PEDSTD_SB_TIME + 1) -#define KEY_D_PEDSTD_TIML (KEY_D_PEDSTD_PEAKTHRSH + 1) -#define KEY_D_PEDSTD_TIMH (KEY_D_PEDSTD_TIML + 1) -#define KEY_D_PEDSTD_PEAK (KEY_D_PEDSTD_TIMH + 1) -#define KEY_D_PEDSTD_TIMECTR (KEY_D_PEDSTD_PEAK + 1) -#define KEY_D_PEDSTD_STEPCTR (KEY_D_PEDSTD_TIMECTR + 1) -#define KEY_D_PEDSTD_WALKTIME (KEY_D_PEDSTD_STEPCTR + 1) -#define KEY_D_PEDSTD_DECI (KEY_D_PEDSTD_WALKTIME + 1) -#define KEY_CFG_PED_INT (KEY_D_PEDSTD_DECI + 1) -#define KEY_CFG_PED_ENABLE (KEY_CFG_PED_INT + 1) - -/*Host Based No Motion*/ -#define KEY_D_HOST_NO_MOT (KEY_CFG_PED_ENABLE + 1) - -/*Host Based Accel Bias*/ -#define KEY_D_ACCEL_BIAS (KEY_D_HOST_NO_MOT + 1) - -/*Screen/Display Orientation Keys*/ -#define KEY_D_ORIENT_GAP (KEY_D_ACCEL_BIAS + 1) -#define KEY_D_TILT0_H (KEY_D_ORIENT_GAP + 1) -#define KEY_D_TILT0_L (KEY_D_TILT0_H + 1) -#define KEY_D_TILT1_H (KEY_D_TILT0_L + 1) -#define KEY_D_TILT1_L (KEY_D_TILT1_H + 1) -#define KEY_D_TILT2_H (KEY_D_TILT1_L + 1) -#define KEY_D_TILT2_L (KEY_D_TILT2_H + 1) -#define KEY_D_TILT3_H (KEY_D_TILT2_L + 1) -#define KEY_D_TILT3_L (KEY_D_TILT3_H + 1) - -/* Stream keys */ -#define KEY_STREAM_P_GYRO_Z (KEY_D_TILT3_L + 1) -#define KEY_STREAM_P_GYRO_Y (KEY_STREAM_P_GYRO_Z + 1) -#define KEY_STREAM_P_GYRO_X (KEY_STREAM_P_GYRO_Y + 1) -#define KEY_STREAM_P_TEMP (KEY_STREAM_P_GYRO_X + 1) -#define KEY_STREAM_P_AUX_Y (KEY_STREAM_P_TEMP + 1) -#define KEY_STREAM_P_AUX_X (KEY_STREAM_P_AUX_Y + 1) -#define KEY_STREAM_P_AUX_Z (KEY_STREAM_P_AUX_X + 1) -#define KEY_STREAM_P_ACCEL_Y (KEY_STREAM_P_AUX_Z + 1) -#define KEY_STREAM_P_ACCEL_X (KEY_STREAM_P_ACCEL_Y + 1) -#define KEY_STREAM_P_FOOTER (KEY_STREAM_P_ACCEL_X + 1) -#define KEY_STREAM_P_ACCEL_Z (KEY_STREAM_P_FOOTER + 1) - -/* Batch mode */ -#define KEY_BM_ENABLE (KEY_STREAM_P_ACCEL_Z + 1) -#define KEY_BM_BATCH_THLD (KEY_BM_ENABLE + 1) -#define KEY_BM_BATCH_CNTR (KEY_BM_BATCH_THLD + 1) -#define KEY_BM_NUMWORD_TOFILL (KEY_BM_BATCH_CNTR + 1) - -/* Watermark */ -#define KEY_CFG_WATERMARK_H (KEY_BM_NUMWORD_TOFILL + 1) -#define KEY_CFG_WATERMARK_L (KEY_CFG_WATERMARK_H + 1) - -/* FIFO output control */ -#define KEY_CFG_OUT_ACCL (KEY_CFG_WATERMARK_L + 1) -#define KEY_CFG_OUT_GYRO (KEY_CFG_OUT_ACCL + 1) -#define KEY_CFG_OUT_3QUAT (KEY_CFG_OUT_GYRO + 1) -#define KEY_CFG_OUT_6QUAT (KEY_CFG_OUT_3QUAT + 1) -#define KEY_CFG_OUT_PQUAT (KEY_CFG_OUT_6QUAT + 1) -#define KEY_CFG_FIFO_INT (KEY_CFG_OUT_PQUAT + 1) -/* Ped Step detection */ -#define KEY_CFG_PEDSTEP_DET (KEY_CFG_FIFO_INT + 1) - -/* Screen Orientation data */ -#define KEY_SO_DATA (KEY_CFG_PEDSTEP_DET + 1) - -/* MPU for DMP Android K */ -#define KEY_P_HW_ID (KEY_SO_DATA + 1) - -#define NUM_KEYS (KEY_P_HW_ID + 1) - -struct tKeyLabel { - unsigned short key; - unsigned short addr; -}; - -#define DINA0A 0x0a -#define DINA22 0x22 -#define DINA42 0x42 -#define DINA5A 0x5a - -#define DINA06 0x06 -#define DINA0E 0x0e -#define DINA16 0x16 -#define DINA1E 0x1e -#define DINA26 0x26 -#define DINA2E 0x2e -#define DINA36 0x36 -#define DINA3E 0x3e -#define DINA46 0x46 -#define DINA4E 0x4e -#define DINA56 0x56 -#define DINA5E 0x5e -#define DINA66 0x66 -#define DINA6E 0x6e -#define DINA76 0x76 -#define DINA7E 0x7e - -#define DINA00 0x00 -#define DINA08 0x08 -#define DINA10 0x10 -#define DINA18 0x18 -#define DINA20 0x20 -#define DINA28 0x28 -#define DINA30 0x30 -#define DINA38 0x38 -#define DINA40 0x40 -#define DINA48 0x48 -#define DINA50 0x50 -#define DINA58 0x58 -#define DINA60 0x60 -#define DINA68 0x68 -#define DINA70 0x70 -#define DINA78 0x78 - -#define DINA04 0x04 -#define DINA0C 0x0c -#define DINA14 0x14 -#define DINA1C 0x1C -#define DINA24 0x24 -#define DINA2C 0x2c -#define DINA34 0x34 -#define DINA3C 0x3c -#define DINA44 0x44 -#define DINA4C 0x4c -#define DINA54 0x54 -#define DINA5C 0x5c -#define DINA64 0x64 -#define DINA6C 0x6c -#define DINA74 0x74 -#define DINA7C 0x7c - -#define DINA01 0x01 -#define DINA09 0x09 -#define DINA11 0x11 -#define DINA19 0x19 -#define DINA21 0x21 -#define DINA29 0x29 -#define DINA31 0x31 -#define DINA39 0x39 -#define DINA41 0x41 -#define DINA49 0x49 -#define DINA51 0x51 -#define DINA59 0x59 -#define DINA61 0x61 -#define DINA69 0x69 -#define DINA71 0x71 -#define DINA79 0x79 - -#define DINA25 0x25 -#define DINA2D 0x2d -#define DINA35 0x35 -#define DINA3D 0x3d -#define DINA4D 0x4d -#define DINA55 0x55 -#define DINA5D 0x5D -#define DINA6D 0x6d -#define DINA75 0x75 -#define DINA7D 0x7d - -#define DINADC 0xdc -#define DINAF2 0xf2 -#define DINAAB 0xab -#define DINAAA 0xaa -#define DINAF1 0xf1 -#define DINADF 0xdf -#define DINADA 0xda -#define DINAB1 0xb1 -#define DINAB9 0xb9 -#define DINAF3 0xf3 -#define DINA8B 0x8b -#define DINAA3 0xa3 -#define DINA91 0x91 -#define DINAB6 0xb6 -#define DINAB4 0xb4 - - -#define DINC00 0x00 -#define DINC01 0x01 -#define DINC02 0x02 -#define DINC03 0x03 -#define DINC08 0x08 -#define DINC09 0x09 -#define DINC0A 0x0a -#define DINC0B 0x0b -#define DINC10 0x10 -#define DINC11 0x11 -#define DINC12 0x12 -#define DINC13 0x13 -#define DINC18 0x18 -#define DINC19 0x19 -#define DINC1A 0x1a -#define DINC1B 0x1b - -#define DINC20 0x20 -#define DINC21 0x21 -#define DINC22 0x22 -#define DINC23 0x23 -#define DINC28 0x28 -#define DINC29 0x29 -#define DINC2A 0x2a -#define DINC2B 0x2b -#define DINC30 0x30 -#define DINC31 0x31 -#define DINC32 0x32 -#define DINC33 0x33 -#define DINC38 0x38 -#define DINC39 0x39 -#define DINC3A 0x3a -#define DINC3B 0x3b - -#define DINC40 0x40 -#define DINC41 0x41 -#define DINC42 0x42 -#define DINC43 0x43 -#define DINC48 0x48 -#define DINC49 0x49 -#define DINC4A 0x4a -#define DINC4B 0x4b -#define DINC50 0x50 -#define DINC51 0x51 -#define DINC52 0x52 -#define DINC53 0x53 -#define DINC58 0x58 -#define DINC59 0x59 -#define DINC5A 0x5a -#define DINC5B 0x5b - -#define DINC60 0x60 -#define DINC61 0x61 -#define DINC62 0x62 -#define DINC63 0x63 -#define DINC68 0x68 -#define DINC69 0x69 -#define DINC6A 0x6a -#define DINC6B 0x6b -#define DINC70 0x70 -#define DINC71 0x71 -#define DINC72 0x72 -#define DINC73 0x73 -#define DINC78 0x78 -#define DINC79 0x79 -#define DINC7A 0x7a -#define DINC7B 0x7b -#define DIND40 0x40 -#define DINA80 0x80 -#define DINA90 0x90 -#define DINAA0 0xa0 -#define DINAC9 0xc9 -#define DINACB 0xcb -#define DINACD 0xcd -#define DINACF 0xcf -#define DINAC8 0xc8 -#define DINACA 0xca -#define DINACC 0xcc -#define DINACE 0xce -#define DINAD8 0xd8 -#define DINADD 0xdd -#define DINAF8 0xf0 -#define DINAFE 0xfe - -#define DINBF8 0xf8 -#define DINAC0 0xb0 -#define DINAC1 0xb1 -#define DINAC2 0xb4 -#define DINAC3 0xb5 -#define DINAC4 0xb8 -#define DINAC5 0xb9 -#define DINBC0 0xc0 -#define DINBC2 0xc2 -#define DINBC4 0xc4 -#define DINBC6 0xc6 - -#endif diff --git a/drivers/staging/iio/imu/inv_mpu/dmpmap.h b/drivers/staging/iio/imu/inv_mpu/dmpmap.h deleted file mode 100644 index 28f59af01571..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/dmpmap.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file dmpmap.h - * @brief dmp map definition - * @details This file is part of invensense mpu driver code - * - */ -#ifndef DMPMAP_H -#define DMPMAP_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define DMP_PTAT 0 -#define DMP_XGYR 2 -#define DMP_YGYR 4 -#define DMP_ZGYR 6 -#define DMP_XACC 8 -#define DMP_YACC 10 -#define DMP_ZACC 12 -#define DMP_ADC1 14 -#define DMP_ADC2 16 -#define DMP_ADC3 18 -#define DMP_BIASUNC 20 -#define DMP_FIFORT 22 -#define DMP_INVGSFH 24 -#define DMP_INVGSFL 26 -#define DMP_1H 28 -#define DMP_1L 30 -#define DMP_BLPFSTCH 32 -#define DMP_BLPFSTCL 34 -#define DMP_BLPFSXH 36 -#define DMP_BLPFSXL 38 -#define DMP_BLPFSYH 40 -#define DMP_BLPFSYL 42 -#define DMP_BLPFSZH 44 -#define DMP_BLPFSZL 46 -#define DMP_BLPFMTC 48 -#define DMP_SMC 50 -#define DMP_BLPFMXH 52 -#define DMP_BLPFMXL 54 -#define DMP_BLPFMYH 56 -#define DMP_BLPFMYL 58 -#define DMP_BLPFMZH 60 -#define DMP_BLPFMZL 62 -#define DMP_BLPFC 64 -#define DMP_SMCTH 66 -#define DMP_0H2 68 -#define DMP_0L2 70 -#define DMP_BERR2H 72 -#define DMP_BERR2L 74 -#define DMP_BERR2NH 76 -#define DMP_SMCINC 78 -#define DMP_ANGVBXH 80 -#define DMP_ANGVBXL 82 -#define DMP_ANGVBYH 84 -#define DMP_ANGVBYL 86 -#define DMP_ANGVBZH 88 -#define DMP_ANGVBZL 90 -#define DMP_BERR1H 92 -#define DMP_BERR1L 94 -#define DMP_ATCH 96 -#define DMP_BIASUNCSF 98 -#define DMP_ACT2H 100 -#define DMP_ACT2L 102 -#define DMP_GSFH 104 -#define DMP_GSFL 106 -#define DMP_GH 108 -#define DMP_GL 110 -#define DMP_0_5H 112 -#define DMP_0_5L 114 -#define DMP_0_0H 116 -#define DMP_0_0L 118 -#define DMP_1_0H 120 -#define DMP_1_0L 122 -#define DMP_1_5H 124 -#define DMP_1_5L 126 -#define DMP_TMP1AH 128 -#define DMP_TMP1AL 130 -#define DMP_TMP2AH 132 -#define DMP_TMP2AL 134 -#define DMP_TMP3AH 136 -#define DMP_TMP3AL 138 -#define DMP_TMP4AH 140 -#define DMP_TMP4AL 142 -#define DMP_XACCW 144 -#define DMP_TMP5 146 -#define DMP_XACCB 148 -#define DMP_TMP8 150 -#define DMP_YACCB 152 -#define DMP_TMP9 154 -#define DMP_ZACCB 156 -#define DMP_TMP10 158 -#define DMP_DZH 160 -#define DMP_DZL 162 -#define DMP_XGCH 164 -#define DMP_XGCL 166 -#define DMP_YGCH 168 -#define DMP_YGCL 170 -#define DMP_ZGCH 172 -#define DMP_ZGCL 174 -#define DMP_YACCW 176 -#define DMP_TMP7 178 -#define DMP_AFB1H 180 -#define DMP_AFB1L 182 -#define DMP_AFB2H 184 -#define DMP_AFB2L 186 -#define DMP_MAGFBH 188 -#define DMP_MAGFBL 190 -#define DMP_QT1H 192 -#define DMP_QT1L 194 -#define DMP_QT2H 196 -#define DMP_QT2L 198 -#define DMP_QT3H 200 -#define DMP_QT3L 202 -#define DMP_QT4H 204 -#define DMP_QT4L 206 -#define DMP_CTRL1H 208 -#define DMP_CTRL1L 210 -#define DMP_CTRL2H 212 -#define DMP_CTRL2L 214 -#define DMP_CTRL3H 216 -#define DMP_CTRL3L 218 -#define DMP_CTRL4H 220 -#define DMP_CTRL4L 222 -#define DMP_CTRLS1 224 -#define DMP_CTRLSF1 226 -#define DMP_CTRLS2 228 -#define DMP_CTRLSF2 230 -#define DMP_CTRLS3 232 -#define DMP_CTRLSFNLL 234 -#define DMP_CTRLS4 236 -#define DMP_CTRLSFNL2 238 -#define DMP_CTRLSFNL 240 -#define DMP_TMP30 242 -#define DMP_CTRLSFJT 244 -#define DMP_TMP31 246 -#define DMP_TMP11 248 -#define DMP_CTRLSF2_2 250 -#define DMP_TMP12 252 -#define DMP_CTRLSF1_2 254 -#define DMP_PREVPTAT 256 -#define DMP_ACCZB 258 -#define DMP_ACCXB 264 -#define DMP_ACCYB 266 -#define DMP_1HB 272 -#define DMP_1LB 274 -#define DMP_0H 276 -#define DMP_0L 278 -#define DMP_ASR22H 280 -#define DMP_ASR22L 282 -#define DMP_ASR6H 284 -#define DMP_ASR6L 286 -#define DMP_TMP13 288 -#define DMP_TMP14 290 -#define DMP_FINTXH 292 -#define DMP_FINTXL 294 -#define DMP_FINTYH 296 -#define DMP_FINTYL 298 -#define DMP_FINTZH 300 -#define DMP_FINTZL 302 -#define DMP_TMP1BH 304 -#define DMP_TMP1BL 306 -#define DMP_TMP2BH 308 -#define DMP_TMP2BL 310 -#define DMP_TMP3BH 312 -#define DMP_TMP3BL 314 -#define DMP_TMP4BH 316 -#define DMP_TMP4BL 318 -#define DMP_STXG 320 -#define DMP_ZCTXG 322 -#define DMP_STYG 324 -#define DMP_ZCTYG 326 -#define DMP_STZG 328 -#define DMP_ZCTZG 330 -#define DMP_CTRLSFJT2 332 -#define DMP_CTRLSFJTCNT 334 -#define DMP_PVXG 336 -#define DMP_TMP15 338 -#define DMP_PVYG 340 -#define DMP_TMP16 342 -#define DMP_PVZG 344 -#define DMP_TMP17 346 -#define DMP_MNMFLAGH 352 -#define DMP_MNMFLAGL 354 -#define DMP_MNMTMH 356 -#define DMP_MNMTML 358 -#define DMP_MNMTMTHRH 360 -#define DMP_MNMTMTHRL 362 -#define DMP_MNMTHRH 364 -#define DMP_MNMTHRL 366 -#define DMP_ACCQD4H 368 -#define DMP_ACCQD4L 370 -#define DMP_ACCQD5H 372 -#define DMP_ACCQD5L 374 -#define DMP_ACCQD6H 376 -#define DMP_ACCQD6L 378 -#define DMP_ACCQD7H 380 -#define DMP_ACCQD7L 382 -#define DMP_ACCQD0H 384 -#define DMP_ACCQD0L 386 -#define DMP_ACCQD1H 388 -#define DMP_ACCQD1L 390 -#define DMP_ACCQD2H 392 -#define DMP_ACCQD2L 394 -#define DMP_ACCQD3H 396 -#define DMP_ACCQD3L 398 -#define DMP_XN2H 400 -#define DMP_XN2L 402 -#define DMP_XN1H 404 -#define DMP_XN1L 406 -#define DMP_YN2H 408 -#define DMP_YN2L 410 -#define DMP_YN1H 412 -#define DMP_YN1L 414 -#define DMP_YH 416 -#define DMP_YL 418 -#define DMP_B0H 420 -#define DMP_B0L 422 -#define DMP_A1H 424 -#define DMP_A1L 426 -#define DMP_A2H 428 -#define DMP_A2L 430 -#define DMP_SEM1 432 -#define DMP_FIFOCNT 434 -#define DMP_SH_TH_X 436 -#define DMP_PACKET 438 -#define DMP_SH_TH_Y 440 -#define DMP_FOOTER 442 -#define DMP_SH_TH_Z 444 -#define DMP_TEMP29 448 -#define DMP_TEMP30 450 -#define DMP_XACCB_PRE 452 -#define DMP_XACCB_PREL 454 -#define DMP_YACCB_PRE 456 -#define DMP_YACCB_PREL 458 -#define DMP_ZACCB_PRE 460 -#define DMP_ZACCB_PREL 462 -#define DMP_TMP22 464 -#define DMP_TAP_TIMER 466 -#define DMP_TAP_THX 468 -#define DMP_TAP_THY 472 -#define DMP_TAP_THZ 476 -#define DMP_TAPW_MIN 478 -#define DMP_TMP25 480 -#define DMP_TMP26 482 -#define DMP_TMP27 484 -#define DMP_TMP28 486 -#define DMP_ORIENT 488 -#define DMP_THRSH 490 -#define DMP_ENDIANH 492 -#define DMP_ENDIANL 494 -#define DMP_BLPFNMTCH 496 -#define DMP_BLPFNMTCL 498 -#define DMP_BLPFNMXH 500 -#define DMP_BLPFNMXL 502 -#define DMP_BLPFNMYH 504 -#define DMP_BLPFNMYL 506 -#define DMP_BLPFNMZH 508 -#define DMP_BLPFNMZL 510 -#ifdef __cplusplus -} -#endif -#endif diff --git a/drivers/staging/iio/imu/inv_mpu/inv_counters.c b/drivers/staging/iio/imu/inv_mpu/inv_counters.c deleted file mode 100644 index 3ba495fab8ae..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_counters.c +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * @file inv_counters.c - * @brief Exports i2c read write counts through sysfs - * - * @version 0.1 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_counters.h" - -static int mpu_irq; -static int accel_irq; -static int compass_irq; - -struct inv_counters { - uint32_t i2c_tempreads; - uint32_t i2c_mpureads; - uint32_t i2c_mpuwrites; - uint32_t i2c_accelreads; - uint32_t i2c_accelwrites; - uint32_t i2c_compassreads; - uint32_t i2c_compasswrites; - uint32_t i2c_compassirq; - uint32_t i2c_accelirq; -}; - -static struct inv_counters Counters; - -static ssize_t i2c_counters_show(struct class *cls, - struct class_attribute *attr, char *buf) -{ - return scnprintf(buf, PAGE_SIZE, - "%ld.%03ld %u %u %u %u %u %u %u %u %u %u\n", - jiffies / HZ, ((jiffies % HZ) * (1024 / HZ)), - mpu_irq ? kstat_irqs(mpu_irq) : 0, - Counters.i2c_tempreads, - Counters.i2c_mpureads, Counters.i2c_mpuwrites, - accel_irq ? kstat_irqs(accel_irq) : Counters.i2c_accelirq, - Counters.i2c_accelreads, Counters.i2c_accelwrites, - compass_irq ? kstat_irqs(compass_irq) : Counters.i2c_compassirq, - Counters.i2c_compassreads, Counters.i2c_compasswrites); -} - -void inv_iio_counters_set_i2cirq(enum irqtype type, int irq) -{ - switch (type) { - case IRQ_MPU: - mpu_irq = irq; - break; - case IRQ_ACCEL: - accel_irq = irq; - break; - case IRQ_COMPASS: - compass_irq = irq; - break; - } -} -EXPORT_SYMBOL_GPL(inv_iio_counters_set_i2cirq); - -void inv_iio_counters_tempread(int count) -{ - Counters.i2c_tempreads += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_tempread); - -void inv_iio_counters_mpuread(int count) -{ - Counters.i2c_mpureads += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_mpuread); - -void inv_iio_counters_mpuwrite(int count) -{ - Counters.i2c_mpuwrites += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_mpuwrite); - -void inv_iio_counters_accelread(int count) -{ - Counters.i2c_accelreads += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_accelread); - -void inv_iio_counters_accelwrite(int count) -{ - Counters.i2c_accelwrites += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_accelwrite); - -void inv_iio_counters_compassread(int count) -{ - Counters.i2c_compassreads += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_compassread); - -void inv_iio_counters_compasswrite(int count) -{ - Counters.i2c_compasswrites += count; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_compasswrite); - -void inv_iio_counters_compassirq(void) -{ - Counters.i2c_compassirq++; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_compassirq); - -void inv_iio_counters_accelirq(void) -{ - Counters.i2c_accelirq++; -} -EXPORT_SYMBOL_GPL(inv_iio_counters_accelirq); - -static struct class_attribute inv_class_attr[] = { - __ATTR(i2c_counter, S_IRUGO, i2c_counters_show, NULL), - __ATTR_NULL -}; - -static struct class inv_counters_class = { - .name = "inv_counters", - .owner = THIS_MODULE, - .class_attrs = (struct class_attribute *) &inv_class_attr -}; - -static int __init inv_counters_init(void) -{ - memset(&Counters, 0, sizeof(Counters)); - - return class_register(&inv_counters_class); -} - -static void __exit inv_counters_exit(void) -{ - class_unregister(&inv_counters_class); -} - -module_init(inv_counters_init); -module_exit(inv_counters_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("GESL"); -MODULE_DESCRIPTION("inv_counters debug support"); - diff --git a/drivers/staging/iio/imu/inv_mpu/inv_counters.h b/drivers/staging/iio/imu/inv_mpu/inv_counters.h deleted file mode 100644 index c3221718a55f..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_counters.h +++ /dev/null @@ -1,73 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * @file inv_counters.h - * @brief Debug file to keep track of various counters for the InvenSense - * sensor drivers. - * - * @version 0.1 - */ - -#ifndef _INV_COUNTERS_H_ -#define _INV_COUNTERS_H_ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_INV_TESTING - -enum irqtype { - IRQ_MPU, - IRQ_ACCEL, - IRQ_COMPASS -}; - -#define INV_I2C_INC_MPUREAD(x) inv_iio_counters_mpuread(x) -#define INV_I2C_INC_MPUWRITE(x) inv_iio_counters_mpuwrite(x) -#define INV_I2C_INC_ACCELREAD(x) inv_iio_counters_accelread(x) -#define INV_I2C_INC_ACCELWRITE(x) inv_iio_counters_accelwrite(x) -#define INV_I2C_INC_COMPASSREAD(x) inv_iio_counters_compassread(x) -#define INV_I2C_INC_COMPASSWRITE(x) inv_iio_counters_compasswrite(x) - -#define INV_I2C_INC_TEMPREAD(x) inv_iio_counters_tempread(x) - -#define INV_I2C_SETIRQ(type, irq) inv_iio_counters_set_i2cirq(type, irq) -#define INV_I2C_INC_COMPASSIRQ() inv_iio_counters_compassirq() -#define INV_I2C_INC_ACCELIRQ() inv_iio_counters_accelirq() - -void inv_iio_counters_mpuread(int count); -void inv_iio_counters_mpuwrite(int count); -void inv_iio_counters_accelread(int count); -void inv_iio_counters_accelwrite(int count); -void inv_iio_counters_compassread(int count); -void inv_iio_counters_compasswrite(int count); - -void inv_iio_counters_tempread(int count); - -void inv_iio_counters_set_i2cirq(enum irqtype type, int irq); -void inv_iio_counters_compassirq(void); -void inv_iio_counters_accelirq(void); - -#else - -#define INV_I2C_INC_MPUREAD(x) -#define INV_I2C_INC_MPUWRITE(x) -#define INV_I2C_INC_ACCELREAD(x) -#define INV_I2C_INC_ACCELWRITE(x) -#define INV_I2C_INC_COMPASSREAD(x) -#define INV_I2C_INC_COMPASSWRITE(x) - -#define INV_I2C_INC_TEMPREAD(x) - -#define INV_I2C_SETIRQ(type, irq) -#define INV_I2C_INC_COMPASSIRQ() -#define INV_I2C_INC_ACCELIRQ() - -#endif /* CONFIG_INV_TESTING */ - -#endif /* _INV_COUNTERS_H_ */ - diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu3050_iio.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu3050_iio.c deleted file mode 100644 index fab04c9a0c79..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu3050_iio.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_mpu3050_iio.c - * @brief A sysfs device driver for Invensense devices - * @details This file is part of invensense mpu driver code - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_mpu_iio.h" -#define MPU3050_NACK_MIN_TIME (2 * 1000) -#define MPU3050_NACK_MAX_TIME (3 * 1000) - -#define MPU3050_ONE_MPU_TIME 20 -#define MPU3050_BOGUS_ADDR 0x7F -int __attribute__((weak)) inv_register_mpu3050_slave(struct inv_mpu_iio_s *st) -{ - return 0; -} - -int set_3050_bypass(struct inv_mpu_iio_s *st, bool enable) -{ - struct inv_reg_map_s *reg; - int result; - u8 b; - - reg = &st->reg; - result = inv_plat_read(st, reg->user_ctrl, 1, &b); - if (result) - return result; - if (((b & BIT_3050_AUX_IF_EN) == 0) && enable) - return 0; - if ((b & BIT_3050_AUX_IF_EN) && (enable == 0)) - return 0; - b &= ~BIT_3050_AUX_IF_EN; - if (!enable) { - b |= BIT_3050_AUX_IF_EN; - result = inv_plat_single_write(st, reg->user_ctrl, b | st->i2c_dis); - return result; - } else { - /* Coming out of I2C is tricky due to several erratta. Do not - * modify this algorithm - */ - /* - * 1) wait for the right time and send the command to change - * the aux i2c slave address to an invalid address that will - * get nack'ed - * - * 0x00 is broadcast. 0x7F is unlikely to be used by any aux. - */ - result = inv_plat_single_write(st, REG_3050_SLAVE_ADDR, - MPU3050_BOGUS_ADDR); - if (result) - return result; - /* - * 2) wait enough time for a nack to occur, then go into - * bypass mode: - */ - usleep_range(MPU3050_NACK_MIN_TIME, MPU3050_NACK_MAX_TIME); - result = inv_plat_single_write(st, reg->user_ctrl, b | st->i2c_dis); - if (result) - return result; - /* - * 3) wait for up to one MPU cycle then restore the slave - * address - */ - msleep(MPU3050_ONE_MPU_TIME); - - result = inv_plat_single_write(st, REG_3050_SLAVE_ADDR, - st->plat_data.secondary_i2c_addr); - if (result) - return result; - - result = inv_plat_single_write(st, reg->user_ctrl, - (b | BIT_3050_AUX_IF_RST | st->i2c_dis)); - if (result) - return result; - usleep_range(MPU3050_NACK_MIN_TIME, MPU3050_NACK_MAX_TIME); - } - return 0; -} - -void inv_setup_reg_mpu3050(struct inv_reg_map_s *reg) -{ - reg->fifo_en = REG_3050_FIFO_EN; - reg->sample_rate_div = REG_3050_SAMPLE_RATE_DIV; - reg->lpf = REG_3050_LPF; - reg->fifo_count_h = REG_3050_FIFO_COUNT_H; - reg->fifo_r_w = REG_3050_FIFO_R_W; - reg->user_ctrl = REG_3050_USER_CTRL; - reg->pwr_mgmt_1 = REG_3050_PWR_MGMT_1; - reg->raw_gyro = REG_3050_RAW_GYRO; - reg->raw_accl = REG_3050_AUX_XOUT_H; - reg->temperature = REG_3050_TEMPERATURE; - reg->int_enable = REG_3050_INT_ENABLE; - reg->int_status = REG_3050_INT_STATUS; -} - -int inv_switch_3050_gyro_engine(struct inv_mpu_iio_s *st, bool en) -{ - struct inv_reg_map_s *reg; - u8 data, p; - int result; - reg = &st->reg; - if (en) { - data = INV_CLK_PLL; - p = (BITS_3050_POWER1 | data); - result = inv_plat_single_write(st, reg->pwr_mgmt_1, p); - if (result) - return result; - p = (BITS_3050_POWER2 | data); - result = inv_plat_single_write(st, reg->pwr_mgmt_1, p); - if (result) - return result; - p = data; - result = inv_plat_single_write(st, reg->pwr_mgmt_1, p); - msleep(SENSOR_UP_TIME); - } else { - p = BITS_3050_GYRO_STANDBY; - result = inv_plat_single_write(st, reg->pwr_mgmt_1, p); - } - - return result; -} - -int inv_switch_3050_accl_engine(struct inv_mpu_iio_s *st, bool en) -{ - int result; - if (NULL == st->mpu_slave) - return -EPERM; - if (en) - result = st->mpu_slave->resume(st); - else - result = st->mpu_slave->suspend(st); - - return result; -} - -/** - * inv_init_config_mpu3050() - Initialize hardware, disable FIFO. - * @st: Device driver instance. - * Initial configuration: - * FSR: +/- 2000DPS - * DLPF: 42Hz - * FIFO rate: 50Hz - * Clock source: Gyro PLL - */ -int inv_init_config_mpu3050(struct iio_dev *indio_dev) -{ - struct inv_reg_map_s *reg; - int result; - u8 data; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - if (st->chip_config.is_asleep) - return -EPERM; - /*reading AUX VDDIO register */ - result = inv_plat_read(st, REG_3050_AUX_VDDIO, 1, &data); - if (result) - return result; - data &= ~BIT_3050_VDDIO; - if (st->plat_data.level_shifter) - data |= BIT_3050_VDDIO; - result = inv_plat_single_write(st, REG_3050_AUX_VDDIO, data); - if (result) - return result; - - reg = &st->reg; - /*2000dps full scale range*/ - result = inv_plat_single_write(st, reg->lpf, - (INV_FSR_2000DPS << GYRO_CONFIG_FSR_SHIFT) - | INV_FILTER_42HZ); - if (result) - return result; - st->chip_config.fsr = INV_FSR_2000DPS; - st->chip_config.lpf = INV_FILTER_42HZ; - result = inv_plat_single_write(st, reg->sample_rate_div, - ONE_K_HZ/INIT_FIFO_RATE - 1); - if (result) - return result; - st->chip_config.fifo_rate = INIT_FIFO_RATE; - st->chip_config.new_fifo_rate = INIT_FIFO_RATE; - st->irq_dur_ns = INIT_DUR_TIME; - if ((SECONDARY_SLAVE_TYPE_ACCEL == st->plat_data.sec_slave_type) && - st->mpu_slave) { - result = st->mpu_slave->setup(st); - if (result) - return result; - result = st->mpu_slave->set_fs(st, INV_FS_02G); - if (result) - return result; - result = st->mpu_slave->set_lpf(st, INIT_FIFO_RATE); - if (result) - return result; - } - - return 0; -} - -/** - * set_power_mpu3050() - set power of mpu3050. - * @st: Device driver instance. - * @power_on: on/off - */ -int set_power_mpu3050(struct inv_mpu_iio_s *st, bool power_on) -{ - struct inv_reg_map_s *reg; - u8 data, p; - int result; - reg = &st->reg; - if (power_on) { - data = 0; - } else { - if (st->mpu_slave) { - result = st->mpu_slave->suspend(st); - if (result) - return result; - } - data = BIT_SLEEP; - } - if (st->chip_config.gyro_enable) { - p = (BITS_3050_POWER1 | INV_CLK_PLL); - result = inv_plat_single_write(st, reg->pwr_mgmt_1, data | p); - if (result) - return result; - - p = (BITS_3050_POWER2 | INV_CLK_PLL); - result = inv_plat_single_write(st, reg->pwr_mgmt_1, data | p); - if (result) - return result; - - p = INV_CLK_PLL; - result = inv_plat_single_write(st, reg->pwr_mgmt_1, data | p); - if (result) - return result; - } else { - data |= (BITS_3050_GYRO_STANDBY | INV_CLK_INTERNAL); - result = inv_plat_single_write(st, reg->pwr_mgmt_1, data); - if (result) - return result; - } - if (power_on) { - msleep(POWER_UP_TIME); - if (st->mpu_slave) { - result = st->mpu_slave->resume(st); - if (result) - return result; - } - } - st->chip_config.is_asleep = !power_on; - - return 0; -} -/** - * @} - */ - diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_core.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_core.c deleted file mode 100644 index 3e7d07b463c3..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_core.c +++ /dev/null @@ -1,1944 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_mpu_core.c - * @brief A sysfs device driver for Invensense devices - * @details This driver currently works for the - * MPU3050/MPU6050/MPU9150/MPU6500/MPU9250 devices. - */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_mpu_iio.h" -#ifdef INV_KERNEL_3_10 -#include -#else -#include "sysfs.h" -#endif -#include "inv_counters.h" - -s64 get_time_ns(void) -{ - struct timespec ts; - ktime_get_ts(&ts); - return timespec_to_ns(&ts); -} - -static const short AKM8975_ST_Lower[3] = {-100, -100, -1000}; -static const short AKM8975_ST_Upper[3] = {100, 100, -300}; - -static const short AKM8972_ST_Lower[3] = {-50, -50, -500}; -static const short AKM8972_ST_Upper[3] = {50, 50, -100}; - -static const short AKM8963_ST_Lower[3] = {-200, -200, -3200}; -static const short AKM8963_ST_Upper[3] = {200, 200, -800}; - -/* This is for compatibility for power state. Should remove once HAL - does not use power_state sysfs entry */ -static bool fake_asleep; - -static const struct inv_hw_s hw_info[INV_NUM_PARTS] = { - {119, "ITG3500"}, - { 63, "MPU3050"}, - {117, "MPU6050"}, - {118, "MPU9150"}, - {119, "MPU6500"}, - {118, "MPU9250"}, - {128, "MPU6515"}, -}; - -/* define INV_REG_NUM_MAX the max register unmbers of all sensor type */ -#define INV_REG_NUM_MAX 128 -static u8 inv_reg_data[128] = {0}; -/** - * inv_reg_store() - Register store for hw poweroff. - */ -int inv_reg_store(struct inv_mpu_iio_s *st) -{ - int ii; - char data; - - if (!st->chip_config.enable) - st->set_power_state(st, true); - for (ii = 0; ii < st->hw->num_reg; ii++) { - /* don't read fifo r/w register */ - if (ii == st->reg.fifo_r_w) - data = 0; - else - inv_plat_read(st, ii, 1, &data); - inv_reg_data[ii] = data; - } - if (!st->chip_config.enable) - st->set_power_state(st, false); - - return 0; -} - -/** - * inv_reg_recover() - Register recover for hw poweroff. - */ -int inv_reg_recover(struct inv_mpu_iio_s *st) -{ - int ii; - char data; - - if (!st->chip_config.enable) - st->set_power_state(st, true); - for (ii = 0; ii < st->hw->num_reg; ii++) { - data = inv_reg_data[ii]; - /* don't write fifo r/w register */ - if (ii == st->reg.fifo_r_w) - continue; - else - inv_plat_single_write(st, ii, data); - } - if (!st->chip_config.enable) - st->set_power_state(st, false); - - return 0; -} - -static void inv_setup_reg(struct inv_reg_map_s *reg) -{ - reg->sample_rate_div = REG_SAMPLE_RATE_DIV; - reg->lpf = REG_CONFIG; - reg->bank_sel = REG_BANK_SEL; - reg->user_ctrl = REG_USER_CTRL; - reg->fifo_en = REG_FIFO_EN; - reg->gyro_config = REG_GYRO_CONFIG; - reg->accl_config = REG_ACCEL_CONFIG; - reg->fifo_count_h = REG_FIFO_COUNT_H; - reg->fifo_r_w = REG_FIFO_R_W; - reg->raw_gyro = REG_RAW_GYRO; - reg->raw_accl = REG_RAW_ACCEL; - reg->temperature = REG_TEMPERATURE; - reg->int_enable = REG_INT_ENABLE; - reg->int_status = REG_INT_STATUS; - reg->pwr_mgmt_1 = REG_PWR_MGMT_1; - reg->pwr_mgmt_2 = REG_PWR_MGMT_2; - reg->mem_start_addr = REG_MEM_START_ADDR; - reg->mem_r_w = REG_MEM_RW; - reg->prgm_strt_addrh = REG_PRGM_STRT_ADDRH; -}; - -static int inv_switch_engine(struct inv_mpu_iio_s *st, bool en, u32 mask) -{ - struct inv_reg_map_s *reg; - u8 data, mgmt_1; - int result; - reg = &st->reg; - /* switch clock needs to be careful. Only when gyro is on, can - clock source be switched to gyro. Otherwise, it must be set to - internal clock */ - if (BIT_PWR_GYRO_STBY == mask) { - result = inv_plat_read(st, reg->pwr_mgmt_1, 1, &mgmt_1); - if (result) - return result; - - mgmt_1 &= ~BIT_CLK_MASK; - } - - if ((BIT_PWR_GYRO_STBY == mask) && (!en)) { - /* turning off gyro requires switch to internal clock first. - Then turn off gyro engine */ - mgmt_1 |= INV_CLK_INTERNAL; - result = inv_plat_single_write(st, reg->pwr_mgmt_1, - mgmt_1); - if (result) - return result; - } - - result = inv_plat_read(st, reg->pwr_mgmt_2, 1, &data); - if (result) - return result; - if (en) - data &= (~mask); - else - data |= mask; - result = inv_plat_single_write(st, reg->pwr_mgmt_2, data); - if (result) - return result; - - if ((BIT_PWR_GYRO_STBY == mask) && en) { - /* only gyro on needs sensor up time */ - msleep(SENSOR_UP_TIME); - /* after gyro is on & stable, switch internal clock to PLL */ - mgmt_1 |= INV_CLK_PLL; - result = inv_plat_single_write(st, reg->pwr_mgmt_1, - mgmt_1); - if (result) - return result; - } - if ((BIT_PWR_ACCL_STBY == mask) && en) - msleep(REG_UP_TIME); - - return 0; -} - -/** - * inv_lpa_freq() - store current low power frequency setting. - */ -static int inv_lpa_freq(struct inv_mpu_iio_s *st, int lpa_freq) -{ - unsigned long result; - u8 d; - const u8 mpu6500_lpa_mapping[] = {2, 4, 6, 7}; - - if (lpa_freq > MAX_LPA_FREQ_PARAM) - return -EINVAL; - - if (INV_MPU6500 == st->chip_type) { - d = mpu6500_lpa_mapping[lpa_freq]; - result = inv_plat_single_write(st, REG_6500_LP_ACCEL_ODR, d); - if (result) - return result; - } - st->chip_config.lpa_freq = lpa_freq; - - return 0; -} - -static int set_power_itg(struct inv_mpu_iio_s *st, bool power_on) -{ - struct inv_reg_map_s *reg; - u8 data; - int result; - - if ((!power_on) == st->chip_config.is_asleep) - return 0; - reg = &st->reg; - if (power_on) - data = 0; - else - data = BIT_SLEEP; - result = inv_plat_single_write(st, reg->pwr_mgmt_1, data); - if (result) - return result; - - if (power_on) { - if (INV_MPU6500 == st->chip_type) - msleep(POWER_UP_TIME); - else - msleep(REG_UP_TIME); - } - - st->chip_config.is_asleep = !power_on; - - return 0; -} - -/** - * inv_init_config() - Initialize hardware, disable FIFO. - * @indio_dev: Device driver instance. - * Initial configuration: - * FSR: +/- 2000DPS - * DLPF: 42Hz - * FIFO rate: 50Hz - */ -static int inv_init_config(struct iio_dev *indio_dev) -{ - struct inv_reg_map_s *reg; - int result; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - - reg = &st->reg; - -#if 0 - /* set int latch en */ - result = inv_plat_single_write(st, REG_INT_PIN_CFG, 0x20); - if (result) - return result; -#endif - result = inv_plat_single_write(st, reg->gyro_config, - INV_FSR_2000DPS << GYRO_CONFIG_FSR_SHIFT); - if (result) - return result; - - st->chip_config.fsr = INV_FSR_2000DPS; - - result = inv_plat_single_write(st, reg->lpf, INV_FILTER_42HZ); - if (result) - return result; - st->chip_config.lpf = INV_FILTER_42HZ; - - result = inv_plat_single_write(st, reg->sample_rate_div, - ONE_K_HZ / INIT_FIFO_RATE - 1); - if (result) - return result; - st->chip_config.fifo_rate = INIT_FIFO_RATE; - st->chip_config.new_fifo_rate = INIT_FIFO_RATE; - st->irq_dur_ns = INIT_DUR_TIME; - st->chip_config.prog_start_addr = DMP_START_ADDR; - st->chip_config.dmp_output_rate = INIT_DMP_OUTPUT_RATE; - st->self_test.samples = INIT_ST_SAMPLES; - st->self_test.threshold = INIT_ST_THRESHOLD; - if (INV_ITG3500 != st->chip_type) { - st->chip_config.accl_fs = INV_FS_02G; - result = inv_plat_single_write(st, reg->accl_config, - (INV_FS_02G << ACCL_CONFIG_FSR_SHIFT)); - if (result) - return result; - st->tap.time = INIT_TAP_TIME; - st->tap.thresh = INIT_TAP_THRESHOLD; - st->tap.min_count = INIT_TAP_MIN_COUNT; - st->smd.threshold = MPU_INIT_SMD_THLD; - st->smd.delay = MPU_INIT_SMD_DELAY_THLD; - st->smd.delay2 = MPU_INIT_SMD_DELAY2_THLD; - - result = inv_plat_single_write(st, REG_ACCEL_MOT_DUR, - INIT_MOT_DUR); - if (result) - return result; - st->mot_int.mot_dur = INIT_MOT_DUR; - - result = inv_plat_single_write(st, REG_ACCEL_MOT_THR, - INIT_MOT_THR); - if (result) - return result; - st->mot_int.mot_thr = INIT_MOT_THR; - } - - return 0; -} - -/** - * inv_compass_scale_show() - show compass scale. - */ -static int inv_compass_scale_show(struct inv_mpu_iio_s *st, int *scale) -{ - if (COMPASS_ID_AK8975 == st->plat_data.sec_slave_id) - *scale = DATA_AKM8975_SCALE; - else if (COMPASS_ID_AK8972 == st->plat_data.sec_slave_id) - *scale = DATA_AKM8972_SCALE; - else if (COMPASS_ID_AK8963 == st->plat_data.sec_slave_id) - if (st->compass_scale) - *scale = DATA_AKM8963_SCALE1; - else - *scale = DATA_AKM8963_SCALE0; - else - return -EINVAL; - - return IIO_VAL_INT; -} - -/** - * inv_sensor_show() - Read gyro/accel data directly from registers. - */ -static int inv_sensor_show(struct inv_mpu_iio_s *st, int reg, int axis, - int *val) -{ - int ind, result; - u8 d[2]; - - ind = (axis - IIO_MOD_X) * 2; - result = i2c_smbus_read_i2c_block_data(st->client, - reg + ind, 2, d); - if (result != 2) - return -EINVAL; - *val = (short)be16_to_cpup((__be16 *)(d)); - - return IIO_VAL_INT; -} - -/** - * mpu_read_raw() - read raw method. - */ -static int mpu_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, int *val2, long mask) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result; - - switch (mask) { - case 0: - /* if enabled, power is on already */ - if (!st->chip_config.enable) - return -EBUSY; - switch (chan->type) { - case IIO_ANGL_VEL: - if (!st->chip_config.gyro_enable) - return -EPERM; - return inv_sensor_show(st, st->reg.raw_gyro, - chan->channel2, val); - case IIO_ACCEL: - if (!st->chip_config.accl_enable) - return -EPERM; - return inv_sensor_show(st, st->reg.raw_accl, - chan->channel2, val); - case IIO_MAGN: - if (!st->chip_config.compass_enable) - return -EPERM; - *val = st->raw_compass[chan->channel2 - IIO_MOD_X]; - return IIO_VAL_INT; - case IIO_QUATERNION: - if (!(st->chip_config.dmp_on - && st->chip_config.quaternion_on)) - return -EPERM; - if (IIO_MOD_R == chan->channel2) - *val = st->raw_quaternion[0]; - else - *val = st->raw_quaternion[chan->channel2 - - IIO_MOD_X + 1]; - return IIO_VAL_INT; - default: - return -EINVAL; - } - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_ANGL_VEL: - { - const s16 gyro_scale[] = {250, 500, 1000, 2000}; - - *val = gyro_scale[st->chip_config.fsr]; - - return IIO_VAL_INT; - } - case IIO_ACCEL: - { - const s16 accel_scale[] = {2, 4, 8, 16}; - *val = accel_scale[st->chip_config.accl_fs] * - st->chip_info.multi; - return IIO_VAL_INT; - } - case IIO_MAGN: - return inv_compass_scale_show(st, val); - default: - return -EINVAL; - } - case IIO_CHAN_INFO_CALIBBIAS: - if (st->chip_config.self_test_run_once == 0) { - /* This can only be run when enable is zero */ - if (st->chip_config.enable) - return -EBUSY; - mutex_lock(&indio_dev->mlock); - - result = inv_power_up_self_test(st); - if (result) - goto error_info_calibbias; - result = inv_do_test(st, 0, st->gyro_bias, - st->accel_bias); - if (result) - goto error_info_calibbias; - st->chip_config.self_test_run_once = 1; -error_info_calibbias: - /* Reset Accel and Gyro full scale range - back to default value */ - inv_recover_setting(st); - mutex_unlock(&indio_dev->mlock); - } - - switch (chan->type) { - case IIO_ANGL_VEL: - *val = st->gyro_bias[chan->channel2 - IIO_MOD_X]; - return IIO_VAL_INT; - case IIO_ACCEL: - *val = st->accel_bias[chan->channel2 - IIO_MOD_X] * - st->chip_info.multi; - return IIO_VAL_INT; - default: - return -EINVAL; - } - case IIO_CHAN_INFO_OFFSET: - switch (chan->type) { - case IIO_ACCEL: - *val = st->input_accel_bias[chan->channel2 - IIO_MOD_X]; - return IIO_VAL_INT; - default: - return -EINVAL; - } - default: - return -EINVAL; - } -} - -/** - * inv_write_fsr() - Configure the gyro's scale range. - */ -static int inv_write_fsr(struct inv_mpu_iio_s *st, int fsr) -{ - struct inv_reg_map_s *reg; - int result; - reg = &st->reg; - if ((fsr < 0) || (fsr > MAX_GYRO_FS_PARAM)) - return -EINVAL; - if (fsr == st->chip_config.fsr) - return 0; - - if (INV_MPU3050 == st->chip_type) - result = inv_plat_single_write(st, reg->lpf, - (fsr << GYRO_CONFIG_FSR_SHIFT) | st->chip_config.lpf); - else - result = inv_plat_single_write(st, reg->gyro_config, - fsr << GYRO_CONFIG_FSR_SHIFT); - - if (result) - return result; - st->chip_config.fsr = fsr; - - return 0; -} - -/** - * inv_write_accel_fs() - Configure the accelerometer's scale range. - */ -static int inv_write_accel_fs(struct inv_mpu_iio_s *st, int fs) -{ - int result; - struct inv_reg_map_s *reg; - - reg = &st->reg; - if (fs < 0 || fs > MAX_ACCL_FS_PARAM) - return -EINVAL; - if (fs == st->chip_config.accl_fs) - return 0; - if (INV_MPU3050 == st->chip_type) - result = st->mpu_slave->set_fs(st, fs); - else - result = inv_plat_single_write(st, reg->accl_config, - (fs << ACCL_CONFIG_FSR_SHIFT)); - if (result) - return result; - - st->chip_config.accl_fs = fs; - - return 0; -} - -/** - * inv_write_compass_scale() - Configure the compass's scale range. - */ -static int inv_write_compass_scale(struct inv_mpu_iio_s *st, int data) -{ - char d, en; - int result; - if (COMPASS_ID_AK8963 != st->plat_data.sec_slave_id) - return 0; - en = !!data; - if (st->compass_scale == en) - return 0; - d = (DATA_AKM_MODE_SM | (st->compass_scale << AKM8963_SCALE_SHIFT)); - result = inv_plat_single_write(st, REG_I2C_SLV1_DO, d); - if (result) - return result; - st->compass_scale = en; - - return 0; -} - -/** - * mpu_write_raw() - write raw method. - */ -static int mpu_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) { - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result; - - if (st->chip_config.enable) - return -EBUSY; - mutex_lock(&indio_dev->mlock); - result = st->set_power_state(st, true); - if (result) { - mutex_unlock(&indio_dev->mlock); - return result; - } - - switch (mask) { - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_ANGL_VEL: - result = inv_write_fsr(st, val); - break; - case IIO_ACCEL: - result = inv_write_accel_fs(st, val); - break; - case IIO_MAGN: - result = inv_write_compass_scale(st, val); - break; - default: - result = -EINVAL; - break; - } - break; - case IIO_CHAN_INFO_OFFSET: - switch (chan->type) { - case IIO_ACCEL: - if (!st->chip_config.firmware_loaded) { - result = -EPERM; - goto error_write_raw; - } - result = inv_set_accel_bias_dmp(st); - if (result) - goto error_write_raw; - st->input_accel_bias[chan->channel2 - IIO_MOD_X] = val; - result = 0; - break; - default: - result = -EINVAL; - break; - } - break; - default: - result = -EINVAL; - break; - } - -error_write_raw: - result |= st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - - return result; -} - -/** - * inv_fifo_rate_store() - Set fifo rate. - */ -static int inv_fifo_rate_store(struct inv_mpu_iio_s *st, int fifo_rate) -{ - if ((fifo_rate < MIN_FIFO_RATE) || (fifo_rate > MAX_FIFO_RATE)) - return -EINVAL; - - if (st->chip_config.has_compass) { - st->compass_divider = COMPASS_RATE_SCALE * fifo_rate / - ONE_K_HZ; - if (st->compass_divider > 0) - st->compass_divider -= 1; - st->compass_counter = 0; - } - st->irq_dur_ns = (ONE_K_HZ / fifo_rate) * NSEC_PER_MSEC; - st->chip_config.new_fifo_rate = fifo_rate; - - return 0; -} - -/** - * inv_reg_dump_show() - Register dump for testing. - */ -static ssize_t inv_reg_dump_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ii; - char data; - ssize_t bytes_printed = 0; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - mutex_lock(&indio_dev->mlock); - if (!st->chip_config.enable) - st->set_power_state(st, true); - for (ii = 0; ii < st->hw->num_reg; ii++) { - /* don't read fifo r/w register */ - if (ii == st->reg.fifo_r_w) - data = 0; - else - inv_plat_read(st, ii, 1, &data); - bytes_printed += sprintf(buf + bytes_printed, "%#2x: %#2x\n", - ii, data); - } - if (!st->chip_config.enable) - st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - - return bytes_printed; -} - -int write_be32_key_to_mem(struct inv_mpu_iio_s *st, - u32 data, int key) -{ - cpu_to_be32s(&data); - return mem_w_key(key, sizeof(data), (u8 *)&data); -} - -/** - * inv_quaternion_on() - calling this function will store - * current quaternion on - */ -static int inv_quaternion_on(struct inv_mpu_iio_s *st, - struct iio_buffer *ring, bool en) -{ - st->chip_config.quaternion_on = en; - if (!en) { - clear_bit(INV_MPU_SCAN_QUAT_R, ring->scan_mask); - clear_bit(INV_MPU_SCAN_QUAT_X, ring->scan_mask); - clear_bit(INV_MPU_SCAN_QUAT_Y, ring->scan_mask); - clear_bit(INV_MPU_SCAN_QUAT_Z, ring->scan_mask); - } - - return 0; -} - -/** - * inv_dmp_attr_store() - calling this function will store current - * dmp parameter settings - */ -static ssize_t inv_dmp_attr_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int result, data; - - mutex_lock(&indio_dev->mlock); - if (st->chip_config.enable) { - result = -EBUSY; - goto dmp_attr_store_fail; - } - if (this_attr->address <= ATTR_DMP_DISPLAY_ORIENTATION_ON) { - if (!st->chip_config.firmware_loaded) { - result = -EINVAL; - goto dmp_attr_store_fail; - } - result = st->set_power_state(st, true); - if (result) - goto dmp_attr_store_fail; - } - - result = kstrtoint(buf, 10, &data); - if (result) - goto dmp_attr_store_fail; - switch (this_attr->address) { - case ATTR_DMP_SMD_ENABLE: - { - u8 on[] = {0, 1}; - u8 off[] = {0, 0}; - u8 *d; - if (data) - d = on; - else - d = off; - result = mem_w_key(KEY_SMD_ENABLE, ARRAY_SIZE(on), d); - if (result) - goto dmp_attr_store_fail; - st->chip_config.smd_enable = !!data; - } - break; - case ATTR_DMP_SMD_THLD: - if (data < 0 || data > SHRT_MAX) - goto dmp_attr_store_fail; - result = write_be32_key_to_mem(st, data << 16, - KEY_SMD_ACCEL_THLD); - if (result) - goto dmp_attr_store_fail; - st->smd.threshold = data; - break; - case ATTR_DMP_SMD_DELAY_THLD: - if (data < 0 || data > INT_MAX / MPU_DEFAULT_DMP_FREQ) - goto dmp_attr_store_fail; - result = write_be32_key_to_mem(st, data * MPU_DEFAULT_DMP_FREQ, - KEY_SMD_DELAY_THLD); - if (result) - goto dmp_attr_store_fail; - st->smd.delay = data; - break; - case ATTR_DMP_SMD_DELAY_THLD2: - if (data < 0 || data > INT_MAX / MPU_DEFAULT_DMP_FREQ) - goto dmp_attr_store_fail; - result = write_be32_key_to_mem(st, data * MPU_DEFAULT_DMP_FREQ, - KEY_SMD_DELAY2_THLD); - if (result) - goto dmp_attr_store_fail; - st->smd.delay2 = data; - break; - case ATTR_DMP_TAP_ON: - result = inv_enable_tap_dmp(st, !!data); - if (result) - goto dmp_attr_store_fail; - st->chip_config.tap_on = !!data; - break; - case ATTR_DMP_TAP_THRESHOLD: { - const char ax[] = {INV_TAP_AXIS_X, INV_TAP_AXIS_Y, - INV_TAP_AXIS_Z}; - int i; - if (data < 0 || data > USHRT_MAX) { - result = -EINVAL; - goto dmp_attr_store_fail; - } - for (i = 0; i < ARRAY_SIZE(ax); i++) { - result = inv_set_tap_threshold_dmp(st, ax[i], data); - if (result) - goto dmp_attr_store_fail; - } - st->tap.thresh = data; - break; - } - case ATTR_DMP_TAP_MIN_COUNT: - if (data < 0 || data > USHRT_MAX) { - result = -EINVAL; - goto dmp_attr_store_fail; - } - result = inv_set_min_taps_dmp(st, data); - if (result) - goto dmp_attr_store_fail; - st->tap.min_count = data; - break; - case ATTR_DMP_TAP_TIME: - if (data < 0 || data > USHRT_MAX) { - result = -EINVAL; - goto dmp_attr_store_fail; - } - result = inv_set_tap_time_dmp(st, data); - if (result) - goto dmp_attr_store_fail; - st->tap.time = data; - break; - case ATTR_DMP_DISPLAY_ORIENTATION_ON: - result = inv_set_display_orient_interrupt_dmp(st, !!data); - if (result) - goto dmp_attr_store_fail; - st->chip_config.display_orient_on = !!data; - break; - /* from here, power of chip is not turned on */ - case ATTR_DMP_ON: - st->chip_config.dmp_on = !!data; - break; - case ATTR_DMP_INT_ON: - st->chip_config.dmp_int_on = !!data; - break; - case ATTR_DMP_EVENT_INT_ON: - st->chip_config.dmp_event_int_on = !!data; - break; - case ATTR_DMP_OUTPUT_RATE: - if (data <= 0 || data > MAX_DMP_OUTPUT_RATE) { - result = -EINVAL; - goto dmp_attr_store_fail; - } - st->chip_config.dmp_output_rate = data; - if (st->chip_config.has_compass) { - st->compass_dmp_divider = COMPASS_RATE_SCALE * data / - ONE_K_HZ; - if (st->compass_dmp_divider > 0) - st->compass_dmp_divider -= 1; - st->compass_counter = 0; - } - break; - case ATTR_DMP_QUATERNION_ON: - result = inv_quaternion_on(st, indio_dev->buffer, !!data); - break; -#ifdef CONFIG_INV_TESTING - case ATTR_DEBUG_SMD_ENABLE_TESTP1: - { - u8 d[] = {0x42}; - result = st->set_power_state(st, true); - if (result) - goto dmp_attr_store_fail; - result = mem_w_key(KEY_SMD_ENABLE_TESTPT1, ARRAY_SIZE(d), d); - if (result) - goto dmp_attr_store_fail; - } - break; - case ATTR_DEBUG_SMD_ENABLE_TESTP2: - { - u8 d[] = {0x42}; - result = st->set_power_state(st, true); - if (result) - goto dmp_attr_store_fail; - result = mem_w_key(KEY_SMD_ENABLE_TESTPT2, ARRAY_SIZE(d), d); - if (result) - goto dmp_attr_store_fail; - } - break; -#endif - default: - result = -EINVAL; - goto dmp_attr_store_fail; - } - -dmp_attr_store_fail: - if ((this_attr->address <= ATTR_DMP_DISPLAY_ORIENTATION_ON) && - (!st->chip_config.enable)) - result |= st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - if (result) - return result; - - return count; -} - -/** - * inv_attr_show() - calling this function will show current - * dmp parameters. - */ -static ssize_t inv_attr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int result; - s8 *m; - - switch (this_attr->address) { - case ATTR_DMP_SMD_ENABLE: - return sprintf(buf, "%d\n", st->chip_config.smd_enable); - case ATTR_DMP_SMD_THLD: - return sprintf(buf, "%d\n", st->smd.threshold); - case ATTR_DMP_SMD_DELAY_THLD: - return sprintf(buf, "%d\n", st->smd.delay); - case ATTR_DMP_SMD_DELAY_THLD2: - return sprintf(buf, "%d\n", st->smd.delay2); - case ATTR_DMP_TAP_ON: - return sprintf(buf, "%d\n", st->chip_config.tap_on); - case ATTR_DMP_TAP_THRESHOLD: - return sprintf(buf, "%d\n", st->tap.thresh); - case ATTR_DMP_TAP_MIN_COUNT: - return sprintf(buf, "%d\n", st->tap.min_count); - case ATTR_DMP_TAP_TIME: - return sprintf(buf, "%d\n", st->tap.time); - case ATTR_DMP_DISPLAY_ORIENTATION_ON: - return sprintf(buf, "%d\n", - st->chip_config.display_orient_on); - - case ATTR_DMP_ON: - return sprintf(buf, "%d\n", st->chip_config.dmp_on); - case ATTR_DMP_INT_ON: - return sprintf(buf, "%d\n", st->chip_config.dmp_int_on); - case ATTR_DMP_EVENT_INT_ON: - return sprintf(buf, "%d\n", st->chip_config.dmp_event_int_on); - case ATTR_DMP_OUTPUT_RATE: - return sprintf(buf, "%d\n", - st->chip_config.dmp_output_rate); - case ATTR_DMP_QUATERNION_ON: - return sprintf(buf, "%d\n", st->chip_config.quaternion_on); - - case ATTR_MOTION_LPA_ON: - return sprintf(buf, "%d\n", st->mot_int.mot_on); - case ATTR_MOTION_LPA_FREQ:{ - const char *f[] = {"1.25", "5", "20", "40"}; - return sprintf(buf, "%s\n", f[st->chip_config.lpa_freq]); - } - case ATTR_MOTION_LPA_THRESHOLD: - return sprintf(buf, "%d\n", st->mot_int.mot_thr); - - case ATTR_SELF_TEST_SAMPLES: - return sprintf(buf, "%d\n", st->self_test.samples); - case ATTR_SELF_TEST_THRESHOLD: - return sprintf(buf, "%d\n", st->self_test.threshold); - case ATTR_GYRO_ENABLE: - return sprintf(buf, "%d\n", st->chip_config.gyro_enable); - case ATTR_ACCL_ENABLE: - return sprintf(buf, "%d\n", st->chip_config.accl_enable); - case ATTR_COMPASS_ENABLE: - return sprintf(buf, "%d\n", st->chip_config.compass_enable); - case ATTR_POWER_STATE: - return sprintf(buf, "%d\n", !fake_asleep); - case ATTR_FIRMWARE_LOADED: - return sprintf(buf, "%d\n", st->chip_config.firmware_loaded); - case ATTR_SAMPLING_FREQ: - return sprintf(buf, "%d\n", st->chip_config.new_fifo_rate); - - case ATTR_SELF_TEST: - if (st->chip_config.enable) - return -EBUSY; - mutex_lock(&indio_dev->mlock); - if (INV_MPU3050 == st->chip_type) - result = 1; - else - result = inv_hw_self_test(st); - mutex_unlock(&indio_dev->mlock); - return sprintf(buf, "%d\n", result); - - case ATTR_GYRO_MATRIX: - m = st->plat_data.orientation; - return sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n", - m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); - case ATTR_ACCL_MATRIX: - if (st->plat_data.sec_slave_type == SECONDARY_SLAVE_TYPE_ACCEL) - m = st->plat_data.secondary_orientation; - else - m = st->plat_data.orientation; - return sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n", - m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); - case ATTR_COMPASS_MATRIX: - if (st->plat_data.sec_slave_type == - SECONDARY_SLAVE_TYPE_COMPASS) - m = st->plat_data.secondary_orientation; - else - return -ENODEV; - return sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d\n", - m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]); - case ATTR_SECONDARY_NAME:{ - const char *n[] = {"0", "AK8975", "AK8972", "AK8963", "BMA250"}; - if (COMPASS_ID_AK8975 == st->plat_data.sec_slave_id) - return sprintf(buf, "%s\n", n[1]); - else if (COMPASS_ID_AK8972 == st->plat_data.sec_slave_id) - return sprintf(buf, "%s\n", n[2]); - else if (COMPASS_ID_AK8963 == st->plat_data.sec_slave_id) - return sprintf(buf, "%s\n", n[3]); - else if (ACCEL_ID_BMA250 == st->plat_data.sec_slave_id) - return sprintf(buf, "%s\n", n[4]); - else - return sprintf(buf, "%s\n", n[0]); - } - -#ifdef CONFIG_INV_TESTING - case ATTR_REG_WRITE: - return sprintf(buf, "1\n"); - case ATTR_DEBUG_SMD_EXE_STATE: - { - u8 d[2]; - - result = st->set_power_state(st, true); - mpu_memory_read(st, st->i2c_addr, - inv_dmp_get_address(KEY_SMD_EXE_STATE), 2, d); - return sprintf(buf, "%d\n", (short)be16_to_cpup((__be16 *)(d))); - } - case ATTR_DEBUG_SMD_DELAY_CNTR: - { - u8 d[4]; - - result = st->set_power_state(st, true); - mpu_memory_read(st, st->i2c_addr, - inv_dmp_get_address(KEY_SMD_DELAY_CNTR), 4, d); - return sprintf(buf, "%d\n", (int)be32_to_cpup((__be32 *)(d))); - } -#endif - default: - return -EPERM; - } -} - -/** - * inv_dmp_display_orient_show() - calling this function will - * show orientation This event must use poll. - */ -static ssize_t inv_dmp_display_orient_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct inv_mpu_iio_s *st = iio_priv(dev_get_drvdata(dev)); - return sprintf(buf, "%d\n", st->display_orient_data); -} - -/** - * inv_accel_motion_show() - calling this function showes motion interrupt. - * This event must use poll. - */ -static ssize_t inv_accel_motion_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "1\n"); -} - -/** - * inv_smd_show() - calling this function showes smd interrupt. - * This event must use poll. - */ -static ssize_t inv_smd_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "1\n"); -} - -/** - * inv_temperature_show() - Read temperature data directly from registers. - */ -static ssize_t inv_temperature_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct inv_reg_map_s *reg; - int result, cur_scale, cur_off; - short temp; - long scale_t; - u8 data[2]; - const long scale[] = {3834792L, 3158064L, 3340827L}; - const long offset[] = {5383314L, 2394184L, 1376256L}; - - reg = &st->reg; - mutex_lock(&indio_dev->mlock); - if (!st->chip_config.enable) - result = st->set_power_state(st, true); - else - result = 0; - if (result) { - mutex_unlock(&indio_dev->mlock); - return result; - } - result = inv_plat_read(st, reg->temperature, 2, data); - if (!st->chip_config.enable) - result |= st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - if (result) { - pr_err("Could not read temperature register.\n"); - return result; - } - if (st->use_hid) - temp = st->hid_temperature; - else - temp = (signed short)(be16_to_cpup((short *)&data[0])); - switch (st->chip_type) { - case INV_MPU3050: - cur_scale = scale[0]; - cur_off = offset[0]; - break; - case INV_MPU6050: - cur_scale = scale[1]; - cur_off = offset[1]; - break; - case INV_MPU6500: - cur_scale = scale[2]; - cur_off = offset[2]; - break; - default: - return -EINVAL; - }; - scale_t = cur_off + - inv_q30_mult((int)temp << MPU_TEMP_SHIFT, cur_scale); - - INV_I2C_INC_TEMPREAD(1); - - if (st->use_hid) - return sprintf(buf, "%ld %lld\n", scale_t, st->hid_timestamp); - else - return sprintf(buf, "%ld %lld\n", scale_t, get_time_ns()); -} - -/** - * inv_firmware_loaded() - calling this function will change - * firmware load - */ -static int inv_firmware_loaded(struct inv_mpu_iio_s *st, int data) -{ - if (data) - return -EINVAL; - st->chip_config.firmware_loaded = 0; - st->chip_config.dmp_on = 0; - st->chip_config.quaternion_on = 0; - - return 0; -} - -static int inv_switch_gyro_engine(struct inv_mpu_iio_s *st, bool en) -{ - return inv_switch_engine(st, en, BIT_PWR_GYRO_STBY); -} - -static int inv_switch_accl_engine(struct inv_mpu_iio_s *st, bool en) -{ - return inv_switch_engine(st, en, BIT_PWR_ACCL_STBY); -} - -/** - * inv_gyro_enable() - Enable/disable gyro. - */ -static int inv_gyro_enable(struct inv_mpu_iio_s *st, - struct iio_buffer *ring, bool en) -{ - if (en == st->chip_config.gyro_enable) - return 0; - if (!en) { - st->chip_config.gyro_fifo_enable = 0; - clear_bit(INV_MPU_SCAN_GYRO_X, ring->scan_mask); - clear_bit(INV_MPU_SCAN_GYRO_Y, ring->scan_mask); - clear_bit(INV_MPU_SCAN_GYRO_Z, ring->scan_mask); - } - st->chip_config.gyro_enable = en; - - return 0; -} - -/** - * inv_accl_enable() - Enable/disable accl. - */ -static int inv_accl_enable(struct inv_mpu_iio_s *st, - struct iio_buffer *ring, bool en) -{ - if (en == st->chip_config.accl_enable) - return 0; - if (!en) { - st->chip_config.accl_fifo_enable = 0; - clear_bit(INV_MPU_SCAN_ACCL_X, ring->scan_mask); - clear_bit(INV_MPU_SCAN_ACCL_Y, ring->scan_mask); - clear_bit(INV_MPU_SCAN_ACCL_Z, ring->scan_mask); - } - st->chip_config.accl_enable = en; - - return 0; -} - -/** - * inv_compass_enable() - calling this function will store compass - * enable - */ -static int inv_compass_enable(struct inv_mpu_iio_s *st, - struct iio_buffer *ring, bool en) -{ - if (en == st->chip_config.compass_enable) - return 0; - if (!en) { - st->chip_config.compass_fifo_enable = 0; - clear_bit(INV_MPU_SCAN_MAGN_X, ring->scan_mask); - clear_bit(INV_MPU_SCAN_MAGN_Y, ring->scan_mask); - clear_bit(INV_MPU_SCAN_MAGN_Z, ring->scan_mask); - } - st->chip_config.compass_enable = en; - - return 0; -} - -/** - * inv_attr_store() - calling this function will store current - * non-dmp parameter settings - */ -static ssize_t inv_attr_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int data; - u8 d; - int result; - - mutex_lock(&indio_dev->mlock); - if (st->chip_config.enable) { - result = -EBUSY; - goto attr_store_fail; - } - if (this_attr->address <= ATTR_MOTION_LPA_THRESHOLD) { - result = st->set_power_state(st, true); - if (result) - goto attr_store_fail; - } - - result = kstrtoint(buf, 10, &data); - if (result) - goto attr_store_fail; - switch (this_attr->address) { - case ATTR_MOTION_LPA_ON: - if (INV_MPU6500 == st->chip_type) { - if (data) - /* enable and put in MPU6500 mode */ - d = BIT_ACCEL_INTEL_ENABLE - | BIT_ACCEL_INTEL_MODE; - else - d = 0; - result = inv_plat_single_write(st, - REG_6500_ACCEL_INTEL_CTRL, d); - if (result) - goto attr_store_fail; - } - st->mot_int.mot_on = !!data; - st->chip_config.lpa_mode = !!data; - break; - case ATTR_MOTION_LPA_FREQ: - result = inv_lpa_freq(st, data); - break; - case ATTR_MOTION_LPA_THRESHOLD: - if ((data > MPU6XXX_MAX_MOTION_THRESH) || (data < 0)) { - result = -EINVAL; - goto attr_store_fail; - } - d = (u8)(data >> MPU6XXX_MOTION_THRESH_SHIFT); - data = (d << MPU6XXX_MOTION_THRESH_SHIFT); - result = inv_plat_single_write(st, REG_ACCEL_MOT_THR, d); - if (result) - goto attr_store_fail; - st->mot_int.mot_thr = data; - break; - /* from now on, power is not turned on */ - case ATTR_SELF_TEST_SAMPLES: - if (data > ST_MAX_SAMPLES || data < 0) { - result = -EINVAL; - goto attr_store_fail; - } - st->self_test.samples = data; - break; - case ATTR_SELF_TEST_THRESHOLD: - if (data > ST_MAX_THRESHOLD || data < 0) { - result = -EINVAL; - goto attr_store_fail; - } - st->self_test.threshold = data; - case ATTR_GYRO_ENABLE: - result = st->gyro_en(st, ring, !!data); - break; - case ATTR_ACCL_ENABLE: - result = st->accl_en(st, ring, !!data); - break; - case ATTR_COMPASS_ENABLE: - result = inv_compass_enable(st, ring, !!data); - break; - case ATTR_POWER_STATE: - fake_asleep = !data; - break; - case ATTR_FIRMWARE_LOADED: - result = inv_firmware_loaded(st, data); - break; - case ATTR_SAMPLING_FREQ: - result = inv_fifo_rate_store(st, data); - break; - default: - result = -EINVAL; - goto attr_store_fail; - }; - -attr_store_fail: - if ((this_attr->address <= ATTR_MOTION_LPA_THRESHOLD) && - (!st->chip_config.enable)) - result |= st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - if (result) - return result; - - return count; -} - -#ifdef CONFIG_INV_TESTING -/** - * inv_reg_write_store() - register write command for testing. - * Format: WSRRDD, where RR is the register in hex, - * and DD is the data in hex. - */ -static ssize_t inv_reg_write_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - u32 result; - u8 wreg, wval; - int temp; - char local_buf[10]; - - if ((buf[0] != 'W' && buf[0] != 'w') || - (buf[1] != 'S' && buf[1] != 's')) - return -EINVAL; - if (strlen(buf) < 6) - return -EINVAL; - - strncpy(local_buf, buf, 7); - local_buf[6] = 0; - result = sscanf(&local_buf[4], "%x", &temp); - if (result == 0) - return -EINVAL; - wval = temp; - local_buf[4] = 0; - sscanf(&local_buf[2], "%x", &temp); - if (result == 0) - return -EINVAL; - wreg = temp; - - result = inv_plat_single_write(st, wreg, wval); - if (result) - return result; - - return count; -} -#endif /* CONFIG_INV_TESTING */ - -#define IIO_ST(si, rb, sb, sh) \ - { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } -#define INV_MPU_CHAN(_type, _channel2, _index) \ - { \ - .type = _type, \ - .modified = 1, \ - .channel2 = _channel2, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_CALIBBIAS), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_index = _index, \ - .scan_type = IIO_ST('s', 16, 16, 0) \ - } - -#define INV_ACCL_CHAN(_type, _channel2, _index) \ - { \ - .type = _type, \ - .modified = 1, \ - .channel2 = _channel2, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_CALIBBIAS) | \ - BIT(IIO_CHAN_INFO_OFFSET), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_index = _index, \ - .scan_type = IIO_ST('s', 16, 16, 0) \ - } - -#define INV_MPU_QUATERNION_CHAN(_channel2, _index) \ - { \ - .type = IIO_QUATERNION, \ - .modified = 1, \ - .channel2 = _channel2, \ - .scan_index = _index, \ - .scan_type = IIO_ST('s', 32, 32, 0) \ - } - -#define INV_MPU_MAGN_CHAN(_channel2, _index) \ - { \ - .type = IIO_MAGN, \ - .modified = 1, \ - .channel2 = _channel2, \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_index = _index, \ - .scan_type = IIO_ST('s', 16, 16, 0) \ - } - -static const struct iio_chan_spec inv_mpu_channels[] = { - IIO_CHAN_SOFT_TIMESTAMP(INV_MPU_SCAN_TIMESTAMP), - INV_MPU_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_MPU_SCAN_GYRO_X), - INV_MPU_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_MPU_SCAN_GYRO_Y), - INV_MPU_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_MPU_SCAN_GYRO_Z), - - INV_ACCL_CHAN(IIO_ACCEL, IIO_MOD_X, INV_MPU_SCAN_ACCL_X), - INV_ACCL_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_MPU_SCAN_ACCL_Y), - INV_ACCL_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU_SCAN_ACCL_Z), - - INV_MPU_QUATERNION_CHAN(IIO_MOD_R, INV_MPU_SCAN_QUAT_R), - INV_MPU_QUATERNION_CHAN(IIO_MOD_X, INV_MPU_SCAN_QUAT_X), - INV_MPU_QUATERNION_CHAN(IIO_MOD_Y, INV_MPU_SCAN_QUAT_Y), - INV_MPU_QUATERNION_CHAN(IIO_MOD_Z, INV_MPU_SCAN_QUAT_Z), - - INV_MPU_MAGN_CHAN(IIO_MOD_X, INV_MPU_SCAN_MAGN_X), - INV_MPU_MAGN_CHAN(IIO_MOD_Y, INV_MPU_SCAN_MAGN_Y), - INV_MPU_MAGN_CHAN(IIO_MOD_Z, INV_MPU_SCAN_MAGN_Z), -}; - - -/*constant IIO attribute */ -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 20 50 100 200 500"); - -/* special sysfs */ -static DEVICE_ATTR(reg_dump, S_IRUGO, inv_reg_dump_show, NULL); -static DEVICE_ATTR(temperature, S_IRUGO, inv_temperature_show, NULL); - -/* event based sysfs, needs poll to read */ -static DEVICE_ATTR(event_display_orientation, S_IRUGO, - inv_dmp_display_orient_show, NULL); -static DEVICE_ATTR(event_accel_motion, S_IRUGO, inv_accel_motion_show, NULL); -static DEVICE_ATTR(event_smd, S_IRUGO, inv_smd_show, NULL); - -/* DMP sysfs with power on/off */ -static IIO_DEVICE_ATTR(smd_enable, S_IRUGO | S_IWUSR, - inv_attr_show, inv_dmp_attr_store, ATTR_DMP_SMD_ENABLE); -static IIO_DEVICE_ATTR(smd_threshold, S_IRUGO | S_IWUSR, - inv_attr_show, inv_dmp_attr_store, ATTR_DMP_SMD_THLD); -static IIO_DEVICE_ATTR(smd_delay_threshold, S_IRUGO | S_IWUSR, - inv_attr_show, inv_dmp_attr_store, ATTR_DMP_SMD_DELAY_THLD); -static IIO_DEVICE_ATTR(smd_delay_threshold2, S_IRUGO | S_IWUSR, - inv_attr_show, inv_dmp_attr_store, ATTR_DMP_SMD_DELAY_THLD2); -static IIO_DEVICE_ATTR(display_orientation_on, S_IRUGO | S_IWUSR, - inv_attr_show, inv_dmp_attr_store, ATTR_DMP_DISPLAY_ORIENTATION_ON); - -/* DMP sysfs without power on/off */ -static IIO_DEVICE_ATTR(dmp_on, S_IRUGO | S_IWUSR, inv_attr_show, - inv_dmp_attr_store, ATTR_DMP_ON); -static IIO_DEVICE_ATTR(dmp_int_on, S_IRUGO | S_IWUSR, inv_attr_show, - inv_dmp_attr_store, ATTR_DMP_INT_ON); -static IIO_DEVICE_ATTR(dmp_event_int_on, S_IRUGO | S_IWUSR, inv_attr_show, - inv_dmp_attr_store, ATTR_DMP_EVENT_INT_ON); -static IIO_DEVICE_ATTR(dmp_output_rate, S_IRUGO | S_IWUSR, inv_attr_show, - inv_dmp_attr_store, ATTR_DMP_OUTPUT_RATE); -static IIO_DEVICE_ATTR(quaternion_on, S_IRUGO | S_IWUSR, inv_attr_show, - inv_dmp_attr_store, ATTR_DMP_QUATERNION_ON); - -/* non DMP sysfs with power on/off */ -static IIO_DEVICE_ATTR(motion_lpa_on, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_MOTION_LPA_ON); -static IIO_DEVICE_ATTR(motion_lpa_freq, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_MOTION_LPA_FREQ); -static IIO_DEVICE_ATTR(motion_lpa_threshold, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_MOTION_LPA_THRESHOLD); - -/* non DMP sysfs without power on/off */ -static IIO_DEVICE_ATTR(self_test_samples, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_SELF_TEST_SAMPLES); -static IIO_DEVICE_ATTR(self_test_threshold, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_SELF_TEST_THRESHOLD); -static IIO_DEVICE_ATTR(gyro_enable, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_GYRO_ENABLE); -static IIO_DEVICE_ATTR(accl_enable, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_ACCL_ENABLE); -static IIO_DEVICE_ATTR(compass_enable, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_COMPASS_ENABLE); -static IIO_DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_POWER_STATE); -static IIO_DEVICE_ATTR(firmware_loaded, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_FIRMWARE_LOADED); -static IIO_DEVICE_ATTR(sampling_frequency, S_IRUGO | S_IWUSR, inv_attr_show, - inv_attr_store, ATTR_SAMPLING_FREQ); - -/* show method only sysfs but with power on/off */ -static IIO_DEVICE_ATTR(self_test, S_IRUGO, inv_attr_show, NULL, - ATTR_SELF_TEST); - -/* show method only sysfs */ -static IIO_DEVICE_ATTR(gyro_matrix, S_IRUGO, inv_attr_show, NULL, - ATTR_GYRO_MATRIX); -static IIO_DEVICE_ATTR(accl_matrix, S_IRUGO, inv_attr_show, NULL, - ATTR_ACCL_MATRIX); -static IIO_DEVICE_ATTR(compass_matrix, S_IRUGO, inv_attr_show, NULL, - ATTR_COMPASS_MATRIX); -static IIO_DEVICE_ATTR(secondary_name, S_IRUGO, inv_attr_show, NULL, - ATTR_SECONDARY_NAME); - -#ifdef CONFIG_INV_TESTING -static IIO_DEVICE_ATTR(reg_write, S_IRUGO | S_IWUSR, inv_attr_show, - inv_reg_write_store, ATTR_REG_WRITE); -/* smd debug related sysfs */ -static IIO_DEVICE_ATTR(debug_smd_enable_testp1, S_IWUSR, NULL, - inv_dmp_attr_store, ATTR_DEBUG_SMD_ENABLE_TESTP1); -static IIO_DEVICE_ATTR(debug_smd_enable_testp2, S_IWUSR, NULL, - inv_dmp_attr_store, ATTR_DEBUG_SMD_ENABLE_TESTP2); -static IIO_DEVICE_ATTR(debug_smd_exe_state, S_IRUGO, inv_attr_show, - NULL, ATTR_DEBUG_SMD_EXE_STATE); -static IIO_DEVICE_ATTR(debug_smd_delay_cntr, S_IRUGO, inv_attr_show, - NULL, ATTR_DEBUG_SMD_DELAY_CNTR); -#endif - -static const struct attribute *inv_gyro_attributes[] = { - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &dev_attr_reg_dump.attr, - &dev_attr_temperature.attr, - &iio_dev_attr_self_test_samples.dev_attr.attr, - &iio_dev_attr_self_test_threshold.dev_attr.attr, - &iio_dev_attr_gyro_enable.dev_attr.attr, - &iio_dev_attr_power_state.dev_attr.attr, - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_dev_attr_self_test.dev_attr.attr, - &iio_dev_attr_gyro_matrix.dev_attr.attr, - &iio_dev_attr_secondary_name.dev_attr.attr, -#ifdef CONFIG_INV_TESTING - &iio_dev_attr_reg_write.dev_attr.attr, - &iio_dev_attr_debug_smd_enable_testp1.dev_attr.attr, - &iio_dev_attr_debug_smd_enable_testp2.dev_attr.attr, - &iio_dev_attr_debug_smd_exe_state.dev_attr.attr, - &iio_dev_attr_debug_smd_delay_cntr.dev_attr.attr, -#endif -}; - -static const struct attribute *inv_mpu6050_attributes[] = { - &dev_attr_event_display_orientation.attr, - &dev_attr_event_smd.attr, - &iio_dev_attr_smd_enable.dev_attr.attr, - &iio_dev_attr_smd_threshold.dev_attr.attr, - &iio_dev_attr_smd_delay_threshold.dev_attr.attr, - &iio_dev_attr_smd_delay_threshold2.dev_attr.attr, - &iio_dev_attr_display_orientation_on.dev_attr.attr, - &iio_dev_attr_dmp_on.dev_attr.attr, - &iio_dev_attr_dmp_int_on.dev_attr.attr, - &iio_dev_attr_dmp_event_int_on.dev_attr.attr, - &iio_dev_attr_dmp_output_rate.dev_attr.attr, - &iio_dev_attr_quaternion_on.dev_attr.attr, - &iio_dev_attr_accl_enable.dev_attr.attr, - &iio_dev_attr_firmware_loaded.dev_attr.attr, - &iio_dev_attr_accl_matrix.dev_attr.attr, - -}; - -static const struct attribute *inv_mpu6500_attributes[] = { - &dev_attr_event_accel_motion.attr, - &iio_dev_attr_motion_lpa_on.dev_attr.attr, - &iio_dev_attr_motion_lpa_freq.dev_attr.attr, - &iio_dev_attr_motion_lpa_threshold.dev_attr.attr, -}; - -static const struct attribute *inv_compass_attributes[] = { - &iio_dev_attr_compass_enable.dev_attr.attr, - &iio_dev_attr_compass_matrix.dev_attr.attr, -}; - -static const struct attribute *inv_mpu3050_attributes[] = { - &iio_dev_attr_accl_enable.dev_attr.attr, - &iio_dev_attr_accl_matrix.dev_attr.attr, -}; - -static struct attribute *inv_attributes[ARRAY_SIZE(inv_gyro_attributes) + - ARRAY_SIZE(inv_mpu6050_attributes) + - ARRAY_SIZE(inv_mpu6500_attributes) + - ARRAY_SIZE(inv_compass_attributes) + 1]; - -static const struct attribute_group inv_attribute_group = { - .name = "mpu", - .attrs = inv_attributes -}; - -static const struct iio_info mpu_info = { - .driver_module = THIS_MODULE, - .read_raw = &mpu_read_raw, - .write_raw = &mpu_write_raw, - .attrs = &inv_attribute_group, -}; - -void inv_set_iio_info(struct inv_mpu_iio_s *st, struct iio_dev *indio_dev) -{ - indio_dev->channels = inv_mpu_channels; - indio_dev->num_channels = st->num_channels; - - indio_dev->info = &mpu_info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->currentmode = INDIO_DIRECT_MODE; -} - -/** - * inv_setup_compass() - Configure compass. - */ -static int inv_setup_compass(struct inv_mpu_iio_s *st) -{ - int result; - u8 data[4]; - - if (INV_MPU6050 == st->chip_type) { - result = inv_plat_read(st, REG_YGOFFS_TC, 1, data); - if (result) - return result; - data[0] &= ~BIT_I2C_MST_VDDIO; - if (st->plat_data.level_shifter) - data[0] |= BIT_I2C_MST_VDDIO; - /*set up VDDIO register */ - result = inv_plat_single_write(st, REG_YGOFFS_TC, data[0]); - if (result) - return result; - } - /* set to bypass mode */ - result = inv_plat_single_write(st, REG_INT_PIN_CFG, - st->plat_data.int_config | BIT_BYPASS_EN); - if (result) - return result; - /*read secondary i2c ID register */ - result = inv_secondary_read(st, REG_AKM_ID, 1, data); - if (result) - return result; - if (data[0] != DATA_AKM_ID) - return -ENXIO; - /*set AKM to Fuse ROM access mode */ - result = inv_secondary_write(st, REG_AKM_MODE, DATA_AKM_MODE_FR); - if (result) - return result; - result = inv_secondary_read(st, REG_AKM_SENSITIVITY, THREE_AXIS, - st->chip_info.compass_sens); - if (result) - return result; - /*revert to power down mode */ - result = inv_secondary_write(st, REG_AKM_MODE, DATA_AKM_MODE_PD); - if (result) - return result; - pr_debug("%s senx=%d, seny=%d, senz=%d\n", - st->hw->name, - st->chip_info.compass_sens[0], - st->chip_info.compass_sens[1], - st->chip_info.compass_sens[2]); - /*restore to non-bypass mode */ - result = inv_plat_single_write(st, REG_INT_PIN_CFG, - st->plat_data.int_config); - if (result) - return result; - - /*setup master mode and master clock and ES bit*/ - result = inv_plat_single_write(st, REG_I2C_MST_CTRL, BIT_WAIT_FOR_ES); - if (result) - return result; - /* slave 0 is used to read data from compass */ - /*read mode */ - result = inv_plat_single_write(st, REG_I2C_SLV0_ADDR, BIT_I2C_READ| - st->plat_data.secondary_i2c_addr); - if (result) - return result; - /* AKM status register address is 2 */ - result = inv_plat_single_write(st, REG_I2C_SLV0_REG, REG_AKM_STATUS); - if (result) - return result; - /* slave 0 is enabled at the beginning, read 8 bytes from here */ - result = inv_plat_single_write(st, REG_I2C_SLV0_CTRL, BIT_SLV_EN | - NUM_BYTES_COMPASS_SLAVE); - if (result) - return result; - /*slave 1 is used for AKM mode change only*/ - result = inv_plat_single_write(st, REG_I2C_SLV1_ADDR, - st->plat_data.secondary_i2c_addr); - if (result) - return result; - /* AKM mode register address is 0x0A */ - result = inv_plat_single_write(st, REG_I2C_SLV1_REG, REG_AKM_MODE); - if (result) - return result; - /* slave 1 is enabled, byte length is 1 */ - result = inv_plat_single_write(st, REG_I2C_SLV1_CTRL, BIT_SLV_EN | 1); - if (result) - return result; - /* output data for slave 1 is fixed, single measure mode*/ - st->compass_scale = 1; - if (COMPASS_ID_AK8975 == st->plat_data.sec_slave_id) { - st->compass_st_upper = AKM8975_ST_Upper; - st->compass_st_lower = AKM8975_ST_Lower; - data[0] = DATA_AKM_MODE_SM; - } else if (COMPASS_ID_AK8972 == st->plat_data.sec_slave_id) { - st->compass_st_upper = AKM8972_ST_Upper; - st->compass_st_lower = AKM8972_ST_Lower; - data[0] = DATA_AKM_MODE_SM; - } else if (COMPASS_ID_AK8963 == st->plat_data.sec_slave_id) { - st->compass_st_upper = AKM8963_ST_Upper; - st->compass_st_lower = AKM8963_ST_Lower; - data[0] = DATA_AKM_MODE_SM | - (st->compass_scale << AKM8963_SCALE_SHIFT); - } - result = inv_plat_single_write(st, REG_I2C_SLV1_DO, data[0]); - if (result) - return result; - /* slave 0 and 1 timer action is enabled every sample*/ - result = inv_plat_single_write(st, REG_I2C_MST_DELAY_CTRL, - BIT_SLV0_DLY_EN | BIT_SLV1_DLY_EN); - return result; -} - -static void inv_setup_func_ptr(struct inv_mpu_iio_s *st) -{ - if (st->chip_type == INV_MPU3050) { - st->set_power_state = set_power_mpu3050; - st->switch_gyro_engine = inv_switch_3050_gyro_engine; - st->switch_accl_engine = inv_switch_3050_accl_engine; - st->init_config = inv_init_config_mpu3050; - st->setup_reg = inv_setup_reg_mpu3050; - } else { - st->set_power_state = set_power_itg; - st->switch_gyro_engine = inv_switch_gyro_engine; - st->switch_accl_engine = inv_switch_accl_engine; - st->init_config = inv_init_config; - st->setup_reg = inv_setup_reg; - /*MPU6XXX special functions */ - st->compass_en = inv_compass_enable; - st->quaternion_en = inv_quaternion_on; - } - st->gyro_en = inv_gyro_enable; - st->accl_en = inv_accl_enable; -} - -static int inv_detect_6xxx(struct inv_mpu_iio_s *st) -{ - int result; - u8 d; - - result = inv_plat_read(st, REG_WHOAMI, 1, &d); - if (result) - return result; - if ((d == MPU6500_ID) || (d == MPU6515_ID)) { - st->chip_type = INV_MPU6500; - strcpy(st->name, "mpu6500"); - } else { - strcpy(st->name, "mpu6050"); - } - - return 0; -} - -/** - * inv_check_chip_type() - check and setup chip type. - */ -int inv_check_chip_type(struct inv_mpu_iio_s *st, const char *name) -{ - struct inv_reg_map_s *reg; - int result; - int t_ind; - int timeout = 10; - - if (!strcmp(name, "itg3500")) - st->chip_type = INV_ITG3500; - else if (!strcmp(name, "mpu3050")) - st->chip_type = INV_MPU3050; - else if (!strcmp(name, "mpu6050")) - st->chip_type = INV_MPU6050; - else if (!strcmp(name, "mpu9150")) - st->chip_type = INV_MPU6050; - else if (!strcmp(name, "mpu6500")) - st->chip_type = INV_MPU6500; - else if (!strcmp(name, "mpu9250")) - st->chip_type = INV_MPU6500; - else if (!strcmp(name, "mpu6xxx")) - st->chip_type = INV_MPU6050; - else if (!strcmp(name, "mpu6515")) - st->chip_type = INV_MPU6500; - else - return -EPERM; - inv_setup_func_ptr(st); - st->hw = &hw_info[st->chip_type]; - st->mpu_slave = NULL; - reg = &st->reg; - st->setup_reg(reg); - /* reset to make sure previous state are not there */ - while (timeout) { - result = inv_plat_single_write(st, reg->pwr_mgmt_1, BIT_H_RESET); - if (!result) - break; - pr_err("inv_mpu: reset chip failed, err = %d\n", result); - timeout--; - msleep(POWER_UP_TIME); - } - msleep(POWER_UP_TIME); - /* toggle power state */ - result = st->set_power_state(st, false); - if (result) - return result; - - result = st->set_power_state(st, true); - if (result) - return result; - - /* add by lyx@rock-chips.com */ - result = inv_plat_single_write(st, reg->user_ctrl, st->i2c_dis); - if (result) - return result; - - if (!strcmp(name, "mpu6xxx")) { - /* for MPU6500, reading register need more time */ - msleep(POWER_UP_TIME); - result = inv_detect_6xxx(st); - if (result) - return result; - } - - switch (st->chip_type) { - case INV_ITG3500: - st->num_channels = INV_CHANNEL_NUM_GYRO; - break; - case INV_MPU6050: - case INV_MPU6500: - if (SECONDARY_SLAVE_TYPE_COMPASS == - st->plat_data.sec_slave_type) { - st->chip_config.has_compass = 1; - st->num_channels = - INV_CHANNEL_NUM_GYRO_ACCL_QUANTERNION_MAGN; - } else { - st->chip_config.has_compass = 0; - st->num_channels = - INV_CHANNEL_NUM_GYRO_ACCL_QUANTERNION; - } - break; - case INV_MPU3050: - if (SECONDARY_SLAVE_TYPE_ACCEL == - st->plat_data.sec_slave_type) { - if (ACCEL_ID_BMA250 == st->plat_data.sec_slave_id) - inv_register_mpu3050_slave(st); - st->num_channels = INV_CHANNEL_NUM_GYRO_ACCL; - } else { - st->num_channels = INV_CHANNEL_NUM_GYRO; - } - break; - default: - result = st->set_power_state(st, false); - return -ENODEV; - } - st->chip_info.multi = 1; - switch (st->chip_type) { - case INV_MPU6050: - result = inv_get_silicon_rev_mpu6050(st); - break; - case INV_MPU6500: - result = inv_get_silicon_rev_mpu6500(st); - break; - default: - result = 0; - break; - } - if (result) { - pr_err("read silicon rev error\n"); - st->set_power_state(st, false); - return result; - } - /* turn off the gyro engine after OTP reading */ - result = st->switch_gyro_engine(st, false); - if (result) - return result; - result = st->switch_accl_engine(st, false); - if (result) - return result; - if (st->chip_config.has_compass) { - result = inv_setup_compass(st); - if (result) { - pr_err("compass setup failed\n"); - st->set_power_state(st, false); - return result; - } - } - - t_ind = 0; - memcpy(&inv_attributes[t_ind], inv_gyro_attributes, - sizeof(inv_gyro_attributes)); - t_ind += ARRAY_SIZE(inv_gyro_attributes); - - if (INV_MPU3050 == st->chip_type && st->mpu_slave != NULL) { - memcpy(&inv_attributes[t_ind], inv_mpu3050_attributes, - sizeof(inv_mpu3050_attributes)); - t_ind += ARRAY_SIZE(inv_mpu3050_attributes); - inv_attributes[t_ind] = NULL; - return 0; - } - - if ((INV_MPU6050 == st->chip_type) || (INV_MPU6500 == st->chip_type)) { - memcpy(&inv_attributes[t_ind], inv_mpu6050_attributes, - sizeof(inv_mpu6050_attributes)); - t_ind += ARRAY_SIZE(inv_mpu6050_attributes); - } - - if (INV_MPU6500 == st->chip_type) { - memcpy(&inv_attributes[t_ind], inv_mpu6500_attributes, - sizeof(inv_mpu6500_attributes)); - t_ind += ARRAY_SIZE(inv_mpu6500_attributes); - } - - if (st->chip_config.has_compass) { - memcpy(&inv_attributes[t_ind], inv_compass_attributes, - sizeof(inv_compass_attributes)); - t_ind += ARRAY_SIZE(inv_compass_attributes); - } - inv_attributes[t_ind] = NULL; - - return 0; -} - -/** - * inv_create_dmp_sysfs() - create binary sysfs dmp entry. - */ -static const struct bin_attribute dmp_firmware = { - .attr = { - .name = "dmp_firmware", - .mode = S_IRUGO | S_IWUSR - }, - .size = 4096, - .read = inv_dmp_firmware_read, - .write = inv_dmp_firmware_write, -}; - -int inv_create_dmp_sysfs(struct iio_dev *ind) -{ - int result; - result = sysfs_create_bin_file(&ind->dev.kobj, &dmp_firmware); - - return result; -} - -/** - * @} - */ diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_hid.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_hid.c deleted file mode 100644 index 4788f5c21601..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_hid.c +++ /dev/null @@ -1,303 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include "inv_mpu_iio.h" - -static int inv_hid_read(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data) -{ - return 0; -} - -static int inv_hid_single_write(struct inv_mpu_iio_s *st, u8 reg, u8 data) -{ - return 0; -} - -static int inv_hid_secondary_read(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data) -{ - return 0; -} - -static int inv_hid_secondary_write(struct inv_mpu_iio_s *st, u8 reg, u8 data) -{ - return 0; -} - -static int mpu_hid_memory_write(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 const *data) -{ - return 0; -} - -static int mpu_hid_memory_read(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 *data) -{ - return 0; -} - -static struct mpu_platform_data mpu_data = { - .int_config = 0x00, - .level_shifter = 0, - .orientation = { - 1, 0, 0, - 0, 1, 0, - 0, 0, 1, - }, -}; - -/** - * inv_mpu_probe() - probe function. - */ -static int inv_mpu_probe(struct platform_device *pdev) -{ - struct inv_mpu_iio_s *st; - struct iio_dev *indio_dev; - int result = -ENOMEM; - -#ifdef INV_KERNEL_3_10 - indio_dev = iio_device_alloc(sizeof(*st)); -#else - indio_dev = iio_allocate_device(sizeof(*st)); -#endif - if (!indio_dev) { - pr_err("memory allocation failed\n"); - goto out_no_free; - } - st = iio_priv(indio_dev); - st->plat_data = mpu_data; - st->dev = &pdev->dev; - indio_dev->dev.parent = &pdev->dev; - indio_dev->name = "mpu6500"; - platform_set_drvdata(pdev, indio_dev); - st->use_hid = 1; - - st->plat_read = inv_hid_read; - st->plat_single_write = inv_hid_single_write; - st->secondary_read = inv_hid_secondary_read; - st->secondary_write = inv_hid_secondary_write; - st->memory_read = mpu_hid_memory_read; - st->memory_write = mpu_hid_memory_write; - - /* power is turned on inside check chip type*/ - result = inv_check_chip_type(st, indio_dev->name); - if (result) - goto out_free; - - result = st->init_config(indio_dev); - if (result) { - dev_err(&pdev->dev, "Could not initialize device.\n"); - goto out_free; - } - result = st->set_power_state(st, false); - if (result) { - dev_err(&pdev->dev, "%s could not be turned off.\n", st->hw->name); - goto out_free; - } - - inv_set_iio_info(st, indio_dev); - - result = inv_mpu_configure_ring(indio_dev); - if (result) { - dev_err(&pdev->dev, "configure ring buffer fail\n"); - goto out_free; - } - - result = inv_mpu_probe_trigger(indio_dev); - if (result) { - dev_err(&pdev->dev, "trigger probe fail\n"); - goto out_unreg_ring; - } - - result = iio_device_register(indio_dev); - if (result) { - dev_err(&pdev->dev, "IIO device register fail\n"); - goto out_remove_trigger; - } - - if (INV_MPU6050 == st->chip_type || - INV_MPU6500 == st->chip_type) { - result = inv_create_dmp_sysfs(indio_dev); - if (result) { - dev_err(&pdev->dev, "create dmp sysfs failed\n"); - goto out_unreg_iio; - } - } - - INIT_KFIFO(st->timestamps); - spin_lock_init(&st->time_stamp_lock); - dev_info(&pdev->dev, "%s is ready to go!\n", - indio_dev->name); - - return 0; -out_unreg_iio: - iio_device_unregister(indio_dev); -out_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - inv_mpu_remove_trigger(indio_dev); -out_unreg_ring: - inv_mpu_unconfigure_ring(indio_dev); -out_free: -#ifdef INV_KERNEL_3_10 - iio_device_free(indio_dev); -#else - iio_free_device(indio_dev); -#endif -out_no_free: - dev_err(&pdev->dev, "%s failed %d\n", __func__, result); - - return -EIO; -} - -/** - * inv_mpu_remove() - remove function. - */ -static int inv_mpu_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - kfifo_free(&st->timestamps); - iio_device_unregister(indio_dev); - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - inv_mpu_remove_trigger(indio_dev); - inv_mpu_unconfigure_ring(indio_dev); -#ifdef INV_KERNEL_3_10 - iio_device_free(indio_dev); -#else - iio_free_device(indio_dev); -#endif - - dev_info(&pdev->dev, "inv-mpu-iio module removed.\n"); - - return 0; -} - -static void inv_mpu_shutdown(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct inv_reg_map_s *reg; - int result; - - reg = &st->reg; - dev_dbg(&pdev->dev, "Shutting down %s...\n", st->hw->name); - - /* reset to make sure previous state are not there */ - result = inv_plat_single_write(st, reg->pwr_mgmt_1, BIT_H_RESET); - if (result) - dev_err(&pdev->dev, "Failed to reset %s\n", - st->hw->name); - msleep(POWER_UP_TIME); - /* turn off power to ensure gyro engine is off */ - result = st->set_power_state(st, false); - if (result) - dev_err(&pdev->dev, "Failed to turn off %s\n", - st->hw->name); -} - -#ifdef CONFIG_PM -static int __maybe_unused inv_mpu_resume(struct device *dev) -{ - struct inv_mpu_iio_s *st = - iio_priv(platform_get_drvdata(to_platform_device(dev))); - pr_debug("%s inv_mpu_resume\n", st->hw->name); - return st->set_power_state(st, true); -} - -static int __maybe_unused inv_mpu_suspend(struct device *dev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(to_platform_device(dev)); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result; - - pr_debug("%s inv_mpu_suspend\n", st->hw->name); - mutex_lock(&indio_dev->mlock); - result = 0; - if ((!st->chip_config.dmp_on) || - (!st->chip_config.enable) || - (!st->chip_config.dmp_event_int_on)) - result = st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - - return result; -} - -static const struct dev_pm_ops inv_mpu_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) -}; - -#define INV_MPU_PMOPS (&inv_mpu_pmops) -#else -#define INV_MPU_PMOPS NULL -#endif /* CONFIG_PM */ - -/* device id table is used to identify what device can be - * supported by this driver - */ -static const struct platform_device_id inv_mpu_id[] = { - {"itg3500", INV_ITG3500}, - {"mpu3050", INV_MPU3050}, - {"mpu6050", INV_MPU6050}, - {"mpu9150", INV_MPU9150}, - {"mpu6500", INV_MPU6500}, - {"mpu9250", INV_MPU9250}, - {"mpu6xxx", INV_MPU6XXX}, - {"mpu6515", INV_MPU6515}, - {} -}; - -MODULE_DEVICE_TABLE(platform, inv_mpu_id); - -static const struct of_device_id inv_mpu_of_match[] = { - { .compatible = "inv-hid,itg3500", }, - { .compatible = "inv-hid,mpu3050", }, - { .compatible = "inv-hid,mpu6050", }, - { .compatible = "inv-hid,mpu9150", }, - { .compatible = "inv-hid,mpu6500", }, - { .compatible = "inv-hid,mpu9250", }, - { .compatible = "inv-hid,mpu6xxx", }, - { .compatible = "inv-hid,mpu9350", }, - { .compatible = "inv-hid,mpu6515", }, - {} -}; - -MODULE_DEVICE_TABLE(of, inv_mpu_of_match); - -static struct platform_driver inv_mpu_platform_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "inv_mpu_iio_hid", - .pm = INV_MPU_PMOPS, - .of_match_table = of_match_ptr(inv_mpu_of_match), - }, - .probe = inv_mpu_probe, - .remove = inv_mpu_remove, - .id_table = inv_mpu_id, - .shutdown = inv_mpu_shutdown, -}; - -module_platform_driver(inv_mpu_platform_driver); - -MODULE_AUTHOR("lyx "); -MODULE_DESCRIPTION("Invensense device driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("inv-mpu-iio-hid"); diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_i2c.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_i2c.c deleted file mode 100644 index 7ef87e6aa115..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_i2c.c +++ /dev/null @@ -1,769 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_mpu_iio.h" -#ifdef INV_KERNEL_3_10 -#include -#else -#include "sysfs.h" -#endif -#include "inv_counters.h" - -/** - * inv_i2c_read_base() - Read one or more bytes from the device registers. - * @st: Device driver instance. - * @reg: First device register to be read from. - * @length: Number of bytes to read. - * @data: Data read from device. - * NOTE:This is not re-implementation of i2c_smbus_read because i2c - * address could be specified in this case. We could have two different - * i2c address due to secondary i2c interface. - */ -static int inv_i2c_read_base(struct inv_mpu_iio_s *st, u16 i2c_addr, - u8 reg, u16 length, u8 *data) -{ - struct i2c_msg msgs[2]; - int res; - - if (!data) - return -EINVAL; - - msgs[0].addr = i2c_addr; - msgs[0].flags = 0; /* write */ - msgs[0].buf = ® - msgs[0].len = 1; - /* msgs[0].scl_rate = 200*1000; */ - - msgs[1].addr = i2c_addr; - msgs[1].flags = I2C_M_RD; - msgs[1].buf = data; - msgs[1].len = length; - /* msgs[1].scl_rate = 200*1000; */ - - res = i2c_transfer(st->sl_handle, msgs, 2); - - if (res < 2) { - if (res >= 0) - res = -EIO; - } else - res = 0; - - INV_I2C_INC_MPUWRITE(3); - INV_I2C_INC_MPUREAD(length); -#if 0 - { - char *read = 0; - pr_debug("%s RD%02X%02X%02X -> %s%s\n", st->hw->name, - i2c_addr, reg, length, - wr_pr_debug_begin(data, length, read), - wr_pr_debug_end(read)); - } -#endif - return res; -} - -/** - * inv_i2c_single_write_base() - Write a byte to a device register. - * @st: Device driver instance. - * @reg: Device register to be written to. - * @data: Byte to write to device. - * NOTE:This is not re-implementation of i2c_smbus_write because i2c - * address could be specified in this case. We could have two different - * i2c address due to secondary i2c interface. - */ -static int inv_i2c_single_write_base(struct inv_mpu_iio_s *st, - u16 i2c_addr, u8 reg, u8 data) -{ - u8 tmp[2]; - struct i2c_msg msg; - int res; - tmp[0] = reg; - tmp[1] = data; - - msg.addr = i2c_addr; - msg.flags = 0; /* write */ - msg.buf = tmp; - msg.len = 2; - /* msg.scl_rate = 200*1000; */ - - pr_debug("%s WR%02X%02X%02X\n", st->hw->name, i2c_addr, reg, data); - INV_I2C_INC_MPUWRITE(3); - - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res == 0) - res = -EIO; - return res; - } else - return 0; -} - -static int inv_i2c_single_write(struct inv_mpu_iio_s *st, u8 reg, u8 data) -{ - return inv_i2c_single_write_base(st, st->i2c_addr, reg, data); -} - -static int inv_i2c_read(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data) -{ - return inv_i2c_read_base(st, st->i2c_addr, reg, len, data); -} - -static int inv_i2c_secondary_read(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data) -{ - return inv_i2c_read_base(st, st->plat_data.secondary_i2c_addr, reg, len, data); -} - -static int inv_i2c_secondary_write(struct inv_mpu_iio_s *st, u8 reg, u8 data) -{ - return inv_i2c_single_write_base(st, st->plat_data.secondary_i2c_addr, reg, data); -} - -static int mpu_i2c_memory_write(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 const *data) -{ - u8 bank[2]; - u8 addr[2]; - u8 buf[513]; - - struct i2c_msg msg; - int res; - - if (!data || !st) - return -EINVAL; - - if (len >= (sizeof(buf) - 1)) - return -ENOMEM; - - bank[0] = REG_BANK_SEL; - bank[1] = mem_addr >> 8; - - addr[0] = REG_MEM_START_ADDR; - addr[1] = mem_addr & 0xFF; - - buf[0] = REG_MEM_RW; - memcpy(buf + 1, data, len); - - /* write message */ - msg.addr = mpu_addr; - msg.flags = 0; - msg.buf = bank; - msg.len = sizeof(bank); - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUWRITE(3); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } - - msg.addr = mpu_addr; - msg.flags = 0; - msg.buf = addr; - msg.len = sizeof(addr); - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUWRITE(3); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } - - msg.addr = mpu_addr; - msg.flags = 0; - msg.buf = (u8 *)buf; - msg.len = len + 1; - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUWRITE(2+len); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } -#if 0 - { - char *write = 0; - pr_debug("%s WM%02X%02X%02X%s%s - %d\n", st->hw->name, - mpu_addr, bank[1], addr[1], - wr_pr_debug_begin(data, len, write), - wr_pr_debug_end(write), - len); - } -#endif - return 0; -} - -static int mpu_i2c_memory_read(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 *data) -{ - u8 bank[2]; - u8 addr[2]; - u8 buf; - - struct i2c_msg msg; - int res; - - if (!data || !st) - return -EINVAL; - - bank[0] = REG_BANK_SEL; - bank[1] = mem_addr >> 8; - - addr[0] = REG_MEM_START_ADDR; - addr[1] = mem_addr & 0xFF; - - buf = REG_MEM_RW; - - /* write message */ - msg.addr = mpu_addr; - msg.flags = 0; - msg.buf = bank; - msg.len = sizeof(bank); - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUWRITE(3); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } - - msg.addr = mpu_addr; - msg.flags = 0; - msg.buf = addr; - msg.len = sizeof(addr); - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUWRITE(3); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } - - msg.addr = mpu_addr; - msg.flags = 0; - msg.buf = &buf; - msg.len = 1; - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUWRITE(3); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } - - msg.addr = mpu_addr; - msg.flags = I2C_M_RD; - msg.buf = data; - msg.len = len; - /* msg.scl_rate = 200*1000; */ - INV_I2C_INC_MPUREAD(len); - res = i2c_transfer(st->sl_handle, &msg, 1); - if (res < 1) { - if (res >= 0) - res = -EIO; - return res; - } -#if 0 - { - char *read = 0; - pr_debug("%s RM%02X%02X%02X%02X - %s%s\n", st->hw->name, - mpu_addr, bank[1], addr[1], len, - wr_pr_debug_begin(data, len, read), - wr_pr_debug_end(read)); - } -#endif - return 0; -} - -#include -#include -#include - -static struct mpu_platform_data mpu_data = { - .int_config = 0x00, - .level_shifter = 0, - .orientation = { - 0, 1, 0, - -1, 0, 0, - 0, 0, -1, - }, -/* - .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, - .sec_slave_id = COMPASS_ID_AK8963, - .secondary_i2c_addr = 0x0d, - .secondary_orientation = { - -1, 0, 0, - 0, 1, 0, - 0, 0, -1, - }, - .key = { - 221, 22, 205, 7, 217, 186, 151, 55, - 206, 254, 35, 144, 225, 102, 47, 50, - }, -*/ -}; - -static int of_inv_parse_platform_data(struct i2c_client *client, - struct mpu_platform_data *pdata) -{ - int ret; - int length = 0, size = 0; - struct property *prop; - u32 orientation[9]; - int orig_x, orig_y, orig_z; - int i; - struct device_node *np = client->dev.of_node; - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - unsigned long irq_flags; - int irq_pin; - int gpio_pin; - int debug; - int hw_pwoff; - - gpio_pin = of_get_named_gpio_flags(np, "irq-gpio", 0, (enum of_gpio_flags *)&irq_flags); - gpio_request(gpio_pin, "mpu6500"); - irq_pin = gpio_to_irq(gpio_pin); - client->irq = irq_pin; - - ret = of_property_read_u8(np, "mpu-int_config", &mpu_data.int_config); - if (ret != 0) { - dev_err(&client->dev, "get mpu-int_config error\n"); - return -EIO; - } - - ret = of_property_read_u8(np, "mpu-level_shifter", &mpu_data.level_shifter); - if (ret != 0) { - dev_err(&client->dev, "get mpu-level_shifter error\n"); - return -EIO; - } - - prop = of_find_property(np, "mpu-orientation", &length); - if (!prop) { - dev_err(&client->dev, "get mpu-orientation length error\n"); - return -EINVAL; - } - size = length / sizeof(u32); - if ((size > 0) && (size < 10)) { - ret = of_property_read_u32_array(np, "mpu-orientation", orientation, size); - if (ret < 0) { - dev_err(&client->dev, "get mpu-orientation data error\n"); - return -EINVAL; - } - for (i = 0; i < 9; i++) - mpu_data.orientation[i] = orientation[i]; - } else { - dev_info(&client->dev, "use default orientation\n"); - } - - ret = of_property_read_u32(np, "orientation-x", &orig_x); - if (ret != 0) { - dev_err(&client->dev, "get orientation-x error\n"); - return -EIO; - } - if (orig_x > 0) { - for (i = 0; i < 3; i++) - if (mpu_data.orientation[i]) - mpu_data.orientation[i] = -1; - } - - ret = of_property_read_u32(np, "orientation-y", &orig_y); - if (ret != 0) { - dev_err(&client->dev, "get orientation-y error\n"); - return -EIO; - } - if (orig_y > 0) { - for (i = 3; i < 6; i++) - if (mpu_data.orientation[i]) - mpu_data.orientation[i] = -1; - } - - ret = of_property_read_u32(np, "orientation-z", &orig_z); - if (ret != 0) { - dev_err(&client->dev, "get orientation-z error\n"); - return -EIO; - } - if (orig_z > 0) { - for (i = 6; i < 9; i++) - if (mpu_data.orientation[i]) - mpu_data.orientation[i] = -1; - } - - ret = of_property_read_u32(np, "support-hw-poweroff", &hw_pwoff); - if (ret != 0) { - st->support_hw_poweroff = 0; - } - st->support_hw_poweroff = hw_pwoff; - - ret = of_property_read_u32(np, "mpu-debug", &debug); - if (ret != 0) { - dev_err(&client->dev, "get mpu-debug error\n"); - return -EINVAL; - } - if (debug) { - dev_info(&client->dev, "int_config=%d,level_shifter=%d,client.addr=%x,client.irq=%x\n", - mpu_data.int_config, - mpu_data.level_shifter, - client->addr, - client->irq); - for (i = 0; i < size; i++) - dev_info(&client->dev, "%d ", mpu_data.orientation[i]); - dev_info(&client->dev, "\n"); - } - - return 0; -} - -/** - * inv_mpu_probe() - probe function. - */ -static int inv_mpu_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct inv_mpu_iio_s *st; - struct iio_dev *indio_dev; - int result; - - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - result = -ENOSYS; - pr_err("I2c function error\n"); - goto out_no_free; - } -#ifdef INV_KERNEL_3_10 - indio_dev = iio_device_alloc(sizeof(*st)); -#else - indio_dev = iio_allocate_device(sizeof(*st)); -#endif - if (indio_dev == NULL) { - pr_err("memory allocation failed\n"); - result = -ENOMEM; - goto out_no_free; - } - st = iio_priv(indio_dev); - st->client = client; - st->sl_handle = client->adapter; - st->i2c_addr = client->addr; - i2c_set_clientdata(client, indio_dev); - if (client->dev.of_node) { - result = of_inv_parse_platform_data(client, &st->plat_data); - if (result) - goto out_free; - st->plat_data = mpu_data; - pr_info("secondary_i2c_addr=%x\n", st->plat_data.secondary_i2c_addr); - } else - st->plat_data = - *(struct mpu_platform_data *)dev_get_platdata(&client->dev); - - st->irq = client->irq; - st->plat_read = inv_i2c_read; - st->plat_single_write = inv_i2c_single_write; - st->secondary_read = inv_i2c_secondary_read; - st->secondary_write = inv_i2c_secondary_write; - st->memory_read = mpu_i2c_memory_read; - st->memory_write = mpu_i2c_memory_write; - - /* power is turned on inside check chip type*/ - result = inv_check_chip_type(st, id->name); - if (result) - goto out_free; - - result = st->init_config(indio_dev); - if (result) { - dev_err(&client->adapter->dev, - "Could not initialize device.\n"); - goto out_free; - } - result = st->set_power_state(st, false); - if (result) { - dev_err(&client->adapter->dev, - "%s could not be turned off.\n", st->hw->name); - goto out_free; - } - - /* Make state variables available to all _show and _store functions. */ - indio_dev->dev.parent = &client->dev; - if (!strcmp(id->name, "mpu6xxx")) - indio_dev->name = st->name; - else - indio_dev->name = id->name; - - inv_set_iio_info(st, indio_dev); - - result = inv_mpu_configure_ring(indio_dev); - if (result) { - pr_err("configure ring buffer fail\n"); - goto out_free; - } - st->dev = &client->dev; - result = inv_mpu_probe_trigger(indio_dev); - if (result) { - pr_err("trigger probe fail\n"); - goto out_unreg_ring; - } - - /* Tell the i2c counter, we have an IRQ */ - INV_I2C_SETIRQ(IRQ_MPU, client->irq); - - result = iio_device_register(indio_dev); - if (result) { - pr_err("IIO device register fail\n"); - goto out_remove_trigger; - } - - if (INV_MPU6050 == st->chip_type || - INV_MPU6500 == st->chip_type) { - result = inv_create_dmp_sysfs(indio_dev); - if (result) { - pr_err("create dmp sysfs failed\n"); - goto out_unreg_iio; - } - } - - INIT_KFIFO(st->timestamps); - spin_lock_init(&st->time_stamp_lock); - dev_info(&client->dev, "%s is ready to go!\n", - indio_dev->name); - - return 0; -out_unreg_iio: - iio_device_unregister(indio_dev); -out_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - inv_mpu_remove_trigger(indio_dev); -out_unreg_ring: - inv_mpu_unconfigure_ring(indio_dev); -out_free: -#ifdef INV_KERNEL_3_10 - iio_device_free(indio_dev); -#else - iio_free_device(indio_dev); -#endif -out_no_free: - dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result); - - return -EIO; -} - -static void inv_mpu_shutdown(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct inv_reg_map_s *reg; - int result; - - reg = &st->reg; - dev_dbg(&client->adapter->dev, "Shutting down %s...\n", st->hw->name); - - /* reset to make sure previous state are not there */ - result = inv_plat_single_write(st, reg->pwr_mgmt_1, BIT_H_RESET); - if (result) - dev_err(&client->adapter->dev, "Failed to reset %s\n", - st->hw->name); - msleep(POWER_UP_TIME); - /* turn off power to ensure gyro engine is off */ - result = st->set_power_state(st, false); - if (result) - dev_err(&client->adapter->dev, "Failed to turn off %s\n", - st->hw->name); -} - -/** - * inv_mpu_remove() - remove function. - */ -static int inv_mpu_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - kfifo_free(&st->timestamps); - iio_device_unregister(indio_dev); - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - inv_mpu_remove_trigger(indio_dev); - inv_mpu_unconfigure_ring(indio_dev); -#ifdef INV_KERNEL_3_10 - iio_device_free(indio_dev); -#else - iio_free_device(indio_dev); -#endif - - dev_info(&client->adapter->dev, "inv-mpu-iio module removed.\n"); - - return 0; -} - -#ifdef CONFIG_PM -static int __maybe_unused inv_mpu_resume(struct device *dev) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result; - - pr_debug("%s inv_mpu_resume\n", st->hw->name); - - mutex_lock(&indio_dev->mlock); - if (st->support_hw_poweroff) { - /* reset to make sure previous state are not there */ - result = inv_plat_single_write(st, st->reg.pwr_mgmt_1, BIT_H_RESET); - if (result) { - pr_err("%s, reset failed\n", __func__); - goto rw_err; - } - msleep(POWER_UP_TIME); - /* toggle power state */ - result = st->set_power_state(st, false); - if (result) { - pr_err("%s, set_power_state false failed\n", __func__); - goto rw_err; - } - result = st->set_power_state(st, true); - if (result) { - pr_err("%s, set_power_state true failed\n", __func__); - goto rw_err; - } - result = inv_plat_single_write(st, st->reg.user_ctrl, st->i2c_dis); - if (result) { - pr_err("%s, set user_ctrl failed\n", __func__); - goto rw_err; - } - inv_resume_recover_setting(st); - } else { - result = st->set_power_state(st, true); - } - -rw_err: - mutex_unlock(&indio_dev->mlock); - return result; -} - -static int __maybe_unused inv_mpu_suspend(struct device *dev) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result = 0; - - pr_debug("%s inv_mpu_suspend\n", st->hw->name); - - mutex_lock(&indio_dev->mlock); - if ((!st->chip_config.dmp_on) || - (!st->chip_config.enable) || - (!st->chip_config.dmp_event_int_on)) - result = st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - - return result; -} -static const struct dev_pm_ops inv_mpu_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) -}; -#define INV_MPU_PMOPS (&inv_mpu_pmops) -#else -#define INV_MPU_PMOPS NULL -#endif /* CONFIG_PM */ - -static const u16 normal_i2c[] = { I2C_CLIENT_END }; -/* device id table is used to identify what device can be - * supported by this driver - */ -static const struct i2c_device_id inv_mpu_id[] = { - {"itg3500", INV_ITG3500}, - {"mpu3050", INV_MPU3050}, - {"mpu6050", INV_MPU6050}, - {"mpu9150", INV_MPU9150}, - {"mpu6500", INV_MPU6500}, - {"mpu9250", INV_MPU9250}, - {"mpu6xxx", INV_MPU6XXX}, - {"mpu6515", INV_MPU6515}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, inv_mpu_id); - -static const struct of_device_id inv_mpu_of_match[] = { - { .compatible = "invensense,itg3500", }, - { .compatible = "invensense,mpu3050", }, - { .compatible = "invensense,mpu6050", }, - { .compatible = "invensense,mpu9150", }, - { .compatible = "invensense,mpu6500", }, - { .compatible = "invensense,mpu9250", }, - { .compatible = "invensense,mpu6xxx", }, - { .compatible = "invensense,mpu9350", }, - { .compatible = "invensense,mpu6515", }, - {} -}; - -MODULE_DEVICE_TABLE(of, inv_mpu_of_match); - -static struct i2c_driver inv_mpu_driver = { - .class = I2C_CLASS_HWMON, - .probe = inv_mpu_probe, - .remove = inv_mpu_remove, - .shutdown = inv_mpu_shutdown, - .id_table = inv_mpu_id, - .driver = { - .owner = THIS_MODULE, - .name = "inv-mpu-iio", - .pm = INV_MPU_PMOPS, - .of_match_table = of_match_ptr(inv_mpu_of_match), - }, - .address_list = normal_i2c, -}; - -static int __init inv_mpu_init(void) -{ - int result = i2c_add_driver(&inv_mpu_driver); - pr_info("%s:%d\n", __func__, __LINE__); - if (result) { - pr_err("failed\n"); - return result; - } - return 0; -} - -static void __exit inv_mpu_exit(void) -{ - i2c_del_driver(&inv_mpu_driver); -} - -module_init(inv_mpu_init); -module_exit(inv_mpu_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Invensense device driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("inv-mpu-iio"); - -/** - * @} - */ diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_iio.h b/drivers/staging/iio/imu/inv_mpu/inv_mpu_iio.h deleted file mode 100644 index 92f59942512e..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_iio.h +++ /dev/null @@ -1,929 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_mpu_iio.h - * @brief Struct definitions for the Invensense mpu driver. - */ - -#ifndef _INV_MPU_IIO_H_ -#define _INV_MPU_IIO_H_ - -#include -#include -#include -#include -#ifdef INV_KERNEL_3_10 -#include -#include -#include -#else -#include - -#include "iio.h" -#include "buffer.h" -#endif - -#include "dmpKey.h" - -/** - * struct inv_reg_map_s - Notable slave registers. - * @sample_rate_div: Divider applied to gyro output rate. - * @lpf: Configures internal LPF. - * @bank_sel: Selects between memory banks. - * @user_ctrl: Enables/resets the FIFO. - * @fifo_en: Determines which data will appear in FIFO. - * @gyro_config: gyro config register. - * @accl_config: accel config register - * @fifo_count_h: Upper byte of FIFO count. - * @fifo_r_w: FIFO register. - * @raw_gyro Address of first gyro register. - * @raw_accl Address of first accel register. - * @temperature temperature register - * @int_enable: Interrupt enable register. - * @int_status: Interrupt flags. - * @pwr_mgmt_1: Controls chip's power state and clock source. - * @pwr_mgmt_2: Controls power state of individual sensors. - * @mem_start_addr: Address of first memory read. - * @mem_r_w: Access to memory. - * @prgm_strt_addrh firmware program start address register - */ -struct inv_reg_map_s { - u8 sample_rate_div; - u8 lpf; - u8 bank_sel; - u8 user_ctrl; - u8 fifo_en; - u8 gyro_config; - u8 accl_config; - u8 fifo_count_h; - u8 fifo_r_w; - u8 raw_gyro; - u8 raw_accl; - u8 temperature; - u8 int_enable; - u8 int_status; - u8 pwr_mgmt_1; - u8 pwr_mgmt_2; - u8 mem_start_addr; - u8 mem_r_w; - u8 prgm_strt_addrh; -}; -/*device enum */ -enum inv_devices { - INV_ITG3500, - INV_MPU3050, - INV_MPU6050, - INV_MPU9150, - INV_MPU6500, - INV_MPU9250, - INV_MPU6XXX, - INV_MPU6515, - INV_NUM_PARTS -}; - -/** - * struct test_setup_t - set up parameters for self test. - * @gyro_sens: sensitity for gyro. - * @sample_rate: sample rate, i.e, fifo rate. - * @lpf: low pass filter. - * @fsr: full scale range. - * @accl_fs: accel full scale range. - * @accl_sens: accel sensitivity - */ -struct test_setup_t { - int gyro_sens; - int sample_rate; - int lpf; - int fsr; - int accl_fs; - u32 accl_sens[3]; -}; - -/** - * struct inv_hw_s - Other important hardware information. - * @num_reg: Number of registers on device. - * @name: name of the chip - */ -struct inv_hw_s { - u8 num_reg; - u8 *name; -}; - -/** - * struct inv_chip_config_s - Cached chip configuration data. - * @fsr: Full scale range. - * @lpf: Digital low pass filter frequency. - * @accl_fs: accel full scale range. - * @self_test_run_once flag for self test run ever. - * @has_footer: MPU3050 specific work around. - * @has_compass: has compass or not. - * @enable: master enable to enable output - * @accl_enable: enable accel functionality - * @accl_fifo_enable: enable accel data output - * @gyro_enable: enable gyro functionality - * @gyro_fifo_enable: enable gyro data output - * @compass_enable: enable compass - * @compass_fifo_enable: enable compass data output - * @is_asleep: 1 if chip is powered down. - * @dmp_on: dmp is on/off. - * @dmp_int_on: dmp interrupt on/off. - * @dmp_event_int_on: dmp event interrupt on/off. - * @firmware_loaded: flag indicate firmware loaded or not. - * @lpa_mod: low power mode. - * @tap_on: tap on/off. - * @quaternion_on: send quaternion data on/off. - * @display_orient_on: display orientation on/off. - * @normal_compass_measure: discard first compass data after reset. - * @smd_enable: disable/enable SMD function. - * @lpa_freq: low power frequency - * @prog_start_addr: firmware program start address. - * @fifo_rate: current FIFO update rate. - * @new_fifo_rate: set FIFO update rate - * @dmp_output_rate: current dmp output rate. - */ -struct inv_chip_config_s { - u32 fsr:2; - u32 lpf:3; - u32 accl_fs:2; - u32 self_test_run_once:1; - u32 has_footer:1; - u32 has_compass:1; - u32 enable:1; - u32 accl_enable:1; - u32 accl_fifo_enable:1; - u32 gyro_enable:1; - u32 gyro_fifo_enable:1; - u32 compass_enable:1; - u32 compass_fifo_enable:1; - u32 is_asleep:1; - u32 dmp_on:1; - u32 dmp_int_on:1; - u32 dmp_event_int_on:1; - u32 firmware_loaded:1; - u32 lpa_mode:1; - u32 tap_on:1; - u32 quaternion_on:1; - u32 display_orient_on:1; - u32 normal_compass_measure:1; - u32 smd_enable:1; - u16 lpa_freq; - u16 prog_start_addr; - u16 fifo_rate; - u16 new_fifo_rate; - u16 dmp_output_rate; -}; - -/** - * struct inv_chip_info_s - Chip related information. - * @product_id: Product id. - * @product_revision: Product revision. - * @silicon_revision: Silicon revision. - * @software_revision: software revision. - * @multi: accel specific multiplier. - * @compass_sens: compass sensitivity. - * @gyro_sens_trim: Gyro sensitivity trim factor. - * @accl_sens_trim: accel sensitivity trim factor. - */ -struct inv_chip_info_s { - u8 product_id; - u8 product_revision; - u8 silicon_revision; - u8 software_revision; - u8 multi; - u8 compass_sens[3]; - u32 gyro_sens_trim; - u32 accl_sens_trim; -}; - -enum inv_channel_num { - INV_CHANNEL_NUM_GYRO = 4, - INV_CHANNEL_NUM_GYRO_ACCL = 7, - INV_CHANNEL_NUM_GYRO_ACCL_QUANTERNION = 11, - INV_CHANNEL_NUM_GYRO_ACCL_QUANTERNION_MAGN = 14, -}; - -/** - * struct inv_tap_s structure to store tap data. - * @min_count: minimum taps counted. - * @thresh: tap threshold. - * @time: tap time. - */ -struct inv_tap_s { - u16 min_count; - u16 thresh; - u16 time; -}; - -/** - * struct accel_mot_int_s structure to store motion interrupt data - * @mot_thr: motion threshold. - * @mot_dur: motion duration. - * @mot_on: flag to indicate motion detection on; - */ -struct accel_mot_int_s { - u16 mot_thr; - u32 mot_dur; - u8 mot_on:1; -}; - -/** - * struct self_test_setting - self test settables from sysfs - * samples: number of samples used in self test. - * threshold: threshold fail/pass criterion in self test. - * This value is in the percentage multiplied by 100. - * So 14% would be 14. - */ -struct self_test_setting { - u16 samples; - u16 threshold; -}; - -/** - * struct inv_smd_s significant motion detection structure. - * threshold: accel threshold for motion detection. - * delay: delay time to confirm 2nd motion. - * delay2: delay window parameter. - */ -struct inv_smd_s { - u32 threshold; - u32 delay; - u32 delay2; -}; - -struct inv_mpu_slave; -/** - * struct inv_mpu_iio_s - Driver state variables. - * @chip_config: Cached attribute information. - * @chip_info: Chip information from read-only registers. - * @trig; iio trigger. - * @tap: tap data structure. - * @smd: SMD data structure. - * @reg: Map of important registers. - * @self_test: self test settings. - * @hw: Other hardware-specific information. - * @chip_type: chip type. - * @time_stamp_lock: spin lock to time stamp. - * @client: i2c client handle. - * @plat_data: platform data. - * @mpu_slave: mpu slave handle. - * (*set_power_state)(struct inv_mpu_iio_s *, int on): function ptr - * (*switch_gyro_engine)(struct inv_mpu_iio_s *, int on): function ptr - * (*switch_accl_engine)(struct inv_mpu_iio_s *, int on): function ptr - * (*compass_en)(struct inv_mpu_iio_s *, struct iio_buffer *, bool); - * (*quaternion_en)(struct inv_mpu_iio_s *, struct iio_buffer *, bool) - * (*gyro_en)(struct inv_mpu_iio_s *, struct iio_buffer *, bool): func ptr. - * (*accl_en)(struct inv_mpu_iio_s *, struct iio_buffer *, bool): func ptr. - * (*init_config)(struct iio_dev *indio_dev): function ptr - * void (*setup_reg)(struct inv_reg_map_s *reg): function ptr - * @timestamps: kfifo queue to store time stamp. - * @compass_st_upper: compass self test upper limit. - * @compass_st_lower: compass self test lower limit. - * @irq: irq number store. - * @accel_bias: accel bias store. - * @gyro_bias: gyro bias store. - * @raw_gyro: raw gyro data. - * @raw_accel: raw accel data. - * @raw_compass: raw compass. - * @raw_quaternion raw quaternion data. - * @int input_accel_bias[3]: accel bias from sysfs. - * @compass_scale: compass scale. - * @i2c_addr: i2c address. - * @compass_divider: slow down compass rate. - * @compass_dmp_divider: slow down compass rate for dmp. - * @compass_counter: slow down compass rate. - * @sample_divider: sample divider for dmp. - * @fifo_divider: fifo divider for dmp. - * @display_orient_data:display orient data. - * @tap_data: tap data. - * @num_channels: number of channels for current chip. - * @sl_handle: Handle to I2C port. - * @irq_dur_ns: duration between each irq. - * @last_isr_time: last isr time. - * @mpu6500_last_motion_time: MPU6500 last real motion interrupt time. - * @name: name for distiguish MPU6050 and MPU6500 in MPU6XXX. - */ -struct inv_mpu_iio_s { -#define TIMESTAMP_FIFO_SIZE 16 - struct device *dev; - struct inv_chip_config_s chip_config; - struct inv_chip_info_s chip_info; - struct iio_trigger *trig; - struct inv_tap_s tap; - struct inv_smd_s smd; - struct inv_reg_map_s reg; - struct self_test_setting self_test; - const struct inv_hw_s *hw; - enum inv_devices chip_type; - spinlock_t time_stamp_lock; - struct i2c_client *client; - struct mpu_platform_data plat_data; - struct inv_mpu_slave *mpu_slave; - struct accel_mot_int_s mot_int; - int (*set_power_state)(struct inv_mpu_iio_s *, bool on); - int (*switch_gyro_engine)(struct inv_mpu_iio_s *, bool on); - int (*switch_accl_engine)(struct inv_mpu_iio_s *, bool on); - int (*compass_en)(struct inv_mpu_iio_s *, - struct iio_buffer *ring, bool on); - int (*quaternion_en)(struct inv_mpu_iio_s *, - struct iio_buffer *ring, bool on); - int (*gyro_en)(struct inv_mpu_iio_s *, - struct iio_buffer *ring, bool on); - int (*accl_en)(struct inv_mpu_iio_s *, - struct iio_buffer *ring, bool on); - int (*init_config)(struct iio_dev *indio_dev); - void (*setup_reg)(struct inv_reg_map_s *reg); - - int (*plat_read)(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data); - int (*plat_single_write)(struct inv_mpu_iio_s *st, u8 reg, u8 data); - int (*secondary_read)(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data); - int (*secondary_write)(struct inv_mpu_iio_s *st, u8 reg, u8 data); - int (*memory_write)(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 const *data); - int (*memory_read)(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 *data); - - DECLARE_KFIFO(timestamps, u64, TIMESTAMP_FIFO_SIZE); - const short *compass_st_upper; - const short *compass_st_lower; - short irq; - signed short hid_temperature; - u64 hid_timestamp; - int use_hid; - int support_hw_poweroff; - int accel_bias[3]; - int gyro_bias[3]; - short raw_gyro[3]; - short raw_accel[3]; - short raw_compass[3]; - int raw_quaternion[4]; - int input_accel_bias[3]; - u8 compass_scale; - u8 i2c_addr; - u8 compass_divider; - u8 compass_counter; - u8 compass_dmp_divider; - u8 sample_divider; - u8 fifo_divider; - u8 display_orient_data; - u8 tap_data; - enum inv_channel_num num_channels; - void *sl_handle; - u32 irq_dur_ns; - u64 last_isr_time; - u64 mpu6500_last_motion_time; - u8 i2c_dis; - u8 name[20]; - u8 secondary_name[20]; -}; - -/* produces an unique identifier for each device based on the - combination of product version and product revision */ -struct prod_rev_map_t { - u16 mpl_product_key; - u8 silicon_rev; - u16 gyro_trim; - u16 accel_trim; -}; - -/** - * struct inv_mpu_slave - MPU slave structure. - * @suspend: suspend operation. - * @resume: resume operation. - * @setup: setup chip. initialization. - * @combine_data: combine raw data into meaningful data. - * @get_mode: get current chip mode. - * @set_lpf set low pass filter. - * @set_fs set full scale - */ -struct inv_mpu_slave { - int (*suspend)(struct inv_mpu_iio_s *); - int (*resume)(struct inv_mpu_iio_s *); - int (*setup)(struct inv_mpu_iio_s *); - int (*combine_data)(u8 *in, short *out); - int (*get_mode)(void); - int (*set_lpf)(struct inv_mpu_iio_s *, int rate); - int (*set_fs)(struct inv_mpu_iio_s *, int fs); -}; - -/* AKM definitions */ -#define REG_AKM_ID 0x00 -#define REG_AKM_STATUS 0x02 -#define REG_AKM_MEASURE_DATA 0x03 -#define REG_AKM_MODE 0x0A -#define REG_AKM_ST_CTRL 0x0C -#define REG_AKM_SENSITIVITY 0x10 -#define REG_AKM8963_CNTL1 0x0A - -#define DATA_AKM_ID 0x48 -#define DATA_AKM_MODE_PD 0x00 -#define DATA_AKM_MODE_SM 0x01 -#define DATA_AKM_MODE_ST 0x08 -#define DATA_AKM_MODE_FR 0x0F -#define DATA_AKM_SELF_TEST 0x40 -#define DATA_AKM_DRDY 0x01 -#define DATA_AKM8963_BIT 0x10 -#define DATA_AKM_STAT_MASK 0x0C - -#define DATA_AKM8975_SCALE (9830 * (1L << 15)) -#define DATA_AKM8972_SCALE (19661 * (1L << 15)) -#define DATA_AKM8963_SCALE0 (19661 * (1L << 15)) -#define DATA_AKM8963_SCALE1 (4915 * (1L << 15)) -#define AKM8963_SCALE_SHIFT 4 -#define NUM_BYTES_COMPASS_SLAVE 8 - -/*register and associated bit definition*/ -#define REG_3050_FIFO_EN 0x12 -#define BITS_3050_ACCL_OUT 0x0E - -#define REG_3050_AUX_VDDIO 0x13 -#define BIT_3050_VDDIO 0x04 - -#define REG_3050_SLAVE_ADDR 0x14 -#define REG_3050_SAMPLE_RATE_DIV 0x15 -#define REG_3050_LPF 0x16 -#define REG_3050_INT_ENABLE 0x17 -#define REG_3050_AUX_BST_ADDR 0x18 -#define REG_3050_INT_STATUS 0x1A -#define REG_3050_TEMPERATURE 0x1B -#define REG_3050_RAW_GYRO 0x1D -#define REG_3050_AUX_XOUT_H 0x23 -#define REG_3050_FIFO_COUNT_H 0x3A -#define REG_3050_FIFO_R_W 0x3C - -#define REG_3050_USER_CTRL 0x3D -#define BIT_3050_AUX_IF_EN 0x20 -#define BIT_3050_AUX_IF_RST 0x08 -#define BIT_3050_FIFO_RST 0x02 - -#define REG_3050_PWR_MGMT_1 0x3E -#define BITS_3050_POWER1 0x30 -#define BITS_3050_POWER2 0x10 -#define BITS_3050_GYRO_STANDBY 0x38 - -#define REG_3500_OTP 0x0 - -#define REG_YGOFFS_TC 0x1 -#define BIT_I2C_MST_VDDIO 0x80 - -#define REG_XA_OFFS_L_TC 0x7 -#define REG_PRODUCT_ID 0xC -#define REG_ST_GCT_X 0xD -#define REG_SAMPLE_RATE_DIV 0x19 -#define REG_CONFIG 0x1A - -#define REG_GYRO_CONFIG 0x1B -#define BITS_SELF_TEST_EN 0xE0 - -#define REG_ACCEL_CONFIG 0x1C -#define REG_ACCEL_MOT_THR 0x1F -#define REG_ACCEL_MOT_DUR 0x20 - -#define REG_FIFO_EN 0x23 -#define BIT_ACCEL_OUT 0x08 -#define BITS_GYRO_OUT 0x70 - - -#define REG_I2C_MST_CTRL 0x24 -#define BIT_WAIT_FOR_ES 0x40 - -#define REG_I2C_SLV0_ADDR 0x25 -#define BIT_I2C_READ 0x80 - -#define REG_I2C_SLV0_REG 0x26 - -#define REG_I2C_SLV0_CTRL 0x27 -#define BIT_SLV_EN 0x80 - -#define REG_I2C_SLV1_ADDR 0x28 -#define REG_I2C_SLV1_REG 0x29 -#define REG_I2C_SLV1_CTRL 0x2A - -#define REG_I2C_SLV2_ADDR 0x2B -#define REG_I2C_SLV2_REG 0x2C -#define REG_I2C_SLV2_CTRL 0x2D - -#define REG_I2C_SLV4_CTRL 0x34 - -#define REG_INT_PIN_CFG 0x37 -#define BIT_BYPASS_EN 0x2 - -#define REG_INT_ENABLE 0x38 -#define BIT_DATA_RDY_EN 0x01 -#define BIT_DMP_INT_EN 0x02 -#define BIT_ZMOT_EN 0x20 -#define BIT_MOT_EN 0x40 -#define BIT_6500_WOM_EN 0x40 - -#define REG_DMP_INT_STATUS 0x39 -#define SMD_INT_ON 0x04 - -#define REG_INT_STATUS 0x3A -#define BIT_MOT_INT 0x40 -#define BIT_ZMOT_INT 0x20 - -#define REG_RAW_ACCEL 0x3B -#define REG_TEMPERATURE 0x41 -#define REG_RAW_GYRO 0x43 -#define REG_EXT_SENS_DATA_00 0x49 - -#define REG_ACCEL_INTEL_STATUS 0x61 - -#define REG_I2C_SLV1_DO 0x64 - -#define REG_I2C_MST_DELAY_CTRL 0x67 -#define BIT_SLV0_DLY_EN 0x01 -#define BIT_SLV1_DLY_EN 0x02 -#define BIT_SLV2_DLY_EN 0x04 - -#define REG_USER_CTRL 0x6A -#define BIT_FIFO_RST 0x04 -#define BIT_DMP_RST 0x08 -#define BIT_I2C_MST_EN 0x20 -#define BIT_FIFO_EN 0x40 -#define BIT_DMP_EN 0x80 -#define BIT_I2C_IF_DIS 0x10 - -#define REG_PWR_MGMT_1 0x6B -#define BIT_H_RESET 0x80 -#define BIT_SLEEP 0x40 -#define BIT_CYCLE 0x20 -#define BIT_CLK_MASK 0x7 - -#define REG_PWR_MGMT_2 0x6C -#define BIT_PWR_ACCL_STBY 0x38 -#define BIT_PWR_GYRO_STBY 0x07 -#define BIT_LPA_FREQ 0xC0 - -#define REG_BANK_SEL 0x6D -#define REG_MEM_START_ADDR 0x6E -#define REG_MEM_RW 0x6F -#define REG_PRGM_STRT_ADDRH 0x70 -#define REG_FIFO_COUNT_H 0x72 -#define REG_FIFO_R_W 0x74 -#define REG_WHOAMI 0x75 - -#define REG_6500_XG_ST_DATA 0x0 -#define REG_6500_XA_ST_DATA 0xD -#define REG_6500_ACCEL_CONFIG2 0x1D -#define BIT_ACCEL_FCHOCIE_B 0x08 -#define BIT_FIFO_SIZE_1K 0x40 - - -#define REG_6500_LP_ACCEL_ODR 0x1E -#define REG_6500_ACCEL_WOM_THR 0x1F - -#define REG_6500_ACCEL_INTEL_CTRL 0x69 -#define BIT_ACCEL_INTEL_ENABLE 0x80 -#define BIT_ACCEL_INTEL_MODE 0x40 - -/* data definitions */ -#define DMP_START_ADDR 0x400 -#define DMP_MASK_TAP 0x3f -#define DMP_MASK_DIS_ORIEN 0xC0 -#define DMP_DIS_ORIEN_SHIFT 6 - -#define BYTES_FOR_DMP 16 -#define BYTES_FOR_EVENTS 4 -#define QUATERNION_BYTES 16 -#define BYTES_PER_SENSOR 6 -#define MPU3050_FOOTER_SIZE 2 -#define FIFO_COUNT_BYTE 2 -#define FIFO_THRESHOLD 500 -#define POWER_UP_TIME 100 -#define SENSOR_UP_TIME 30 -#define REG_UP_TIME 5 -#define INV_MPU_SAMPLE_RATE_CHANGE_STABLE 50 -#define MPU_MEM_BANK_SIZE 256 - -#define MPU6XXX_MAX_MOTION_THRESH (255*4) -#define MPU6XXX_MOTION_THRESH_SHIFT 5 -#define MPU6050_MOTION_DUR_DEFAULT 1 -#define MPU6050_ID 0x68 -#define MPU6050_MAX_MOTION_DUR 255 -#define MPU_TEMP_SHIFT 16 -#define LPA_FREQ_SHIFT 6 -#define COMPASS_RATE_SCALE 10 -#define MAX_GYRO_FS_PARAM 3 -#define MAX_ACCL_FS_PARAM 3 -#define MAX_LPA_FREQ_PARAM 3 -#define MPU6XXX_MAX_MPU_MEM (256 * 12) - -#define INIT_MOT_DUR 128 -#define INIT_MOT_THR 128 -#define INIT_ZMOT_DUR 128 -#define INIT_ZMOT_THR 128 -#define INIT_ST_SAMPLES 50 -#define INIT_ST_THRESHOLD 14 -#define ST_THRESHOLD_MULTIPLIER 10 -#define ST_MAX_SAMPLES 500 -#define ST_MAX_THRESHOLD 100 - -/*---- MPU6500 ----*/ -#define MPU6500_ID 0x70 /* unique WHOAMI */ -#define MPU6500_PRODUCT_REVISION 1 -#define MPU6500_MEM_REV_ADDR 0x16 -#define INV_MPU_REV_MASK 0xF -#define MPU6500_REV 2 - -/*---- MPU6515 ----*/ -#define MPU6515_ID 0x74 /* unique WHOAMI */ - -/*---- MPU9250 ----*/ -#define MPU9250_ID 0x71 /* unique WHOAMI */ - -/*---- MPU6880 ----*/ -#define MPU6880_ID 0x78 /* unique WHOAMI */ - -#define THREE_AXIS 3 -#define GYRO_CONFIG_FSR_SHIFT 3 -#define ACCL_CONFIG_FSR_SHIFT 3 -#define GYRO_DPS_SCALE 250 -#define MEM_ADDR_PROD_REV 0x6 -#define SOFT_PROD_VER_BYTES 5 -#define CRC_FIRMWARE_SEED 0 -#define SELF_TEST_SUCCESS 1 -#define MS_PER_DMP_TICK 20 - -/* init parameters */ -#define INIT_FIFO_RATE 50 -#define INIT_DMP_OUTPUT_RATE 25 -#define INIT_DUR_TIME ((1000 / INIT_FIFO_RATE) * 1000 * 1000) -#define INIT_TAP_THRESHOLD 100 -#define INIT_TAP_TIME 100 -#define INIT_TAP_MIN_COUNT 2 -#define MPU_INIT_SMD_DELAY_THLD 3 -#define MPU_INIT_SMD_DELAY2_THLD 1 -#define MPU_INIT_SMD_THLD 1500 -#define MPU_DEFAULT_DMP_FREQ 200 -#define MPL_PROD_KEY(ver, rev) (ver * 100 + rev) -#define NUM_OF_PROD_REVS (ARRAY_SIZE(prod_rev_map)) -/*---- MPU6050 Silicon Revisions ----*/ -#define MPU_SILICON_REV_A2 1 /* MPU6050A2 Device */ -#define MPU_SILICON_REV_B1 2 /* MPU6050B1 Device */ - -#define BIT_PRFTCH_EN 0x40 -#define BIT_CFG_USER_BANK 0x20 -#define BITS_MEM_SEL 0x1f - -#define TIME_STAMP_TOR 5 -#define MAX_CATCH_UP 5 -#define DEFAULT_ACCL_TRIM 16384 -#define DEFAULT_GYRO_TRIM 131 -#define MAX_FIFO_RATE 1000 -#define MAX_DMP_OUTPUT_RATE 200 -#define MIN_FIFO_RATE 4 -#define ONE_K_HZ 1000 -#define NS_PER_MS_SHIFT 20 - -/*tap related defines */ -#define INV_TAP 0x08 -#define INV_NUM_TAP_AXES 3 - -#define INV_TAP_AXIS_X_POS 0x20 -#define INV_TAP_AXIS_X_NEG 0x10 -#define INV_TAP_AXIS_Y_POS 0x08 -#define INV_TAP_AXIS_Y_NEG 0x04 -#define INV_TAP_AXIS_Z_POS 0x02 -#define INV_TAP_AXIS_Z_NEG 0x01 -#define INV_TAP_ALL_DIRECTIONS 0x3f - -#define INV_TAP_AXIS_X 0x1 -#define INV_TAP_AXIS_Y 0x2 -#define INV_TAP_AXIS_Z 0x4 - -#define INV_TAP_AXIS_ALL \ - (INV_TAP_AXIS_X | \ - INV_TAP_AXIS_Y | \ - INV_TAP_AXIS_Z) - -#define INT_SRC_TAP 0x01 -#define INT_SRC_DISPLAY_ORIENT 0x08 -#define INT_SRC_SHAKE 0x10 - -#define INV_X_AXIS_INDEX 0x00 -#define INV_Y_AXIS_INDEX 0x01 -#define INV_Z_AXIS_INDEX 0x02 - -#define INV_ELEMENT_1 0x0001 -#define INV_ELEMENT_2 0x0002 -#define INV_ELEMENT_3 0x0004 -#define INV_ELEMENT_4 0x0008 -#define INV_ELEMENT_5 0x0010 -#define INV_ELEMENT_6 0x0020 -#define INV_ELEMENT_7 0x0040 -#define INV_ELEMENT_8 0x0080 -#define INV_ALL 0xFFFF -#define INV_ELEMENT_MASK 0x00FF -#define INV_GYRO_ACC_MASK 0x007E -#define INV_ACCL_MASK 0x70 -#define INV_GYRO_MASK 0xE -/* scan element definition */ -enum inv_mpu_scan { - INV_MPU_SCAN_QUAT_R = 0, - INV_MPU_SCAN_QUAT_X, - INV_MPU_SCAN_QUAT_Y, - INV_MPU_SCAN_QUAT_Z, - INV_MPU_SCAN_ACCL_X, - INV_MPU_SCAN_ACCL_Y, - INV_MPU_SCAN_ACCL_Z, - INV_MPU_SCAN_GYRO_X, - INV_MPU_SCAN_GYRO_Y, - INV_MPU_SCAN_GYRO_Z, - INV_MPU_SCAN_MAGN_X, - INV_MPU_SCAN_MAGN_Y, - INV_MPU_SCAN_MAGN_Z, - INV_MPU_SCAN_TIMESTAMP, -}; - -enum inv_filter_e { - INV_FILTER_256HZ_NOLPF2 = 0, - INV_FILTER_188HZ, - INV_FILTER_98HZ, - INV_FILTER_42HZ, - INV_FILTER_20HZ, - INV_FILTER_10HZ, - INV_FILTER_5HZ, - INV_FILTER_2100HZ_NOLPF, - NUM_FILTER -}; - -enum inv_slave_mode { - INV_MODE_SUSPEND, - INV_MODE_NORMAL, -}; - -/*==== 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 -}; - -/* IIO attribute address */ -enum MPU_IIO_ATTR_ADDR { - ATTR_DMP_SMD_ENABLE, - ATTR_DMP_SMD_THLD, - ATTR_DMP_SMD_DELAY_THLD, - ATTR_DMP_SMD_DELAY_THLD2, - ATTR_DMP_TAP_ON, - ATTR_DMP_TAP_THRESHOLD, - ATTR_DMP_TAP_MIN_COUNT, - ATTR_DMP_TAP_TIME, - ATTR_DMP_DISPLAY_ORIENTATION_ON, -/* *****above this line, are DMP features, power needs on/off */ -/* *****below this line, are DMP features, no power needed */ - ATTR_DMP_ON, - ATTR_DMP_INT_ON, - ATTR_DMP_EVENT_INT_ON, - ATTR_DMP_OUTPUT_RATE, - ATTR_DMP_QUATERNION_ON, -/* *****above this line, it is all DMP related features */ -/* *****below this line, it is all non-DMP related features */ - ATTR_MOTION_LPA_ON, - ATTR_MOTION_LPA_FREQ, - ATTR_MOTION_LPA_THRESHOLD, -/* *****above this line, it is non-DMP, power needs on/off */ -/* *****below this line, it is non-DMP, no needs to on/off power */ - ATTR_SELF_TEST_SAMPLES, - ATTR_SELF_TEST_THRESHOLD, - ATTR_GYRO_ENABLE, - ATTR_ACCL_ENABLE, - ATTR_COMPASS_ENABLE, - ATTR_POWER_STATE, /* this is fake sysfs for compatibility */ - ATTR_FIRMWARE_LOADED, - ATTR_SAMPLING_FREQ, -/* *****below this line, it is attributes only has show methods */ - ATTR_SELF_TEST, /* this has show-only methods but needs power on/off */ - ATTR_GYRO_MATRIX, - ATTR_ACCL_MATRIX, - ATTR_COMPASS_MATRIX, - ATTR_SECONDARY_NAME, -#ifdef CONFIG_INV_TESTING - ATTR_I2C_COUNTERS, - ATTR_REG_WRITE, - ATTR_DEBUG_SMD_ENABLE_TESTP1, - ATTR_DEBUG_SMD_ENABLE_TESTP2, - ATTR_DEBUG_SMD_EXE_STATE, - ATTR_DEBUG_SMD_DELAY_CNTR -#endif -}; - -enum inv_accl_fs_e { - INV_FS_02G = 0, - INV_FS_04G, - INV_FS_08G, - INV_FS_16G, - NUM_ACCL_FSR -}; - -enum inv_fsr_e { - INV_FSR_250DPS = 0, - INV_FSR_500DPS, - INV_FSR_1000DPS, - INV_FSR_2000DPS, - NUM_FSR -}; - -enum inv_clock_sel_e { - INV_CLK_INTERNAL = 0, - INV_CLK_PLL, - NUM_CLK -}; - -ssize_t inv_dmp_firmware_write(struct file *fp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, loff_t pos, size_t size); -ssize_t inv_dmp_firmware_read(struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count); -int inv_reg_store(struct inv_mpu_iio_s *st); -int inv_reg_recover(struct inv_mpu_iio_s *st); -int inv_mpu_configure_ring(struct iio_dev *indio_dev); -int inv_mpu_probe_trigger(struct iio_dev *indio_dev); -void inv_mpu_unconfigure_ring(struct iio_dev *indio_dev); -void inv_mpu_remove_trigger(struct iio_dev *indio_dev); -int inv_init_config_mpu3050(struct iio_dev *indio_dev); -int inv_get_silicon_rev_mpu6050(struct inv_mpu_iio_s *st); -int inv_get_silicon_rev_mpu6500(struct inv_mpu_iio_s *st); -int set_3050_bypass(struct inv_mpu_iio_s *st, bool enable); -int inv_register_mpu3050_slave(struct inv_mpu_iio_s *st); -void inv_setup_reg_mpu3050(struct inv_reg_map_s *reg); -int inv_switch_3050_gyro_engine(struct inv_mpu_iio_s *st, bool en); -int inv_switch_3050_accl_engine(struct inv_mpu_iio_s *st, bool en); -int set_power_mpu3050(struct inv_mpu_iio_s *st, bool power_on); -int inv_set_interrupt_on_gesture_event(struct inv_mpu_iio_s *st, bool on); -int inv_send_quaternion(struct inv_mpu_iio_s *st, bool on); -int inv_set_display_orient_interrupt_dmp(struct inv_mpu_iio_s *st, bool on); -int inv_set_fifo_rate(struct inv_mpu_iio_s *st, u16 fifo_rate); -u16 inv_dmp_get_address(u16 key); -int inv_q30_mult(int a, int b); -int inv_set_tap_threshold_dmp(struct inv_mpu_iio_s *st, - u32 axis, u16 threshold); -int inv_set_min_taps_dmp(struct inv_mpu_iio_s *st, u16 min_taps); -int inv_set_tap_time_dmp(struct inv_mpu_iio_s *st, u16 time); -int inv_enable_tap_dmp(struct inv_mpu_iio_s *st, bool on); -int inv_check_chip_type(struct inv_mpu_iio_s *st, const char *name); -int inv_create_dmp_sysfs(struct iio_dev *ind); -void inv_set_iio_info(struct inv_mpu_iio_s *st, struct iio_dev *indio_dev); -int inv_do_test(struct inv_mpu_iio_s *st, int self_test_flag, - int *gyro_result, int *accl_result); -int inv_hw_self_test(struct inv_mpu_iio_s *st); -void inv_recover_setting(struct inv_mpu_iio_s *st); -void inv_resume_recover_setting(struct inv_mpu_iio_s *st); -int inv_power_up_self_test(struct inv_mpu_iio_s *st); -s64 get_time_ns(void); -int write_be32_key_to_mem(struct inv_mpu_iio_s *st, - u32 data, int key); -int inv_set_accel_bias_dmp(struct inv_mpu_iio_s *st); -int inv_send_sensor_data(struct inv_mpu_iio_s *st, u16 elements); -int inv_send_interrupt_word(struct inv_mpu_iio_s *st, bool on); -int mpu_memory_write_unaligned(struct inv_mpu_iio_s *st, u16 key, int len, - u8 const *d); -/* used to print i2c data using pr_debug */ -char *wr_pr_debug_begin(u8 const *data, u32 len, char *string); -char *wr_pr_debug_end(char *string); - -#define inv_plat_read(st, reg, len, data) \ - st->plat_read(st, reg, len, data) -#define inv_plat_single_write(st, reg, data) \ - st->plat_single_write(st, reg, data) -#define inv_secondary_read(st, reg, len, data) \ - st->secondary_read(st, reg, len, data) -#define inv_secondary_write(st, reg, data) \ - st->secondary_write(st, reg, data) -#define mpu_memory_write(st, mpu_addr, mem_addr, len, data) \ - st->memory_write(st, mpu_addr, mem_addr, len, data) -#define mpu_memory_read(st, mpu_addr, mem_addr, len, data) \ - st->memory_read(st, mpu_addr, mem_addr, len, data) -#define mem_w(a, b, c) \ - st->memory_write(st, st->i2c_addr, a, b, c) -#define mem_w_key(key, b, c) mpu_memory_write_unaligned(st, key, b, c) -#endif /* #ifndef _INV_MPU_IIO_H_ */ - diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_misc.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_misc.c deleted file mode 100644 index 480dd95720ed..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_misc.c +++ /dev/null @@ -1,2024 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_mpu_misc.c - * @brief A sysfs device driver for Invensense mpu. - * @details This file is part of invensense mpu driver code - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_mpu_iio.h" -#include "inv_counters.h" - -/* DMP defines */ -#define DMP_ORIENTATION_TIME 500 -#define DMP_ORIENTATION_ANGLE 60 -#define DMP_DEFAULT_FIFO_RATE 200 -#define DMP_TAP_SCALE (767603923 / 5) -#define DMP_MULTI_SHIFT 30 -#define DMP_MULTI_TAP_TIME 500 -#define DMP_SHAKE_REJECT_THRESH 100 -#define DMP_SHAKE_REJECT_TIME 10 -#define DMP_SHAKE_REJECT_TIMEOUT 10 -#define DMP_ANGLE_SCALE 15 -#define DMP_PRECISION 1000 -#define DMP_MAX_DIVIDER 4 -#define DMP_MAX_MIN_TAPS 4 -#define DMP_IMAGE_CRC_VALUE 0x665f5a73 -#define DMP_IMAGE_SIZE 2913 - -/*--- Test parameters defaults --- */ -#define DEF_OLDEST_SUPP_PROD_REV 8 -#define DEF_OLDEST_SUPP_SW_REV 2 - -/* sample rate */ -#define DEF_SELFTEST_SAMPLE_RATE 0 -/* full scale setting dps */ -#define DEF_SELFTEST_GYRO_FS (0 << 3) -#define DEF_SELFTEST_ACCEL_FS (2 << 3) -#define DEF_SELFTEST_GYRO_SENS (32768 / 250) -/* wait time before collecting data */ -#define DEF_GYRO_WAIT_TIME 10 -#define DEF_ST_STABLE_TIME 200 -#define DEF_ST_6500_STABLE_TIME 20 -#define DEF_GYRO_SCALE 131 -#define DEF_ST_PRECISION 1000 -#define DEF_ST_ACCEL_FS_MG 8000UL -#define DEF_ST_SCALE (1L << 15) -#define DEF_ST_TRY_TIMES 2 -#define DEF_ST_COMPASS_RESULT_SHIFT 2 -#define DEF_ST_ACCEL_RESULT_SHIFT 1 -#define DEF_ST_OTP0_THRESH 60 -#define DEF_ST_ABS_THRESH 20 -#define DEF_ST_TOR 2 - -#define DEF_ST_COMPASS_WAIT_MIN (10 * 1000) -#define DEF_ST_COMPASS_WAIT_MAX (15 * 1000) -#define DEF_ST_COMPASS_TRY_TIMES 10 -#define DEF_ST_COMPASS_8963_SHIFT 2 - -#define X 0 -#define Y 1 -#define Z 2 -/*---- MPU6050 notable product revisions ----*/ -#define MPU_PRODUCT_KEY_B1_E1_5 105 -#define MPU_PRODUCT_KEY_B2_F1 431 -/* accelerometer Hw self test min and max bias shift (mg) */ -#define DEF_ACCEL_ST_SHIFT_MIN 300 -#define DEF_ACCEL_ST_SHIFT_MAX 950 - -#define DEF_ACCEL_ST_SHIFT_DELTA 140 -#define DEF_GYRO_CT_SHIFT_DELTA 140 -/* gyroscope Coriolis self test min and max bias shift (dps) */ -#define DEF_GYRO_CT_SHIFT_MIN 10 -#define DEF_GYRO_CT_SHIFT_MAX 105 - -/*---- MPU6500 Self Test Pass/Fail Criteria ----*/ -/* Gyro Offset Max Value (dps) */ -#define DEF_GYRO_OFFSET_MAX 20 -/* Gyro Self Test Absolute Limits ST_AL (dps) */ -#define DEF_GYRO_ST_AL 60 -/* Accel Self Test Absolute Limits ST_AL (mg) */ -#define DEF_ACCEL_ST_AL_MIN 225 -#define DEF_ACCEL_ST_AL_MAX 675 -#define DEF_6500_ACCEL_ST_SHIFT_DELTA 500 -#define DEF_6500_GYRO_CT_SHIFT_DELTA 500 -#define DEF_ST_MPU6500_ACCEL_LPF 2 -#define DEF_ST_6500_ACCEL_FS_MG 2000UL -#define DEF_SELFTEST_6500_ACCEL_FS (0 << 3) - -/* Note: The ST_AL values are only used when ST_OTP = 0, - * i.e no factory self test values for reference - */ - -/* NOTE: product entries are in chronological order */ -static const 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}, - /* prod_ver = 1 */ - {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}, - {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}, - /* prod_ver = 1 */ - {MPL_PROD_KEY(1, 16), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 17), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 18), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 19), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 20), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 28), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 1), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 2), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 3), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 4), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 5), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(1, 6), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 2 */ - {MPL_PROD_KEY(2, 7), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(2, 8), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(2, 9), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(2, 10), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(2, 11), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(2, 12), MPU_SILICON_REV_B1, 131, 16384}, - {MPL_PROD_KEY(2, 29), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 3 */ - {MPL_PROD_KEY(3, 30), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 4 */ - {MPL_PROD_KEY(4, 31), MPU_SILICON_REV_B1, 131, 8192}, - {MPL_PROD_KEY(4, 1), MPU_SILICON_REV_B1, 131, 8192}, - {MPL_PROD_KEY(4, 3), MPU_SILICON_REV_B1, 131, 8192}, - /* prod_ver = 5 */ - {MPL_PROD_KEY(5, 3), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 6 */ - {MPL_PROD_KEY(6, 19), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 7 */ - {MPL_PROD_KEY(7, 19), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 8 */ - {MPL_PROD_KEY(8, 19), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 9 */ - {MPL_PROD_KEY(9, 19), MPU_SILICON_REV_B1, 131, 16384}, - /* prod_ver = 10 */ - {MPL_PROD_KEY(10, 19), MPU_SILICON_REV_B1, 131, 16384} -}; - -/* -* List of product software revisions -* -* NOTE : -* software revision 0 falls back to the old detection method -* based off the product version and product revision per the -* table above -*/ -static const struct prod_rev_map_t sw_rev_map[] = { - {0, 0, 0, 0}, - {1, MPU_SILICON_REV_B1, 131, 8192}, /* rev C */ - {2, MPU_SILICON_REV_B1, 131, 16384} /* rev D */ -}; - -static const u16 mpu_6500_st_tb[256] = { - 2620, 2646, 2672, 2699, 2726, 2753, 2781, 2808, - 2837, 2865, 2894, 2923, 2952, 2981, 3011, 3041, - 3072, 3102, 3133, 3165, 3196, 3228, 3261, 3293, - 3326, 3359, 3393, 3427, 3461, 3496, 3531, 3566, - 3602, 3638, 3674, 3711, 3748, 3786, 3823, 3862, - 3900, 3939, 3979, 4019, 4059, 4099, 4140, 4182, - 4224, 4266, 4308, 4352, 4395, 4439, 4483, 4528, - 4574, 4619, 4665, 4712, 4759, 4807, 4855, 4903, - 4953, 5002, 5052, 5103, 5154, 5205, 5257, 5310, - 5363, 5417, 5471, 5525, 5581, 5636, 5693, 5750, - 5807, 5865, 5924, 5983, 6043, 6104, 6165, 6226, - 6289, 6351, 6415, 6479, 6544, 6609, 6675, 6742, - 6810, 6878, 6946, 7016, 7086, 7157, 7229, 7301, - 7374, 7448, 7522, 7597, 7673, 7750, 7828, 7906, - 7985, 8065, 8145, 8227, 8309, 8392, 8476, 8561, - 8647, 8733, 8820, 8909, 8998, 9088, 9178, 9270, - 9363, 9457, 9551, 9647, 9743, 9841, 9939, 10038, - 10139, 10240, 10343, 10446, 10550, 10656, 10763, 10870, - 10979, 11089, 11200, 11312, 11425, 11539, 11654, 11771, - 11889, 12008, 12128, 12249, 12371, 12495, 12620, 12746, - 12874, 13002, 13132, 13264, 13396, 13530, 13666, 13802, - 13940, 14080, 14221, 14363, 14506, 14652, 14798, 14946, - 15096, 15247, 15399, 15553, 15709, 15866, 16024, 16184, - 16346, 16510, 16675, 16842, 17010, 17180, 17352, 17526, - 17701, 17878, 18057, 18237, 18420, 18604, 18790, 18978, - 19167, 19359, 19553, 19748, 19946, 20145, 20347, 20550, - 20756, 20963, 21173, 21385, 21598, 21814, 22033, 22253, - 22475, 22700, 22927, 23156, 23388, 23622, 23858, 24097, - 24338, 24581, 24827, 25075, 25326, 25579, 25835, 26093, - 26354, 26618, 26884, 27153, 27424, 27699, 27976, 28255, - 28538, 28823, 29112, 29403, 29697, 29994, 30294, 30597, - 30903, 31212, 31524, 31839, 32157, 32479, 32804 -}; - -static const int accl_st_tb[31] = { - 340, 351, 363, 375, 388, 401, 414, 428, - 443, 458, 473, 489, 506, 523, 541, 559, - 578, 597, 617, 638, 660, 682, 705, 729, - 753, 779, 805, 832, 860, 889, 919}; - -static const int gyro_6050_st_tb[31] = { - 3275, 3425, 3583, 3748, 3920, 4100, 4289, 4486, - 4693, 4909, 5134, 5371, 5618, 5876, 6146, 6429, - 6725, 7034, 7358, 7696, 8050, 8421, 8808, 9213, - 9637, 10080, 10544, 11029, 11537, 12067, 12622}; -static const int gyro_3500_st_tb[255] = { - 2620, 2646, 2672, 2699, 2726, 2753, 2781, 2808, - 2837, 2865, 2894, 2923, 2952, 2981, 3011, 3041, - 3072, 3102, 3133, 3165, 3196, 3228, 3261, 3293, - 3326, 3359, 3393, 3427, 3461, 3496, 3531, 3566, - 3602, 3638, 3674, 3711, 3748, 3786, 3823, 3862, - 3900, 3939, 3979, 4019, 4059, 4099, 4140, 4182, - 4224, 4266, 4308, 4352, 4395, 4439, 4483, 4528, - 4574, 4619, 4665, 4712, 4759, 4807, 4855, 4903, - 4953, 5002, 5052, 5103, 5154, 5205, 5257, 5310, - 5363, 5417, 5471, 5525, 5581, 5636, 5693, 5750, - 5807, 5865, 5924, 5983, 6043, 6104, 6165, 6226, - 6289, 6351, 6415, 6479, 6544, 6609, 6675, 6742, - 6810, 6878, 6946, 7016, 7086, 7157, 7229, 7301, - 7374, 7448, 7522, 7597, 7673, 7750, 7828, 7906, - 7985, 8065, 8145, 8227, 8309, 8392, 8476, 8561, - 8647, 8733, 8820, 8909, 8998, 9088, 9178, 9270, - 9363, 9457, 9551, 9647, 9743, 9841, 9939, 10038, - 10139, 10240, 10343, 10446, 10550, 10656, 10763, 10870, - 10979, 11089, 11200, 11312, 11425, 11539, 11654, 11771, - 11889, 12008, 12128, 12249, 12371, 12495, 12620, 12746, - 12874, 13002, 13132, 13264, 13396, 13530, 13666, 13802, - 13940, 14080, 14221, 14363, 14506, 14652, 14798, 14946, - 15096, 15247, 15399, 15553, 15709, 15866, 16024, 16184, - 16346, 16510, 16675, 16842, 17010, 17180, 17352, 17526, - 17701, 17878, 18057, 18237, 18420, 18604, 18790, 18978, - 19167, 19359, 19553, 19748, 19946, 20145, 20347, 20550, - 20756, 20963, 21173, 21385, 21598, 21814, 22033, 22253, - 22475, 22700, 22927, 23156, 23388, 23622, 23858, 24097, - 24338, 24581, 24827, 25075, 25326, 25579, 25835, 26093, - 26354, 26618, 26884, 27153, 27424, 27699, 27976, 28255, - 28538, 28823, 29112, 29403, 29697, 29994, 30294, 30597, - 30903, 31212, 31524, 31839, 32157, 32479, 32804}; - -char *wr_pr_debug_begin(u8 const *data, u32 len, char *string) -{ - int ii; - string = kmalloc(len * 2 + 1, GFP_KERNEL); - for (ii = 0; ii < len; ii++) - sprintf(&string[ii * 2], "%02X", data[ii]); - string[len * 2] = 0; - return string; -} - -char *wr_pr_debug_end(char *string) -{ - kfree(string); - return ""; -} - -int mpu_memory_write_unaligned(struct inv_mpu_iio_s *st, u16 key, int len, - u8 const *d) -{ - u32 addr; - int start, end; - int len1, len2; - int result = 0; - if (len > MPU_MEM_BANK_SIZE) - return -EINVAL; - addr = inv_dmp_get_address(key); - if (addr > MPU6XXX_MAX_MPU_MEM) - return -EINVAL; - start = (addr >> 8); - end = ((addr + len - 1) >> 8); - if (start == end) { - result = mpu_memory_write(st, st->i2c_addr, addr, len, d); - } else { - end <<= 8; - len1 = end - addr; - len2 = len - len1; - result = mpu_memory_write(st, st->i2c_addr, addr, len1, d); - result |= mpu_memory_write(st, st->i2c_addr, end, len2, - d + len1); - } - - return result; -} - -/** - * index_of_key()- Inverse lookup of the index of an MPL product key . - * @key: the MPL product indentifier also referred to as 'key'. - */ -static short index_of_key(u16 key) -{ - int i; - for (i = 0; i < NUM_OF_PROD_REVS; i++) - if (prod_rev_map[i].mpl_product_key == key) - return (short)i; - return -EINVAL; -} - -int inv_get_silicon_rev_mpu6500(struct inv_mpu_iio_s *st) -{ - struct inv_chip_info_s *chip_info = &st->chip_info; - int result; - u8 whoami, sw_rev; - - if (!st->use_hid) { - result = inv_plat_read(st, REG_WHOAMI, 1, &whoami); - if (result) - return result; - if (whoami != MPU6500_ID && whoami != MPU9250_ID && - whoami != MPU6515_ID && whoami != MPU6880_ID) - return -EINVAL; - - /*memory read need more time after power up */ - msleep(POWER_UP_TIME); - result = mpu_memory_read(st, st->i2c_addr, - MPU6500_MEM_REV_ADDR, 1, &sw_rev); - sw_rev &= INV_MPU_REV_MASK; - if (result) - return result; - if (sw_rev != 0) - return -EINVAL; - } - /* these values are place holders and not real values */ - chip_info->product_id = MPU6500_PRODUCT_REVISION; - chip_info->product_revision = MPU6500_PRODUCT_REVISION; - chip_info->silicon_revision = MPU6500_PRODUCT_REVISION; - chip_info->software_revision = sw_rev; - chip_info->gyro_sens_trim = DEFAULT_GYRO_TRIM; - chip_info->accl_sens_trim = DEFAULT_ACCL_TRIM; - chip_info->multi = 1; - - return 0; -} - -int inv_get_silicon_rev_mpu6050(struct inv_mpu_iio_s *st) -{ - int result; - struct inv_reg_map_s *reg; - u8 prod_ver = 0x00, prod_rev = 0x00; - struct prod_rev_map_t *p_rev; - u8 bank = - (BIT_PRFTCH_EN | BIT_CFG_USER_BANK | MPU_MEM_OTP_BANK_0); - u16 mem_addr = ((bank << 8) | MEM_ADDR_PROD_REV); - u16 key; - u8 regs[5]; - u16 sw_rev; - short index; - struct inv_chip_info_s *chip_info = &st->chip_info; - reg = &st->reg; - - result = inv_plat_read(st, REG_PRODUCT_ID, 1, &prod_ver); - if (result) - return result; - prod_ver &= 0xf; - /*memory read need more time after power up */ - msleep(POWER_UP_TIME); - result = mpu_memory_read(st, st->i2c_addr, mem_addr, - 1, &prod_rev); - if (result) - return result; - prod_rev >>= 2; - /* clean the prefetch and cfg user bank bits */ - result = inv_plat_single_write(st, reg->bank_sel, 0); - if (result) - return result; - /* get the software-product version, read from XA_OFFS_L */ - result = inv_plat_read(st, REG_XA_OFFS_L_TC, - SOFT_PROD_VER_BYTES, regs); - if (result) - return result; - - sw_rev = (regs[4] & 0x01) << 2 | /* 0x0b, bit 0 */ - (regs[2] & 0x01) << 1 | /* 0x09, bit 0 */ - (regs[0] & 0x01); /* 0x07, bit 0 */ - /* if 0, use the product key to determine the type of part */ - if (sw_rev == 0) { - key = MPL_PROD_KEY(prod_ver, prod_rev); - if (key == 0) - return -EINVAL; - index = index_of_key(key); - if (index < 0 || index >= NUM_OF_PROD_REVS) - return -EINVAL; - /* check MPL is compiled for this device */ - if (prod_rev_map[index].silicon_rev != MPU_SILICON_REV_B1) - return -EINVAL; - p_rev = (struct prod_rev_map_t *)&prod_rev_map[index]; - /* if valid, use the software product key */ - } else if (sw_rev < ARRAY_SIZE(sw_rev_map)) { - p_rev = (struct prod_rev_map_t *)&sw_rev_map[sw_rev]; - } else { - return -EINVAL; - } - chip_info->product_id = prod_ver; - chip_info->product_revision = prod_rev; - chip_info->silicon_revision = p_rev->silicon_rev; - chip_info->software_revision = sw_rev; - chip_info->gyro_sens_trim = p_rev->gyro_trim; - chip_info->accl_sens_trim = p_rev->accel_trim; - if (chip_info->accl_sens_trim == 0) - chip_info->accl_sens_trim = DEFAULT_ACCL_TRIM; - chip_info->multi = DEFAULT_ACCL_TRIM / chip_info->accl_sens_trim; - if (chip_info->multi != 1) - pr_info("multi is %d\n", chip_info->multi); - return result; -} - -/** - * read_accel_hw_self_test_prod_shift()- read the accelerometer hardware - * self-test bias shift calculated - * during final production test and - * stored in chip non-volatile memory. - * @st: main data structure. - * @st_prod: A pointer to an array of 3 elements to hold the values - * for production hardware self-test bias shifts returned to the - * user. - * @accl_sens: accel sensitivity. - */ -static int read_accel_hw_self_test_prod_shift(struct inv_mpu_iio_s *st, - int *st_prod, int *accl_sens) -{ - u8 regs[4]; - u8 shift_code[3]; - int result, i; - - for (i = 0; i < 3; i++) - st_prod[i] = 0; - - result = inv_plat_read(st, REG_ST_GCT_X, ARRAY_SIZE(regs), regs); - - if (result) - return result; - if ((0 == regs[0]) && (0 == regs[1]) && - (0 == regs[2]) && (0 == regs[3])) - return -EINVAL; - shift_code[X] = ((regs[0] & 0xE0) >> 3) | ((regs[3] & 0x30) >> 4); - shift_code[Y] = ((regs[1] & 0xE0) >> 3) | ((regs[3] & 0x0C) >> 2); - shift_code[Z] = ((regs[2] & 0xE0) >> 3) | (regs[3] & 0x03); - for (i = 0; i < 3; i++) { - if (shift_code[i] != 0) - st_prod[i] = accl_sens[i] * - accl_st_tb[shift_code[i] - 1]; - } - - return 0; -} - -/** -* inv_check_accl_self_test()- check accel self test. this function returns -* zero as success. A non-zero return value -* indicates failure in self test. -* @*st: main data structure. -* @*reg_avg: average value of normal test. -* @*st_avg: average value of self test -*/ -static int inv_check_accl_self_test(struct inv_mpu_iio_s *st, - int *reg_avg, int *st_avg){ - int gravity, reg_z_avg, g_z_sign, j, ret_val; - int tmp; - int st_shift_prod[THREE_AXIS], st_shift_cust[THREE_AXIS]; - int st_shift_ratio[THREE_AXIS]; - int accel_sens[THREE_AXIS]; - - if (st->chip_info.software_revision < DEF_OLDEST_SUPP_SW_REV && - st->chip_info.product_revision < DEF_OLDEST_SUPP_PROD_REV) - return 0; - g_z_sign = 1; - ret_val = 0; - tmp = DEF_ST_SCALE * DEF_ST_PRECISION / DEF_ST_ACCEL_FS_MG; - for (j = 0; j < 3; j++) - accel_sens[j] = tmp; - - if (MPL_PROD_KEY(st->chip_info.product_id, - st->chip_info.product_revision) == - MPU_PRODUCT_KEY_B1_E1_5) { - /* half sensitivity Z accelerometer parts */ - accel_sens[Z] /= 2; - } else { - /* half sensitivity X, Y, Z accelerometer parts */ - accel_sens[X] /= st->chip_info.multi; - accel_sens[Y] /= st->chip_info.multi; - accel_sens[Z] /= st->chip_info.multi; - } - gravity = accel_sens[Z]; - reg_z_avg = reg_avg[Z] - g_z_sign * gravity * DEF_ST_PRECISION; - ret_val = read_accel_hw_self_test_prod_shift(st, st_shift_prod, - accel_sens); - if (ret_val) - return ret_val; - - for (j = 0; j < 3; j++) { - st_shift_cust[j] = abs(reg_avg[j] - st_avg[j]); - if (st_shift_prod[j]) { - tmp = st_shift_prod[j] / DEF_ST_PRECISION; - st_shift_ratio[j] = abs(st_shift_cust[j] / tmp - - DEF_ST_PRECISION); - if (st_shift_ratio[j] > DEF_ACCEL_ST_SHIFT_DELTA) - ret_val = 1; - } else { - if (st_shift_cust[j] < - DEF_ACCEL_ST_SHIFT_MIN * gravity) - ret_val = 1; - if (st_shift_cust[j] > - DEF_ACCEL_ST_SHIFT_MAX * gravity) - ret_val = 1; - } - } - - return ret_val; -} - -/** -* inv_check_3500_gyro_self_test() check gyro self test. this function returns -* zero as success. A non-zero return value -* indicates failure in self test. -* @*st: main data structure. -* @*reg_avg: average value of normal test. -* @*st_avg: average value of self test -*/ - -static int inv_check_3500_gyro_self_test(struct inv_mpu_iio_s *st, - int *reg_avg, int *st_avg){ - int result; - int gst[3], ret_val; - int gst_otp[3], i; - u8 st_code[THREE_AXIS]; - ret_val = 0; - - for (i = 0; i < 3; i++) - gst[i] = st_avg[i] - reg_avg[i]; - result = inv_plat_read(st, REG_3500_OTP, THREE_AXIS, st_code); - if (result) - return result; - gst_otp[0] = 0; - gst_otp[1] = 0; - gst_otp[2] = 0; - for (i = 0; i < 3; i++) { - if (st_code[i] != 0) - gst_otp[i] = gyro_3500_st_tb[st_code[i] - 1]; - } - /* check self test value passing criterion. Using the DEF_ST_TOR - * for certain degree of tolerance */ - for (i = 0; i < 3; i++) { - if (gst_otp[i] == 0) { - if (abs(gst[i]) * DEF_ST_TOR < DEF_ST_OTP0_THRESH * - DEF_ST_PRECISION * - DEF_GYRO_SCALE) - ret_val |= (1 << i); - } else { - if (abs(gst[i]/gst_otp[i] - DEF_ST_PRECISION) > - DEF_GYRO_CT_SHIFT_DELTA) - ret_val |= (1 << i); - } - } - /* check for absolute value passing criterion. Using DEF_ST_TOR - * for certain degree of tolerance */ - for (i = 0; i < 3; i++) { - if (abs(reg_avg[i]) > DEF_ST_TOR * DEF_ST_ABS_THRESH * - DEF_ST_PRECISION * DEF_GYRO_SCALE) - ret_val |= (1 << i); - } - - return ret_val; -} - -/** -* inv_check_6050_gyro_self_test() - check 6050 gyro self test. this function -* returns zero as success. A non-zero return -* value indicates failure in self test. -* @*st: main data structure. -* @*reg_avg: average value of normal test. -* @*st_avg: average value of self test -*/ -static int inv_check_6050_gyro_self_test(struct inv_mpu_iio_s *st, - int *reg_avg, int *st_avg){ - int result; - int ret_val; - int st_shift_prod[3], st_shift_cust[3], st_shift_ratio[3], i; - u8 regs[3]; - - if (st->chip_info.software_revision < DEF_OLDEST_SUPP_SW_REV && - st->chip_info.product_revision < DEF_OLDEST_SUPP_PROD_REV) - return 0; - - ret_val = 0; - result = inv_plat_read(st, REG_ST_GCT_X, 3, regs); - if (result) - return result; - regs[X] &= 0x1f; - regs[Y] &= 0x1f; - regs[Z] &= 0x1f; - for (i = 0; i < 3; i++) { - if (regs[i] != 0) - st_shift_prod[i] = gyro_6050_st_tb[regs[i] - 1]; - else - st_shift_prod[i] = 0; - } - st_shift_prod[1] = -st_shift_prod[1]; - - for (i = 0; i < 3; i++) { - st_shift_cust[i] = st_avg[i] - reg_avg[i]; - if (st_shift_prod[i]) { - st_shift_ratio[i] = abs(st_shift_cust[i] / - st_shift_prod[i] - DEF_ST_PRECISION); - if (st_shift_ratio[i] > DEF_GYRO_CT_SHIFT_DELTA) - ret_val = 1; - } else { - if (st_shift_cust[i] < DEF_ST_PRECISION * - DEF_GYRO_CT_SHIFT_MIN * DEF_SELFTEST_GYRO_SENS) - ret_val = 1; - if (st_shift_cust[i] > DEF_ST_PRECISION * - DEF_GYRO_CT_SHIFT_MAX * DEF_SELFTEST_GYRO_SENS) - ret_val = 1; - } - } - /* check for absolute value passing criterion. Using DEF_ST_TOR - * for certain degree of tolerance */ - for (i = 0; i < 3; i++) - if (abs(reg_avg[i]) > DEF_ST_TOR * DEF_ST_ABS_THRESH * - DEF_ST_PRECISION * DEF_GYRO_SCALE) - ret_val = 1; - - return ret_val; -} - -/** -* inv_check_6500_gyro_self_test() - check 6500 gyro self test. this function -* returns zero as success. A non-zero return -* value indicates failure in self test. -* @*st: main data structure. -* @*reg_avg: average value of normal test. -* @*st_avg: average value of self test -*/ -static int inv_check_6500_gyro_self_test(struct inv_mpu_iio_s *st, - int *reg_avg, int *st_avg) -{ - u8 regs[3]; - int ret_val, result; - int otp_value_zero = 0; - int st_shift_prod[3], st_shift_cust[3], i; - - ret_val = 0; - result = inv_plat_read(st, REG_6500_XG_ST_DATA, 3, regs); - if (result) - return result; - pr_debug("%s self_test gyro shift_code - %02x %02x %02x\n", - st->hw->name, regs[0], regs[1], regs[2]); - - for (i = 0; i < 3; i++) { - if (regs[i] != 0) { - st_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; - } else { - st_shift_prod[i] = 0; - otp_value_zero = 1; - } - } - pr_debug("%s self_test gyro st_shift_prod - %+d %+d %+d\n", - st->hw->name, st_shift_prod[0], st_shift_prod[1], - st_shift_prod[2]); - - for (i = 0; i < 3; i++) { - st_shift_cust[i] = st_avg[i] - reg_avg[i]; - if (!otp_value_zero) { - /* Self Test Pass/Fail Criteria A */ - if (st_shift_cust[i] < DEF_6500_GYRO_CT_SHIFT_DELTA - * st_shift_prod[i]) - ret_val = 1; - } else { - /* Self Test Pass/Fail Criteria B */ - if (st_shift_cust[i] < DEF_GYRO_ST_AL * - DEF_SELFTEST_GYRO_SENS * - DEF_ST_PRECISION) - ret_val = 1; - } - } - pr_debug("%s self_test gyro st_shift_cust - %+d %+d %+d\n", - st->hw->name, st_shift_cust[0], st_shift_cust[1], - st_shift_cust[2]); - - if (ret_val == 0) { - /* Self Test Pass/Fail Criteria C */ - for (i = 0; i < 3; i++) - if (abs(reg_avg[i]) > DEF_GYRO_OFFSET_MAX * - DEF_SELFTEST_GYRO_SENS * - DEF_ST_PRECISION) - ret_val = 1; - } - - return ret_val; -} - -/** -* inv_check_6500_accel_self_test() - check 6500 accel self test. this function -* returns zero as success. A non-zero return -* value indicates failure in self test. -* @*st: main data structure. -* @*reg_avg: average value of normal test. -* @*st_avg: average value of self test -*/ -static int inv_check_6500_accel_self_test(struct inv_mpu_iio_s *st, - int *reg_avg, int *st_avg) { - int ret_val, result; - int st_shift_prod[3], st_shift_cust[3], st_shift_ratio[3], i; - u8 regs[3]; - int otp_value_zero = 0; - -#define ACCEL_ST_AL_MIN ((DEF_ACCEL_ST_AL_MIN * DEF_ST_SCALE \ - / DEF_ST_6500_ACCEL_FS_MG) * DEF_ST_PRECISION) -#define ACCEL_ST_AL_MAX ((DEF_ACCEL_ST_AL_MAX * DEF_ST_SCALE \ - / DEF_ST_6500_ACCEL_FS_MG) * DEF_ST_PRECISION) - - ret_val = 0; - result = inv_plat_read(st, REG_6500_XA_ST_DATA, 3, regs); - if (result) - return result; - pr_debug("%s self_test accel shift_code - %02x %02x %02x\n", - st->hw->name, regs[0], regs[1], regs[2]); - - for (i = 0; i < 3; i++) { - if (regs[i] != 0) { - st_shift_prod[i] = mpu_6500_st_tb[regs[i] - 1]; - } else { - st_shift_prod[i] = 0; - otp_value_zero = 1; - } - } - pr_debug("%s self_test accel st_shift_prod - %+d %+d %+d\n", - st->hw->name, st_shift_prod[0], st_shift_prod[1], - st_shift_prod[2]); - - if (!otp_value_zero) { - /* Self Test Pass/Fail Criteria A */ - for (i = 0; i < 3; i++) { - st_shift_cust[i] = st_avg[i] - reg_avg[i]; - st_shift_ratio[i] = abs(st_shift_cust[i] / - st_shift_prod[i] - DEF_ST_PRECISION); - if (st_shift_ratio[i] > DEF_6500_ACCEL_ST_SHIFT_DELTA) - ret_val = 1; - } - } else { - /* Self Test Pass/Fail Criteria B */ - for (i = 0; i < 3; i++) { - st_shift_cust[i] = abs(st_avg[i] - reg_avg[i]); - if (st_shift_cust[i] < ACCEL_ST_AL_MIN || - st_shift_cust[i] > ACCEL_ST_AL_MAX) - ret_val = 1; - } - } - pr_debug("%s self_test accel st_shift_cust - %+d %+d %+d\n", - st->hw->name, st_shift_cust[0], st_shift_cust[1], - st_shift_cust[2]); - - return ret_val; -} - -/* - * inv_do_test() - do the actual test of self testing - */ -int inv_do_test(struct inv_mpu_iio_s *st, int self_test_flag, - int *gyro_result, int *accl_result) -{ - struct inv_reg_map_s *reg; - int result, i, j, packet_size; - u8 data[BYTES_PER_SENSOR * 2], d; - bool has_accl; - int fifo_count, packet_count, ind, s; - - reg = &st->reg; - has_accl = (st->chip_type != INV_ITG3500); - if (has_accl) - packet_size = BYTES_PER_SENSOR * 2; - else - packet_size = BYTES_PER_SENSOR; - - result = inv_plat_single_write(st, reg->int_enable, 0); - if (result) - return result; - /* disable the sensor output to FIFO */ - result = inv_plat_single_write(st, reg->fifo_en, 0); - if (result) - return result; - /* disable fifo reading */ - result = inv_plat_single_write(st, reg->user_ctrl, st->i2c_dis); - if (result) - return result; - /* clear FIFO */ - result = inv_plat_single_write(st, reg->user_ctrl, BIT_FIFO_RST | st->i2c_dis); - if (result) - return result; - /* setup parameters */ - result = inv_plat_single_write(st, reg->lpf, INV_FILTER_98HZ); - if (result) - return result; - - if (INV_MPU6500 == st->chip_type) { - /* config accel LPF register for MPU6500 */ - result = inv_plat_single_write(st, REG_6500_ACCEL_CONFIG2, - DEF_ST_MPU6500_ACCEL_LPF | - BIT_FIFO_SIZE_1K); - if (result) - return result; - } - - result = inv_plat_single_write(st, reg->sample_rate_div, - DEF_SELFTEST_SAMPLE_RATE); - if (result) - return result; - /* wait for the sampling rate change to stabilize */ - mdelay(INV_MPU_SAMPLE_RATE_CHANGE_STABLE); - result = inv_plat_single_write(st, reg->gyro_config, - self_test_flag | DEF_SELFTEST_GYRO_FS); - if (result) - return result; - if (has_accl) { - if (INV_MPU6500 == st->chip_type) - d = DEF_SELFTEST_6500_ACCEL_FS; - else - d = DEF_SELFTEST_ACCEL_FS; - d |= self_test_flag; - result = inv_plat_single_write(st, reg->accl_config, d); - if (result) - return result; - } - /* wait for the output to get stable */ - if (self_test_flag) { - if (INV_MPU6500 == st->chip_type) - msleep(DEF_ST_6500_STABLE_TIME); - else - msleep(DEF_ST_STABLE_TIME); - } - - /* enable FIFO reading */ - result = inv_plat_single_write(st, reg->user_ctrl, BIT_FIFO_EN | st->i2c_dis); - if (result) - return result; - /* enable sensor output to FIFO */ - if (has_accl) - d = BITS_GYRO_OUT | BIT_ACCEL_OUT; - else - d = BITS_GYRO_OUT; - for (i = 0; i < THREE_AXIS; i++) { - gyro_result[i] = 0; - accl_result[i] = 0; - } - s = 0; - while (s < st->self_test.samples) { - result = inv_plat_single_write(st, reg->fifo_en, d); - if (result) - return result; - mdelay(DEF_GYRO_WAIT_TIME); - result = inv_plat_single_write(st, reg->fifo_en, 0); - if (result) - return result; - - result = inv_plat_read(st, reg->fifo_count_h, - FIFO_COUNT_BYTE, data); - if (result) - return result; - fifo_count = be16_to_cpup((__be16 *)(&data[0])); - pr_debug("%s self_test fifo_count - %d\n", - st->hw->name, fifo_count); - packet_count = fifo_count / packet_size; - i = 0; - while ((i < packet_count) && (s < st->self_test.samples)) { - short vals[3]; - result = inv_plat_read(st, reg->fifo_r_w, - packet_size, data); - if (result) - return result; - ind = 0; - if (has_accl) { - for (j = 0; j < THREE_AXIS; j++) { - vals[j] = (short)be16_to_cpup( - (__be16 *)(&data[ind + 2 * j])); - accl_result[j] += vals[j]; - } - ind += BYTES_PER_SENSOR; - pr_debug( - "%s self_test accel data - %d %+d %+d %+d", - st->hw->name, s, vals[0], vals[1], vals[2]); - } - - for (j = 0; j < THREE_AXIS; j++) { - vals[j] = (short)be16_to_cpup( - (__be16 *)(&data[ind + 2 * j])); - gyro_result[j] += vals[j]; - } - pr_debug("%s self_test gyro data - %d %+d %+d %+d", - st->hw->name, s, vals[0], vals[1], vals[2]); - - s++; - i++; - } - } - - if (has_accl) { - for (j = 0; j < THREE_AXIS; j++) { - accl_result[j] = accl_result[j] / s; - accl_result[j] *= DEF_ST_PRECISION; - } - } - for (j = 0; j < THREE_AXIS; j++) { - gyro_result[j] = gyro_result[j] / s; - gyro_result[j] *= DEF_ST_PRECISION; - } - - return 0; -} - -/* - * inv_recover_setting() recover the old settings after everything is done - */ -void inv_recover_setting(struct inv_mpu_iio_s *st) -{ - struct inv_reg_map_s *reg; - int data; - - reg = &st->reg; - inv_plat_single_write(st, reg->gyro_config, - st->chip_config.fsr << GYRO_CONFIG_FSR_SHIFT); - inv_plat_single_write(st, reg->lpf, st->chip_config.lpf); - data = ONE_K_HZ/st->chip_config.new_fifo_rate - 1; - inv_plat_single_write(st, reg->sample_rate_div, data); - if (INV_ITG3500 != st->chip_type) { - inv_plat_single_write(st, reg->accl_config, - (st->chip_config.accl_fs << - ACCL_CONFIG_FSR_SHIFT)); - } - st->switch_gyro_engine(st, false); - st->switch_accl_engine(st, false); - st->set_power_state(st, false); -} - -/* - * inv_resume_recover_setting() recover the old settings after from hw powerdown - */ -void inv_resume_recover_setting(struct inv_mpu_iio_s *st) -{ - struct inv_reg_map_s *reg; - int data; - - reg = &st->reg; - inv_plat_single_write(st, reg->gyro_config, - st->chip_config.fsr << GYRO_CONFIG_FSR_SHIFT); - inv_plat_single_write(st, reg->lpf, st->chip_config.lpf); - data = ONE_K_HZ / st->chip_config.new_fifo_rate - 1; - inv_plat_single_write(st, reg->sample_rate_div, data); - if (INV_ITG3500 != st->chip_type) { - inv_plat_single_write(st, reg->accl_config, - (st->chip_config.accl_fs << - ACCL_CONFIG_FSR_SHIFT)); - } -} - -static int inv_check_compass_self_test(struct inv_mpu_iio_s *st) -{ - int result; - u8 data[6]; - u8 counter, cntl; - short x, y, z; - u8 *sens; - sens = st->chip_info.compass_sens; - - /* set to bypass mode */ - result = inv_plat_single_write(st, REG_INT_PIN_CFG, - st->plat_data.int_config | BIT_BYPASS_EN); - if (result) { - result = inv_plat_single_write(st, REG_INT_PIN_CFG, - st->plat_data.int_config); - return result; - } - /* set to power down mode */ - result = inv_secondary_write(st, REG_AKM_MODE, DATA_AKM_MODE_PD); - if (result) - goto AKM_fail; - - /* write 1 to ASTC register */ - result = inv_secondary_write(st, REG_AKM_ST_CTRL, DATA_AKM_SELF_TEST); - if (result) - goto AKM_fail; - /* set self test mode */ - result = inv_secondary_write(st, REG_AKM_MODE, DATA_AKM_MODE_ST); - if (result) - goto AKM_fail; - counter = DEF_ST_COMPASS_TRY_TIMES; - while (counter > 0) { - usleep_range(DEF_ST_COMPASS_WAIT_MIN, DEF_ST_COMPASS_WAIT_MAX); - result = inv_secondary_read(st, REG_AKM_STATUS, 1, data); - if (result) - goto AKM_fail; - if ((data[0] & DATA_AKM_DRDY) == 0) - counter--; - else - counter = 0; - } - if ((data[0] & DATA_AKM_DRDY) == 0) { - result = -EINVAL; - goto AKM_fail; - } - result = inv_secondary_read(st, REG_AKM_MEASURE_DATA, - BYTES_PER_SENSOR, data); - if (result) - goto AKM_fail; - - x = le16_to_cpup((__le16 *)(&data[0])); - y = le16_to_cpup((__le16 *)(&data[2])); - z = le16_to_cpup((__le16 *)(&data[4])); - x = ((x * (sens[0] + 128)) >> 8); - y = ((y * (sens[1] + 128)) >> 8); - z = ((z * (sens[2] + 128)) >> 8); - if (COMPASS_ID_AK8963 == st->plat_data.sec_slave_id) { - result = inv_secondary_read(st, REG_AKM8963_CNTL1, 1, &cntl); - if (result) - goto AKM_fail; - if (0 == (cntl & DATA_AKM8963_BIT)) { - x <<= DEF_ST_COMPASS_8963_SHIFT; - y <<= DEF_ST_COMPASS_8963_SHIFT; - z <<= DEF_ST_COMPASS_8963_SHIFT; - } - } - result = -EINVAL; - if (x > st->compass_st_upper[X] || x < st->compass_st_lower[X]) - goto AKM_fail; - if (y > st->compass_st_upper[Y] || y < st->compass_st_lower[Y]) - goto AKM_fail; - if (z > st->compass_st_upper[Z] || z < st->compass_st_lower[Z]) - goto AKM_fail; - result = 0; -AKM_fail: - /*write 0 to ASTC register */ - result |= inv_secondary_write(st, REG_AKM_ST_CTRL, 0); - /*set to power down mode */ - result |= inv_secondary_write(st, REG_AKM_MODE, DATA_AKM_MODE_PD); - /*restore to non-bypass mode */ - result |= inv_plat_single_write(st, REG_INT_PIN_CFG, - st->plat_data.int_config); - return result; -} - -int inv_power_up_self_test(struct inv_mpu_iio_s *st) -{ - int result; - - result = st->set_power_state(st, true); - if (result) - return result; - result = st->switch_accl_engine(st, true); - if (result) - return result; - result = st->switch_gyro_engine(st, true); - if (result) - return result; - - return 0; -} - -/* - * inv_hw_self_test() - main function to do hardware self test - */ -int inv_hw_self_test(struct inv_mpu_iio_s *st) -{ - int result; - int gyro_bias_st[THREE_AXIS], gyro_bias_regular[THREE_AXIS]; - int accl_bias_st[THREE_AXIS], accl_bias_regular[THREE_AXIS]; - int test_times; - char compass_result, accel_result, gyro_result; - - result = inv_power_up_self_test(st); - if (result) - return result; - compass_result = 0; - accel_result = 0; - gyro_result = 0; - test_times = DEF_ST_TRY_TIMES; - while (test_times > 0) { - result = inv_do_test(st, 0, gyro_bias_regular, - accl_bias_regular); - if (result == -EAGAIN) - test_times--; - else - test_times = 0; - } - if (result) - goto test_fail; - - test_times = DEF_ST_TRY_TIMES; - while (test_times > 0) { - result = inv_do_test(st, BITS_SELF_TEST_EN, gyro_bias_st, - accl_bias_st); - if (result == -EAGAIN) - test_times--; - else - break; - } - if (result) - goto test_fail; - if (st->chip_type == INV_ITG3500) { - gyro_result = !inv_check_3500_gyro_self_test(st, - gyro_bias_regular, gyro_bias_st); - } else { - if (st->chip_config.has_compass) - compass_result = !inv_check_compass_self_test(st); - - if (INV_MPU6050 == st->chip_type) { - accel_result = !inv_check_accl_self_test(st, - accl_bias_regular, accl_bias_st); - gyro_result = !inv_check_6050_gyro_self_test(st, - gyro_bias_regular, gyro_bias_st); - } else if (INV_MPU6500 == st->chip_type) { - accel_result = !inv_check_6500_accel_self_test(st, - accl_bias_regular, accl_bias_st); - gyro_result = !inv_check_6500_gyro_self_test(st, - gyro_bias_regular, gyro_bias_st); - } - } -test_fail: - inv_recover_setting(st); - - return (compass_result << DEF_ST_COMPASS_RESULT_SHIFT) | - (accel_result << DEF_ST_ACCEL_RESULT_SHIFT) | gyro_result; -} - -static int inv_load_firmware(struct inv_mpu_iio_s *st, - u8 *data, int size) -{ - int bank, write_size; - int result; - u16 memaddr; - - /* 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; - - memaddr = ((bank << 8) | 0x00); - - result = mem_w(memaddr, write_size, data); - if (result) - return result; - } - return 0; -} - -static int inv_verify_firmware(struct inv_mpu_iio_s *st, - u8 *data, int size) -{ - int bank, write_size; - int result; - u16 memaddr; - u8 firmware[MPU_MEM_BANK_SIZE]; - - /* 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; - - memaddr = ((bank << 8) | 0x00); - result = mpu_memory_read(st, - st->i2c_addr, memaddr, write_size, firmware); - if (result) - return result; - if (0 != memcmp(firmware, data, write_size)) - return -EINVAL; - } - return 0; -} - -static int inv_set_fifo_div(struct inv_mpu_iio_s *st, - u16 fifoRate) -{ - u8 regs[2]; - int result = 0; - /*For some reason DINAC4 is defined as 0xb8, but DINBC4 is not*/ - const u8 regs_end[] = {DINAFE, DINAF2, DINAAB, 0xc4, - DINAAA, DINAF1, DINADF, DINADF, - 0xbb, 0xaf, DINADF, DINADF}; - - regs[0] = (u8)((fifoRate >> 8) & 0xff); - regs[1] = (u8)(fifoRate & 0xff); - result = mem_w_key(KEY_D_0_22, ARRAY_SIZE(regs), regs); - if (result) - return result; - - /*Modify the FIFO handler to reset the tap/orient interrupt flags*/ - /* each time the FIFO handler runs*/ - result = mem_w_key(KEY_CFG_6, ARRAY_SIZE(regs_end), regs_end); - - return result; -} - -int inv_send_quaternion(struct inv_mpu_iio_s *st, bool on) -{ - const u8 regs_on[] = {DINBC0, DINBC2, - DINBC4, DINBC6}; - const u8 regs_off[] = {DINA80, DINA80, - DINA80, DINA80}; - const u8 *regs; - u8 result; - if (on) - regs = regs_on; - else - regs = regs_off; - result = mem_w_key(KEY_CFG_LP_QUAT, ARRAY_SIZE(regs_on), regs); - - return result; -} - -int inv_set_display_orient_interrupt_dmp(struct inv_mpu_iio_s *st, - bool on) -{ - /*Turn on the display orientation interrupt in the DMP*/ - int result; - u8 regs[] = {0xd8}; - - if (on) - regs[0] = 0xd9; - result = mem_w_key(KEY_CFG_DISPLAY_ORIENT_INT, 1, regs); - return result; -} - -int inv_set_fifo_rate(struct inv_mpu_iio_s *st, u16 fifo_rate) -{ - u8 divider; - int result; - - divider = (u8)(ONE_K_HZ / fifo_rate) - 1; - if (divider > DMP_MAX_DIVIDER) { - st->sample_divider = DMP_MAX_DIVIDER; - st->fifo_divider = - (u8)(DMP_DEFAULT_FIFO_RATE / fifo_rate) - 1; - } else { - st->sample_divider = divider; - st->fifo_divider = 0; - } - - result = inv_set_fifo_div(st, st->fifo_divider); - return result; -} - -static int inv_set_tap_interrupt_dmp(struct inv_mpu_iio_s *st, - u8 on) -{ - int result; - u8 regs[] = {0}; - - if (on) - regs[0] = 0xf8; - else - regs[0] = DINAD8; - result = mem_w_key(KEY_CFG_20, ARRAY_SIZE(regs), regs); - if (result) - return result; - return result; -} - -int inv_set_tap_threshold_dmp(struct inv_mpu_iio_s *st, - u32 axis, u16 threshold) -{ - /* Sets the tap threshold in the dmp - Simultaneously sets secondary tap threshold to help correct the tap - direction for soft taps */ - int result; - /* DMP Algorithm */ - u8 data[2]; - int sampleDivider; - int scaledThreshold; - u32 dmpThreshold; - u8 sample_div; - const u32 accel_sens = (0x20000000 / 0x00010000); - - if ((axis & ~(INV_TAP_AXIS_ALL)) || (threshold > (1 << 15))) - return -EINVAL; - sample_div = st->sample_divider; - - sampleDivider = (1 + sample_div); - /* Scale factor corresponds linearly using - * 0 : 0 - * 25 : 0.0250 g/ms - * 50 : 0.0500 g/ms - * 100: 1.0000 g/ms - * 200: 2.0000 g/ms - * 400: 4.0000 g/ms - * 800: 8.0000 g/ms - */ - /*multiply by 1000 to avoid floating point 1000/1000*/ - scaledThreshold = threshold; - /* Convert to per sample */ - scaledThreshold *= sampleDivider; - - /* Scale to DMP 16 bit value */ - if (accel_sens != 0) - dmpThreshold = (u32)(scaledThreshold * accel_sens); - else - return -EINVAL; - dmpThreshold = dmpThreshold / DMP_PRECISION; - - data[0] = dmpThreshold >> 8; - data[1] = dmpThreshold & 0xFF; - - /* MPL algorithm */ - if (axis & INV_TAP_AXIS_X) { - result = mem_w_key(KEY_DMP_TAP_THR_X, ARRAY_SIZE(data), data); - if (result) - return result; - - /*Also set additional threshold for correcting the direction - of taps that were very near the threshold. */ - data[0] = (dmpThreshold * 3 / 4) >> 8; - data[1] = (dmpThreshold * 3 / 4) & 0xFF; - result = mem_w_key(KEY_D_1_36, ARRAY_SIZE(data), data); - if (result) - return result; - } - if (axis & INV_TAP_AXIS_Y) { - result = mem_w_key(KEY_DMP_TAP_THR_Y, 2, data); - if (result) - return result; - data[0] = (dmpThreshold * 3 / 4) >> 8; - data[1] = (dmpThreshold * 3 / 4) & 0xFF; - - result = mem_w_key(KEY_D_1_40, ARRAY_SIZE(data), data); - if (result) - return result; - } - if (axis & INV_TAP_AXIS_Z) { - result = mem_w_key(KEY_DMP_TAP_THR_Z, ARRAY_SIZE(data), data); - if (result) - return result; - data[0] = (dmpThreshold * 3 / 4) >> 8; - data[1] = (dmpThreshold * 3 / 4) & 0xFF; - - result = mem_w_key(KEY_D_1_44, ARRAY_SIZE(data), data); - if (result) - return result; - } - return 0; -} - -static int inv_set_tap_axes_dmp(struct inv_mpu_iio_s *st, - u32 axes) -{ - /* Sets a mask in the DMP that indicates what tap events - should result in an interrupt */ - u8 regs[4]; - u8 result; - - /* check if any spurious bit other the ones expected are set */ - if (axes & (~(INV_TAP_ALL_DIRECTIONS))) - return -EINVAL; - - regs[0] = (u8)axes; - result = mem_w_key(KEY_D_1_72, 1, regs); - - return result; -} - -int inv_set_min_taps_dmp(struct inv_mpu_iio_s *st, - u16 min_taps) { - /*Indicates the minimum number of consecutive taps required - before the DMP will generate an interrupt */ - u8 regs[1]; - u8 result; - /* check if any spurious bit other the ones expected are set */ - if ((min_taps > DMP_MAX_MIN_TAPS) || (min_taps < 1)) - return -EINVAL; - regs[0] = (u8)(min_taps-1); - result = mem_w_key(KEY_D_1_79, ARRAY_SIZE(regs), regs); - - return result; -} - -int inv_set_tap_time_dmp(struct inv_mpu_iio_s *st, u16 time) -{ - /* Determines how long after a tap the DMP requires before - another tap can be registered*/ - int result; - /* DMP Algorithm */ - u16 dmpTime; - u8 data[2]; - u8 sampleDivider; - - sampleDivider = st->sample_divider; - sampleDivider++; - - /* 60 ms minimum time added */ - dmpTime = ((time) / sampleDivider); - data[0] = dmpTime >> 8; - data[1] = dmpTime & 0xFF; - - result = mem_w_key(KEY_DMP_TAPW_MIN, ARRAY_SIZE(data), data); - - return result; -} - -static int inv_set_multiple_tap_time_dmp(struct inv_mpu_iio_s *st, - u32 time) -{ - /*Determines how close together consecutive taps must occur - to be considered double/triple taps*/ - int result; - /* DMP Algorithm */ - u16 dmpTime; - u8 data[2]; - u8 sampleDivider; - - sampleDivider = st->sample_divider; - sampleDivider++; - - /* 60 ms minimum time added */ - dmpTime = ((time) / sampleDivider); - data[0] = dmpTime >> 8; - data[1] = dmpTime & 0xFF; - result = mem_w_key(KEY_D_1_218, ARRAY_SIZE(data), data); - - return result; -} - -int inv_q30_mult(int a, int b) -{ - u64 temp; - int result; - - temp = (u64)a * b; - result = (int)(temp >> DMP_MULTI_SHIFT); - - return result; -} - -static u16 inv_row_2_scale(const s8 *row) -{ - u16 b; - - if (row[0] > 0) - b = 0; - else if (row[0] < 0) - b = 4; - else if (row[1] > 0) - b = 1; - else if (row[1] < 0) - b = 5; - else if (row[2] > 0) - b = 2; - else if (row[2] < 0) - b = 6; - else - b = 7; - - return b; -} - -/** Converts an orientation matrix made up of 0,+1,and -1 to a scalar -* representation. -* @param[in] mtx Orientation matrix to convert to a scalar. -* @return Description of orientation matrix. The lowest 2 bits (0 and 1) -* represent the column the one is on for the -* first row, with the bit number 2 being the sign. The next 2 bits -* (3 and 4) represent -* the column the one is on for the second row with bit number 5 being -* the sign. -* The next 2 bits (6 and 7) represent the column the one is on for the -* third row with -* bit number 8 being the sign. In binary the identity matrix would therefor -* be: 010_001_000 or 0x88 in hex. -*/ -static u16 inv_orientation_matrix_to_scaler(const signed char *mtx) -{ - - u16 scalar; - scalar = inv_row_2_scale(mtx); - scalar |= inv_row_2_scale(mtx + 3) << 3; - scalar |= inv_row_2_scale(mtx + 6) << 6; - - return scalar; -} -#if 0 -static int inv_disable_gyro_cal(struct inv_mpu_iio_s *st) -{ - const u8 regs[] = { - 0xb8, 0xaa, 0xaa, 0xaa, - 0xb0, 0x88, 0xc3, 0xc5, - 0xc7 - }; - return mem_w_key(KEY_CFG_MOTION_BIAS, ARRAY_SIZE(regs), regs); -} -#endif - -static int inv_gyro_dmp_cal(struct inv_mpu_iio_s *st) -{ - int inv_gyro_orient; - u8 regs[3]; - int result; - - u8 tmpD = DINA4C; - u8 tmpE = DINACD; - u8 tmpF = DINA6C; - - inv_gyro_orient = - inv_orientation_matrix_to_scaler(st->plat_data.orientation); - - if ((inv_gyro_orient & 3) == 0) - regs[0] = tmpD; - else if ((inv_gyro_orient & 3) == 1) - regs[0] = tmpE; - else if ((inv_gyro_orient & 3) == 2) - regs[0] = tmpF; - if ((inv_gyro_orient & 0x18) == 0) - regs[1] = tmpD; - else if ((inv_gyro_orient & 0x18) == 0x8) - regs[1] = tmpE; - else if ((inv_gyro_orient & 0x18) == 0x10) - regs[1] = tmpF; - if ((inv_gyro_orient & 0xc0) == 0) - regs[2] = tmpD; - else if ((inv_gyro_orient & 0xc0) == 0x40) - regs[2] = tmpE; - else if ((inv_gyro_orient & 0xc0) == 0x80) - regs[2] = tmpF; - - result = mem_w_key(KEY_FCFG_1, ARRAY_SIZE(regs), regs); - if (result) - return result; - - if (inv_gyro_orient & 4) - regs[0] = DINA36 | 1; - else - regs[0] = DINA36; - if (inv_gyro_orient & 0x20) - regs[1] = DINA56 | 1; - else - regs[1] = DINA56; - if (inv_gyro_orient & 0x100) - regs[2] = DINA76 | 1; - else - regs[2] = DINA76; - - result = mem_w_key(KEY_FCFG_3, ARRAY_SIZE(regs), regs); - - return result; -} - -static int inv_accel_dmp_cal(struct inv_mpu_iio_s *st) -{ - int inv_accel_orient; - int result; - u8 regs[3]; - const u8 tmp[3] = { DINA0C, DINAC9, DINA2C }; - inv_accel_orient = - inv_orientation_matrix_to_scaler(st->plat_data.orientation); - - regs[0] = tmp[inv_accel_orient & 3]; - regs[1] = tmp[(inv_accel_orient >> 3) & 3]; - regs[2] = tmp[(inv_accel_orient >> 6) & 3]; - result = mem_w_key(KEY_FCFG_2, ARRAY_SIZE(regs), regs); - if (result) - return result; - - regs[0] = DINA26; - regs[1] = DINA46; - regs[2] = DINA66; - if (inv_accel_orient & 4) - regs[0] |= 1; - if (inv_accel_orient & 0x20) - regs[1] |= 1; - if (inv_accel_orient & 0x100) - regs[2] |= 1; - result = mem_w_key(KEY_FCFG_7, ARRAY_SIZE(regs), regs); - - return result; -} - -static u16 inv_orientation_matrix_to_scalar(const s8 *mtx) -{ - - u16 scalar; - - /* - XYZ 010_001_000 Identity Matrix - XZY 001_010_000 - YXZ 010_000_001 - YZX 000_010_001 - ZXY 001_000_010 - ZYX 000_001_010 - */ - - scalar = inv_row_2_scale(mtx); - scalar |= inv_row_2_scale(mtx + 3) << 3; - scalar |= inv_row_2_scale(mtx + 6) << 6; - - return scalar; -} - -int inv_set_accel_bias_dmp(struct inv_mpu_iio_s *st) -{ - int inv_accel_orient, result, i, accel_bias_body[3], out[3]; - int tmp[] = {1, 1, 1}; - int mask[] = {4, 0x20, 0x100}; - int accel_sf = 0x20000000;/* 536870912 */ - u8 *regs; - - inv_accel_orient = - inv_orientation_matrix_to_scalar(st->plat_data.orientation); - - for (i = 0; i < 3; i++) - if (inv_accel_orient & mask[i]) - tmp[i] = -1; - - for (i = 0; i < 3; i++) - accel_bias_body[i] = st->input_accel_bias[(inv_accel_orient >> - (i * 3)) & 3] * tmp[i]; - for (i = 0; i < 3; i++) - accel_bias_body[i] = inv_q30_mult(accel_sf, - accel_bias_body[i]); - for (i = 0; i < 3; i++) - out[i] = cpu_to_be32p(&accel_bias_body[i]); - regs = (u8 *)out; - result = mem_w_key(KEY_D_ACCEL_BIAS, sizeof(out), regs); - - return result; -} - -static int inv_set_gyro_sf_dmp(struct inv_mpu_iio_s *st) -{ - /*The gyro threshold, in dps, above which taps will be rejected*/ - int result; - /* DMP Algorithm */ - u8 sampleDivider; - u32 gyro_sf; - const u32 gyro_sens = 0x03e80000; - - sampleDivider = st->sample_divider; - gyro_sf = inv_q30_mult(gyro_sens, - (int)(DMP_TAP_SCALE * (sampleDivider + 1))); - result = write_be32_key_to_mem(st, gyro_sf, KEY_D_0_104); - - return result; -} - -static int inv_set_shake_reject_thresh_dmp(struct inv_mpu_iio_s *st, - int thresh) -{ /*THIS FUNCTION FAILS MEM_W*/ - /*The gyro threshold, in dps, above which taps will be rejected */ - int result; - /* DMP Algorithm */ - u8 sampleDivider; - int thresh_scaled; - u32 gyro_sf; - const u32 gyro_sens = 0x03e80000; - sampleDivider = st->sample_divider; - gyro_sf = inv_q30_mult(gyro_sens, (int)(DMP_TAP_SCALE * - (sampleDivider + 1))); - /* We're in units of DPS, convert it back to chip units*/ - /*split the operation to aviod overflow of integer*/ - thresh_scaled = gyro_sens / (1L << 16); - thresh_scaled = thresh_scaled / thresh; - thresh_scaled = gyro_sf / thresh_scaled; - result = write_be32_key_to_mem(st, thresh_scaled, KEY_D_1_92); - - return result; -} - -static int inv_set_shake_reject_time_dmp(struct inv_mpu_iio_s *st, - u32 time) -{ - /* How long a gyro axis must remain above its threshold - before taps are rejected */ - int result; - /* DMP Algorithm */ - u16 dmpTime; - u8 data[2]; - u8 sampleDivider; - - sampleDivider = st->sample_divider; - sampleDivider++; - - /* 60 ms minimum time added */ - dmpTime = ((time) / sampleDivider); - data[0] = dmpTime >> 8; - data[1] = dmpTime & 0xFF; - - result = mem_w_key(KEY_D_1_88, ARRAY_SIZE(data), data); - return result; -} - -static int inv_set_shake_reject_timeout_dmp(struct inv_mpu_iio_s *st, - u32 time) -{ - /*How long the gyros must remain below their threshold, - after taps have been rejected, before taps can be detected again*/ - int result; - /* DMP Algorithm */ - u16 dmpTime; - u8 data[2]; - u8 sampleDivider; - - sampleDivider = st->sample_divider; - sampleDivider++; - - /* 60 ms minimum time added */ - dmpTime = ((time) / sampleDivider); - data[0] = dmpTime >> 8; - data[1] = dmpTime & 0xFF; - - result = mem_w_key(KEY_D_1_90, ARRAY_SIZE(data), data); - return result; -} - -int inv_set_interrupt_on_gesture_event(struct inv_mpu_iio_s *st, bool on) -{ - u8 result; - const u8 regs_on[] = {DINADA, DINAB1, DINAB9, - DINAF3, DINA8B, DINAA3, DINA91, - DINAB6, DINADA, DINAB4, DINADA}; - const u8 regs_off[] = {0xd8, 0xb1, 0xb9, 0xf3, 0x8b, - 0xa3, 0x91, 0xb6, 0x09, 0xb4, 0xd9}; - /*For some reason DINAC4 is defined as 0xb8, - but DINBC4 is not defined.*/ - const u8 regs_end[] = {DINAFE, DINAF2, DINAAB, 0xc4, - DINAAA, DINAF1, DINADF, DINADF, - 0xbb, 0xaf, DINADF, DINADF}; - const u8 regs[] = {0, 0}; - /* reset fifo count to zero */ - result = mem_w_key(KEY_D_1_178, ARRAY_SIZE(regs), regs); - if (result) - return result; - - if (on) - /*Sets the DMP to send an interrupt and put a FIFO packet - in the FIFO if and only if a tap/orientation event - just occurred*/ - result = mem_w_key(KEY_CFG_FIFO_ON_EVENT, ARRAY_SIZE(regs_on), - regs_on); - else - /*Sets the DMP to send an interrupt and put a FIFO packet - in the FIFO at the rate specified by the FIFO div. - see inv_set_fifo_div in hw_setup.c to set the FIFO div.*/ - result = mem_w_key(KEY_CFG_FIFO_ON_EVENT, ARRAY_SIZE(regs_off), - regs_off); - if (result) - return result; - - result = mem_w_key(KEY_CFG_6, ARRAY_SIZE(regs_end), regs_end); - - return result; -} - -/** - * inv_enable_tap_dmp() - calling this function will enable/disable tap function. - */ -int inv_enable_tap_dmp(struct inv_mpu_iio_s *st, bool on) -{ - int result; - - result = inv_set_tap_interrupt_dmp(st, on); - if (result) - return result; - if (on) { - result = inv_set_tap_threshold_dmp(st, INV_TAP_AXIS_X, - st->tap.thresh); - if (result) - return result; - result = inv_set_tap_threshold_dmp(st, INV_TAP_AXIS_Y, - st->tap.thresh); - if (result) - return result; - result = inv_set_tap_threshold_dmp(st, INV_TAP_AXIS_Z, - st->tap.thresh); - if (result) - return result; - } - - result = inv_set_tap_axes_dmp(st, INV_TAP_ALL_DIRECTIONS); - if (result) - return result; - result = inv_set_min_taps_dmp(st, st->tap.min_count); - if (result) - return result; - - result = inv_set_tap_time_dmp(st, st->tap.time); - if (result) - return result; - - result = inv_set_multiple_tap_time_dmp(st, DMP_MULTI_TAP_TIME); - if (result) - return result; - - result = inv_set_gyro_sf_dmp(st); - if (result) - return result; - - result = inv_set_shake_reject_thresh_dmp(st, DMP_SHAKE_REJECT_THRESH); - if (result) - return result; - - result = inv_set_shake_reject_time_dmp(st, DMP_SHAKE_REJECT_TIME); - if (result) - return result; - - result = inv_set_shake_reject_timeout_dmp(st, - DMP_SHAKE_REJECT_TIMEOUT); - return result; -} - -int inv_send_sensor_data(struct inv_mpu_iio_s *st, u16 elements) -{ - int result; - u8 regs[] = {DINAA0 + 3, DINAA0 + 3, DINAA0 + 3, - DINAA0 + 3, DINAA0 + 3, DINAA0 + 3, - DINAA0 + 3, DINAA0 + 3, DINAA0 + 3, - DINAA0 + 3}; - - if (elements & INV_ELEMENT_1) - regs[0] = DINACA; - if (elements & INV_ELEMENT_2) - regs[4] = DINBC4; - if (elements & INV_ELEMENT_3) - regs[5] = DINACC; - if (elements & INV_ELEMENT_4) - regs[6] = DINBC6; - if ((elements & INV_ELEMENT_5) || (elements & INV_ELEMENT_6) || - (elements & INV_ELEMENT_7)) { - regs[1] = DINBC0; - regs[2] = DINAC8; - regs[3] = DINBC2; - } - result = mem_w_key(KEY_CFG_15, ARRAY_SIZE(regs), regs); - return result; -} - -int inv_send_interrupt_word(struct inv_mpu_iio_s *st, bool on) -{ - const u8 regs_on[] = { DINA20 }; - const u8 regs_off[] = { DINAA3 }; - u8 result; - - if (on) - result = mem_w_key(KEY_CFG_27, ARRAY_SIZE(regs_on), regs_on); - else - result = mem_w_key(KEY_CFG_27, ARRAY_SIZE(regs_off), regs_off); - - return result; -} - -/** - * inv_dmp_firmware_write() - calling this function will load the firmware. - * This is the write function of file "dmp_firmware". - */ -ssize_t inv_dmp_firmware_write(struct file *fp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t pos, size_t size) -{ - u8 *firmware; - int result; - struct inv_reg_map_s *reg; - struct iio_dev *indio_dev; - struct inv_mpu_iio_s *st; - - indio_dev = dev_get_drvdata(container_of(kobj, struct device, kobj)); - st = iio_priv(indio_dev); - - if (st->chip_config.firmware_loaded) - return -EINVAL; - if (st->chip_config.enable) - return -EBUSY; - - reg = &st->reg; - if (DMP_IMAGE_SIZE != size) { - pr_err("wrong DMP image size\n"); - return -EINVAL; - } - - firmware = kmalloc(size, GFP_KERNEL); - if (!firmware) - return -ENOMEM; - - mutex_lock(&indio_dev->mlock); - - memcpy(firmware, buf, size); - result = crc32(CRC_FIRMWARE_SEED, firmware, size); - if (DMP_IMAGE_CRC_VALUE != result) { - pr_err("firmware CRC error - 0x%08x vs 0x%08x\n", - result, DMP_IMAGE_CRC_VALUE); - result = -EINVAL; - goto firmware_write_fail; - } - - result = st->set_power_state(st, true); - if (result) - goto firmware_write_fail; - - result = inv_load_firmware(st, firmware, size); - if (result) - goto firmware_write_fail; - - result = inv_verify_firmware(st, firmware, size); - if (result) - goto firmware_write_fail; - - result = inv_plat_single_write(st, reg->prgm_strt_addrh, - st->chip_config.prog_start_addr >> 8); - if (result) - goto firmware_write_fail; - result = inv_plat_single_write(st, reg->prgm_strt_addrh + 1, - st->chip_config.prog_start_addr & 0xff); - if (result) - goto firmware_write_fail; - - result = inv_set_fifo_rate(st, DMP_DEFAULT_FIFO_RATE); - if (result) - goto firmware_write_fail; - result = inv_gyro_dmp_cal(st); - if (result) - goto firmware_write_fail; - result = inv_accel_dmp_cal(st); - if (result) - goto firmware_write_fail; - /* result = inv_disable_gyro_cal(st);*/ - if (result) - goto firmware_write_fail; - - st->chip_config.firmware_loaded = 1; - -firmware_write_fail: - result |= st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - kfree(firmware); - if (result) - return result; - return size; -} - -ssize_t inv_dmp_firmware_read(struct file *filp, - struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t off, size_t count) -{ - int bank, write_size, size, data, result; - u16 memaddr; - struct iio_dev *indio_dev; - struct inv_mpu_iio_s *st; - - size = count; - indio_dev = dev_get_drvdata(container_of(kobj, struct device, kobj)); - st = iio_priv(indio_dev); - - data = 0; - mutex_lock(&indio_dev->mlock); - if (!st->chip_config.enable) { - result = st->set_power_state(st, true); - if (result) { - mutex_unlock(&indio_dev->mlock); - return result; - } - } - 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; - - memaddr = (bank << 8); - result = mpu_memory_read(st, - st->i2c_addr, memaddr, write_size, &buf[data]); - if (result) { - mutex_unlock(&indio_dev->mlock); - return result; - } - } - if (!st->chip_config.enable) - result = st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - if (result) - return result; - - return count; -} -/** - * @} - */ diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_ring.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_ring.c deleted file mode 100644 index dead8352a1a2..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_ring.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_mpu_ring.c - * @brief A sysfs device driver for Invensense gyroscopes. - * @details This file is part of inv mpu iio driver code - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef INV_KERNEL_3_10 -#include -#include -#include -#include -#else -#include "iio.h" -#include "kfifo_buf.h" -#include "trigger_consumer.h" -#include "sysfs.h" -#endif - -#include "inv_mpu_iio.h" -#include "../../../../hid/hid-rkvr.h" - -/** - * reset_fifo_mpu3050() - Reset FIFO related registers - * @st: Device driver instance. - */ -static int reset_fifo_mpu3050(struct iio_dev *indio_dev) -{ - struct inv_reg_map_s *reg; - int result; - u8 val, user_ctrl; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - reg = &st->reg; - - /* disable interrupt */ - result = inv_plat_single_write(st, reg->int_enable, - st->plat_data.int_config); - if (result) - return result; - /* disable the sensor output to FIFO */ - result = inv_plat_single_write(st, reg->fifo_en, 0); - if (result) - goto reset_fifo_fail; - result = inv_plat_read(st, reg->user_ctrl, 1, &user_ctrl); - if (result) - goto reset_fifo_fail; - /* disable fifo reading */ - user_ctrl &= ~BIT_FIFO_EN; - st->chip_config.has_footer = 0; - /* reset fifo */ - val = (BIT_3050_FIFO_RST | user_ctrl); - result = inv_plat_single_write(st, reg->user_ctrl, val | st->i2c_dis); - if (result) - goto reset_fifo_fail; - st->last_isr_time = get_time_ns(); - if (st->chip_config.dmp_on) { - /* enable interrupt when DMP is done */ - result = inv_plat_single_write(st, reg->int_enable, - st->plat_data.int_config | BIT_DMP_INT_EN); - if (result) - return result; - - result = inv_plat_single_write(st, reg->user_ctrl, - BIT_FIFO_EN | user_ctrl | st->i2c_dis); - if (result) - return result; - } else { - /* enable interrupt */ - if (st->chip_config.accl_fifo_enable || - st->chip_config.gyro_fifo_enable) { - result = inv_plat_single_write(st, reg->int_enable, - st->plat_data.int_config | BIT_DATA_RDY_EN); - if (result) - return result; - } - /* enable FIFO reading and I2C master interface*/ - result = inv_plat_single_write(st, reg->user_ctrl, - BIT_FIFO_EN | user_ctrl | st->i2c_dis); - if (result) - return result; - /* enable sensor output to FIFO and FIFO footer*/ - val = 1; - if (st->chip_config.accl_fifo_enable) - val |= BITS_3050_ACCL_OUT; - if (st->chip_config.gyro_fifo_enable) - val |= BITS_GYRO_OUT; - result = inv_plat_single_write(st, reg->fifo_en, val); - if (result) - return result; - } - - return 0; -reset_fifo_fail: - if (st->chip_config.dmp_on) - val = BIT_DMP_INT_EN; - else - val = BIT_DATA_RDY_EN; - inv_plat_single_write(st, reg->int_enable, - st->plat_data.int_config | val); - pr_err("reset fifo failed\n"); - - return result; -} - -/** - * inv_set_lpf() - set low pass filer based on fifo rate. - */ -static int inv_set_lpf(struct inv_mpu_iio_s *st, int rate) -{ - const short hz[] = {188, 98, 42, 20, 10, 5}; - const int d[] = {INV_FILTER_188HZ, INV_FILTER_98HZ, - INV_FILTER_42HZ, INV_FILTER_20HZ, - INV_FILTER_10HZ, INV_FILTER_5HZ}; - int i, h, data, result; - struct inv_reg_map_s *reg; - reg = &st->reg; - h = (rate >> 1); - i = 0; - while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1)) - i++; - data = d[i]; - if (INV_MPU3050 == st->chip_type) { - if (st->mpu_slave != NULL) { - result = st->mpu_slave->set_lpf(st, rate); - if (result) - return result; - } - result = inv_plat_single_write(st, reg->lpf, data | - (st->chip_config.fsr << GYRO_CONFIG_FSR_SHIFT)); - } else { - result = inv_plat_single_write(st, reg->lpf, data); - } - if (result) - return result; - st->chip_config.lpf = data; - - return 0; -} - -/** - * set_fifo_rate_reg() - Set fifo rate in hardware register - */ -static int set_fifo_rate_reg(struct inv_mpu_iio_s *st) -{ - u8 data; - u16 fifo_rate; - int result; - struct inv_reg_map_s *reg; - - reg = &st->reg; - fifo_rate = st->chip_config.new_fifo_rate; - data = ONE_K_HZ / fifo_rate - 1; - result = inv_plat_single_write(st, reg->sample_rate_div, data); - if (result) - return result; - result = inv_set_lpf(st, fifo_rate); - if (result) - return result; - st->chip_config.fifo_rate = fifo_rate; - - return 0; -} - -/** - * inv_lpa_mode() - store current low power mode settings - */ -static int inv_lpa_mode(struct inv_mpu_iio_s *st, int lpa_mode) -{ - unsigned long result; - u8 d; - struct inv_reg_map_s *reg; - - reg = &st->reg; - result = inv_plat_read(st, reg->pwr_mgmt_1, 1, &d); - if (result) - return result; - if (lpa_mode) - d |= BIT_CYCLE; - else - d &= ~BIT_CYCLE; - - result = inv_plat_single_write(st, reg->pwr_mgmt_1, d); - if (result) - return result; - if (INV_MPU6500 == st->chip_type) { - if (lpa_mode) - d = BIT_ACCEL_FCHOCIE_B; - else - d = 0; - result = inv_plat_single_write(st, REG_6500_ACCEL_CONFIG2, d); - if (result) - return result; - } - - return 0; -} - -/** - * reset_fifo_itg() - Reset FIFO related registers. - * @st: Device driver instance. - */ -static int reset_fifo_itg(struct iio_dev *indio_dev) -{ - struct inv_reg_map_s *reg; - int result, data; - u8 val, int_word; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - reg = &st->reg; - - if (st->chip_config.lpa_mode) { - result = inv_lpa_mode(st, 0); - if (result) { - pr_err("reset lpa mode failed\n"); - return result; - } - } - /* disable interrupt */ - result = inv_plat_single_write(st, reg->int_enable, 0); - if (result) { - pr_err("int_enable write failed\n"); - return result; - } - /* disable the sensor output to FIFO */ - result = inv_plat_single_write(st, reg->fifo_en, 0); - if (result) - goto reset_fifo_fail; - /* disable fifo reading */ - result = inv_plat_single_write(st, reg->user_ctrl, st->i2c_dis); - if (result) - goto reset_fifo_fail; - int_word = 0; - - /* MPU6500's BIT_6500_WOM_EN is the same as BIT_MOT_EN */ - if (st->mot_int.mot_on) - int_word |= BIT_MOT_EN; - - if (st->chip_config.dmp_on) { - val = (BIT_FIFO_RST | BIT_DMP_RST); - result = inv_plat_single_write(st, reg->user_ctrl, val | st->i2c_dis); - if (result) - goto reset_fifo_fail; - st->last_isr_time = get_time_ns(); - if (st->chip_config.dmp_int_on) { - int_word |= BIT_DMP_INT_EN; - result = inv_plat_single_write(st, reg->int_enable, - int_word); - if (result) - return result; - } - val = (BIT_DMP_EN | BIT_FIFO_EN); - if (st->chip_config.compass_enable & - (!st->chip_config.dmp_event_int_on)) - val |= BIT_I2C_MST_EN; - result = inv_plat_single_write(st, reg->user_ctrl, val | st->i2c_dis); - if (result) - goto reset_fifo_fail; - - if (st->chip_config.compass_enable) { - /* I2C_MST_DLY is set according to sample rate, - slow down the power*/ - data = max(COMPASS_RATE_SCALE * - st->chip_config.new_fifo_rate / ONE_K_HZ, - st->chip_config.new_fifo_rate / - st->chip_config.dmp_output_rate); - if (data > 0) - data -= 1; - result = inv_plat_single_write(st, REG_I2C_SLV4_CTRL, - data); - if (result) - return result; - } - val = 0; - if (st->chip_config.accl_fifo_enable) - val |= INV_ACCL_MASK; - if (st->chip_config.gyro_fifo_enable) - val |= INV_GYRO_MASK; - result = inv_send_sensor_data(st, val); - if (result) - return result; - if (st->chip_config.display_orient_on || st->chip_config.tap_on) - result = inv_send_interrupt_word(st, true); - else - result = inv_send_interrupt_word(st, false); - } else { - /* reset FIFO and possibly reset I2C*/ - val = BIT_FIFO_RST; - result = inv_plat_single_write(st, reg->user_ctrl, val | st->i2c_dis); - if (result) - goto reset_fifo_fail; - st->last_isr_time = get_time_ns(); - /* enable interrupt */ - if (st->chip_config.accl_fifo_enable || - st->chip_config.gyro_fifo_enable || - st->chip_config.compass_enable) { - int_word |= BIT_DATA_RDY_EN; - } - result = inv_plat_single_write(st, reg->int_enable, int_word); - if (result) - return result; - /* enable FIFO reading and I2C master interface*/ - val = BIT_FIFO_EN; - if (st->chip_config.compass_enable) - val |= BIT_I2C_MST_EN; - result = inv_plat_single_write(st, reg->user_ctrl, val | st->i2c_dis); - if (result) - goto reset_fifo_fail; - if (st->chip_config.compass_enable) { - /* I2C_MST_DLY is set according to sample rate, - slow down the power*/ - data = COMPASS_RATE_SCALE * - st->chip_config.new_fifo_rate / ONE_K_HZ; - if (data > 0) - data -= 1; - result = inv_plat_single_write(st, REG_I2C_SLV4_CTRL, - data); - if (result) - return result; - } - /* enable sensor output to FIFO */ - val = 0; - if (st->chip_config.gyro_fifo_enable) - val |= BITS_GYRO_OUT; - if (st->chip_config.accl_fifo_enable) - val |= BIT_ACCEL_OUT; - result = inv_plat_single_write(st, reg->fifo_en, val); - if (result) - goto reset_fifo_fail; - } - st->chip_config.normal_compass_measure = 0; - result = inv_lpa_mode(st, st->chip_config.lpa_mode); - if (result) - goto reset_fifo_fail; - - return 0; - -reset_fifo_fail: - if (st->chip_config.dmp_on) - val = BIT_DMP_INT_EN; - else - val = BIT_DATA_RDY_EN; - inv_plat_single_write(st, reg->int_enable, val); - pr_err("reset fifo failed\n"); - - return result; -} - -/** - * inv_clear_kfifo() - clear time stamp fifo - * @st: Device driver instance. - */ -static void inv_clear_kfifo(struct inv_mpu_iio_s *st) -{ - unsigned long flags; - - spin_lock_irqsave(&st->time_stamp_lock, flags); - kfifo_reset(&st->timestamps); - spin_unlock_irqrestore(&st->time_stamp_lock, flags); -} - -/** - * inv_reset_fifo() - Reset FIFO related registers. - * @st: Device driver instance. - */ -static int inv_reset_fifo(struct iio_dev *indio_dev) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - inv_clear_kfifo(st); - if (INV_MPU3050 == st->chip_type) - return reset_fifo_mpu3050(indio_dev); - else - return reset_fifo_itg(indio_dev); -} - -static int inv_set_dmp_sysfs(struct inv_mpu_iio_s *st) -{ - int result; - - result = inv_set_fifo_rate(st, st->chip_config.dmp_output_rate); - if (result) - return result; - result = inv_set_interrupt_on_gesture_event(st, - st->chip_config.dmp_event_int_on); - - return result; -} - -/** - * set_inv_enable() - Reset FIFO related registers. - * This also powers on the chip if needed. - * @st: Device driver instance. - * @fifo_enable: enable/disable - */ -static int set_inv_enable(struct iio_dev *indio_dev, - bool enable) { - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct inv_reg_map_s *reg; - int result; - - reg = &st->reg; - if (enable) { - if (st->chip_config.new_fifo_rate != - st->chip_config.fifo_rate) { - result = set_fifo_rate_reg(st); - if (result) - return result; - } - if (st->chip_config.dmp_on) { - result = inv_set_dmp_sysfs(st); - if (result) - return result; - } - - if (st->chip_config.gyro_enable) { - result = st->switch_gyro_engine(st, true); - if (result) - return result; - } - if (st->chip_config.accl_enable) { - result = st->switch_accl_engine(st, true); - if (result) - return result; - } - - result = inv_reset_fifo(indio_dev); - if (result) - return result; - } else { - if ((INV_MPU3050 != st->chip_type) - && st->chip_config.lpa_mode) { - /* if the chip is in low power mode, - register write/read could fail */ - result = inv_lpa_mode(st, 0); - if (result) - return result; - } - result = inv_plat_single_write(st, reg->fifo_en, 0); - if (result) - return result; - /* disable fifo reading */ - if (INV_MPU3050 != st->chip_type) { - result = inv_plat_single_write(st, reg->int_enable, 0); - if (result) - return result; - result = inv_plat_single_write(st, reg->user_ctrl, st->i2c_dis); - } else { - result = inv_plat_single_write(st, reg->int_enable, - st->plat_data.int_config); - } - if (result) - return result; - /* turn off the gyro/accl engine during disable phase */ - result = st->switch_gyro_engine(st, false); - if (result) - return result; - result = st->switch_accl_engine(st, false); - if (result) - return result; - result = st->set_power_state(st, false); - if (result) - return result; - } - st->chip_config.enable = enable; - - return 0; -} - -/* #define _RATE_DEBUG */ - -#ifdef _RATE_DEBUG -static s64 tm_irq_min = -1; -static s64 tm_irq_max = -1; -static s64 tm_irq_sum = -1; -static s64 tm_irq_last_print = -1; -static s64 tm_irq_count = -1; -#endif - -/** - * inv_irq_handler() - Cache a timestamp at each data ready interrupt. - */ -static irqreturn_t inv_irq_handler(int irq, void *dev_id) -{ - struct inv_mpu_iio_s *st; - u64 timestamp; - int catch_up; - u64 time_since_last_irq; - - st = (struct inv_mpu_iio_s *)dev_id; - timestamp = get_time_ns(); - time_since_last_irq = timestamp - st->last_isr_time; - spin_lock(&st->time_stamp_lock); - -#ifdef _RATE_DEBUG - if (tm_irq_min <= 0 && tm_irq_max <= 0) { - tm_irq_min = time_since_last_irq; - tm_irq_max = time_since_last_irq; - tm_irq_sum = 0; - tm_irq_count = 0; - } else if (time_since_last_irq < tm_irq_min) { - tm_irq_min = time_since_last_irq; - } else if (time_since_last_irq > tm_irq_max) { - tm_irq_max = time_since_last_irq; - } - tm_irq_sum += time_since_last_irq; - tm_irq_count++; - - if (unlikely((timestamp - tm_irq_last_print) >= 1000000000)) { - pr_info("MPU Interrupt: %lld,%d,%lld\n", tm_irq_min, (u32)tm_irq_sum / (u32)tm_irq_count, tm_irq_max); - tm_irq_last_print = timestamp; - tm_irq_min = 0; - tm_irq_max = 0; - tm_irq_count = 0; - tm_irq_sum = 0; - } -#endif - - catch_up = 0; - while ((time_since_last_irq > st->irq_dur_ns * 2) && - (catch_up < MAX_CATCH_UP) && - (!st->chip_config.lpa_mode) && - (!st->chip_config.dmp_on)) { - st->last_isr_time += st->irq_dur_ns; - kfifo_in(&st->timestamps, - &st->last_isr_time, 1); - time_since_last_irq = timestamp - st->last_isr_time; - catch_up++; - } - kfifo_in(&st->timestamps, ×tamp, 1); - st->last_isr_time = timestamp; - spin_unlock(&st->time_stamp_lock); - - return IRQ_WAKE_THREAD; -} - -static int put_scan_to_buf(struct iio_dev *indio_dev, u8 *d, - short *s, int scan_index, int d_ind) { - struct iio_buffer *ring = indio_dev->buffer; - int st; - int i; - for (i = 0; i < 3; i++) { - st = iio_scan_mask_query(indio_dev, ring, scan_index + i); - if (st) { - memcpy(&d[d_ind], &s[i], sizeof(s[i])); - d_ind += sizeof(s[i]); - } - } - return d_ind; -} - -static void inv_report_data_3050(struct iio_dev *indio_dev, s64 t, - int has_footer, u8 *data) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - int ind, i, d_ind; - struct inv_chip_config_s *conf; - short g[THREE_AXIS], a[THREE_AXIS]; - s64 buf[8]; - u8 *tmp; - int bytes_per_datum, scan_count; - conf = &st->chip_config; - - scan_count = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); - bytes_per_datum = scan_count * 2; - - ind = 0; - if (has_footer) - ind += 2; - tmp = (u8 *)buf; - d_ind = 0; - - if (conf->gyro_fifo_enable) { - for (i = 0; i < ARRAY_SIZE(g); i++) { - g[i] = be16_to_cpup((__be16 *)(&data[ind + i * 2])); - st->raw_gyro[i] = g[i]; - } - ind += BYTES_PER_SENSOR; - } - if (conf->accl_fifo_enable) { - st->mpu_slave->combine_data(&data[ind], a); - for (i = 0; i < ARRAY_SIZE(a); i++) - st->raw_accel[i] = a[i]; - - ind += BYTES_PER_SENSOR; - d_ind = put_scan_to_buf(indio_dev, tmp, a, - INV_MPU_SCAN_ACCL_X, d_ind); - } - if (conf->gyro_fifo_enable) - d_ind = put_scan_to_buf(indio_dev, tmp, g, - INV_MPU_SCAN_GYRO_X, d_ind); - - i = (bytes_per_datum + 7) / 8; - if (ring->scan_timestamp) - buf[i] = t; -#ifdef INV_KERNEL_3_10 - ring->access->store_to(indio_dev->buffer, (u8 *)buf); -#else - ring->access->store_to(indio_dev->buffer, (u8 *)buf, t); -#endif -} - -/** - * inv_read_fifo_mpu3050() - Transfer data from FIFO to ring buffer for - * mpu3050. - */ -irqreturn_t inv_read_fifo_mpu3050(int irq, void *dev_id) -{ - - struct inv_mpu_iio_s *st = (struct inv_mpu_iio_s *)dev_id; - struct iio_dev *indio_dev = iio_priv_to_dev(st); - int bytes_per_datum; - u8 data[64]; - int result; - short fifo_count, byte_read; - u32 copied; - s64 timestamp; - struct inv_reg_map_s *reg; - reg = &st->reg; - /* It is impossible that chip is asleep or enable is - zero when interrupt is on - * because interrupt is now connected with enable */ - if (st->chip_config.dmp_on) - bytes_per_datum = BYTES_FOR_DMP; - else - bytes_per_datum = (st->chip_config.accl_fifo_enable + - st->chip_config.gyro_fifo_enable)*BYTES_PER_SENSOR; - if (st->chip_config.has_footer) - byte_read = bytes_per_datum + MPU3050_FOOTER_SIZE; - else - byte_read = bytes_per_datum; - - fifo_count = 0; - if (byte_read != 0) { - result = inv_plat_read(st, reg->fifo_count_h, - FIFO_COUNT_BYTE, data); - if (result) - goto end_session; - fifo_count = be16_to_cpup((__be16 *)(&data[0])); - if (fifo_count < byte_read) - goto end_session; - if (fifo_count & 1) - goto flush_fifo; - if (fifo_count > FIFO_THRESHOLD) - goto flush_fifo; - /* Timestamp mismatch. */ - if (kfifo_len(&st->timestamps) < - fifo_count / byte_read) - goto flush_fifo; - if (kfifo_len(&st->timestamps) > - fifo_count / byte_read + TIME_STAMP_TOR) { - if (st->chip_config.dmp_on) { - result = kfifo_to_user(&st->timestamps, - ×tamp, sizeof(timestamp), &copied); - if (result) - goto flush_fifo; - } else { - goto flush_fifo; - } - } - } - while ((bytes_per_datum != 0) && (fifo_count >= byte_read)) { - result = inv_plat_read(st, reg->fifo_r_w, byte_read, data); - if (result) - goto flush_fifo; - - result = kfifo_to_user(&st->timestamps, - ×tamp, sizeof(timestamp), &copied); - if (result) - goto flush_fifo; - inv_report_data_3050(indio_dev, timestamp, - st->chip_config.has_footer, data); - fifo_count -= byte_read; - if (st->chip_config.has_footer == 0) { - st->chip_config.has_footer = 1; - byte_read = bytes_per_datum + MPU3050_FOOTER_SIZE; - } - } - -end_session: - return IRQ_HANDLED; - -flush_fifo: - /* Flush HW and SW FIFOs. */ - inv_reset_fifo(indio_dev); - inv_clear_kfifo(st); - return IRQ_HANDLED; -} - -static int inv_report_gyro_accl_compass(struct iio_dev *indio_dev, - u8 *data, s64 t) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - short g[THREE_AXIS], a[THREE_AXIS], c[THREE_AXIS]; - int q[4]; - int result, ind; - u32 word; - u8 d[8], compass_divider; - u8 buf[64]; - u64 *tmp; - int source, i; - struct inv_chip_config_s *conf; - - conf = &st->chip_config; - ind = 0; - - if (conf->quaternion_on & conf->dmp_on) { - for (i = 0; i < ARRAY_SIZE(q); i++) { - q[i] = be32_to_cpup((__be32 *)(&data[ind + i * 4])); - st->raw_quaternion[i] = q[i]; - memcpy(&buf[ind + i * sizeof(q[i])], &q[i], - sizeof(q[i])); - } - ind += QUATERNION_BYTES; - } - - if (conf->accl_fifo_enable) { - for (i = 0; i < ARRAY_SIZE(a); i++) { - a[i] = be16_to_cpup((__be16 *)(&data[ind + i * 2])); - memcpy(&buf[ind + i * sizeof(a[i])], &a[i], - sizeof(a[i])); - } - ind += BYTES_PER_SENSOR; - } - - if (conf->gyro_fifo_enable) { - for (i = 0; i < ARRAY_SIZE(g); i++) { - g[i] = be16_to_cpup((__be16 *)(&data[ind + i * 2])); - memcpy(&buf[ind + i * sizeof(g[i])], &g[i], - sizeof(g[i])); - } - ind += BYTES_PER_SENSOR; - } - - if (conf->dmp_on && (conf->tap_on || conf->display_orient_on)) { - word = (u32)(be32_to_cpup((u32 *)&data[ind])); - source = ((word >> 16) & 0xff); - if (source) { - st->tap_data = (DMP_MASK_TAP & (word & 0xff)); - st->display_orient_data = - ((DMP_MASK_DIS_ORIEN & (word & 0xff)) >> - DMP_DIS_ORIEN_SHIFT); - } - - /* report tap information */ - if (source & INT_SRC_TAP) - sysfs_notify(&indio_dev->dev.kobj, NULL, "event_tap"); - /* report orientation information */ - if (source & INT_SRC_DISPLAY_ORIENT) - sysfs_notify(&indio_dev->dev.kobj, NULL, - "event_display_orientation"); - } - /*divider and counter is used to decrease the speed of read in - high frequency sample rate*/ - if (conf->compass_fifo_enable) { - c[0] = 0; - c[1] = 0; - c[2] = 0; - if (conf->dmp_on) - compass_divider = st->compass_dmp_divider; - else - compass_divider = st->compass_divider; - if (compass_divider <= st->compass_counter) { - /*read from external sensor data register */ - result = inv_plat_read(st, REG_EXT_SENS_DATA_00, - NUM_BYTES_COMPASS_SLAVE, d); - /* d[7] is status 2 register */ - /*for AKM8975, bit 2 and 3 should be all be zero*/ - /* for AMK8963, bit 3 should be zero*/ - if ((DATA_AKM_DRDY == d[0]) && - (0 == (d[7] & DATA_AKM_STAT_MASK)) && - (!result)) { - u8 *sens; - sens = st->chip_info.compass_sens; - c[0] = (short)((d[2] << 8) | d[1]); - c[1] = (short)((d[4] << 8) | d[3]); - c[2] = (short)((d[6] << 8) | d[5]); - c[0] = (short)(((int)c[0] * - (sens[0] + 128)) >> 8); - c[1] = (short)(((int)c[1] * - (sens[1] + 128)) >> 8); - c[2] = (short)(((int)c[2] * - (sens[2] + 128)) >> 8); - st->raw_compass[0] = c[0]; - st->raw_compass[1] = c[1]; - st->raw_compass[2] = c[2]; - } - st->compass_counter = 0; - } else if (compass_divider != 0) { - st->compass_counter++; - } - if (!conf->normal_compass_measure) { - c[0] = 0; - c[1] = 0; - c[2] = 0; - conf->normal_compass_measure = 1; - } - for (i = 0; i < 3; i++) - memcpy(&buf[ind + i * sizeof(c[i])], &c[i], - sizeof(c[i])); - ind += BYTES_PER_SENSOR; - } - tmp = (u64 *)buf; - tmp[DIV_ROUND_UP(ind, 8)] = t; - - if (ind > 0) { -#ifdef INV_KERNEL_3_10 - iio_push_to_buffers(indio_dev, buf); -#else - iio_push_to_buffer(indio_dev->buffer, buf, t); -#endif - } - - return 0; -} - -static void inv_process_motion(struct inv_mpu_iio_s *st) -{ - struct iio_dev *indio_dev = iio_priv_to_dev(st); - s32 diff, true_motion; - s64 timestamp; - int result; - u8 data[1]; - - /* motion interrupt */ - result = inv_plat_read(st, REG_INT_STATUS, 1, data); - if (result) - return; - - if (data[0] & BIT_MOT_INT) { - timestamp = get_time_ns(); - diff = (int)(((timestamp - st->mpu6500_last_motion_time) >> - NS_PER_MS_SHIFT)); - if (diff > st->mot_int.mot_dur) { - st->mpu6500_last_motion_time = timestamp; - true_motion = 1; - } else { - true_motion = 0; - } - if (true_motion) - sysfs_notify(&indio_dev->dev.kobj, NULL, - "event_accel_motion"); - } -} - -static int get_bytes_per_datum(struct inv_mpu_iio_s *st) -{ - int bytes_per_datum; - - bytes_per_datum = 0; - if (st->chip_config.dmp_on) { - if (st->chip_config.quaternion_on) - bytes_per_datum += QUATERNION_BYTES; - if (st->chip_config.tap_on || - st->chip_config.display_orient_on) - bytes_per_datum += BYTES_FOR_EVENTS; - } - if (st->chip_config.accl_fifo_enable) - bytes_per_datum += BYTES_PER_SENSOR; - if (st->chip_config.gyro_fifo_enable) - bytes_per_datum += BYTES_PER_SENSOR; - - return bytes_per_datum; -} - -#ifdef _RATE_DEBUG -static s64 tm_end_min = -1; -static s64 tm_end_max = -1; -static s64 tm_end_sum = -1; -static s64 tm_end_last_print = -1; -static s64 tm_end_count = -1; -#endif -/** - * inv_read_fifo() - Transfer data from FIFO to ring buffer. - */ -irqreturn_t inv_read_fifo(int irq, void *dev_id) -{ - - struct inv_mpu_iio_s *st = (struct inv_mpu_iio_s *)dev_id; - struct iio_dev *indio_dev = iio_priv_to_dev(st); - size_t bytes_per_datum; - int result; - u8 data[BYTES_FOR_DMP + QUATERNION_BYTES]; - u16 fifo_count; - u32 copied; - s64 timestamp; - struct inv_reg_map_s *reg; - s64 buf[8]; - s8 *tmp; - - mutex_lock(&indio_dev->mlock); - if (!(iio_buffer_enabled(indio_dev))) - goto end_session; - - reg = &st->reg; - if (!(st->chip_config.accl_fifo_enable | - st->chip_config.gyro_fifo_enable | - st->chip_config.dmp_on | - st->chip_config.compass_fifo_enable | - st->mot_int.mot_on)) - goto end_session; - if (st->mot_int.mot_on) - inv_process_motion(st); - if (st->chip_config.dmp_on && st->chip_config.smd_enable) { - /* dmp interrupt status */ - result = inv_plat_read(st, REG_DMP_INT_STATUS, 1, data); - if (!result) - if (data[0] & SMD_INT_ON) { - sysfs_notify(&indio_dev->dev.kobj, NULL, - "event_smd"); - st->chip_config.smd_enable = 0; - } - } - if (st->chip_config.lpa_mode) { - result = inv_plat_read(st, reg->raw_accl, - BYTES_PER_SENSOR, data); - if (result) - goto end_session; - inv_report_gyro_accl_compass(indio_dev, data, - get_time_ns()); - goto end_session; - } - bytes_per_datum = get_bytes_per_datum(st); - fifo_count = 0; - if (bytes_per_datum != 0) { - result = inv_plat_read(st, reg->fifo_count_h, - FIFO_COUNT_BYTE, data); - if (result) - goto end_session; - fifo_count = be16_to_cpup((__be16 *)(&data[0])); - if ((fifo_count == 0) && (kfifo_len(&st->timestamps) > 0)) - goto flush_fifo; - if (fifo_count < bytes_per_datum) - goto end_session; - /* fifo count can't be odd number */ - if (fifo_count & 1) - goto flush_fifo; - if (fifo_count > FIFO_THRESHOLD) - goto flush_fifo; - /* timestamp mismatch. */ - if (kfifo_len(&st->timestamps) < - fifo_count / bytes_per_datum) - goto flush_fifo; - if (kfifo_len(&st->timestamps) > - fifo_count / bytes_per_datum + TIME_STAMP_TOR) { - if (st->chip_config.dmp_on) { - result = kfifo_to_user(&st->timestamps, - ×tamp, sizeof(timestamp), &copied); - if (result) - goto flush_fifo; - } else { - goto flush_fifo; - } - } - } else { - result = kfifo_to_user(&st->timestamps, - ×tamp, sizeof(timestamp), &copied); - if (result) - goto flush_fifo; - } - tmp = (s8 *)buf; - while ((bytes_per_datum != 0) && (fifo_count >= bytes_per_datum)) { - result = inv_plat_read(st, reg->fifo_r_w, bytes_per_datum, - data); - if (result) - goto flush_fifo; - - result = kfifo_to_user(&st->timestamps, - ×tamp, sizeof(timestamp), &copied); - if (result) - goto flush_fifo; - inv_report_gyro_accl_compass(indio_dev, data, timestamp); - fifo_count -= bytes_per_datum; - } - if (bytes_per_datum == 0 && st->chip_config.compass_fifo_enable) - inv_report_gyro_accl_compass(indio_dev, data, timestamp); - -#ifdef _RATE_DEBUG -{ - s64 tm_end_cur = get_time_ns(); - s64 tm_end_delta = tm_end_cur - timestamp; - - if (tm_end_min <= 0 && tm_end_max <= 0) { - tm_end_min = tm_end_delta; - tm_end_max = tm_end_delta; - tm_end_sum = 0; - tm_end_count = 0; - } else if (tm_end_delta < tm_end_min) { - tm_end_min = tm_end_delta; - } else if (tm_end_delta > tm_end_max) { - tm_end_max = tm_end_delta; - } - tm_end_sum += tm_end_delta; - tm_end_count++; - - if (unlikely((tm_end_cur - tm_end_last_print) >= 1000000000)) { - pr_info("MPU KRNL report rate[%4lld]: %8lld, %8d, %8lld\n", - tm_end_count, tm_end_min, (u32)tm_end_sum / (u32)tm_end_count, tm_end_max); - tm_end_last_print = tm_end_cur; - tm_end_min = 0; - tm_end_max = 0; - tm_end_count = 0; - tm_end_sum = 0; - } -} -#endif - -end_session: - mutex_unlock(&indio_dev->mlock); - return IRQ_HANDLED; - -flush_fifo: - /* Flush HW and SW FIFOs. */ - pr_info("fifo_count = %d, fifo_len = %d\n", fifo_count, kfifo_len(&st->timestamps)); - inv_reset_fifo(indio_dev); - inv_clear_kfifo(st); - mutex_unlock(&indio_dev->mlock); - - return IRQ_HANDLED; -} - -void inv_mpu_unconfigure_ring(struct iio_dev *indio_dev) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - if (!st->use_hid) - free_irq(st->irq, st); - iio_kfifo_free(indio_dev->buffer); -}; - -static int inv_postenable(struct iio_dev *indio_dev) -{ - return set_inv_enable(indio_dev, true); -} - -static int inv_predisable(struct iio_dev *indio_dev) -{ - return set_inv_enable(indio_dev, false); -} - -static void inv_scan_query(struct iio_dev *indio_dev) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - int result; - - if (iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_GYRO_X) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_GYRO_Y) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_GYRO_Z)) - st->chip_config.gyro_fifo_enable = 1; - else - st->chip_config.gyro_fifo_enable = 0; - - if (iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_ACCL_X) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_ACCL_Y) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_ACCL_Z)) - st->chip_config.accl_fifo_enable = 1; - else - st->chip_config.accl_fifo_enable = 0; - - if (iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_MAGN_X) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_MAGN_Y) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_MAGN_Z)) - st->chip_config.compass_fifo_enable = 1; - else - st->chip_config.compass_fifo_enable = 0; - - /* check to make sure engine is turned on if fifo is turned on */ - if (st->chip_config.gyro_fifo_enable && - (!st->chip_config.gyro_enable)) { - result = st->switch_gyro_engine(st, true); - if (result) - return; - st->chip_config.gyro_enable = true; - } - if (st->chip_config.accl_fifo_enable && - (!st->chip_config.accl_enable)) { - result = st->switch_accl_engine(st, true); - if (result) - return; - st->chip_config.accl_enable = true; - } -} - -static int inv_check_quaternion(struct iio_dev *indio_dev) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - int result; - - if (st->chip_config.dmp_on) { - if ( - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_QUAT_R) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_QUAT_X) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_QUAT_Y) || - iio_scan_mask_query(indio_dev, ring, INV_MPU_SCAN_QUAT_Z)) - st->chip_config.quaternion_on = 1; - else - st->chip_config.quaternion_on = 0; - - result = inv_send_quaternion(st, - st->chip_config.quaternion_on); - if (result) - return result; - } else { - st->chip_config.quaternion_on = 0; - clear_bit(INV_MPU_SCAN_QUAT_R, ring->scan_mask); - clear_bit(INV_MPU_SCAN_QUAT_X, ring->scan_mask); - clear_bit(INV_MPU_SCAN_QUAT_Y, ring->scan_mask); - clear_bit(INV_MPU_SCAN_QUAT_Z, ring->scan_mask); - } - - return 0; -} - -static int inv_check_conflict_sysfs(struct iio_dev *indio_dev) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; - int result; - - if (st->chip_config.lpa_mode) { - /* dmp cannot run with low power mode on */ - st->chip_config.dmp_on = 0; - result = st->gyro_en(st, ring, false); - if (result) - return result; - result = st->compass_en(st, ring, false); - if (result) - return result; - result = st->quaternion_en(st, ring, false); - if (result) - return result; - - result = st->accl_en(st, ring, true); - if (result) - return result; - } - result = inv_check_quaternion(indio_dev); - if (result) - return result; - - return result; -} - -static int inv_preenable(struct iio_dev *indio_dev) -{ - int result; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - result = st->set_power_state(st, true); - if (result) - return result; - - result = inv_check_conflict_sysfs(indio_dev); - if (result) - return result; - inv_scan_query(indio_dev); - - return result; -} - -static const struct iio_buffer_setup_ops inv_mpu_ring_setup_ops = { - .preenable = &inv_preenable, - .postenable = &inv_postenable, - .predisable = &inv_predisable, -}; - -#ifdef CONFIG_HID_RKVR -/* Callback handler to send event */ -static int inv_proc_event(char *raw_data, size_t raw_len, void *priv) -{ - struct inv_mpu_iio_s *st = (struct inv_mpu_iio_s *)priv; - struct iio_dev *indio_dev = iio_priv_to_dev(st); - short g[THREE_AXIS], a[THREE_AXIS]; - int ind; - u8 buf[64]; - u64 *tmp; - int i; - char *p; - struct inv_chip_config_s *conf; - - conf = &st->chip_config; - ind = 0; - -#ifdef DUMP_HEX -{ - int hex_index; - char hex[raw_len * 3 + (8 - 3)]; - - for (hex_index = 0; hex_index < raw_len; hex_index++) - sprintf(&hex[hex_index * 3], "%02X ", raw_data[hex_index]); - hex[hex_index * 3] = '\n'; - hex[hex_index * 3 + 1] = '\0'; - pr_info("in:%s\n", hex); -} -#endif - if (st->chip_config.is_asleep) - return 0; - - if (raw_data[1] == 0) - return 0; - - p = raw_data + 6; - st->hid_temperature = (p[1] << 8) | p[0]; - p = raw_data + 8; - - if (conf->quaternion_on) - ind += BYTES_FOR_DMP; - - if (conf->accl_fifo_enable) { - for (i = 0; i < ARRAY_SIZE(a); i++) { - a[i] = (p[1] << 8) | p[0]; - p += 2; - } - memcpy(&buf[ind], a, sizeof(a)); - ind += BYTES_PER_SENSOR; - } - - if (conf->gyro_fifo_enable) { - for (i = 0; i < ARRAY_SIZE(g); i++) { - g[i] = (p[1] << 8) | p[0]; - p += 2; - } - memcpy(&buf[ind], g, sizeof(g)); - ind += BYTES_PER_SENSOR; - } - - tmp = (u64 *)buf; - st->hid_timestamp = get_time_ns(); - tmp[DIV_ROUND_UP(ind, 8)] = st->hid_timestamp; - - if (ind > 0) { -#ifdef INV_KERNEL_3_10 - iio_push_to_buffers(indio_dev, buf); -#else - iio_push_to_buffer(indio_dev->buffer, buf, st->hid_timestamp); -#endif - } - - return 0; -} -#endif - -int inv_mpu_configure_ring(struct iio_dev *indio_dev) -{ - int ret; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct iio_buffer *ring; - - ring = iio_kfifo_allocate(); - if (!ring) - return -ENOMEM; - indio_dev->buffer = ring; - /* setup ring buffer */ - ring->scan_timestamp = true; - indio_dev->setup_ops = &inv_mpu_ring_setup_ops; - - if (st->use_hid) { -#ifdef CONFIG_HID_RKVR - pr_info("register event callback\n"); - rkvr_sensor_register_callback(inv_proc_event, st); -#endif - } else { - /*scan count double count timestamp. should subtract 1. but - number of channels still includes timestamp*/ - if (INV_MPU3050 == st->chip_type) - ret = request_threaded_irq(st->irq, inv_irq_handler, - inv_read_fifo_mpu3050, - IRQF_TRIGGER_RISING | IRQF_SHARED, "inv_irq", st); - else - ret = request_threaded_irq(st->irq, inv_irq_handler, - inv_read_fifo, - IRQF_TRIGGER_RISING | IRQF_SHARED, "inv_irq", st); - if (ret) - goto error_iio_sw_rb_free; - } - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; -error_iio_sw_rb_free: - iio_kfifo_free(indio_dev->buffer); - return ret; -} - -/** - * @} - */ - diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_spi.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_spi.c deleted file mode 100644 index b4ff1a4c25c7..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_spi.c +++ /dev/null @@ -1,610 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_mpu_iio.h" -#ifdef INV_KERNEL_3_10 -#include -#else -#include "sysfs.h" -#endif -#include "inv_counters.h" - -#define INV_SPI_READ 0x80 -static int inv_spi_read(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data) -{ - struct spi_message msg; - int res; - u8 d[2]; - struct spi_device *spi = to_spi_device(st->dev); - struct spi_transfer xfers[] = { - { - .tx_buf = d, - .bits_per_word = 8, - .len = 1, - }, - { - .rx_buf = data, - .bits_per_word = 8, - .len = len, - } - }; - - if (!data) - return -EINVAL; - - d[0] = (reg | INV_SPI_READ); - - if ((reg == REG_FIFO_R_W) || (reg == REG_FIFO_COUNT_H)) - spi->max_speed_hz = 20000000; - else - spi->max_speed_hz = 1000000; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - res = spi_sync(spi, &msg); - - return res; -} - -static int inv_spi_single_write(struct inv_mpu_iio_s *st, u8 reg, u8 data) -{ - struct spi_message msg; - int res; - u8 d[2]; - struct spi_device *spi = to_spi_device(st->dev); - struct spi_transfer xfers = { - .tx_buf = d, - .bits_per_word = 8, - .len = 2, - }; - - d[0] = reg; - d[1] = data; - spi->max_speed_hz = 1000000; - spi_message_init(&msg); - spi_message_add_tail(&xfers, &msg); - res = spi_sync(to_spi_device(st->dev), &msg); - - return res; -} - -static int inv_spi_secondary_read(struct inv_mpu_iio_s *st, u8 reg, int len, u8 *data) -{ - return 0; -} - -static int inv_spi_secondary_write(struct inv_mpu_iio_s *st, u8 reg, u8 data) -{ - return 0; -} - -static int mpu_spi_memory_write(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 const *data) -{ - struct spi_message msg; - u8 buf[513]; - int res; - - struct spi_transfer xfers = { - .tx_buf = buf, - .bits_per_word = 8, - .len = len + 1, - }; - - if (!data || !st) - return -EINVAL; - - if (len > (sizeof(buf) - 1)) - return -ENOMEM; - - inv_plat_single_write(st, REG_BANK_SEL, mem_addr >> 8); - inv_plat_single_write(st, REG_MEM_START_ADDR, mem_addr & 0xFF); - - buf[0] = REG_MEM_RW; - memcpy(buf + 1, data, len); - spi_message_init(&msg); - spi_message_add_tail(&xfers, &msg); - res = spi_sync(to_spi_device(st->dev), &msg); - - return res; -} - -static int mpu_spi_memory_read(struct inv_mpu_iio_s *st, u8 mpu_addr, u16 mem_addr, - u32 len, u8 *data) -{ - int res; - - if (!data || !st) - return -EINVAL; - - res = inv_plat_single_write(st, REG_BANK_SEL, mem_addr >> 8); - res = inv_plat_single_write(st, REG_MEM_START_ADDR, mem_addr & 0xFF); - res = inv_plat_read(st, REG_MEM_RW, len, data); - - return res; -} - -#include -#include -#include - -static struct mpu_platform_data mpu_data = { - .int_config = 0x00, - .level_shifter = 0, - .orientation = { - 0, 1, 0, - -1, 0, 0, - 0, 0, -1, - }, -/* - .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS, - .sec_slave_id = COMPASS_ID_AK8963, - .secondary_i2c_addr = 0x0d, - .secondary_orientation = { - -1, 0, 0, - 0, 1, 0, - 0, 0, -1, - }, - .key = { - 221, 22, 205, 7, 217, 186, 151, 55, - 206, 254, 35, 144, 225, 102, 47, 50, - }, -*/ -}; - -static int of_inv_parse_platform_data(struct spi_device *spi, - struct mpu_platform_data *pdata) -{ - int ret; - int length = 0, size = 0; - struct property *prop; - u32 orientation[9]; - int orig_x, orig_y, orig_z; - int i; - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct device_node *np = spi->dev.of_node; - unsigned long irq_flags; - int irq_pin; - int gpio_pin; - int debug; - int hw_pwoff; - - gpio_pin = of_get_named_gpio_flags(np, "irq-gpio", 0, (enum of_gpio_flags *)&irq_flags); - gpio_request(gpio_pin, "mpu6500"); - irq_pin = gpio_to_irq(gpio_pin); - spi->irq = irq_pin; - - ret = of_property_read_u8(np, "mpu-int_config", &mpu_data.int_config); - if (ret != 0) { - dev_err(&spi->dev, "get mpu-int_config error\n"); - return -EIO; - } - - ret = of_property_read_u8(np, "mpu-level_shifter", &mpu_data.level_shifter); - if (ret != 0) { - dev_err(&spi->dev, "get mpu-level_shifter error\n"); - return -EIO; - } - - prop = of_find_property(np, "mpu-orientation", &length); - if (!prop) { - dev_err(&spi->dev, "get mpu-orientation length error\n"); - return -EINVAL; - } - size = length / sizeof(u32); - if ((size > 0) && (size < 10)) { - ret = of_property_read_u32_array(np, "mpu-orientation", orientation, size); - if (ret < 0) { - dev_err(&spi->dev, "get mpu-orientation data error\n"); - return -EINVAL; - } - for (i = 0; i < 9; i++) - mpu_data.orientation[i] = orientation[i]; - } else { - dev_info(&spi->dev, "use default orientation\n"); - } - - ret = of_property_read_u32(np, "orientation-x", &orig_x); - if (ret != 0) { - dev_err(&spi->dev, "get orientation-x error\n"); - return -EIO; - } - if (orig_x > 0) { - for (i = 0; i < 3; i++) - if (mpu_data.orientation[i]) - mpu_data.orientation[i] = -1; - } - - ret = of_property_read_u32(np, "orientation-y", &orig_y); - if (ret != 0) { - dev_err(&spi->dev, "get orientation-y error\n"); - return -EIO; - } - if (orig_y > 0) { - for (i = 3; i < 6; i++) - if (mpu_data.orientation[i]) - mpu_data.orientation[i] = -1; - } - - ret = of_property_read_u32(np, "orientation-z", &orig_z); - if (ret != 0) { - dev_err(&spi->dev, "get orientation-z error\n"); - return -EIO; - } - if (orig_z > 0) { - for (i = 6; i < 9; i++) - if (mpu_data.orientation[i]) - mpu_data.orientation[i] = -1; - } - - ret = of_property_read_u32(np, "support-hw-poweroff", &hw_pwoff); - if (ret != 0) { - st->support_hw_poweroff = 0; - } - st->support_hw_poweroff = hw_pwoff; - - ret = of_property_read_u32(np, "mpu-debug", &debug); - if (ret != 0) { - dev_err(&spi->dev, "get mpu-debug error\n"); - return -EINVAL; - } - if (debug) { - dev_info(&spi->dev, "int_config=%d,level_shifter=%d,irq=%x\n", - mpu_data.int_config, - mpu_data.level_shifter, - spi->irq); - for (i = 0; i < size; i++) - dev_info(&spi->dev, "%d ", mpu_data.orientation[i]); - dev_info(&spi->dev, "\n"); - } - - return 0; -} - -/** - * inv_mpu_probe() - probe function. - */ -static int inv_mpu_probe(struct spi_device *spi) -{ - struct inv_mpu_iio_s *st; - struct iio_dev *indio_dev; - int result; - - if (!spi) - return -ENOMEM; - - spi->bits_per_word = 8; - result = spi_setup(spi); - if (result < 0) { - dev_err(&spi->dev, "ERR: fail to setup spi\n"); - goto out_no_free; - } - -#ifdef INV_KERNEL_3_10 - indio_dev = iio_device_alloc(sizeof(*st)); -#else - indio_dev = iio_allocate_device(sizeof(*st)); -#endif - if (indio_dev == NULL) { - pr_err("memory allocation failed\n"); - result = -ENOMEM; - goto out_no_free; - } - st = iio_priv(indio_dev); - spi_set_drvdata(spi, indio_dev); - if (spi->dev.of_node) { - result = of_inv_parse_platform_data(spi, &st->plat_data); - if (result) - goto out_free; - st->plat_data = mpu_data; - pr_info("secondary_i2c_addr=%x\n", st->plat_data.secondary_i2c_addr); - } else - st->plat_data = - *(struct mpu_platform_data *)dev_get_platdata(&spi->dev); - - /* Make state variables available to all _show and _store functions. */ - indio_dev->dev.parent = &spi->dev; - st->dev = &spi->dev; - st->irq = spi->irq; - st->i2c_dis = BIT_I2C_IF_DIS; - if (!strcmp(spi->modalias, "mpu6xxx")) - indio_dev->name = st->name; - else - indio_dev->name = spi->modalias; - - st->plat_read = inv_spi_read; - st->plat_single_write = inv_spi_single_write; - st->secondary_read = inv_spi_secondary_read; - st->secondary_write = inv_spi_secondary_write; - st->memory_read = mpu_spi_memory_read; - st->memory_write = mpu_spi_memory_write; - - /* power is turned on inside check chip type*/ - result = inv_check_chip_type(st, indio_dev->name); - if (result) - goto out_free; - - result = st->init_config(indio_dev); - if (result) { - dev_err(&spi->dev, - "Could not initialize device.\n"); - goto out_free; - } - result = st->set_power_state(st, false); - if (result) { - dev_err(&spi->dev, - "%s could not be turned off.\n", st->hw->name); - goto out_free; - } - - inv_set_iio_info(st, indio_dev); - - result = inv_mpu_configure_ring(indio_dev); - if (result) { - pr_err("configure ring buffer fail\n"); - goto out_free; - } - - result = inv_mpu_probe_trigger(indio_dev); - if (result) { - pr_err("trigger probe fail\n"); - goto out_unreg_ring; - } - - result = iio_device_register(indio_dev); - if (result) { - pr_err("IIO device register fail\n"); - goto out_remove_trigger; - } - - if (INV_MPU6050 == st->chip_type || - INV_MPU6500 == st->chip_type) { - result = inv_create_dmp_sysfs(indio_dev); - if (result) { - pr_err("create dmp sysfs failed\n"); - goto out_unreg_iio; - } - } - - INIT_KFIFO(st->timestamps); - spin_lock_init(&st->time_stamp_lock); - dev_info(&spi->dev, "%s is ready to go!\n", - indio_dev->name); - - return 0; -out_unreg_iio: - iio_device_unregister(indio_dev); -out_remove_trigger: - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - inv_mpu_remove_trigger(indio_dev); -out_unreg_ring: - inv_mpu_unconfigure_ring(indio_dev); -out_free: -#ifdef INV_KERNEL_3_10 - iio_device_free(indio_dev); -#else - iio_free_device(indio_dev); -#endif -out_no_free: - dev_err(&spi->dev, "%s failed %d\n", __func__, result); - - return -EIO; -} - -static void inv_mpu_shutdown(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - struct inv_reg_map_s *reg; - int result; - - reg = &st->reg; - dev_dbg(&spi->dev, "Shutting down %s...\n", st->hw->name); - - /* reset to make sure previous state are not there */ - result = inv_plat_single_write(st, reg->pwr_mgmt_1, BIT_H_RESET); - if (result) - dev_err(&spi->dev, "Failed to reset %s\n", - st->hw->name); - msleep(POWER_UP_TIME); - /* turn off power to ensure gyro engine is off */ - result = st->set_power_state(st, false); - if (result) - dev_err(&spi->dev, "Failed to turn off %s\n", - st->hw->name); -} - -/** - * inv_mpu_remove() - remove function. - */ -static int inv_mpu_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - kfifo_free(&st->timestamps); - iio_device_unregister(indio_dev); - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) - inv_mpu_remove_trigger(indio_dev); - inv_mpu_unconfigure_ring(indio_dev); -#ifdef INV_KERNEL_3_10 - iio_device_free(indio_dev); -#else - iio_free_device(indio_dev); -#endif - - dev_info(&spi->dev, "inv-mpu-iio module removed.\n"); - - return 0; -} - -#ifdef CONFIG_PM -static int __maybe_unused inv_mpu_resume(struct device *dev) -{ - struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev)); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result; - - pr_debug("%s inv_mpu_resume\n", st->hw->name); - - mutex_lock(&indio_dev->mlock); - if (st->support_hw_poweroff) { - /* reset to make sure previous state are not there */ - result = inv_plat_single_write(st, st->reg.pwr_mgmt_1, BIT_H_RESET); - if (result) { - pr_err("%s, reset failed\n", __func__); - goto rw_err; - } - msleep(POWER_UP_TIME); - /* toggle power state */ - result = st->set_power_state(st, false); - if (result) { - pr_err("%s, set_power_state false failed\n", __func__); - goto rw_err; - } - result = st->set_power_state(st, true); - if (result) { - pr_err("%s, set_power_state true failed\n", __func__); - goto rw_err; - } - result = inv_plat_single_write(st, st->reg.user_ctrl, st->i2c_dis); - if (result) { - pr_err("%s, set user_ctrl failed\n", __func__); - goto rw_err; - } - inv_resume_recover_setting(st); - } else { - result = st->set_power_state(st, true); - } - -rw_err: - mutex_unlock(&indio_dev->mlock); - return result; -} - -static int __maybe_unused inv_mpu_suspend(struct device *dev) -{ - struct iio_dev *indio_dev = spi_get_drvdata(to_spi_device(dev)); - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - int result = 0; - - pr_debug("%s inv_mpu_suspend\n", st->hw->name); - - mutex_lock(&indio_dev->mlock); - if ((!st->chip_config.dmp_on) || - (!st->chip_config.enable) || - (!st->chip_config.dmp_event_int_on)) - result = st->set_power_state(st, false); - mutex_unlock(&indio_dev->mlock); - - return result; -} -static const struct dev_pm_ops inv_mpu_pmops = { - SET_SYSTEM_SLEEP_PM_OPS(inv_mpu_suspend, inv_mpu_resume) -}; -#define INV_MPU_PMOPS (&inv_mpu_pmops) -#else -#define INV_MPU_PMOPS NULL -#endif /* CONFIG_PM */ - -/* device id table is used to identify what device can be - * supported by this driver - */ -static const struct spi_device_id inv_mpu_id[] = { - {"itg3500", INV_ITG3500}, - {"mpu3050", INV_MPU3050}, - {"mpu6050", INV_MPU6050}, - {"mpu9150", INV_MPU9150}, - {"mpu6500", INV_MPU6500}, - {"mpu9250", INV_MPU9250}, - {"mpu6xxx", INV_MPU6XXX}, - {"mpu6515", INV_MPU6515}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, inv_mpu_id); - -static const struct of_device_id inv_mpu_of_match[] = { - { .compatible = "inv-spi,itg3500", }, - { .compatible = "inv-spi,mpu3050", }, - { .compatible = "inv-spi,mpu6050", }, - { .compatible = "inv-spi,mpu9150", }, - { .compatible = "inv-spi,mpu6500", }, - { .compatible = "inv-spi,mpu9250", }, - { .compatible = "inv-spi,mpu6xxx", }, - { .compatible = "inv-spi,mpu9350", }, - { .compatible = "inv-spi,mpu6515", }, - {} -}; - -MODULE_DEVICE_TABLE(of, inv_mpu_of_match); - -static struct spi_driver inv_mpu_driver_spi = { - .driver = { - .owner = THIS_MODULE, - .name = "inv_mpu_iio_spi", - .pm = INV_MPU_PMOPS, - .of_match_table = of_match_ptr(inv_mpu_of_match), - }, - .probe = inv_mpu_probe, - .remove = inv_mpu_remove, - .id_table = inv_mpu_id, - .shutdown = inv_mpu_shutdown, -}; - -static int __init inv_mpu_init(void) -{ - int result = spi_register_driver(&inv_mpu_driver_spi); - - if (result) { - pr_err("failed\n"); - return result; - } - return 0; -} - -static void __exit inv_mpu_exit(void) -{ - spi_unregister_driver(&inv_mpu_driver_spi); -} - -module_init(inv_mpu_init); -module_exit(inv_mpu_exit); - -MODULE_AUTHOR("Invensense Corporation"); -MODULE_DESCRIPTION("Invensense device driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("inv-mpu-iio-spi"); - -/** - * @} - */ diff --git a/drivers/staging/iio/imu/inv_mpu/inv_mpu_trigger.c b/drivers/staging/iio/imu/inv_mpu/inv_mpu_trigger.c deleted file mode 100644 index 1c577097a773..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_mpu_trigger.c +++ /dev/null @@ -1,120 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_mpu_trigger.c - * @brief A sysfs device driver for Invensense devices - * @details This file is part of inv mpu iio driver code - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef INV_KERNEL_3_10 -#include -#include -#include -#else -#include "iio.h" -#include "sysfs.h" -#include "trigger.h" -#endif - -#include "inv_mpu_iio.h" - -/** - * inv_mpu_data_rdy_trigger_set_state() set data ready interrupt state - **/ -static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ -/* - --yd struct iio_dev *indio_dev = trig->private_data; - - --yd dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); -*/ - return 0; -} - -static const struct iio_trigger_ops inv_mpu_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &inv_mpu_data_rdy_trigger_set_state, -}; - -int inv_mpu_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct inv_mpu_iio_s *st = iio_priv(indio_dev); -#ifdef INV_KERNEL_3_10 - st->trig = iio_trigger_alloc("%s-dev%d", -#else - st->trig = iio_allocate_trigger("%s-dev%d", -#endif - indio_dev->name, - indio_dev->id); - if (st->trig == NULL) - return -ENOMEM; - st->trig->dev.parent = st->dev; -#ifdef INV_KERNEL_3_10 - iio_trigger_set_drvdata(st->trig, indio_dev); -#else - st->trig->private_data = indio_dev; -#endif - st->trig->ops = &inv_mpu_trigger_ops; - ret = iio_trigger_register(st->trig); - - if (ret) { -#ifdef INV_KERNEL_3_10 - iio_trigger_free(st->trig); -#else - iio_free_trigger(st->trig); -#endif - return -EPERM; - } - indio_dev->trig = st->trig; - - return 0; -} - -void inv_mpu_remove_trigger(struct iio_dev *indio_dev) -{ - struct inv_mpu_iio_s *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); -#ifdef INV_KERNEL_3_10 - iio_trigger_free(st->trig); -#else - iio_free_trigger(st->trig); -#endif -} -/** - * @} - */ - diff --git a/drivers/staging/iio/imu/inv_mpu/inv_slave_bma250.c b/drivers/staging/iio/imu/inv_mpu/inv_slave_bma250.c deleted file mode 100644 index 1452f9c0b5d1..000000000000 --- a/drivers/staging/iio/imu/inv_mpu/inv_slave_bma250.c +++ /dev/null @@ -1,330 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -* -*/ - -/** - * @addtogroup DRIVERS - * @brief Hardware drivers. - * - * @{ - * @file inv_slave_bma250.c - * @brief A sysfs device driver for Invensense devices - * @details This file is part of invensense mpu driver code - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "inv_mpu_iio.h" -#define BMA250_CHIP_ID 3 -#define BMA250_RANGE_SET 0 -#define BMA250_BW_SET 4 - -/* range and bandwidth */ -#define BMA250_RANGE_2G 3 -#define BMA250_RANGE_4G 5 -#define BMA250_RANGE_8G 8 -#define BMA250_RANGE_16G 12 -#define BMA250_RANGE_MAX 4 -#define BMA250_RANGE_MASK 0xF0 - -#define BMA250_BW_7_81HZ 0x08 -#define BMA250_BW_15_63HZ 0x09 -#define BMA250_BW_31_25HZ 0x0A -#define BMA250_BW_62_50HZ 0x0B -#define BMA250_BW_125HZ 0x0C -#define BMA250_BW_250HZ 0x0D -#define BMA250_BW_500HZ 0x0E -#define BMA250_BW_1000HZ 0x0F -#define BMA250_MAX_BW_SIZE 8 -#define BMA250_BW_REG_MASK 0xE0 - -/* register definitions */ -#define BMA250_X_AXIS_LSB_REG 0x02 -#define BMA250_RANGE_SEL_REG 0x0F -#define BMA250_BW_SEL_REG 0x10 -#define BMA250_MODE_CTRL_REG 0x11 - -/* mode settings */ -#define BMA250_MODE_NORMAL 0 -#define BMA250_MODE_LOWPOWER 1 -#define BMA250_MODE_SUSPEND 2 -#define BMA250_MODE_MAX 3 -#define BMA250_MODE_MASK 0x3F -#define BMA250_BIT_SUSPEND 0x80 -#define BMA250_BIT_LP 0x40 - -struct bma_property { - int range; - int bandwidth; - int mode; -}; - -static struct bma_property bma_static_property = { - .range = BMA250_RANGE_SET, - .bandwidth = BMA250_BW_SET, - .mode = BMA250_MODE_SUSPEND -}; - -static int bma250_set_bandwidth(struct inv_mpu_iio_s *st, u8 bw) -{ - int res; - u8 data; - int bandwidth; - switch (bw) { - case 0: - bandwidth = BMA250_BW_7_81HZ; - break; - case 1: - bandwidth = BMA250_BW_15_63HZ; - break; - case 2: - bandwidth = BMA250_BW_31_25HZ; - break; - case 3: - bandwidth = BMA250_BW_62_50HZ; - break; - case 4: - bandwidth = BMA250_BW_125HZ; - break; - case 5: - bandwidth = BMA250_BW_250HZ; - break; - case 6: - bandwidth = BMA250_BW_500HZ; - break; - case 7: - bandwidth = BMA250_BW_1000HZ; - break; - default: - return -EINVAL; - } - res = inv_secondary_read(BMA250_BW_SEL_REG, 1, &data); - if (res) - return res; - data &= BMA250_BW_REG_MASK; - data |= bandwidth; - res = inv_secondary_write(st, BMA250_BW_SEL_REG, data); - return res; -} - -static int bma250_set_range(struct inv_mpu_iio_s *st, u8 range) -{ - int res; - u8 orig, data; - switch (range) { - case 0: - data = BMA250_RANGE_2G; - break; - case 1: - data = BMA250_RANGE_4G; - break; - case 2: - data = BMA250_RANGE_8G; - break; - case 3: - data = BMA250_RANGE_16G; - break; - default: - return -EINVAL; - } - res = inv_secondary_read(BMA250_RANGE_SEL_REG, 1, &orig); - if (res) - return res; - orig &= BMA250_RANGE_MASK; - data |= orig; - res = inv_secondary_write(st, BMA250_RANGE_SEL_REG, data); - if (res) - return res; - bma_static_property.range = range; - - return 0; -} - -static int setup_slave_bma250(struct inv_mpu_iio_s *st) -{ - int result; - u8 data[2]; - result = set_3050_bypass(st, true); - if (result) - return result; - /*read secondary i2c ID register */ - result = inv_secondary_read(0, 1, data); - if (result) - return result; - if (BMA250_CHIP_ID != data[0]) - return -EINVAL; - result = set_3050_bypass(st, false); - if (result) - return result; - /*AUX(accel), slave address is set inside set_3050_bypass*/ - /* bma250 x axis LSB register address is 2 */ - result = inv_plat_single_write(st, REG_3050_AUX_BST_ADDR, - BMA250_X_AXIS_LSB_REG); - - return result; -} - -static int bma250_set_mode(struct inv_mpu_iio_s *st, u8 mode) -{ - int res; - u8 data; - - res = inv_secondary_read(BMA250_MODE_CTRL_REG, 1, &data); - if (res) - return res; - data &= BMA250_MODE_MASK; - switch (mode) { - case BMA250_MODE_NORMAL: - break; - case BMA250_MODE_LOWPOWER: - data |= BMA250_BIT_LP; - break; - case BMA250_MODE_SUSPEND: - data |= BMA250_BIT_SUSPEND; - break; - default: - return -EINVAL; - } - res = inv_secondary_write(st, BMA250_MODE_CTRL_REG, data); - if (res) - return res; - bma_static_property.mode = mode; - - return 0; -} - -static int suspend_slave_bma250(struct inv_mpu_iio_s *st) -{ - int result; - if (bma_static_property.mode == BMA250_MODE_SUSPEND) - return 0; - /*set to bypass mode */ - result = set_3050_bypass(st, true); - if (result) - return result; - bma250_set_mode(st, BMA250_MODE_SUSPEND); - /* no need to recover to non-bypass mode because we need it now */ - - return 0; -} - -static int resume_slave_bma250(struct inv_mpu_iio_s *st) -{ - int result; - if (bma_static_property.mode == BMA250_MODE_NORMAL) - return 0; - /*set to bypass mode */ - result = set_3050_bypass(st, true); - if (result) - return result; - result = bma250_set_mode(st, BMA250_MODE_NORMAL); - /* recover bypass mode */ - result |= set_3050_bypass(st, false); - - return result ? (-EINVAL) : 0; -} - -static int combine_data_slave_bma250(u8 *in, short *out) -{ - out[0] = le16_to_cpup((__le16 *)(&in[0])); - out[1] = le16_to_cpup((__le16 *)(&in[2])); - out[2] = le16_to_cpup((__le16 *)(&in[4])); - - return 0; -} - -static int get_mode_slave_bma250(void) -{ - switch (bma_static_property.mode) { - case BMA250_MODE_SUSPEND: - return INV_MODE_SUSPEND; - case BMA250_MODE_NORMAL: - return INV_MODE_NORMAL; - default: - return -EINVAL; - } -} - -/** - * set_lpf_bma250() - set lpf value - */ - -static int set_lpf_bma250(struct inv_mpu_iio_s *st, int rate) -{ - const short hz[] = {1000, 500, 250, 125, 62, 31, 15, 7}; - const int d[] = {7, 6, 5, 4, 3, 2, 1, 0}; - int i, h, data, result; - h = (rate >> 1); - i = 0; - while ((h < hz[i]) && (i < ARRAY_SIZE(hz) - 1)) - i++; - data = d[i]; - - result = set_3050_bypass(st, true); - if (result) - return result; - result = bma250_set_bandwidth(st, (u8) data); - result |= set_3050_bypass(st, false); - - return result ? (-EINVAL) : 0; -} -/** - * set_fs_bma250() - set range value - */ - -static int set_fs_bma250(struct inv_mpu_iio_s *st, int fs) -{ - int result; - result = set_3050_bypass(st, true); - if (result) - return result; - result = bma250_set_range(st, (u8) fs); - result |= set_3050_bypass(st, false); - - return result ? (-EINVAL) : 0; -} - -static struct inv_mpu_slave slave_bma250 = { - .suspend = suspend_slave_bma250, - .resume = resume_slave_bma250, - .setup = setup_slave_bma250, - .combine_data = combine_data_slave_bma250, - .get_mode = get_mode_slave_bma250, - .set_lpf = set_lpf_bma250, - .set_fs = set_fs_bma250 -}; - -int inv_register_mpu3050_slave(struct inv_mpu_iio_s *st) -{ - st->mpu_slave = &slave_bma250; - - return 0; -} -/** - * @} - */ - diff --git a/include/linux/mpu.h b/include/linux/mpu.h deleted file mode 100755 index f47496239366..000000000000 --- a/include/linux/mpu.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -* Copyright (C) 2012 Invensense, Inc. -* -* This software is licensed under the terms of the GNU General Public -* License version 2, as published by the Free Software Foundation, and -* may be copied, distributed, and modified under those terms. -* -* 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. -*/ - -#ifndef __MPU_H_ -#define __MPU_H_ - -#ifdef __KERNEL__ -#include -#include -#endif - -enum secondary_slave_type { - SECONDARY_SLAVE_TYPE_NONE, - SECONDARY_SLAVE_TYPE_ACCEL, - SECONDARY_SLAVE_TYPE_COMPASS, - SECONDARY_SLAVE_TYPE_PRESSURE, - SECONDARY_SLAVE_TYPE_ALS, - - SECONDARY_SLAVE_TYPE_TYPES -}; - -enum ext_slave_id { - ID_INVALID = 0, - GYRO_ID_MPU3050, - GYRO_ID_MPU6050A2, - GYRO_ID_MPU6050B1, - GYRO_ID_MPU6050B1_NO_ACCEL, - GYRO_ID_ITG3500, - - ACCEL_ID_LIS331, - ACCEL_ID_LSM303DLX, - ACCEL_ID_LIS3DH, - ACCEL_ID_KXSD9, - ACCEL_ID_KXTF9, - ACCEL_ID_BMA150, - ACCEL_ID_BMA222, - ACCEL_ID_BMA250, - ACCEL_ID_ADXL34X, - ACCEL_ID_MMA8450, - ACCEL_ID_MMA845X, - ACCEL_ID_MPU6050, - - COMPASS_ID_AK8963, - COMPASS_ID_AK8975, - COMPASS_ID_AK8972, - COMPASS_ID_AMI30X, - COMPASS_ID_AMI306, - COMPASS_ID_YAS529, - COMPASS_ID_YAS530, - COMPASS_ID_HMC5883, - COMPASS_ID_LSM303DLH, - COMPASS_ID_LSM303DLM, - COMPASS_ID_MMC314X, - COMPASS_ID_HSCDTD002B, - COMPASS_ID_HSCDTD004A, - COMPASS_ID_MLX90399, - COMPASS_ID_AK09911, - COMPASS_ID_AK09912, - COMPASS_ID_ST480M, - - PRESSURE_ID_BMP085, - PRESSURE_ID_BMP280, - - ALS_ID_APDS_9900, - ALS_ID_APDS_9930, -}; - -#define INV_PROD_KEY(ver, rev) (ver * 100 + rev) -/** - * struct mpu_platform_data - Platform data for the mpu driver - * @int_config: Bits [7:3] of the int config register. - * @level_shifter: 0: VLogic, 1: VDD - * @orientation: Orientation matrix of the gyroscope - * @sec_slave_type: secondary slave device type, can be compass, accel, etc - * @sec_slave_id: id of the secondary slave device - * @secondary_i2c_address: secondary device's i2c address - * @secondary_orientation: secondary device's orientation matrix - * @aux_slave_type: auxiliary slave. Another slave device type - * @aux_slave_id: auxiliary slave ID. - * @aux_i2c_addr: auxiliary device I2C address. - * @read_only_slave_type: read only slave type. - * @read_only_slave_id: read only slave device ID. - * @read_only_i2c_addr: read only slave device address. - * - * 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 mpu_platform_data { - __u8 int_config; - __u8 level_shifter; - __s8 orientation[9]; - enum secondary_slave_type sec_slave_type; - enum ext_slave_id sec_slave_id; - __u16 secondary_i2c_addr; - __s8 secondary_orientation[9]; - enum secondary_slave_type aux_slave_type; - enum ext_slave_id aux_slave_id; - __u16 aux_i2c_addr; - enum secondary_slave_type read_only_slave_type; - enum ext_slave_id read_only_slave_id; - __u16 read_only_i2c_addr; -#ifdef CONFIG_DTS_INV_MPU_IIO - int (*power_on)(struct mpu_platform_data *); - int (*power_off)(struct mpu_platform_data *); - struct regulator *vdd_ana; - struct regulator *vdd_i2c; -#endif -}; - -#endif /* __MPU_H_ */