* [PATCH v2 0/4] iio: bmc150 regmap and SPI
@ 2015-08-20 12:49 Markus Pargmann
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel, Markus Pargmann
Hi,
this series converts the bmc150 driver to use regmap and adds an SPI interface.
In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI support".
It now depends on "regmap: i2c block support".
Changes in v2:
- Removed default values for regmap_config fields.
- Redesigned the fifo_transfer function to avoid running in errors first.
- Dropped irq checks patch as it is already mainline
- Core can now be built as module with autoselection of i2c and spi parts
As my hardware is missing an interrupt line from the SPI connected bmc150 I am
not able to test the iio buffer code path and the i2c code path. Tests would be
appreciated.
Best regards,
Markus
Markus Pargmann (4):
iio: bmc150: Use i2c regmap
iio: bcm150: Remove i2c_client from private data
iio: bmc150: Split the driver into core and i2c
iio: bmc150: Add SPI driver
drivers/iio/accel/Kconfig | 14 +-
drivers/iio/accel/Makefile | 4 +-
.../accel/{bmc150-accel.c => bmc150-accel-core.c} | 398 ++++++++-------------
drivers/iio/accel/bmc150-accel-i2c.c | 99 +++++
drivers/iio/accel/bmc150-accel-spi.c | 83 +++++
drivers/iio/accel/bmc150-accel.h | 21 ++
6 files changed, 367 insertions(+), 252 deletions(-)
rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (81%)
create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
create mode 100644 drivers/iio/accel/bmc150-accel.h
--
2.4.6
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 1/4] iio: bmc150: Use i2c regmap
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
2015-08-31 16:11 ` Jonathan Cameron
2015-09-09 14:36 ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
` (3 subsequent siblings)
4 siblings, 2 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel, Markus Pargmann
This replaces all usage of direct i2c accesses with regmap accesses.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/iio/accel/Kconfig | 2 +
drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------------------
2 files changed, 95 insertions(+), 126 deletions(-)
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 00e7bcbdbe24..01dd03d194d1 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,8 @@ config BMC150_ACCEL
depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
+ select REGMAP
+ select REGMAP_I2C
help
Say yes here to build support for the following Bosch accelerometers:
BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index 55751d9e1ade..c5c773e75173 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -35,6 +35,7 @@
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
+#include <linux/regmap.h>
#define BMC150_ACCEL_DRV_NAME "bmc150_accel"
#define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
@@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
struct bmc150_accel_data {
struct i2c_client *client;
+ struct regmap *regmap;
+ struct device *dev;
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
atomic_t active_intr;
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -241,6 +244,11 @@ static const struct {
{500000, BMC150_ACCEL_SLEEP_500_MS},
{1000000, BMC150_ACCEL_SLEEP_1_SEC} };
+static const struct regmap_config bmc150_i2c_regmap_conf = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x3f,
+};
static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
enum bmc150_power_modes mode,
@@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
if (ret < 0) {
dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
return ret;
@@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
if (bmc150_accel_samp_freq_table[i].val == val &&
bmc150_accel_samp_freq_table[i].val2 == val2) {
- ret = i2c_smbus_write_byte_data(
- data->client,
+ ret = regmap_write(data->regmap,
BMC150_ACCEL_REG_PMU_BW,
bmc150_accel_samp_freq_table[i].bw_bits);
if (ret < 0)
@@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
{
- int ret, val;
+ int ret;
- ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
data->slope_thres);
if (ret < 0) {
dev_err(&data->client->dev, "Error writing reg_int_6\n");
return ret;
}
- ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
+ ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
+ BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading reg_int_5\n");
- return ret;
- }
-
- val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
- ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
- val);
- if (ret < 0) {
- dev_err(&data->client->dev, "Error write reg_int_5\n");
+ dev_err(&data->client->dev, "Error updating reg_int_5\n");
return ret;
}
@@ -348,17 +347,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
{
int ret;
+ unsigned int val;
- ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
+ ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
if (ret < 0) {
dev_err(&data->client->dev,
"Error: Reading chip id\n");
return ret;
}
- dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
- if (ret != data->chip_info->chip_id) {
- dev_err(&data->client->dev, "Invalid chip %x\n", ret);
+ dev_dbg(&data->client->dev, "Chip Id %x\n", val);
+ if (val != data->chip_info->chip_id) {
+ dev_err(&data->client->dev, "Invalid chip %x\n", val);
return -ENODEV;
}
@@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
return ret;
/* Set Default Range */
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_PMU_RANGE,
- BMC150_ACCEL_DEF_RANGE_4G);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
+ BMC150_ACCEL_DEF_RANGE_4G);
if (ret < 0) {
dev_err(&data->client->dev,
"Error writing reg_pmu_range\n");
@@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
return ret;
/* Set default as latched interrupts */
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_INT_RST_LATCH,
- BMC150_ACCEL_INT_MODE_LATCH_INT |
- BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret < 0) {
dev_err(&data->client->dev,
"Error writing reg_int_rst_latch\n");
@@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
return ret;
/* map the interrupt to the appropriate pins */
- ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
+ ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
+ (state ? info->map_bitmask : 0));
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading reg_int_map\n");
- goto out_fix_power_state;
- }
- if (state)
- ret |= info->map_bitmask;
- else
- ret &= ~info->map_bitmask;
-
- ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
- ret);
- if (ret < 0) {
- dev_err(&data->client->dev, "Error writing reg_int_map\n");
+ dev_err(&data->client->dev, "Error updating reg_int_map\n");
goto out_fix_power_state;
}
/* enable/disable the interrupt */
- ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
+ ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
+ (state ? info->en_bitmask : 0));
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading reg_int_en\n");
- goto out_fix_power_state;
- }
-
- if (state)
- ret |= info->en_bitmask;
- else
- ret &= ~info->en_bitmask;
-
- ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
- if (ret < 0) {
- dev_err(&data->client->dev, "Error writing reg_int_en\n");
+ dev_err(&data->client->dev, "Error updating reg_int_en\n");
goto out_fix_power_state;
}
@@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
if (data->chip_info->scale_table[i].scale == val) {
- ret = i2c_smbus_write_byte_data(
- data->client,
+ ret = regmap_write(data->regmap,
BMC150_ACCEL_REG_PMU_RANGE,
data->chip_info->scale_table[i].reg_range);
if (ret < 0) {
@@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
{
int ret;
+ unsigned int value;
mutex_lock(&data->mutex);
- ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
+ ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
if (ret < 0) {
dev_err(&data->client->dev, "Error reading reg_temp\n");
mutex_unlock(&data->mutex);
return ret;
}
- *val = sign_extend32(ret, 7);
+ *val = sign_extend32(value, 7);
mutex_unlock(&data->mutex);
@@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
{
int ret;
int axis = chan->scan_index;
+ unsigned int raw_val;
mutex_lock(&data->mutex);
ret = bmc150_accel_set_power_state(data, true);
@@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
return ret;
}
- ret = i2c_smbus_read_word_data(data->client,
- BMC150_ACCEL_AXIS_TO_REG(axis));
+ ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
+ &raw_val, 2);
if (ret < 0) {
dev_err(&data->client->dev, "Error reading axis %d\n", axis);
bmc150_accel_set_power_state(data, false);
mutex_unlock(&data->mutex);
return ret;
}
- *val = sign_extend32(ret >> chan->scan_type.shift,
+ *val = sign_extend32(raw_val >> chan->scan_type.shift,
chan->scan_type.realbits - 1);
ret = bmc150_accel_set_power_state(data, false);
mutex_unlock(&data->mutex);
@@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
* We must read at least one full frame in one burst, otherwise the rest of the
* frame data is discarded.
*/
-static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
+static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
char *buffer, int samples)
{
int sample_length = 3 * 2;
- u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
- int ret = -EIO;
-
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- struct i2c_msg msg[2] = {
- {
- .addr = client->addr,
- .flags = 0,
- .buf = ®_fifo_data,
- .len = sizeof(reg_fifo_data),
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .buf = (u8 *)buffer,
- .len = samples * sample_length,
- }
- };
+ int ret;
+ int total_length = samples * sample_length;
+ int i;
+ int step = regmap_get_raw_read_max(data->regmap);
- ret = i2c_transfer(client->adapter, msg, 2);
- if (ret != 2)
- ret = -EIO;
- else
- ret = 0;
- } else {
- int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
-
- for (i = 0; i < samples * sample_length; i += step) {
- ret = i2c_smbus_read_i2c_block_data(client,
- reg_fifo_data, step,
- &buffer[i]);
- if (ret != step) {
- ret = -EIO;
- break;
- }
+ if (!step || step > total_length)
+ step = total_length;
+ else if (step < total_length)
+ step = sample_length;
- ret = 0;
- }
+ /*
+ * Seems we have a bus with size limitation so we have to execute
+ * multiple reads
+ */
+ for (i = 0; i < total_length; i += step) {
+ ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA,
+ &buffer[i], step);
+ if (ret)
+ break;
}
if (ret)
- dev_err(&client->dev, "Error transferring data from fifo\n");
+ dev_err(data->dev, "Error transferring data from fifo in single steps of %zu\n",
+ step);
return ret;
}
@@ -963,14 +924,15 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
int64_t tstamp;
uint64_t sample_period;
- ret = i2c_smbus_read_byte_data(data->client,
- BMC150_ACCEL_REG_FIFO_STATUS);
+ unsigned int val;
+
+ ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
if (ret < 0) {
dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
return ret;
}
- count = ret & 0x7F;
+ count = val & 0x7F;
if (!count)
return 0;
@@ -1009,7 +971,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
if (samples && count > samples)
count = samples;
- ret = bmc150_accel_fifo_transfer(data->client, (u8 *)buffer, count);
+ ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
if (ret)
return ret;
@@ -1206,17 +1168,19 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
struct iio_dev *indio_dev = pf->indio_dev;
struct bmc150_accel_data *data = iio_priv(indio_dev);
int bit, ret, i = 0;
+ unsigned int raw_val;
mutex_lock(&data->mutex);
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->masklength) {
- ret = i2c_smbus_read_word_data(data->client,
- BMC150_ACCEL_AXIS_TO_REG(bit));
+ ret = regmap_bulk_read(data->regmap,
+ BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
+ 2);
if (ret < 0) {
mutex_unlock(&data->mutex);
goto err_read;
}
- data->buffer[i++] = ret;
+ data->buffer[i++] = raw_val;
}
mutex_unlock(&data->mutex);
@@ -1240,10 +1204,9 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
mutex_lock(&data->mutex);
/* clear any latched interrupt */
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_INT_RST_LATCH,
- BMC150_ACCEL_INT_MODE_LATCH_INT |
- BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
mutex_unlock(&data->mutex);
if (ret < 0) {
dev_err(&data->client->dev,
@@ -1300,34 +1263,34 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
struct bmc150_accel_data *data = iio_priv(indio_dev);
int dir;
int ret;
+ unsigned int val;
- ret = i2c_smbus_read_byte_data(data->client,
- BMC150_ACCEL_REG_INT_STATUS_2);
+ ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
if (ret < 0) {
dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
return ret;
}
- if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
+ if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
dir = IIO_EV_DIR_FALLING;
else
dir = IIO_EV_DIR_RISING;
- if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
+ if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
0,
IIO_MOD_X,
IIO_EV_TYPE_ROC,
dir),
data->timestamp);
- if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
+ if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
0,
IIO_MOD_Y,
IIO_EV_TYPE_ROC,
dir),
data->timestamp);
- if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
+ if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
0,
IIO_MOD_Z,
@@ -1360,10 +1323,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
}
if (ack) {
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_INT_RST_LATCH,
- BMC150_ACCEL_INT_MODE_LATCH_INT |
- BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_INT |
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret)
dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
ret = IRQ_HANDLED;
@@ -1516,7 +1478,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
int ret;
- ret = i2c_smbus_write_byte_data(data->client, reg, data->fifo_mode);
+ ret = regmap_write(data->regmap, reg, data->fifo_mode);
if (ret < 0) {
dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
return ret;
@@ -1525,9 +1487,8 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
if (!data->fifo_mode)
return 0;
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_FIFO_CONFIG0,
- data->watermark);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
+ data->watermark);
if (ret < 0)
dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
@@ -1627,6 +1588,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
+ data->dev = &client->dev;
+
+ data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
+ if (IS_ERR(data->regmap)) {
+ dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+ return PTR_ERR(data->regmap);
+ }
if (id) {
name = id->name;
@@ -1680,9 +1648,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
* want to use latch mode when we can to prevent interrupt
* flooding.
*/
- ret = i2c_smbus_write_byte_data(data->client,
- BMC150_ACCEL_REG_INT_RST_LATCH,
- BMC150_ACCEL_INT_MODE_LATCH_RESET);
+ ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+ BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret < 0) {
dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
goto err_buffer_cleanup;
--
2.4.6
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
2015-09-09 14:39 ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
` (2 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel, Markus Pargmann
i2c_client struct is now only used for debugging output. We can use the
device struct as well so we can remove all struct i2c_client usage.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Acked-by: Jonathan Cameron <jic23@kernel.org>
---
drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
1 file changed, 58 insertions(+), 62 deletions(-)
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index c5c773e75173..e4a0691d9b88 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
};
struct bmc150_accel_data {
- struct i2c_client *client;
struct regmap *regmap;
struct device *dev;
+ int irq;
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
atomic_t active_intr;
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -276,11 +276,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
- dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
+ dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
if (ret < 0) {
- dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
+ dev_err(data->dev, "Error writing reg_pmu_lpw\n");
return ret;
}
@@ -318,18 +318,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
data->slope_thres);
if (ret < 0) {
- dev_err(&data->client->dev, "Error writing reg_int_6\n");
+ dev_err(data->dev, "Error writing reg_int_6\n");
return ret;
}
ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
if (ret < 0) {
- dev_err(&data->client->dev, "Error updating reg_int_5\n");
+ dev_err(data->dev, "Error updating reg_int_5\n");
return ret;
}
- dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
+ dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
data->slope_dur);
return ret;
@@ -351,14 +351,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"Error: Reading chip id\n");
return ret;
}
- dev_dbg(&data->client->dev, "Chip Id %x\n", val);
+ dev_dbg(data->dev, "Chip Id %x\n", val);
if (val != data->chip_info->chip_id) {
- dev_err(&data->client->dev, "Invalid chip %x\n", val);
+ dev_err(data->dev, "Invalid chip %x\n", val);
return -ENODEV;
}
@@ -375,8 +375,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
BMC150_ACCEL_DEF_RANGE_4G);
if (ret < 0) {
- dev_err(&data->client->dev,
- "Error writing reg_pmu_range\n");
+ dev_err(data->dev, "Error writing reg_pmu_range\n");
return ret;
}
@@ -394,7 +393,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
BMC150_ACCEL_INT_MODE_LATCH_INT |
BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"Error writing reg_int_rst_latch\n");
return ret;
}
@@ -436,16 +435,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
int ret;
if (on)
- ret = pm_runtime_get_sync(&data->client->dev);
+ ret = pm_runtime_get_sync(data->dev);
else {
- pm_runtime_mark_last_busy(&data->client->dev);
- ret = pm_runtime_put_autosuspend(&data->client->dev);
+ pm_runtime_mark_last_busy(data->dev);
+ ret = pm_runtime_put_autosuspend(data->dev);
}
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"Failed: bmc150_accel_set_power_state for %d\n", on);
if (on)
- pm_runtime_put_noidle(&data->client->dev);
+ pm_runtime_put_noidle(data->dev);
return ret;
}
@@ -528,7 +527,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
(state ? info->map_bitmask : 0));
if (ret < 0) {
- dev_err(&data->client->dev, "Error updating reg_int_map\n");
+ dev_err(data->dev, "Error updating reg_int_map\n");
goto out_fix_power_state;
}
@@ -536,7 +535,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
(state ? info->en_bitmask : 0));
if (ret < 0) {
- dev_err(&data->client->dev, "Error updating reg_int_en\n");
+ dev_err(data->dev, "Error updating reg_int_en\n");
goto out_fix_power_state;
}
@@ -563,7 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
BMC150_ACCEL_REG_PMU_RANGE,
data->chip_info->scale_table[i].reg_range);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"Error writing pmu_range\n");
return ret;
}
@@ -585,7 +584,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading reg_temp\n");
+ dev_err(data->dev, "Error reading reg_temp\n");
mutex_unlock(&data->mutex);
return ret;
}
@@ -614,7 +613,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
&raw_val, 2);
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading axis %d\n", axis);
+ dev_err(data->dev, "Error reading axis %d\n", axis);
bmc150_accel_set_power_state(data, false);
mutex_unlock(&data->mutex);
return ret;
@@ -928,7 +927,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
+ dev_err(data->dev, "Error reading reg_fifo_status\n");
return ret;
}
@@ -1209,7 +1208,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
BMC150_ACCEL_INT_MODE_LATCH_RESET);
mutex_unlock(&data->mutex);
if (ret < 0) {
- dev_err(&data->client->dev,
+ dev_err(data->dev,
"Error writing reg_int_rst_latch\n");
return ret;
}
@@ -1267,7 +1266,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
if (ret < 0) {
- dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
+ dev_err(data->dev, "Error reading reg_int_status_2\n");
return ret;
}
@@ -1327,7 +1326,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
BMC150_ACCEL_INT_MODE_LATCH_INT |
BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret)
- dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+ dev_err(data->dev, "Error writing reg_int_rst_latch\n");
ret = IRQ_HANDLED;
} else {
ret = IRQ_NONE;
@@ -1379,17 +1378,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
return dev_name(dev);
}
-static int bmc150_accel_gpio_probe(struct i2c_client *client,
- struct bmc150_accel_data *data)
+static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
{
struct device *dev;
struct gpio_desc *gpio;
int ret;
- if (!client)
- return -EINVAL;
-
- dev = &client->dev;
+ dev = data->dev;
/* data ready gpio interrupt pin */
gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
@@ -1442,7 +1437,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
struct bmc150_accel_trigger *t = &data->triggers[i];
- t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
+ t->indio_trig = devm_iio_trigger_alloc(data->dev,
bmc150_accel_triggers[i].name,
indio_dev->name,
indio_dev->id);
@@ -1451,7 +1446,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
break;
}
- t->indio_trig->dev.parent = &data->client->dev;
+ t->indio_trig->dev.parent = data->dev;
t->indio_trig->ops = &bmc150_accel_trigger_ops;
t->intr = bmc150_accel_triggers[i].intr;
t->data = data;
@@ -1480,7 +1475,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
ret = regmap_write(data->regmap, reg, data->fifo_mode);
if (ret < 0) {
- dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
+ dev_err(data->dev, "Error writing reg_fifo_config1\n");
return ret;
}
@@ -1490,7 +1485,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
data->watermark);
if (ret < 0)
- dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
+ dev_err(data->dev, "Error writing reg_fifo_config0\n");
return ret;
}
@@ -1580,6 +1575,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
int ret;
const char *name = NULL;
int chip_id = 0;
+ struct device *dev;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
@@ -1587,12 +1583,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
- data->client = client;
data->dev = &client->dev;
+ dev = &client->dev;
+ data->irq = client->irq;
data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
if (IS_ERR(data->regmap)) {
- dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+ dev_err(dev, "Failed to initialize i2c regmap\n");
return PTR_ERR(data->regmap);
}
@@ -1601,8 +1598,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
chip_id = id->driver_data;
}
- if (ACPI_HANDLE(&client->dev))
- name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
+ if (ACPI_HANDLE(dev))
+ name = bmc150_accel_match_acpi_device(dev, &chip_id);
data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
@@ -1612,7 +1609,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
mutex_init(&data->mutex);
- indio_dev->dev.parent = &client->dev;
+ indio_dev->dev.parent = dev;
indio_dev->channels = data->chip_info->channels;
indio_dev->num_channels = data->chip_info->num_channels;
indio_dev->name = name;
@@ -1624,16 +1621,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
bmc150_accel_trigger_handler,
&bmc150_accel_buffer_ops);
if (ret < 0) {
- dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
+ dev_err(data->dev, "Failed: iio triggered buffer setup\n");
return ret;
}
- if (client->irq < 0)
- client->irq = bmc150_accel_gpio_probe(client, data);
+ if (data->irq <= 0)
+ data->irq = bmc150_accel_gpio_probe(data);
- if (client->irq > 0) {
+ if (data->irq > 0) {
ret = devm_request_threaded_irq(
- &client->dev, client->irq,
+ data->dev, data->irq,
bmc150_accel_irq_handler,
bmc150_accel_irq_thread_handler,
IRQF_TRIGGER_RISING,
@@ -1651,7 +1648,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
BMC150_ACCEL_INT_MODE_LATCH_RESET);
if (ret < 0) {
- dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+ dev_err(data->dev, "Error writing reg_int_rst_latch\n");
goto err_buffer_cleanup;
}
@@ -1672,18 +1669,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret < 0) {
- dev_err(&client->dev, "Unable to register iio device\n");
+ dev_err(data->dev, "Unable to register iio device\n");
goto err_trigger_unregister;
}
- ret = pm_runtime_set_active(&client->dev);
+ ret = pm_runtime_set_active(dev);
if (ret)
goto err_iio_unregister;
- pm_runtime_enable(&client->dev);
- pm_runtime_set_autosuspend_delay(&client->dev,
- BMC150_AUTO_SUSPEND_DELAY_MS);
- pm_runtime_use_autosuspend(&client->dev);
+ pm_runtime_enable(dev);
+ pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(dev);
return 0;
@@ -1702,9 +1698,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct bmc150_accel_data *data = iio_priv(indio_dev);
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
- pm_runtime_put_noidle(&client->dev);
+ pm_runtime_disable(data->dev);
+ pm_runtime_set_suspended(data->dev);
+ pm_runtime_put_noidle(data->dev);
iio_device_unregister(indio_dev);
@@ -1722,7 +1718,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int bmc150_accel_suspend(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
mutex_lock(&data->mutex);
@@ -1734,7 +1730,7 @@ static int bmc150_accel_suspend(struct device *dev)
static int bmc150_accel_resume(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
mutex_lock(&data->mutex);
@@ -1750,11 +1746,11 @@ static int bmc150_accel_resume(struct device *dev)
#ifdef CONFIG_PM
static int bmc150_accel_runtime_suspend(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
int ret;
- dev_dbg(&data->client->dev, __func__);
+ dev_dbg(data->dev, __func__);
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
if (ret < 0)
return -EAGAIN;
@@ -1764,12 +1760,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
static int bmc150_accel_runtime_resume(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
int ret;
int sleep_val;
- dev_dbg(&data->client->dev, __func__);
+ dev_dbg(data->dev, __func__);
ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
if (ret < 0)
--
2.4.6
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
2015-08-31 16:15 ` Jonathan Cameron
2015-09-09 14:45 ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
4 siblings, 2 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel, Markus Pargmann
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/iio/accel/Kconfig | 9 +-
drivers/iio/accel/Makefile | 3 +-
.../accel/{bmc150-accel.c => bmc150-accel-core.c} | 95 ++++-----------------
drivers/iio/accel/bmc150-accel-i2c.c | 99 ++++++++++++++++++++++
drivers/iio/accel/bmc150-accel.h | 21 +++++
5 files changed, 144 insertions(+), 83 deletions(-)
rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
create mode 100644 drivers/iio/accel/bmc150-accel.h
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 01dd03d194d1..6da4eb0db57b 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -19,21 +19,22 @@ config BMA180
config BMC150_ACCEL
tristate "Bosch BMC150 Accelerometer Driver"
- depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
select REGMAP
- select REGMAP_I2C
+ select BMC150_ACCEL_I2C if I2C
help
Say yes here to build support for the following Bosch accelerometers:
BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
- Currently this only supports the device via an i2c interface.
-
This is a combo module with both accelerometer and magnetometer.
This driver is only implementing accelerometer part, which has
its own address and register map.
+config BMC150_ACCEL_I2C
+ tristate
+ select REGMAP_I2C
+
config HID_SENSOR_ACCEL_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index ebd2675b2a02..5ef8bdbad092 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -4,7 +4,8 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_BMA180) += bma180.o
-obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
+obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
+obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
obj-$(CONFIG_KXSD9) += kxsd9.o
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
similarity index 95%
rename from drivers/iio/accel/bmc150-accel.c
rename to drivers/iio/accel/bmc150-accel-core.c
index e4a0691d9b88..614cf61f0110 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -37,6 +37,8 @@
#include <linux/iio/triggered_buffer.h>
#include <linux/regmap.h>
+#include "bmc150-accel.h"
+
#define BMC150_ACCEL_DRV_NAME "bmc150_accel"
#define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
#define BMC150_ACCEL_GPIO_NAME "bmc150_accel_int"
@@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
struct bmc150_accel_data {
struct regmap *regmap;
struct device *dev;
- int irq;
struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
atomic_t active_intr;
struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -201,6 +202,7 @@ struct bmc150_accel_data {
int ev_enable_state;
int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
const struct bmc150_accel_chip_info *chip_info;
+ int irq;
};
static const struct {
@@ -1070,15 +1072,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
static const struct iio_chan_spec bma280_accel_channels[] =
BMC150_ACCEL_CHANNELS(14);
-enum {
- bmc150,
- bmi055,
- bma255,
- bma250e,
- bma222e,
- bma280,
-};
-
static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
[bmc150] = {
.chip_id = 0xFA,
@@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
.postdisable = bmc150_accel_buffer_postdisable,
};
-static int bmc150_accel_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
+ const char *name, int chip_id, bool block_supported)
{
struct bmc150_accel_data *data;
struct iio_dev *indio_dev;
int ret;
- const char *name = NULL;
- int chip_id = 0;
- struct device *dev;
- indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
- i2c_set_clientdata(client, indio_dev);
- data->dev = &client->dev;
- dev = &client->dev;
- data->irq = client->irq;
-
- data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
- if (IS_ERR(data->regmap)) {
- dev_err(dev, "Failed to initialize i2c regmap\n");
- return PTR_ERR(data->regmap);
- }
-
- if (id) {
- name = id->name;
- chip_id = id->driver_data;
- }
+ dev_set_drvdata(dev, indio_dev);
+ data->dev = dev;
+ data->irq = irq;
+ data->regmap = regmap;
if (ACPI_HANDLE(dev))
name = bmc150_accel_match_acpi_device(dev, &chip_id);
@@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
if (ret)
goto err_buffer_cleanup;
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
- i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ if (block_supported) {
indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
indio_dev->info = &bmc150_accel_info_fifo;
indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
@@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret < 0) {
- dev_err(data->dev, "Unable to register iio device\n");
+ dev_err(dev, "Unable to register iio device\n");
goto err_trigger_unregister;
}
@@ -1692,10 +1669,11 @@ err_buffer_cleanup:
return ret;
}
+EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
-static int bmc150_accel_remove(struct i2c_client *client)
+int bmc150_accel_core_remove(struct device *dev)
{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct bmc150_accel_data *data = iio_priv(indio_dev);
pm_runtime_disable(data->dev);
@@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
return 0;
}
+EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
#ifdef CONFIG_PM_SLEEP
static int bmc150_accel_suspend(struct device *dev)
@@ -1784,48 +1763,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
}
#endif
-static const struct dev_pm_ops bmc150_accel_pm_ops = {
+const struct dev_pm_ops bmc150_accel_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
bmc150_accel_runtime_resume, NULL)
};
-
-static const struct acpi_device_id bmc150_accel_acpi_match[] = {
- {"BSBA0150", bmc150},
- {"BMC150A", bmc150},
- {"BMI055A", bmi055},
- {"BMA0255", bma255},
- {"BMA250E", bma250e},
- {"BMA222E", bma222e},
- {"BMA0280", bma280},
- { },
-};
-MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
-
-static const struct i2c_device_id bmc150_accel_id[] = {
- {"bmc150_accel", bmc150},
- {"bmi055_accel", bmi055},
- {"bma255", bma255},
- {"bma250e", bma250e},
- {"bma222e", bma222e},
- {"bma280", bma280},
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
-
-static struct i2c_driver bmc150_accel_driver = {
- .driver = {
- .name = BMC150_ACCEL_DRV_NAME,
- .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
- .pm = &bmc150_accel_pm_ops,
- },
- .probe = bmc150_accel_probe,
- .remove = bmc150_accel_remove,
- .id_table = bmc150_accel_id,
-};
-module_i2c_driver(bmc150_accel_driver);
-
-MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("BMC150 accelerometer driver");
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
new file mode 100644
index 000000000000..e4dd596ba8f2
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -0,0 +1,99 @@
+/*
+ * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
+ * - BMC150
+ * - BMI055
+ * - BMA255
+ * - BMA250E
+ * - BMA222E
+ * - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+
+#include "bmc150-accel.h"
+
+static const struct regmap_config bmc150_i2c_regmap_conf = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int bmc150_accel_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct regmap *regmap;
+ bool block_supported =
+ i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
+ i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK);
+
+ regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
+ if (IS_ERR(regmap)) {
+ dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
+ id->name, id->driver_data,
+ block_supported);
+}
+
+static int bmc150_accel_remove(struct i2c_client *client)
+{
+ return bmc150_accel_core_remove(&client->dev);
+}
+
+static const struct acpi_device_id bmc150_accel_acpi_match[] = {
+ {"BSBA0150", bmc150},
+ {"BMC150A", bmc150},
+ {"BMI055A", bmi055},
+ {"BMA0255", bma255},
+ {"BMA250E", bma250e},
+ {"BMA222E", bma222e},
+ {"BMA0280", bma280},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
+
+static const struct i2c_device_id bmc150_accel_id[] = {
+ {"bmc150_accel", bmc150},
+ {"bmi055_accel", bmi055},
+ {"bma255", bma255},
+ {"bma250e", bma250e},
+ {"bma222e", bma222e},
+ {"bma280", bma280},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
+
+static struct i2c_driver bmc150_accel_driver = {
+ .driver = {
+ .name = "bmc150_accel_i2c",
+ .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+ .pm = &bmc150_accel_pm_ops,
+ },
+ .probe = bmc150_accel_probe,
+ .remove = bmc150_accel_remove,
+ .id_table = bmc150_accel_id,
+};
+module_i2c_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
new file mode 100644
index 000000000000..988b57573d0c
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -0,0 +1,21 @@
+#ifndef _BMC150_ACCEL_H_
+#define _BMC150_ACCEL_H_
+
+struct regmap;
+
+enum {
+ bmc150,
+ bmi055,
+ bma255,
+ bma250e,
+ bma222e,
+ bma280,
+};
+
+int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
+ const char *name, int chip_id,
+ bool block_supported);
+int bmc150_accel_core_remove(struct device *dev);
+extern const struct dev_pm_ops bmc150_accel_pm_ops;
+
+#endif /* _BMC150_ACCEL_H_ */
--
2.4.6
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 4/4] iio: bmc150: Add SPI driver
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
` (2 preceding siblings ...)
2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
2015-08-31 16:18 ` Jonathan Cameron
2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
4 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel, Markus Pargmann
Add a simple SPI driver which initializes the spi regmap for the bmc150
core driver.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/iio/accel/Kconfig | 5 +++
drivers/iio/accel/Makefile | 1 +
drivers/iio/accel/bmc150-accel-spi.c | 83 ++++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+)
create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 6da4eb0db57b..56d24fa3d34a 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -23,6 +23,7 @@ config BMC150_ACCEL
select IIO_TRIGGERED_BUFFER
select REGMAP
select BMC150_ACCEL_I2C if I2C
+ select BMC150_ACCEL_SPI if SPI
help
Say yes here to build support for the following Bosch accelerometers:
BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
@@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
tristate
select REGMAP_I2C
+config BMC150_ACCEL_SPI
+ tristate
+ select REGMAP_SPI
+
config HID_SENSOR_ACCEL_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 5ef8bdbad092..e579e93bf022 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -6,6 +6,7 @@
obj-$(CONFIG_BMA180) += bma180.o
obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
+obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
obj-$(CONFIG_KXSD9) += kxsd9.o
diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
new file mode 100644
index 000000000000..1c2a4f683da4
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -0,0 +1,83 @@
+/*
+ * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
+ * - BMC150
+ * - BMI055
+ * - BMA255
+ * - BMA250E
+ * - BMA222E
+ * - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "bmc150-accel.h"
+
+static const struct regmap_config bmc150_spi_regmap_conf = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0x3f,
+};
+
+static int bmc150_accel_probe(struct spi_device *spi)
+{
+ struct regmap *regmap;
+ const struct spi_device_id *id = spi_get_device_id(spi);
+
+ regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
+ if (IS_ERR(regmap)) {
+ dev_err(&spi->dev, "Failed to initialize spi regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
+ id->name, id->driver_data, true);
+}
+
+static int bmc150_accel_remove(struct spi_device *spi)
+{
+ return bmc150_accel_core_remove(&spi->dev);
+}
+
+static const struct spi_device_id bmc150_accel_id[] = {
+ {"bmc150_accel", bmc150},
+ {"bmi055_accel", bmi055},
+ {"bma255", bma255},
+ {"bma250e", bma250e},
+ {"bma222e", bma222e},
+ {"bma280", bma280},
+ {}
+};
+
+MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
+
+static struct spi_driver bmc150_accel_driver = {
+ .driver = {
+ .name = "bmc150_accel_spi",
+ .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+ .pm = &bmc150_accel_pm_ops,
+ },
+ .probe = bmc150_accel_probe,
+ .remove = bmc150_accel_remove,
+ .id_table = bmc150_accel_id,
+};
+module_spi_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
--
2.4.6
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
@ 2015-08-31 16:11 ` Jonathan Cameron
2015-08-31 19:38 ` Srinivas Pandruvada
2015-09-01 13:57 ` Srinivas Pandruvada
2015-09-09 14:36 ` Tirdea, Irina
1 sibling, 2 replies; 21+ messages in thread
From: Jonathan Cameron @ 2015-08-31 16:11 UTC (permalink / raw)
To: Markus Pargmann
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel
On 20/08/15 13:49, Markus Pargmann wrote:
> This replaces all usage of direct i2c accesses with regmap accesses.
>
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Looks fine to me, but I will be wanting an Ack / reviewed-by
and preferably a tested by from Srinivas.
Thanks,
Jonathan
> ---
> drivers/iio/accel/Kconfig | 2 +
> drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------------------
> 2 files changed, 95 insertions(+), 126 deletions(-)
>
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 00e7bcbdbe24..01dd03d194d1 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -22,6 +22,8 @@ config BMC150_ACCEL
> depends on I2C
> select IIO_BUFFER
> select IIO_TRIGGERED_BUFFER
> + select REGMAP
> + select REGMAP_I2C
> help
> Say yes here to build support for the following Bosch accelerometers:
> BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index 55751d9e1ade..c5c773e75173 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -35,6 +35,7 @@
> #include <linux/iio/trigger.h>
> #include <linux/iio/trigger_consumer.h>
> #include <linux/iio/triggered_buffer.h>
> +#include <linux/regmap.h>
>
> #define BMC150_ACCEL_DRV_NAME "bmc150_accel"
> #define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
> @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
>
> struct bmc150_accel_data {
> struct i2c_client *client;
> + struct regmap *regmap;
> + struct device *dev;
> struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> atomic_t active_intr;
> struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -241,6 +244,11 @@ static const struct {
> {500000, BMC150_ACCEL_SLEEP_500_MS},
> {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
>
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> + .reg_bits = 8,
> + .val_bits = 8,
> + .max_register = 0x3f,
> +};
>
> static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> enum bmc150_power_modes mode,
> @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>
> dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
>
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> return ret;
> @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
> for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
> if (bmc150_accel_samp_freq_table[i].val == val &&
> bmc150_accel_samp_freq_table[i].val2 == val2) {
> - ret = i2c_smbus_write_byte_data(
> - data->client,
> + ret = regmap_write(data->regmap,
> BMC150_ACCEL_REG_PMU_BW,
> bmc150_accel_samp_freq_table[i].bw_bits);
> if (ret < 0)
> @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
>
> static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
> {
> - int ret, val;
> + int ret;
>
> - ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> data->slope_thres);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_int_6\n");
> return ret;
> }
>
> - ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
> + ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> + BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_5\n");
> - return ret;
> - }
> -
> - val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
> - ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
> - val);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error write reg_int_5\n");
> + dev_err(&data->client->dev, "Error updating reg_int_5\n");
> return ret;
> }
>
> @@ -348,17 +347,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
> static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> {
> int ret;
> + unsigned int val;
>
> - ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
> + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
> if (ret < 0) {
> dev_err(&data->client->dev,
> "Error: Reading chip id\n");
> return ret;
> }
>
> - dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> - if (ret != data->chip_info->chip_id) {
> - dev_err(&data->client->dev, "Invalid chip %x\n", ret);
> + dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> + if (val != data->chip_info->chip_id) {
> + dev_err(&data->client->dev, "Invalid chip %x\n", val);
> return -ENODEV;
> }
>
> @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> return ret;
>
> /* Set Default Range */
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_PMU_RANGE,
> - BMC150_ACCEL_DEF_RANGE_4G);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> + BMC150_ACCEL_DEF_RANGE_4G);
> if (ret < 0) {
> dev_err(&data->client->dev,
> "Error writing reg_pmu_range\n");
> @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> return ret;
>
> /* Set default as latched interrupts */
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_INT |
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret < 0) {
> dev_err(&data->client->dev,
> "Error writing reg_int_rst_latch\n");
> @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
> return ret;
>
> /* map the interrupt to the appropriate pins */
> - ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
> + ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
> + (state ? info->map_bitmask : 0));
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_map\n");
> - goto out_fix_power_state;
> - }
> - if (state)
> - ret |= info->map_bitmask;
> - else
> - ret &= ~info->map_bitmask;
> -
> - ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
> - ret);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_map\n");
> + dev_err(&data->client->dev, "Error updating reg_int_map\n");
> goto out_fix_power_state;
> }
>
> /* enable/disable the interrupt */
> - ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
> + ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
> + (state ? info->en_bitmask : 0));
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_en\n");
> - goto out_fix_power_state;
> - }
> -
> - if (state)
> - ret |= info->en_bitmask;
> - else
> - ret &= ~info->en_bitmask;
> -
> - ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_en\n");
> + dev_err(&data->client->dev, "Error updating reg_int_en\n");
> goto out_fix_power_state;
> }
>
> @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>
> for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
> if (data->chip_info->scale_table[i].scale == val) {
> - ret = i2c_smbus_write_byte_data(
> - data->client,
> + ret = regmap_write(data->regmap,
> BMC150_ACCEL_REG_PMU_RANGE,
> data->chip_info->scale_table[i].reg_range);
> if (ret < 0) {
> @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
> static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
> {
> int ret;
> + unsigned int value;
>
> mutex_lock(&data->mutex);
>
> - ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
> + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading reg_temp\n");
> mutex_unlock(&data->mutex);
> return ret;
> }
> - *val = sign_extend32(ret, 7);
> + *val = sign_extend32(value, 7);
>
> mutex_unlock(&data->mutex);
>
> @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
> {
> int ret;
> int axis = chan->scan_index;
> + unsigned int raw_val;
>
> mutex_lock(&data->mutex);
> ret = bmc150_accel_set_power_state(data, true);
> @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
> return ret;
> }
>
> - ret = i2c_smbus_read_word_data(data->client,
> - BMC150_ACCEL_AXIS_TO_REG(axis));
> + ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> + &raw_val, 2);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> bmc150_accel_set_power_state(data, false);
> mutex_unlock(&data->mutex);
> return ret;
> }
> - *val = sign_extend32(ret >> chan->scan_type.shift,
> + *val = sign_extend32(raw_val >> chan->scan_type.shift,
> chan->scan_type.realbits - 1);
> ret = bmc150_accel_set_power_state(data, false);
> mutex_unlock(&data->mutex);
> @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
> * We must read at least one full frame in one burst, otherwise the rest of the
> * frame data is discarded.
> */
> -static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
> +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
> char *buffer, int samples)
> {
> int sample_length = 3 * 2;
> - u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> - int ret = -EIO;
> -
> - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> - struct i2c_msg msg[2] = {
> - {
> - .addr = client->addr,
> - .flags = 0,
> - .buf = ®_fifo_data,
> - .len = sizeof(reg_fifo_data),
> - },
> - {
> - .addr = client->addr,
> - .flags = I2C_M_RD,
> - .buf = (u8 *)buffer,
> - .len = samples * sample_length,
> - }
> - };
> + int ret;
> + int total_length = samples * sample_length;
> + int i;
> + int step = regmap_get_raw_read_max(data->regmap);
>
> - ret = i2c_transfer(client->adapter, msg, 2);
> - if (ret != 2)
> - ret = -EIO;
> - else
> - ret = 0;
> - } else {
> - int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
> -
> - for (i = 0; i < samples * sample_length; i += step) {
> - ret = i2c_smbus_read_i2c_block_data(client,
> - reg_fifo_data, step,
> - &buffer[i]);
> - if (ret != step) {
> - ret = -EIO;
> - break;
> - }
> + if (!step || step > total_length)
> + step = total_length;
> + else if (step < total_length)
> + step = sample_length;
>
> - ret = 0;
> - }
> + /*
> + * Seems we have a bus with size limitation so we have to execute
> + * multiple reads
> + */
> + for (i = 0; i < total_length; i += step) {
> + ret = regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA,
> + &buffer[i], step);
> + if (ret)
> + break;
> }
>
> if (ret)
> - dev_err(&client->dev, "Error transferring data from fifo\n");
> + dev_err(data->dev, "Error transferring data from fifo in single steps of %zu\n",
> + step);
>
> return ret;
> }
> @@ -963,14 +924,15 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
> u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
> int64_t tstamp;
> uint64_t sample_period;
> - ret = i2c_smbus_read_byte_data(data->client,
> - BMC150_ACCEL_REG_FIFO_STATUS);
> + unsigned int val;
> +
> + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> return ret;
> }
>
> - count = ret & 0x7F;
> + count = val & 0x7F;
>
> if (!count)
> return 0;
> @@ -1009,7 +971,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
> if (samples && count > samples)
> count = samples;
>
> - ret = bmc150_accel_fifo_transfer(data->client, (u8 *)buffer, count);
> + ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
> if (ret)
> return ret;
>
> @@ -1206,17 +1168,19 @@ static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p)
> struct iio_dev *indio_dev = pf->indio_dev;
> struct bmc150_accel_data *data = iio_priv(indio_dev);
> int bit, ret, i = 0;
> + unsigned int raw_val;
>
> mutex_lock(&data->mutex);
> for_each_set_bit(bit, indio_dev->active_scan_mask,
> indio_dev->masklength) {
> - ret = i2c_smbus_read_word_data(data->client,
> - BMC150_ACCEL_AXIS_TO_REG(bit));
> + ret = regmap_bulk_read(data->regmap,
> + BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
> + 2);
> if (ret < 0) {
> mutex_unlock(&data->mutex);
> goto err_read;
> }
> - data->buffer[i++] = ret;
> + data->buffer[i++] = raw_val;
> }
> mutex_unlock(&data->mutex);
>
> @@ -1240,10 +1204,9 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
>
> mutex_lock(&data->mutex);
> /* clear any latched interrupt */
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_INT |
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> mutex_unlock(&data->mutex);
> if (ret < 0) {
> dev_err(&data->client->dev,
> @@ -1300,34 +1263,34 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
> struct bmc150_accel_data *data = iio_priv(indio_dev);
> int dir;
> int ret;
> + unsigned int val;
>
> - ret = i2c_smbus_read_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_STATUS_2);
> + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> return ret;
> }
>
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> dir = IIO_EV_DIR_FALLING;
> else
> dir = IIO_EV_DIR_RISING;
>
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
> iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> 0,
> IIO_MOD_X,
> IIO_EV_TYPE_ROC,
> dir),
> data->timestamp);
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> 0,
> IIO_MOD_Y,
> IIO_EV_TYPE_ROC,
> dir),
> data->timestamp);
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> 0,
> IIO_MOD_Z,
> @@ -1360,10 +1323,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
> }
>
> if (ack) {
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_INT |
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret)
> dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> ret = IRQ_HANDLED;
> @@ -1516,7 +1478,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
> int ret;
>
> - ret = i2c_smbus_write_byte_data(data->client, reg, data->fifo_mode);
> + ret = regmap_write(data->regmap, reg, data->fifo_mode);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> return ret;
> @@ -1525,9 +1487,8 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> if (!data->fifo_mode)
> return 0;
>
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_FIFO_CONFIG0,
> - data->watermark);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
> + data->watermark);
> if (ret < 0)
> dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
>
> @@ -1627,6 +1588,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
> data = iio_priv(indio_dev);
> i2c_set_clientdata(client, indio_dev);
> data->client = client;
> + data->dev = &client->dev;
> +
> + data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> + if (IS_ERR(data->regmap)) {
> + dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> + return PTR_ERR(data->regmap);
> + }
>
> if (id) {
> name = id->name;
> @@ -1680,9 +1648,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
> * want to use latch mode when we can to prevent interrupt
> * flooding.
> */
> - ret = i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> goto err_buffer_cleanup;
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
@ 2015-08-31 16:15 ` Jonathan Cameron
2015-09-01 14:07 ` Srinivas Pandruvada
2015-09-09 14:45 ` Tirdea, Irina
1 sibling, 1 reply; 21+ messages in thread
From: Jonathan Cameron @ 2015-08-31 16:15 UTC (permalink / raw)
To: Markus Pargmann
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel
On 20/08/15 13:49, Markus Pargmann wrote:
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
A couple of little bits inline. Again would like Srinivas to
take a quick look at this patch as well.
Thanks,
Jonathan
> ---
> drivers/iio/accel/Kconfig | 9 +-
> drivers/iio/accel/Makefile | 3 +-
> .../accel/{bmc150-accel.c => bmc150-accel-core.c} | 95 ++++-----------------
> drivers/iio/accel/bmc150-accel-i2c.c | 99 ++++++++++++++++++++++
> drivers/iio/accel/bmc150-accel.h | 21 +++++
> 5 files changed, 144 insertions(+), 83 deletions(-)
> rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
> create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> create mode 100644 drivers/iio/accel/bmc150-accel.h
>
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 01dd03d194d1..6da4eb0db57b 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -19,21 +19,22 @@ config BMA180
>
> config BMC150_ACCEL
> tristate "Bosch BMC150 Accelerometer Driver"
> - depends on I2C
> select IIO_BUFFER
> select IIO_TRIGGERED_BUFFER
> select REGMAP
> - select REGMAP_I2C
> + select BMC150_ACCEL_I2C if I2C
> help
> Say yes here to build support for the following Bosch accelerometers:
> BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
>
> - Currently this only supports the device via an i2c interface.
> -
Well technically this is true until the next patch ;) I'll let that one go
though....
> This is a combo module with both accelerometer and magnetometer.
> This driver is only implementing accelerometer part, which has
> its own address and register map.
>
> +config BMC150_ACCEL_I2C
> + tristate
> + select REGMAP_I2C
> +
> config HID_SENSOR_ACCEL_3D
> depends on HID_SENSOR_HUB
> select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index ebd2675b2a02..5ef8bdbad092 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -4,7 +4,8 @@
>
> # When adding new entries keep the list in alphabetical order
> obj-$(CONFIG_BMA180) += bma180.o
> -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> obj-$(CONFIG_KXSD9) += kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
> similarity index 95%
> rename from drivers/iio/accel/bmc150-accel.c
> rename to drivers/iio/accel/bmc150-accel-core.c
> index e4a0691d9b88..614cf61f0110 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel-core.c
> @@ -37,6 +37,8 @@
> #include <linux/iio/triggered_buffer.h>
> #include <linux/regmap.h>
>
> +#include "bmc150-accel.h"
> +
> #define BMC150_ACCEL_DRV_NAME "bmc150_accel"
> #define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
> #define BMC150_ACCEL_GPIO_NAME "bmc150_accel_int"
> @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
> struct bmc150_accel_data {
> struct regmap *regmap;
> struct device *dev;
> - int irq;
> struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> atomic_t active_intr;
> struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -201,6 +202,7 @@ struct bmc150_accel_data {
> int ev_enable_state;
> int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
> const struct bmc150_accel_chip_info *chip_info;
> + int irq;
Why move the location of this element of the structure?
> };
>
> static const struct {
> @@ -1070,15 +1072,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
> static const struct iio_chan_spec bma280_accel_channels[] =
> BMC150_ACCEL_CHANNELS(14);
>
> -enum {
> - bmc150,
> - bmi055,
> - bma255,
> - bma250e,
> - bma222e,
> - bma280,
> -};
> -
> static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
> [bmc150] = {
> .chip_id = 0xFA,
> @@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
> .postdisable = bmc150_accel_buffer_postdisable,
> };
>
> -static int bmc150_accel_probe(struct i2c_client *client,
> - const struct i2c_device_id *id)
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> + const char *name, int chip_id, bool block_supported)
> {
> struct bmc150_accel_data *data;
> struct iio_dev *indio_dev;
> int ret;
> - const char *name = NULL;
> - int chip_id = 0;
> - struct device *dev;
>
> - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> if (!indio_dev)
> return -ENOMEM;
>
> data = iio_priv(indio_dev);
> - i2c_set_clientdata(client, indio_dev);
> - data->dev = &client->dev;
> - dev = &client->dev;
> - data->irq = client->irq;
> -
> - data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> - if (IS_ERR(data->regmap)) {
> - dev_err(dev, "Failed to initialize i2c regmap\n");
> - return PTR_ERR(data->regmap);
> - }
> -
> - if (id) {
> - name = id->name;
> - chip_id = id->driver_data;
> - }
> + dev_set_drvdata(dev, indio_dev);
> + data->dev = dev;
> + data->irq = irq;
> + data->regmap = regmap;
>
> if (ACPI_HANDLE(dev))
> name = bmc150_accel_match_acpi_device(dev, &chip_id);
> @@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> if (ret)
> goto err_buffer_cleanup;
>
> - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> - i2c_check_functionality(client->adapter,
> - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> + if (block_supported) {
> indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> indio_dev->info = &bmc150_accel_info_fifo;
> indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
> @@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>
> ret = iio_device_register(indio_dev);
> if (ret < 0) {
> - dev_err(data->dev, "Unable to register iio device\n");
> + dev_err(dev, "Unable to register iio device\n");
> goto err_trigger_unregister;
> }
>
> @@ -1692,10 +1669,11 @@ err_buffer_cleanup:
>
> return ret;
> }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
>
> -static int bmc150_accel_remove(struct i2c_client *client)
> +int bmc150_accel_core_remove(struct device *dev)
> {
> - struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
>
> pm_runtime_disable(data->dev);
> @@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
>
> return 0;
> }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
>
> #ifdef CONFIG_PM_SLEEP
> static int bmc150_accel_suspend(struct device *dev)
> @@ -1784,48 +1763,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
> }
> #endif
>
> -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> +const struct dev_pm_ops bmc150_accel_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
> SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
> bmc150_accel_runtime_resume, NULL)
> };
> -
> -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> - {"BSBA0150", bmc150},
> - {"BMC150A", bmc150},
> - {"BMI055A", bmi055},
> - {"BMA0255", bma255},
> - {"BMA250E", bma250e},
> - {"BMA222E", bma222e},
> - {"BMA0280", bma280},
> - { },
> -};
> -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> -
> -static const struct i2c_device_id bmc150_accel_id[] = {
> - {"bmc150_accel", bmc150},
> - {"bmi055_accel", bmi055},
> - {"bma255", bma255},
> - {"bma250e", bma250e},
> - {"bma222e", bma222e},
> - {"bma280", bma280},
> - {}
> -};
> -
> -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> -
> -static struct i2c_driver bmc150_accel_driver = {
> - .driver = {
> - .name = BMC150_ACCEL_DRV_NAME,
> - .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> - .pm = &bmc150_accel_pm_ops,
> - },
> - .probe = bmc150_accel_probe,
> - .remove = bmc150_accel_remove,
> - .id_table = bmc150_accel_id,
> -};
> -module_i2c_driver(bmc150_accel_driver);
> -
> -MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("BMC150 accelerometer driver");
Note we have a core module now so it wants this stuff to still be there.
> diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
> new file mode 100644
> index 000000000000..e4dd596ba8f2
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> @@ -0,0 +1,99 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + * - BMC150
> + * - BMI055
> + * - BMA255
> + * - BMA250E
> + * - BMA222E
> + * - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> + .reg_bits = 8,
> + .val_bits = 8,
> +};
> +
> +static int bmc150_accel_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct regmap *regmap;
> + bool block_supported =
> + i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> + i2c_check_functionality(client->adapter,
> + I2C_FUNC_SMBUS_READ_I2C_BLOCK);
> +
> + regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> + if (IS_ERR(regmap)) {
> + dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> + return PTR_ERR(regmap);
> + }
> +
> + return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
> + id->name, id->driver_data,
> + block_supported);
> +}
> +
> +static int bmc150_accel_remove(struct i2c_client *client)
> +{
> + return bmc150_accel_core_remove(&client->dev);
> +}
> +
> +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> + {"BSBA0150", bmc150},
> + {"BMC150A", bmc150},
> + {"BMI055A", bmi055},
> + {"BMA0255", bma255},
> + {"BMA250E", bma250e},
> + {"BMA222E", bma222e},
> + {"BMA0280", bma280},
> + { },
> +};
> +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> +
> +static const struct i2c_device_id bmc150_accel_id[] = {
> + {"bmc150_accel", bmc150},
> + {"bmi055_accel", bmi055},
> + {"bma255", bma255},
> + {"bma250e", bma250e},
> + {"bma222e", bma222e},
> + {"bma280", bma280},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> +
> +static struct i2c_driver bmc150_accel_driver = {
> + .driver = {
> + .name = "bmc150_accel_i2c",
> + .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> + .pm = &bmc150_accel_pm_ops,
> + },
> + .probe = bmc150_accel_probe,
> + .remove = bmc150_accel_remove,
> + .id_table = bmc150_accel_id,
> +};
> +module_i2c_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
> new file mode 100644
> index 000000000000..988b57573d0c
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel.h
> @@ -0,0 +1,21 @@
> +#ifndef _BMC150_ACCEL_H_
> +#define _BMC150_ACCEL_H_
> +
> +struct regmap;
> +
> +enum {
> + bmc150,
> + bmi055,
> + bma255,
> + bma250e,
> + bma222e,
> + bma280,
> +};
> +
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> + const char *name, int chip_id,
> + bool block_supported);
> +int bmc150_accel_core_remove(struct device *dev);
> +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> +
> +#endif /* _BMC150_ACCEL_H_ */
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] iio: bmc150: Add SPI driver
2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
@ 2015-08-31 16:18 ` Jonathan Cameron
2015-09-01 14:10 ` Srinivas Pandruvada
0 siblings, 1 reply; 21+ messages in thread
From: Jonathan Cameron @ 2015-08-31 16:18 UTC (permalink / raw)
To: Markus Pargmann
Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel
On 20/08/15 13:49, Markus Pargmann wrote:
> Add a simple SPI driver which initializes the spi regmap for the bmc150
> core driver.
>
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Looks good to me, but clearly will have to wait for the earlier
patches in the series.
Nearly there!
Jonathan
> ---
> drivers/iio/accel/Kconfig | 5 +++
> drivers/iio/accel/Makefile | 1 +
> drivers/iio/accel/bmc150-accel-spi.c | 83 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 89 insertions(+)
> create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
>
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 6da4eb0db57b..56d24fa3d34a 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -23,6 +23,7 @@ config BMC150_ACCEL
> select IIO_TRIGGERED_BUFFER
> select REGMAP
> select BMC150_ACCEL_I2C if I2C
> + select BMC150_ACCEL_SPI if SPI
> help
> Say yes here to build support for the following Bosch accelerometers:
> BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> @@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
> tristate
> select REGMAP_I2C
>
> +config BMC150_ACCEL_SPI
> + tristate
> + select REGMAP_SPI
> +
> config HID_SENSOR_ACCEL_3D
> depends on HID_SENSOR_HUB
> select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index 5ef8bdbad092..e579e93bf022 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -6,6 +6,7 @@
> obj-$(CONFIG_BMA180) += bma180.o
> obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> obj-$(CONFIG_KXSD9) += kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
> new file mode 100644
> index 000000000000..1c2a4f683da4
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-spi.c
> @@ -0,0 +1,83 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + * - BMC150
> + * - BMI055
> + * - BMA255
> + * - BMA250E
> + * - BMA222E
> + * - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +#include <linux/spi/spi.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_spi_regmap_conf = {
> + .reg_bits = 8,
> + .val_bits = 8,
> + .max_register = 0x3f,
> +};
> +
> +static int bmc150_accel_probe(struct spi_device *spi)
> +{
> + struct regmap *regmap;
> + const struct spi_device_id *id = spi_get_device_id(spi);
> +
> + regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
> + if (IS_ERR(regmap)) {
> + dev_err(&spi->dev, "Failed to initialize spi regmap\n");
> + return PTR_ERR(regmap);
> + }
> +
> + return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
> + id->name, id->driver_data, true);
> +}
> +
> +static int bmc150_accel_remove(struct spi_device *spi)
> +{
> + return bmc150_accel_core_remove(&spi->dev);
> +}
> +
> +static const struct spi_device_id bmc150_accel_id[] = {
> + {"bmc150_accel", bmc150},
> + {"bmi055_accel", bmi055},
> + {"bma255", bma255},
> + {"bma250e", bma250e},
> + {"bma222e", bma222e},
> + {"bma280", bma280},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> +
> +static struct spi_driver bmc150_accel_driver = {
> + .driver = {
> + .name = "bmc150_accel_spi",
> + .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> + .pm = &bmc150_accel_pm_ops,
> + },
> + .probe = bmc150_accel_probe,
> + .remove = bmc150_accel_remove,
> + .id_table = bmc150_accel_id,
> +};
> +module_spi_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
2015-08-31 16:11 ` Jonathan Cameron
@ 2015-08-31 19:38 ` Srinivas Pandruvada
2015-09-08 1:09 ` Tirdea, Irina
2015-09-01 13:57 ` Srinivas Pandruvada
1 sibling, 1 reply; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-08-31 19:38 UTC (permalink / raw)
To: Jonathan Cameron, Markus Pargmann, Irina Tirdea
Cc: Lars-Peter Clausen, linux-iio, linux-kernel, kernel
Hi Irina,
Is it possible for you to test this patchset? I don't have platform to
test with me now (working remotely for couple of weeks).
Thanks,
Srinivas
On Mon, 2015-08-31 at 17:11 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > This replaces all usage of direct i2c accesses with regmap
> > accesses.
> >
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Looks fine to me, but I will be wanting an Ack / reviewed-by
> and preferably a tested by from Srinivas.
>
> Thanks,
>
> Jonathan
> > ---
> > drivers/iio/accel/Kconfig | 2 +
> > drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------
> > ------------
> > 2 files changed, 95 insertions(+), 126 deletions(-)
> >
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 00e7bcbdbe24..01dd03d194d1 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -22,6 +22,8 @@ config BMC150_ACCEL
> > depends on I2C
> > select IIO_BUFFER
> > select IIO_TRIGGERED_BUFFER
> > + select REGMAP
> > + select REGMAP_I2C
> > help
> > Say yes here to build support for the following Bosch
> > accelerometers:
> > BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > diff --git a/drivers/iio/accel/bmc150-accel.c
> > b/drivers/iio/accel/bmc150-accel.c
> > index 55751d9e1ade..c5c773e75173 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -35,6 +35,7 @@
> > #include <linux/iio/trigger.h>
> > #include <linux/iio/trigger_consumer.h>
> > #include <linux/iio/triggered_buffer.h>
> > +#include <linux/regmap.h>
> >
> > #define BMC150_ACCEL_DRV_NAME "bmc150_accel
> > "
> > #define BMC150_ACCEL_IRQ_NAME "bmc150_accel
> > _event"
> > @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
> >
> > struct bmc150_accel_data {
> > struct i2c_client *client;
> > + struct regmap *regmap;
> > + struct device *dev;
> > struct bmc150_accel_interrupt
> > interrupts[BMC150_ACCEL_INTERRUPTS];
> > atomic_t active_intr;
> > struct bmc150_accel_trigger
> > triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -241,6 +244,11 @@ static const struct {
> > {500000,
> > BMC150_ACCEL_SLEEP_500_MS},
> > {1000000,
> > BMC150_ACCEL_SLEEP_1_SEC} };
> >
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > + .reg_bits = 8,
> > + .val_bits = 8,
> > + .max_register = 0x3f,
> > +};
> >
> > static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> > enum bmc150_power_modes mode,
> > @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct
> > bmc150_accel_data *data,
> >
> > dev_dbg(&data->client->dev, "Set Mode bits %x\n",
> > lpw_bits);
> >
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_PMU_LPW,
> > lpw_bits);
> > + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW,
> > lpw_bits);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_pmu_lpw\n");
> > return ret;
> > @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct
> > bmc150_accel_data *data, int val,
> > for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table);
> > ++i) {
> > if (bmc150_accel_samp_freq_table[i].val == val &&
> > bmc150_accel_samp_freq_table[i].va
> > l2 == val2) {
> > - ret = i2c_smbus_write_byte_data(
> > - data->client,
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_PMU_BW,
> > bmc150_accel_samp_freq_table[i].bw
> > _bits);
> > if (ret < 0)
> > @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct
> > bmc150_accel_data *data, int val,
> >
> > static int bmc150_accel_update_slope(struct bmc150_accel_data
> > *data)
> > {
> > - int ret, val;
> > + int ret;
> >
> > - ret = i2c_smbus_write_byte_data(data->client,
> > BMC150_ACCEL_REG_INT_6,
> > + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> > data->slope_thres);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_int_6\n");
> > return ret;
> > }
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > BMC150_ACCEL_REG_INT_5);
> > + ret = regmap_update_bits(data->regmap,
> > BMC150_ACCEL_REG_INT_5,
> > + BMC150_ACCEL_SLOPE_DUR_MASK, data
> > ->slope_dur);
> > if (ret < 0) {
> > - dev_err(&data->client->dev, "Error reading
> > reg_int_5\n");
> > - return ret;
> > - }
> > -
> > - val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data
> > ->slope_dur;
> > - ret = i2c_smbus_write_byte_data(data->client,
> > BMC150_ACCEL_REG_INT_5,
> > - val);
> > - if (ret < 0) {
> > - dev_err(&data->client->dev, "Error write
> > reg_int_5\n");
> > + dev_err(&data->client->dev, "Error updating
> > reg_int_5\n");
> > return ret;
> > }
> >
> > @@ -348,17 +347,18 @@ static int
> > bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
> > static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> > {
> > int ret;
> > + unsigned int val;
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > BMC150_ACCEL_REG_CHIP_ID);
> > + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID,
> > &val);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > "Error: Reading chip id\n");
> > return ret;
> > }
> >
> > - dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> > - if (ret != data->chip_info->chip_id) {
> > - dev_err(&data->client->dev, "Invalid chip %x\n",
> > ret);
> > + dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> > + if (val != data->chip_info->chip_id) {
> > + dev_err(&data->client->dev, "Invalid chip %x\n",
> > val);
> > return -ENODEV;
> > }
> >
> > @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct
> > bmc150_accel_data *data)
> > return ret;
> >
> > /* Set Default Range */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_PMU_RANGE
> > ,
> > - BMC150_ACCEL_DEF_RANGE_4G)
> > ;
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_PMU_RANGE,
> > + BMC150_ACCEL_DEF_RANGE_4G);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > "Error writing
> > reg_pmu_range\n");
> > @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct
> > bmc150_accel_data *data)
> > return ret;
> >
> > /* Set default as latched interrupts */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > + BMC150_ACCEL_INT_MODE_LATCH_INT |
> > + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > "Error writing reg_int_rst_latch\n");
> > @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct
> > bmc150_accel_data *data, int i,
> > return ret;
> >
> > /* map the interrupt to the appropriate pins */
> > - ret = i2c_smbus_read_byte_data(data->client, info
> > ->map_reg);
> > + ret = regmap_update_bits(data->regmap, info->map_reg, info
> > ->map_bitmask,
> > + (state ? info->map_bitmask : 0));
> > if (ret < 0) {
> > - dev_err(&data->client->dev, "Error reading
> > reg_int_map\n");
> > - goto out_fix_power_state;
> > - }
> > - if (state)
> > - ret |= info->map_bitmask;
> > - else
> > - ret &= ~info->map_bitmask;
> > -
> > - ret = i2c_smbus_write_byte_data(data->client, info
> > ->map_reg,
> > - ret);
> > - if (ret < 0) {
> > - dev_err(&data->client->dev, "Error writing
> > reg_int_map\n");
> > + dev_err(&data->client->dev, "Error updating
> > reg_int_map\n");
> > goto out_fix_power_state;
> > }
> >
> > /* enable/disable the interrupt */
> > - ret = i2c_smbus_read_byte_data(data->client, info
> > ->en_reg);
> > + ret = regmap_update_bits(data->regmap, info->en_reg, info
> > ->en_bitmask,
> > + (state ? info->en_bitmask : 0));
> > if (ret < 0) {
> > - dev_err(&data->client->dev, "Error reading
> > reg_int_en\n");
> > - goto out_fix_power_state;
> > - }
> > -
> > - if (state)
> > - ret |= info->en_bitmask;
> > - else
> > - ret &= ~info->en_bitmask;
> > -
> > - ret = i2c_smbus_write_byte_data(data->client, info
> > ->en_reg, ret);
> > - if (ret < 0) {
> > - dev_err(&data->client->dev, "Error writing
> > reg_int_en\n");
> > + dev_err(&data->client->dev, "Error updating
> > reg_int_en\n");
> > goto out_fix_power_state;
> > }
> >
> > @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct
> > bmc150_accel_data *data, int val)
> >
> > for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table);
> > ++i) {
> > if (data->chip_info->scale_table[i].scale == val)
> > {
> > - ret = i2c_smbus_write_byte_data(
> > - data->client,
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_PMU_RANGE,
> > data->chip_info
> > ->scale_table[i].reg_range);
> > if (ret < 0) {
> > @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct
> > bmc150_accel_data *data, int val)
> > static int bmc150_accel_get_temp(struct bmc150_accel_data *data,
> > int *val)
> > {
> > int ret;
> > + unsigned int value;
> >
> > mutex_lock(&data->mutex);
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > BMC150_ACCEL_REG_TEMP);
> > + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP,
> > &value);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading
> > reg_temp\n");
> > mutex_unlock(&data->mutex);
> > return ret;
> > }
> > - *val = sign_extend32(ret, 7);
> > + *val = sign_extend32(value, 7);
> >
> > mutex_unlock(&data->mutex);
> >
> > @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct
> > bmc150_accel_data *data,
> > {
> > int ret;
> > int axis = chan->scan_index;
> > + unsigned int raw_val;
> >
> > mutex_lock(&data->mutex);
> > ret = bmc150_accel_set_power_state(data, true);
> > @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct
> > bmc150_accel_data *data,
> > return ret;
> > }
> >
> > - ret = i2c_smbus_read_word_data(data->client,
> > -
> > BMC150_ACCEL_AXIS_TO_REG(axis));
> > + ret = regmap_bulk_read(data->regmap,
> > BMC150_ACCEL_AXIS_TO_REG(axis),
> > + &raw_val, 2);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading axis
> > %d\n", axis);
> > bmc150_accel_set_power_state(data, false);
> > mutex_unlock(&data->mutex);
> > return ret;
> > }
> > - *val = sign_extend32(ret >> chan->scan_type.shift,
> > + *val = sign_extend32(raw_val >> chan->scan_type.shift,
> > chan->scan_type.realbits - 1);
> > ret = bmc150_accel_set_power_state(data, false);
> > mutex_unlock(&data->mutex);
> > @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct
> > iio_dev *indio_dev, unsigned val)
> > * We must read at least one full frame in one burst, otherwise
> > the rest of the
> > * frame data is discarded.
> > */
> > -static int bmc150_accel_fifo_transfer(const struct i2c_client
> > *client,
> > +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data
> > *data,
> > char *buffer, int samples)
> > {
> > int sample_length = 3 * 2;
> > - u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> > - int ret = -EIO;
> > -
> > - if (i2c_check_functionality(client->adapter,
> > I2C_FUNC_I2C)) {
> > - struct i2c_msg msg[2] = {
> > - {
> > - .addr = client->addr,
> > - .flags = 0,
> > - .buf = ®_fifo_data,
> > - .len = sizeof(reg_fifo_data),
> > - },
> > - {
> > - .addr = client->addr,
> > - .flags = I2C_M_RD,
> > - .buf = (u8 *)buffer,
> > - .len = samples * sample_length,
> > - }
> > - };
> > + int ret;
> > + int total_length = samples * sample_length;
> > + int i;
> > + int step = regmap_get_raw_read_max(data->regmap);
> >
> > - ret = i2c_transfer(client->adapter, msg, 2);
> > - if (ret != 2)
> > - ret = -EIO;
> > - else
> > - ret = 0;
> > - } else {
> > - int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
> > -
> > - for (i = 0; i < samples * sample_length; i +=
> > step) {
> > - ret =
> > i2c_smbus_read_i2c_block_data(client,
> > -
> > reg_fifo_data, step,
> > -
> > &buffer[i]);
> > - if (ret != step) {
> > - ret = -EIO;
> > - break;
> > - }
> > + if (!step || step > total_length)
> > + step = total_length;
> > + else if (step < total_length)
> > + step = sample_length;
> >
> > - ret = 0;
> > - }
> > + /*
> > + * Seems we have a bus with size limitation so we have to
> > execute
> > + * multiple reads
> > + */
> > + for (i = 0; i < total_length; i += step) {
> > + ret = regmap_raw_read(data->regmap,
> > BMC150_ACCEL_REG_FIFO_DATA,
> > + &buffer[i], step);
> > + if (ret)
> > + break;
> > }
> >
> > if (ret)
> > - dev_err(&client->dev, "Error transferring data
> > from fifo\n");
> > + dev_err(data->dev, "Error transferring data from
> > fifo in single steps of %zu\n",
> > + step);
> >
> > return ret;
> > }
> > @@ -963,14 +924,15 @@ static int __bmc150_accel_fifo_flush(struct
> > iio_dev *indio_dev,
> > u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
> > int64_t tstamp;
> > uint64_t sample_period;
> > - ret = i2c_smbus_read_byte_data(data->client,
> > -
> > BMC150_ACCEL_REG_FIFO_STATUS);
> > + unsigned int val;
> > +
> > + ret = regmap_read(data->regmap,
> > BMC150_ACCEL_REG_FIFO_STATUS, &val);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading
> > reg_fifo_status\n");
> > return ret;
> > }
> >
> > - count = ret & 0x7F;
> > + count = val & 0x7F;
> >
> > if (!count)
> > return 0;
> > @@ -1009,7 +971,7 @@ static int __bmc150_accel_fifo_flush(struct
> > iio_dev *indio_dev,
> > if (samples && count > samples)
> > count = samples;
> >
> > - ret = bmc150_accel_fifo_transfer(data->client, (u8
> > *)buffer, count);
> > + ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer,
> > count);
> > if (ret)
> > return ret;
> >
> > @@ -1206,17 +1168,19 @@ static irqreturn_t
> > bmc150_accel_trigger_handler(int irq, void *p)
> > struct iio_dev *indio_dev = pf->indio_dev;
> > struct bmc150_accel_data *data = iio_priv(indio_dev);
> > int bit, ret, i = 0;
> > + unsigned int raw_val;
> >
> > mutex_lock(&data->mutex);
> > for_each_set_bit(bit, indio_dev->active_scan_mask,
> > indio_dev->masklength) {
> > - ret = i2c_smbus_read_word_data(data->client,
> > -
> > BMC150_ACCEL_AXIS_TO_REG(bit));
> > + ret = regmap_bulk_read(data->regmap,
> > +
> > BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
> > + 2);
> > if (ret < 0) {
> > mutex_unlock(&data->mutex);
> > goto err_read;
> > }
> > - data->buffer[i++] = ret;
> > + data->buffer[i++] = raw_val;
> > }
> > mutex_unlock(&data->mutex);
> >
> > @@ -1240,10 +1204,9 @@ static int bmc150_accel_trig_try_reen(struct
> > iio_trigger *trig)
> >
> > mutex_lock(&data->mutex);
> > /* clear any latched interrupt */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > + BMC150_ACCEL_INT_MODE_LATCH_INT |
> > + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > mutex_unlock(&data->mutex);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > @@ -1300,34 +1263,34 @@ static int
> > bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
> > struct bmc150_accel_data *data = iio_priv(indio_dev);
> > int dir;
> > int ret;
> > + unsigned int val;
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > -
> > BMC150_ACCEL_REG_INT_STATUS_2);
> > + ret = regmap_read(data->regmap,
> > BMC150_ACCEL_REG_INT_STATUS_2, &val);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading
> > reg_int_status_2\n");
> > return ret;
> > }
> >
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> > dir = IIO_EV_DIR_FALLING;
> > else
> > dir = IIO_EV_DIR_RISING;
> >
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
> > iio_push_event(indio_dev,
> > IIO_MOD_EVENT_CODE(IIO_ACCEL,
> > 0,
> > IIO_MOD_X,
> > IIO_EV_TYP
> > E_ROC,
> > dir),
> > data
> > ->timestamp);
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> > iio_push_event(indio_dev,
> > IIO_MOD_EVENT_CODE(IIO_ACCEL,
> > 0,
> > IIO_MOD_Y,
> > IIO_EV_TYP
> > E_ROC,
> > dir),
> > data
> > ->timestamp);
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> > iio_push_event(indio_dev,
> > IIO_MOD_EVENT_CODE(IIO_ACCEL,
> > 0,
> > IIO_MOD_Z,
> > @@ -1360,10 +1323,9 @@ static irqreturn_t
> > bmc150_accel_irq_thread_handler(int irq, void *private)
> > }
> >
> > if (ack) {
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > + BMC150_ACCEL_INT_MODE_LATCH_INT
> > |
> > +
> > BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > if (ret)
> > dev_err(&data->client->dev, "Error writing
> > reg_int_rst_latch\n");
> > ret = IRQ_HANDLED;
> > @@ -1516,7 +1478,7 @@ static int bmc150_accel_fifo_set_mode(struct
> > bmc150_accel_data *data)
> > u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
> > int ret;
> >
> > - ret = i2c_smbus_write_byte_data(data->client, reg, data
> > ->fifo_mode);
> > + ret = regmap_write(data->regmap, reg, data->fifo_mode);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_fifo_config1\n");
> > return ret;
> > @@ -1525,9 +1487,8 @@ static int bmc150_accel_fifo_set_mode(struct
> > bmc150_accel_data *data)
> > if (!data->fifo_mode)
> > return 0;
> >
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_FIFO_CONF
> > IG0,
> > - data->watermark);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_FIFO_CONFIG0,
> > + data->watermark);
> > if (ret < 0)
> > dev_err(&data->client->dev, "Error writing
> > reg_fifo_config0\n");
> >
> > @@ -1627,6 +1588,13 @@ static int bmc150_accel_probe(struct
> > i2c_client *client,
> > data = iio_priv(indio_dev);
> > i2c_set_clientdata(client, indio_dev);
> > data->client = client;
> > + data->dev = &client->dev;
> > +
> > + data->regmap = devm_regmap_init_i2c(client,
> > &bmc150_i2c_regmap_conf);
> > + if (IS_ERR(data->regmap)) {
> > + dev_err(&client->dev, "Failed to initialize i2c
> > regmap\n");
> > + return PTR_ERR(data->regmap);
> > + }
> >
> > if (id) {
> > name = id->name;
> > @@ -1680,9 +1648,8 @@ static int bmc150_accel_probe(struct
> > i2c_client *client,
> > * want to use latch mode when we can to prevent
> > interrupt
> > * flooding.
> > */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_I
> > NT_RST_LATCH,
> > -
> > BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > +
> > BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_int_rst_latch\n");
> > goto err_buffer_cleanup;
> >
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
2015-08-31 16:11 ` Jonathan Cameron
2015-08-31 19:38 ` Srinivas Pandruvada
@ 2015-09-01 13:57 ` Srinivas Pandruvada
1 sibling, 0 replies; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-09-01 13:57 UTC (permalink / raw)
To: Jonathan Cameron, Markus Pargmann
Cc: Irina Tirdea, Lars-Peter Clausen, linux-iio, linux-kernel, kernel
On Mon, 2015-08-31 at 17:11 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > This replaces all usage of direct i2c accesses with regmap
> > accesses.
> >
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Looks fine to me, but I will be wanting an Ack / reviewed-by
> and preferably a tested by from Srinivas.
Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
I requested Irina, if she can test this patch.
Thanks,
Srinivas
>
> Thanks,
>
> Jonathan
> > ---
> > drivers/iio/accel/Kconfig | 2 +
> > drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------
> > ------------
> > 2 files changed, 95 insertions(+), 126 deletions(-)
> >
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 00e7bcbdbe24..01dd03d194d1 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -22,6 +22,8 @@ config BMC150_ACCEL
> > depends on I2C
> > select IIO_BUFFER
> > select IIO_TRIGGERED_BUFFER
> > + select REGMAP
> > + select REGMAP_I2C
> > help
> > Say yes here to build support for the following Bosch
> > accelerometers:
> > BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > diff --git a/drivers/iio/accel/bmc150-accel.c
> > b/drivers/iio/accel/bmc150-accel.c
> > index 55751d9e1ade..c5c773e75173 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -35,6 +35,7 @@
> > #include <linux/iio/trigger.h>
> > #include <linux/iio/trigger_consumer.h>
> > #include <linux/iio/triggered_buffer.h>
> > +#include <linux/regmap.h>
> >
> > #define BMC150_ACCEL_DRV_NAME "bmc150_accel
> > "
> > #define BMC150_ACCEL_IRQ_NAME "bmc150_accel
> > _event"
> > @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
> >
> > struct bmc150_accel_data {
> > struct i2c_client *client;
> > + struct regmap *regmap;
> > + struct device *dev;
> > struct bmc150_accel_interrupt
> > interrupts[BMC150_ACCEL_INTERRUPTS];
> > atomic_t active_intr;
> > struct bmc150_accel_trigger
> > triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -241,6 +244,11 @@ static const struct {
> > {500000,
> > BMC150_ACCEL_SLEEP_500_MS},
> > {1000000,
> > BMC150_ACCEL_SLEEP_1_SEC} };
> >
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > + .reg_bits = 8,
> > + .val_bits = 8,
> > + .max_register = 0x3f,
> > +};
> >
> > static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> > enum bmc150_power_modes mode,
> > @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct
> > bmc150_accel_data *data,
> >
> > dev_dbg(&data->client->dev, "Set Mode bits %x\n",
> > lpw_bits);
> >
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_PMU_LPW,
> > lpw_bits);
> > + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW,
> > lpw_bits);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_pmu_lpw\n");
> > return ret;
> > @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct
> > bmc150_accel_data *data, int val,
> > for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table);
> > ++i) {
> > if (bmc150_accel_samp_freq_table[i].val == val &&
> > bmc150_accel_samp_freq_table[i].va
> > l2 == val2) {
> > - ret = i2c_smbus_write_byte_data(
> > - data->client,
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_PMU_BW,
> > bmc150_accel_samp_freq_table[i].bw
> > _bits);
> > if (ret < 0)
> > @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct
> > bmc150_accel_data *data, int val,
> >
> > static int bmc150_accel_update_slope(struct bmc150_accel_data
> > *data)
> > {
> > - int ret, val;
> > + int ret;
> >
> > - ret = i2c_smbus_write_byte_data(data->client,
> > BMC150_ACCEL_REG_INT_6,
> > + ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> > data->slope_thres);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_int_6\n");
> > return ret;
> > }
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > BMC150_ACCEL_REG_INT_5);
> > + ret = regmap_update_bits(data->regmap,
> > BMC150_ACCEL_REG_INT_5,
> > + BMC150_ACCEL_SLOPE_DUR_MASK, data
> > ->slope_dur);
> > if (ret < 0) {
> > - dev_err(&data->client->dev, "Error reading
> > reg_int_5\n");
> > - return ret;
> > - }
> > -
> > - val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data
> > ->slope_dur;
> > - ret = i2c_smbus_write_byte_data(data->client,
> > BMC150_ACCEL_REG_INT_5,
> > - val);
> > - if (ret < 0) {
> > - dev_err(&data->client->dev, "Error write
> > reg_int_5\n");
> > + dev_err(&data->client->dev, "Error updating
> > reg_int_5\n");
> > return ret;
> > }
> >
> > @@ -348,17 +347,18 @@ static int
> > bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
> > static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> > {
> > int ret;
> > + unsigned int val;
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > BMC150_ACCEL_REG_CHIP_ID);
> > + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID,
> > &val);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > "Error: Reading chip id\n");
> > return ret;
> > }
> >
> > - dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> > - if (ret != data->chip_info->chip_id) {
> > - dev_err(&data->client->dev, "Invalid chip %x\n",
> > ret);
> > + dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> > + if (val != data->chip_info->chip_id) {
> > + dev_err(&data->client->dev, "Invalid chip %x\n",
> > val);
> > return -ENODEV;
> > }
> >
> > @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct
> > bmc150_accel_data *data)
> > return ret;
> >
> > /* Set Default Range */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_PMU_RANGE
> > ,
> > - BMC150_ACCEL_DEF_RANGE_4G)
> > ;
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_PMU_RANGE,
> > + BMC150_ACCEL_DEF_RANGE_4G);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > "Error writing
> > reg_pmu_range\n");
> > @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct
> > bmc150_accel_data *data)
> > return ret;
> >
> > /* Set default as latched interrupts */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > + BMC150_ACCEL_INT_MODE_LATCH_INT |
> > + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > "Error writing reg_int_rst_latch\n");
> > @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct
> > bmc150_accel_data *data, int i,
> > return ret;
> >
> > /* map the interrupt to the appropriate pins */
> > - ret = i2c_smbus_read_byte_data(data->client, info
> > ->map_reg);
> > + ret = regmap_update_bits(data->regmap, info->map_reg, info
> > ->map_bitmask,
> > + (state ? info->map_bitmask : 0));
> > if (ret < 0) {
> > - dev_err(&data->client->dev, "Error reading
> > reg_int_map\n");
> > - goto out_fix_power_state;
> > - }
> > - if (state)
> > - ret |= info->map_bitmask;
> > - else
> > - ret &= ~info->map_bitmask;
> > -
> > - ret = i2c_smbus_write_byte_data(data->client, info
> > ->map_reg,
> > - ret);
> > - if (ret < 0) {
> > - dev_err(&data->client->dev, "Error writing
> > reg_int_map\n");
> > + dev_err(&data->client->dev, "Error updating
> > reg_int_map\n");
> > goto out_fix_power_state;
> > }
> >
> > /* enable/disable the interrupt */
> > - ret = i2c_smbus_read_byte_data(data->client, info
> > ->en_reg);
> > + ret = regmap_update_bits(data->regmap, info->en_reg, info
> > ->en_bitmask,
> > + (state ? info->en_bitmask : 0));
> > if (ret < 0) {
> > - dev_err(&data->client->dev, "Error reading
> > reg_int_en\n");
> > - goto out_fix_power_state;
> > - }
> > -
> > - if (state)
> > - ret |= info->en_bitmask;
> > - else
> > - ret &= ~info->en_bitmask;
> > -
> > - ret = i2c_smbus_write_byte_data(data->client, info
> > ->en_reg, ret);
> > - if (ret < 0) {
> > - dev_err(&data->client->dev, "Error writing
> > reg_int_en\n");
> > + dev_err(&data->client->dev, "Error updating
> > reg_int_en\n");
> > goto out_fix_power_state;
> > }
> >
> > @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct
> > bmc150_accel_data *data, int val)
> >
> > for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table);
> > ++i) {
> > if (data->chip_info->scale_table[i].scale == val)
> > {
> > - ret = i2c_smbus_write_byte_data(
> > - data->client,
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_PMU_RANGE,
> > data->chip_info
> > ->scale_table[i].reg_range);
> > if (ret < 0) {
> > @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct
> > bmc150_accel_data *data, int val)
> > static int bmc150_accel_get_temp(struct bmc150_accel_data *data,
> > int *val)
> > {
> > int ret;
> > + unsigned int value;
> >
> > mutex_lock(&data->mutex);
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > BMC150_ACCEL_REG_TEMP);
> > + ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP,
> > &value);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading
> > reg_temp\n");
> > mutex_unlock(&data->mutex);
> > return ret;
> > }
> > - *val = sign_extend32(ret, 7);
> > + *val = sign_extend32(value, 7);
> >
> > mutex_unlock(&data->mutex);
> >
> > @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct
> > bmc150_accel_data *data,
> > {
> > int ret;
> > int axis = chan->scan_index;
> > + unsigned int raw_val;
> >
> > mutex_lock(&data->mutex);
> > ret = bmc150_accel_set_power_state(data, true);
> > @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct
> > bmc150_accel_data *data,
> > return ret;
> > }
> >
> > - ret = i2c_smbus_read_word_data(data->client,
> > -
> > BMC150_ACCEL_AXIS_TO_REG(axis));
> > + ret = regmap_bulk_read(data->regmap,
> > BMC150_ACCEL_AXIS_TO_REG(axis),
> > + &raw_val, 2);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading axis
> > %d\n", axis);
> > bmc150_accel_set_power_state(data, false);
> > mutex_unlock(&data->mutex);
> > return ret;
> > }
> > - *val = sign_extend32(ret >> chan->scan_type.shift,
> > + *val = sign_extend32(raw_val >> chan->scan_type.shift,
> > chan->scan_type.realbits - 1);
> > ret = bmc150_accel_set_power_state(data, false);
> > mutex_unlock(&data->mutex);
> > @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct
> > iio_dev *indio_dev, unsigned val)
> > * We must read at least one full frame in one burst, otherwise
> > the rest of the
> > * frame data is discarded.
> > */
> > -static int bmc150_accel_fifo_transfer(const struct i2c_client
> > *client,
> > +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data
> > *data,
> > char *buffer, int samples)
> > {
> > int sample_length = 3 * 2;
> > - u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> > - int ret = -EIO;
> > -
> > - if (i2c_check_functionality(client->adapter,
> > I2C_FUNC_I2C)) {
> > - struct i2c_msg msg[2] = {
> > - {
> > - .addr = client->addr,
> > - .flags = 0,
> > - .buf = ®_fifo_data,
> > - .len = sizeof(reg_fifo_data),
> > - },
> > - {
> > - .addr = client->addr,
> > - .flags = I2C_M_RD,
> > - .buf = (u8 *)buffer,
> > - .len = samples * sample_length,
> > - }
> > - };
> > + int ret;
> > + int total_length = samples * sample_length;
> > + int i;
> > + int step = regmap_get_raw_read_max(data->regmap);
> >
> > - ret = i2c_transfer(client->adapter, msg, 2);
> > - if (ret != 2)
> > - ret = -EIO;
> > - else
> > - ret = 0;
> > - } else {
> > - int i, step = I2C_SMBUS_BLOCK_MAX / sample_length;
> > -
> > - for (i = 0; i < samples * sample_length; i +=
> > step) {
> > - ret =
> > i2c_smbus_read_i2c_block_data(client,
> > -
> > reg_fifo_data, step,
> > -
> > &buffer[i]);
> > - if (ret != step) {
> > - ret = -EIO;
> > - break;
> > - }
> > + if (!step || step > total_length)
> > + step = total_length;
> > + else if (step < total_length)
> > + step = sample_length;
> >
> > - ret = 0;
> > - }
> > + /*
> > + * Seems we have a bus with size limitation so we have to
> > execute
> > + * multiple reads
> > + */
> > + for (i = 0; i < total_length; i += step) {
> > + ret = regmap_raw_read(data->regmap,
> > BMC150_ACCEL_REG_FIFO_DATA,
> > + &buffer[i], step);
> > + if (ret)
> > + break;
> > }
> >
> > if (ret)
> > - dev_err(&client->dev, "Error transferring data
> > from fifo\n");
> > + dev_err(data->dev, "Error transferring data from
> > fifo in single steps of %zu\n",
> > + step);
> >
> > return ret;
> > }
> > @@ -963,14 +924,15 @@ static int __bmc150_accel_fifo_flush(struct
> > iio_dev *indio_dev,
> > u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
> > int64_t tstamp;
> > uint64_t sample_period;
> > - ret = i2c_smbus_read_byte_data(data->client,
> > -
> > BMC150_ACCEL_REG_FIFO_STATUS);
> > + unsigned int val;
> > +
> > + ret = regmap_read(data->regmap,
> > BMC150_ACCEL_REG_FIFO_STATUS, &val);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading
> > reg_fifo_status\n");
> > return ret;
> > }
> >
> > - count = ret & 0x7F;
> > + count = val & 0x7F;
> >
> > if (!count)
> > return 0;
> > @@ -1009,7 +971,7 @@ static int __bmc150_accel_fifo_flush(struct
> > iio_dev *indio_dev,
> > if (samples && count > samples)
> > count = samples;
> >
> > - ret = bmc150_accel_fifo_transfer(data->client, (u8
> > *)buffer, count);
> > + ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer,
> > count);
> > if (ret)
> > return ret;
> >
> > @@ -1206,17 +1168,19 @@ static irqreturn_t
> > bmc150_accel_trigger_handler(int irq, void *p)
> > struct iio_dev *indio_dev = pf->indio_dev;
> > struct bmc150_accel_data *data = iio_priv(indio_dev);
> > int bit, ret, i = 0;
> > + unsigned int raw_val;
> >
> > mutex_lock(&data->mutex);
> > for_each_set_bit(bit, indio_dev->active_scan_mask,
> > indio_dev->masklength) {
> > - ret = i2c_smbus_read_word_data(data->client,
> > -
> > BMC150_ACCEL_AXIS_TO_REG(bit));
> > + ret = regmap_bulk_read(data->regmap,
> > +
> > BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
> > + 2);
> > if (ret < 0) {
> > mutex_unlock(&data->mutex);
> > goto err_read;
> > }
> > - data->buffer[i++] = ret;
> > + data->buffer[i++] = raw_val;
> > }
> > mutex_unlock(&data->mutex);
> >
> > @@ -1240,10 +1204,9 @@ static int bmc150_accel_trig_try_reen(struct
> > iio_trigger *trig)
> >
> > mutex_lock(&data->mutex);
> > /* clear any latched interrupt */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > + BMC150_ACCEL_INT_MODE_LATCH_INT |
> > + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > mutex_unlock(&data->mutex);
> > if (ret < 0) {
> > dev_err(&data->client->dev,
> > @@ -1300,34 +1263,34 @@ static int
> > bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
> > struct bmc150_accel_data *data = iio_priv(indio_dev);
> > int dir;
> > int ret;
> > + unsigned int val;
> >
> > - ret = i2c_smbus_read_byte_data(data->client,
> > -
> > BMC150_ACCEL_REG_INT_STATUS_2);
> > + ret = regmap_read(data->regmap,
> > BMC150_ACCEL_REG_INT_STATUS_2, &val);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error reading
> > reg_int_status_2\n");
> > return ret;
> > }
> >
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> > dir = IIO_EV_DIR_FALLING;
> > else
> > dir = IIO_EV_DIR_RISING;
> >
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
> > iio_push_event(indio_dev,
> > IIO_MOD_EVENT_CODE(IIO_ACCEL,
> > 0,
> > IIO_MOD_X,
> > IIO_EV_TYP
> > E_ROC,
> > dir),
> > data
> > ->timestamp);
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> > iio_push_event(indio_dev,
> > IIO_MOD_EVENT_CODE(IIO_ACCEL,
> > 0,
> > IIO_MOD_Y,
> > IIO_EV_TYP
> > E_ROC,
> > dir),
> > data
> > ->timestamp);
> > - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> > + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> > iio_push_event(indio_dev,
> > IIO_MOD_EVENT_CODE(IIO_ACCEL,
> > 0,
> > IIO_MOD_Z,
> > @@ -1360,10 +1323,9 @@ static irqreturn_t
> > bmc150_accel_irq_thread_handler(int irq, void *private)
> > }
> >
> > if (ack) {
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > - BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > + BMC150_ACCEL_INT_MODE_LATCH_INT
> > |
> > +
> > BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > if (ret)
> > dev_err(&data->client->dev, "Error writing
> > reg_int_rst_latch\n");
> > ret = IRQ_HANDLED;
> > @@ -1516,7 +1478,7 @@ static int bmc150_accel_fifo_set_mode(struct
> > bmc150_accel_data *data)
> > u8 reg = BMC150_ACCEL_REG_FIFO_CONFIG1;
> > int ret;
> >
> > - ret = i2c_smbus_write_byte_data(data->client, reg, data
> > ->fifo_mode);
> > + ret = regmap_write(data->regmap, reg, data->fifo_mode);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_fifo_config1\n");
> > return ret;
> > @@ -1525,9 +1487,8 @@ static int bmc150_accel_fifo_set_mode(struct
> > bmc150_accel_data *data)
> > if (!data->fifo_mode)
> > return 0;
> >
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_FIFO_CONF
> > IG0,
> > - data->watermark);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_FIFO_CONFIG0,
> > + data->watermark);
> > if (ret < 0)
> > dev_err(&data->client->dev, "Error writing
> > reg_fifo_config0\n");
> >
> > @@ -1627,6 +1588,13 @@ static int bmc150_accel_probe(struct
> > i2c_client *client,
> > data = iio_priv(indio_dev);
> > i2c_set_clientdata(client, indio_dev);
> > data->client = client;
> > + data->dev = &client->dev;
> > +
> > + data->regmap = devm_regmap_init_i2c(client,
> > &bmc150_i2c_regmap_conf);
> > + if (IS_ERR(data->regmap)) {
> > + dev_err(&client->dev, "Failed to initialize i2c
> > regmap\n");
> > + return PTR_ERR(data->regmap);
> > + }
> >
> > if (id) {
> > name = id->name;
> > @@ -1680,9 +1648,8 @@ static int bmc150_accel_probe(struct
> > i2c_client *client,
> > * want to use latch mode when we can to prevent
> > interrupt
> > * flooding.
> > */
> > - ret = i2c_smbus_write_byte_data(data->client,
> > - BMC150_ACCEL_REG_I
> > NT_RST_LATCH,
> > -
> > BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > + ret = regmap_write(data->regmap,
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > +
> > BMC150_ACCEL_INT_MODE_LATCH_RESET);
> > if (ret < 0) {
> > dev_err(&data->client->dev, "Error writing
> > reg_int_rst_latch\n");
> > goto err_buffer_cleanup;
> >
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
2015-08-31 16:15 ` Jonathan Cameron
@ 2015-09-01 14:07 ` Srinivas Pandruvada
0 siblings, 0 replies; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-09-01 14:07 UTC (permalink / raw)
To: Jonathan Cameron, Markus Pargmann
Cc: Irina Tirdea, Lars-Peter Clausen, linux-iio, linux-kernel, kernel
On Mon, 2015-08-31 at 17:15 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> A couple of little bits inline. Again would like Srinivas to
> take a quick look at this patch as well.
Once your comments are addressed, it looks fine to me.
Thanks,
Srinivas
>
> Jonathan
> > ---
> > drivers/iio/accel/Kconfig | 9 +-
> > drivers/iio/accel/Makefile | 3 +-
> > .../accel/{bmc150-accel.c => bmc150-accel-core.c} | 95 ++++------
> > -----------
> > drivers/iio/accel/bmc150-accel-i2c.c | 99
> > ++++++++++++++++++++++
> > drivers/iio/accel/bmc150-accel.h | 21 +++++
> > 5 files changed, 144 insertions(+), 83 deletions(-)
> > rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c}
> > (95%)
> > create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> > create mode 100644 drivers/iio/accel/bmc150-accel.h
> >
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 01dd03d194d1..6da4eb0db57b 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -19,21 +19,22 @@ config BMA180
> >
> > config BMC150_ACCEL
> > tristate "Bosch BMC150 Accelerometer Driver"
> > - depends on I2C
> > select IIO_BUFFER
> > select IIO_TRIGGERED_BUFFER
> > select REGMAP
> > - select REGMAP_I2C
> > + select BMC150_ACCEL_I2C if I2C
> > help
> > Say yes here to build support for the following Bosch
> > accelerometers:
> > BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> >
> > - Currently this only supports the device via an i2c
> > interface.
> > -
> Well technically this is true until the next patch ;) I'll let that
> one go
> though....
> > This is a combo module with both accelerometer and
> > magnetometer.
> > This driver is only implementing accelerometer part,
> > which has
> > its own address and register map.
> >
> > +config BMC150_ACCEL_I2C
> > + tristate
> > + select REGMAP_I2C
> > +
> > config HID_SENSOR_ACCEL_3D
> > depends on HID_SENSOR_HUB
> > select IIO_BUFFER
> > diff --git a/drivers/iio/accel/Makefile
> > b/drivers/iio/accel/Makefile
> > index ebd2675b2a02..5ef8bdbad092 100644
> > --- a/drivers/iio/accel/Makefile
> > +++ b/drivers/iio/accel/Makefile
> > @@ -4,7 +4,8 @@
> >
> > # When adding new entries keep the list in alphabetical order
> > obj-$(CONFIG_BMA180) += bma180.o
> > -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> > +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> > +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> > obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> > obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> > obj-$(CONFIG_KXSD9) += kxsd9.o
> > diff --git a/drivers/iio/accel/bmc150-accel.c
> > b/drivers/iio/accel/bmc150-accel-core.c
> > similarity index 95%
> > rename from drivers/iio/accel/bmc150-accel.c
> > rename to drivers/iio/accel/bmc150-accel-core.c
> > index e4a0691d9b88..614cf61f0110 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel-core.c
> > @@ -37,6 +37,8 @@
> > #include <linux/iio/triggered_buffer.h>
> > #include <linux/regmap.h>
> >
> > +#include "bmc150-accel.h"
> > +
> > #define BMC150_ACCEL_DRV_NAME "bmc150_accel
> > "
> > #define BMC150_ACCEL_IRQ_NAME "bmc150_accel
> > _event"
> > #define BMC150_ACCEL_GPIO_NAME "bmc150_acce
> > l_int"
> > @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
> > struct bmc150_accel_data {
> > struct regmap *regmap;
> > struct device *dev;
> > - int irq;
> > struct bmc150_accel_interrupt
> > interrupts[BMC150_ACCEL_INTERRUPTS];
> > atomic_t active_intr;
> > struct bmc150_accel_trigger
> > triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -201,6 +202,7 @@ struct bmc150_accel_data {
> > int ev_enable_state;
> > int64_t timestamp, old_timestamp; /* Only used in hw fifo
> > mode. */
> > const struct bmc150_accel_chip_info *chip_info;
> > + int irq;
> Why move the location of this element of the structure?
>
> > };
> >
> > static const struct {
> > @@ -1070,15 +1072,6 @@ static const struct iio_chan_spec
> > bmc150_accel_channels[] =
> > static const struct iio_chan_spec bma280_accel_channels[] =
> > BMC150_ACCEL_CHANNELS(14);
> >
> > -enum {
> > - bmc150,
> > - bmi055,
> > - bma255,
> > - bma250e,
> > - bma222e,
> > - bma280,
> > -};
> > -
> > static const struct bmc150_accel_chip_info
> > bmc150_accel_chip_info_tbl[] = {
> > [bmc150] = {
> > .chip_id = 0xFA,
> > @@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops
> > bmc150_accel_buffer_ops = {
> > .postdisable = bmc150_accel_buffer_postdisable,
> > };
> >
> > -static int bmc150_accel_probe(struct i2c_client *client,
> > - const struct i2c_device_id *id)
> > +int bmc150_accel_core_probe(struct device *dev, struct regmap
> > *regmap, int irq,
> > + const char *name, int chip_id, bool
> > block_supported)
> > {
> > struct bmc150_accel_data *data;
> > struct iio_dev *indio_dev;
> > int ret;
> > - const char *name = NULL;
> > - int chip_id = 0;
> > - struct device *dev;
> >
> > - indio_dev = devm_iio_device_alloc(&client->dev,
> > sizeof(*data));
> > + indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> > if (!indio_dev)
> > return -ENOMEM;
> >
> > data = iio_priv(indio_dev);
> > - i2c_set_clientdata(client, indio_dev);
> > - data->dev = &client->dev;
> > - dev = &client->dev;
> > - data->irq = client->irq;
> > -
> > - data->regmap = devm_regmap_init_i2c(client,
> > &bmc150_i2c_regmap_conf);
> > - if (IS_ERR(data->regmap)) {
> > - dev_err(dev, "Failed to initialize i2c regmap\n");
> > - return PTR_ERR(data->regmap);
> > - }
> > -
> > - if (id) {
> > - name = id->name;
> > - chip_id = id->driver_data;
> > - }
> > + dev_set_drvdata(dev, indio_dev);
> > + data->dev = dev;
> > + data->irq = irq;
> > + data->regmap = regmap;
> >
> > if (ACPI_HANDLE(dev))
> > name = bmc150_accel_match_acpi_device(dev,
> > &chip_id);
> > @@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct
> > i2c_client *client,
> > if (ret)
> > goto err_buffer_cleanup;
> >
> > - if (i2c_check_functionality(client->adapter,
> > I2C_FUNC_I2C) ||
> > - i2c_check_functionality(client->adapter,
> > -
> > I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> > + if (block_supported) {
> > indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> > indio_dev->info = &bmc150_accel_info_fifo;
> > indio_dev->buffer->attrs =
> > bmc150_accel_fifo_attributes;
> > @@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct
> > i2c_client *client,
> >
> > ret = iio_device_register(indio_dev);
> > if (ret < 0) {
> > - dev_err(data->dev, "Unable to register iio
> > device\n");
> > + dev_err(dev, "Unable to register iio device\n");
> > goto err_trigger_unregister;
> > }
> >
> > @@ -1692,10 +1669,11 @@ err_buffer_cleanup:
> >
> > return ret;
> > }
> > +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
> >
> > -static int bmc150_accel_remove(struct i2c_client *client)
> > +int bmc150_accel_core_remove(struct device *dev)
> > {
> > - struct iio_dev *indio_dev = i2c_get_clientdata(client);
> > + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> > struct bmc150_accel_data *data = iio_priv(indio_dev);
> >
> > pm_runtime_disable(data->dev);
> > @@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct
> > i2c_client *client)
> >
> > return 0;
> > }
> > +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
> >
> > #ifdef CONFIG_PM_SLEEP
> > static int bmc150_accel_suspend(struct device *dev)
> > @@ -1784,48 +1763,8 @@ static int
> > bmc150_accel_runtime_resume(struct device *dev)
> > }
> > #endif
> >
> > -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> > +const struct dev_pm_ops bmc150_accel_pm_ops = {
> > SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend,
> > bmc150_accel_resume)
> > SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
> > bmc150_accel_runtime_resume, NULL)
> > };
> > -
> > -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> > - {"BSBA0150", bmc150},
> > - {"BMC150A", bmc150},
> > - {"BMI055A", bmi055},
> > - {"BMA0255", bma255},
> > - {"BMA250E", bma250e},
> > - {"BMA222E", bma222e},
> > - {"BMA0280", bma280},
> > - { },
> > -};
> > -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> > -
> > -static const struct i2c_device_id bmc150_accel_id[] = {
> > - {"bmc150_accel", bmc150},
> > - {"bmi055_accel", bmi055},
> > - {"bma255", bma255},
> > - {"bma250e", bma250e},
> > - {"bma222e", bma222e},
> > - {"bma280", bma280},
> > - {}
> > -};
> > -
> > -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> > -
> > -static struct i2c_driver bmc150_accel_driver = {
> > - .driver = {
> > - .name = BMC150_ACCEL_DRV_NAME,
> > - .acpi_match_table =
> > ACPI_PTR(bmc150_accel_acpi_match),
> > - .pm = &bmc150_accel_pm_ops,
> > - },
> > - .probe = bmc150_accel_probe,
> > - .remove = bmc150_accel_remove,
> > - .id_table = bmc150_accel_id,
> > -};
> > -module_i2c_driver(bmc150_accel_driver);
> > -
> > -MODULE_AUTHOR("Srinivas Pandruvada <
> > srinivas.pandruvada@linux.intel.com>");
> > -MODULE_LICENSE("GPL v2");
> > -MODULE_DESCRIPTION("BMC150 accelerometer driver");
> Note we have a core module now so it wants this stuff to still be
> there.
>
> > diff --git a/drivers/iio/accel/bmc150-accel-i2c.c
> > b/drivers/iio/accel/bmc150-accel-i2c.c
> > new file mode 100644
> > index 000000000000..e4dd596ba8f2
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> > @@ -0,0 +1,99 @@
> > +/*
> > + * 3-axis accelerometer driver supporting following I2C Bosch
> > -Sensortec chips:
> > + * - BMC150
> > + * - BMI055
> > + * - BMA255
> > + * - BMA250E
> > + * - BMA222E
> > + * - BMA280
> > + *
> > + * Copyright (c) 2014, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify it
> > + * under the terms and conditions of the GNU General Public
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope 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/device.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/regmap.h>
> > +
> > +#include "bmc150-accel.h"
> > +
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > + .reg_bits = 8,
> > + .val_bits = 8,
> > +};
> > +
> > +static int bmc150_accel_probe(struct i2c_client *client,
> > + const struct i2c_device_id *id)
> > +{
> > + struct regmap *regmap;
> > + bool block_supported =
> > + i2c_check_functionality(client->adapter,
> > I2C_FUNC_I2C) ||
> > + i2c_check_functionality(client->adapter,
> > + I2C_FUNC_SMBUS_READ_I2C_BL
> > OCK);
> > +
> > + regmap = devm_regmap_init_i2c(client,
> > &bmc150_i2c_regmap_conf);
> > + if (IS_ERR(regmap)) {
> > + dev_err(&client->dev, "Failed to initialize i2c
> > regmap\n");
> > + return PTR_ERR(regmap);
> > + }
> > +
> > + return bmc150_accel_core_probe(&client->dev, regmap,
> > client->irq,
> > + id->name, id->driver_data,
> > + block_supported);
> > +}
> > +
> > +static int bmc150_accel_remove(struct i2c_client *client)
> > +{
> > + return bmc150_accel_core_remove(&client->dev);
> > +}
> > +
> > +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> > + {"BSBA0150", bmc150},
> > + {"BMC150A", bmc150},
> > + {"BMI055A", bmi055},
> > + {"BMA0255", bma255},
> > + {"BMA250E", bma250e},
> > + {"BMA222E", bma222e},
> > + {"BMA0280", bma280},
> > + { },
> > +};
> > +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> > +
> > +static const struct i2c_device_id bmc150_accel_id[] = {
> > + {"bmc150_accel", bmc150},
> > + {"bmi055_accel", bmi055},
> > + {"bma255", bma255},
> > + {"bma250e", bma250e},
> > + {"bma222e", bma222e},
> > + {"bma280", bma280},
> > + {}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> > +
> > +static struct i2c_driver bmc150_accel_driver = {
> > + .driver = {
> > + .name = "bmc150_accel_i2c",
> > + .acpi_match_table =
> > ACPI_PTR(bmc150_accel_acpi_match),
> > + .pm = &bmc150_accel_pm_ops,
> > + },
> > + .probe = bmc150_accel_probe,
> > + .remove = bmc150_accel_remove,
> > + .id_table = bmc150_accel_id,
> > +};
> > +module_i2c_driver(bmc150_accel_driver);
> > +
> > +MODULE_AUTHOR("Srinivas Pandruvada <
> > srinivas.pandruvada@linux.intel.com>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> > diff --git a/drivers/iio/accel/bmc150-accel.h
> > b/drivers/iio/accel/bmc150-accel.h
> > new file mode 100644
> > index 000000000000..988b57573d0c
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel.h
> > @@ -0,0 +1,21 @@
> > +#ifndef _BMC150_ACCEL_H_
> > +#define _BMC150_ACCEL_H_
> > +
> > +struct regmap;
> > +
> > +enum {
> > + bmc150,
> > + bmi055,
> > + bma255,
> > + bma250e,
> > + bma222e,
> > + bma280,
> > +};
> > +
> > +int bmc150_accel_core_probe(struct device *dev, struct regmap
> > *regmap, int irq,
> > + const char *name, int chip_id,
> > + bool block_supported);
> > +int bmc150_accel_core_remove(struct device *dev);
> > +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> > +
> > +#endif /* _BMC150_ACCEL_H_ */
> >
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] iio: bmc150: Add SPI driver
2015-08-31 16:18 ` Jonathan Cameron
@ 2015-09-01 14:10 ` Srinivas Pandruvada
2015-09-16 10:01 ` Markus Pargmann
0 siblings, 1 reply; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-09-01 14:10 UTC (permalink / raw)
To: Jonathan Cameron, Markus Pargmann
Cc: Irina Tirdea, Lars-Peter Clausen, linux-iio, linux-kernel, kernel
On Mon, 2015-08-31 at 17:18 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > Add a simple SPI driver which initializes the spi regmap for the
> > bmc150
> > core driver.
> >
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Looks good to me, but clearly will have to wait for the earlier
> patches in the series.
>
> Nearly there!
>
> Jonathan
> > ---
> > drivers/iio/accel/Kconfig | 5 +++
> > drivers/iio/accel/Makefile | 1 +
> > drivers/iio/accel/bmc150-accel-spi.c | 83
> > ++++++++++++++++++++++++++++++++++++
> > 3 files changed, 89 insertions(+)
> > create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> >
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 6da4eb0db57b..56d24fa3d34a 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -23,6 +23,7 @@ config BMC150_ACCEL
> > select IIO_TRIGGERED_BUFFER
> > select REGMAP
> > select BMC150_ACCEL_I2C if I2C
> > + select BMC150_ACCEL_SPI if SPI
> > help
> > Say yes here to build support for the following Bosch
> > accelerometers:
> > BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > @@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
> > tristate
> > select REGMAP_I2C
> >
> > +config BMC150_ACCEL_SPI
> > + tristate
> > + select REGMAP_SPI
> > +
> > config HID_SENSOR_ACCEL_3D
> > depends on HID_SENSOR_HUB
> > select IIO_BUFFER
> > diff --git a/drivers/iio/accel/Makefile
> > b/drivers/iio/accel/Makefile
> > index 5ef8bdbad092..e579e93bf022 100644
> > --- a/drivers/iio/accel/Makefile
> > +++ b/drivers/iio/accel/Makefile
> > @@ -6,6 +6,7 @@
> > obj-$(CONFIG_BMA180) += bma180.o
> > obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> > obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> > +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> > obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> > obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> > obj-$(CONFIG_KXSD9) += kxsd9.o
> > diff --git a/drivers/iio/accel/bmc150-accel-spi.c
> > b/drivers/iio/accel/bmc150-accel-spi.c
> > new file mode 100644
> > index 000000000000..1c2a4f683da4
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel-spi.c
> > @@ -0,0 +1,83 @@
> > +/*
> > + * 3-axis accelerometer driver supporting following I2C Bosch
> > -Sensortec chips:
> > + * - BMC150
> > + * - BMI055
> > + * - BMA255
> > + * - BMA250E
> > + * - BMA222E
> > + * - BMA280
> > + *
> > + * Copyright (c) 2014, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > modify it
> > + * under the terms and conditions of the GNU General Public
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope 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.
> > + */
Not sure If you want to carry Intel Copyright for SPI driver part. If
you want to use change the year to 2015.
> > +
> > +#include <linux/device.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/regmap.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#include "bmc150-accel.h"
> > +
> > +static const struct regmap_config bmc150_spi_regmap_conf = {
> > + .reg_bits = 8,
> > + .val_bits = 8,
> > + .max_register = 0x3f,
> > +};
> > +
> > +static int bmc150_accel_probe(struct spi_device *spi)
> > +{
> > + struct regmap *regmap;
> > + const struct spi_device_id *id = spi_get_device_id(spi);
> > +
> > + regmap = devm_regmap_init_spi(spi,
> > &bmc150_spi_regmap_conf);
> > + if (IS_ERR(regmap)) {
> > + dev_err(&spi->dev, "Failed to initialize spi
> > regmap\n");
> > + return PTR_ERR(regmap);
> > + }
> > +
> > + return bmc150_accel_core_probe(&spi->dev, regmap, spi
> > ->irq,
> > + id->name, id->driver_data,
> > true);
> > +}
> > +
> > +static int bmc150_accel_remove(struct spi_device *spi)
> > +{
> > + return bmc150_accel_core_remove(&spi->dev);
> > +}
> > +
> > +static const struct spi_device_id bmc150_accel_id[] = {
> > + {"bmc150_accel", bmc150},
> > + {"bmi055_accel", bmi055},
> > + {"bma255", bma255},
> > + {"bma250e", bma250e},
> > + {"bma222e", bma222e},
> > + {"bma280", bma280},
> > + {}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> > +
> > +static struct spi_driver bmc150_accel_driver = {
> > + .driver = {
> > + .name = "bmc150_accel_spi",
> > + .acpi_match_table =
> > ACPI_PTR(bmc150_accel_acpi_match),
> > + .pm = &bmc150_accel_pm_ops,
> > + },
> > + .probe = bmc150_accel_probe,
> > + .remove = bmc150_accel_remove,
> > + .id_table = bmc150_accel_id,
> > +};
> > +module_spi_driver(bmc150_accel_driver);
> > +
> > +MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> >
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
2015-08-31 19:38 ` Srinivas Pandruvada
@ 2015-09-08 1:09 ` Tirdea, Irina
0 siblings, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-08 1:09 UTC (permalink / raw)
To: Srinivas Pandruvada, Jonathan Cameron, Markus Pargmann
Cc: Lars-Peter Clausen, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, kernel@pengutronix.de
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogU3Jpbml2YXMgUGFuZHJ1
dmFkYSBbbWFpbHRvOnNyaW5pdmFzLnBhbmRydXZhZGFAbGludXguaW50ZWwuY29tXQ0KPiBTZW50
OiAzMSBBdWd1c3QsIDIwMTUgMjI6MzkNCj4gVG86IEpvbmF0aGFuIENhbWVyb247IE1hcmt1cyBQ
YXJnbWFubjsgVGlyZGVhLCBJcmluYQ0KPiBDYzogTGFycy1QZXRlciBDbGF1c2VuOyBsaW51eC1p
aW9Admdlci5rZXJuZWwub3JnOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOyBrZXJuZWxA
cGVuZ3V0cm9uaXguZGUNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2MiAxLzRdIGlpbzogYm1jMTUw
OiBVc2UgaTJjIHJlZ21hcA0KPiANCj4gSGkgSXJpbmEsDQo+IA0KDQpIaSBTcmluaXZhcywNCg0K
PiBJcyBpdCBwb3NzaWJsZSBmb3IgeW91IHRvIHRlc3QgdGhpcyBwYXRjaHNldD8gSSBkb24ndCBo
YXZlIHBsYXRmb3JtIHRvDQo+IHRlc3Qgd2l0aCBtZSBub3cgKHdvcmtpbmcgcmVtb3RlbHkgZm9y
IGNvdXBsZSBvZiB3ZWVrcykuDQo+IA0KDQpTdXJlLCBJJ2xsIHRlc3QgdGhpcyBwYXRjaCBzZXQg
dG9kYXkuDQpTb3JyeSBmb3IgdGhlIGxhdGUgcmVzcG9uc2UsIHNlZW1zIEkgc29tZWhvdyBtaXNz
ZWQgeW91ciBlLW1haWwuDQoNClJlZ2FyZHMsDQpJcmluYQ0KDQo+IFRoYW5rcywNCj4gU3Jpbml2
YXMNCj4gDQo+IE9uIE1vbiwgMjAxNS0wOC0zMSBhdCAxNzoxMSArMDEwMCwgSm9uYXRoYW4gQ2Ft
ZXJvbiB3cm90ZToNCj4gPiBPbiAyMC8wOC8xNSAxMzo0OSwgTWFya3VzIFBhcmdtYW5uIHdyb3Rl
Og0KPiA+ID4gVGhpcyByZXBsYWNlcyBhbGwgdXNhZ2Ugb2YgZGlyZWN0IGkyYyBhY2Nlc3NlcyB3
aXRoIHJlZ21hcA0KPiA+ID4gYWNjZXNzZXMuDQo+ID4gPg0KPiA+ID4gU2lnbmVkLW9mZi1ieTog
TWFya3VzIFBhcmdtYW5uIDxtcGFAcGVuZ3V0cm9uaXguZGU+DQo+ID4gTG9va3MgZmluZSB0byBt
ZSwgIGJ1dCBJIHdpbGwgYmUgd2FudGluZyBhbiBBY2sgLyByZXZpZXdlZC1ieQ0KPiA+IGFuZCBw
cmVmZXJhYmx5IGEgdGVzdGVkIGJ5IGZyb20gU3Jpbml2YXMuDQo+ID4NCj4gPiBUaGFua3MsDQo+
ID4NCj4gPiBKb25hdGhhbg0KPiA+ID4gLS0tDQo+ID4gPiAgZHJpdmVycy9paW8vYWNjZWwvS2Nv
bmZpZyAgICAgICAgfCAgIDIgKw0KPiA+ID4gIGRyaXZlcnMvaWlvL2FjY2VsL2JtYzE1MC1hY2Nl
bC5jIHwgMjE5ICsrKysrKysrKysrKysrKysrLS0tLS0tLS0tLQ0KPiA+ID4gLS0tLS0tLS0tLS0t
DQo+ID4gPiAgMiBmaWxlcyBjaGFuZ2VkLCA5NSBpbnNlcnRpb25zKCspLCAxMjYgZGVsZXRpb25z
KC0pDQo+ID4gPg0KPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaWlvL2FjY2VsL0tjb25maWcg
Yi9kcml2ZXJzL2lpby9hY2NlbC9LY29uZmlnDQo+ID4gPiBpbmRleCAwMGU3YmNiZGJlMjQuLjAx
ZGQwM2QxOTRkMSAxMDA2NDQNCj4gPiA+IC0tLSBhL2RyaXZlcnMvaWlvL2FjY2VsL0tjb25maWcN
Cj4gPiA+ICsrKyBiL2RyaXZlcnMvaWlvL2FjY2VsL0tjb25maWcNCj4gPiA+IEBAIC0yMiw2ICsy
Miw4IEBAIGNvbmZpZyBCTUMxNTBfQUNDRUwNCj4gPiA+ICAJZGVwZW5kcyBvbiBJMkMNCj4gPiA+
ICAJc2VsZWN0IElJT19CVUZGRVINCj4gPiA+ICAJc2VsZWN0IElJT19UUklHR0VSRURfQlVGRkVS
DQo+ID4gPiArCXNlbGVjdCBSRUdNQVANCj4gPiA+ICsJc2VsZWN0IFJFR01BUF9JMkMNCj4gPiA+
ICAJaGVscA0KPiA+ID4gIAkgIFNheSB5ZXMgaGVyZSB0byBidWlsZCBzdXBwb3J0IGZvciB0aGUg
Zm9sbG93aW5nIEJvc2NoDQo+ID4gPiBhY2NlbGVyb21ldGVyczoNCj4gPiA+ICAJICBCTUMxNTAs
IEJNSTA1NSwgQk1BMjUwRSwgQk1BMjIyRSwgQk1BMjU1LCBCTUEyODAuDQo+ID4gPiBkaWZmIC0t
Z2l0IGEvZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFjY2VsLmMNCj4gPiA+IGIvZHJpdmVycy9p
aW8vYWNjZWwvYm1jMTUwLWFjY2VsLmMNCj4gPiA+IGluZGV4IDU1NzUxZDllMWFkZS4uYzVjNzcz
ZTc1MTczIDEwMDY0NA0KPiA+ID4gLS0tIGEvZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFjY2Vs
LmMNCj4gPiA+ICsrKyBiL2RyaXZlcnMvaWlvL2FjY2VsL2JtYzE1MC1hY2NlbC5jDQo+ID4gPiBA
QCAtMzUsNiArMzUsNyBAQA0KPiA+ID4gICNpbmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlci5oPg0K
PiA+ID4gICNpbmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcl9jb25zdW1lci5oPg0KPiA+ID4gICNp
bmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcmVkX2J1ZmZlci5oPg0KPiA+ID4gKyNpbmNsdWRlIDxs
aW51eC9yZWdtYXAuaD4NCj4gPiA+DQo+ID4gPiAgI2RlZmluZSBCTUMxNTBfQUNDRUxfRFJWX05B
TUUJCQkiYm1jMTUwX2FjY2VsDQo+ID4gPiAiDQo+ID4gPiAgI2RlZmluZSBCTUMxNTBfQUNDRUxf
SVJRX05BTUUJCQkiYm1jMTUwX2FjY2VsDQo+ID4gPiBfZXZlbnQiDQo+ID4gPiBAQCAtMTg1LDYg
KzE4Niw4IEBAIGVudW0gYm1jMTUwX2FjY2VsX3RyaWdnZXJfaWQgew0KPiA+ID4NCj4gPiA+ICBz
dHJ1Y3QgYm1jMTUwX2FjY2VsX2RhdGEgew0KPiA+ID4gIAlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xp
ZW50Ow0KPiA+ID4gKwlzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7DQo+ID4gPiArCXN0cnVjdCBkZXZp
Y2UgKmRldjsNCj4gPiA+ICAJc3RydWN0IGJtYzE1MF9hY2NlbF9pbnRlcnJ1cHQNCj4gPiA+IGlu
dGVycnVwdHNbQk1DMTUwX0FDQ0VMX0lOVEVSUlVQVFNdOw0KPiA+ID4gIAlhdG9taWNfdCBhY3Rp
dmVfaW50cjsNCj4gPiA+ICAJc3RydWN0IGJtYzE1MF9hY2NlbF90cmlnZ2VyDQo+ID4gPiB0cmln
Z2Vyc1tCTUMxNTBfQUNDRUxfVFJJR0dFUlNdOw0KPiA+ID4gQEAgLTI0MSw2ICsyNDQsMTEgQEAg
c3RhdGljIGNvbnN0IHN0cnVjdCB7DQo+ID4gPiAgCQkJCSAgICAgICB7NTAwMDAwLA0KPiA+ID4g
Qk1DMTUwX0FDQ0VMX1NMRUVQXzUwMF9NU30sDQo+ID4gPiAgCQkJCSAgICAgICB7MTAwMDAwMCwN
Cj4gPiA+IEJNQzE1MF9BQ0NFTF9TTEVFUF8xX1NFQ30gfTsNCj4gPiA+DQo+ID4gPiArc3RhdGlj
IGNvbnN0IHN0cnVjdCByZWdtYXBfY29uZmlnIGJtYzE1MF9pMmNfcmVnbWFwX2NvbmYgPSB7DQo+
ID4gPiArCS5yZWdfYml0cyA9IDgsDQo+ID4gPiArCS52YWxfYml0cyA9IDgsDQo+ID4gPiArCS5t
YXhfcmVnaXN0ZXIgPSAweDNmLA0KPiA+ID4gK307DQo+ID4gPg0KPiA+ID4gIHN0YXRpYyBpbnQg
Ym1jMTUwX2FjY2VsX3NldF9tb2RlKHN0cnVjdCBibWMxNTBfYWNjZWxfZGF0YSAqZGF0YSwNCj4g
PiA+ICAJCQkJIGVudW0gYm1jMTUwX3Bvd2VyX21vZGVzIG1vZGUsDQo+ID4gPiBAQCAtMjcwLDgg
KzI3OCw3IEBAIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3NldF9tb2RlKHN0cnVjdA0KPiA+ID4g
Ym1jMTUwX2FjY2VsX2RhdGEgKmRhdGEsDQo+ID4gPg0KPiA+ID4gIAlkZXZfZGJnKCZkYXRhLT5j
bGllbnQtPmRldiwgIlNldCBNb2RlIGJpdHMgJXhcbiIsDQo+ID4gPiBscHdfYml0cyk7DQo+ID4g
Pg0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwN
Cj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9SRUdfUE1VX0xQVywNCj4gPiA+IGxwd19iaXRzKTsN
Cj4gPiA+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKGRhdGEtPnJlZ21hcCwgQk1DMTUwX0FDQ0VMX1JF
R19QTVVfTFBXLA0KPiA+ID4gbHB3X2JpdHMpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+
ID4gIAkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB3cml0aW5nDQo+ID4gPiBy
ZWdfcG11X2xwd1xuIik7DQo+ID4gPiAgCQlyZXR1cm4gcmV0Ow0KPiA+ID4gQEAgLTI4OSw4ICsy
OTYsNyBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9zZXRfYncoc3RydWN0DQo+ID4gPiBibWMx
NTBfYWNjZWxfZGF0YSAqZGF0YSwgaW50IHZhbCwNCj4gPiA+ICAJZm9yIChpID0gMDsgaSA8IEFS
UkFZX1NJWkUoYm1jMTUwX2FjY2VsX3NhbXBfZnJlcV90YWJsZSk7DQo+ID4gPiArK2kpIHsNCj4g
PiA+ICAJCWlmIChibWMxNTBfYWNjZWxfc2FtcF9mcmVxX3RhYmxlW2ldLnZhbCA9PSB2YWwgJiYN
Cj4gPiA+ICAJCQkJYm1jMTUwX2FjY2VsX3NhbXBfZnJlcV90YWJsZVtpXS52YQ0KPiA+ID4gbDIg
PT0gdmFsMikgew0KPiA+ID4gLQkJCXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoDQo+
ID4gPiAtCQkJCWRhdGEtPmNsaWVudCwNCj4gPiA+ICsJCQlyZXQgPSByZWdtYXBfd3JpdGUoZGF0
YS0+cmVnbWFwLA0KPiA+ID4gIAkJCQlCTUMxNTBfQUNDRUxfUkVHX1BNVV9CVywNCj4gPiA+ICAJ
CQkJYm1jMTUwX2FjY2VsX3NhbXBfZnJlcV90YWJsZVtpXS5idw0KPiA+ID4gX2JpdHMpOw0KPiA+
ID4gIAkJCWlmIChyZXQgPCAwKQ0KPiA+ID4gQEAgLTMwNywyNiArMzEzLDE5IEBAIHN0YXRpYyBp
bnQgYm1jMTUwX2FjY2VsX3NldF9idyhzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9hY2NlbF9kYXRhICpk
YXRhLCBpbnQgdmFsLA0KPiA+ID4NCj4gPiA+ICBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF91cGRh
dGVfc2xvcGUoc3RydWN0IGJtYzE1MF9hY2NlbF9kYXRhDQo+ID4gPiAqZGF0YSkNCj4gPiA+ICB7
DQo+ID4gPiAtCWludCByZXQsIHZhbDsNCj4gPiA+ICsJaW50IHJldDsNCj4gPiA+DQo+ID4gPiAt
CXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gQk1D
MTUwX0FDQ0VMX1JFR19JTlRfNiwNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKGRhdGEtPnJl
Z21hcCwgQk1DMTUwX0FDQ0VMX1JFR19JTlRfNiwNCj4gPiA+ICAJCQkJCWRhdGEtPnNsb3BlX3Ro
cmVzKTsNCj4gPiA+ICAJaWYgKHJldCA8IDApIHsNCj4gPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNs
aWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZw0KPiA+ID4gcmVnX2ludF82XG4iKTsNCj4gPiA+ICAJ
CXJldHVybiByZXQ7DQo+ID4gPiAgCX0NCj4gPiA+DQo+ID4gPiAtCXJldCA9IGkyY19zbWJ1c19y
ZWFkX2J5dGVfZGF0YShkYXRhLT5jbGllbnQsDQo+ID4gPiBCTUMxNTBfQUNDRUxfUkVHX0lOVF81
KTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRzKGRhdGEtPnJlZ21hcCwNCj4gPiA+
IEJNQzE1MF9BQ0NFTF9SRUdfSU5UXzUsDQo+ID4gPiArCQkJCSBCTUMxNTBfQUNDRUxfU0xPUEVf
RFVSX01BU0ssIGRhdGENCj4gPiA+IC0+c2xvcGVfZHVyKTsNCj4gPiA+ICAJaWYgKHJldCA8IDAp
IHsNCj4gPiA+IC0JCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiRXJyb3IgcmVhZGluZw0K
PiA+ID4gcmVnX2ludF81XG4iKTsNCj4gPiA+IC0JCXJldHVybiByZXQ7DQo+ID4gPiAtCX0NCj4g
PiA+IC0NCj4gPiA+IC0JdmFsID0gKHJldCAmIH5CTUMxNTBfQUNDRUxfU0xPUEVfRFVSX01BU0sp
IHwgZGF0YQ0KPiA+ID4gLT5zbG9wZV9kdXI7DQo+ID4gPiAtCXJldCA9IGkyY19zbWJ1c193cml0
ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfNSwN
Cj4gPiA+IC0JCQkJCXZhbCk7DQo+ID4gPiAtCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAtCQlkZXZf
ZXJyKCZkYXRhLT5jbGllbnQtPmRldiwgIkVycm9yIHdyaXRlDQo+ID4gPiByZWdfaW50XzVcbiIp
Ow0KPiA+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB1cGRhdGluZw0K
PiA+ID4gcmVnX2ludF81XG4iKTsNCj4gPiA+ICAJCXJldHVybiByZXQ7DQo+ID4gPiAgCX0NCj4g
PiA+DQo+ID4gPiBAQCAtMzQ4LDE3ICszNDcsMTggQEAgc3RhdGljIGludA0KPiA+ID4gYm1jMTUw
X2FjY2VsX2FueV9tb3Rpb25fc2V0dXAoc3RydWN0IGJtYzE1MF9hY2NlbF90cmlnZ2VyICp0LA0K
PiA+ID4gIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX2NoaXBfaW5pdChzdHJ1Y3QgYm1jMTUwX2Fj
Y2VsX2RhdGEgKmRhdGEpDQo+ID4gPiAgew0KPiA+ID4gIAlpbnQgcmV0Ow0KPiA+ID4gKwl1bnNp
Z25lZCBpbnQgdmFsOw0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9k
YXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9SRUdfQ0hJUF9JRCk7DQo+ID4g
PiArCXJldCA9IHJlZ21hcF9yZWFkKGRhdGEtPnJlZ21hcCwgQk1DMTUwX0FDQ0VMX1JFR19DSElQ
X0lELA0KPiA+ID4gJnZhbCk7DQo+ID4gPiAgCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAgCQlkZXZf
ZXJyKCZkYXRhLT5jbGllbnQtPmRldiwNCj4gPiA+ICAJCQkiRXJyb3I6IFJlYWRpbmcgY2hpcCBp
ZFxuIik7DQo+ID4gPiAgCQlyZXR1cm4gcmV0Ow0KPiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4gLQlk
ZXZfZGJnKCZkYXRhLT5jbGllbnQtPmRldiwgIkNoaXAgSWQgJXhcbiIsIHJldCk7DQo+ID4gPiAt
CWlmIChyZXQgIT0gZGF0YS0+Y2hpcF9pbmZvLT5jaGlwX2lkKSB7DQo+ID4gPiAtCQlkZXZfZXJy
KCZkYXRhLT5jbGllbnQtPmRldiwgIkludmFsaWQgY2hpcCAleFxuIiwNCj4gPiA+IHJldCk7DQo+
ID4gPiArCWRldl9kYmcoJmRhdGEtPmNsaWVudC0+ZGV2LCAiQ2hpcCBJZCAleFxuIiwgdmFsKTsN
Cj4gPiA+ICsJaWYgKHZhbCAhPSBkYXRhLT5jaGlwX2luZm8tPmNoaXBfaWQpIHsNCj4gPiA+ICsJ
CWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiSW52YWxpZCBjaGlwICV4XG4iLA0KPiA+ID4g
dmFsKTsNCj4gPiA+ICAJCXJldHVybiAtRU5PREVWOw0KPiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4g
QEAgLTM3Miw5ICszNzIsOCBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9jaGlwX2luaXQoc3Ry
dWN0DQo+ID4gPiBibWMxNTBfYWNjZWxfZGF0YSAqZGF0YSkNCj4gPiA+ICAJCXJldHVybiByZXQ7
DQo+ID4gPg0KPiA+ID4gIAkvKiBTZXQgRGVmYXVsdCBSYW5nZSAqLw0KPiA+ID4gLQlyZXQgPSBp
MmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0JCQkJCUJNQzE1
MF9BQ0NFTF9SRUdfUE1VX1JBTkdFDQo+ID4gPiAsDQo+ID4gPiAtCQkJCQlCTUMxNTBfQUNDRUxf
REVGX1JBTkdFXzRHKQ0KPiA+ID4gOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfd3JpdGUoZGF0YS0+
cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19QTVVfUkFOR0UsDQo+ID4gPiArCQkJICAg
Qk1DMTUwX0FDQ0VMX0RFRl9SQU5HRV80Ryk7DQo+ID4gPiAgCWlmIChyZXQgPCAwKSB7DQo+ID4g
PiAgCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRldiwNCj4gPiA+ICAJCQkJCSJFcnJvciB3cml0
aW5nDQo+ID4gPiByZWdfcG11X3JhbmdlXG4iKTsNCj4gPiA+IEBAIC0zOTEsMTAgKzM5MCw5IEBA
IHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX2NoaXBfaW5pdChzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9h
Y2NlbF9kYXRhICpkYXRhKQ0KPiA+ID4gIAkJcmV0dXJuIHJldDsNCj4gPiA+DQo+ID4gPiAgCS8q
IFNldCBkZWZhdWx0IGFzIGxhdGNoZWQgaW50ZXJydXB0cyAqLw0KPiA+ID4gLQlyZXQgPSBpMmNf
c21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0JCQkJCUJNQzE1MF9B
Q0NFTF9SRUdfSU5UX1JTVF9MDQo+ID4gPiBBVENILA0KPiA+ID4gLQkJCQkJQk1DMTUwX0FDQ0VM
X0lOVF9NT0RFX0xBVEMNCj4gPiA+IEhfSU5UIHwNCj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9J
TlRfTU9ERV9MQVRDDQo+ID4gPiBIX1JFU0VUKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3dyaXRl
KGRhdGEtPnJlZ21hcCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9SRUdfSU5UX1JTVF9MQVRDSCwNCj4g
PiA+ICsJCQkgICBCTUMxNTBfQUNDRUxfSU5UX01PREVfTEFUQ0hfSU5UIHwNCj4gPiA+ICsJCQkg
ICBCTUMxNTBfQUNDRUxfSU5UX01PREVfTEFUQ0hfUkVTRVQpOw0KPiA+ID4gIAlpZiAocmV0IDwg
MCkgew0KPiA+ID4gIAkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsDQo+ID4gPiAgCQkJIkVy
cm9yIHdyaXRpbmcgcmVnX2ludF9yc3RfbGF0Y2hcbiIpOw0KPiA+ID4gQEAgLTUyNywzOCArNTI1
LDE4IEBAIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3NldF9pbnRlcnJ1cHQoc3RydWN0DQo+ID4g
PiBibWMxNTBfYWNjZWxfZGF0YSAqZGF0YSwgaW50IGksDQo+ID4gPiAgCQlyZXR1cm4gcmV0Ow0K
PiA+ID4NCj4gPiA+ICAJLyogbWFwIHRoZSBpbnRlcnJ1cHQgdG8gdGhlIGFwcHJvcHJpYXRlIHBp
bnMgKi8NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRhKGRhdGEtPmNsaWVu
dCwgaW5mbw0KPiA+ID4gLT5tYXBfcmVnKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9i
aXRzKGRhdGEtPnJlZ21hcCwgaW5mby0+bWFwX3JlZywgaW5mbw0KPiA+ID4gLT5tYXBfYml0bWFz
aywNCj4gPiA+ICsJCQkJIChzdGF0ZSA/IGluZm8tPm1hcF9iaXRtYXNrIDogMCkpOw0KPiA+ID4g
IAlpZiAocmV0IDwgMCkgew0KPiA+ID4gLQkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJF
cnJvciByZWFkaW5nDQo+ID4gPiByZWdfaW50X21hcFxuIik7DQo+ID4gPiAtCQlnb3RvIG91dF9m
aXhfcG93ZXJfc3RhdGU7DQo+ID4gPiAtCX0NCj4gPiA+IC0JaWYgKHN0YXRlKQ0KPiA+ID4gLQkJ
cmV0IHw9IGluZm8tPm1hcF9iaXRtYXNrOw0KPiA+ID4gLQllbHNlDQo+ID4gPiAtCQlyZXQgJj0g
fmluZm8tPm1hcF9iaXRtYXNrOw0KPiA+ID4gLQ0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3Jp
dGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwgaW5mbw0KPiA+ID4gLT5tYXBfcmVnLA0KPiA+ID4g
LQkJCQkJcmV0KTsNCj4gPiA+IC0JaWYgKHJldCA8IDApIHsNCj4gPiA+IC0JCWRldl9lcnIoJmRh
dGEtPmNsaWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZw0KPiA+ID4gcmVnX2ludF9tYXBcbiIpOw0K
PiA+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB1cGRhdGluZw0KPiA+
ID4gcmVnX2ludF9tYXBcbiIpOw0KPiA+ID4gIAkJZ290byBvdXRfZml4X3Bvd2VyX3N0YXRlOw0K
PiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4gIAkvKiBlbmFibGUvZGlzYWJsZSB0aGUgaW50ZXJydXB0
ICovDQo+ID4gPiAtCXJldCA9IGkyY19zbWJ1c19yZWFkX2J5dGVfZGF0YShkYXRhLT5jbGllbnQs
IGluZm8NCj4gPiA+IC0+ZW5fcmVnKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRz
KGRhdGEtPnJlZ21hcCwgaW5mby0+ZW5fcmVnLCBpbmZvDQo+ID4gPiAtPmVuX2JpdG1hc2ssDQo+
ID4gPiArCQkJCSAoc3RhdGUgPyBpbmZvLT5lbl9iaXRtYXNrIDogMCkpOw0KPiA+ID4gIAlpZiAo
cmV0IDwgMCkgew0KPiA+ID4gLQkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciBy
ZWFkaW5nDQo+ID4gPiByZWdfaW50X2VuXG4iKTsNCj4gPiA+IC0JCWdvdG8gb3V0X2ZpeF9wb3dl
cl9zdGF0ZTsNCj4gPiA+IC0JfQ0KPiA+ID4gLQ0KPiA+ID4gLQlpZiAoc3RhdGUpDQo+ID4gPiAt
CQlyZXQgfD0gaW5mby0+ZW5fYml0bWFzazsNCj4gPiA+IC0JZWxzZQ0KPiA+ID4gLQkJcmV0ICY9
IH5pbmZvLT5lbl9iaXRtYXNrOw0KPiA+ID4gLQ0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3Jp
dGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwgaW5mbw0KPiA+ID4gLT5lbl9yZWcsIHJldCk7DQo+
ID4gPiAtCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAtCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRl
diwgIkVycm9yIHdyaXRpbmcNCj4gPiA+IHJlZ19pbnRfZW5cbiIpOw0KPiA+ID4gKwkJZGV2X2Vy
cigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB1cGRhdGluZw0KPiA+ID4gcmVnX2ludF9lblxu
Iik7DQo+ID4gPiAgCQlnb3RvIG91dF9maXhfcG93ZXJfc3RhdGU7DQo+ID4gPiAgCX0NCj4gPiA+
DQo+ID4gPiBAQCAtNTgxLDggKzU1OSw3IEBAIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3NldF9z
Y2FsZShzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLCBpbnQgdmFsKQ0KPiA+
ID4NCj4gPiA+ICAJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUoZGF0YS0+Y2hpcF9pbmZvLT5z
Y2FsZV90YWJsZSk7DQo+ID4gPiArK2kpIHsNCj4gPiA+ICAJCWlmIChkYXRhLT5jaGlwX2luZm8t
PnNjYWxlX3RhYmxlW2ldLnNjYWxlID09IHZhbCkNCj4gPiA+IHsNCj4gPiA+IC0JCQlyZXQgPSBp
MmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKA0KPiA+ID4gLQkJCQkgICAgIGRhdGEtPmNsaWVudCwN
Cj4gPiA+ICsJCQlyZXQgPSByZWdtYXBfd3JpdGUoZGF0YS0+cmVnbWFwLA0KPiA+ID4gIAkJCQkg
ICAgIEJNQzE1MF9BQ0NFTF9SRUdfUE1VX1JBTkdFLA0KPiA+ID4gIAkJCQkgICAgIGRhdGEtPmNo
aXBfaW5mbw0KPiA+ID4gLT5zY2FsZV90YWJsZVtpXS5yZWdfcmFuZ2UpOw0KPiA+ID4gIAkJCWlm
IChyZXQgPCAwKSB7DQo+ID4gPiBAQCAtNjAyLDE2ICs1NzksMTcgQEAgc3RhdGljIGludCBibWMx
NTBfYWNjZWxfc2V0X3NjYWxlKHN0cnVjdA0KPiA+ID4gYm1jMTUwX2FjY2VsX2RhdGEgKmRhdGEs
IGludCB2YWwpDQo+ID4gPiAgc3RhdGljIGludCBibWMxNTBfYWNjZWxfZ2V0X3RlbXAoc3RydWN0
IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLA0KPiA+ID4gaW50ICp2YWwpDQo+ID4gPiAgew0KPiA+
ID4gIAlpbnQgcmV0Ow0KPiA+ID4gKwl1bnNpZ25lZCBpbnQgdmFsdWU7DQo+ID4gPg0KPiA+ID4g
IAltdXRleF9sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gPg0KPiA+ID4gLQlyZXQgPSBpMmNfc21i
dXNfcmVhZF9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19U
RU1QKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3JlYWQoZGF0YS0+cmVnbWFwLCBCTUMxNTBfQUND
RUxfUkVHX1RFTVAsDQo+ID4gPiAmdmFsdWUpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+
ID4gIAkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciByZWFkaW5nDQo+ID4gPiBy
ZWdfdGVtcFxuIik7DQo+ID4gPiAgCQltdXRleF91bmxvY2soJmRhdGEtPm11dGV4KTsNCj4gPiA+
ICAJCXJldHVybiByZXQ7DQo+ID4gPiAgCX0NCj4gPiA+IC0JKnZhbCA9IHNpZ25fZXh0ZW5kMzIo
cmV0LCA3KTsNCj4gPiA+ICsJKnZhbCA9IHNpZ25fZXh0ZW5kMzIodmFsdWUsIDcpOw0KPiA+ID4N
Cj4gPiA+ICAJbXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gPg0KPiA+ID4gQEAgLTYy
NCw2ICs2MDIsNyBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9nZXRfYXhpcyhzdHJ1Y3QNCj4g
PiA+IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLA0KPiA+ID4gIHsNCj4gPiA+ICAJaW50IHJldDsN
Cj4gPiA+ICAJaW50IGF4aXMgPSBjaGFuLT5zY2FuX2luZGV4Ow0KPiA+ID4gKwl1bnNpZ25lZCBp
bnQgcmF3X3ZhbDsNCj4gPiA+DQo+ID4gPiAgCW11dGV4X2xvY2soJmRhdGEtPm11dGV4KTsNCj4g
PiA+ICAJcmV0ID0gYm1jMTUwX2FjY2VsX3NldF9wb3dlcl9zdGF0ZShkYXRhLCB0cnVlKTsNCj4g
PiA+IEBAIC02MzIsMTUgKzYxMSwxNSBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9nZXRfYXhp
cyhzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLA0KPiA+ID4gIAkJcmV0dXJu
IHJldDsNCj4gPiA+ICAJfQ0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3JlYWRfd29y
ZF9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0NCj4gPiA+ICBCTUMxNTBfQUNDRUxfQVhJU19U
T19SRUcoYXhpcykpOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfYnVsa19yZWFkKGRhdGEtPnJlZ21h
cCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9BWElTX1RPX1JFRyhheGlzKSwNCj4gPiA+ICsJCQkgICAg
ICAgJnJhd192YWwsIDIpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJZGV2X2Vy
cigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciByZWFkaW5nIGF4aXMNCj4gPiA+ICVkXG4iLCBh
eGlzKTsNCj4gPiA+ICAJCWJtYzE1MF9hY2NlbF9zZXRfcG93ZXJfc3RhdGUoZGF0YSwgZmFsc2Up
Ow0KPiA+ID4gIAkJbXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gPiAgCQlyZXR1cm4g
cmV0Ow0KPiA+ID4gIAl9DQo+ID4gPiAtCSp2YWwgPSBzaWduX2V4dGVuZDMyKHJldCA+PiBjaGFu
LT5zY2FuX3R5cGUuc2hpZnQsDQo+ID4gPiArCSp2YWwgPSBzaWduX2V4dGVuZDMyKHJhd192YWwg
Pj4gY2hhbi0+c2Nhbl90eXBlLnNoaWZ0LA0KPiA+ID4gIAkJCSAgICAgY2hhbi0+c2Nhbl90eXBl
LnJlYWxiaXRzIC0gMSk7DQo+ID4gPiAgCXJldCA9IGJtYzE1MF9hY2NlbF9zZXRfcG93ZXJfc3Rh
dGUoZGF0YSwgZmFsc2UpOw0KPiA+ID4gIAltdXRleF91bmxvY2soJmRhdGEtPm11dGV4KTsNCj4g
PiA+IEBAIC05MDQsNTIgKzg4MywzNCBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9zZXRfd2F0
ZXJtYXJrKHN0cnVjdA0KPiA+ID4gaWlvX2RldiAqaW5kaW9fZGV2LCB1bnNpZ25lZCB2YWwpDQo+
ID4gPiAgICogV2UgbXVzdCByZWFkIGF0IGxlYXN0IG9uZSBmdWxsIGZyYW1lIGluIG9uZSBidXJz
dCwgb3RoZXJ3aXNlDQo+ID4gPiB0aGUgcmVzdCBvZiB0aGUNCj4gPiA+ICAgKiBmcmFtZSBkYXRh
IGlzIGRpc2NhcmRlZC4NCj4gPiA+ICAgKi8NCj4gPiA+IC1zdGF0aWMgaW50IGJtYzE1MF9hY2Nl
bF9maWZvX3RyYW5zZmVyKGNvbnN0IHN0cnVjdCBpMmNfY2xpZW50DQo+ID4gPiAqY2xpZW50LA0K
PiA+ID4gK3N0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX2ZpZm9fdHJhbnNmZXIoc3RydWN0IGJtYzE1
MF9hY2NlbF9kYXRhDQo+ID4gPiAqZGF0YSwNCj4gPiA+ICAJCQkJICAgICAgY2hhciAqYnVmZmVy
LCBpbnQgc2FtcGxlcykNCj4gPiA+ICB7DQo+ID4gPiAgCWludCBzYW1wbGVfbGVuZ3RoID0gMyAq
IDI7DQo+ID4gPiAtCXU4IHJlZ19maWZvX2RhdGEgPSBCTUMxNTBfQUNDRUxfUkVHX0ZJRk9fREFU
QTsNCj4gPiA+IC0JaW50IHJldCA9IC1FSU87DQo+ID4gPiAtDQo+ID4gPiAtCWlmIChpMmNfY2hl
Y2tfZnVuY3Rpb25hbGl0eShjbGllbnQtPmFkYXB0ZXIsDQo+ID4gPiBJMkNfRlVOQ19JMkMpKSB7
DQo+ID4gPiAtCQlzdHJ1Y3QgaTJjX21zZyBtc2dbMl0gPSB7DQo+ID4gPiAtCQkJew0KPiA+ID4g
LQkJCQkuYWRkciA9IGNsaWVudC0+YWRkciwNCj4gPiA+IC0JCQkJLmZsYWdzID0gMCwNCj4gPiA+
IC0JCQkJLmJ1ZiA9ICZyZWdfZmlmb19kYXRhLA0KPiA+ID4gLQkJCQkubGVuID0gc2l6ZW9mKHJl
Z19maWZvX2RhdGEpLA0KPiA+ID4gLQkJCX0sDQo+ID4gPiAtCQkJew0KPiA+ID4gLQkJCQkuYWRk
ciA9IGNsaWVudC0+YWRkciwNCj4gPiA+IC0JCQkJLmZsYWdzID0gSTJDX01fUkQsDQo+ID4gPiAt
CQkJCS5idWYgPSAodTggKilidWZmZXIsDQo+ID4gPiAtCQkJCS5sZW4gPSBzYW1wbGVzICogc2Ft
cGxlX2xlbmd0aCwNCj4gPiA+IC0JCQl9DQo+ID4gPiAtCQl9Ow0KPiA+ID4gKwlpbnQgcmV0Ow0K
PiA+ID4gKwlpbnQgdG90YWxfbGVuZ3RoID0gc2FtcGxlcyAqIHNhbXBsZV9sZW5ndGg7DQo+ID4g
PiArCWludCBpOw0KPiA+ID4gKwlpbnQgc3RlcCA9IHJlZ21hcF9nZXRfcmF3X3JlYWRfbWF4KGRh
dGEtPnJlZ21hcCk7DQo+ID4gPg0KPiA+ID4gLQkJcmV0ID0gaTJjX3RyYW5zZmVyKGNsaWVudC0+
YWRhcHRlciwgbXNnLCAyKTsNCj4gPiA+IC0JCWlmIChyZXQgIT0gMikNCj4gPiA+IC0JCQlyZXQg
PSAtRUlPOw0KPiA+ID4gLQkJZWxzZQ0KPiA+ID4gLQkJCXJldCA9IDA7DQo+ID4gPiAtCX0gZWxz
ZSB7DQo+ID4gPiAtCQlpbnQgaSwgc3RlcCA9IEkyQ19TTUJVU19CTE9DS19NQVggLyBzYW1wbGVf
bGVuZ3RoOw0KPiA+ID4gLQ0KPiA+ID4gLQkJZm9yIChpID0gMDsgaSA8IHNhbXBsZXMgKiBzYW1w
bGVfbGVuZ3RoOyBpICs9DQo+ID4gPiBzdGVwKSB7DQo+ID4gPiAtCQkJcmV0ID0NCj4gPiA+IGky
Y19zbWJ1c19yZWFkX2kyY19ibG9ja19kYXRhKGNsaWVudCwNCj4gPiA+IC0NCj4gPiA+ICByZWdf
Zmlmb19kYXRhLCBzdGVwLA0KPiA+ID4gLQ0KPiA+ID4gICZidWZmZXJbaV0pOw0KPiA+ID4gLQkJ
CWlmIChyZXQgIT0gc3RlcCkgew0KPiA+ID4gLQkJCQlyZXQgPSAtRUlPOw0KPiA+ID4gLQkJCQli
cmVhazsNCj4gPiA+IC0JCQl9DQo+ID4gPiArCWlmICghc3RlcCB8fCBzdGVwID4gdG90YWxfbGVu
Z3RoKQ0KPiA+ID4gKwkJc3RlcCA9IHRvdGFsX2xlbmd0aDsNCj4gPiA+ICsJZWxzZSBpZiAoc3Rl
cCA8IHRvdGFsX2xlbmd0aCkNCj4gPiA+ICsJCXN0ZXAgPSBzYW1wbGVfbGVuZ3RoOw0KPiA+ID4N
Cj4gPiA+IC0JCQlyZXQgPSAwOw0KPiA+ID4gLQkJfQ0KPiA+ID4gKwkvKg0KPiA+ID4gKwkgKiBT
ZWVtcyB3ZSBoYXZlIGEgYnVzIHdpdGggc2l6ZSBsaW1pdGF0aW9uIHNvIHdlIGhhdmUgdG8NCj4g
PiA+IGV4ZWN1dGUNCj4gPiA+ICsJICogbXVsdGlwbGUgcmVhZHMNCj4gPiA+ICsJICovDQo+ID4g
PiArCWZvciAoaSA9IDA7IGkgPCB0b3RhbF9sZW5ndGg7IGkgKz0gc3RlcCkgew0KPiA+ID4gKwkJ
cmV0ID0gcmVnbWFwX3Jhd19yZWFkKGRhdGEtPnJlZ21hcCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9S
RUdfRklGT19EQVRBLA0KPiA+ID4gKwkJCQkgICAgICAmYnVmZmVyW2ldLCBzdGVwKTsNCj4gPiA+
ICsJCWlmIChyZXQpDQo+ID4gPiArCQkJYnJlYWs7DQo+ID4gPiAgCX0NCj4gPiA+DQo+ID4gPiAg
CWlmIChyZXQpDQo+ID4gPiAtCQlkZXZfZXJyKCZjbGllbnQtPmRldiwgIkVycm9yIHRyYW5zZmVy
cmluZyBkYXRhDQo+ID4gPiBmcm9tIGZpZm9cbiIpOw0KPiA+ID4gKwkJZGV2X2VycihkYXRhLT5k
ZXYsICJFcnJvciB0cmFuc2ZlcnJpbmcgZGF0YSBmcm9tDQo+ID4gPiBmaWZvIGluIHNpbmdsZSBz
dGVwcyBvZiAlenVcbiIsDQo+ID4gPiArCQkJc3RlcCk7DQo+ID4gPg0KPiA+ID4gIAlyZXR1cm4g
cmV0Ow0KPiA+ID4gIH0NCj4gPiA+IEBAIC05NjMsMTQgKzkyNCwxNSBAQCBzdGF0aWMgaW50IF9f
Ym1jMTUwX2FjY2VsX2ZpZm9fZmx1c2goc3RydWN0DQo+ID4gPiBpaW9fZGV2ICppbmRpb19kZXYs
DQo+ID4gPiAgCXUxNiBidWZmZXJbQk1DMTUwX0FDQ0VMX0ZJRk9fTEVOR1RIICogM107DQo+ID4g
PiAgCWludDY0X3QgdHN0YW1wOw0KPiA+ID4gIAl1aW50NjRfdCBzYW1wbGVfcGVyaW9kOw0KPiA+
ID4gLQlyZXQgPSBpMmNfc21idXNfcmVhZF9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4g
LQ0KPiA+ID4gIEJNQzE1MF9BQ0NFTF9SRUdfRklGT19TVEFUVVMpOw0KPiA+ID4gKwl1bnNpZ25l
ZCBpbnQgdmFsOw0KPiA+ID4gKw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfcmVhZChkYXRhLT5yZWdt
YXAsDQo+ID4gPiBCTUMxNTBfQUNDRUxfUkVHX0ZJRk9fU1RBVFVTLCAmdmFsKTsNCj4gPiA+ICAJ
aWYgKHJldCA8IDApIHsNCj4gPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiRXJy
b3IgcmVhZGluZw0KPiA+ID4gcmVnX2ZpZm9fc3RhdHVzXG4iKTsNCj4gPiA+ICAJCXJldHVybiBy
ZXQ7DQo+ID4gPiAgCX0NCj4gPiA+DQo+ID4gPiAtCWNvdW50ID0gcmV0ICYgMHg3RjsNCj4gPiA+
ICsJY291bnQgPSB2YWwgJiAweDdGOw0KPiA+ID4NCj4gPiA+ICAJaWYgKCFjb3VudCkNCj4gPiA+
ICAJCXJldHVybiAwOw0KPiA+ID4gQEAgLTEwMDksNyArOTcxLDcgQEAgc3RhdGljIGludCBfX2Jt
YzE1MF9hY2NlbF9maWZvX2ZsdXNoKHN0cnVjdA0KPiA+ID4gaWlvX2RldiAqaW5kaW9fZGV2LA0K
PiA+ID4gIAlpZiAoc2FtcGxlcyAmJiBjb3VudCA+IHNhbXBsZXMpDQo+ID4gPiAgCQljb3VudCA9
IHNhbXBsZXM7DQo+ID4gPg0KPiA+ID4gLQlyZXQgPSBibWMxNTBfYWNjZWxfZmlmb190cmFuc2Zl
cihkYXRhLT5jbGllbnQsICh1OA0KPiA+ID4gKilidWZmZXIsIGNvdW50KTsNCj4gPiA+ICsJcmV0
ID0gYm1jMTUwX2FjY2VsX2ZpZm9fdHJhbnNmZXIoZGF0YSwgKHU4ICopYnVmZmVyLA0KPiA+ID4g
Y291bnQpOw0KPiA+ID4gIAlpZiAocmV0KQ0KPiA+ID4gIAkJcmV0dXJuIHJldDsNCj4gPiA+DQo+
ID4gPiBAQCAtMTIwNiwxNyArMTE2OCwxOSBAQCBzdGF0aWMgaXJxcmV0dXJuX3QNCj4gPiA+IGJt
YzE1MF9hY2NlbF90cmlnZ2VyX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqcCkNCj4gPiA+ICAJc3Ry
dWN0IGlpb19kZXYgKmluZGlvX2RldiA9IHBmLT5pbmRpb19kZXY7DQo+ID4gPiAgCXN0cnVjdCBi
bWMxNTBfYWNjZWxfZGF0YSAqZGF0YSA9IGlpb19wcml2KGluZGlvX2Rldik7DQo+ID4gPiAgCWlu
dCBiaXQsIHJldCwgaSA9IDA7DQo+ID4gPiArCXVuc2lnbmVkIGludCByYXdfdmFsOw0KPiA+ID4N
Cj4gPiA+ICAJbXV0ZXhfbG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ID4gIAlmb3JfZWFjaF9zZXRf
Yml0KGJpdCwgaW5kaW9fZGV2LT5hY3RpdmVfc2Nhbl9tYXNrLA0KPiA+ID4gIAkJCSBpbmRpb19k
ZXYtPm1hc2tsZW5ndGgpIHsNCj4gPiA+IC0JCXJldCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfZGF0
YShkYXRhLT5jbGllbnQsDQo+ID4gPiAtDQo+ID4gPiAgQk1DMTUwX0FDQ0VMX0FYSVNfVE9fUkVH
KGJpdCkpOw0KPiA+ID4gKwkJcmV0ID0gcmVnbWFwX2J1bGtfcmVhZChkYXRhLT5yZWdtYXAsDQo+
ID4gPiArDQo+ID4gPiAgQk1DMTUwX0FDQ0VMX0FYSVNfVE9fUkVHKGJpdCksICZyYXdfdmFsLA0K
PiA+ID4gKwkJCQkgICAgICAgMik7DQo+ID4gPiAgCQlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJ
CW11dGV4X3VubG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ID4gIAkJCWdvdG8gZXJyX3JlYWQ7DQo+
ID4gPiAgCQl9DQo+ID4gPiAtCQlkYXRhLT5idWZmZXJbaSsrXSA9IHJldDsNCj4gPiA+ICsJCWRh
dGEtPmJ1ZmZlcltpKytdID0gcmF3X3ZhbDsNCj4gPiA+ICAJfQ0KPiA+ID4gIAltdXRleF91bmxv
Y2soJmRhdGEtPm11dGV4KTsNCj4gPiA+DQo+ID4gPiBAQCAtMTI0MCwxMCArMTIwNCw5IEBAIHN0
YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3RyaWdfdHJ5X3JlZW4oc3RydWN0DQo+ID4gPiBpaW9fdHJp
Z2dlciAqdHJpZykNCj4gPiA+DQo+ID4gPiAgCW11dGV4X2xvY2soJmRhdGEtPm11dGV4KTsNCj4g
PiA+ICAJLyogY2xlYXIgYW55IGxhdGNoZWQgaW50ZXJydXB0ICovDQo+ID4gPiAtCXJldCA9IGky
Y19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gLQkJCQkJQk1DMTUw
X0FDQ0VMX1JFR19JTlRfUlNUX0wNCj4gPiA+IEFUQ0gsDQo+ID4gPiAtCQkJCQlCTUMxNTBfQUND
RUxfSU5UX01PREVfTEFUQw0KPiA+ID4gSF9JTlQgfA0KPiA+ID4gLQkJCQkJQk1DMTUwX0FDQ0VM
X0lOVF9NT0RFX0xBVEMNCj4gPiA+IEhfUkVTRVQpOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfd3Jp
dGUoZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfUlNUX0xBVENILA0K
PiA+ID4gKwkJCSAgIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9JTlQgfA0KPiA+ID4gKwkJ
CSAgIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9SRVNFVCk7DQo+ID4gPiAgCW11dGV4X3Vu
bG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJZGV2
X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsDQo+ID4gPiBAQCAtMTMwMCwzNCArMTI2MywzNCBAQCBz
dGF0aWMgaW50DQo+ID4gPiBibWMxNTBfYWNjZWxfaGFuZGxlX3JvY19ldmVudChzdHJ1Y3QgaWlv
X2RldiAqaW5kaW9fZGV2KQ0KPiA+ID4gIAlzdHJ1Y3QgYm1jMTUwX2FjY2VsX2RhdGEgKmRhdGEg
PSBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ID4gIAlpbnQgZGlyOw0KPiA+ID4gIAlpbnQgcmV0
Ow0KPiA+ID4gKwl1bnNpZ25lZCBpbnQgdmFsOw0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3Nt
YnVzX3JlYWRfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0NCj4gPiA+ICBCTUMxNTBf
QUNDRUxfUkVHX0lOVF9TVEFUVVNfMik7DQo+ID4gPiArCXJldCA9IHJlZ21hcF9yZWFkKGRhdGEt
PnJlZ21hcCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9SRUdfSU5UX1NUQVRVU18yLCAmdmFsKTsNCj4g
PiA+ICAJaWYgKHJldCA8IDApIHsNCj4gPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2
LCAiRXJyb3IgcmVhZGluZw0KPiA+ID4gcmVnX2ludF9zdGF0dXNfMlxuIik7DQo+ID4gPiAgCQly
ZXR1cm4gcmV0Ow0KPiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4gLQlpZiAocmV0ICYgQk1DMTUwX0FD
Q0VMX0FOWV9NT1RJT05fQklUX1NJR04pDQo+ID4gPiArCWlmICh2YWwgJiBCTUMxNTBfQUNDRUxf
QU5ZX01PVElPTl9CSVRfU0lHTikNCj4gPiA+ICAJCWRpciA9IElJT19FVl9ESVJfRkFMTElORzsN
Cj4gPiA+ICAJZWxzZQ0KPiA+ID4gIAkJZGlyID0gSUlPX0VWX0RJUl9SSVNJTkc7DQo+ID4gPg0K
PiA+ID4gLQlpZiAocmV0ICYgQk1DMTUwX0FDQ0VMX0FOWV9NT1RJT05fQklUX1gpDQo+ID4gPiAr
CWlmICh2YWwgJiBCTUMxNTBfQUNDRUxfQU5ZX01PVElPTl9CSVRfWCkNCj4gPiA+ICAJCWlpb19w
dXNoX2V2ZW50KGluZGlvX2RldiwNCj4gPiA+IElJT19NT0RfRVZFTlRfQ09ERShJSU9fQUNDRUws
DQo+ID4gPiAgCQkJCQkJCTAsDQo+ID4gPiAgCQkJCQkJCUlJT19NT0RfWCwNCj4gPiA+ICAJCQkJ
CQkJSUlPX0VWX1RZUA0KPiA+ID4gRV9ST0MsDQo+ID4gPiAgCQkJCQkJCWRpciksDQo+ID4gPiAg
CQkJCQkJCWRhdGENCj4gPiA+IC0+dGltZXN0YW1wKTsNCj4gPiA+IC0JaWYgKHJldCAmIEJNQzE1
MF9BQ0NFTF9BTllfTU9USU9OX0JJVF9ZKQ0KPiA+ID4gKwlpZiAodmFsICYgQk1DMTUwX0FDQ0VM
X0FOWV9NT1RJT05fQklUX1kpDQo+ID4gPiAgCQlpaW9fcHVzaF9ldmVudChpbmRpb19kZXYsDQo+
ID4gPiBJSU9fTU9EX0VWRU5UX0NPREUoSUlPX0FDQ0VMLA0KPiA+ID4gIAkJCQkJCQkwLA0KPiA+
ID4gIAkJCQkJCQlJSU9fTU9EX1ksDQo+ID4gPiAgCQkJCQkJCUlJT19FVl9UWVANCj4gPiA+IEVf
Uk9DLA0KPiA+ID4gIAkJCQkJCQlkaXIpLA0KPiA+ID4gIAkJCQkJCQlkYXRhDQo+ID4gPiAtPnRp
bWVzdGFtcCk7DQo+ID4gPiAtCWlmIChyZXQgJiBCTUMxNTBfQUNDRUxfQU5ZX01PVElPTl9CSVRf
WikNCj4gPiA+ICsJaWYgKHZhbCAmIEJNQzE1MF9BQ0NFTF9BTllfTU9USU9OX0JJVF9aKQ0KPiA+
ID4gIAkJaWlvX3B1c2hfZXZlbnQoaW5kaW9fZGV2LA0KPiA+ID4gSUlPX01PRF9FVkVOVF9DT0RF
KElJT19BQ0NFTCwNCj4gPiA+ICAJCQkJCQkJMCwNCj4gPiA+ICAJCQkJCQkJSUlPX01PRF9aLA0K
PiA+ID4gQEAgLTEzNjAsMTAgKzEzMjMsOSBAQCBzdGF0aWMgaXJxcmV0dXJuX3QNCj4gPiA+IGJt
YzE1MF9hY2NlbF9pcnFfdGhyZWFkX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqcHJpdmF0ZSkNCj4g
PiA+ICAJfQ0KPiA+ID4NCj4gPiA+ICAJaWYgKGFjaykgew0KPiA+ID4gLQkJcmV0ID0gaTJjX3Nt
YnVzX3dyaXRlX2J5dGVfZGF0YShkYXRhLT5jbGllbnQsDQo+ID4gPiAtCQkJCQlCTUMxNTBfQUND
RUxfUkVHX0lOVF9SU1RfTA0KPiA+ID4gQVRDSCwNCj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9J
TlRfTU9ERV9MQVRDDQo+ID4gPiBIX0lOVCB8DQo+ID4gPiAtCQkJCQlCTUMxNTBfQUNDRUxfSU5U
X01PREVfTEFUQw0KPiA+ID4gSF9SRVNFVCk7DQo+ID4gPiArCQlyZXQgPSByZWdtYXBfd3JpdGUo
ZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfUlNUX0xBVENILA0KPiA+
ID4gKwkJCQkgICBCTUMxNTBfQUNDRUxfSU5UX01PREVfTEFUQ0hfSU5UDQo+ID4gPiB8DQo+ID4g
PiArDQo+ID4gPiAgQk1DMTUwX0FDQ0VMX0lOVF9NT0RFX0xBVENIX1JFU0VUKTsNCj4gPiA+ICAJ
CWlmIChyZXQpDQo+ID4gPiAgCQkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB3
cml0aW5nDQo+ID4gPiByZWdfaW50X3JzdF9sYXRjaFxuIik7DQo+ID4gPiAgCQlyZXQgPSBJUlFf
SEFORExFRDsNCj4gPiA+IEBAIC0xNTE2LDcgKzE0NzgsNyBAQCBzdGF0aWMgaW50IGJtYzE1MF9h
Y2NlbF9maWZvX3NldF9tb2RlKHN0cnVjdA0KPiA+ID4gYm1jMTUwX2FjY2VsX2RhdGEgKmRhdGEp
DQo+ID4gPiAgCXU4IHJlZyA9IEJNQzE1MF9BQ0NFTF9SRUdfRklGT19DT05GSUcxOw0KPiA+ID4g
IAlpbnQgcmV0Ow0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0
YShkYXRhLT5jbGllbnQsIHJlZywgZGF0YQ0KPiA+ID4gLT5maWZvX21vZGUpOw0KPiA+ID4gKwly
ZXQgPSByZWdtYXBfd3JpdGUoZGF0YS0+cmVnbWFwLCByZWcsIGRhdGEtPmZpZm9fbW9kZSk7DQo+
ID4gPiAgCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAgCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRl
diwgIkVycm9yIHdyaXRpbmcNCj4gPiA+IHJlZ19maWZvX2NvbmZpZzFcbiIpOw0KPiA+ID4gIAkJ
cmV0dXJuIHJldDsNCj4gPiA+IEBAIC0xNTI1LDkgKzE0ODcsOCBAQCBzdGF0aWMgaW50IGJtYzE1
MF9hY2NlbF9maWZvX3NldF9tb2RlKHN0cnVjdA0KPiA+ID4gYm1jMTUwX2FjY2VsX2RhdGEgKmRh
dGEpDQo+ID4gPiAgCWlmICghZGF0YS0+Zmlmb19tb2RlKQ0KPiA+ID4gIAkJcmV0dXJuIDA7DQo+
ID4gPg0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVu
dCwNCj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9SRUdfRklGT19DT05GDQo+ID4gPiBJRzAsDQo+
ID4gPiAtCQkJCQlkYXRhLT53YXRlcm1hcmspOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfd3JpdGUo
ZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19GSUZPX0NPTkZJRzAsDQo+ID4g
PiArCQkJICAgZGF0YS0+d2F0ZXJtYXJrKTsNCj4gPiA+ICAJaWYgKHJldCA8IDApDQo+ID4gPiAg
CQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRldiwgIkVycm9yIHdyaXRpbmcNCj4gPiA+IHJlZ19m
aWZvX2NvbmZpZzBcbiIpOw0KPiA+ID4NCj4gPiA+IEBAIC0xNjI3LDYgKzE1ODgsMTMgQEAgc3Rh
dGljIGludCBibWMxNTBfYWNjZWxfcHJvYmUoc3RydWN0DQo+ID4gPiBpMmNfY2xpZW50ICpjbGll
bnQsDQo+ID4gPiAgCWRhdGEgPSBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ID4gIAlpMmNfc2V0
X2NsaWVudGRhdGEoY2xpZW50LCBpbmRpb19kZXYpOw0KPiA+ID4gIAlkYXRhLT5jbGllbnQgPSBj
bGllbnQ7DQo+ID4gPiArCWRhdGEtPmRldiA9ICZjbGllbnQtPmRldjsNCj4gPiA+ICsNCj4gPiA+
ICsJZGF0YS0+cmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LA0KPiA+ID4gJmJt
YzE1MF9pMmNfcmVnbWFwX2NvbmYpOw0KPiA+ID4gKwlpZiAoSVNfRVJSKGRhdGEtPnJlZ21hcCkp
IHsNCj4gPiA+ICsJCWRldl9lcnIoJmNsaWVudC0+ZGV2LCAiRmFpbGVkIHRvIGluaXRpYWxpemUg
aTJjDQo+ID4gPiByZWdtYXBcbiIpOw0KPiA+ID4gKwkJcmV0dXJuIFBUUl9FUlIoZGF0YS0+cmVn
bWFwKTsNCj4gPiA+ICsJfQ0KPiA+ID4NCj4gPiA+ICAJaWYgKGlkKSB7DQo+ID4gPiAgCQluYW1l
ID0gaWQtPm5hbWU7DQo+ID4gPiBAQCAtMTY4MCw5ICsxNjQ4LDggQEAgc3RhdGljIGludCBibWMx
NTBfYWNjZWxfcHJvYmUoc3RydWN0DQo+ID4gPiBpMmNfY2xpZW50ICpjbGllbnQsDQo+ID4gPiAg
CQkgKiB3YW50IHRvIHVzZSBsYXRjaCBtb2RlIHdoZW4gd2UgY2FuIHRvIHByZXZlbnQNCj4gPiA+
IGludGVycnVwdA0KPiA+ID4gIAkJICogZmxvb2RpbmcuDQo+ID4gPiAgCQkgKi8NCj4gPiA+IC0J
CXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gLQkJ
CQkJCUJNQzE1MF9BQ0NFTF9SRUdfSQ0KPiA+ID4gTlRfUlNUX0xBVENILA0KPiA+ID4gLQ0KPiA+
ID4gIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9SRVNFVCk7DQo+ID4gPiArCQlyZXQgPSBy
ZWdtYXBfd3JpdGUoZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfUlNU
X0xBVENILA0KPiA+ID4gKw0KPiA+ID4gIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9SRVNF
VCk7DQo+ID4gPiAgCQlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJCWRldl9lcnIoJmRhdGEtPmNs
aWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZw0KPiA+ID4gcmVnX2ludF9yc3RfbGF0Y2hcbiIpOw0K
PiA+ID4gIAkJCWdvdG8gZXJyX2J1ZmZlcl9jbGVhbnVwOw0KPiA+ID4NCj4gPg0K
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 0/4] iio: bmc150 regmap and SPI
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
` (3 preceding siblings ...)
2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
@ 2015-09-09 14:30 ` Tirdea, Irina
2015-09-16 10:13 ` Markus Pargmann
4 siblings, 1 reply; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:30 UTC (permalink / raw)
To: Markus Pargmann, Jonathan Cameron
Cc: Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vge=
r.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 0/4] iio: bmc150 regmap and SPI
>=20
> Hi,
>=20
Hi Markus,
I tested your patches with my BMA250E driver connected on the i2c bus .
The code looks good and most of it works. There are a couple of issues I wi=
ll mention
below and in the individual patches.
The patches in this version no longer apply cleanly on the togreg branch of=
the iio tree.
I did the rebase myself, but since there were many conflicts I will do anot=
her test
when you send the new rebased v3.
> this series converts the bmc150 driver to use regmap and adds an SPI inte=
rface.
>=20
> In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI suppo=
rt".
> It now depends on "regmap: i2c block support".
>=20
I used the patches that were already merged in the regmap tree. This bmc150=
series should
probably wait until the regmap patches end up in Jonathan's tree, otherwise=
they will
break the build.
Thanks,
Irina
> Changes in v2:
> - Removed default values for regmap_config fields.
> - Redesigned the fifo_transfer function to avoid running in errors first.
> - Dropped irq checks patch as it is already mainline
> - Core can now be built as module with autoselection of i2c and spi parts
>=20
> As my hardware is missing an interrupt line from the SPI connected bmc150=
I am
> not able to test the iio buffer code path and the i2c code path. Tests wo=
uld be
> appreciated.
>=20
> Best regards,
>=20
> Markus
>=20
>=20
> Markus Pargmann (4):
> iio: bmc150: Use i2c regmap
> iio: bcm150: Remove i2c_client from private data
> iio: bmc150: Split the driver into core and i2c
> iio: bmc150: Add SPI driver
>=20
> drivers/iio/accel/Kconfig | 14 +-
> drivers/iio/accel/Makefile | 4 +-
> .../accel/{bmc150-accel.c =3D> bmc150-accel-core.c} | 398 ++++++++-----=
--------
> drivers/iio/accel/bmc150-accel-i2c.c | 99 +++++
> drivers/iio/accel/bmc150-accel-spi.c | 83 +++++
> drivers/iio/accel/bmc150-accel.h | 21 ++
> 6 files changed, 367 insertions(+), 252 deletions(-)
> rename drivers/iio/accel/{bmc150-accel.c =3D> bmc150-accel-core.c} (81%)
> create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> create mode 100644 drivers/iio/accel/bmc150-accel.h
>=20
> --
> 2.4.6
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
2015-08-31 16:11 ` Jonathan Cameron
@ 2015-09-09 14:36 ` Tirdea, Irina
1 sibling, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:36 UTC (permalink / raw)
To: Markus Pargmann, Jonathan Cameron
Cc: Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vge=
r.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
>=20
> This replaces all usage of direct i2c accesses with regmap accesses.
>=20
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> ---
This patch works, but I would wait for the rebased version and check again.
One minor comment below.
> drivers/iio/accel/Kconfig | 2 +
> drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------------=
------
> 2 files changed, 95 insertions(+), 126 deletions(-)
>=20
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 00e7bcbdbe24..01dd03d194d1 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -22,6 +22,8 @@ config BMC150_ACCEL
> depends on I2C
> select IIO_BUFFER
> select IIO_TRIGGERED_BUFFER
> + select REGMAP
> + select REGMAP_I2C
> help
> Say yes here to build support for the following Bosch accelerometers:
> BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-=
accel.c
> index 55751d9e1ade..c5c773e75173 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -35,6 +35,7 @@
> #include <linux/iio/trigger.h>
> #include <linux/iio/trigger_consumer.h>
> #include <linux/iio/triggered_buffer.h>
> +#include <linux/regmap.h>
>=20
> #define BMC150_ACCEL_DRV_NAME "bmc150_accel"
> #define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
> @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
>=20
> struct bmc150_accel_data {
> struct i2c_client *client;
> + struct regmap *regmap;
> + struct device *dev;
> struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> atomic_t active_intr;
> struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -241,6 +244,11 @@ static const struct {
> {500000, BMC150_ACCEL_SLEEP_500_MS},
> {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
>=20
> +static const struct regmap_config bmc150_i2c_regmap_conf =3D {
> + .reg_bits =3D 8,
> + .val_bits =3D 8,
> + .max_register =3D 0x3f,
> +};
>=20
> static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> enum bmc150_power_modes mode,
> @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_=
data *data,
>=20
> dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
>=20
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> return ret;
> @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_da=
ta *data, int val,
> for (i =3D 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
> if (bmc150_accel_samp_freq_table[i].val =3D=3D val &&
> bmc150_accel_samp_freq_table[i].val2 =3D=3D val2) {
> - ret =3D i2c_smbus_write_byte_data(
> - data->client,
> + ret =3D regmap_write(data->regmap,
> BMC150_ACCEL_REG_PMU_BW,
> bmc150_accel_samp_freq_table[i].bw_bits);
> if (ret < 0)
> @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_=
data *data, int val,
>=20
> static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
> {
> - int ret, val;
> + int ret;
>=20
> - ret =3D i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> data->slope_thres);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_int_6\n");
> return ret;
> }
>=20
> - ret =3D i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
> + ret =3D regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> + BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_5\n");
> - return ret;
> - }
> -
> - val =3D (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
> - ret =3D i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
> - val);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error write reg_int_5\n");
> + dev_err(&data->client->dev, "Error updating reg_int_5\n");
> return ret;
> }
>=20
> @@ -348,17 +347,18 @@ static int bmc150_accel_any_motion_setup(struct bmc=
150_accel_trigger *t,
> static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> {
> int ret;
> + unsigned int val;
>=20
> - ret =3D i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID=
);
> + ret =3D regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
> if (ret < 0) {
> dev_err(&data->client->dev,
> "Error: Reading chip id\n");
> return ret;
> }
>=20
> - dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> - if (ret !=3D data->chip_info->chip_id) {
> - dev_err(&data->client->dev, "Invalid chip %x\n", ret);
> + dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> + if (val !=3D data->chip_info->chip_id) {
> + dev_err(&data->client->dev, "Invalid chip %x\n", val);
> return -ENODEV;
> }
>=20
> @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel=
_data *data)
> return ret;
>=20
> /* Set Default Range */
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_PMU_RANGE,
> - BMC150_ACCEL_DEF_RANGE_4G);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> + BMC150_ACCEL_DEF_RANGE_4G);
> if (ret < 0) {
> dev_err(&data->client->dev,
> "Error writing reg_pmu_range\n");
> @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct bmc150_acce=
l_data *data)
> return ret;
>=20
> /* Set default as latched interrupts */
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_INT |
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret < 0) {
> dev_err(&data->client->dev,
> "Error writing reg_int_rst_latch\n");
> @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150=
_accel_data *data, int i,
> return ret;
>=20
> /* map the interrupt to the appropriate pins */
> - ret =3D i2c_smbus_read_byte_data(data->client, info->map_reg);
> + ret =3D regmap_update_bits(data->regmap, info->map_reg, info->map_bitma=
sk,
> + (state ? info->map_bitmask : 0));
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_map\n");
> - goto out_fix_power_state;
> - }
> - if (state)
> - ret |=3D info->map_bitmask;
> - else
> - ret &=3D ~info->map_bitmask;
> -
> - ret =3D i2c_smbus_write_byte_data(data->client, info->map_reg,
> - ret);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_map\n");
> + dev_err(&data->client->dev, "Error updating reg_int_map\n");
> goto out_fix_power_state;
> }
>=20
> /* enable/disable the interrupt */
> - ret =3D i2c_smbus_read_byte_data(data->client, info->en_reg);
> + ret =3D regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask=
,
> + (state ? info->en_bitmask : 0));
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_en\n");
> - goto out_fix_power_state;
> - }
> -
> - if (state)
> - ret |=3D info->en_bitmask;
> - else
> - ret &=3D ~info->en_bitmask;
> -
> - ret =3D i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> - if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_en\n");
> + dev_err(&data->client->dev, "Error updating reg_int_en\n");
> goto out_fix_power_state;
> }
>=20
> @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel=
_data *data, int val)
>=20
> for (i =3D 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
> if (data->chip_info->scale_table[i].scale =3D=3D val) {
> - ret =3D i2c_smbus_write_byte_data(
> - data->client,
> + ret =3D regmap_write(data->regmap,
> BMC150_ACCEL_REG_PMU_RANGE,
> data->chip_info->scale_table[i].reg_range);
> if (ret < 0) {
> @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct bmc150_acc=
el_data *data, int val)
> static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *va=
l)
> {
> int ret;
> + unsigned int value;
>=20
> mutex_lock(&data->mutex);
>=20
> - ret =3D i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
> + ret =3D regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading reg_temp\n");
> mutex_unlock(&data->mutex);
> return ret;
> }
> - *val =3D sign_extend32(ret, 7);
> + *val =3D sign_extend32(value, 7);
>=20
> mutex_unlock(&data->mutex);
>=20
> @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_=
data *data,
> {
> int ret;
> int axis =3D chan->scan_index;
> + unsigned int raw_val;
>=20
> mutex_lock(&data->mutex);
> ret =3D bmc150_accel_set_power_state(data, true);
> @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct bmc150_acce=
l_data *data,
> return ret;
> }
>=20
> - ret =3D i2c_smbus_read_word_data(data->client,
> - BMC150_ACCEL_AXIS_TO_REG(axis));
> + ret =3D regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> + &raw_val, 2);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> bmc150_accel_set_power_state(data, false);
> mutex_unlock(&data->mutex);
> return ret;
> }
> - *val =3D sign_extend32(ret >> chan->scan_type.shift,
> + *val =3D sign_extend32(raw_val >> chan->scan_type.shift,
> chan->scan_type.realbits - 1);
> ret =3D bmc150_accel_set_power_state(data, false);
> mutex_unlock(&data->mutex);
> @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct iio_de=
v *indio_dev, unsigned val)
> * We must read at least one full frame in one burst, otherwise the rest=
of the
> * frame data is discarded.
> */
> -static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
> +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
> char *buffer, int samples)
> {
> int sample_length =3D 3 * 2;
> - u8 reg_fifo_data =3D BMC150_ACCEL_REG_FIFO_DATA;
> - int ret =3D -EIO;
> -
> - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> - struct i2c_msg msg[2] =3D {
> - {
> - .addr =3D client->addr,
> - .flags =3D 0,
> - .buf =3D ®_fifo_data,
> - .len =3D sizeof(reg_fifo_data),
> - },
> - {
> - .addr =3D client->addr,
> - .flags =3D I2C_M_RD,
> - .buf =3D (u8 *)buffer,
> - .len =3D samples * sample_length,
> - }
> - };
> + int ret;
> + int total_length =3D samples * sample_length;
> + int i;
> + int step =3D regmap_get_raw_read_max(data->regmap);
>=20
> - ret =3D i2c_transfer(client->adapter, msg, 2);
> - if (ret !=3D 2)
> - ret =3D -EIO;
> - else
> - ret =3D 0;
> - } else {
> - int i, step =3D I2C_SMBUS_BLOCK_MAX / sample_length;
> -
> - for (i =3D 0; i < samples * sample_length; i +=3D step) {
> - ret =3D i2c_smbus_read_i2c_block_data(client,
> - reg_fifo_data, step,
> - &buffer[i]);
> - if (ret !=3D step) {
> - ret =3D -EIO;
> - break;
> - }
> + if (!step || step > total_length)
> + step =3D total_length;
> + else if (step < total_length)
> + step =3D sample_length;
>=20
> - ret =3D 0;
> - }
> + /*
> + * Seems we have a bus with size limitation so we have to execute
> + * multiple reads
> + */
> + for (i =3D 0; i < total_length; i +=3D step) {
> + ret =3D regmap_raw_read(data->regmap, BMC150_ACCEL_REG_FIFO_DATA,
> + &buffer[i], step);
> + if (ret)
> + break;
> }
>=20
> if (ret)
> - dev_err(&client->dev, "Error transferring data from fifo\n");
> + dev_err(data->dev, "Error transferring data from fifo in single steps =
of %zu\n",
> + step);
step is declared as int, so using %zu will generate the following warning a=
t build:
drivers/iio/accel/bmc150-accel.c:859:4: warning: format '%zu' expects argum=
ent of type 'size_t', but argument 3 has type 'int' [-Wformat=3D]
step);
^
>=20
> return ret;
> }
> @@ -963,14 +924,15 @@ static int __bmc150_accel_fifo_flush(struct iio_dev=
*indio_dev,
> u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];
> int64_t tstamp;
> uint64_t sample_period;
> - ret =3D i2c_smbus_read_byte_data(data->client,
> - BMC150_ACCEL_REG_FIFO_STATUS);
> + unsigned int val;
> +
> + ret =3D regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> return ret;
> }
>=20
> - count =3D ret & 0x7F;
> + count =3D val & 0x7F;
>=20
> if (!count)
> return 0;
> @@ -1009,7 +971,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev =
*indio_dev,
> if (samples && count > samples)
> count =3D samples;
>=20
> - ret =3D bmc150_accel_fifo_transfer(data->client, (u8 *)buffer, count);
> + ret =3D bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
> if (ret)
> return ret;
>=20
> @@ -1206,17 +1168,19 @@ static irqreturn_t bmc150_accel_trigger_handler(i=
nt irq, void *p)
> struct iio_dev *indio_dev =3D pf->indio_dev;
> struct bmc150_accel_data *data =3D iio_priv(indio_dev);
> int bit, ret, i =3D 0;
> + unsigned int raw_val;
>=20
> mutex_lock(&data->mutex);
> for_each_set_bit(bit, indio_dev->active_scan_mask,
> indio_dev->masklength) {
> - ret =3D i2c_smbus_read_word_data(data->client,
> - BMC150_ACCEL_AXIS_TO_REG(bit));
> + ret =3D regmap_bulk_read(data->regmap,
> + BMC150_ACCEL_AXIS_TO_REG(bit), &raw_val,
> + 2);
> if (ret < 0) {
> mutex_unlock(&data->mutex);
> goto err_read;
> }
> - data->buffer[i++] =3D ret;
> + data->buffer[i++] =3D raw_val;
> }
> mutex_unlock(&data->mutex);
>=20
> @@ -1240,10 +1204,9 @@ static int bmc150_accel_trig_try_reen(struct iio_t=
rigger *trig)
>=20
> mutex_lock(&data->mutex);
> /* clear any latched interrupt */
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_INT |
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> mutex_unlock(&data->mutex);
> if (ret < 0) {
> dev_err(&data->client->dev,
> @@ -1300,34 +1263,34 @@ static int bmc150_accel_handle_roc_event(struct i=
io_dev *indio_dev)
> struct bmc150_accel_data *data =3D iio_priv(indio_dev);
> int dir;
> int ret;
> + unsigned int val;
>=20
> - ret =3D i2c_smbus_read_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_STATUS_2);
> + ret =3D regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> return ret;
> }
>=20
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_SIGN)
> dir =3D IIO_EV_DIR_FALLING;
> else
> dir =3D IIO_EV_DIR_RISING;
>=20
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_X)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_X)
> iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> 0,
> IIO_MOD_X,
> IIO_EV_TYPE_ROC,
> dir),
> data->timestamp);
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Y)
> iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> 0,
> IIO_MOD_Y,
> IIO_EV_TYPE_ROC,
> dir),
> data->timestamp);
> - if (ret & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> + if (val & BMC150_ACCEL_ANY_MOTION_BIT_Z)
> iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL,
> 0,
> IIO_MOD_Z,
> @@ -1360,10 +1323,9 @@ static irqreturn_t bmc150_accel_irq_thread_handler=
(int irq, void *private)
> }
>=20
> if (ack) {
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_INT |
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_INT |
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret)
> dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> ret =3D IRQ_HANDLED;
> @@ -1516,7 +1478,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150=
_accel_data *data)
> u8 reg =3D BMC150_ACCEL_REG_FIFO_CONFIG1;
> int ret;
>=20
> - ret =3D i2c_smbus_write_byte_data(data->client, reg, data->fifo_mode);
> + ret =3D regmap_write(data->regmap, reg, data->fifo_mode);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> return ret;
> @@ -1525,9 +1487,8 @@ static int bmc150_accel_fifo_set_mode(struct bmc150=
_accel_data *data)
> if (!data->fifo_mode)
> return 0;
>=20
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_FIFO_CONFIG0,
> - data->watermark);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
> + data->watermark);
> if (ret < 0)
> dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
>=20
> @@ -1627,6 +1588,13 @@ static int bmc150_accel_probe(struct i2c_client *c=
lient,
> data =3D iio_priv(indio_dev);
> i2c_set_clientdata(client, indio_dev);
> data->client =3D client;
> + data->dev =3D &client->dev;
> +
> + data->regmap =3D devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> + if (IS_ERR(data->regmap)) {
> + dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> + return PTR_ERR(data->regmap);
> + }
>=20
> if (id) {
> name =3D id->name;
> @@ -1680,9 +1648,8 @@ static int bmc150_accel_probe(struct i2c_client *cl=
ient,
> * want to use latch mode when we can to prevent interrupt
> * flooding.
> */
> - ret =3D i2c_smbus_write_byte_data(data->client,
> - BMC150_ACCEL_REG_INT_RST_LATCH,
> - BMC150_ACCEL_INT_MODE_LATCH_RESET);
> + ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> + BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret < 0) {
> dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> goto err_buffer_cleanup;
> --
> 2.4.6
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data
2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
@ 2015-09-09 14:39 ` Tirdea, Irina
0 siblings, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:39 UTC (permalink / raw)
To: Markus Pargmann, Jonathan Cameron
Cc: Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data
>
> i2c_client struct is now only used for debugging output. We can use the
> device struct as well so we can remove all struct i2c_client usage.
>
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Acked-by: Jonathan Cameron <jic23@kernel.org>
> ---
This patch also works (in my rebased version) .
I have tested the iio buffer code path and the i2c code path.
> drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
> 1 file changed, 58 insertions(+), 62 deletions(-)
>
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index c5c773e75173..e4a0691d9b88 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
> };
>
> struct bmc150_accel_data {
> - struct i2c_client *client;
> struct regmap *regmap;
> struct device *dev;
> + int irq;
> struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> atomic_t active_intr;
> struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -276,11 +276,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
> lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
>
> - dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
> + dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
>
> ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> + dev_err(data->dev, "Error writing reg_pmu_lpw\n");
> return ret;
> }
>
> @@ -318,18 +318,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
> ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> data->slope_thres);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_6\n");
> + dev_err(data->dev, "Error writing reg_int_6\n");
> return ret;
> }
>
> ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error updating reg_int_5\n");
> + dev_err(data->dev, "Error updating reg_int_5\n");
> return ret;
> }
>
> - dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
> + dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
> data->slope_dur);
>
> return ret;
> @@ -351,14 +351,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>
> ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
> if (ret < 0) {
> - dev_err(&data->client->dev,
> + dev_err(data->dev,
> "Error: Reading chip id\n");
> return ret;
> }
>
> - dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> + dev_dbg(data->dev, "Chip Id %x\n", val);
> if (val != data->chip_info->chip_id) {
> - dev_err(&data->client->dev, "Invalid chip %x\n", val);
> + dev_err(data->dev, "Invalid chip %x\n", val);
> return -ENODEV;
> }
>
> @@ -375,8 +375,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> BMC150_ACCEL_DEF_RANGE_4G);
> if (ret < 0) {
> - dev_err(&data->client->dev,
> - "Error writing reg_pmu_range\n");
> + dev_err(data->dev, "Error writing reg_pmu_range\n");
> return ret;
> }
>
> @@ -394,7 +393,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> BMC150_ACCEL_INT_MODE_LATCH_INT |
> BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret < 0) {
> - dev_err(&data->client->dev,
> + dev_err(data->dev,
> "Error writing reg_int_rst_latch\n");
> return ret;
> }
> @@ -436,16 +435,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
> int ret;
>
> if (on)
> - ret = pm_runtime_get_sync(&data->client->dev);
> + ret = pm_runtime_get_sync(data->dev);
> else {
> - pm_runtime_mark_last_busy(&data->client->dev);
> - ret = pm_runtime_put_autosuspend(&data->client->dev);
> + pm_runtime_mark_last_busy(data->dev);
> + ret = pm_runtime_put_autosuspend(data->dev);
> }
> if (ret < 0) {
> - dev_err(&data->client->dev,
> + dev_err(data->dev,
> "Failed: bmc150_accel_set_power_state for %d\n", on);
> if (on)
> - pm_runtime_put_noidle(&data->client->dev);
> + pm_runtime_put_noidle(data->dev);
>
> return ret;
> }
> @@ -528,7 +527,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
> ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
> (state ? info->map_bitmask : 0));
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error updating reg_int_map\n");
> + dev_err(data->dev, "Error updating reg_int_map\n");
> goto out_fix_power_state;
> }
>
> @@ -536,7 +535,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
> ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
> (state ? info->en_bitmask : 0));
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error updating reg_int_en\n");
> + dev_err(data->dev, "Error updating reg_int_en\n");
> goto out_fix_power_state;
> }
>
> @@ -563,7 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
> BMC150_ACCEL_REG_PMU_RANGE,
> data->chip_info->scale_table[i].reg_range);
> if (ret < 0) {
> - dev_err(&data->client->dev,
> + dev_err(data->dev,
> "Error writing pmu_range\n");
> return ret;
> }
> @@ -585,7 +584,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
>
> ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_temp\n");
> + dev_err(data->dev, "Error reading reg_temp\n");
> mutex_unlock(&data->mutex);
> return ret;
> }
> @@ -614,7 +613,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
> ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> &raw_val, 2);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> + dev_err(data->dev, "Error reading axis %d\n", axis);
> bmc150_accel_set_power_state(data, false);
> mutex_unlock(&data->mutex);
> return ret;
> @@ -928,7 +927,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
>
> ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> + dev_err(data->dev, "Error reading reg_fifo_status\n");
> return ret;
> }
>
> @@ -1209,7 +1208,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
> BMC150_ACCEL_INT_MODE_LATCH_RESET);
> mutex_unlock(&data->mutex);
> if (ret < 0) {
> - dev_err(&data->client->dev,
> + dev_err(data->dev,
> "Error writing reg_int_rst_latch\n");
> return ret;
> }
> @@ -1267,7 +1266,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
>
> ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> + dev_err(data->dev, "Error reading reg_int_status_2\n");
> return ret;
> }
>
> @@ -1327,7 +1326,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
> BMC150_ACCEL_INT_MODE_LATCH_INT |
> BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret)
> - dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> + dev_err(data->dev, "Error writing reg_int_rst_latch\n");
> ret = IRQ_HANDLED;
> } else {
> ret = IRQ_NONE;
> @@ -1379,17 +1378,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
> return dev_name(dev);
> }
>
> -static int bmc150_accel_gpio_probe(struct i2c_client *client,
> - struct bmc150_accel_data *data)
> +static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
> {
> struct device *dev;
> struct gpio_desc *gpio;
> int ret;
>
> - if (!client)
> - return -EINVAL;
> -
> - dev = &client->dev;
> + dev = data->dev;
>
> /* data ready gpio interrupt pin */
> gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
> @@ -1442,7 +1437,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
> for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
> struct bmc150_accel_trigger *t = &data->triggers[i];
>
> - t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
> + t->indio_trig = devm_iio_trigger_alloc(data->dev,
> bmc150_accel_triggers[i].name,
> indio_dev->name,
> indio_dev->id);
> @@ -1451,7 +1446,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
> break;
> }
>
> - t->indio_trig->dev.parent = &data->client->dev;
> + t->indio_trig->dev.parent = data->dev;
> t->indio_trig->ops = &bmc150_accel_trigger_ops;
> t->intr = bmc150_accel_triggers[i].intr;
> t->data = data;
> @@ -1480,7 +1475,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
>
> ret = regmap_write(data->regmap, reg, data->fifo_mode);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> + dev_err(data->dev, "Error writing reg_fifo_config1\n");
> return ret;
> }
>
> @@ -1490,7 +1485,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
> data->watermark);
> if (ret < 0)
> - dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
> + dev_err(data->dev, "Error writing reg_fifo_config0\n");
>
> return ret;
> }
> @@ -1580,6 +1575,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> int ret;
> const char *name = NULL;
> int chip_id = 0;
> + struct device *dev;
>
> indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> if (!indio_dev)
> @@ -1587,12 +1583,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
>
> data = iio_priv(indio_dev);
> i2c_set_clientdata(client, indio_dev);
> - data->client = client;
> data->dev = &client->dev;
> + dev = &client->dev;
> + data->irq = client->irq;
>
> data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> if (IS_ERR(data->regmap)) {
> - dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> + dev_err(dev, "Failed to initialize i2c regmap\n");
> return PTR_ERR(data->regmap);
> }
>
> @@ -1601,8 +1598,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
> chip_id = id->driver_data;
> }
>
> - if (ACPI_HANDLE(&client->dev))
> - name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
> + if (ACPI_HANDLE(dev))
> + name = bmc150_accel_match_acpi_device(dev, &chip_id);
>
> data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
>
> @@ -1612,7 +1609,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>
> mutex_init(&data->mutex);
>
> - indio_dev->dev.parent = &client->dev;
> + indio_dev->dev.parent = dev;
> indio_dev->channels = data->chip_info->channels;
> indio_dev->num_channels = data->chip_info->num_channels;
> indio_dev->name = name;
> @@ -1624,16 +1621,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
> bmc150_accel_trigger_handler,
> &bmc150_accel_buffer_ops);
> if (ret < 0) {
> - dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
> + dev_err(data->dev, "Failed: iio triggered buffer setup\n");
> return ret;
> }
>
> - if (client->irq < 0)
> - client->irq = bmc150_accel_gpio_probe(client, data);
> + if (data->irq <= 0)
> + data->irq = bmc150_accel_gpio_probe(data);
>
> - if (client->irq > 0) {
> + if (data->irq > 0) {
> ret = devm_request_threaded_irq(
> - &client->dev, client->irq,
> + data->dev, data->irq,
> bmc150_accel_irq_handler,
> bmc150_accel_irq_thread_handler,
> IRQF_TRIGGER_RISING,
> @@ -1651,7 +1648,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> BMC150_ACCEL_INT_MODE_LATCH_RESET);
> if (ret < 0) {
> - dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> + dev_err(data->dev, "Error writing reg_int_rst_latch\n");
> goto err_buffer_cleanup;
> }
>
> @@ -1672,18 +1669,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
>
> ret = iio_device_register(indio_dev);
> if (ret < 0) {
> - dev_err(&client->dev, "Unable to register iio device\n");
> + dev_err(data->dev, "Unable to register iio device\n");
> goto err_trigger_unregister;
> }
>
> - ret = pm_runtime_set_active(&client->dev);
> + ret = pm_runtime_set_active(dev);
> if (ret)
> goto err_iio_unregister;
>
> - pm_runtime_enable(&client->dev);
> - pm_runtime_set_autosuspend_delay(&client->dev,
> - BMC150_AUTO_SUSPEND_DELAY_MS);
> - pm_runtime_use_autosuspend(&client->dev);
> + pm_runtime_enable(dev);
> + pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
> + pm_runtime_use_autosuspend(dev);
>
> return 0;
>
> @@ -1702,9 +1698,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
> struct iio_dev *indio_dev = i2c_get_clientdata(client);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
>
> - pm_runtime_disable(&client->dev);
> - pm_runtime_set_suspended(&client->dev);
> - pm_runtime_put_noidle(&client->dev);
> + pm_runtime_disable(data->dev);
> + pm_runtime_set_suspended(data->dev);
> + pm_runtime_put_noidle(data->dev);
>
> iio_device_unregister(indio_dev);
>
> @@ -1722,7 +1718,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
> #ifdef CONFIG_PM_SLEEP
> static int bmc150_accel_suspend(struct device *dev)
> {
> - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
>
> mutex_lock(&data->mutex);
> @@ -1734,7 +1730,7 @@ static int bmc150_accel_suspend(struct device *dev)
>
> static int bmc150_accel_resume(struct device *dev)
> {
> - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
>
> mutex_lock(&data->mutex);
> @@ -1750,11 +1746,11 @@ static int bmc150_accel_resume(struct device *dev)
> #ifdef CONFIG_PM
> static int bmc150_accel_runtime_suspend(struct device *dev)
> {
> - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
> int ret;
>
> - dev_dbg(&data->client->dev, __func__);
> + dev_dbg(data->dev, __func__);
> ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
> if (ret < 0)
> return -EAGAIN;
> @@ -1764,12 +1760,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
>
> static int bmc150_accel_runtime_resume(struct device *dev)
> {
> - struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
> int ret;
> int sleep_val;
>
> - dev_dbg(&data->client->dev, __func__);
> + dev_dbg(data->dev, __func__);
>
> ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
> if (ret < 0)
> --
> 2.4.6
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
2015-08-31 16:15 ` Jonathan Cameron
@ 2015-09-09 14:45 ` Tirdea, Irina
1 sibling, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:45 UTC (permalink / raw)
To: Markus Pargmann, Jonathan Cameron
Cc: Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
>
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> ---
> drivers/iio/accel/Kconfig | 9 +-
> drivers/iio/accel/Makefile | 3 +-
> .../accel/{bmc150-accel.c => bmc150-accel-core.c} | 95 ++++-----------------
> drivers/iio/accel/bmc150-accel-i2c.c | 99 ++++++++++++++++++++++
> drivers/iio/accel/bmc150-accel.h | 21 +++++
> 5 files changed, 144 insertions(+), 83 deletions(-)
> rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
> create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> create mode 100644 drivers/iio/accel/bmc150-accel.h
>
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 01dd03d194d1..6da4eb0db57b 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -19,21 +19,22 @@ config BMA180
>
> config BMC150_ACCEL
> tristate "Bosch BMC150 Accelerometer Driver"
> - depends on I2C
> select IIO_BUFFER
> select IIO_TRIGGERED_BUFFER
> select REGMAP
> - select REGMAP_I2C
> + select BMC150_ACCEL_I2C if I2C
> help
> Say yes here to build support for the following Bosch accelerometers:
> BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
>
> - Currently this only supports the device via an i2c interface.
> -
> This is a combo module with both accelerometer and magnetometer.
> This driver is only implementing accelerometer part, which has
> its own address and register map.
>
> +config BMC150_ACCEL_I2C
> + tristate
> + select REGMAP_I2C
> +
> config HID_SENSOR_ACCEL_3D
> depends on HID_SENSOR_HUB
> select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index ebd2675b2a02..5ef8bdbad092 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -4,7 +4,8 @@
>
> # When adding new entries keep the list in alphabetical order
> obj-$(CONFIG_BMA180) += bma180.o
> -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> obj-$(CONFIG_KXSD9) += kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
> similarity index 95%
> rename from drivers/iio/accel/bmc150-accel.c
> rename to drivers/iio/accel/bmc150-accel-core.c
> index e4a0691d9b88..614cf61f0110 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel-core.c
> @@ -37,6 +37,8 @@
> #include <linux/iio/triggered_buffer.h>
> #include <linux/regmap.h>
>
> +#include "bmc150-accel.h"
> +
> #define BMC150_ACCEL_DRV_NAME "bmc150_accel"
> #define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event"
> #define BMC150_ACCEL_GPIO_NAME "bmc150_accel_int"
> @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
> struct bmc150_accel_data {
> struct regmap *regmap;
> struct device *dev;
> - int irq;
> struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
> atomic_t active_intr;
> struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -201,6 +202,7 @@ struct bmc150_accel_data {
> int ev_enable_state;
> int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
> const struct bmc150_accel_chip_info *chip_info;
> + int irq;
> };
>
> static const struct {
> @@ -1070,15 +1072,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
> static const struct iio_chan_spec bma280_accel_channels[] =
> BMC150_ACCEL_CHANNELS(14);
>
> -enum {
> - bmc150,
> - bmi055,
> - bma255,
> - bma250e,
> - bma222e,
> - bma280,
> -};
> -
> static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
> [bmc150] = {
> .chip_id = 0xFA,
> @@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
> .postdisable = bmc150_accel_buffer_postdisable,
> };
>
> -static int bmc150_accel_probe(struct i2c_client *client,
> - const struct i2c_device_id *id)
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> + const char *name, int chip_id, bool block_supported)
> {
> struct bmc150_accel_data *data;
> struct iio_dev *indio_dev;
> int ret;
> - const char *name = NULL;
> - int chip_id = 0;
> - struct device *dev;
>
> - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> if (!indio_dev)
> return -ENOMEM;
>
> data = iio_priv(indio_dev);
> - i2c_set_clientdata(client, indio_dev);
> - data->dev = &client->dev;
> - dev = &client->dev;
> - data->irq = client->irq;
> -
> - data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> - if (IS_ERR(data->regmap)) {
> - dev_err(dev, "Failed to initialize i2c regmap\n");
> - return PTR_ERR(data->regmap);
> - }
> -
> - if (id) {
> - name = id->name;
> - chip_id = id->driver_data;
> - }
> + dev_set_drvdata(dev, indio_dev);
> + data->dev = dev;
> + data->irq = irq;
> + data->regmap = regmap;
>
> if (ACPI_HANDLE(dev))
> name = bmc150_accel_match_acpi_device(dev, &chip_id);
> @@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> if (ret)
> goto err_buffer_cleanup;
>
> - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> - i2c_check_functionality(client->adapter,
> - I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> + if (block_supported) {
> indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> indio_dev->info = &bmc150_accel_info_fifo;
> indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
> @@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>
> ret = iio_device_register(indio_dev);
> if (ret < 0) {
> - dev_err(data->dev, "Unable to register iio device\n");
> + dev_err(dev, "Unable to register iio device\n");
> goto err_trigger_unregister;
> }
>
> @@ -1692,10 +1669,11 @@ err_buffer_cleanup:
>
> return ret;
> }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
>
> -static int bmc150_accel_remove(struct i2c_client *client)
> +int bmc150_accel_core_remove(struct device *dev)
> {
> - struct iio_dev *indio_dev = i2c_get_clientdata(client);
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct bmc150_accel_data *data = iio_priv(indio_dev);
>
> pm_runtime_disable(data->dev);
> @@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
>
> return 0;
> }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
>
> #ifdef CONFIG_PM_SLEEP
> static int bmc150_accel_suspend(struct device *dev)
> @@ -1784,48 +1763,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
> }
> #endif
>
> -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> +const struct dev_pm_ops bmc150_accel_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
> SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
> bmc150_accel_runtime_resume, NULL)
> };
> -
> -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> - {"BSBA0150", bmc150},
> - {"BMC150A", bmc150},
> - {"BMI055A", bmi055},
> - {"BMA0255", bma255},
> - {"BMA250E", bma250e},
> - {"BMA222E", bma222e},
> - {"BMA0280", bma280},
> - { },
> -};
> -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> -
> -static const struct i2c_device_id bmc150_accel_id[] = {
> - {"bmc150_accel", bmc150},
> - {"bmi055_accel", bmi055},
> - {"bma255", bma255},
> - {"bma250e", bma250e},
> - {"bma222e", bma222e},
> - {"bma280", bma280},
> - {}
> -};
> -
> -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> -
> -static struct i2c_driver bmc150_accel_driver = {
> - .driver = {
> - .name = BMC150_ACCEL_DRV_NAME,
> - .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> - .pm = &bmc150_accel_pm_ops,
> - },
> - .probe = bmc150_accel_probe,
> - .remove = bmc150_accel_remove,
> - .id_table = bmc150_accel_id,
> -};
> -module_i2c_driver(bmc150_accel_driver);
> -
> -MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("BMC150 accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
> new file mode 100644
> index 000000000000..e4dd596ba8f2
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> @@ -0,0 +1,99 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + * - BMC150
> + * - BMI055
> + * - BMA255
> + * - BMA250E
> + * - BMA222E
> + * - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope 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/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> + .reg_bits = 8,
> + .val_bits = 8,
> +};
> +
> +static int bmc150_accel_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct regmap *regmap;
> + bool block_supported =
> + i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> + i2c_check_functionality(client->adapter,
> + I2C_FUNC_SMBUS_READ_I2C_BLOCK);
> +
> + regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> + if (IS_ERR(regmap)) {
> + dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> + return PTR_ERR(regmap);
> + }
> +
> + return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
> + id->name, id->driver_data,
> + block_supported);
> +}
For ACPI, id will be NULL and the call above will dereference a NULL pointer.
The original code was checking if id is NULL:
- if (id) {
- name = id->name;
- chip_id = id->driver_data;
- }
Please note that the initialization of name and chip_id has changed in the
current version of bmc150.
Thanks,
Irina
> +
> +static int bmc150_accel_remove(struct i2c_client *client)
> +{
> + return bmc150_accel_core_remove(&client->dev);
> +}
> +
> +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> + {"BSBA0150", bmc150},
> + {"BMC150A", bmc150},
> + {"BMI055A", bmi055},
> + {"BMA0255", bma255},
> + {"BMA250E", bma250e},
> + {"BMA222E", bma222e},
> + {"BMA0280", bma280},
> + { },
> +};
> +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> +
> +static const struct i2c_device_id bmc150_accel_id[] = {
> + {"bmc150_accel", bmc150},
> + {"bmi055_accel", bmi055},
> + {"bma255", bma255},
> + {"bma250e", bma250e},
> + {"bma222e", bma222e},
> + {"bma280", bma280},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> +
> +static struct i2c_driver bmc150_accel_driver = {
> + .driver = {
> + .name = "bmc150_accel_i2c",
> + .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> + .pm = &bmc150_accel_pm_ops,
> + },
> + .probe = bmc150_accel_probe,
> + .remove = bmc150_accel_remove,
> + .id_table = bmc150_accel_id,
> +};
> +module_i2c_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
> new file mode 100644
> index 000000000000..988b57573d0c
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel.h
> @@ -0,0 +1,21 @@
> +#ifndef _BMC150_ACCEL_H_
> +#define _BMC150_ACCEL_H_
> +
> +struct regmap;
> +
> +enum {
> + bmc150,
> + bmi055,
> + bma255,
> + bma250e,
> + bma222e,
> + bma280,
> +};
> +
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> + const char *name, int chip_id,
> + bool block_supported);
> +int bmc150_accel_core_remove(struct device *dev);
> +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> +
> +#endif /* _BMC150_ACCEL_H_ */
> --
> 2.4.6
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] iio: bmc150: Add SPI driver
2015-09-01 14:10 ` Srinivas Pandruvada
@ 2015-09-16 10:01 ` Markus Pargmann
0 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-09-16 10:01 UTC (permalink / raw)
To: Srinivas Pandruvada
Cc: Jonathan Cameron, Irina Tirdea, Lars-Peter Clausen, linux-iio,
linux-kernel, kernel
[-- Attachment #1: Type: text/plain, Size: 6002 bytes --]
On Tue, Sep 01, 2015 at 07:10:57AM -0700, Srinivas Pandruvada wrote:
> On Mon, 2015-08-31 at 17:18 +0100, Jonathan Cameron wrote:
> > On 20/08/15 13:49, Markus Pargmann wrote:
> > > Add a simple SPI driver which initializes the spi regmap for the
> > > bmc150
> > > core driver.
> > >
> > > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> > Looks good to me, but clearly will have to wait for the earlier
> > patches in the series.
> >
> > Nearly there!
> >
> > Jonathan
> > > ---
> > > drivers/iio/accel/Kconfig | 5 +++
> > > drivers/iio/accel/Makefile | 1 +
> > > drivers/iio/accel/bmc150-accel-spi.c | 83
> > > ++++++++++++++++++++++++++++++++++++
> > > 3 files changed, 89 insertions(+)
> > > create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> > >
> > > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > > index 6da4eb0db57b..56d24fa3d34a 100644
> > > --- a/drivers/iio/accel/Kconfig
> > > +++ b/drivers/iio/accel/Kconfig
> > > @@ -23,6 +23,7 @@ config BMC150_ACCEL
> > > select IIO_TRIGGERED_BUFFER
> > > select REGMAP
> > > select BMC150_ACCEL_I2C if I2C
> > > + select BMC150_ACCEL_SPI if SPI
> > > help
> > > Say yes here to build support for the following Bosch
> > > accelerometers:
> > > BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > > @@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
> > > tristate
> > > select REGMAP_I2C
> > >
> > > +config BMC150_ACCEL_SPI
> > > + tristate
> > > + select REGMAP_SPI
> > > +
> > > config HID_SENSOR_ACCEL_3D
> > > depends on HID_SENSOR_HUB
> > > select IIO_BUFFER
> > > diff --git a/drivers/iio/accel/Makefile
> > > b/drivers/iio/accel/Makefile
> > > index 5ef8bdbad092..e579e93bf022 100644
> > > --- a/drivers/iio/accel/Makefile
> > > +++ b/drivers/iio/accel/Makefile
> > > @@ -6,6 +6,7 @@
> > > obj-$(CONFIG_BMA180) += bma180.o
> > > obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> > > obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> > > +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> > > obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> > > obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> > > obj-$(CONFIG_KXSD9) += kxsd9.o
> > > diff --git a/drivers/iio/accel/bmc150-accel-spi.c
> > > b/drivers/iio/accel/bmc150-accel-spi.c
> > > new file mode 100644
> > > index 000000000000..1c2a4f683da4
> > > --- /dev/null
> > > +++ b/drivers/iio/accel/bmc150-accel-spi.c
> > > @@ -0,0 +1,83 @@
> > > +/*
> > > + * 3-axis accelerometer driver supporting following I2C Bosch
> > > -Sensortec chips:
> > > + * - BMC150
> > > + * - BMI055
> > > + * - BMA255
> > > + * - BMA250E
> > > + * - BMA222E
> > > + * - BMA280
> > > + *
> > > + * Copyright (c) 2014, Intel Corporation.
> > > + *
> > > + * This program is free software; you can redistribute it and/or
> > > modify it
> > > + * under the terms and conditions of the GNU General Public
> > > License,
> > > + * version 2, as published by the Free Software Foundation.
> > > + *
> > > + * This program is distributed in the hope 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.
> > > + */
> Not sure If you want to carry Intel Copyright for SPI driver part. If
> you want to use change the year to 2015.
Thanks, will replace that.
Best Regards,
Markus
> > > +
> > > +#include <linux/device.h>
> > > +#include <linux/mod_devicetable.h>
> > > +#include <linux/module.h>
> > > +#include <linux/acpi.h>
> > > +#include <linux/regmap.h>
> > > +#include <linux/spi/spi.h>
> > > +
> > > +#include "bmc150-accel.h"
> > > +
> > > +static const struct regmap_config bmc150_spi_regmap_conf = {
> > > + .reg_bits = 8,
> > > + .val_bits = 8,
> > > + .max_register = 0x3f,
> > > +};
> > > +
> > > +static int bmc150_accel_probe(struct spi_device *spi)
> > > +{
> > > + struct regmap *regmap;
> > > + const struct spi_device_id *id = spi_get_device_id(spi);
> > > +
> > > + regmap = devm_regmap_init_spi(spi,
> > > &bmc150_spi_regmap_conf);
> > > + if (IS_ERR(regmap)) {
> > > + dev_err(&spi->dev, "Failed to initialize spi
> > > regmap\n");
> > > + return PTR_ERR(regmap);
> > > + }
> > > +
> > > + return bmc150_accel_core_probe(&spi->dev, regmap, spi
> > > ->irq,
> > > + id->name, id->driver_data,
> > > true);
> > > +}
> > > +
> > > +static int bmc150_accel_remove(struct spi_device *spi)
> > > +{
> > > + return bmc150_accel_core_remove(&spi->dev);
> > > +}
> > > +
> > > +static const struct spi_device_id bmc150_accel_id[] = {
> > > + {"bmc150_accel", bmc150},
> > > + {"bmi055_accel", bmi055},
> > > + {"bma255", bma255},
> > > + {"bma250e", bma250e},
> > > + {"bma222e", bma222e},
> > > + {"bma280", bma280},
> > > + {}
> > > +};
> > > +
> > > +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> > > +
> > > +static struct spi_driver bmc150_accel_driver = {
> > > + .driver = {
> > > + .name = "bmc150_accel_spi",
> > > + .acpi_match_table =
> > > ACPI_PTR(bmc150_accel_acpi_match),
> > > + .pm = &bmc150_accel_pm_ops,
> > > + },
> > > + .probe = bmc150_accel_probe,
> > > + .remove = bmc150_accel_remove,
> > > + .id_table = bmc150_accel_id,
> > > +};
> > > +module_spi_driver(bmc150_accel_driver);
> > > +
> > > +MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
> > > +MODULE_LICENSE("GPL v2");
> > > +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> > >
> >
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
@ 2015-09-16 10:13 ` Markus Pargmann
2015-09-23 12:44 ` Tirdea, Irina
0 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2015-09-16 10:13 UTC (permalink / raw)
To: Tirdea, Irina
Cc: Jonathan Cameron, Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
[-- Attachment #1: Type: text/plain, Size: 3466 bytes --]
Hi Irina,
On Wed, Sep 09, 2015 at 02:30:30PM +0000, Tirdea, Irina wrote:
>
>
> > -----Original Message-----
> > From: Markus Pargmann [mailto:mpa@pengutronix.de]
> > Sent: 20 August, 2015 15:50
> > To: Jonathan Cameron
> > Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
> > kernel@pengutronix.de; Markus Pargmann
> > Subject: [PATCH v2 0/4] iio: bmc150 regmap and SPI
> >
> > Hi,
> >
>
> Hi Markus,
>
> I tested your patches with my BMA250E driver connected on the i2c bus .
> The code looks good and most of it works. There are a couple of issues I will mention
> below and in the individual patches.
>
> The patches in this version no longer apply cleanly on the togreg branch of the iio tree.
> I did the rebase myself, but since there were many conflicts I will do another test
> when you send the new rebased v3.
Thank you for review and testing. I will integrate your comments and
send a rebased v3.
>
> > this series converts the bmc150 driver to use regmap and adds an SPI interface.
> >
> > In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI support".
> > It now depends on "regmap: i2c block support".
> >
>
> I used the patches that were already merged in the regmap tree. This bmc150 series should
> probably wait until the regmap patches end up in Jonathan's tree, otherwise they will
> break the build.
It seems the necessary patches are already in v4.3-rc1:
29332534e2b6 (regmap-i2c: Add smbus i2c block support)
Best Regards,
Markus
>
> Thanks,
> Irina
>
> > Changes in v2:
> > - Removed default values for regmap_config fields.
> > - Redesigned the fifo_transfer function to avoid running in errors first.
> > - Dropped irq checks patch as it is already mainline
> > - Core can now be built as module with autoselection of i2c and spi parts
> >
> > As my hardware is missing an interrupt line from the SPI connected bmc150 I am
> > not able to test the iio buffer code path and the i2c code path. Tests would be
> > appreciated.
> >
> > Best regards,
> >
> > Markus
> >
> >
> > Markus Pargmann (4):
> > iio: bmc150: Use i2c regmap
> > iio: bcm150: Remove i2c_client from private data
> > iio: bmc150: Split the driver into core and i2c
> > iio: bmc150: Add SPI driver
> >
> > drivers/iio/accel/Kconfig | 14 +-
> > drivers/iio/accel/Makefile | 4 +-
> > .../accel/{bmc150-accel.c => bmc150-accel-core.c} | 398 ++++++++-------------
> > drivers/iio/accel/bmc150-accel-i2c.c | 99 +++++
> > drivers/iio/accel/bmc150-accel-spi.c | 83 +++++
> > drivers/iio/accel/bmc150-accel.h | 21 ++
> > 6 files changed, 367 insertions(+), 252 deletions(-)
> > rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (81%)
> > create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> > create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> > create mode 100644 drivers/iio/accel/bmc150-accel.h
> >
> > --
> > 2.4.6
>
>
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH v2 0/4] iio: bmc150 regmap and SPI
2015-09-16 10:13 ` Markus Pargmann
@ 2015-09-23 12:44 ` Tirdea, Irina
2015-09-27 15:58 ` Jonathan Cameron
0 siblings, 1 reply; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-23 12:44 UTC (permalink / raw)
To: Markus Pargmann
Cc: Jonathan Cameron, Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogTWFya3VzIFBhcmdtYW5u
IFttYWlsdG86bXBhQHBlbmd1dHJvbml4LmRlXQ0KPiBTZW50OiAxNiBTZXB0ZW1iZXIsIDIwMTUg
MTM6MTMNCj4gVG86IFRpcmRlYSwgSXJpbmENCj4gQ2M6IEpvbmF0aGFuIENhbWVyb247IFNyaW5p
dmFzIFBhbmRydXZhZGE7IExhcnMtUGV0ZXIgQ2xhdXNlbjsgbGludXgtaWlvQHZnZXIua2VybmVs
Lm9yZzsgbGludXgta2VybmVsQHZnZXIua2VybmVsLm9yZzsNCj4ga2VybmVsQHBlbmd1dHJvbml4
LmRlDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjIgMC80XSBpaW86IGJtYzE1MCByZWdtYXAgYW5k
IFNQSQ0KPiANCj4gSGkgSXJpbmEsDQo+IA0KPiBPbiBXZWQsIFNlcCAwOSwgMjAxNSBhdCAwMjoz
MDozMFBNICswMDAwLCBUaXJkZWEsIElyaW5hIHdyb3RlOg0KPiA+DQo+ID4NCj4gPiA+IC0tLS0t
T3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4gPiBGcm9tOiBNYXJrdXMgUGFyZ21hbm4gW21haWx0
bzptcGFAcGVuZ3V0cm9uaXguZGVdDQo+ID4gPiBTZW50OiAyMCBBdWd1c3QsIDIwMTUgMTU6NTAN
Cj4gPiA+IFRvOiBKb25hdGhhbiBDYW1lcm9uDQo+ID4gPiBDYzogU3Jpbml2YXMgUGFuZHJ1dmFk
YTsgVGlyZGVhLCBJcmluYTsgTGFycy1QZXRlciBDbGF1c2VuOyBsaW51eC1paW9Admdlci5rZXJu
ZWwub3JnOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOw0KPiA+ID4ga2VybmVsQHBlbmd1
dHJvbml4LmRlOyBNYXJrdXMgUGFyZ21hbm4NCj4gPiA+IFN1YmplY3Q6IFtQQVRDSCB2MiAwLzRd
IGlpbzogYm1jMTUwIHJlZ21hcCBhbmQgU1BJDQo+ID4gPg0KPiA+ID4gSGksDQo+ID4gPg0KPiA+
DQo+ID4gSGkgTWFya3VzLA0KPiA+DQo+ID4gSSB0ZXN0ZWQgeW91ciBwYXRjaGVzIHdpdGggbXkg
Qk1BMjUwRSBkcml2ZXIgY29ubmVjdGVkIG9uIHRoZSBpMmMgYnVzIC4NCj4gPiBUaGUgY29kZSBs
b29rcyBnb29kIGFuZCBtb3N0IG9mIGl0IHdvcmtzLiBUaGVyZSBhcmUgYSBjb3VwbGUgb2YgaXNz
dWVzIEkgd2lsbCBtZW50aW9uDQo+ID4gYmVsb3cgYW5kIGluIHRoZSBpbmRpdmlkdWFsIHBhdGNo
ZXMuDQo+ID4NCj4gPiBUaGUgcGF0Y2hlcyBpbiB0aGlzIHZlcnNpb24gbm8gbG9uZ2VyIGFwcGx5
IGNsZWFubHkgb24gdGhlIHRvZ3JlZyBicmFuY2ggb2YgdGhlIGlpbyB0cmVlLg0KPiA+IEkgZGlk
IHRoZSByZWJhc2UgbXlzZWxmLCBidXQgc2luY2UgdGhlcmUgd2VyZSBtYW55IGNvbmZsaWN0cyBJ
IHdpbGwgZG8gYW5vdGhlciB0ZXN0DQo+ID4gd2hlbiB5b3Ugc2VuZCB0aGUgbmV3IHJlYmFzZWQg
djMuDQo+IA0KPiBUaGFuayB5b3UgZm9yIHJldmlldyBhbmQgdGVzdGluZy4gSSB3aWxsIGludGVn
cmF0ZSB5b3VyIGNvbW1lbnRzIGFuZA0KPiBzZW5kIGEgcmViYXNlZCB2My4NCj4gDQo+ID4NCj4g
PiA+IHRoaXMgc2VyaWVzIGNvbnZlcnRzIHRoZSBibWMxNTAgZHJpdmVyIHRvIHVzZSByZWdtYXAg
YW5kIGFkZHMgYW4gU1BJIGludGVyZmFjZS4NCj4gPiA+DQo+ID4gPiBJbiB2MSB0aGlzIHdhcyBw
YXJ0IG9mIHRoZSBzZXJpZXMgIlJlZ21hcCBtYXhfcmF3X2lvIGFuZCBibWMxNTAgU1BJIHN1cHBv
cnQiLg0KPiA+ID4gSXQgbm93IGRlcGVuZHMgb24gInJlZ21hcDogaTJjIGJsb2NrIHN1cHBvcnQi
Lg0KPiA+ID4NCj4gPg0KPiA+IEkgdXNlZCB0aGUgcGF0Y2hlcyB0aGF0IHdlcmUgYWxyZWFkeSBt
ZXJnZWQgaW4gdGhlIHJlZ21hcCB0cmVlLiBUaGlzIGJtYzE1MCBzZXJpZXMgc2hvdWxkDQo+ID4g
cHJvYmFibHkgd2FpdCB1bnRpbCB0aGUgcmVnbWFwIHBhdGNoZXMgZW5kIHVwIGluIEpvbmF0aGFu
J3MgdHJlZSwgb3RoZXJ3aXNlIHRoZXkgd2lsbA0KPiA+IGJyZWFrIHRoZSBidWlsZC4NCj4gDQo+
IEl0IHNlZW1zIHRoZSBuZWNlc3NhcnkgcGF0Y2hlcyBhcmUgYWxyZWFkeSBpbiB2NC4zLXJjMToN
Cj4gCTI5MzMyNTM0ZTJiNiAocmVnbWFwLWkyYzogQWRkIHNtYnVzIGkyYyBibG9jayBzdXBwb3J0
KQ0KPiANCg0KQUZBSUssIEpvbmF0aGFuIHdhaXRzIHVudGlsIGNoYW5nZXMgZnJvbSB0aGUgbWFp
biBrZXJuZWwgZ2V0IG1lcmdlZCBiYWNrDQppbnRvIGhpcyB0b2dyZWcgYnJhbmNoLiBTaW5jZSB5
b3UgYXJlIHVzaW5nIHJlZ21hcF9nZXRfcmF3X3JlYWRfbWF4IHRoYXQNCmlzIGludHJvZHVjZWQg
aW4gdGhlIHJlZ21hcCBwYXRjaGVzLCB0aGUgZHJpdmVyIHdvbid0IGJ1aWxkIHdpdGhvdXQgdGhl
bQ0KKGlmIHRoZXkgYXJlIG1lcmdlZCBub3cgaW4gdGhlIGlpbyB0cmVlKS4NCg0KSG93ZXZlciwg
dGhhdCBkb2VzIG5vdCBwcmV2ZW50IG1lIGZyb20gdGVzdGluZyB0aGUgY2hhbmdlcyB1c2luZw0K
dGhlIHJlZ21hcCBjaGFuZ2VzIGZyb20gdjQuMy1yYzEuDQoNClRoYW5rcywNCklyaW5hDQoNCj4g
QmVzdCBSZWdhcmRzLA0KPiANCj4gTWFya3VzDQo+IA0KPiA+DQo+ID4gVGhhbmtzLA0KPiA+IEly
aW5hDQo+ID4NCj4gPiA+IENoYW5nZXMgaW4gdjI6DQo+ID4gPiAtIFJlbW92ZWQgZGVmYXVsdCB2
YWx1ZXMgZm9yIHJlZ21hcF9jb25maWcgZmllbGRzLg0KPiA+ID4gLSBSZWRlc2lnbmVkIHRoZSBm
aWZvX3RyYW5zZmVyIGZ1bmN0aW9uIHRvIGF2b2lkIHJ1bm5pbmcgaW4gZXJyb3JzIGZpcnN0Lg0K
PiA+ID4gLSBEcm9wcGVkIGlycSBjaGVja3MgcGF0Y2ggYXMgaXQgaXMgYWxyZWFkeSBtYWlubGlu
ZQ0KPiA+ID4gLSBDb3JlIGNhbiBub3cgYmUgYnVpbHQgYXMgbW9kdWxlIHdpdGggYXV0b3NlbGVj
dGlvbiBvZiBpMmMgYW5kIHNwaSBwYXJ0cw0KPiA+ID4NCj4gPiA+IEFzIG15IGhhcmR3YXJlIGlz
IG1pc3NpbmcgYW4gaW50ZXJydXB0IGxpbmUgZnJvbSB0aGUgU1BJIGNvbm5lY3RlZCBibWMxNTAg
SSBhbQ0KPiA+ID4gbm90IGFibGUgdG8gdGVzdCB0aGUgaWlvIGJ1ZmZlciBjb2RlIHBhdGggYW5k
IHRoZSBpMmMgY29kZSBwYXRoLiBUZXN0cyB3b3VsZCBiZQ0KPiA+ID4gYXBwcmVjaWF0ZWQuDQo+
ID4gPg0KPiA+ID4gQmVzdCByZWdhcmRzLA0KPiA+ID4NCj4gPiA+IE1hcmt1cw0KPiA+ID4NCj4g
PiA+DQo+ID4gPiBNYXJrdXMgUGFyZ21hbm4gKDQpOg0KPiA+ID4gICBpaW86IGJtYzE1MDogVXNl
IGkyYyByZWdtYXANCj4gPiA+ICAgaWlvOiBiY20xNTA6IFJlbW92ZSBpMmNfY2xpZW50IGZyb20g
cHJpdmF0ZSBkYXRhDQo+ID4gPiAgIGlpbzogYm1jMTUwOiBTcGxpdCB0aGUgZHJpdmVyIGludG8g
Y29yZSBhbmQgaTJjDQo+ID4gPiAgIGlpbzogYm1jMTUwOiBBZGQgU1BJIGRyaXZlcg0KPiA+ID4N
Cj4gPiA+ICBkcml2ZXJzL2lpby9hY2NlbC9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAg
ICB8ICAxNCArLQ0KPiA+ID4gIGRyaXZlcnMvaWlvL2FjY2VsL01ha2VmaWxlICAgICAgICAgICAg
ICAgICAgICAgICAgIHwgICA0ICstDQo+ID4gPiAgLi4uL2FjY2VsL3tibWMxNTAtYWNjZWwuYyA9
PiBibWMxNTAtYWNjZWwtY29yZS5jfSAgfCAzOTggKysrKysrKystLS0tLS0tLS0tLS0tDQo+ID4g
PiAgZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFjY2VsLWkyYy5jICAgICAgICAgICAgICAgfCAg
OTkgKysrKysNCj4gPiA+ICBkcml2ZXJzL2lpby9hY2NlbC9ibWMxNTAtYWNjZWwtc3BpLmMgICAg
ICAgICAgICAgICB8ICA4MyArKysrKw0KPiA+ID4gIGRyaXZlcnMvaWlvL2FjY2VsL2JtYzE1MC1h
Y2NlbC5oICAgICAgICAgICAgICAgICAgIHwgIDIxICsrDQo+ID4gPiAgNiBmaWxlcyBjaGFuZ2Vk
LCAzNjcgaW5zZXJ0aW9ucygrKSwgMjUyIGRlbGV0aW9ucygtKQ0KPiA+ID4gIHJlbmFtZSBkcml2
ZXJzL2lpby9hY2NlbC97Ym1jMTUwLWFjY2VsLmMgPT4gYm1jMTUwLWFjY2VsLWNvcmUuY30gKDgx
JSkNCj4gPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFj
Y2VsLWkyYy5jDQo+ID4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaWlvL2FjY2VsL2Jt
YzE1MC1hY2NlbC1zcGkuYw0KPiA+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2lpby9h
Y2NlbC9ibWMxNTAtYWNjZWwuaA0KPiA+ID4NCj4gPiA+IC0tDQo+ID4gPiAyLjQuNg0KPiA+DQo+
ID4NCj4gDQo+IC0tDQo+IFBlbmd1dHJvbml4IGUuSy4gICAgICAgICAgICAgICAgICAgICAgICAg
ICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQo+IEluZHVzdHJpYWwgTGludXggU29s
dXRpb25zICAgICAgICAgICAgICAgICB8IGh0dHA6Ly93d3cucGVuZ3V0cm9uaXguZGUvICB8DQo+
IFBlaW5lciBTdHIuIDYtOCwgMzExMzcgSGlsZGVzaGVpbSwgR2VybWFueSB8IFBob25lOiArNDkt
NTEyMS0yMDY5MTctMCAgICB8DQo+IEFtdHNnZXJpY2h0IEhpbGRlc2hlaW0sIEhSQSAyNjg2ICAg
ICAgICAgICB8IEZheDogICArNDktNTEyMS0yMDY5MTctNTU1NSB8DQo=
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
2015-09-23 12:44 ` Tirdea, Irina
@ 2015-09-27 15:58 ` Jonathan Cameron
0 siblings, 0 replies; 21+ messages in thread
From: Jonathan Cameron @ 2015-09-27 15:58 UTC (permalink / raw)
To: Tirdea, Irina, Markus Pargmann
Cc: Srinivas Pandruvada, Lars-Peter Clausen,
linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
kernel@pengutronix.de
On 23/09/15 13:44, Tirdea, Irina wrote:
>
>
>> -----Original Message-----
>> From: Markus Pargmann [mailto:mpa@pengutronix.de]
>> Sent: 16 September, 2015 13:13
>> To: Tirdea, Irina
>> Cc: Jonathan Cameron; Srinivas Pandruvada; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
>> kernel@pengutronix.de
>> Subject: Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
>>
>> Hi Irina,
>>
>> On Wed, Sep 09, 2015 at 02:30:30PM +0000, Tirdea, Irina wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Markus Pargmann [mailto:mpa@pengutronix.de]
>>>> Sent: 20 August, 2015 15:50
>>>> To: Jonathan Cameron
>>>> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
>>>> kernel@pengutronix.de; Markus Pargmann
>>>> Subject: [PATCH v2 0/4] iio: bmc150 regmap and SPI
>>>>
>>>> Hi,
>>>>
>>>
>>> Hi Markus,
>>>
>>> I tested your patches with my BMA250E driver connected on the i2c bus .
>>> The code looks good and most of it works. There are a couple of issues I will mention
>>> below and in the individual patches.
>>>
>>> The patches in this version no longer apply cleanly on the togreg branch of the iio tree.
>>> I did the rebase myself, but since there were many conflicts I will do another test
>>> when you send the new rebased v3.
>>
>> Thank you for review and testing. I will integrate your comments and
>> send a rebased v3.
>>
>>>
>>>> this series converts the bmc150 driver to use regmap and adds an SPI interface.
>>>>
>>>> In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI support".
>>>> It now depends on "regmap: i2c block support".
>>>>
>>>
>>> I used the patches that were already merged in the regmap tree. This bmc150 series should
>>> probably wait until the regmap patches end up in Jonathan's tree, otherwise they will
>>> break the build.
>>
>> It seems the necessary patches are already in v4.3-rc1:
>> 29332534e2b6 (regmap-i2c: Add smbus i2c block support)
>>
>
> AFAIK, Jonathan waits until changes from the main kernel get merged back
> into his togreg branch. Since you are using regmap_get_raw_read_max that
> is introduced in the regmap patches, the driver won't build without them
> (if they are merged now in the iio tree).
Exactly, I tend not to explicitly pull other trees into mine other than my
upstream (staging-next currently). Those merges tend to only occur as fast
forward merges after Greg has accepted a pull request from me. Right
now I have one outstanding. After / if he takes that I can then fast forward
to a tree based on 4.3-rcX and apply these patches.
>
> However, that does not prevent me from testing the changes using
> the regmap changes from v4.3-rc1.
>
> Thanks,
> Irina
>
>> Best Regards,
>>
>> Markus
>>
>>>
>>> Thanks,
>>> Irina
>>>
>>>> Changes in v2:
>>>> - Removed default values for regmap_config fields.
>>>> - Redesigned the fifo_transfer function to avoid running in errors first.
>>>> - Dropped irq checks patch as it is already mainline
>>>> - Core can now be built as module with autoselection of i2c and spi parts
>>>>
>>>> As my hardware is missing an interrupt line from the SPI connected bmc150 I am
>>>> not able to test the iio buffer code path and the i2c code path. Tests would be
>>>> appreciated.
>>>>
>>>> Best regards,
>>>>
>>>> Markus
>>>>
>>>>
>>>> Markus Pargmann (4):
>>>> iio: bmc150: Use i2c regmap
>>>> iio: bcm150: Remove i2c_client from private data
>>>> iio: bmc150: Split the driver into core and i2c
>>>> iio: bmc150: Add SPI driver
>>>>
>>>> drivers/iio/accel/Kconfig | 14 +-
>>>> drivers/iio/accel/Makefile | 4 +-
>>>> .../accel/{bmc150-accel.c => bmc150-accel-core.c} | 398 ++++++++-------------
>>>> drivers/iio/accel/bmc150-accel-i2c.c | 99 +++++
>>>> drivers/iio/accel/bmc150-accel-spi.c | 83 +++++
>>>> drivers/iio/accel/bmc150-accel.h | 21 ++
>>>> 6 files changed, 367 insertions(+), 252 deletions(-)
>>>> rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (81%)
>>>> create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
>>>> create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
>>>> create mode 100644 drivers/iio/accel/bmc150-accel.h
>>>>
>>>> --
>>>> 2.4.6
>>>
>>>
>>
>> --
>> Pengutronix e.K. | |
>> Industrial Linux Solutions | http://www.pengutronix.de/ |
>> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
>> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
> N�����r��y���b�X��ǧv�^�){.n�+����{��*"��^n�r���z�\x1a��h����&��\x1e�G���h�\x03(�階�ݢj"��\x1a�^[m�����z�ޖ���f���h���~�mml==
>
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2015-09-27 15:58 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
2015-08-31 16:11 ` Jonathan Cameron
2015-08-31 19:38 ` Srinivas Pandruvada
2015-09-08 1:09 ` Tirdea, Irina
2015-09-01 13:57 ` Srinivas Pandruvada
2015-09-09 14:36 ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
2015-09-09 14:39 ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
2015-08-31 16:15 ` Jonathan Cameron
2015-09-01 14:07 ` Srinivas Pandruvada
2015-09-09 14:45 ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
2015-08-31 16:18 ` Jonathan Cameron
2015-09-01 14:10 ` Srinivas Pandruvada
2015-09-16 10:01 ` Markus Pargmann
2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
2015-09-16 10:13 ` Markus Pargmann
2015-09-23 12:44 ` Tirdea, Irina
2015-09-27 15:58 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).