* [PATCH v1 0/4] iio: imu: inv_mpu6050: Split driver into core and I2C/SPI functionality
@ 2016-02-02 15:02 Adriana Reus
2016-02-02 15:02 ` [PATCH v1 1/4] iio: imu: inv-mpu6050: Fix interrupt pin configuration Adriana Reus
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Adriana Reus @ 2016-02-02 15:02 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, srinivas.pandruvada, ggao, Adriana Reus
This series splits this driver into general and I2C/SPI specific funtionality.
functionality.
The first patch is a fix for a bug in the interrupt pin configuration.
The second patch changes all the I2C specific calls into regmap calls.
The third patch separated the remaining I2C specific part into a different component.
Finally the fourth patch adds SPI support for the MPU6000 chip.
Since the initial version there have been minor changes according to the
comments received.
Adriana Reus (4):
iio: imu: inv-mpu6050: Fix interrupt pin configuration
iio: imu: inv_mpu6050: Use regmap instead of i2c specific functions
iio: imu: inv_mpu6050: Separate driver into core and i2c
functionality.
iio: imu: inv_mpu6050: Add SPI support for MPU6000
drivers/iio/imu/inv_mpu6050/Kconfig | 21 ++-
drivers/iio/imu/inv_mpu6050/Makefile | 8 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 14 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 253 +++++---------------------
drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 207 +++++++++++++++++++++
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 13 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 35 ++--
drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 ++++++++
drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 10 +-
9 files changed, 402 insertions(+), 239 deletions(-)
create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
--
1.9.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v1 1/4] iio: imu: inv-mpu6050: Fix interrupt pin configuration
2016-02-02 15:02 [PATCH v1 0/4] iio: imu: inv_mpu6050: Split driver into core and I2C/SPI functionality Adriana Reus
@ 2016-02-02 15:02 ` Adriana Reus
2016-02-02 15:02 ` [PATCH v1 2/4] iio: imu: inv_mpu6050: Use regmap instead of i2c specific functions Adriana Reus
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Adriana Reus @ 2016-02-02 15:02 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, srinivas.pandruvada, ggao, Adriana Reus
The select/deselect_bypass duo writes the irq number into the interrupt
configuration register.
If there is a i2c slave device connected to the mpu (eg. a magnetometer)
then this can hinder interrupt delivery for the accelerometer and
gyroscope.
Set this register to the default configuration.
Signed-off-by: Adriana Reus <adriana.reus@intel.com>
---
* No change since the previous submitted version
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 4 ++--
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 0852b7f..1121f4e 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -129,7 +129,7 @@ static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv,
if (!ret) {
st->powerup_count++;
ret = inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
- st->client->irq |
+ INV_MPU6050_INT_PIN_CFG |
INV_MPU6050_BIT_BYPASS_EN);
}
write_error:
@@ -147,7 +147,7 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
mutex_lock(&indio_dev->mlock);
/* It doesn't really mattter, if any of the calls fails */
inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
- st->client->irq);
+ INV_MPU6050_INT_PIN_CFG);
st->powerup_count--;
if (!st->powerup_count)
inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index db0a4a2..455b99d 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -185,6 +185,7 @@ struct inv_mpu6050_state {
#define INV_MPU6050_REG_INT_PIN_CFG 0x37
#define INV_MPU6050_BIT_BYPASS_EN 0x2
+#define INV_MPU6050_INT_PIN_CFG 0
/* init parameters */
#define INV_MPU6050_INIT_FIFO_RATE 50
--
1.9.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v1 2/4] iio: imu: inv_mpu6050: Use regmap instead of i2c specific functions
2016-02-02 15:02 [PATCH v1 0/4] iio: imu: inv_mpu6050: Split driver into core and I2C/SPI functionality Adriana Reus
2016-02-02 15:02 ` [PATCH v1 1/4] iio: imu: inv-mpu6050: Fix interrupt pin configuration Adriana Reus
@ 2016-02-02 15:02 ` Adriana Reus
2016-02-02 15:02 ` [PATCH v1 3/4] iio: imu: inv_mpu6050: Separate driver into core and i2c functionality Adriana Reus
2016-02-02 15:02 ` [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000 Adriana Reus
3 siblings, 0 replies; 12+ messages in thread
From: Adriana Reus @ 2016-02-02 15:02 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, srinivas.pandruvada, ggao, Adriana Reus
Use regmap instead of i2c specific functions.
This is in preparation of splitting this driver into core and
i2c specific functionality.
Signed-off-by: Adriana Reus <adriana.reus@intel.com>
---
* No change since the initial submitted version for this patch either
drivers/iio/imu/inv_mpu6050/Kconfig | 1 +
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 71 ++++++++++++++-------------
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 2 +
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 30 ++++++-----
drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 6 +--
5 files changed, 57 insertions(+), 53 deletions(-)
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index 48fbc0b..f301f3a 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -8,6 +8,7 @@ config INV_MPU6050_IIO
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select I2C_MUX
+ select REGMAP_I2C
help
This driver supports the Invensense MPU6050 devices.
This driver can also support MPU6500 in MPU6050 compatibility mode
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 1121f4e..151a378 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -27,6 +27,11 @@
#include <linux/acpi.h>
#include "inv_mpu_iio.h"
+static const struct regmap_config inv_mpu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
/*
* this is the gyro scale translated from dynamic range plus/minus
* {250, 500, 1000, 2000} to rad/s
@@ -75,11 +80,6 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = {
},
};
-int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d)
-{
- return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d);
-}
-
/*
* The i2c read/write needs to happen in unlocked mode. As the parent
* adapter is common. If we use locked versions, it will fail as
@@ -159,16 +159,15 @@ static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
{
- u8 d, mgmt_1;
+ unsigned int d, mgmt_1;
int result;
/* 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 (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) {
- result = i2c_smbus_read_i2c_block_data(st->client,
- st->reg->pwr_mgmt_1, 1, &mgmt_1);
- if (result != 1)
+ result = regmap_read(st->map, st->reg->pwr_mgmt_1, &mgmt_1);
+ if (result)
return result;
mgmt_1 &= ~INV_MPU6050_BIT_CLK_MASK;
@@ -178,20 +177,19 @@ int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
/* turning off gyro requires switch to internal clock first.
Then turn off gyro engine */
mgmt_1 |= INV_CLK_INTERNAL;
- result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, mgmt_1);
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1, mgmt_1);
if (result)
return result;
}
- result = i2c_smbus_read_i2c_block_data(st->client,
- st->reg->pwr_mgmt_2, 1, &d);
- if (result != 1)
+ result = regmap_read(st->map, st->reg->pwr_mgmt_2, &d);
+ if (result)
return result;
if (en)
d &= ~mask;
else
d |= mask;
- result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_2, d);
+ result = regmap_write(st->map, st->reg->pwr_mgmt_2, d);
if (result)
return result;
@@ -201,7 +199,7 @@ int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
if (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) {
/* switch internal clock to PLL */
mgmt_1 |= INV_CLK_PLL;
- result = inv_mpu6050_write_reg(st,
+ result = regmap_write(st->map,
st->reg->pwr_mgmt_1, mgmt_1);
if (result)
return result;
@@ -218,15 +216,14 @@ int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
if (power_on) {
/* Already under indio-dev->mlock mutex */
if (!st->powerup_count)
- result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
- 0);
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
if (!result)
st->powerup_count++;
} else {
st->powerup_count--;
if (!st->powerup_count)
- result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
- INV_MPU6050_BIT_SLEEP);
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1,
+ INV_MPU6050_BIT_SLEEP);
}
if (result)
@@ -257,22 +254,22 @@ static int inv_mpu6050_init_config(struct iio_dev *indio_dev)
if (result)
return result;
d = (INV_MPU6050_FSR_2000DPS << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
- result = inv_mpu6050_write_reg(st, st->reg->gyro_config, d);
+ result = regmap_write(st->map, st->reg->gyro_config, d);
if (result)
return result;
d = INV_MPU6050_FILTER_20HZ;
- result = inv_mpu6050_write_reg(st, st->reg->lpf, d);
+ result = regmap_write(st->map, st->reg->lpf, d);
if (result)
return result;
d = INV_MPU6050_ONE_K_HZ / INV_MPU6050_INIT_FIFO_RATE - 1;
- result = inv_mpu6050_write_reg(st, st->reg->sample_rate_div, d);
+ result = regmap_write(st->map, st->reg->sample_rate_div, d);
if (result)
return result;
d = (INV_MPU6050_FS_02G << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
- result = inv_mpu6050_write_reg(st, st->reg->accl_config, d);
+ result = regmap_write(st->map, st->reg->accl_config, d);
if (result)
return result;
@@ -290,9 +287,8 @@ static int inv_mpu6050_sensor_show(struct inv_mpu6050_state *st, int reg,
__be16 d;
ind = (axis - IIO_MOD_X) * 2;
- result = i2c_smbus_read_i2c_block_data(st->client, reg + ind, 2,
- (u8 *)&d);
- if (result != 2)
+ result = regmap_bulk_read(st->map, reg + ind, (u8 *)&d, 2);
+ if (result)
return -EINVAL;
*val = (short)be16_to_cpup(&d);
@@ -418,8 +414,7 @@ static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val)
for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) {
if (gyro_scale_6050[i] == val) {
d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT);
- result = inv_mpu6050_write_reg(st,
- st->reg->gyro_config, d);
+ result = regmap_write(st->map, st->reg->gyro_config, d);
if (result)
return result;
@@ -456,8 +451,7 @@ static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val)
for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) {
if (accel_scale[i] == val) {
d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT);
- result = inv_mpu6050_write_reg(st,
- st->reg->accl_config, d);
+ result = regmap_write(st->map, st->reg->accl_config, d);
if (result)
return result;
@@ -537,7 +531,7 @@ static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate)
while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1))
i++;
data = d[i];
- result = inv_mpu6050_write_reg(st, st->reg->lpf, data);
+ result = regmap_write(st->map, st->reg->lpf, data);
if (result)
return result;
st->chip_config.lpf = data;
@@ -575,7 +569,7 @@ static ssize_t inv_mpu6050_fifo_rate_store(struct device *dev,
goto fifo_rate_fail;
d = INV_MPU6050_ONE_K_HZ / fifo_rate - 1;
- result = inv_mpu6050_write_reg(st, st->reg->sample_rate_div, d);
+ result = regmap_write(st->map, st->reg->sample_rate_div, d);
if (result)
goto fifo_rate_fail;
st->chip_config.fifo_rate = fifo_rate;
@@ -736,8 +730,8 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
st->reg = hw_info[st->chip_type].reg;
/* reset to make sure previous state are not there */
- result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
- INV_MPU6050_BIT_H_RESET);
+ result = regmap_write(st->map, st->reg->pwr_mgmt_1,
+ INV_MPU6050_BIT_H_RESET);
if (result)
return result;
msleep(INV_MPU6050_POWER_UP_TIME);
@@ -778,11 +772,19 @@ static int inv_mpu_probe(struct i2c_client *client,
struct iio_dev *indio_dev;
struct inv_mpu6050_platform_data *pdata;
int result;
+ struct regmap *regmap;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENOSYS;
+ regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "Failed to register i2c regmap %d\n",
+ (int)PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -790,6 +792,7 @@ static int inv_mpu_probe(struct i2c_client *client,
st = iio_priv(indio_dev);
st->client = client;
st->powerup_count = 0;
+ st->map = regmap;
pdata = dev_get_platdata(&client->dev);
if (pdata)
st->plat_data = *pdata;
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index 455b99d..469cd1f 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -15,6 +15,7 @@
#include <linux/spinlock.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
+#include <linux/regmap.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger.h>
@@ -125,6 +126,7 @@ struct inv_mpu6050_state {
unsigned int powerup_count;
struct inv_mpu6050_platform_data plat_data;
DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
+ struct regmap *map;
};
/*register and associated bit definition*/
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
index ba27e27..eb19dae 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
@@ -13,7 +13,6 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
@@ -41,22 +40,22 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
struct inv_mpu6050_state *st = iio_priv(indio_dev);
/* disable interrupt */
- result = inv_mpu6050_write_reg(st, st->reg->int_enable, 0);
+ result = regmap_write(st->map, st->reg->int_enable, 0);
if (result) {
dev_err(&st->client->dev, "int_enable failed %d\n", result);
return result;
}
/* disable the sensor output to FIFO */
- result = inv_mpu6050_write_reg(st, st->reg->fifo_en, 0);
+ result = regmap_write(st->map, st->reg->fifo_en, 0);
if (result)
goto reset_fifo_fail;
/* disable fifo reading */
- result = inv_mpu6050_write_reg(st, st->reg->user_ctrl, 0);
+ result = regmap_write(st->map, st->reg->user_ctrl, 0);
if (result)
goto reset_fifo_fail;
/* reset FIFO*/
- result = inv_mpu6050_write_reg(st, st->reg->user_ctrl,
+ result = regmap_write(st->map, st->reg->user_ctrl,
INV_MPU6050_BIT_FIFO_RST);
if (result)
goto reset_fifo_fail;
@@ -67,13 +66,13 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
/* enable interrupt */
if (st->chip_config.accl_fifo_enable ||
st->chip_config.gyro_fifo_enable) {
- result = inv_mpu6050_write_reg(st, st->reg->int_enable,
+ result = regmap_write(st->map, st->reg->int_enable,
INV_MPU6050_BIT_DATA_RDY_EN);
if (result)
return result;
}
/* enable FIFO reading and I2C master interface*/
- result = inv_mpu6050_write_reg(st, st->reg->user_ctrl,
+ result = regmap_write(st->map, st->reg->user_ctrl,
INV_MPU6050_BIT_FIFO_EN);
if (result)
goto reset_fifo_fail;
@@ -83,7 +82,7 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
d |= INV_MPU6050_BITS_GYRO_OUT;
if (st->chip_config.accl_fifo_enable)
d |= INV_MPU6050_BIT_ACCEL_OUT;
- result = inv_mpu6050_write_reg(st, st->reg->fifo_en, d);
+ result = regmap_write(st->map, st->reg->fifo_en, d);
if (result)
goto reset_fifo_fail;
@@ -91,7 +90,7 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
reset_fifo_fail:
dev_err(&st->client->dev, "reset fifo failed %d\n", result);
- result = inv_mpu6050_write_reg(st, st->reg->int_enable,
+ result = regmap_write(st->map, st->reg->int_enable,
INV_MPU6050_BIT_DATA_RDY_EN);
return result;
@@ -143,10 +142,10 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
* read fifo_count register to know how many bytes inside FIFO
* right now
*/
- result = i2c_smbus_read_i2c_block_data(st->client,
+ result = regmap_bulk_read(st->map,
st->reg->fifo_count_h,
- INV_MPU6050_FIFO_COUNT_BYTE, data);
- if (result != INV_MPU6050_FIFO_COUNT_BYTE)
+ data, INV_MPU6050_FIFO_COUNT_BYTE);
+ if (result)
goto end_session;
fifo_count = be16_to_cpup((__be16 *)(&data[0]));
if (fifo_count < bytes_per_datum)
@@ -161,10 +160,9 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
goto flush_fifo;
while (fifo_count >= bytes_per_datum) {
- result = i2c_smbus_read_i2c_block_data(st->client,
- st->reg->fifo_r_w,
- bytes_per_datum, data);
- if (result != bytes_per_datum)
+ result = regmap_bulk_read(st->map, st->reg->fifo_r_w,
+ data, bytes_per_datum);
+ if (result)
goto flush_fifo;
result = kfifo_out(&st->timestamps, ×tamp, 1);
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index 844610c..ee9e66d 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -65,15 +65,15 @@ static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
if (result)
return result;
} else {
- result = inv_mpu6050_write_reg(st, st->reg->fifo_en, 0);
+ result = regmap_write(st->map, st->reg->fifo_en, 0);
if (result)
return result;
- result = inv_mpu6050_write_reg(st, st->reg->int_enable, 0);
+ result = regmap_write(st->map, st->reg->int_enable, 0);
if (result)
return result;
- result = inv_mpu6050_write_reg(st, st->reg->user_ctrl, 0);
+ result = regmap_write(st->map, st->reg->user_ctrl, 0);
if (result)
return result;
--
1.9.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v1 3/4] iio: imu: inv_mpu6050: Separate driver into core and i2c functionality.
2016-02-02 15:02 [PATCH v1 0/4] iio: imu: inv_mpu6050: Split driver into core and I2C/SPI functionality Adriana Reus
2016-02-02 15:02 ` [PATCH v1 1/4] iio: imu: inv-mpu6050: Fix interrupt pin configuration Adriana Reus
2016-02-02 15:02 ` [PATCH v1 2/4] iio: imu: inv_mpu6050: Use regmap instead of i2c specific functions Adriana Reus
@ 2016-02-02 15:02 ` Adriana Reus
2016-02-02 15:02 ` [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000 Adriana Reus
3 siblings, 0 replies; 12+ messages in thread
From: Adriana Reus @ 2016-02-02 15:02 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, srinivas.pandruvada, ggao, Adriana Reus
Separate this driver into core and i2c functionality.
This is in preparation for adding spi support.
Signed-off-by: Adriana Reus <adriana.reus@intel.com>
---
Changes since initial version:
* Modified Kconfig in order to make the i2c driver select the core component
instead of the other way around.
* Minor change: removed a cast to (char*) in core probe as it was not needed.
* In write_reg_unlocked - initialize the buffer at declaration as suggested
* Retrieve dev from regmap_get_device instead of having a separate copy
of the pointer.
drivers/iio/imu/inv_mpu6050/Kconfig | 15 +-
drivers/iio/imu/inv_mpu6050/Makefile | 5 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c | 14 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 208 ++++----------------------
drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 207 +++++++++++++++++++++++++
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 9 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 5 +-
drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 4 +-
8 files changed, 267 insertions(+), 200 deletions(-)
create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index f301f3a..483f52d 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -4,11 +4,9 @@
config INV_MPU6050_IIO
tristate "Invensense MPU6050 devices"
- depends on I2C && SYSFS
+ depends on SYSFS
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
- select I2C_MUX
- select REGMAP_I2C
help
This driver supports the Invensense MPU6050 devices.
This driver can also support MPU6500 in MPU6050 compatibility mode
@@ -16,3 +14,14 @@ config INV_MPU6050_IIO
It is a gyroscope/accelerometer combo device.
This driver can be built as a module. The module will be called
inv-mpu6050.
+
+config INV_MPU6050_I2C
+ tristate "Invensense MPU6050 devices"
+ depends on I2C
+ select INV_MPU6050_IIO
+ select I2C_MUX
+ select REGMAP_I2C
+ help
+ This driver can be built as a module. The module will be called
+ inv-mpu6050-i2c.
+
diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
index f566f6a..ca4941d 100644
--- a/drivers/iio/imu/inv_mpu6050/Makefile
+++ b/drivers/iio/imu/inv_mpu6050/Makefile
@@ -3,4 +3,7 @@
#
obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o
-inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o inv_mpu_acpi.o
+inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
+
+obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
+inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
index 1c982a5..36d7067 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
@@ -139,22 +139,23 @@ static int inv_mpu_process_acpi_config(struct i2c_client *client,
return 0;
}
-int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
+int inv_mpu_acpi_create_mux_client(struct i2c_client *client)
{
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
st->mux_client = NULL;
- if (ACPI_HANDLE(&st->client->dev)) {
+ if (ACPI_HANDLE(&client->dev)) {
struct i2c_board_info info;
struct acpi_device *adev;
int ret = -1;
- adev = ACPI_COMPANION(&st->client->dev);
+ adev = ACPI_COMPANION(&client->dev);
memset(&info, 0, sizeof(info));
dmi_check_system(inv_mpu_dev_list);
switch (matched_product_name) {
case INV_MPU_ASUS_T100TA:
- ret = asus_acpi_get_sensor_info(adev, st->client,
+ ret = asus_acpi_get_sensor_info(adev, client,
&info);
break;
/* Add more matched product processing here */
@@ -166,7 +167,7 @@ int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
/* No matching DMI, so create device on INV6XX type */
unsigned short primary, secondary;
- ret = inv_mpu_process_acpi_config(st->client, &primary,
+ ret = inv_mpu_process_acpi_config(client, &primary,
&secondary);
if (!ret && secondary) {
char *name;
@@ -191,8 +192,9 @@ int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
return 0;
}
-void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st)
+void inv_mpu_acpi_delete_mux_client(struct i2c_client *client)
{
+ struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev));
if (st->mux_client)
i2c_unregister_device(st->mux_client);
}
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 151a378..7b46db5 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -27,11 +27,6 @@
#include <linux/acpi.h>
#include "inv_mpu_iio.h"
-static const struct regmap_config inv_mpu_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
-};
-
/*
* this is the gyro scale translated from dynamic range plus/minus
* {250, 500, 1000, 2000} to rad/s
@@ -80,83 +75,6 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = {
},
};
-/*
- * The i2c read/write needs to happen in unlocked mode. As the parent
- * adapter is common. If we use locked versions, it will fail as
- * the mux adapter will lock the parent i2c adapter, while calling
- * select/deselect functions.
- */
-static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st,
- u8 reg, u8 d)
-{
- int ret;
- u8 buf[2];
- struct i2c_msg msg[1] = {
- {
- .addr = st->client->addr,
- .flags = 0,
- .len = sizeof(buf),
- .buf = buf,
- }
- };
-
- buf[0] = reg;
- buf[1] = d;
- ret = __i2c_transfer(st->client->adapter, msg, 1);
- if (ret != 1)
- return ret;
-
- return 0;
-}
-
-static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv,
- u32 chan_id)
-{
- struct iio_dev *indio_dev = mux_priv;
- struct inv_mpu6050_state *st = iio_priv(indio_dev);
- int ret = 0;
-
- /* Use the same mutex which was used everywhere to protect power-op */
- mutex_lock(&indio_dev->mlock);
- if (!st->powerup_count) {
- ret = inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
- 0);
- if (ret)
- goto write_error;
-
- msleep(INV_MPU6050_REG_UP_TIME);
- }
- if (!ret) {
- st->powerup_count++;
- ret = inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
- INV_MPU6050_INT_PIN_CFG |
- INV_MPU6050_BIT_BYPASS_EN);
- }
-write_error:
- mutex_unlock(&indio_dev->mlock);
-
- return ret;
-}
-
-static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
- void *mux_priv, u32 chan_id)
-{
- struct iio_dev *indio_dev = mux_priv;
- struct inv_mpu6050_state *st = iio_priv(indio_dev);
-
- mutex_lock(&indio_dev->mlock);
- /* It doesn't really mattter, if any of the calls fails */
- inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
- INV_MPU6050_INT_PIN_CFG);
- st->powerup_count--;
- if (!st->powerup_count)
- inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
- INV_MPU6050_BIT_SLEEP);
- mutex_unlock(&indio_dev->mlock);
-
- return 0;
-}
-
int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
{
unsigned int d, mgmt_1;
@@ -758,42 +676,23 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st)
return 0;
}
-/**
- * inv_mpu_probe() - probe function.
- * @client: i2c client.
- * @id: i2c device id.
- *
- * Returns 0 on success, a negative error code otherwise.
- */
-static int inv_mpu_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name)
{
struct inv_mpu6050_state *st;
struct iio_dev *indio_dev;
struct inv_mpu6050_platform_data *pdata;
+ struct device *dev = regmap_get_device(regmap);
int result;
- struct regmap *regmap;
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_I2C_BLOCK))
- return -ENOSYS;
-
- regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&client->dev, "Failed to register i2c regmap %d\n",
- (int)PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
-
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->client = client;
st->powerup_count = 0;
+ st->irq = irq;
st->map = regmap;
- pdata = dev_get_platdata(&client->dev);
+ pdata = dev_get_platdata(dev);
if (pdata)
st->plat_data = *pdata;
/* power is turned on inside check chip type*/
@@ -803,18 +702,17 @@ static int inv_mpu_probe(struct i2c_client *client,
result = inv_mpu6050_init_config(indio_dev);
if (result) {
- dev_err(&client->dev,
- "Could not initialize device.\n");
+ dev_err(dev, "Could not initialize device.\n");
return result;
}
- i2c_set_clientdata(client, indio_dev);
- indio_dev->dev.parent = &client->dev;
- /* id will be NULL when enumerated via ACPI */
- if (id)
- indio_dev->name = (char *)id->name;
+ dev_set_drvdata(dev, indio_dev);
+ indio_dev->dev.parent = dev;
+ /* name will be NULL when enumerated via ACPI */
+ if (name)
+ indio_dev->name = name;
else
- indio_dev->name = (char *)dev_name(&client->dev);
+ indio_dev->name = dev_name(dev);
indio_dev->channels = inv_mpu_channels;
indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels);
@@ -826,13 +724,12 @@ static int inv_mpu_probe(struct i2c_client *client,
inv_mpu6050_read_fifo,
NULL);
if (result) {
- dev_err(&st->client->dev, "configure buffer fail %d\n",
- result);
+ dev_err(dev, "configure buffer fail %d\n", result);
return result;
}
result = inv_mpu6050_probe_trigger(indio_dev);
if (result) {
- dev_err(&st->client->dev, "trigger probe fail %d\n", result);
+ dev_err(dev, "trigger probe fail %d\n", result);
goto out_unreg_ring;
}
@@ -840,102 +737,47 @@ static int inv_mpu_probe(struct i2c_client *client,
spin_lock_init(&st->time_stamp_lock);
result = iio_device_register(indio_dev);
if (result) {
- dev_err(&st->client->dev, "IIO register fail %d\n", result);
+ dev_err(dev, "IIO register fail %d\n", result);
goto out_remove_trigger;
}
- st->mux_adapter = i2c_add_mux_adapter(client->adapter,
- &client->dev,
- indio_dev,
- 0, 0, 0,
- inv_mpu6050_select_bypass,
- inv_mpu6050_deselect_bypass);
- if (!st->mux_adapter) {
- result = -ENODEV;
- goto out_unreg_device;
- }
-
- result = inv_mpu_acpi_create_mux_client(st);
- if (result)
- goto out_del_mux;
-
return 0;
-out_del_mux:
- i2c_del_mux_adapter(st->mux_adapter);
-out_unreg_device:
- iio_device_unregister(indio_dev);
out_remove_trigger:
inv_mpu6050_remove_trigger(st);
out_unreg_ring:
iio_triggered_buffer_cleanup(indio_dev);
return result;
}
+EXPORT_SYMBOL_GPL(inv_mpu_core_probe);
-static int inv_mpu_remove(struct i2c_client *client)
+int inv_mpu_core_remove(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
- inv_mpu_acpi_delete_mux_client(st);
- i2c_del_mux_adapter(st->mux_adapter);
iio_device_unregister(indio_dev);
- inv_mpu6050_remove_trigger(st);
+ inv_mpu6050_remove_trigger(iio_priv(indio_dev));
iio_triggered_buffer_cleanup(indio_dev);
return 0;
}
+EXPORT_SYMBOL_GPL(inv_mpu_core_remove);
+
#ifdef CONFIG_PM_SLEEP
static int inv_mpu_resume(struct device *dev)
{
- return inv_mpu6050_set_power_itg(
- iio_priv(i2c_get_clientdata(to_i2c_client(dev))), true);
+ return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), true);
}
static int inv_mpu_suspend(struct device *dev)
{
- return inv_mpu6050_set_power_itg(
- iio_priv(i2c_get_clientdata(to_i2c_client(dev))), false);
+ return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), false);
}
-static SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
-
-#define INV_MPU6050_PMOPS (&inv_mpu_pmops)
-#else
-#define INV_MPU6050_PMOPS NULL
#endif /* CONFIG_PM_SLEEP */
-/*
- * device id table is used to identify what device can be
- * supported by this driver
- */
-static const struct i2c_device_id inv_mpu_id[] = {
- {"mpu6050", INV_MPU6050},
- {"mpu6500", INV_MPU6500},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
-
-static const struct acpi_device_id inv_acpi_match[] = {
- {"INVN6500", 0},
- { },
-};
-
-MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
-
-static struct i2c_driver inv_mpu_driver = {
- .probe = inv_mpu_probe,
- .remove = inv_mpu_remove,
- .id_table = inv_mpu_id,
- .driver = {
- .name = "inv-mpu6050",
- .pm = INV_MPU6050_PMOPS,
- .acpi_match_table = ACPI_PTR(inv_acpi_match),
- },
-};
-
-module_i2c_driver(inv_mpu_driver);
+SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume);
+EXPORT_SYMBOL_GPL(inv_mpu_pmops);
MODULE_AUTHOR("Invensense Corporation");
MODULE_DESCRIPTION("Invensense device MPU6050 driver");
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
new file mode 100644
index 0000000..6c225a0
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
@@ -0,0 +1,207 @@
+/*
+* 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.
+*/
+
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include "inv_mpu_iio.h"
+
+static const struct regmap_config inv_mpu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+/*
+ * The i2c read/write needs to happen in unlocked mode. As the parent
+ * adapter is common. If we use locked versions, it will fail as
+ * the mux adapter will lock the parent i2c adapter, while calling
+ * select/deselect functions.
+ */
+static int inv_mpu6050_write_reg_unlocked(struct i2c_client *client,
+ u8 reg, u8 d)
+{
+ int ret;
+ u8 buf[2] = {reg, d};
+ struct i2c_msg msg[1] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = sizeof(buf),
+ .buf = buf,
+ }
+ };
+
+ ret = __i2c_transfer(client->adapter, msg, 1);
+ if (ret != 1)
+ return ret;
+
+ return 0;
+}
+
+static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv,
+ u32 chan_id)
+{
+ struct i2c_client *client = mux_priv;
+ struct iio_dev *indio_dev = dev_get_drvdata(&client->dev);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ /* Use the same mutex which was used everywhere to protect power-op */
+ mutex_lock(&indio_dev->mlock);
+ if (!st->powerup_count) {
+ ret = inv_mpu6050_write_reg_unlocked(client,
+ st->reg->pwr_mgmt_1, 0);
+ if (ret)
+ goto write_error;
+
+ msleep(INV_MPU6050_REG_UP_TIME);
+ }
+ if (!ret) {
+ st->powerup_count++;
+ ret = inv_mpu6050_write_reg_unlocked(client,
+ st->reg->int_pin_cfg,
+ INV_MPU6050_INT_PIN_CFG |
+ INV_MPU6050_BIT_BYPASS_EN);
+ }
+write_error:
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret;
+}
+
+static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
+ void *mux_priv, u32 chan_id)
+{
+ struct i2c_client *client = mux_priv;
+ struct iio_dev *indio_dev = dev_get_drvdata(&client->dev);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ mutex_lock(&indio_dev->mlock);
+ /* It doesn't really mattter, if any of the calls fails */
+ inv_mpu6050_write_reg_unlocked(client, st->reg->int_pin_cfg,
+ INV_MPU6050_INT_PIN_CFG);
+ st->powerup_count--;
+ if (!st->powerup_count)
+ inv_mpu6050_write_reg_unlocked(client, st->reg->pwr_mgmt_1,
+ INV_MPU6050_BIT_SLEEP);
+ mutex_unlock(&indio_dev->mlock);
+
+ return 0;
+}
+
+/**
+ * inv_mpu_probe() - probe function.
+ * @client: i2c client.
+ * @id: i2c device id.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+static int inv_mpu_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct inv_mpu6050_state *st;
+ int result;
+ const char *name = id ? id->name : NULL;
+ struct regmap *regmap;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -ENOSYS;
+
+ regmap = devm_regmap_init_i2c(client, &inv_mpu_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "Failed to register i2c regmap %d\n",
+ (int)PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ result = inv_mpu_core_probe(regmap, client->irq, name);
+ if (result < 0)
+ return result;
+
+ st = iio_priv(dev_get_drvdata(&client->dev));
+ st->mux_adapter = i2c_add_mux_adapter(client->adapter,
+ &client->dev,
+ client,
+ 0, 0, 0,
+ inv_mpu6050_select_bypass,
+ inv_mpu6050_deselect_bypass);
+ if (!st->mux_adapter) {
+ result = -ENODEV;
+ goto out_unreg_device;
+ }
+
+ result = inv_mpu_acpi_create_mux_client(client);
+ if (result)
+ goto out_del_mux;
+
+ return 0;
+
+out_del_mux:
+ i2c_del_mux_adapter(st->mux_adapter);
+out_unreg_device:
+ inv_mpu_core_remove(&client->dev);
+ return result;
+}
+
+static int inv_mpu_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+ inv_mpu_acpi_delete_mux_client(client);
+ i2c_del_mux_adapter(st->mux_adapter);
+
+ return inv_mpu_core_remove(&client->dev);
+}
+
+/*
+ * device id table is used to identify what device can be
+ * supported by this driver
+ */
+static const struct i2c_device_id inv_mpu_id[] = {
+ {"mpu6050", INV_MPU6050},
+ {"mpu6500", INV_MPU6500},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
+
+static const struct acpi_device_id inv_acpi_match[] = {
+ {"INVN6500", 0},
+ { },
+};
+
+MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
+
+static struct i2c_driver inv_mpu_driver = {
+ .probe = inv_mpu_probe,
+ .remove = inv_mpu_remove,
+ .id_table = inv_mpu_id,
+ .driver = {
+ .owner = THIS_MODULE,
+ .acpi_match_table = ACPI_PTR(inv_acpi_match),
+ .name = "inv-mpu6050 i2c driver",
+ .pm = &inv_mpu_pmops,
+ },
+};
+
+module_i2c_driver(inv_mpu_driver);
+
+MODULE_AUTHOR("Invensense Corporation");
+MODULE_DESCRIPTION("Invensense device MPU6050 driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index 469cd1f..af406a3 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -120,13 +120,13 @@ struct inv_mpu6050_state {
const struct inv_mpu6050_hw *hw;
enum inv_devices chip_type;
spinlock_t time_stamp_lock;
- struct i2c_client *client;
struct i2c_adapter *mux_adapter;
struct i2c_client *mux_client;
unsigned int powerup_count;
struct inv_mpu6050_platform_data plat_data;
DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
struct regmap *map;
+ int irq;
};
/*register and associated bit definition*/
@@ -255,5 +255,8 @@ int inv_reset_fifo(struct iio_dev *indio_dev);
int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask);
int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
-int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st);
-void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st);
+int inv_mpu_acpi_create_mux_client(struct i2c_client *client);
+void inv_mpu_acpi_delete_mux_client(struct i2c_client *client);
+int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name);
+int inv_mpu_core_remove(struct device *dev);
+extern const struct dev_pm_ops inv_mpu_pmops;
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
index eb19dae..1fc5fd9 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
@@ -42,7 +42,8 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
/* disable interrupt */
result = regmap_write(st->map, st->reg->int_enable, 0);
if (result) {
- dev_err(&st->client->dev, "int_enable failed %d\n", result);
+ dev_err(regmap_get_device(st->map), "int_enable failed %d\n",
+ result);
return result;
}
/* disable the sensor output to FIFO */
@@ -89,7 +90,7 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
return 0;
reset_fifo_fail:
- dev_err(&st->client->dev, "reset fifo failed %d\n", result);
+ dev_err(regmap_get_device(st->map), "reset fifo failed %d\n", result);
result = regmap_write(st->map, st->reg->int_enable,
INV_MPU6050_BIT_DATA_RDY_EN);
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index ee9e66d..72d6aae 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -123,7 +123,7 @@ int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
if (!st->trig)
return -ENOMEM;
- ret = devm_request_irq(&indio_dev->dev, st->client->irq,
+ ret = devm_request_irq(&indio_dev->dev, st->irq,
&iio_trigger_generic_data_rdy_poll,
IRQF_TRIGGER_RISING,
"inv_mpu",
@@ -131,7 +131,7 @@ int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
if (ret)
return ret;
- st->trig->dev.parent = &st->client->dev;
+ st->trig->dev.parent = regmap_get_device(st->map);
st->trig->ops = &inv_mpu_trigger_ops;
iio_trigger_set_drvdata(st->trig, indio_dev);
--
1.9.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-02 15:02 [PATCH v1 0/4] iio: imu: inv_mpu6050: Split driver into core and I2C/SPI functionality Adriana Reus
` (2 preceding siblings ...)
2016-02-02 15:02 ` [PATCH v1 3/4] iio: imu: inv_mpu6050: Separate driver into core and i2c functionality Adriana Reus
@ 2016-02-02 15:02 ` Adriana Reus
2016-02-02 15:29 ` Crt Mori
2016-02-03 3:39 ` Lucas De Marchi
3 siblings, 2 replies; 12+ messages in thread
From: Adriana Reus @ 2016-02-02 15:02 UTC (permalink / raw)
To: jic23; +Cc: linux-iio, srinivas.pandruvada, ggao, Adriana Reus
The only difference between the MPU6000 and the
MPU6050 is that the first also supports SPI.
Add SPI driver for this chip.
Signed-off-by: Adriana Reus <adriana.reus@intel.com>
---
Changes since initial version:
* Modified Kconfig so that the SPI component selects the core component
instead of the other way around.
drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
4 files changed, 91 insertions(+)
create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index 483f52d..6f6a419 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -25,3 +25,10 @@ config INV_MPU6050_I2C
This driver can be built as a module. The module will be called
inv-mpu6050-i2c.
+config INV_MPU6050_SPI
+ tristate "Invensense MPU6050 devices"
+ select INV_MPU6050_IIO
+ select REGMAP_SPI
+ help
+ This driver can be built as a module. The module will be called
+ inv-mpu6050-spi.
diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
index ca4941d..734af5e 100644
--- a/drivers/iio/imu/inv_mpu6050/Makefile
+++ b/drivers/iio/imu/inv_mpu6050/Makefile
@@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
+
+obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
+inv-mpu6050-spi-objs := inv_mpu_spi.o
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index af406a3..758fe2b 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
enum inv_devices {
INV_MPU6050,
INV_MPU6500,
+ INV_MPU6000,
INV_NUM_PARTS
};
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
new file mode 100644
index 0000000..484171e
--- /dev/null
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
@@ -0,0 +1,80 @@
+/*
+* Copyright (C) 2015 Intel Corporation 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.
+*/
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/spi/spi.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include "inv_mpu_iio.h"
+
+static const struct regmap_config inv_mpu_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int inv_mpu_probe(struct spi_device *spi)
+{
+ struct regmap *regmap;
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ const char *name = id ? id->name : NULL;
+
+ regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
+ if (IS_ERR(regmap)) {
+ dev_err(&spi->dev, "Failed to register spi regmap %d\n",
+ (int)PTR_ERR(regmap));
+ return PTR_ERR(regmap);
+ }
+
+ return inv_mpu_core_probe(regmap, spi->irq, name);
+}
+
+static int inv_mpu_remove(struct spi_device *spi)
+{
+ return inv_mpu_core_remove(&spi->dev);
+}
+
+/*
+ * device id table is used to identify what device can be
+ * supported by this driver
+ */
+static const struct spi_device_id inv_mpu_id[] = {
+ {"mpu6050", INV_MPU6050},
+ {"mpu6000", INV_MPU6000},
+ {}
+};
+
+MODULE_DEVICE_TABLE(spi, inv_mpu_id);
+
+static const struct acpi_device_id inv_acpi_match[] = {
+ {"INVN6000", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
+
+static struct spi_driver inv_mpu_driver = {
+ .probe = inv_mpu_probe,
+ .remove = inv_mpu_remove,
+ .id_table = inv_mpu_id,
+ .driver = {
+ .owner = THIS_MODULE,
+ .acpi_match_table = ACPI_PTR(inv_acpi_match),
+ .name = "inv-mpu6050 spi driver",
+ .pm = &inv_mpu_pmops,
+ },
+};
+
+module_spi_driver(inv_mpu_driver);
+
+MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
+MODULE_DESCRIPTION("Invensense device MPU6050 driver");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-02 15:02 ` [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000 Adriana Reus
@ 2016-02-02 15:29 ` Crt Mori
2016-02-02 15:34 ` Crt Mori
2016-02-03 3:39 ` Lucas De Marchi
1 sibling, 1 reply; 12+ messages in thread
From: Crt Mori @ 2016-02-02 15:29 UTC (permalink / raw)
To: Adriana Reus; +Cc: Johnathan Iain Cameron, linux-iio, Srinivas Pandruvada, ggao
As far as I understand regmap, you do not need to add a separate file
like that - but you can combine them all together with just passing
i2c or spi device to them depending on the connection type (can be
linked to dt).
Is there a reason for this kind of change?
On 2 February 2016 at 16:02, Adriana Reus <adriana.reus@intel.com> wrote:
> The only difference between the MPU6000 and the
> MPU6050 is that the first also supports SPI.
> Add SPI driver for this chip.
>
> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
> ---
> Changes since initial version:
> * Modified Kconfig so that the SPI component selects the core component
> instead of the other way around.
>
> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
> 4 files changed, 91 insertions(+)
> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>
> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
> index 483f52d..6f6a419 100644
> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
> This driver can be built as a module. The module will be called
> inv-mpu6050-i2c.
>
> +config INV_MPU6050_SPI
> + tristate "Invensense MPU6050 devices"
> + select INV_MPU6050_IIO
> + select REGMAP_SPI
> + help
> + This driver can be built as a module. The module will be called
> + inv-mpu6050-spi.
> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
> index ca4941d..734af5e 100644
> --- a/drivers/iio/imu/inv_mpu6050/Makefile
> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
> @@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
>
> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
> inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
> +
> +obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
> +inv-mpu6050-spi-objs := inv_mpu_spi.o
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
> index af406a3..758fe2b 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
> enum inv_devices {
> INV_MPU6050,
> INV_MPU6500,
> + INV_MPU6000,
> INV_NUM_PARTS
> };
>
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> new file mode 100644
> index 0000000..484171e
> --- /dev/null
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> @@ -0,0 +1,80 @@
> +/*
> +* Copyright (C) 2015 Intel Corporation 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.
> +*/
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/spi/spi.h>
> +#include <linux/regmap.h>
> +#include <linux/iio/iio.h>
> +#include "inv_mpu_iio.h"
> +
> +static const struct regmap_config inv_mpu_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 8,
> +};
> +
> +static int inv_mpu_probe(struct spi_device *spi)
> +{
> + struct regmap *regmap;
> + const struct spi_device_id *id = spi_get_device_id(spi);
> + const char *name = id ? id->name : NULL;
> +
> + regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
> + if (IS_ERR(regmap)) {
> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
> + (int)PTR_ERR(regmap));
> + return PTR_ERR(regmap);
> + }
> +
> + return inv_mpu_core_probe(regmap, spi->irq, name);
> +}
> +
> +static int inv_mpu_remove(struct spi_device *spi)
> +{
> + return inv_mpu_core_remove(&spi->dev);
> +}
> +
> +/*
> + * device id table is used to identify what device can be
> + * supported by this driver
> + */
> +static const struct spi_device_id inv_mpu_id[] = {
> + {"mpu6050", INV_MPU6050},
> + {"mpu6000", INV_MPU6000},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(spi, inv_mpu_id);
> +
> +static const struct acpi_device_id inv_acpi_match[] = {
> + {"INVN6000", 0},
> + { },
> +};
> +MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
> +
> +static struct spi_driver inv_mpu_driver = {
> + .probe = inv_mpu_probe,
> + .remove = inv_mpu_remove,
> + .id_table = inv_mpu_id,
> + .driver = {
> + .owner = THIS_MODULE,
> + .acpi_match_table = ACPI_PTR(inv_acpi_match),
> + .name = "inv-mpu6050 spi driver",
> + .pm = &inv_mpu_pmops,
> + },
> +};
> +
> +module_spi_driver(inv_mpu_driver);
> +
> +MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
> +MODULE_DESCRIPTION("Invensense device MPU6050 driver");
> +MODULE_LICENSE("GPL");
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-02 15:29 ` Crt Mori
@ 2016-02-02 15:34 ` Crt Mori
2016-02-02 15:48 ` Adriana Reus
0 siblings, 1 reply; 12+ messages in thread
From: Crt Mori @ 2016-02-02 15:34 UTC (permalink / raw)
To: Adriana Reus; +Cc: Johnathan Iain Cameron, linux-iio, Srinivas Pandruvada, ggao
Nevermind, saw the trick with other patches (3/4) and I get the point.
You just split up the spi and i2c parts, but retained the rest.
On 2 February 2016 at 16:29, Crt Mori <cmo@melexis.com> wrote:
> As far as I understand regmap, you do not need to add a separate file
> like that - but you can combine them all together with just passing
> i2c or spi device to them depending on the connection type (can be
> linked to dt).
>
> Is there a reason for this kind of change?
>
>
> On 2 February 2016 at 16:02, Adriana Reus <adriana.reus@intel.com> wrote:
>> The only difference between the MPU6000 and the
>> MPU6050 is that the first also supports SPI.
>> Add SPI driver for this chip.
>>
>> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
>> ---
>> Changes since initial version:
>> * Modified Kconfig so that the SPI component selects the core component
>> instead of the other way around.
>>
>> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
>> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
>> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
>> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
>> 4 files changed, 91 insertions(+)
>> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>
>> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
>> index 483f52d..6f6a419 100644
>> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
>> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
>> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
>> This driver can be built as a module. The module will be called
>> inv-mpu6050-i2c.
>>
>> +config INV_MPU6050_SPI
>> + tristate "Invensense MPU6050 devices"
>> + select INV_MPU6050_IIO
>> + select REGMAP_SPI
>> + help
>> + This driver can be built as a module. The module will be called
>> + inv-mpu6050-spi.
>> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
>> index ca4941d..734af5e 100644
>> --- a/drivers/iio/imu/inv_mpu6050/Makefile
>> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
>> @@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
>>
>> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
>> inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
>> +
>> +obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
>> +inv-mpu6050-spi-objs := inv_mpu_spi.o
>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>> index af406a3..758fe2b 100644
>> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
>> enum inv_devices {
>> INV_MPU6050,
>> INV_MPU6500,
>> + INV_MPU6000,
>> INV_NUM_PARTS
>> };
>>
>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>> new file mode 100644
>> index 0000000..484171e
>> --- /dev/null
>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>> @@ -0,0 +1,80 @@
>> +/*
>> +* Copyright (C) 2015 Intel Corporation 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.
>> +*/
>> +#include <linux/module.h>
>> +#include <linux/acpi.h>
>> +#include <linux/spi/spi.h>
>> +#include <linux/regmap.h>
>> +#include <linux/iio/iio.h>
>> +#include "inv_mpu_iio.h"
>> +
>> +static const struct regmap_config inv_mpu_regmap_config = {
>> + .reg_bits = 8,
>> + .val_bits = 8,
>> +};
>> +
>> +static int inv_mpu_probe(struct spi_device *spi)
>> +{
>> + struct regmap *regmap;
>> + const struct spi_device_id *id = spi_get_device_id(spi);
>> + const char *name = id ? id->name : NULL;
>> +
>> + regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
>> + if (IS_ERR(regmap)) {
>> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
>> + (int)PTR_ERR(regmap));
>> + return PTR_ERR(regmap);
>> + }
>> +
>> + return inv_mpu_core_probe(regmap, spi->irq, name);
>> +}
>> +
>> +static int inv_mpu_remove(struct spi_device *spi)
>> +{
>> + return inv_mpu_core_remove(&spi->dev);
>> +}
>> +
>> +/*
>> + * device id table is used to identify what device can be
>> + * supported by this driver
>> + */
>> +static const struct spi_device_id inv_mpu_id[] = {
>> + {"mpu6050", INV_MPU6050},
>> + {"mpu6000", INV_MPU6000},
>> + {}
>> +};
>> +
>> +MODULE_DEVICE_TABLE(spi, inv_mpu_id);
>> +
>> +static const struct acpi_device_id inv_acpi_match[] = {
>> + {"INVN6000", 0},
>> + { },
>> +};
>> +MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
>> +
>> +static struct spi_driver inv_mpu_driver = {
>> + .probe = inv_mpu_probe,
>> + .remove = inv_mpu_remove,
>> + .id_table = inv_mpu_id,
>> + .driver = {
>> + .owner = THIS_MODULE,
>> + .acpi_match_table = ACPI_PTR(inv_acpi_match),
>> + .name = "inv-mpu6050 spi driver",
>> + .pm = &inv_mpu_pmops,
>> + },
>> +};
>> +
>> +module_spi_driver(inv_mpu_driver);
>> +
>> +MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
>> +MODULE_DESCRIPTION("Invensense device MPU6050 driver");
>> +MODULE_LICENSE("GPL");
>> --
>> 1.9.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-02 15:34 ` Crt Mori
@ 2016-02-02 15:48 ` Adriana Reus
0 siblings, 0 replies; 12+ messages in thread
From: Adriana Reus @ 2016-02-02 15:48 UTC (permalink / raw)
To: Crt Mori; +Cc: Johnathan Iain Cameron, linux-iio, Srinivas Pandruvada, ggao
Right, there's now going to be a common part, an i2c specific part and
an spi one.
On a different note I just saw that I did not delete the "mpu6050" from
the spi_device_id table - I'll do so in the next version.
On 02.02.2016 17:34, Crt Mori wrote:
> Nevermind, saw the trick with other patches (3/4) and I get the point.
> You just split up the spi and i2c parts, but retained the rest.
>
>
> On 2 February 2016 at 16:29, Crt Mori <cmo@melexis.com> wrote:
>> As far as I understand regmap, you do not need to add a separate file
>> like that - but you can combine them all together with just passing
>> i2c or spi device to them depending on the connection type (can be
>> linked to dt).
>>
>> Is there a reason for this kind of change?
>>
>>
>> On 2 February 2016 at 16:02, Adriana Reus <adriana.reus@intel.com> wrote:
>>> The only difference between the MPU6000 and the
>>> MPU6050 is that the first also supports SPI.
>>> Add SPI driver for this chip.
>>>
>>> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
>>> ---
>>> Changes since initial version:
>>> * Modified Kconfig so that the SPI component selects the core component
>>> instead of the other way around.
>>>
>>> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
>>> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
>>> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
>>> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
>>> 4 files changed, 91 insertions(+)
>>> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>>
>>> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
>>> index 483f52d..6f6a419 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
>>> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
>>> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
>>> This driver can be built as a module. The module will be called
>>> inv-mpu6050-i2c.
>>>
>>> +config INV_MPU6050_SPI
>>> + tristate "Invensense MPU6050 devices"
>>> + select INV_MPU6050_IIO
>>> + select REGMAP_SPI
>>> + help
>>> + This driver can be built as a module. The module will be called
>>> + inv-mpu6050-spi.
>>> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
>>> index ca4941d..734af5e 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/Makefile
>>> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
>>> @@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
>>>
>>> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
>>> inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
>>> +
>>> +obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
>>> +inv-mpu6050-spi-objs := inv_mpu_spi.o
>>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> index af406a3..758fe2b 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
>>> enum inv_devices {
>>> INV_MPU6050,
>>> INV_MPU6500,
>>> + INV_MPU6000,
>>> INV_NUM_PARTS
>>> };
>>>
>>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>> new file mode 100644
>>> index 0000000..484171e
>>> --- /dev/null
>>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>> @@ -0,0 +1,80 @@
>>> +/*
>>> +* Copyright (C) 2015 Intel Corporation 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.
>>> +*/
>>> +#include <linux/module.h>
>>> +#include <linux/acpi.h>
>>> +#include <linux/spi/spi.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/iio/iio.h>
>>> +#include "inv_mpu_iio.h"
>>> +
>>> +static const struct regmap_config inv_mpu_regmap_config = {
>>> + .reg_bits = 8,
>>> + .val_bits = 8,
>>> +};
>>> +
>>> +static int inv_mpu_probe(struct spi_device *spi)
>>> +{
>>> + struct regmap *regmap;
>>> + const struct spi_device_id *id = spi_get_device_id(spi);
>>> + const char *name = id ? id->name : NULL;
>>> +
>>> + regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
>>> + if (IS_ERR(regmap)) {
>>> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
>>> + (int)PTR_ERR(regmap));
>>> + return PTR_ERR(regmap);
>>> + }
>>> +
>>> + return inv_mpu_core_probe(regmap, spi->irq, name);
>>> +}
>>> +
>>> +static int inv_mpu_remove(struct spi_device *spi)
>>> +{
>>> + return inv_mpu_core_remove(&spi->dev);
>>> +}
>>> +
>>> +/*
>>> + * device id table is used to identify what device can be
>>> + * supported by this driver
>>> + */
>>> +static const struct spi_device_id inv_mpu_id[] = {
>>> + {"mpu6050", INV_MPU6050},
>>> + {"mpu6000", INV_MPU6000},
>>> + {}
>>> +};
>>> +
>>> +MODULE_DEVICE_TABLE(spi, inv_mpu_id);
>>> +
>>> +static const struct acpi_device_id inv_acpi_match[] = {
>>> + {"INVN6000", 0},
>>> + { },
>>> +};
>>> +MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
>>> +
>>> +static struct spi_driver inv_mpu_driver = {
>>> + .probe = inv_mpu_probe,
>>> + .remove = inv_mpu_remove,
>>> + .id_table = inv_mpu_id,
>>> + .driver = {
>>> + .owner = THIS_MODULE,
>>> + .acpi_match_table = ACPI_PTR(inv_acpi_match),
>>> + .name = "inv-mpu6050 spi driver",
>>> + .pm = &inv_mpu_pmops,
>>> + },
>>> +};
>>> +
>>> +module_spi_driver(inv_mpu_driver);
>>> +
>>> +MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
>>> +MODULE_DESCRIPTION("Invensense device MPU6050 driver");
>>> +MODULE_LICENSE("GPL");
>>> --
>>> 1.9.1
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-02 15:02 ` [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000 Adriana Reus
2016-02-02 15:29 ` Crt Mori
@ 2016-02-03 3:39 ` Lucas De Marchi
2016-02-03 6:42 ` Ge Gao
1 sibling, 1 reply; 12+ messages in thread
From: Lucas De Marchi @ 2016-02-03 3:39 UTC (permalink / raw)
To: Adriana Reus; +Cc: jic23, linux-iio, srinivas.pandruvada, ggao
Hi Adriana,
On Tue, Feb 2, 2016 at 1:02 PM, Adriana Reus <adriana.reus@intel.com> wrote:
> The only difference between the MPU6000 and the
> MPU6050 is that the first also supports SPI.
> Add SPI driver for this chip.
>
> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
> ---
> Changes since initial version:
> * Modified Kconfig so that the SPI component selects the core component
> instead of the other way around.
>
> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
> 4 files changed, 91 insertions(+)
> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>
> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
> index 483f52d..6f6a419 100644
> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
> This driver can be built as a module. The module will be called
> inv-mpu6050-i2c.
>
> +config INV_MPU6050_SPI
> + tristate "Invensense MPU6050 devices"
> + select INV_MPU6050_IIO
> + select REGMAP_SPI
> + help
> + This driver can be built as a module. The module will be called
> + inv-mpu6050-spi.
> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
> index ca4941d..734af5e 100644
> --- a/drivers/iio/imu/inv_mpu6050/Makefile
> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
> @@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
>
> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
> inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
> +
> +obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
> +inv-mpu6050-spi-objs := inv_mpu_spi.o
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
> index af406a3..758fe2b 100644
> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
> enum inv_devices {
> INV_MPU6050,
> INV_MPU6500,
> + INV_MPU6000,
> INV_NUM_PARTS
> };
>
> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> new file mode 100644
> index 0000000..484171e
> --- /dev/null
> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
> @@ -0,0 +1,80 @@
> +/*
> +* Copyright (C) 2015 Intel Corporation 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.
> +*/
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/spi/spi.h>
> +#include <linux/regmap.h>
> +#include <linux/iio/iio.h>
> +#include "inv_mpu_iio.h"
> +
> +static const struct regmap_config inv_mpu_regmap_config = {
> + .reg_bits = 8,
> + .val_bits = 8,
> +};
> +
> +static int inv_mpu_probe(struct spi_device *spi)
> +{
> + struct regmap *regmap;
> + const struct spi_device_id *id = spi_get_device_id(spi);
> + const char *name = id ? id->name : NULL;
> +
> + regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
> + if (IS_ERR(regmap)) {
> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
> + (int)PTR_ERR(regmap));
> + return PTR_ERR(regmap);
> + }
> +
> + return inv_mpu_core_probe(regmap, spi->irq, name);
I think there's still some spi-only initialization missing. As per
datasheet we should disable the I2C interface when using the SPI
interface.
Lucas De Marchi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-03 3:39 ` Lucas De Marchi
@ 2016-02-03 6:42 ` Ge Gao
2016-02-03 9:17 ` Adriana Reus
0 siblings, 1 reply; 12+ messages in thread
From: Ge Gao @ 2016-02-03 6:42 UTC (permalink / raw)
To: Lucas De Marchi; +Cc: Adriana Reus, jic23, linux-iio, srinivas.pandruvada
That is a good point. That register should be set in case chip get confused if the spi signal mimic a I2C signal
Ge
> On Feb 2, 2016, at 10:31 PM, Lucas De Marchi <lucas.de.marchi@gmail.com> wrote:
>
> Hi Adriana,
>
>> On Tue, Feb 2, 2016 at 1:02 PM, Adriana Reus <adriana.reus@intel.com> wrote:
>> The only difference between the MPU6000 and the
>> MPU6050 is that the first also supports SPI.
>> Add SPI driver for this chip.
>>
>> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
>> ---
>> Changes since initial version:
>> * Modified Kconfig so that the SPI component selects the core component
>> instead of the other way around.
>>
>> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
>> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
>> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
>> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
>> 4 files changed, 91 insertions(+)
>> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>
>> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
>> index 483f52d..6f6a419 100644
>> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
>> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
>> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
>> This driver can be built as a module. The module will be called
>> inv-mpu6050-i2c.
>>
>> +config INV_MPU6050_SPI
>> + tristate "Invensense MPU6050 devices"
>> + select INV_MPU6050_IIO
>> + select REGMAP_SPI
>> + help
>> + This driver can be built as a module. The module will be called
>> + inv-mpu6050-spi.
>> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
>> index ca4941d..734af5e 100644
>> --- a/drivers/iio/imu/inv_mpu6050/Makefile
>> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
>> @@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
>>
>> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
>> inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
>> +
>> +obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
>> +inv-mpu6050-spi-objs := inv_mpu_spi.o
>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>> index af406a3..758fe2b 100644
>> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
>> enum inv_devices {
>> INV_MPU6050,
>> INV_MPU6500,
>> + INV_MPU6000,
>> INV_NUM_PARTS
>> };
>>
>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>> new file mode 100644
>> index 0000000..484171e
>> --- /dev/null
>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>> @@ -0,0 +1,80 @@
>> +/*
>> +* Copyright (C) 2015 Intel Corporation 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.
>> +*/
>> +#include <linux/module.h>
>> +#include <linux/acpi.h>
>> +#include <linux/spi/spi.h>
>> +#include <linux/regmap.h>
>> +#include <linux/iio/iio.h>
>> +#include "inv_mpu_iio.h"
>> +
>> +static const struct regmap_config inv_mpu_regmap_config = {
>> + .reg_bits = 8,
>> + .val_bits = 8,
>> +};
>> +
>> +static int inv_mpu_probe(struct spi_device *spi)
>> +{
>> + struct regmap *regmap;
>> + const struct spi_device_id *id = spi_get_device_id(spi);
>> + const char *name = id ? id->name : NULL;
>> +
>> + regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
>> + if (IS_ERR(regmap)) {
>> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
>> + (int)PTR_ERR(regmap));
>> + return PTR_ERR(regmap);
>> + }
>> +
>> + return inv_mpu_core_probe(regmap, spi->irq, name);
>
> I think there's still some spi-only initialization missing. As per
> datasheet we should disable the I2C interface when using the SPI
> interface.
>
> Lucas De Marchi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-03 6:42 ` Ge Gao
@ 2016-02-03 9:17 ` Adriana Reus
2016-02-03 15:21 ` Ge Gao
0 siblings, 1 reply; 12+ messages in thread
From: Adriana Reus @ 2016-02-03 9:17 UTC (permalink / raw)
To: Ge Gao, Lucas De Marchi; +Cc: jic23, linux-iio, srinivas.pandruvada
Hi Lucas, Ge,
Thanks for pointing that out Lucas, I'm looking into it.
Ge, would it suffice to set the I2C_IF_DIS via an SPI transaction
(spi_write or regmap_write)?
Couldn't the chip get confused during that transaction also?
On 03.02.2016 08:42, Ge Gao wrote:
> That is a good point. That register should be set in case chip get confused if the spi signal mimic a I2C signal
>
> Ge
>
>> On Feb 2, 2016, at 10:31 PM, Lucas De Marchi <lucas.de.marchi@gmail.com> wrote:
>>
>> Hi Adriana,
>>
>>> On Tue, Feb 2, 2016 at 1:02 PM, Adriana Reus <adriana.reus@intel.com> wrote:
>>> The only difference between the MPU6000 and the
>>> MPU6050 is that the first also supports SPI.
>>> Add SPI driver for this chip.
>>>
>>> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
>>> ---
>>> Changes since initial version:
>>> * Modified Kconfig so that the SPI component selects the core component
>>> instead of the other way around.
>>>
>>> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
>>> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
>>> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
>>> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 +++++++++++++++++++++++++++++++
>>> 4 files changed, 91 insertions(+)
>>> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>>
>>> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
>>> index 483f52d..6f6a419 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
>>> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
>>> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
>>> This driver can be built as a module. The module will be called
>>> inv-mpu6050-i2c.
>>>
>>> +config INV_MPU6050_SPI
>>> + tristate "Invensense MPU6050 devices"
>>> + select INV_MPU6050_IIO
>>> + select REGMAP_SPI
>>> + help
>>> + This driver can be built as a module. The module will be called
>>> + inv-mpu6050-spi.
>>> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv_mpu6050/Makefile
>>> index ca4941d..734af5e 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/Makefile
>>> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
>>> @@ -7,3 +7,6 @@ inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
>>>
>>> obj-$(CONFIG_INV_MPU6050_I2C) += inv-mpu6050-i2c.o
>>> inv-mpu6050-i2c-objs := inv_mpu_i2c.o inv_mpu_acpi.o
>>> +
>>> +obj-$(CONFIG_INV_MPU6050_SPI) += inv-mpu6050-spi.o
>>> +inv-mpu6050-spi-objs := inv_mpu_spi.o
>>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> index af406a3..758fe2b 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
>>> enum inv_devices {
>>> INV_MPU6050,
>>> INV_MPU6500,
>>> + INV_MPU6000,
>>> INV_NUM_PARTS
>>> };
>>>
>>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>> new file mode 100644
>>> index 0000000..484171e
>>> --- /dev/null
>>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>> @@ -0,0 +1,80 @@
>>> +/*
>>> +* Copyright (C) 2015 Intel Corporation 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.
>>> +*/
>>> +#include <linux/module.h>
>>> +#include <linux/acpi.h>
>>> +#include <linux/spi/spi.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/iio/iio.h>
>>> +#include "inv_mpu_iio.h"
>>> +
>>> +static const struct regmap_config inv_mpu_regmap_config = {
>>> + .reg_bits = 8,
>>> + .val_bits = 8,
>>> +};
>>> +
>>> +static int inv_mpu_probe(struct spi_device *spi)
>>> +{
>>> + struct regmap *regmap;
>>> + const struct spi_device_id *id = spi_get_device_id(spi);
>>> + const char *name = id ? id->name : NULL;
>>> +
>>> + regmap = devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
>>> + if (IS_ERR(regmap)) {
>>> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
>>> + (int)PTR_ERR(regmap));
>>> + return PTR_ERR(regmap);
>>> + }
>>> +
>>> + return inv_mpu_core_probe(regmap, spi->irq, name);
>>
>> I think there's still some spi-only initialization missing. As per
>> datasheet we should disable the I2C interface when using the SPI
>> interface.
>>
>> Lucas De Marchi
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000
2016-02-03 9:17 ` Adriana Reus
@ 2016-02-03 15:21 ` Ge Gao
0 siblings, 0 replies; 12+ messages in thread
From: Ge Gao @ 2016-02-03 15:21 UTC (permalink / raw)
To: Adriana Reus, Lucas De Marchi; +Cc: jic23, linux-iio, srinivas.pandruvada
Hi Adriana,
Chip only gets confused when a SPI signal could simulate a I2C address.=
Setting the bit tells chip to completely forget about I2C at all. Without=
setting the bit, it still works. But it might risk of triggering I2C if th=
e SPI signal accidentally simulates an I2C address that matches the chip ad=
dress and triggers a subsequent action.
Thanks.
Best Regards,
Ge Gao
________________________________________
From: Adriana Reus <adriana.reus@intel.com>
Sent: Wednesday, February 3, 2016 1:17 AM
To: Ge Gao; Lucas De Marchi
Cc: jic23@kernel.org; linux-iio@vger.kernel.org; srinivas.pandruvada@linux.=
intel.com
Subject: Re: [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6=
000
Hi Lucas, Ge,
Thanks for pointing that out Lucas, I'm looking into it.
Ge, would it suffice to set the I2C_IF_DIS via an SPI transaction
(spi_write or regmap_write)?
Couldn't the chip get confused during that transaction also?
On 03.02.2016 08:42, Ge Gao wrote:
> That is a good point. That register should be set in case chip get confu=
sed if the spi signal mimic a I2C signal
>
> Ge
>
>> On Feb 2, 2016, at 10:31 PM, Lucas De Marchi <lucas.de.marchi@gmail.com>=
wrote:
>>
>> Hi Adriana,
>>
>>> On Tue, Feb 2, 2016 at 1:02 PM, Adriana Reus <adriana.reus@intel.com> w=
rote:
>>> The only difference between the MPU6000 and the
>>> MPU6050 is that the first also supports SPI.
>>> Add SPI driver for this chip.
>>>
>>> Signed-off-by: Adriana Reus <adriana.reus@intel.com>
>>> ---
>>> Changes since initial version:
>>> * Modified Kconfig so that the SPI component selects the core component
>>> instead of the other way around.
>>>
>>> drivers/iio/imu/inv_mpu6050/Kconfig | 7 +++
>>> drivers/iio/imu/inv_mpu6050/Makefile | 3 ++
>>> drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 1 +
>>> drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c | 80 ++++++++++++++++++++++++=
+++++++
>>> 4 files changed, 91 insertions(+)
>>> create mode 100644 drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>>
>>> diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_=
mpu6050/Kconfig
>>> index 483f52d..6f6a419 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/Kconfig
>>> +++ b/drivers/iio/imu/inv_mpu6050/Kconfig
>>> @@ -25,3 +25,10 @@ config INV_MPU6050_I2C
>>> This driver can be built as a module. The module will be call=
ed
>>> inv-mpu6050-i2c.
>>>
>>> +config INV_MPU6050_SPI
>>> + tristate "Invensense MPU6050 devices"
>>> + select INV_MPU6050_IIO
>>> + select REGMAP_SPI
>>> + help
>>> + This driver can be built as a module. The module will be call=
ed
>>> + inv-mpu6050-spi.
>>> diff --git a/drivers/iio/imu/inv_mpu6050/Makefile b/drivers/iio/imu/inv=
_mpu6050/Makefile
>>> index ca4941d..734af5e 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/Makefile
>>> +++ b/drivers/iio/imu/inv_mpu6050/Makefile
>>> @@ -7,3 +7,6 @@ inv-mpu6050-objs :=3D inv_mpu_core.o inv_mpu_ring.o inv=
_mpu_trigger.o
>>>
>>> obj-$(CONFIG_INV_MPU6050_I2C) +=3D inv-mpu6050-i2c.o
>>> inv-mpu6050-i2c-objs :=3D inv_mpu_i2c.o inv_mpu_acpi.o
>>> +
>>> +obj-$(CONFIG_INV_MPU6050_SPI) +=3D inv-mpu6050-spi.o
>>> +inv-mpu6050-spi-objs :=3D inv_mpu_spi.o
>>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/im=
u/inv_mpu6050/inv_mpu_iio.h
>>> index af406a3..758fe2b 100644
>>> --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
>>> @@ -62,6 +62,7 @@ struct inv_mpu6050_reg_map {
>>> enum inv_devices {
>>> INV_MPU6050,
>>> INV_MPU6500,
>>> + INV_MPU6000,
>>> INV_NUM_PARTS
>>> };
>>>
>>> diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c b/drivers/iio/im=
u/inv_mpu6050/inv_mpu_spi.c
>>> new file mode 100644
>>> index 0000000..484171e
>>> --- /dev/null
>>> +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_spi.c
>>> @@ -0,0 +1,80 @@
>>> +/*
>>> +* Copyright (C) 2015 Intel Corporation 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.
>>> +*/
>>> +#include <linux/module.h>
>>> +#include <linux/acpi.h>
>>> +#include <linux/spi/spi.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/iio/iio.h>
>>> +#include "inv_mpu_iio.h"
>>> +
>>> +static const struct regmap_config inv_mpu_regmap_config =3D {
>>> + .reg_bits =3D 8,
>>> + .val_bits =3D 8,
>>> +};
>>> +
>>> +static int inv_mpu_probe(struct spi_device *spi)
>>> +{
>>> + struct regmap *regmap;
>>> + const struct spi_device_id *id =3D spi_get_device_id(spi);
>>> + const char *name =3D id ? id->name : NULL;
>>> +
>>> + regmap =3D devm_regmap_init_spi(spi, &inv_mpu_regmap_config);
>>> + if (IS_ERR(regmap)) {
>>> + dev_err(&spi->dev, "Failed to register spi regmap %d\n"=
,
>>> + (int)PTR_ERR(regmap));
>>> + return PTR_ERR(regmap);
>>> + }
>>> +
>>> + return inv_mpu_core_probe(regmap, spi->irq, name);
>>
>> I think there's still some spi-only initialization missing. As per
>> datasheet we should disable the I2C interface when using the SPI
>> interface.
>>
>> Lucas De Marchi
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-02-03 15:21 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-02 15:02 [PATCH v1 0/4] iio: imu: inv_mpu6050: Split driver into core and I2C/SPI functionality Adriana Reus
2016-02-02 15:02 ` [PATCH v1 1/4] iio: imu: inv-mpu6050: Fix interrupt pin configuration Adriana Reus
2016-02-02 15:02 ` [PATCH v1 2/4] iio: imu: inv_mpu6050: Use regmap instead of i2c specific functions Adriana Reus
2016-02-02 15:02 ` [PATCH v1 3/4] iio: imu: inv_mpu6050: Separate driver into core and i2c functionality Adriana Reus
2016-02-02 15:02 ` [PATCH v1 4/4] iio: imu: inv_mpu6050: Add SPI support for MPU6000 Adriana Reus
2016-02-02 15:29 ` Crt Mori
2016-02-02 15:34 ` Crt Mori
2016-02-02 15:48 ` Adriana Reus
2016-02-03 3:39 ` Lucas De Marchi
2016-02-03 6:42 ` Ge Gao
2016-02-03 9:17 ` Adriana Reus
2016-02-03 15:21 ` Ge Gao
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.