blob: 8b45d904e8b385827237f5bdbc7ca3a961a0be39 [file] [log] [blame]
/*
* Copyright (C) 2012-2018 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) "inv_mpu: " fmt
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include "inv_mpu_iio.h"
#include "inv_mpu_dts.h"
#define CONFIG_DYNAMIC_DEBUG_I2C 0
/**
* inv_i2c_read_base() - Read one or more bytes from the device registers.
* @st: Device driver instance.
* @i2c_addr: i2c address of device.
* @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.
*/
int inv_i2c_read_base(struct inv_mpu_state *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 = &reg;
msgs[0].len = 1;
msgs[1].addr = i2c_addr;
msgs[1].flags = I2C_M_RD;
msgs[1].buf = data;
msgs[1].len = length;
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);
return res;
}
/**
* inv_i2c_single_write_base() - Write a byte to a device register.
* @st: Device driver instance.
* @i2c_addr: I2C address of the device.
* @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.
*/
int inv_i2c_single_write_base(struct inv_mpu_state *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;
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_state *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_state *st, u8 reg, int len, u8 *data)
{
return inv_i2c_read_base(st, st->i2c_addr, reg, len, data);
}
static int _memory_write(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
u32 len, u8 const *data)
{
u8 bank[2];
u8 addr[2];
u8 buf[513];
struct i2c_msg msgs[3];
int res;
if (!data || !st)
return -EINVAL;
if (len >= (sizeof(buf) - 1))
return -ENOMEM;
bank[0] = REG_MEM_BANK_SEL;
bank[1] = mem_addr >> 8;
addr[0] = REG_MEM_START_ADDR;
addr[1] = mem_addr & 0xFF;
buf[0] = REG_MEM_R_W;
memcpy(buf + 1, data, len);
/* write message */
msgs[0].addr = mpu_addr;
msgs[0].flags = 0;
msgs[0].buf = bank;
msgs[0].len = sizeof(bank);
msgs[1].addr = mpu_addr;
msgs[1].flags = 0;
msgs[1].buf = addr;
msgs[1].len = sizeof(addr);
msgs[2].addr = mpu_addr;
msgs[2].flags = 0;
msgs[2].buf = (u8 *) buf;
msgs[2].len = len + 1;
INV_I2C_INC_MPUWRITE(3 + 3 + (2 + len));
#if CONFIG_DYNAMIC_DEBUG_I2C
{
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
res = i2c_transfer(st->sl_handle, msgs, 3);
if (res != 3) {
if (res >= 0)
res = -EIO;
return res;
} else {
return 0;
}
}
static int inv_i2c_mem_write(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
u32 len, u8 const *data)
{
int r, i, j;
#define DMP_MEM_CMP_SIZE 16
u8 w[DMP_MEM_CMP_SIZE];
bool retry;
j = 0;
retry = true;
while ((j < 3) && retry) {
retry = false;
r = _memory_write(st, mpu_addr, mem_addr, len, data);
if (len < DMP_MEM_CMP_SIZE) {
r = mem_r(mem_addr, len, w);
for (i = 0; i < len; i++) {
if (data[i] != w[i]) {
pr_debug
("error write=%x, len=%d,data=%x, w=%x, i=%d\n",
mem_addr, len, data[i], w[i], i);
retry = true;
}
}
}
j++;
}
return r;
}
static int inv_i2c_mem_read(struct inv_mpu_state *st, u8 mpu_addr, u16 mem_addr,
u32 len, u8 *data)
{
u8 bank[2];
u8 addr[2];
u8 buf;
struct i2c_msg msgs[4];
int res;
if (!data || !st)
return -EINVAL;
bank[0] = REG_MEM_BANK_SEL;
bank[1] = mem_addr >> 8;
addr[0] = REG_MEM_START_ADDR;
addr[1] = mem_addr & 0xFF;
buf = REG_MEM_R_W;
/* write message */
msgs[0].addr = mpu_addr;
msgs[0].flags = 0;
msgs[0].buf = bank;
msgs[0].len = sizeof(bank);
msgs[1].addr = mpu_addr;
msgs[1].flags = 0;
msgs[1].buf = addr;
msgs[1].len = sizeof(addr);
msgs[2].addr = mpu_addr;
msgs[2].flags = 0;
msgs[2].buf = &buf;
msgs[2].len = 1;
msgs[3].addr = mpu_addr;
msgs[3].flags = I2C_M_RD;
msgs[3].buf = data;
msgs[3].len = len;
res = i2c_transfer(st->sl_handle, msgs, 4);
if (res != 4) {
if (res >= 0)
res = -EIO;
} else
res = 0;
INV_I2C_INC_MPUWRITE(3 + 3 + 3);
INV_I2C_INC_MPUREAD(len);
#if CONFIG_DYNAMIC_DEBUG_I2C
{
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 res;
}
#ifdef CONFIG_ENABLE_IAM_ACC_GYRO_BUFFERING
static void inv_enable_acc_gyro(struct inv_mpu_state *st)
{
struct iio_dev *indio_dev = iio_priv_to_dev(st);
int accel_hz = 100;
int gyro_hz = 100;
/**Enable the ACCEL**/
st->sensor_l[SENSOR_L_ACCEL].on = 0;
st->trigger_state = RATE_TRIGGER;
inv_check_sensor_on(st);
set_inv_enable(indio_dev);
inv_switch_power_in_lp(st, true);
st->chip_config.accel_fs = ACCEL_FSR_2G;
inv_set_accel_sf(st);
st->trigger_state = MISC_TRIGGER;
set_inv_enable(indio_dev);
st->sensor_l[SENSOR_L_ACCEL].rate = accel_hz;
st->trigger_state = DATA_TRIGGER;
inv_check_sensor_on(st);
set_inv_enable(indio_dev);
st->sensor_l[SENSOR_L_ACCEL].on = 1;
st->trigger_state = RATE_TRIGGER;
inv_check_sensor_on(st);
set_inv_enable(indio_dev);
/**Enable the GYRO**/
st->sensor_l[SENSOR_L_GYRO].on = 0;
st->trigger_state = RATE_TRIGGER;
inv_check_sensor_on(st);
set_inv_enable(indio_dev);
inv_switch_power_in_lp(st, true);
st->chip_config.fsr = GYRO_FSR_250DPS;
inv_set_gyro_sf(st);
st->trigger_state = MISC_TRIGGER;
set_inv_enable(indio_dev);
st->sensor_l[SENSOR_L_GYRO].rate = gyro_hz;
st->trigger_state = DATA_TRIGGER;
inv_check_sensor_on(st);
set_inv_enable(indio_dev);
st->sensor_l[SENSOR_L_GYRO].on = 1;
st->trigger_state = RATE_TRIGGER;
inv_check_sensor_on(st);
set_inv_enable(indio_dev);
}
static int inv_acc_gyro_early_buff_init(struct iio_dev *indio_dev)
{
int i = 0, err = 0;
struct inv_mpu_state *st;
st = iio_priv(indio_dev);
st->acc_bufsample_cnt = 0;
st->gyro_bufsample_cnt = 0;
st->report_evt_cnt = 5;
st->max_buffer_time = 40;
st->inv_acc_cachepool = kmem_cache_create("acc_sensor_sample",
sizeof(struct inv_acc_sample),
0,
SLAB_HWCACHE_ALIGN, NULL);
if (!st->inv_acc_cachepool) {
pr_err("inv_acc_cachepool cache create failed\n");
err = -ENOMEM;
return 0;
}
for (i = 0; i < INV_ACC_MAXSAMPLE; i++) {
st->inv_acc_samplist[i] =
kmem_cache_alloc(st->inv_acc_cachepool,
GFP_KERNEL);
if (!st->inv_acc_samplist[i]) {
err = -ENOMEM;
goto clean_exit1;
}
}
st->inv_gyro_cachepool = kmem_cache_create("gyro_sensor_sample"
, sizeof(struct inv_gyro_sample), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!st->inv_gyro_cachepool) {
pr_err("inv_gyro_cachepool cache create failed\n");
err = -ENOMEM;
goto clean_exit1;
}
for (i = 0; i < INV_GYRO_MAXSAMPLE; i++) {
st->inv_gyro_samplist[i] =
kmem_cache_alloc(st->inv_gyro_cachepool,
GFP_KERNEL);
if (!st->inv_gyro_samplist[i]) {
err = -ENOMEM;
goto clean_exit2;
}
}
st->accbuf_dev = input_allocate_device();
if (!st->accbuf_dev) {
err = -ENOMEM;
pr_err("input device allocation failed\n");
goto clean_exit2;
}
st->accbuf_dev->name = "inv_accbuf";
st->accbuf_dev->id.bustype = BUS_I2C;
input_set_events_per_packet(st->accbuf_dev,
st->report_evt_cnt * INV_ACC_MAXSAMPLE);
set_bit(EV_ABS, st->accbuf_dev->evbit);
input_set_abs_params(st->accbuf_dev, ABS_X,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->accbuf_dev, ABS_Y,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->accbuf_dev, ABS_Z,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->accbuf_dev, ABS_RX,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->accbuf_dev, ABS_RY,
-G_MAX, G_MAX, 0, 0);
err = input_register_device(st->accbuf_dev);
if (err) {
pr_err("unable to register input device %s\n",
st->accbuf_dev->name);
goto clean_exit3;
}
st->gyrobuf_dev = input_allocate_device();
if (!st->gyrobuf_dev) {
err = -ENOMEM;
pr_err("input device allocation failed\n");
goto clean_exit4;
}
st->gyrobuf_dev->name = "inv_gyrobuf";
st->gyrobuf_dev->id.bustype = BUS_I2C;
input_set_events_per_packet(st->gyrobuf_dev,
st->report_evt_cnt * INV_GYRO_MAXSAMPLE);
set_bit(EV_ABS, st->gyrobuf_dev->evbit);
input_set_abs_params(st->gyrobuf_dev, ABS_X,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->gyrobuf_dev, ABS_Y,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->gyrobuf_dev, ABS_Z,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->gyrobuf_dev, ABS_RX,
-G_MAX, G_MAX, 0, 0);
input_set_abs_params(st->gyrobuf_dev, ABS_RY,
-G_MAX, G_MAX, 0, 0);
err = input_register_device(st->gyrobuf_dev);
if (err) {
pr_err("unable to register input device %s\n",
st->gyrobuf_dev->name);
goto clean_exit5;
}
st->acc_buffer_inv_samples = true;
st->gyro_buffer_inv_samples = true;
mutex_init(&st->acc_sensor_buff);
mutex_init(&st->gyro_sensor_buff);
inv_enable_acc_gyro(st);
return 1;
clean_exit5:
input_free_device(st->gyrobuf_dev);
clean_exit4:
input_unregister_device(st->accbuf_dev);
clean_exit3:
input_free_device(st->accbuf_dev);
clean_exit2:
for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
kmem_cache_free(st->inv_gyro_cachepool,
st->inv_gyro_samplist[i]);
kmem_cache_destroy(st->inv_gyro_cachepool);
clean_exit1:
for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
kmem_cache_free(st->inv_acc_cachepool,
st->inv_acc_samplist[i]);
kmem_cache_destroy(st->inv_acc_cachepool);
return 0;
}
static void inv_acc_gyro_input_cleanup(
struct iio_dev *indio_dev)
{
int i = 0;
struct inv_mpu_state *st;
st = iio_priv(indio_dev);
input_free_device(st->accbuf_dev);
input_unregister_device(st->gyrobuf_dev);
input_free_device(st->gyrobuf_dev);
for (i = 0; i < INV_GYRO_MAXSAMPLE; i++)
kmem_cache_free(st->inv_gyro_cachepool,
st->inv_gyro_samplist[i]);
kmem_cache_destroy(st->inv_gyro_cachepool);
for (i = 0; i < INV_ACC_MAXSAMPLE; i++)
kmem_cache_free(st->inv_acc_cachepool,
st->inv_acc_samplist[i]);
kmem_cache_destroy(st->inv_acc_cachepool);
}
#else
static int inv_acc_gyro_early_buff_init(struct iio_dev *indio_dev)
{
return 1;
}
static void inv_acc_gyro_input_cleanup(
struct iio_dev *indio_dev)
{
}
#endif
/*
* inv_mpu_probe() - probe function.
*/
static int inv_mpu_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct inv_mpu_state *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 KERNEL_VERSION_4_X
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (indio_dev == NULL) {
pr_err("memory allocation failed\n");
result = -ENOMEM;
goto out_no_free;
}
#else
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
pr_err("memory allocation failed\n");
result = -ENOMEM;
goto out_no_free;
}
#endif
st = iio_priv(indio_dev);
st->client = client;
st->sl_handle = client->adapter;
st->i2c_addr = client->addr;
st->write = inv_i2c_single_write;
st->read = inv_i2c_read;
st->mem_write = inv_i2c_mem_write;
st->mem_read = inv_i2c_mem_read;
st->dev = &client->dev;
st->bus_type = BUS_IIO_I2C;
#ifdef CONFIG_OF
result = invensense_mpu_parse_dt(st->dev, &st->plat_data);
if (result)
# ifdef KERNEL_VERSION_4_X
return -ENODEV;
# else
goto out_free;
# endif
/* Power on device */
if (st->plat_data.power_on) {
result = st->plat_data.power_on(&st->plat_data);
if (result < 0) {
dev_err(st->dev, "power_on failed: %d\n", result);
# ifdef KERNEL_VERSION_4_X
return -ENODEV;
# else
goto out_free;
# endif
}
pr_info("%s: power on here.\n", __func__);
}
pr_info("%s: power on.\n", __func__);
msleep(100);
#else
if (dev_get_platdata(st->dev) == NULL)
# ifdef KERNEL_VERSION_4_X
return -ENODEV;
# else
goto out_free;
# endif
st->plat_data = *(struct mpu_platform_data *)dev_get_platdata(st->dev);
#endif
/* power is turned on inside check chip type */
result = inv_check_chip_type(indio_dev, id->name);
if (result)
#ifdef KERNEL_VERSION_4_X
return -ENODEV;
#else
goto out_free;
#endif
/* Make state variables available to all _show and _store functions. */
i2c_set_clientdata(client, indio_dev);
indio_dev->dev.parent = st->dev;
indio_dev->name = id->name;
st->irq = client->irq;
result = inv_mpu_configure_ring(indio_dev);
if (result) {
pr_err("configure ring buffer fail\n");
goto out_free;
}
#ifdef KERNEL_VERSION_4_X
INV_I2C_SETIRQ(IRQ_MPU, st->irq);
result = devm_iio_device_register(st->dev, indio_dev);
if (result) {
pr_err("IIO device register fail\n");
goto out_unreg_ring;
}
#else
result = iio_buffer_register(indio_dev, indio_dev->channels,
indio_dev->num_channels);
if (result) {
pr_err("ring buffer register fail\n");
goto out_unreg_ring;
}
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_ring;
}
#endif
result = inv_create_dmp_sysfs(indio_dev);
if (result) {
pr_err("create dmp sysfs failed\n");
goto out_unreg_iio;
}
init_waitqueue_head(&st->wait_queue);
st->resume_state = true;
#ifdef CONFIG_HAS_WAKELOCK
wake_lock_init(&st->wake_lock, WAKE_LOCK_SUSPEND, "inv_mpu");
#else
wakeup_source_init(&st->wake_lock, "inv_mpu");
#endif
dev_info(st->dev, "%s ma-kernel-%s is ready to go!\n",
indio_dev->name, INVENSENSE_DRIVER_VERSION);
#ifdef SENSOR_DATA_FROM_REGISTERS
pr_info("Data read from registers\n");
#else
pr_info("Data read from FIFO\n");
#endif
#ifdef TIMER_BASED_BATCHING
pr_info("Timer based batching\n");
#endif
result = inv_acc_gyro_early_buff_init(indio_dev);
if (!result)
return -EIO;
return 0;
#ifdef KERNEL_VERSION_4_X
out_unreg_iio:
devm_iio_device_unregister(st->dev, indio_dev);
out_unreg_ring:
inv_mpu_unconfigure_ring(indio_dev);
out_free:
devm_iio_device_free(st->dev, indio_dev);
out_no_free:
#else
out_unreg_iio:
iio_device_unregister(indio_dev);
out_remove_ring:
iio_buffer_unregister(indio_dev);
out_unreg_ring:
inv_mpu_unconfigure_ring(indio_dev);
out_free:
dev_err(st->dev, "%s failed %d\n", __func__, result);
iio_device_free(indio_dev);
out_no_free:
#endif
return -EIO;
}
static void inv_mpu_shutdown(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct inv_mpu_state *st = iio_priv(indio_dev);
int result;
mutex_lock(&indio_dev->mlock);
inv_switch_power_in_lp(st, true);
dev_dbg(st->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(st->dev, "Failed to reset %s\n",
st->hw->name);
msleep(POWER_UP_TIME);
/* turn off power to ensure gyro engine is off */
result = inv_set_power(st, false);
if (result)
dev_err(st->dev, "Failed to turn off %s\n",
st->hw->name);
inv_switch_power_in_lp(st, false);
mutex_unlock(&indio_dev->mlock);
}
/*
* 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_state *st = iio_priv(indio_dev);
inv_acc_gyro_input_cleanup(indio_dev);
#ifdef KERNEL_VERSION_4_X
devm_iio_device_unregister(st->dev, indio_dev);
#else
iio_device_unregister(indio_dev);
iio_buffer_unregister(indio_dev);
#endif
inv_mpu_unconfigure_ring(indio_dev);
#ifdef KERNEL_VERSION_4_X
devm_iio_device_free(st->dev, indio_dev);
#else
iio_device_free(indio_dev);
#endif
dev_info(st->dev, "inv-mpu-iio module removed.\n");
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int inv_mpu_i2c_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
return inv_mpu_suspend(indio_dev);
}
static void inv_mpu_i2c_complete(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
inv_mpu_complete(indio_dev);
}
#endif
static const struct dev_pm_ops inv_mpu_i2c_pmops = {
#ifdef CONFIG_PM_SLEEP
.suspend = inv_mpu_i2c_suspend,
.complete = inv_mpu_i2c_complete,
#endif
};
/* device id table is used to identify what device can be
* supported by this driver
*/
static const struct i2c_device_id inv_mpu_id[] = {
#ifdef CONFIG_INV_MPU_IIO_ICM20648
{"icm20645", ICM20645},
{"icm10340", ICM10340},
{"icm20648", ICM20648},
#else
{"icm20608d", ICM20608D},
{"icm20690", ICM20690},
{"icm20602", ICM20602},
{"iam20680", IAM20680},
#endif
{}
};
MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
static struct i2c_driver inv_mpu_driver = {
.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-i2c",
.pm = &inv_mpu_i2c_pmops,
},
};
module_i2c_driver(inv_mpu_driver);
MODULE_AUTHOR("Invensense Corporation");
MODULE_DESCRIPTION("Invensense I2C device driver");
MODULE_LICENSE("GPL");