All of lore.kernel.org
 help / color / mirror / Atom feed
* [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; 25+ 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] 25+ 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; 25+ 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 = &reg_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] 25+ 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; 25+ 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] 25+ 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   ` Tirdea, Irina
  4 siblings, 2 replies; 25+ 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] 25+ 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   ` Tirdea, Irina
  4 siblings, 1 reply; 25+ 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] 25+ 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; 25+ 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 = &reg_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] 25+ 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; 25+ 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] 25+ 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; 25+ 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] 25+ 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; 25+ 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 = &reg_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] 25+ 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; 25+ 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 = &reg_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] 25+ 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; 25+ 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] 25+ 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; 25+ 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] 25+ 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; 25+ 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, linux-kernel, kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 21368 bytes --]



> -----Original Message-----
> From: Srinivas Pandruvada [mailto:srinivas.pandruvada@linux.intel.com]
> Sent: 31 August, 2015 22:39
> To: Jonathan Cameron; Markus Pargmann; Tirdea, Irina
> Cc: Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org; kernel@pengutronix.de
> Subject: Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
> 
> Hi Irina,
> 

Hi Srinivas,

> 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).
> 

Sure, I'll test this patch set today.
Sorry for the late response, seems I somehow missed your e-mail.

Regards,
Irina

> 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 = &reg_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;
> > >
> >
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
@ 2015-09-08  1:09         ` Tirdea, Irina
  0 siblings, 0 replies; 25+ 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, linux-kernel, kernel

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] 25+ 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
@ 2015-09-09 14:30   ` 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, 0 replies; 25+ 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, linux-kernel, kernel



> -----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.

> 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.

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


^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH v2 0/4] iio: bmc150 regmap and SPI
@ 2015-09-09 14:30   ` Tirdea, Irina
  0 siblings, 0 replies; 25+ 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, linux-kernel, kernel



> -----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] 25+ 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-09-09 14:36     ` Tirdea, Irina
  2015-09-09 14:36     ` Tirdea, Irina
  1 sibling, 0 replies; 25+ 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, linux-kernel, kernel



> -----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 1/4] iio: bmc150: Use i2c regmap
> 
> This replaces all usage of direct i2c accesses with regmap accesses.
> 
> 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(-)
> 
> 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 = &reg_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);

step is declared as int, so using %zu will generate the following warning at build:
drivers/iio/accel/bmc150-accel.c:859:4: warning: format '%zu' expects argument of type 'size_t', but argument 3 has type 'int' [-Wformat=]
    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	[flat|nested] 25+ messages in thread

* RE: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
@ 2015-09-09 14:36     ` Tirdea, Irina
  0 siblings, 0 replies; 25+ 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, linux-kernel, kernel



> -----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 &reg_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] 25+ 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; 25+ 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, linux-kernel, kernel



> -----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] 25+ 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; 25+ 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, linux-kernel, kernel



> -----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] 25+ 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; 25+ 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] 25+ messages in thread

* Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
  2015-09-09 14:30   ` Tirdea, Irina
  (?)
@ 2015-09-16 10:13   ` Markus Pargmann
  2015-09-23 12:44       ` Tirdea, Irina
  -1 siblings, 1 reply; 25+ 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, linux-kernel, kernel

[-- 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] 25+ 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
  0 siblings, 0 replies; 25+ 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, linux-kernel, kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4417 bytes --]



> -----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).

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Ç+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 25+ messages in thread

* RE: [PATCH v2 0/4] iio: bmc150 regmap and SPI
@ 2015-09-23 12:44       ` Tirdea, Irina
  0 siblings, 0 replies; 25+ 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, linux-kernel, kernel

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] 25+ 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
  -1 siblings, 0 replies; 25+ 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, linux-kernel, kernel

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] 25+ messages in thread

end of thread, other threads:[~2015-09-27 15:58 UTC | newest]

Thread overview: 25+ 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-08  1:09         ` Tirdea, Irina
2015-09-01 13:57     ` Srinivas Pandruvada
2015-09-09 14:36   ` Tirdea, Irina
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-09 14:30   ` Tirdea, Irina
2015-09-16 10:13   ` Markus Pargmann
2015-09-23 12:44     ` Tirdea, Irina
2015-09-23 12:44       ` Tirdea, Irina
2015-09-27 15:58       ` Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.