linux-iio.vger.kernel.org archive mirror
 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; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel, Markus Pargmann

Hi,

this series converts the bmc150 driver to use regmap and adds an SPI interface.

In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI support".
It now depends on "regmap: i2c block support".

Changes in v2:
- Removed default values for regmap_config fields.
- Redesigned the fifo_transfer function to avoid running in errors first.
- Dropped irq checks patch as it is already mainline
- Core can now be built as module with autoselection of i2c and spi parts

As my hardware is missing an interrupt line from the SPI connected bmc150 I am
not able to test the iio buffer code path and the i2c code path. Tests would be
appreciated.

Best regards,

Markus


Markus Pargmann (4):
  iio: bmc150: Use i2c regmap
  iio: bcm150: Remove i2c_client from private data
  iio: bmc150: Split the driver into core and i2c
  iio: bmc150: Add SPI driver

 drivers/iio/accel/Kconfig                          |  14 +-
 drivers/iio/accel/Makefile                         |   4 +-
 .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 398 ++++++++-------------
 drivers/iio/accel/bmc150-accel-i2c.c               |  99 +++++
 drivers/iio/accel/bmc150-accel-spi.c               |  83 +++++
 drivers/iio/accel/bmc150-accel.h                   |  21 ++
 6 files changed, 367 insertions(+), 252 deletions(-)
 rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (81%)
 create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
 create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
 create mode 100644 drivers/iio/accel/bmc150-accel.h

-- 
2.4.6


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

* [PATCH v2 1/4] iio: bmc150: Use i2c regmap
  2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
  2015-08-31 16:11   ` Jonathan Cameron
  2015-09-09 14:36   ` Tirdea, Irina
  2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel, Markus Pargmann

This replaces all usage of direct i2c accesses with regmap accesses.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/iio/accel/Kconfig        |   2 +
 drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------------------
 2 files changed, 95 insertions(+), 126 deletions(-)

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 00e7bcbdbe24..01dd03d194d1 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -22,6 +22,8 @@ config BMC150_ACCEL
 	depends on I2C
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
+	select REGMAP
+	select REGMAP_I2C
 	help
 	  Say yes here to build support for the following Bosch accelerometers:
 	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index 55751d9e1ade..c5c773e75173 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -35,6 +35,7 @@
 #include <linux/iio/trigger.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
+#include <linux/regmap.h>
 
 #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
 #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
@@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
 
 struct bmc150_accel_data {
 	struct i2c_client *client;
+	struct regmap *regmap;
+	struct device *dev;
 	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
 	atomic_t active_intr;
 	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -241,6 +244,11 @@ static const struct {
 				       {500000, BMC150_ACCEL_SLEEP_500_MS},
 				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
 
+static const struct regmap_config bmc150_i2c_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x3f,
+};
 
 static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 				 enum bmc150_power_modes mode,
@@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 
 	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
 
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
 		return ret;
@@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
 	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
 		if (bmc150_accel_samp_freq_table[i].val == val &&
 				bmc150_accel_samp_freq_table[i].val2 == val2) {
-			ret = i2c_smbus_write_byte_data(
-				data->client,
+			ret = regmap_write(data->regmap,
 				BMC150_ACCEL_REG_PMU_BW,
 				bmc150_accel_samp_freq_table[i].bw_bits);
 			if (ret < 0)
@@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
 
 static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
 {
-	int ret, val;
+	int ret;
 
-	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
 					data->slope_thres);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error writing reg_int_6\n");
 		return ret;
 	}
 
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
+	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
+				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_5\n");
-		return ret;
-	}
-
-	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
-	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
-					val);
-	if (ret < 0) {
-		dev_err(&data->client->dev, "Error write reg_int_5\n");
+		dev_err(&data->client->dev, "Error updating reg_int_5\n");
 		return ret;
 	}
 
@@ -348,17 +347,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
 static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 {
 	int ret;
+	unsigned int val;
 
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
+	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 			"Error: Reading chip id\n");
 		return ret;
 	}
 
-	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
-	if (ret != data->chip_info->chip_id) {
-		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
+	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
+	if (val != data->chip_info->chip_id) {
+		dev_err(&data->client->dev, "Invalid chip %x\n", val);
 		return -ENODEV;
 	}
 
@@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 		return ret;
 
 	/* Set Default Range */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_PMU_RANGE,
-					BMC150_ACCEL_DEF_RANGE_4G);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
+			   BMC150_ACCEL_DEF_RANGE_4G);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 					"Error writing reg_pmu_range\n");
@@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 		return ret;
 
 	/* Set default as latched interrupts */
-	ret = i2c_smbus_write_byte_data(data->client,
-					BMC150_ACCEL_REG_INT_RST_LATCH,
-					BMC150_ACCEL_INT_MODE_LATCH_INT |
-					BMC150_ACCEL_INT_MODE_LATCH_RESET);
+	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
+			   BMC150_ACCEL_INT_MODE_LATCH_INT |
+			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 			"Error writing reg_int_rst_latch\n");
@@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 		return ret;
 
 	/* map the interrupt to the appropriate pins */
-	ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
+	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
+				 (state ? info->map_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_map\n");
-		goto out_fix_power_state;
-	}
-	if (state)
-		ret |= info->map_bitmask;
-	else
-		ret &= ~info->map_bitmask;
-
-	ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
-					ret);
-	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_int_map\n");
+		dev_err(&data->client->dev, "Error updating reg_int_map\n");
 		goto out_fix_power_state;
 	}
 
 	/* enable/disable the interrupt */
-	ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
+	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
+				 (state ? info->en_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_en\n");
-		goto out_fix_power_state;
-	}
-
-	if (state)
-		ret |= info->en_bitmask;
-	else
-		ret &= ~info->en_bitmask;
-
-	ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
-	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_int_en\n");
+		dev_err(&data->client->dev, "Error updating reg_int_en\n");
 		goto out_fix_power_state;
 	}
 
@@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 
 	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
 		if (data->chip_info->scale_table[i].scale == val) {
-			ret = i2c_smbus_write_byte_data(
-				     data->client,
+			ret = regmap_write(data->regmap,
 				     BMC150_ACCEL_REG_PMU_RANGE,
 				     data->chip_info->scale_table[i].reg_range);
 			if (ret < 0) {
@@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
 {
 	int ret;
+	unsigned int value;
 
 	mutex_lock(&data->mutex);
 
-	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
+	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading reg_temp\n");
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
-	*val = sign_extend32(ret, 7);
+	*val = sign_extend32(value, 7);
 
 	mutex_unlock(&data->mutex);
 
@@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 {
 	int ret;
 	int axis = chan->scan_index;
+	unsigned int raw_val;
 
 	mutex_lock(&data->mutex);
 	ret = bmc150_accel_set_power_state(data, true);
@@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 		return ret;
 	}
 
-	ret = i2c_smbus_read_word_data(data->client,
-				       BMC150_ACCEL_AXIS_TO_REG(axis));
+	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
+			       &raw_val, 2);
 	if (ret < 0) {
 		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
 		bmc150_accel_set_power_state(data, false);
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
-	*val = sign_extend32(ret >> chan->scan_type.shift,
+	*val = sign_extend32(raw_val >> chan->scan_type.shift,
 			     chan->scan_type.realbits - 1);
 	ret = bmc150_accel_set_power_state(data, false);
 	mutex_unlock(&data->mutex);
@@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
  * We must read at least one full frame in one burst, otherwise the rest of the
  * frame data is discarded.
  */
-static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
+static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
 				      char *buffer, int samples)
 {
 	int sample_length = 3 * 2;
-	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
-	int ret = -EIO;
-
-	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		struct i2c_msg msg[2] = {
-			{
-				.addr = client->addr,
-				.flags = 0,
-				.buf = &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] 21+ messages in thread

* [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data
  2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
  2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
  2015-09-09 14:39   ` Tirdea, Irina
  2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel, Markus Pargmann

i2c_client struct is now only used for debugging output. We can use the
device struct as well so we can remove all struct i2c_client usage.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Acked-by: Jonathan Cameron <jic23@kernel.org>
---
 drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
 1 file changed, 58 insertions(+), 62 deletions(-)

diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
index c5c773e75173..e4a0691d9b88 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel.c
@@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
 };
 
 struct bmc150_accel_data {
-	struct i2c_client *client;
 	struct regmap *regmap;
 	struct device *dev;
+	int irq;
 	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
 	atomic_t active_intr;
 	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -276,11 +276,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
 	lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
 	lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
 
-	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
+	dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
 
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
+		dev_err(data->dev, "Error writing reg_pmu_lpw\n");
 		return ret;
 	}
 
@@ -318,18 +318,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
 					data->slope_thres);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_int_6\n");
+		dev_err(data->dev, "Error writing reg_int_6\n");
 		return ret;
 	}
 
 	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
 				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error updating reg_int_5\n");
+		dev_err(data->dev, "Error updating reg_int_5\n");
 		return ret;
 	}
 
-	dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
+	dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
 		data->slope_dur);
 
 	return ret;
@@ -351,14 +351,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Error: Reading chip id\n");
 		return ret;
 	}
 
-	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
+	dev_dbg(data->dev, "Chip Id %x\n", val);
 	if (val != data->chip_info->chip_id) {
-		dev_err(&data->client->dev, "Invalid chip %x\n", val);
+		dev_err(data->dev, "Invalid chip %x\n", val);
 		return -ENODEV;
 	}
 
@@ -375,8 +375,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
 			   BMC150_ACCEL_DEF_RANGE_4G);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
-					"Error writing reg_pmu_range\n");
+		dev_err(data->dev, "Error writing reg_pmu_range\n");
 		return ret;
 	}
 
@@ -394,7 +393,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 			   BMC150_ACCEL_INT_MODE_LATCH_INT |
 			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Error writing reg_int_rst_latch\n");
 		return ret;
 	}
@@ -436,16 +435,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
 	int ret;
 
 	if (on)
-		ret = pm_runtime_get_sync(&data->client->dev);
+		ret = pm_runtime_get_sync(data->dev);
 	else {
-		pm_runtime_mark_last_busy(&data->client->dev);
-		ret = pm_runtime_put_autosuspend(&data->client->dev);
+		pm_runtime_mark_last_busy(data->dev);
+		ret = pm_runtime_put_autosuspend(data->dev);
 	}
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Failed: bmc150_accel_set_power_state for %d\n", on);
 		if (on)
-			pm_runtime_put_noidle(&data->client->dev);
+			pm_runtime_put_noidle(data->dev);
 
 		return ret;
 	}
@@ -528,7 +527,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
 				 (state ? info->map_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error updating reg_int_map\n");
+		dev_err(data->dev, "Error updating reg_int_map\n");
 		goto out_fix_power_state;
 	}
 
@@ -536,7 +535,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
 	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
 				 (state ? info->en_bitmask : 0));
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error updating reg_int_en\n");
+		dev_err(data->dev, "Error updating reg_int_en\n");
 		goto out_fix_power_state;
 	}
 
@@ -563,7 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
 				     BMC150_ACCEL_REG_PMU_RANGE,
 				     data->chip_info->scale_table[i].reg_range);
 			if (ret < 0) {
-				dev_err(&data->client->dev,
+				dev_err(data->dev,
 					"Error writing pmu_range\n");
 				return ret;
 			}
@@ -585,7 +584,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_temp\n");
+		dev_err(data->dev, "Error reading reg_temp\n");
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
@@ -614,7 +613,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
 	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
 			       &raw_val, 2);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
+		dev_err(data->dev, "Error reading axis %d\n", axis);
 		bmc150_accel_set_power_state(data, false);
 		mutex_unlock(&data->mutex);
 		return ret;
@@ -928,7 +927,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
+		dev_err(data->dev, "Error reading reg_fifo_status\n");
 		return ret;
 	}
 
@@ -1209,7 +1208,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
 			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 	mutex_unlock(&data->mutex);
 	if (ret < 0) {
-		dev_err(&data->client->dev,
+		dev_err(data->dev,
 			"Error writing reg_int_rst_latch\n");
 		return ret;
 	}
@@ -1267,7 +1266,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
 
 	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
+		dev_err(data->dev, "Error reading reg_int_status_2\n");
 		return ret;
 	}
 
@@ -1327,7 +1326,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
 				   BMC150_ACCEL_INT_MODE_LATCH_INT |
 				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret)
-			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
 		ret = IRQ_HANDLED;
 	} else {
 		ret = IRQ_NONE;
@@ -1379,17 +1378,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
 	return dev_name(dev);
 }
 
-static int bmc150_accel_gpio_probe(struct i2c_client *client,
-					struct bmc150_accel_data *data)
+static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
 {
 	struct device *dev;
 	struct gpio_desc *gpio;
 	int ret;
 
-	if (!client)
-		return -EINVAL;
-
-	dev = &client->dev;
+	dev = data->dev;
 
 	/* data ready gpio interrupt pin */
 	gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
@@ -1442,7 +1437,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
 	for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
 		struct bmc150_accel_trigger *t = &data->triggers[i];
 
-		t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
+		t->indio_trig = devm_iio_trigger_alloc(data->dev,
 					       bmc150_accel_triggers[i].name,
 						       indio_dev->name,
 						       indio_dev->id);
@@ -1451,7 +1446,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
 			break;
 		}
 
-		t->indio_trig->dev.parent = &data->client->dev;
+		t->indio_trig->dev.parent = data->dev;
 		t->indio_trig->ops = &bmc150_accel_trigger_ops;
 		t->intr = bmc150_accel_triggers[i].intr;
 		t->data = data;
@@ -1480,7 +1475,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
 
 	ret = regmap_write(data->regmap, reg, data->fifo_mode);
 	if (ret < 0) {
-		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
+		dev_err(data->dev, "Error writing reg_fifo_config1\n");
 		return ret;
 	}
 
@@ -1490,7 +1485,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
 	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
 			   data->watermark);
 	if (ret < 0)
-		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
+		dev_err(data->dev, "Error writing reg_fifo_config0\n");
 
 	return ret;
 }
@@ -1580,6 +1575,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 	int ret;
 	const char *name = NULL;
 	int chip_id = 0;
+	struct device *dev;
 
 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
@@ -1587,12 +1583,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	data = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
-	data->client = client;
 	data->dev = &client->dev;
+	dev = &client->dev;
+	data->irq = client->irq;
 
 	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
 	if (IS_ERR(data->regmap)) {
-		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+		dev_err(dev, "Failed to initialize i2c regmap\n");
 		return PTR_ERR(data->regmap);
 	}
 
@@ -1601,8 +1598,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		chip_id = id->driver_data;
 	}
 
-	if (ACPI_HANDLE(&client->dev))
-		name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
+	if (ACPI_HANDLE(dev))
+		name = bmc150_accel_match_acpi_device(dev, &chip_id);
 
 	data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
 
@@ -1612,7 +1609,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	mutex_init(&data->mutex);
 
-	indio_dev->dev.parent = &client->dev;
+	indio_dev->dev.parent = dev;
 	indio_dev->channels = data->chip_info->channels;
 	indio_dev->num_channels = data->chip_info->num_channels;
 	indio_dev->name = name;
@@ -1624,16 +1621,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
 					 bmc150_accel_trigger_handler,
 					 &bmc150_accel_buffer_ops);
 	if (ret < 0) {
-		dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
+		dev_err(data->dev, "Failed: iio triggered buffer setup\n");
 		return ret;
 	}
 
-	if (client->irq < 0)
-		client->irq = bmc150_accel_gpio_probe(client, data);
+	if (data->irq <= 0)
+		data->irq = bmc150_accel_gpio_probe(data);
 
-	if (client->irq > 0) {
+	if (data->irq > 0) {
 		ret = devm_request_threaded_irq(
-						&client->dev, client->irq,
+						data->dev, data->irq,
 						bmc150_accel_irq_handler,
 						bmc150_accel_irq_thread_handler,
 						IRQF_TRIGGER_RISING,
@@ -1651,7 +1648,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
 				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
 		if (ret < 0) {
-			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
+			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
 			goto err_buffer_cleanup;
 		}
 
@@ -1672,18 +1669,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
-		dev_err(&client->dev, "Unable to register iio device\n");
+		dev_err(data->dev, "Unable to register iio device\n");
 		goto err_trigger_unregister;
 	}
 
-	ret = pm_runtime_set_active(&client->dev);
+	ret = pm_runtime_set_active(dev);
 	if (ret)
 		goto err_iio_unregister;
 
-	pm_runtime_enable(&client->dev);
-	pm_runtime_set_autosuspend_delay(&client->dev,
-					 BMC150_AUTO_SUSPEND_DELAY_MS);
-	pm_runtime_use_autosuspend(&client->dev);
+	pm_runtime_enable(dev);
+	pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
+	pm_runtime_use_autosuspend(dev);
 
 	return 0;
 
@@ -1702,9 +1698,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
-	pm_runtime_disable(&client->dev);
-	pm_runtime_set_suspended(&client->dev);
-	pm_runtime_put_noidle(&client->dev);
+	pm_runtime_disable(data->dev);
+	pm_runtime_set_suspended(data->dev);
+	pm_runtime_put_noidle(data->dev);
 
 	iio_device_unregister(indio_dev);
 
@@ -1722,7 +1718,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
 #ifdef CONFIG_PM_SLEEP
 static int bmc150_accel_suspend(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 	mutex_lock(&data->mutex);
@@ -1734,7 +1730,7 @@ static int bmc150_accel_suspend(struct device *dev)
 
 static int bmc150_accel_resume(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 	mutex_lock(&data->mutex);
@@ -1750,11 +1746,11 @@ static int bmc150_accel_resume(struct device *dev)
 #ifdef CONFIG_PM
 static int bmc150_accel_runtime_suspend(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int ret;
 
-	dev_dbg(&data->client->dev,  __func__);
+	dev_dbg(data->dev,  __func__);
 	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
 	if (ret < 0)
 		return -EAGAIN;
@@ -1764,12 +1760,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
 
 static int bmc150_accel_runtime_resume(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 	int ret;
 	int sleep_val;
 
-	dev_dbg(&data->client->dev,  __func__);
+	dev_dbg(data->dev,  __func__);
 
 	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
 	if (ret < 0)
-- 
2.4.6


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

* [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
  2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
  2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
  2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
  2015-08-31 16:15   ` Jonathan Cameron
  2015-09-09 14:45   ` Tirdea, Irina
  2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
  2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
  4 siblings, 2 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel, Markus Pargmann

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/iio/accel/Kconfig                          |  9 +-
 drivers/iio/accel/Makefile                         |  3 +-
 .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 95 ++++-----------------
 drivers/iio/accel/bmc150-accel-i2c.c               | 99 ++++++++++++++++++++++
 drivers/iio/accel/bmc150-accel.h                   | 21 +++++
 5 files changed, 144 insertions(+), 83 deletions(-)
 rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
 create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
 create mode 100644 drivers/iio/accel/bmc150-accel.h

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 01dd03d194d1..6da4eb0db57b 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -19,21 +19,22 @@ config BMA180
 
 config BMC150_ACCEL
 	tristate "Bosch BMC150 Accelerometer Driver"
-	depends on I2C
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select REGMAP
-	select REGMAP_I2C
+	select BMC150_ACCEL_I2C if I2C
 	help
 	  Say yes here to build support for the following Bosch accelerometers:
 	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
 
-	  Currently this only supports the device via an i2c interface.
-
 	  This is a combo module with both accelerometer and magnetometer.
 	  This driver is only implementing accelerometer part, which has
 	  its own address and register map.
 
+config BMC150_ACCEL_I2C
+	tristate
+	select REGMAP_I2C
+
 config HID_SENSOR_ACCEL_3D
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index ebd2675b2a02..5ef8bdbad092 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -4,7 +4,8 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_BMA180) += bma180.o
-obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
+obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
+obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
similarity index 95%
rename from drivers/iio/accel/bmc150-accel.c
rename to drivers/iio/accel/bmc150-accel-core.c
index e4a0691d9b88..614cf61f0110 100644
--- a/drivers/iio/accel/bmc150-accel.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -37,6 +37,8 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/regmap.h>
 
+#include "bmc150-accel.h"
+
 #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
 #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
 #define BMC150_ACCEL_GPIO_NAME			"bmc150_accel_int"
@@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
 struct bmc150_accel_data {
 	struct regmap *regmap;
 	struct device *dev;
-	int irq;
 	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
 	atomic_t active_intr;
 	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
@@ -201,6 +202,7 @@ struct bmc150_accel_data {
 	int ev_enable_state;
 	int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
 	const struct bmc150_accel_chip_info *chip_info;
+	int irq;
 };
 
 static const struct {
@@ -1070,15 +1072,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
 static const struct iio_chan_spec bma280_accel_channels[] =
 	BMC150_ACCEL_CHANNELS(14);
 
-enum {
-	bmc150,
-	bmi055,
-	bma255,
-	bma250e,
-	bma222e,
-	bma280,
-};
-
 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 	[bmc150] = {
 		.chip_id = 0xFA,
@@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
 	.postdisable = bmc150_accel_buffer_postdisable,
 };
 
-static int bmc150_accel_probe(struct i2c_client *client,
-			      const struct i2c_device_id *id)
+int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
+			    const char *name, int chip_id, bool block_supported)
 {
 	struct bmc150_accel_data *data;
 	struct iio_dev *indio_dev;
 	int ret;
-	const char *name = NULL;
-	int chip_id = 0;
-	struct device *dev;
 
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
 	if (!indio_dev)
 		return -ENOMEM;
 
 	data = iio_priv(indio_dev);
-	i2c_set_clientdata(client, indio_dev);
-	data->dev = &client->dev;
-	dev = &client->dev;
-	data->irq = client->irq;
-
-	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
-	if (IS_ERR(data->regmap)) {
-		dev_err(dev, "Failed to initialize i2c regmap\n");
-		return PTR_ERR(data->regmap);
-	}
-
-	if (id) {
-		name = id->name;
-		chip_id = id->driver_data;
-	}
+	dev_set_drvdata(dev, indio_dev);
+	data->dev = dev;
+	data->irq = irq;
+	data->regmap = regmap;
 
 	if (ACPI_HANDLE(dev))
 		name = bmc150_accel_match_acpi_device(dev, &chip_id);
@@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		if (ret)
 			goto err_buffer_cleanup;
 
-		if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
-		    i2c_check_functionality(client->adapter,
-					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+		if (block_supported) {
 			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
 			indio_dev->info = &bmc150_accel_info_fifo;
 			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
@@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
-		dev_err(data->dev, "Unable to register iio device\n");
+		dev_err(dev, "Unable to register iio device\n");
 		goto err_trigger_unregister;
 	}
 
@@ -1692,10 +1669,11 @@ err_buffer_cleanup:
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
 
-static int bmc150_accel_remove(struct i2c_client *client)
+int bmc150_accel_core_remove(struct device *dev)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 	pm_runtime_disable(data->dev);
@@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
 
 #ifdef CONFIG_PM_SLEEP
 static int bmc150_accel_suspend(struct device *dev)
@@ -1784,48 +1763,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
 }
 #endif
 
-static const struct dev_pm_ops bmc150_accel_pm_ops = {
+const struct dev_pm_ops bmc150_accel_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
 	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
 			   bmc150_accel_runtime_resume, NULL)
 };
-
-static const struct acpi_device_id bmc150_accel_acpi_match[] = {
-	{"BSBA0150",	bmc150},
-	{"BMC150A",	bmc150},
-	{"BMI055A",	bmi055},
-	{"BMA0255",	bma255},
-	{"BMA250E",	bma250e},
-	{"BMA222E",	bma222e},
-	{"BMA0280",	bma280},
-	{ },
-};
-MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
-
-static const struct i2c_device_id bmc150_accel_id[] = {
-	{"bmc150_accel",	bmc150},
-	{"bmi055_accel",	bmi055},
-	{"bma255",		bma255},
-	{"bma250e",		bma250e},
-	{"bma222e",		bma222e},
-	{"bma280",		bma280},
-	{}
-};
-
-MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
-
-static struct i2c_driver bmc150_accel_driver = {
-	.driver = {
-		.name	= BMC150_ACCEL_DRV_NAME,
-		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
-		.pm	= &bmc150_accel_pm_ops,
-	},
-	.probe		= bmc150_accel_probe,
-	.remove		= bmc150_accel_remove,
-	.id_table	= bmc150_accel_id,
-};
-module_i2c_driver(bmc150_accel_driver);
-
-MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("BMC150 accelerometer driver");
diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
new file mode 100644
index 000000000000..e4dd596ba8f2
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel-i2c.c
@@ -0,0 +1,99 @@
+/*
+ * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
+ *  - BMC150
+ *  - BMI055
+ *  - BMA255
+ *  - BMA250E
+ *  - BMA222E
+ *  - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+
+#include "bmc150-accel.h"
+
+static const struct regmap_config bmc150_i2c_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int bmc150_accel_probe(struct i2c_client *client,
+			      const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	bool block_supported =
+		i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
+		i2c_check_functionality(client->adapter,
+					I2C_FUNC_SMBUS_READ_I2C_BLOCK);
+
+	regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
+		return PTR_ERR(regmap);
+	}
+
+	return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
+				       id->name, id->driver_data,
+				       block_supported);
+}
+
+static int bmc150_accel_remove(struct i2c_client *client)
+{
+	return bmc150_accel_core_remove(&client->dev);
+}
+
+static const struct acpi_device_id bmc150_accel_acpi_match[] = {
+	{"BSBA0150",	bmc150},
+	{"BMC150A",	bmc150},
+	{"BMI055A",	bmi055},
+	{"BMA0255",	bma255},
+	{"BMA250E",	bma250e},
+	{"BMA222E",	bma222e},
+	{"BMA0280",	bma280},
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
+
+static const struct i2c_device_id bmc150_accel_id[] = {
+	{"bmc150_accel",	bmc150},
+	{"bmi055_accel",	bmi055},
+	{"bma255",		bma255},
+	{"bma250e",		bma250e},
+	{"bma222e",		bma222e},
+	{"bma280",		bma280},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
+
+static struct i2c_driver bmc150_accel_driver = {
+	.driver = {
+		.name	= "bmc150_accel_i2c",
+		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+		.pm	= &bmc150_accel_pm_ops,
+	},
+	.probe		= bmc150_accel_probe,
+	.remove		= bmc150_accel_remove,
+	.id_table	= bmc150_accel_id,
+};
+module_i2c_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
new file mode 100644
index 000000000000..988b57573d0c
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel.h
@@ -0,0 +1,21 @@
+#ifndef _BMC150_ACCEL_H_
+#define _BMC150_ACCEL_H_
+
+struct regmap;
+
+enum {
+	bmc150,
+	bmi055,
+	bma255,
+	bma250e,
+	bma222e,
+	bma280,
+};
+
+int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
+			    const char *name, int chip_id,
+			    bool block_supported);
+int bmc150_accel_core_remove(struct device *dev);
+extern const struct dev_pm_ops bmc150_accel_pm_ops;
+
+#endif  /* _BMC150_ACCEL_H_ */
-- 
2.4.6


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

* [PATCH v2 4/4] iio: bmc150: Add SPI driver
  2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
                   ` (2 preceding siblings ...)
  2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
@ 2015-08-20 12:49 ` Markus Pargmann
  2015-08-31 16:18   ` Jonathan Cameron
  2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
  4 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2015-08-20 12:49 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel, Markus Pargmann

Add a simple SPI driver which initializes the spi regmap for the bmc150
core driver.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/iio/accel/Kconfig            |  5 +++
 drivers/iio/accel/Makefile           |  1 +
 drivers/iio/accel/bmc150-accel-spi.c | 83 ++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+)
 create mode 100644 drivers/iio/accel/bmc150-accel-spi.c

diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 6da4eb0db57b..56d24fa3d34a 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -23,6 +23,7 @@ config BMC150_ACCEL
 	select IIO_TRIGGERED_BUFFER
 	select REGMAP
 	select BMC150_ACCEL_I2C if I2C
+	select BMC150_ACCEL_SPI if SPI
 	help
 	  Say yes here to build support for the following Bosch accelerometers:
 	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
@@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
 	tristate
 	select REGMAP_I2C
 
+config BMC150_ACCEL_SPI
+	tristate
+	select REGMAP_SPI
+
 config HID_SENSOR_ACCEL_3D
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 5ef8bdbad092..e579e93bf022 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_BMA180) += bma180.o
 obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
 obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
+obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
 obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
new file mode 100644
index 000000000000..1c2a4f683da4
--- /dev/null
+++ b/drivers/iio/accel/bmc150-accel-spi.c
@@ -0,0 +1,83 @@
+/*
+ * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
+ *  - BMC150
+ *  - BMI055
+ *  - BMA255
+ *  - BMA250E
+ *  - BMA222E
+ *  - BMA280
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include "bmc150-accel.h"
+
+static const struct regmap_config bmc150_spi_regmap_conf = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x3f,
+};
+
+static int bmc150_accel_probe(struct spi_device *spi)
+{
+	struct regmap *regmap;
+	const struct spi_device_id *id = spi_get_device_id(spi);
+
+	regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
+	if (IS_ERR(regmap)) {
+		dev_err(&spi->dev, "Failed to initialize spi regmap\n");
+		return PTR_ERR(regmap);
+	}
+
+	return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
+				       id->name, id->driver_data, true);
+}
+
+static int bmc150_accel_remove(struct spi_device *spi)
+{
+	return bmc150_accel_core_remove(&spi->dev);
+}
+
+static const struct spi_device_id bmc150_accel_id[] = {
+	{"bmc150_accel",	bmc150},
+	{"bmi055_accel",	bmi055},
+	{"bma255",		bma255},
+	{"bma250e",		bma250e},
+	{"bma222e",		bma222e},
+	{"bma280",		bma280},
+	{}
+};
+
+MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
+
+static struct spi_driver bmc150_accel_driver = {
+	.driver = {
+		.name	= "bmc150_accel_spi",
+		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
+		.pm	= &bmc150_accel_pm_ops,
+	},
+	.probe		= bmc150_accel_probe,
+	.remove		= bmc150_accel_remove,
+	.id_table	= bmc150_accel_id,
+};
+module_spi_driver(bmc150_accel_driver);
+
+MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
-- 
2.4.6


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

* Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
  2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
@ 2015-08-31 16:11   ` Jonathan Cameron
  2015-08-31 19:38     ` Srinivas Pandruvada
  2015-09-01 13:57     ` Srinivas Pandruvada
  2015-09-09 14:36   ` Tirdea, Irina
  1 sibling, 2 replies; 21+ messages in thread
From: Jonathan Cameron @ 2015-08-31 16:11 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel

On 20/08/15 13:49, Markus Pargmann wrote:
> This replaces all usage of direct i2c accesses with regmap accesses.
> 
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Looks fine to me,  but I will be wanting an Ack / reviewed-by
and preferably a tested by from Srinivas.

Thanks,

Jonathan
> ---
>  drivers/iio/accel/Kconfig        |   2 +
>  drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------------------
>  2 files changed, 95 insertions(+), 126 deletions(-)
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 00e7bcbdbe24..01dd03d194d1 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -22,6 +22,8 @@ config BMC150_ACCEL
>  	depends on I2C
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
> +	select REGMAP
> +	select REGMAP_I2C
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index 55751d9e1ade..c5c773e75173 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -35,6 +35,7 @@
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/trigger_consumer.h>
>  #include <linux/iio/triggered_buffer.h>
> +#include <linux/regmap.h>
>  
>  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
>  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
> @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
>  
>  struct bmc150_accel_data {
>  	struct i2c_client *client;
> +	struct regmap *regmap;
> +	struct device *dev;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -241,6 +244,11 @@ static const struct {
>  				       {500000, BMC150_ACCEL_SLEEP_500_MS},
>  				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
>  
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = 0x3f,
> +};
>  
>  static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  				 enum bmc150_power_modes mode,
> @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  
>  	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
>  
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
>  		return ret;
> @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
>  	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
>  		if (bmc150_accel_samp_freq_table[i].val == val &&
>  				bmc150_accel_samp_freq_table[i].val2 == val2) {
> -			ret = i2c_smbus_write_byte_data(
> -				data->client,
> +			ret = regmap_write(data->regmap,
>  				BMC150_ACCEL_REG_PMU_BW,
>  				bmc150_accel_samp_freq_table[i].bw_bits);
>  			if (ret < 0)
> @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val,
>  
>  static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
>  {
> -	int ret, val;
> +	int ret;
>  
> -	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
>  					data->slope_thres);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_int_6\n");
>  		return ret;
>  	}
>  
> -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
> +	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> +				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_5\n");
> -		return ret;
> -	}
> -
> -	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
> -	ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
> -					val);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error write reg_int_5\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_5\n");
>  		return ret;
>  	}
>  
> @@ -348,17 +347,18 @@ static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
>  static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  {
>  	int ret;
> +	unsigned int val;
>  
> -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID);
> +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  			"Error: Reading chip id\n");
>  		return ret;
>  	}
>  
> -	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> -	if (ret != data->chip_info->chip_id) {
> -		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
> +	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> +	if (val != data->chip_info->chip_id) {
> +		dev_err(&data->client->dev, "Invalid chip %x\n", val);
>  		return -ENODEV;
>  	}
>  
> @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  		return ret;
>  
>  	/* Set Default Range */
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_PMU_RANGE,
> -					BMC150_ACCEL_DEF_RANGE_4G);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> +			   BMC150_ACCEL_DEF_RANGE_4G);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  					"Error writing reg_pmu_range\n");
> @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  		return ret;
>  
>  	/* Set default as latched interrupts */
> -	ret = i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_INT_RST_LATCH,
> -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  			"Error writing reg_int_rst_latch\n");
> @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
>  		return ret;
>  
>  	/* map the interrupt to the appropriate pins */
> -	ret = i2c_smbus_read_byte_data(data->client, info->map_reg);
> +	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
> +				 (state ? info->map_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_map\n");
> -		goto out_fix_power_state;
> -	}
> -	if (state)
> -		ret |= info->map_bitmask;
> -	else
> -		ret &= ~info->map_bitmask;
> -
> -	ret = i2c_smbus_write_byte_data(data->client, info->map_reg,
> -					ret);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_map\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_map\n");
>  		goto out_fix_power_state;
>  	}
>  
>  	/* enable/disable the interrupt */
> -	ret = i2c_smbus_read_byte_data(data->client, info->en_reg);
> +	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
> +				 (state ? info->en_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_en\n");
> -		goto out_fix_power_state;
> -	}
> -
> -	if (state)
> -		ret |= info->en_bitmask;
> -	else
> -		ret &= ~info->en_bitmask;
> -
> -	ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_en\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_en\n");
>  		goto out_fix_power_state;
>  	}
>  
> @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>  
>  	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
>  		if (data->chip_info->scale_table[i].scale == val) {
> -			ret = i2c_smbus_write_byte_data(
> -				     data->client,
> +			ret = regmap_write(data->regmap,
>  				     BMC150_ACCEL_REG_PMU_RANGE,
>  				     data->chip_info->scale_table[i].reg_range);
>  			if (ret < 0) {
> @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>  static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
>  {
>  	int ret;
> +	unsigned int value;
>  
>  	mutex_lock(&data->mutex);
>  
> -	ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
> +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading reg_temp\n");
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> -	*val = sign_extend32(ret, 7);
> +	*val = sign_extend32(value, 7);
>  
>  	mutex_unlock(&data->mutex);
>  
> @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
>  {
>  	int ret;
>  	int axis = chan->scan_index;
> +	unsigned int raw_val;
>  
>  	mutex_lock(&data->mutex);
>  	ret = bmc150_accel_set_power_state(data, true);
> @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
>  		return ret;
>  	}
>  
> -	ret = i2c_smbus_read_word_data(data->client,
> -				       BMC150_ACCEL_AXIS_TO_REG(axis));
> +	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> +			       &raw_val, 2);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
>  		bmc150_accel_set_power_state(data, false);
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> -	*val = sign_extend32(ret >> chan->scan_type.shift,
> +	*val = sign_extend32(raw_val >> chan->scan_type.shift,
>  			     chan->scan_type.realbits - 1);
>  	ret = bmc150_accel_set_power_state(data, false);
>  	mutex_unlock(&data->mutex);
> @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct iio_dev *indio_dev, unsigned val)
>   * We must read at least one full frame in one burst, otherwise the rest of the
>   * frame data is discarded.
>   */
> -static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
> +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
>  				      char *buffer, int samples)
>  {
>  	int sample_length = 3 * 2;
> -	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> -	int ret = -EIO;
> -
> -	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> -		struct i2c_msg msg[2] = {
> -			{
> -				.addr = client->addr,
> -				.flags = 0,
> -				.buf = &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] 21+ messages in thread

* Re: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
  2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
@ 2015-08-31 16:15   ` Jonathan Cameron
  2015-09-01 14:07     ` Srinivas Pandruvada
  2015-09-09 14:45   ` Tirdea, Irina
  1 sibling, 1 reply; 21+ messages in thread
From: Jonathan Cameron @ 2015-08-31 16:15 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel

On 20/08/15 13:49, Markus Pargmann wrote:
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
A couple of little bits inline.  Again would like Srinivas to
take a quick look at this patch as well.

Thanks,

Jonathan
> ---
>  drivers/iio/accel/Kconfig                          |  9 +-
>  drivers/iio/accel/Makefile                         |  3 +-
>  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 95 ++++-----------------
>  drivers/iio/accel/bmc150-accel-i2c.c               | 99 ++++++++++++++++++++++
>  drivers/iio/accel/bmc150-accel.h                   | 21 +++++
>  5 files changed, 144 insertions(+), 83 deletions(-)
>  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
>  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
>  create mode 100644 drivers/iio/accel/bmc150-accel.h
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 01dd03d194d1..6da4eb0db57b 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -19,21 +19,22 @@ config BMA180
>  
>  config BMC150_ACCEL
>  	tristate "Bosch BMC150 Accelerometer Driver"
> -	depends on I2C
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
>  	select REGMAP
> -	select REGMAP_I2C
> +	select BMC150_ACCEL_I2C if I2C
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
>  
> -	  Currently this only supports the device via an i2c interface.
> -
Well technically this is true until the next patch ;)  I'll let that one go
though....
>  	  This is a combo module with both accelerometer and magnetometer.
>  	  This driver is only implementing accelerometer part, which has
>  	  its own address and register map.
>  
> +config BMC150_ACCEL_I2C
> +	tristate
> +	select REGMAP_I2C
> +
>  config HID_SENSOR_ACCEL_3D
>  	depends on HID_SENSOR_HUB
>  	select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index ebd2675b2a02..5ef8bdbad092 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -4,7 +4,8 @@
>  
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_BMA180) += bma180.o
> -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
>  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
>  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
>  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
> similarity index 95%
> rename from drivers/iio/accel/bmc150-accel.c
> rename to drivers/iio/accel/bmc150-accel-core.c
> index e4a0691d9b88..614cf61f0110 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel-core.c
> @@ -37,6 +37,8 @@
>  #include <linux/iio/triggered_buffer.h>
>  #include <linux/regmap.h>
>  
> +#include "bmc150-accel.h"
> +
>  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
>  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
>  #define BMC150_ACCEL_GPIO_NAME			"bmc150_accel_int"
> @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
>  struct bmc150_accel_data {
>  	struct regmap *regmap;
>  	struct device *dev;
> -	int irq;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -201,6 +202,7 @@ struct bmc150_accel_data {
>  	int ev_enable_state;
>  	int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
>  	const struct bmc150_accel_chip_info *chip_info;
> +	int irq;
Why move the location of this element of the structure?

>  };
>  
>  static const struct {
> @@ -1070,15 +1072,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
>  static const struct iio_chan_spec bma280_accel_channels[] =
>  	BMC150_ACCEL_CHANNELS(14);
>  
> -enum {
> -	bmc150,
> -	bmi055,
> -	bma255,
> -	bma250e,
> -	bma222e,
> -	bma280,
> -};
> -
>  static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
>  	[bmc150] = {
>  		.chip_id = 0xFA,
> @@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
>  	.postdisable = bmc150_accel_buffer_postdisable,
>  };
>  
> -static int bmc150_accel_probe(struct i2c_client *client,
> -			      const struct i2c_device_id *id)
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> +			    const char *name, int chip_id, bool block_supported)
>  {
>  	struct bmc150_accel_data *data;
>  	struct iio_dev *indio_dev;
>  	int ret;
> -	const char *name = NULL;
> -	int chip_id = 0;
> -	struct device *dev;
>  
> -	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
>  	if (!indio_dev)
>  		return -ENOMEM;
>  
>  	data = iio_priv(indio_dev);
> -	i2c_set_clientdata(client, indio_dev);
> -	data->dev = &client->dev;
> -	dev = &client->dev;
> -	data->irq = client->irq;
> -
> -	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> -	if (IS_ERR(data->regmap)) {
> -		dev_err(dev, "Failed to initialize i2c regmap\n");
> -		return PTR_ERR(data->regmap);
> -	}
> -
> -	if (id) {
> -		name = id->name;
> -		chip_id = id->driver_data;
> -	}
> +	dev_set_drvdata(dev, indio_dev);
> +	data->dev = dev;
> +	data->irq = irq;
> +	data->regmap = regmap;
>  
>  	if (ACPI_HANDLE(dev))
>  		name = bmc150_accel_match_acpi_device(dev, &chip_id);
> @@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		if (ret)
>  			goto err_buffer_cleanup;
>  
> -		if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> -		    i2c_check_functionality(client->adapter,
> -					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> +		if (block_supported) {
>  			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
>  			indio_dev->info = &bmc150_accel_info_fifo;
>  			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
> @@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  
>  	ret = iio_device_register(indio_dev);
>  	if (ret < 0) {
> -		dev_err(data->dev, "Unable to register iio device\n");
> +		dev_err(dev, "Unable to register iio device\n");
>  		goto err_trigger_unregister;
>  	}
>  
> @@ -1692,10 +1669,11 @@ err_buffer_cleanup:
>  
>  	return ret;
>  }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
>  
> -static int bmc150_accel_remove(struct i2c_client *client)
> +int bmc150_accel_core_remove(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  
>  	pm_runtime_disable(data->dev);
> @@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
>  
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
>  
>  #ifdef CONFIG_PM_SLEEP
>  static int bmc150_accel_suspend(struct device *dev)
> @@ -1784,48 +1763,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
>  }
>  #endif
>  
> -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> +const struct dev_pm_ops bmc150_accel_pm_ops = {
>  	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
>  	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
>  			   bmc150_accel_runtime_resume, NULL)
>  };
> -
> -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> -	{"BSBA0150",	bmc150},
> -	{"BMC150A",	bmc150},
> -	{"BMI055A",	bmi055},
> -	{"BMA0255",	bma255},
> -	{"BMA250E",	bma250e},
> -	{"BMA222E",	bma222e},
> -	{"BMA0280",	bma280},
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> -
> -static const struct i2c_device_id bmc150_accel_id[] = {
> -	{"bmc150_accel",	bmc150},
> -	{"bmi055_accel",	bmi055},
> -	{"bma255",		bma255},
> -	{"bma250e",		bma250e},
> -	{"bma222e",		bma222e},
> -	{"bma280",		bma280},
> -	{}
> -};
> -
> -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> -
> -static struct i2c_driver bmc150_accel_driver = {
> -	.driver = {
> -		.name	= BMC150_ACCEL_DRV_NAME,
> -		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> -		.pm	= &bmc150_accel_pm_ops,
> -	},
> -	.probe		= bmc150_accel_probe,
> -	.remove		= bmc150_accel_remove,
> -	.id_table	= bmc150_accel_id,
> -};
> -module_i2c_driver(bmc150_accel_driver);
> -
> -MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("BMC150 accelerometer driver");
Note we have a core module now so it wants this stuff to still be there.

> diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
> new file mode 100644
> index 000000000000..e4dd596ba8f2
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> @@ -0,0 +1,99 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + *  - BMC150
> + *  - BMI055
> + *  - BMA255
> + *  - BMA250E
> + *  - BMA222E
> + *  - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +};
> +
> +static int bmc150_accel_probe(struct i2c_client *client,
> +			      const struct i2c_device_id *id)
> +{
> +	struct regmap *regmap;
> +	bool block_supported =
> +		i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> +		i2c_check_functionality(client->adapter,
> +					I2C_FUNC_SMBUS_READ_I2C_BLOCK);
> +
> +	regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
> +				       id->name, id->driver_data,
> +				       block_supported);
> +}
> +
> +static int bmc150_accel_remove(struct i2c_client *client)
> +{
> +	return bmc150_accel_core_remove(&client->dev);
> +}
> +
> +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> +	{"BSBA0150",	bmc150},
> +	{"BMC150A",	bmc150},
> +	{"BMI055A",	bmi055},
> +	{"BMA0255",	bma255},
> +	{"BMA250E",	bma250e},
> +	{"BMA222E",	bma222e},
> +	{"BMA0280",	bma280},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> +
> +static const struct i2c_device_id bmc150_accel_id[] = {
> +	{"bmc150_accel",	bmc150},
> +	{"bmi055_accel",	bmi055},
> +	{"bma255",		bma255},
> +	{"bma250e",		bma250e},
> +	{"bma222e",		bma222e},
> +	{"bma280",		bma280},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> +
> +static struct i2c_driver bmc150_accel_driver = {
> +	.driver = {
> +		.name	= "bmc150_accel_i2c",
> +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> +		.pm	= &bmc150_accel_pm_ops,
> +	},
> +	.probe		= bmc150_accel_probe,
> +	.remove		= bmc150_accel_remove,
> +	.id_table	= bmc150_accel_id,
> +};
> +module_i2c_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
> new file mode 100644
> index 000000000000..988b57573d0c
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel.h
> @@ -0,0 +1,21 @@
> +#ifndef _BMC150_ACCEL_H_
> +#define _BMC150_ACCEL_H_
> +
> +struct regmap;
> +
> +enum {
> +	bmc150,
> +	bmi055,
> +	bma255,
> +	bma250e,
> +	bma222e,
> +	bma280,
> +};
> +
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> +			    const char *name, int chip_id,
> +			    bool block_supported);
> +int bmc150_accel_core_remove(struct device *dev);
> +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> +
> +#endif  /* _BMC150_ACCEL_H_ */
> 


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

* Re: [PATCH v2 4/4] iio: bmc150: Add SPI driver
  2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
@ 2015-08-31 16:18   ` Jonathan Cameron
  2015-09-01 14:10     ` Srinivas Pandruvada
  0 siblings, 1 reply; 21+ messages in thread
From: Jonathan Cameron @ 2015-08-31 16:18 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Srinivas Pandruvada, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel

On 20/08/15 13:49, Markus Pargmann wrote:
> Add a simple SPI driver which initializes the spi regmap for the bmc150
> core driver.
> 
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Looks good to me, but clearly will have to wait for the earlier
patches in the series.

Nearly there!

Jonathan
> ---
>  drivers/iio/accel/Kconfig            |  5 +++
>  drivers/iio/accel/Makefile           |  1 +
>  drivers/iio/accel/bmc150-accel-spi.c | 83 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 89 insertions(+)
>  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 6da4eb0db57b..56d24fa3d34a 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -23,6 +23,7 @@ config BMC150_ACCEL
>  	select IIO_TRIGGERED_BUFFER
>  	select REGMAP
>  	select BMC150_ACCEL_I2C if I2C
> +	select BMC150_ACCEL_SPI if SPI
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> @@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
>  	tristate
>  	select REGMAP_I2C
>  
> +config BMC150_ACCEL_SPI
> +	tristate
> +	select REGMAP_SPI
> +
>  config HID_SENSOR_ACCEL_3D
>  	depends on HID_SENSOR_HUB
>  	select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index 5ef8bdbad092..e579e93bf022 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -6,6 +6,7 @@
>  obj-$(CONFIG_BMA180) += bma180.o
>  obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
>  obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
>  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
>  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
>  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel-spi.c b/drivers/iio/accel/bmc150-accel-spi.c
> new file mode 100644
> index 000000000000..1c2a4f683da4
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-spi.c
> @@ -0,0 +1,83 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + *  - BMC150
> + *  - BMI055
> + *  - BMA255
> + *  - BMA250E
> + *  - BMA222E
> + *  - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +#include <linux/spi/spi.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_spi_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +	.max_register = 0x3f,
> +};
> +
> +static int bmc150_accel_probe(struct spi_device *spi)
> +{
> +	struct regmap *regmap;
> +	const struct spi_device_id *id = spi_get_device_id(spi);
> +
> +	regmap = devm_regmap_init_spi(spi, &bmc150_spi_regmap_conf);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&spi->dev, "Failed to initialize spi regmap\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmc150_accel_core_probe(&spi->dev, regmap, spi->irq,
> +				       id->name, id->driver_data, true);
> +}
> +
> +static int bmc150_accel_remove(struct spi_device *spi)
> +{
> +	return bmc150_accel_core_remove(&spi->dev);
> +}
> +
> +static const struct spi_device_id bmc150_accel_id[] = {
> +	{"bmc150_accel",	bmc150},
> +	{"bmi055_accel",	bmi055},
> +	{"bma255",		bma255},
> +	{"bma250e",		bma250e},
> +	{"bma222e",		bma222e},
> +	{"bma280",		bma280},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> +
> +static struct spi_driver bmc150_accel_driver = {
> +	.driver = {
> +		.name	= "bmc150_accel_spi",
> +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> +		.pm	= &bmc150_accel_pm_ops,
> +	},
> +	.probe		= bmc150_accel_probe,
> +	.remove		= bmc150_accel_remove,
> +	.id_table	= bmc150_accel_id,
> +};
> +module_spi_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> 


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

* Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
  2015-08-31 16:11   ` Jonathan Cameron
@ 2015-08-31 19:38     ` Srinivas Pandruvada
  2015-09-08  1:09       ` Tirdea, Irina
  2015-09-01 13:57     ` Srinivas Pandruvada
  1 sibling, 1 reply; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-08-31 19:38 UTC (permalink / raw)
  To: Jonathan Cameron, Markus Pargmann, Irina Tirdea
  Cc: Lars-Peter Clausen, linux-iio, linux-kernel, kernel

Hi Irina,

Is it possible for you to test this patchset? I don't have platform to
test with me now (working remotely for couple of weeks).

Thanks,
Srinivas

On Mon, 2015-08-31 at 17:11 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > This replaces all usage of direct i2c accesses with regmap 
> > accesses.
> > 
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Looks fine to me,  but I will be wanting an Ack / reviewed-by
> and preferably a tested by from Srinivas.
> 
> Thanks,
> 
> Jonathan
> > ---
> >  drivers/iio/accel/Kconfig        |   2 +
> >  drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------
> > ------------
> >  2 files changed, 95 insertions(+), 126 deletions(-)
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 00e7bcbdbe24..01dd03d194d1 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -22,6 +22,8 @@ config BMC150_ACCEL
> >  	depends on I2C
> >  	select IIO_BUFFER
> >  	select IIO_TRIGGERED_BUFFER
> > +	select REGMAP
> > +	select REGMAP_I2C
> >  	help
> >  	  Say yes here to build support for the following Bosch 
> > accelerometers:
> >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > diff --git a/drivers/iio/accel/bmc150-accel.c 
> > b/drivers/iio/accel/bmc150-accel.c
> > index 55751d9e1ade..c5c773e75173 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/iio/trigger.h>
> >  #include <linux/iio/trigger_consumer.h>
> >  #include <linux/iio/triggered_buffer.h>
> > +#include <linux/regmap.h>
> >  
> >  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel
> > "
> >  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel
> > _event"
> > @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
> >  
> >  struct bmc150_accel_data {
> >  	struct i2c_client *client;
> > +	struct regmap *regmap;
> > +	struct device *dev;
> >  	struct bmc150_accel_interrupt 
> > interrupts[BMC150_ACCEL_INTERRUPTS];
> >  	atomic_t active_intr;
> >  	struct bmc150_accel_trigger 
> > triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -241,6 +244,11 @@ static const struct {
> >  				       {500000, 
> > BMC150_ACCEL_SLEEP_500_MS},
> >  				       {1000000, 
> > BMC150_ACCEL_SLEEP_1_SEC} };
> >  
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.max_register = 0x3f,
> > +};
> >  
> >  static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> >  				 enum bmc150_power_modes mode,
> > @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct 
> > bmc150_accel_data *data,
> >  
> >  	dev_dbg(&data->client->dev, "Set Mode bits %x\n", 
> > lpw_bits);
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_PMU_LPW, 
> > lpw_bits);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, 
> > lpw_bits);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing 
> > reg_pmu_lpw\n");
> >  		return ret;
> > @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct 
> > bmc150_accel_data *data, int val,
> >  	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); 
> > ++i) {
> >  		if (bmc150_accel_samp_freq_table[i].val == val &&
> >  				bmc150_accel_samp_freq_table[i].va
> > l2 == val2) {
> > -			ret = i2c_smbus_write_byte_data(
> > -				data->client,
> > +			ret = regmap_write(data->regmap,
> >  				BMC150_ACCEL_REG_PMU_BW,
> >  				bmc150_accel_samp_freq_table[i].bw
> > _bits);
> >  			if (ret < 0)
> > @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct 
> > bmc150_accel_data *data, int val,
> >  
> >  static int bmc150_accel_update_slope(struct bmc150_accel_data 
> > *data)
> >  {
> > -	int ret, val;
> > +	int ret;
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client, 
> > BMC150_ACCEL_REG_INT_6,
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> >  					data->slope_thres);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing 
> > reg_int_6\n");
> >  		return ret;
> >  	}
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, 
> > BMC150_ACCEL_REG_INT_5);
> > +	ret = regmap_update_bits(data->regmap, 
> > BMC150_ACCEL_REG_INT_5,
> > +				 BMC150_ACCEL_SLOPE_DUR_MASK, data
> > ->slope_dur);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading 
> > reg_int_5\n");
> > -		return ret;
> > -	}
> > -
> > -	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data
> > ->slope_dur;
> > -	ret = i2c_smbus_write_byte_data(data->client, 
> > BMC150_ACCEL_REG_INT_5,
> > -					val);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error write 
> > reg_int_5\n");
> > +		dev_err(&data->client->dev, "Error updating 
> > reg_int_5\n");
> >  		return ret;
> >  	}
> >  
> > @@ -348,17 +347,18 @@ static int 
> > bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
> >  static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  {
> >  	int ret;
> > +	unsigned int val;
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, 
> > BMC150_ACCEL_REG_CHIP_ID);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, 
> > &val);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  			"Error: Reading chip id\n");
> >  		return ret;
> >  	}
> >  
> > -	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> > -	if (ret != data->chip_info->chip_id) {
> > -		dev_err(&data->client->dev, "Invalid chip %x\n", 
> > ret);
> > +	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> > +	if (val != data->chip_info->chip_id) {
> > +		dev_err(&data->client->dev, "Invalid chip %x\n", 
> > val);
> >  		return -ENODEV;
> >  	}
> >  
> > @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct 
> > bmc150_accel_data *data)
> >  		return ret;
> >  
> >  	/* Set Default Range */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_PMU_RANGE
> > ,
> > -					BMC150_ACCEL_DEF_RANGE_4G)
> > ;
> > +	ret = regmap_write(data->regmap, 
> > BMC150_ACCEL_REG_PMU_RANGE,
> > +			   BMC150_ACCEL_DEF_RANGE_4G);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  					"Error writing 
> > reg_pmu_range\n");
> > @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct 
> > bmc150_accel_data *data)
> >  		return ret;
> >  
> >  	/* Set default as latched interrupts */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > -					BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > -					BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > +	ret = regmap_write(data->regmap, 
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> > +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  			"Error writing reg_int_rst_latch\n");
> > @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct 
> > bmc150_accel_data *data, int i,
> >  		return ret;
> >  
> >  	/* map the interrupt to the appropriate pins */
> > -	ret = i2c_smbus_read_byte_data(data->client, info
> > ->map_reg);
> > +	ret = regmap_update_bits(data->regmap, info->map_reg, info
> > ->map_bitmask,
> > +				 (state ? info->map_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading 
> > reg_int_map\n");
> > -		goto out_fix_power_state;
> > -	}
> > -	if (state)
> > -		ret |= info->map_bitmask;
> > -	else
> > -		ret &= ~info->map_bitmask;
> > -
> > -	ret = i2c_smbus_write_byte_data(data->client, info
> > ->map_reg,
> > -					ret);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing 
> > reg_int_map\n");
> > +		dev_err(&data->client->dev, "Error updating 
> > reg_int_map\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> >  	/* enable/disable the interrupt */
> > -	ret = i2c_smbus_read_byte_data(data->client, info
> > ->en_reg);
> > +	ret = regmap_update_bits(data->regmap, info->en_reg, info
> > ->en_bitmask,
> > +				 (state ? info->en_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading 
> > reg_int_en\n");
> > -		goto out_fix_power_state;
> > -	}
> > -
> > -	if (state)
> > -		ret |= info->en_bitmask;
> > -	else
> > -		ret &= ~info->en_bitmask;
> > -
> > -	ret = i2c_smbus_write_byte_data(data->client, info
> > ->en_reg, ret);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing 
> > reg_int_en\n");
> > +		dev_err(&data->client->dev, "Error updating 
> > reg_int_en\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> > @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct 
> > bmc150_accel_data *data, int val)
> >  
> >  	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); 
> > ++i) {
> >  		if (data->chip_info->scale_table[i].scale == val) 
> > {
> > -			ret = i2c_smbus_write_byte_data(
> > -				     data->client,
> > +			ret = regmap_write(data->regmap,
> >  				     BMC150_ACCEL_REG_PMU_RANGE,
> >  				     data->chip_info
> > ->scale_table[i].reg_range);
> >  			if (ret < 0) {
> > @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct 
> > bmc150_accel_data *data, int val)
> >  static int bmc150_accel_get_temp(struct bmc150_accel_data *data, 
> > int *val)
> >  {
> >  	int ret;
> > +	unsigned int value;
> >  
> >  	mutex_lock(&data->mutex);
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, 
> > BMC150_ACCEL_REG_TEMP);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, 
> > &value);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading 
> > reg_temp\n");
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > -	*val = sign_extend32(ret, 7);
> > +	*val = sign_extend32(value, 7);
> >  
> >  	mutex_unlock(&data->mutex);
> >  
> > @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct 
> > bmc150_accel_data *data,
> >  {
> >  	int ret;
> >  	int axis = chan->scan_index;
> > +	unsigned int raw_val;
> >  
> >  	mutex_lock(&data->mutex);
> >  	ret = bmc150_accel_set_power_state(data, true);
> > @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct 
> > bmc150_accel_data *data,
> >  		return ret;
> >  	}
> >  
> > -	ret = i2c_smbus_read_word_data(data->client,
> > -				      
> >  BMC150_ACCEL_AXIS_TO_REG(axis));
> > +	ret = regmap_bulk_read(data->regmap, 
> > BMC150_ACCEL_AXIS_TO_REG(axis),
> > +			       &raw_val, 2);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading axis 
> > %d\n", axis);
> >  		bmc150_accel_set_power_state(data, false);
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > -	*val = sign_extend32(ret >> chan->scan_type.shift,
> > +	*val = sign_extend32(raw_val >> chan->scan_type.shift,
> >  			     chan->scan_type.realbits - 1);
> >  	ret = bmc150_accel_set_power_state(data, false);
> >  	mutex_unlock(&data->mutex);
> > @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct 
> > iio_dev *indio_dev, unsigned val)
> >   * We must read at least one full frame in one burst, otherwise 
> > the rest of the
> >   * frame data is discarded.
> >   */
> > -static int bmc150_accel_fifo_transfer(const struct i2c_client 
> > *client,
> > +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data 
> > *data,
> >  				      char *buffer, int samples)
> >  {
> >  	int sample_length = 3 * 2;
> > -	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> > -	int ret = -EIO;
> > -
> > -	if (i2c_check_functionality(client->adapter, 
> > I2C_FUNC_I2C)) {
> > -		struct i2c_msg msg[2] = {
> > -			{
> > -				.addr = client->addr,
> > -				.flags = 0,
> > -				.buf = &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] 21+ messages in thread

* Re: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
  2015-08-31 16:11   ` Jonathan Cameron
  2015-08-31 19:38     ` Srinivas Pandruvada
@ 2015-09-01 13:57     ` Srinivas Pandruvada
  1 sibling, 0 replies; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-09-01 13:57 UTC (permalink / raw)
  To: Jonathan Cameron, Markus Pargmann
  Cc: Irina Tirdea, Lars-Peter Clausen, linux-iio, linux-kernel, kernel

On Mon, 2015-08-31 at 17:11 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > This replaces all usage of direct i2c accesses with regmap 
> > accesses.
> > 
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Looks fine to me,  but I will be wanting an Ack / reviewed-by
> and preferably a tested by from Srinivas.
Reviewed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

I requested Irina, if she can test this patch.

Thanks,
Srinivas
> 
> Thanks,
> 
> Jonathan
> > ---
> >  drivers/iio/accel/Kconfig        |   2 +
> >  drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------
> > ------------
> >  2 files changed, 95 insertions(+), 126 deletions(-)
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 00e7bcbdbe24..01dd03d194d1 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -22,6 +22,8 @@ config BMC150_ACCEL
> >  	depends on I2C
> >  	select IIO_BUFFER
> >  	select IIO_TRIGGERED_BUFFER
> > +	select REGMAP
> > +	select REGMAP_I2C
> >  	help
> >  	  Say yes here to build support for the following Bosch 
> > accelerometers:
> >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > diff --git a/drivers/iio/accel/bmc150-accel.c 
> > b/drivers/iio/accel/bmc150-accel.c
> > index 55751d9e1ade..c5c773e75173 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/iio/trigger.h>
> >  #include <linux/iio/trigger_consumer.h>
> >  #include <linux/iio/triggered_buffer.h>
> > +#include <linux/regmap.h>
> >  
> >  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel
> > "
> >  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel
> > _event"
> > @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
> >  
> >  struct bmc150_accel_data {
> >  	struct i2c_client *client;
> > +	struct regmap *regmap;
> > +	struct device *dev;
> >  	struct bmc150_accel_interrupt 
> > interrupts[BMC150_ACCEL_INTERRUPTS];
> >  	atomic_t active_intr;
> >  	struct bmc150_accel_trigger 
> > triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -241,6 +244,11 @@ static const struct {
> >  				       {500000, 
> > BMC150_ACCEL_SLEEP_500_MS},
> >  				       {1000000, 
> > BMC150_ACCEL_SLEEP_1_SEC} };
> >  
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.max_register = 0x3f,
> > +};
> >  
> >  static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
> >  				 enum bmc150_power_modes mode,
> > @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct 
> > bmc150_accel_data *data,
> >  
> >  	dev_dbg(&data->client->dev, "Set Mode bits %x\n", 
> > lpw_bits);
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_PMU_LPW, 
> > lpw_bits);
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, 
> > lpw_bits);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing 
> > reg_pmu_lpw\n");
> >  		return ret;
> > @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct 
> > bmc150_accel_data *data, int val,
> >  	for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); 
> > ++i) {
> >  		if (bmc150_accel_samp_freq_table[i].val == val &&
> >  				bmc150_accel_samp_freq_table[i].va
> > l2 == val2) {
> > -			ret = i2c_smbus_write_byte_data(
> > -				data->client,
> > +			ret = regmap_write(data->regmap,
> >  				BMC150_ACCEL_REG_PMU_BW,
> >  				bmc150_accel_samp_freq_table[i].bw
> > _bits);
> >  			if (ret < 0)
> > @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct 
> > bmc150_accel_data *data, int val,
> >  
> >  static int bmc150_accel_update_slope(struct bmc150_accel_data 
> > *data)
> >  {
> > -	int ret, val;
> > +	int ret;
> >  
> > -	ret = i2c_smbus_write_byte_data(data->client, 
> > BMC150_ACCEL_REG_INT_6,
> > +	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
> >  					data->slope_thres);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error writing 
> > reg_int_6\n");
> >  		return ret;
> >  	}
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, 
> > BMC150_ACCEL_REG_INT_5);
> > +	ret = regmap_update_bits(data->regmap, 
> > BMC150_ACCEL_REG_INT_5,
> > +				 BMC150_ACCEL_SLOPE_DUR_MASK, data
> > ->slope_dur);
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading 
> > reg_int_5\n");
> > -		return ret;
> > -	}
> > -
> > -	val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data
> > ->slope_dur;
> > -	ret = i2c_smbus_write_byte_data(data->client, 
> > BMC150_ACCEL_REG_INT_5,
> > -					val);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error write 
> > reg_int_5\n");
> > +		dev_err(&data->client->dev, "Error updating 
> > reg_int_5\n");
> >  		return ret;
> >  	}
> >  
> > @@ -348,17 +347,18 @@ static int 
> > bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t,
> >  static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> >  {
> >  	int ret;
> > +	unsigned int val;
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, 
> > BMC150_ACCEL_REG_CHIP_ID);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, 
> > &val);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  			"Error: Reading chip id\n");
> >  		return ret;
> >  	}
> >  
> > -	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> > -	if (ret != data->chip_info->chip_id) {
> > -		dev_err(&data->client->dev, "Invalid chip %x\n", 
> > ret);
> > +	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> > +	if (val != data->chip_info->chip_id) {
> > +		dev_err(&data->client->dev, "Invalid chip %x\n", 
> > val);
> >  		return -ENODEV;
> >  	}
> >  
> > @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct 
> > bmc150_accel_data *data)
> >  		return ret;
> >  
> >  	/* Set Default Range */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_PMU_RANGE
> > ,
> > -					BMC150_ACCEL_DEF_RANGE_4G)
> > ;
> > +	ret = regmap_write(data->regmap, 
> > BMC150_ACCEL_REG_PMU_RANGE,
> > +			   BMC150_ACCEL_DEF_RANGE_4G);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  					"Error writing 
> > reg_pmu_range\n");
> > @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct 
> > bmc150_accel_data *data)
> >  		return ret;
> >  
> >  	/* Set default as latched interrupts */
> > -	ret = i2c_smbus_write_byte_data(data->client,
> > -					BMC150_ACCEL_REG_INT_RST_L
> > ATCH,
> > -					BMC150_ACCEL_INT_MODE_LATC
> > H_INT |
> > -					BMC150_ACCEL_INT_MODE_LATC
> > H_RESET);
> > +	ret = regmap_write(data->regmap, 
> > BMC150_ACCEL_REG_INT_RST_LATCH,
> > +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> > +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev,
> >  			"Error writing reg_int_rst_latch\n");
> > @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct 
> > bmc150_accel_data *data, int i,
> >  		return ret;
> >  
> >  	/* map the interrupt to the appropriate pins */
> > -	ret = i2c_smbus_read_byte_data(data->client, info
> > ->map_reg);
> > +	ret = regmap_update_bits(data->regmap, info->map_reg, info
> > ->map_bitmask,
> > +				 (state ? info->map_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading 
> > reg_int_map\n");
> > -		goto out_fix_power_state;
> > -	}
> > -	if (state)
> > -		ret |= info->map_bitmask;
> > -	else
> > -		ret &= ~info->map_bitmask;
> > -
> > -	ret = i2c_smbus_write_byte_data(data->client, info
> > ->map_reg,
> > -					ret);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing 
> > reg_int_map\n");
> > +		dev_err(&data->client->dev, "Error updating 
> > reg_int_map\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> >  	/* enable/disable the interrupt */
> > -	ret = i2c_smbus_read_byte_data(data->client, info
> > ->en_reg);
> > +	ret = regmap_update_bits(data->regmap, info->en_reg, info
> > ->en_bitmask,
> > +				 (state ? info->en_bitmask : 0));
> >  	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error reading 
> > reg_int_en\n");
> > -		goto out_fix_power_state;
> > -	}
> > -
> > -	if (state)
> > -		ret |= info->en_bitmask;
> > -	else
> > -		ret &= ~info->en_bitmask;
> > -
> > -	ret = i2c_smbus_write_byte_data(data->client, info
> > ->en_reg, ret);
> > -	if (ret < 0) {
> > -		dev_err(&data->client->dev, "Error writing 
> > reg_int_en\n");
> > +		dev_err(&data->client->dev, "Error updating 
> > reg_int_en\n");
> >  		goto out_fix_power_state;
> >  	}
> >  
> > @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct 
> > bmc150_accel_data *data, int val)
> >  
> >  	for (i = 0; i < ARRAY_SIZE(data->chip_info->scale_table); 
> > ++i) {
> >  		if (data->chip_info->scale_table[i].scale == val) 
> > {
> > -			ret = i2c_smbus_write_byte_data(
> > -				     data->client,
> > +			ret = regmap_write(data->regmap,
> >  				     BMC150_ACCEL_REG_PMU_RANGE,
> >  				     data->chip_info
> > ->scale_table[i].reg_range);
> >  			if (ret < 0) {
> > @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct 
> > bmc150_accel_data *data, int val)
> >  static int bmc150_accel_get_temp(struct bmc150_accel_data *data, 
> > int *val)
> >  {
> >  	int ret;
> > +	unsigned int value;
> >  
> >  	mutex_lock(&data->mutex);
> >  
> > -	ret = i2c_smbus_read_byte_data(data->client, 
> > BMC150_ACCEL_REG_TEMP);
> > +	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, 
> > &value);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading 
> > reg_temp\n");
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > -	*val = sign_extend32(ret, 7);
> > +	*val = sign_extend32(value, 7);
> >  
> >  	mutex_unlock(&data->mutex);
> >  
> > @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct 
> > bmc150_accel_data *data,
> >  {
> >  	int ret;
> >  	int axis = chan->scan_index;
> > +	unsigned int raw_val;
> >  
> >  	mutex_lock(&data->mutex);
> >  	ret = bmc150_accel_set_power_state(data, true);
> > @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct 
> > bmc150_accel_data *data,
> >  		return ret;
> >  	}
> >  
> > -	ret = i2c_smbus_read_word_data(data->client,
> > -				      
> >  BMC150_ACCEL_AXIS_TO_REG(axis));
> > +	ret = regmap_bulk_read(data->regmap, 
> > BMC150_ACCEL_AXIS_TO_REG(axis),
> > +			       &raw_val, 2);
> >  	if (ret < 0) {
> >  		dev_err(&data->client->dev, "Error reading axis 
> > %d\n", axis);
> >  		bmc150_accel_set_power_state(data, false);
> >  		mutex_unlock(&data->mutex);
> >  		return ret;
> >  	}
> > -	*val = sign_extend32(ret >> chan->scan_type.shift,
> > +	*val = sign_extend32(raw_val >> chan->scan_type.shift,
> >  			     chan->scan_type.realbits - 1);
> >  	ret = bmc150_accel_set_power_state(data, false);
> >  	mutex_unlock(&data->mutex);
> > @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct 
> > iio_dev *indio_dev, unsigned val)
> >   * We must read at least one full frame in one burst, otherwise 
> > the rest of the
> >   * frame data is discarded.
> >   */
> > -static int bmc150_accel_fifo_transfer(const struct i2c_client 
> > *client,
> > +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data 
> > *data,
> >  				      char *buffer, int samples)
> >  {
> >  	int sample_length = 3 * 2;
> > -	u8 reg_fifo_data = BMC150_ACCEL_REG_FIFO_DATA;
> > -	int ret = -EIO;
> > -
> > -	if (i2c_check_functionality(client->adapter, 
> > I2C_FUNC_I2C)) {
> > -		struct i2c_msg msg[2] = {
> > -			{
> > -				.addr = client->addr,
> > -				.flags = 0,
> > -				.buf = &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] 21+ messages in thread

* Re: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
  2015-08-31 16:15   ` Jonathan Cameron
@ 2015-09-01 14:07     ` Srinivas Pandruvada
  0 siblings, 0 replies; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-09-01 14:07 UTC (permalink / raw)
  To: Jonathan Cameron, Markus Pargmann
  Cc: Irina Tirdea, Lars-Peter Clausen, linux-iio, linux-kernel, kernel

On Mon, 2015-08-31 at 17:15 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> A couple of little bits inline.  Again would like Srinivas to
> take a quick look at this patch as well.
Once your comments are addressed, it looks fine to me.

Thanks,
Srinivas
> 
> Jonathan
> > ---
> >  drivers/iio/accel/Kconfig                          |  9 +-
> >  drivers/iio/accel/Makefile                         |  3 +-
> >  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 95 ++++------
> > -----------
> >  drivers/iio/accel/bmc150-accel-i2c.c               | 99 
> > ++++++++++++++++++++++
> >  drivers/iio/accel/bmc150-accel.h                   | 21 +++++
> >  5 files changed, 144 insertions(+), 83 deletions(-)
> >  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} 
> > (95%)
> >  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> >  create mode 100644 drivers/iio/accel/bmc150-accel.h
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 01dd03d194d1..6da4eb0db57b 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -19,21 +19,22 @@ config BMA180
> >  
> >  config BMC150_ACCEL
> >  	tristate "Bosch BMC150 Accelerometer Driver"
> > -	depends on I2C
> >  	select IIO_BUFFER
> >  	select IIO_TRIGGERED_BUFFER
> >  	select REGMAP
> > -	select REGMAP_I2C
> > +	select BMC150_ACCEL_I2C if I2C
> >  	help
> >  	  Say yes here to build support for the following Bosch 
> > accelerometers:
> >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> >  
> > -	  Currently this only supports the device via an i2c 
> > interface.
> > -
> Well technically this is true until the next patch ;)  I'll let that 
> one go
> though....
> >  	  This is a combo module with both accelerometer and 
> > magnetometer.
> >  	  This driver is only implementing accelerometer part, 
> > which has
> >  	  its own address and register map.
> >  
> > +config BMC150_ACCEL_I2C
> > +	tristate
> > +	select REGMAP_I2C
> > +
> >  config HID_SENSOR_ACCEL_3D
> >  	depends on HID_SENSOR_HUB
> >  	select IIO_BUFFER
> > diff --git a/drivers/iio/accel/Makefile 
> > b/drivers/iio/accel/Makefile
> > index ebd2675b2a02..5ef8bdbad092 100644
> > --- a/drivers/iio/accel/Makefile
> > +++ b/drivers/iio/accel/Makefile
> > @@ -4,7 +4,8 @@
> >  
> >  # When adding new entries keep the list in alphabetical order
> >  obj-$(CONFIG_BMA180) += bma180.o
> > -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> > +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> > +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> >  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> >  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> >  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> > diff --git a/drivers/iio/accel/bmc150-accel.c 
> > b/drivers/iio/accel/bmc150-accel-core.c
> > similarity index 95%
> > rename from drivers/iio/accel/bmc150-accel.c
> > rename to drivers/iio/accel/bmc150-accel-core.c
> > index e4a0691d9b88..614cf61f0110 100644
> > --- a/drivers/iio/accel/bmc150-accel.c
> > +++ b/drivers/iio/accel/bmc150-accel-core.c
> > @@ -37,6 +37,8 @@
> >  #include <linux/iio/triggered_buffer.h>
> >  #include <linux/regmap.h>
> >  
> > +#include "bmc150-accel.h"
> > +
> >  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel
> > "
> >  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel
> > _event"
> >  #define BMC150_ACCEL_GPIO_NAME			"bmc150_acce
> > l_int"
> > @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
> >  struct bmc150_accel_data {
> >  	struct regmap *regmap;
> >  	struct device *dev;
> > -	int irq;
> >  	struct bmc150_accel_interrupt 
> > interrupts[BMC150_ACCEL_INTERRUPTS];
> >  	atomic_t active_intr;
> >  	struct bmc150_accel_trigger 
> > triggers[BMC150_ACCEL_TRIGGERS];
> > @@ -201,6 +202,7 @@ struct bmc150_accel_data {
> >  	int ev_enable_state;
> >  	int64_t timestamp, old_timestamp; /* Only used in hw fifo 
> > mode. */
> >  	const struct bmc150_accel_chip_info *chip_info;
> > +	int irq;
> Why move the location of this element of the structure?
> 
> >  };
> >  
> >  static const struct {
> > @@ -1070,15 +1072,6 @@ static const struct iio_chan_spec 
> > bmc150_accel_channels[] =
> >  static const struct iio_chan_spec bma280_accel_channels[] =
> >  	BMC150_ACCEL_CHANNELS(14);
> >  
> > -enum {
> > -	bmc150,
> > -	bmi055,
> > -	bma255,
> > -	bma250e,
> > -	bma222e,
> > -	bma280,
> > -};
> > -
> >  static const struct bmc150_accel_chip_info 
> > bmc150_accel_chip_info_tbl[] = {
> >  	[bmc150] = {
> >  		.chip_id = 0xFA,
> > @@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops 
> > bmc150_accel_buffer_ops = {
> >  	.postdisable = bmc150_accel_buffer_postdisable,
> >  };
> >  
> > -static int bmc150_accel_probe(struct i2c_client *client,
> > -			      const struct i2c_device_id *id)
> > +int bmc150_accel_core_probe(struct device *dev, struct regmap 
> > *regmap, int irq,
> > +			    const char *name, int chip_id, bool 
> > block_supported)
> >  {
> >  	struct bmc150_accel_data *data;
> >  	struct iio_dev *indio_dev;
> >  	int ret;
> > -	const char *name = NULL;
> > -	int chip_id = 0;
> > -	struct device *dev;
> >  
> > -	indio_dev = devm_iio_device_alloc(&client->dev, 
> > sizeof(*data));
> > +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
> >  	if (!indio_dev)
> >  		return -ENOMEM;
> >  
> >  	data = iio_priv(indio_dev);
> > -	i2c_set_clientdata(client, indio_dev);
> > -	data->dev = &client->dev;
> > -	dev = &client->dev;
> > -	data->irq = client->irq;
> > -
> > -	data->regmap = devm_regmap_init_i2c(client, 
> > &bmc150_i2c_regmap_conf);
> > -	if (IS_ERR(data->regmap)) {
> > -		dev_err(dev, "Failed to initialize i2c regmap\n");
> > -		return PTR_ERR(data->regmap);
> > -	}
> > -
> > -	if (id) {
> > -		name = id->name;
> > -		chip_id = id->driver_data;
> > -	}
> > +	dev_set_drvdata(dev, indio_dev);
> > +	data->dev = dev;
> > +	data->irq = irq;
> > +	data->regmap = regmap;
> >  
> >  	if (ACPI_HANDLE(dev))
> >  		name = bmc150_accel_match_acpi_device(dev, 
> > &chip_id);
> > @@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct 
> > i2c_client *client,
> >  		if (ret)
> >  			goto err_buffer_cleanup;
> >  
> > -		if (i2c_check_functionality(client->adapter, 
> > I2C_FUNC_I2C) ||
> > -		    i2c_check_functionality(client->adapter,
> > -					   
> >  I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> > +		if (block_supported) {
> >  			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> >  			indio_dev->info = &bmc150_accel_info_fifo;
> >  			indio_dev->buffer->attrs = 
> > bmc150_accel_fifo_attributes;
> > @@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct 
> > i2c_client *client,
> >  
> >  	ret = iio_device_register(indio_dev);
> >  	if (ret < 0) {
> > -		dev_err(data->dev, "Unable to register iio 
> > device\n");
> > +		dev_err(dev, "Unable to register iio device\n");
> >  		goto err_trigger_unregister;
> >  	}
> >  
> > @@ -1692,10 +1669,11 @@ err_buffer_cleanup:
> >  
> >  	return ret;
> >  }
> > +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
> >  
> > -static int bmc150_accel_remove(struct i2c_client *client)
> > +int bmc150_accel_core_remove(struct device *dev)
> >  {
> > -	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> > +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> >  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> >  
> >  	pm_runtime_disable(data->dev);
> > @@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct 
> > i2c_client *client)
> >  
> >  	return 0;
> >  }
> > +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
> >  
> >  #ifdef CONFIG_PM_SLEEP
> >  static int bmc150_accel_suspend(struct device *dev)
> > @@ -1784,48 +1763,8 @@ static int 
> > bmc150_accel_runtime_resume(struct device *dev)
> >  }
> >  #endif
> >  
> > -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> > +const struct dev_pm_ops bmc150_accel_pm_ops = {
> >  	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, 
> > bmc150_accel_resume)
> >  	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
> >  			   bmc150_accel_runtime_resume, NULL)
> >  };
> > -
> > -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> > -	{"BSBA0150",	bmc150},
> > -	{"BMC150A",	bmc150},
> > -	{"BMI055A",	bmi055},
> > -	{"BMA0255",	bma255},
> > -	{"BMA250E",	bma250e},
> > -	{"BMA222E",	bma222e},
> > -	{"BMA0280",	bma280},
> > -	{ },
> > -};
> > -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> > -
> > -static const struct i2c_device_id bmc150_accel_id[] = {
> > -	{"bmc150_accel",	bmc150},
> > -	{"bmi055_accel",	bmi055},
> > -	{"bma255",		bma255},
> > -	{"bma250e",		bma250e},
> > -	{"bma222e",		bma222e},
> > -	{"bma280",		bma280},
> > -	{}
> > -};
> > -
> > -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> > -
> > -static struct i2c_driver bmc150_accel_driver = {
> > -	.driver = {
> > -		.name	= BMC150_ACCEL_DRV_NAME,
> > -		.acpi_match_table = 
> > ACPI_PTR(bmc150_accel_acpi_match),
> > -		.pm	= &bmc150_accel_pm_ops,
> > -	},
> > -	.probe		= bmc150_accel_probe,
> > -	.remove		= bmc150_accel_remove,
> > -	.id_table	= bmc150_accel_id,
> > -};
> > -module_i2c_driver(bmc150_accel_driver);
> > -
> > -MODULE_AUTHOR("Srinivas Pandruvada <
> > srinivas.pandruvada@linux.intel.com>");
> > -MODULE_LICENSE("GPL v2");
> > -MODULE_DESCRIPTION("BMC150 accelerometer driver");
> Note we have a core module now so it wants this stuff to still be 
> there.
> 
> > diff --git a/drivers/iio/accel/bmc150-accel-i2c.c 
> > b/drivers/iio/accel/bmc150-accel-i2c.c
> > new file mode 100644
> > index 000000000000..e4dd596ba8f2
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> > @@ -0,0 +1,99 @@
> > +/*
> > + * 3-axis accelerometer driver supporting following I2C Bosch
> > -Sensortec chips:
> > + *  - BMC150
> > + *  - BMI055
> > + *  - BMA255
> > + *  - BMA250E
> > + *  - BMA222E
> > + *  - BMA280
> > + *
> > + * Copyright (c) 2014, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or 
> > modify it
> > + * under the terms and conditions of the GNU General Public 
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but 
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of 
> > MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public 
> > License for
> > + * more details.
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/regmap.h>
> > +
> > +#include "bmc150-accel.h"
> > +
> > +static const struct regmap_config bmc150_i2c_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +};
> > +
> > +static int bmc150_accel_probe(struct i2c_client *client,
> > +			      const struct i2c_device_id *id)
> > +{
> > +	struct regmap *regmap;
> > +	bool block_supported =
> > +		i2c_check_functionality(client->adapter, 
> > I2C_FUNC_I2C) ||
> > +		i2c_check_functionality(client->adapter,
> > +					I2C_FUNC_SMBUS_READ_I2C_BL
> > OCK);
> > +
> > +	regmap = devm_regmap_init_i2c(client, 
> > &bmc150_i2c_regmap_conf);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(&client->dev, "Failed to initialize i2c 
> > regmap\n");
> > +		return PTR_ERR(regmap);
> > +	}
> > +
> > +	return bmc150_accel_core_probe(&client->dev, regmap, 
> > client->irq,
> > +				       id->name, id->driver_data,
> > +				       block_supported);
> > +}
> > +
> > +static int bmc150_accel_remove(struct i2c_client *client)
> > +{
> > +	return bmc150_accel_core_remove(&client->dev);
> > +}
> > +
> > +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> > +	{"BSBA0150",	bmc150},
> > +	{"BMC150A",	bmc150},
> > +	{"BMI055A",	bmi055},
> > +	{"BMA0255",	bma255},
> > +	{"BMA250E",	bma250e},
> > +	{"BMA222E",	bma222e},
> > +	{"BMA0280",	bma280},
> > +	{ },
> > +};
> > +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> > +
> > +static const struct i2c_device_id bmc150_accel_id[] = {
> > +	{"bmc150_accel",	bmc150},
> > +	{"bmi055_accel",	bmi055},
> > +	{"bma255",		bma255},
> > +	{"bma250e",		bma250e},
> > +	{"bma222e",		bma222e},
> > +	{"bma280",		bma280},
> > +	{}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> > +
> > +static struct i2c_driver bmc150_accel_driver = {
> > +	.driver = {
> > +		.name	= "bmc150_accel_i2c",
> > +		.acpi_match_table = 
> > ACPI_PTR(bmc150_accel_acpi_match),
> > +		.pm	= &bmc150_accel_pm_ops,
> > +	},
> > +	.probe		= bmc150_accel_probe,
> > +	.remove		= bmc150_accel_remove,
> > +	.id_table	= bmc150_accel_id,
> > +};
> > +module_i2c_driver(bmc150_accel_driver);
> > +
> > +MODULE_AUTHOR("Srinivas Pandruvada <
> > srinivas.pandruvada@linux.intel.com>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> > diff --git a/drivers/iio/accel/bmc150-accel.h 
> > b/drivers/iio/accel/bmc150-accel.h
> > new file mode 100644
> > index 000000000000..988b57573d0c
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel.h
> > @@ -0,0 +1,21 @@
> > +#ifndef _BMC150_ACCEL_H_
> > +#define _BMC150_ACCEL_H_
> > +
> > +struct regmap;
> > +
> > +enum {
> > +	bmc150,
> > +	bmi055,
> > +	bma255,
> > +	bma250e,
> > +	bma222e,
> > +	bma280,
> > +};
> > +
> > +int bmc150_accel_core_probe(struct device *dev, struct regmap 
> > *regmap, int irq,
> > +			    const char *name, int chip_id,
> > +			    bool block_supported);
> > +int bmc150_accel_core_remove(struct device *dev);
> > +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> > +
> > +#endif  /* _BMC150_ACCEL_H_ */
> > 
> 

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

* Re: [PATCH v2 4/4] iio: bmc150: Add SPI driver
  2015-08-31 16:18   ` Jonathan Cameron
@ 2015-09-01 14:10     ` Srinivas Pandruvada
  2015-09-16 10:01       ` Markus Pargmann
  0 siblings, 1 reply; 21+ messages in thread
From: Srinivas Pandruvada @ 2015-09-01 14:10 UTC (permalink / raw)
  To: Jonathan Cameron, Markus Pargmann
  Cc: Irina Tirdea, Lars-Peter Clausen, linux-iio, linux-kernel, kernel

On Mon, 2015-08-31 at 17:18 +0100, Jonathan Cameron wrote:
> On 20/08/15 13:49, Markus Pargmann wrote:
> > Add a simple SPI driver which initializes the spi regmap for the 
> > bmc150
> > core driver.
> > 
> > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Looks good to me, but clearly will have to wait for the earlier
> patches in the series.
> 
> Nearly there!
> 
> Jonathan
> > ---
> >  drivers/iio/accel/Kconfig            |  5 +++
> >  drivers/iio/accel/Makefile           |  1 +
> >  drivers/iio/accel/bmc150-accel-spi.c | 83 
> > ++++++++++++++++++++++++++++++++++++
> >  3 files changed, 89 insertions(+)
> >  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> > 
> > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > index 6da4eb0db57b..56d24fa3d34a 100644
> > --- a/drivers/iio/accel/Kconfig
> > +++ b/drivers/iio/accel/Kconfig
> > @@ -23,6 +23,7 @@ config BMC150_ACCEL
> >  	select IIO_TRIGGERED_BUFFER
> >  	select REGMAP
> >  	select BMC150_ACCEL_I2C if I2C
> > +	select BMC150_ACCEL_SPI if SPI
> >  	help
> >  	  Say yes here to build support for the following Bosch 
> > accelerometers:
> >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > @@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
> >  	tristate
> >  	select REGMAP_I2C
> >  
> > +config BMC150_ACCEL_SPI
> > +	tristate
> > +	select REGMAP_SPI
> > +
> >  config HID_SENSOR_ACCEL_3D
> >  	depends on HID_SENSOR_HUB
> >  	select IIO_BUFFER
> > diff --git a/drivers/iio/accel/Makefile 
> > b/drivers/iio/accel/Makefile
> > index 5ef8bdbad092..e579e93bf022 100644
> > --- a/drivers/iio/accel/Makefile
> > +++ b/drivers/iio/accel/Makefile
> > @@ -6,6 +6,7 @@
> >  obj-$(CONFIG_BMA180) += bma180.o
> >  obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> >  obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> > +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> >  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> >  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> >  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> > diff --git a/drivers/iio/accel/bmc150-accel-spi.c 
> > b/drivers/iio/accel/bmc150-accel-spi.c
> > new file mode 100644
> > index 000000000000..1c2a4f683da4
> > --- /dev/null
> > +++ b/drivers/iio/accel/bmc150-accel-spi.c
> > @@ -0,0 +1,83 @@
> > +/*
> > + * 3-axis accelerometer driver supporting following I2C Bosch
> > -Sensortec chips:
> > + *  - BMC150
> > + *  - BMI055
> > + *  - BMA255
> > + *  - BMA250E
> > + *  - BMA222E
> > + *  - BMA280
> > + *
> > + * Copyright (c) 2014, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or 
> > modify it
> > + * under the terms and conditions of the GNU General Public 
> > License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but 
> > WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of 
> > MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public 
> > License for
> > + * more details.
> > + */
Not sure If you want to carry Intel Copyright for SPI driver part. If
you want to use change the year to 2015.
> > +
> > +#include <linux/device.h>
> > +#include <linux/mod_devicetable.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/regmap.h>
> > +#include <linux/spi/spi.h>
> > +
> > +#include "bmc150-accel.h"
> > +
> > +static const struct regmap_config bmc150_spi_regmap_conf = {
> > +	.reg_bits = 8,
> > +	.val_bits = 8,
> > +	.max_register = 0x3f,
> > +};
> > +
> > +static int bmc150_accel_probe(struct spi_device *spi)
> > +{
> > +	struct regmap *regmap;
> > +	const struct spi_device_id *id = spi_get_device_id(spi);
> > +
> > +	regmap = devm_regmap_init_spi(spi, 
> > &bmc150_spi_regmap_conf);
> > +	if (IS_ERR(regmap)) {
> > +		dev_err(&spi->dev, "Failed to initialize spi 
> > regmap\n");
> > +		return PTR_ERR(regmap);
> > +	}
> > +
> > +	return bmc150_accel_core_probe(&spi->dev, regmap, spi
> > ->irq,
> > +				       id->name, id->driver_data, 
> > true);
> > +}
> > +
> > +static int bmc150_accel_remove(struct spi_device *spi)
> > +{
> > +	return bmc150_accel_core_remove(&spi->dev);
> > +}
> > +
> > +static const struct spi_device_id bmc150_accel_id[] = {
> > +	{"bmc150_accel",	bmc150},
> > +	{"bmi055_accel",	bmi055},
> > +	{"bma255",		bma255},
> > +	{"bma250e",		bma250e},
> > +	{"bma222e",		bma222e},
> > +	{"bma280",		bma280},
> > +	{}
> > +};
> > +
> > +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> > +
> > +static struct spi_driver bmc150_accel_driver = {
> > +	.driver = {
> > +		.name	= "bmc150_accel_spi",
> > +		.acpi_match_table = 
> > ACPI_PTR(bmc150_accel_acpi_match),
> > +		.pm	= &bmc150_accel_pm_ops,
> > +	},
> > +	.probe		= bmc150_accel_probe,
> > +	.remove		= bmc150_accel_remove,
> > +	.id_table	= bmc150_accel_id,
> > +};
> > +module_spi_driver(bmc150_accel_driver);
> > +
> > +MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> > 
> 

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

* RE: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
  2015-08-31 19:38     ` Srinivas Pandruvada
@ 2015-09-08  1:09       ` Tirdea, Irina
  0 siblings, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-08  1:09 UTC (permalink / raw)
  To: Srinivas Pandruvada, Jonathan Cameron, Markus Pargmann
  Cc: Lars-Peter Clausen, linux-iio@vger.kernel.org,
	linux-kernel@vger.kernel.org, kernel@pengutronix.de

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogU3Jpbml2YXMgUGFuZHJ1
dmFkYSBbbWFpbHRvOnNyaW5pdmFzLnBhbmRydXZhZGFAbGludXguaW50ZWwuY29tXQ0KPiBTZW50
OiAzMSBBdWd1c3QsIDIwMTUgMjI6MzkNCj4gVG86IEpvbmF0aGFuIENhbWVyb247IE1hcmt1cyBQ
YXJnbWFubjsgVGlyZGVhLCBJcmluYQ0KPiBDYzogTGFycy1QZXRlciBDbGF1c2VuOyBsaW51eC1p
aW9Admdlci5rZXJuZWwub3JnOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOyBrZXJuZWxA
cGVuZ3V0cm9uaXguZGUNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2MiAxLzRdIGlpbzogYm1jMTUw
OiBVc2UgaTJjIHJlZ21hcA0KPiANCj4gSGkgSXJpbmEsDQo+IA0KDQpIaSBTcmluaXZhcywNCg0K
PiBJcyBpdCBwb3NzaWJsZSBmb3IgeW91IHRvIHRlc3QgdGhpcyBwYXRjaHNldD8gSSBkb24ndCBo
YXZlIHBsYXRmb3JtIHRvDQo+IHRlc3Qgd2l0aCBtZSBub3cgKHdvcmtpbmcgcmVtb3RlbHkgZm9y
IGNvdXBsZSBvZiB3ZWVrcykuDQo+IA0KDQpTdXJlLCBJJ2xsIHRlc3QgdGhpcyBwYXRjaCBzZXQg
dG9kYXkuDQpTb3JyeSBmb3IgdGhlIGxhdGUgcmVzcG9uc2UsIHNlZW1zIEkgc29tZWhvdyBtaXNz
ZWQgeW91ciBlLW1haWwuDQoNClJlZ2FyZHMsDQpJcmluYQ0KDQo+IFRoYW5rcywNCj4gU3Jpbml2
YXMNCj4gDQo+IE9uIE1vbiwgMjAxNS0wOC0zMSBhdCAxNzoxMSArMDEwMCwgSm9uYXRoYW4gQ2Ft
ZXJvbiB3cm90ZToNCj4gPiBPbiAyMC8wOC8xNSAxMzo0OSwgTWFya3VzIFBhcmdtYW5uIHdyb3Rl
Og0KPiA+ID4gVGhpcyByZXBsYWNlcyBhbGwgdXNhZ2Ugb2YgZGlyZWN0IGkyYyBhY2Nlc3NlcyB3
aXRoIHJlZ21hcA0KPiA+ID4gYWNjZXNzZXMuDQo+ID4gPg0KPiA+ID4gU2lnbmVkLW9mZi1ieTog
TWFya3VzIFBhcmdtYW5uIDxtcGFAcGVuZ3V0cm9uaXguZGU+DQo+ID4gTG9va3MgZmluZSB0byBt
ZSwgIGJ1dCBJIHdpbGwgYmUgd2FudGluZyBhbiBBY2sgLyByZXZpZXdlZC1ieQ0KPiA+IGFuZCBw
cmVmZXJhYmx5IGEgdGVzdGVkIGJ5IGZyb20gU3Jpbml2YXMuDQo+ID4NCj4gPiBUaGFua3MsDQo+
ID4NCj4gPiBKb25hdGhhbg0KPiA+ID4gLS0tDQo+ID4gPiAgZHJpdmVycy9paW8vYWNjZWwvS2Nv
bmZpZyAgICAgICAgfCAgIDIgKw0KPiA+ID4gIGRyaXZlcnMvaWlvL2FjY2VsL2JtYzE1MC1hY2Nl
bC5jIHwgMjE5ICsrKysrKysrKysrKysrKysrLS0tLS0tLS0tLQ0KPiA+ID4gLS0tLS0tLS0tLS0t
DQo+ID4gPiAgMiBmaWxlcyBjaGFuZ2VkLCA5NSBpbnNlcnRpb25zKCspLCAxMjYgZGVsZXRpb25z
KC0pDQo+ID4gPg0KPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvaWlvL2FjY2VsL0tjb25maWcg
Yi9kcml2ZXJzL2lpby9hY2NlbC9LY29uZmlnDQo+ID4gPiBpbmRleCAwMGU3YmNiZGJlMjQuLjAx
ZGQwM2QxOTRkMSAxMDA2NDQNCj4gPiA+IC0tLSBhL2RyaXZlcnMvaWlvL2FjY2VsL0tjb25maWcN
Cj4gPiA+ICsrKyBiL2RyaXZlcnMvaWlvL2FjY2VsL0tjb25maWcNCj4gPiA+IEBAIC0yMiw2ICsy
Miw4IEBAIGNvbmZpZyBCTUMxNTBfQUNDRUwNCj4gPiA+ICAJZGVwZW5kcyBvbiBJMkMNCj4gPiA+
ICAJc2VsZWN0IElJT19CVUZGRVINCj4gPiA+ICAJc2VsZWN0IElJT19UUklHR0VSRURfQlVGRkVS
DQo+ID4gPiArCXNlbGVjdCBSRUdNQVANCj4gPiA+ICsJc2VsZWN0IFJFR01BUF9JMkMNCj4gPiA+
ICAJaGVscA0KPiA+ID4gIAkgIFNheSB5ZXMgaGVyZSB0byBidWlsZCBzdXBwb3J0IGZvciB0aGUg
Zm9sbG93aW5nIEJvc2NoDQo+ID4gPiBhY2NlbGVyb21ldGVyczoNCj4gPiA+ICAJICBCTUMxNTAs
IEJNSTA1NSwgQk1BMjUwRSwgQk1BMjIyRSwgQk1BMjU1LCBCTUEyODAuDQo+ID4gPiBkaWZmIC0t
Z2l0IGEvZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFjY2VsLmMNCj4gPiA+IGIvZHJpdmVycy9p
aW8vYWNjZWwvYm1jMTUwLWFjY2VsLmMNCj4gPiA+IGluZGV4IDU1NzUxZDllMWFkZS4uYzVjNzcz
ZTc1MTczIDEwMDY0NA0KPiA+ID4gLS0tIGEvZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFjY2Vs
LmMNCj4gPiA+ICsrKyBiL2RyaXZlcnMvaWlvL2FjY2VsL2JtYzE1MC1hY2NlbC5jDQo+ID4gPiBA
QCAtMzUsNiArMzUsNyBAQA0KPiA+ID4gICNpbmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlci5oPg0K
PiA+ID4gICNpbmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcl9jb25zdW1lci5oPg0KPiA+ID4gICNp
bmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcmVkX2J1ZmZlci5oPg0KPiA+ID4gKyNpbmNsdWRlIDxs
aW51eC9yZWdtYXAuaD4NCj4gPiA+DQo+ID4gPiAgI2RlZmluZSBCTUMxNTBfQUNDRUxfRFJWX05B
TUUJCQkiYm1jMTUwX2FjY2VsDQo+ID4gPiAiDQo+ID4gPiAgI2RlZmluZSBCTUMxNTBfQUNDRUxf
SVJRX05BTUUJCQkiYm1jMTUwX2FjY2VsDQo+ID4gPiBfZXZlbnQiDQo+ID4gPiBAQCAtMTg1LDYg
KzE4Niw4IEBAIGVudW0gYm1jMTUwX2FjY2VsX3RyaWdnZXJfaWQgew0KPiA+ID4NCj4gPiA+ICBz
dHJ1Y3QgYm1jMTUwX2FjY2VsX2RhdGEgew0KPiA+ID4gIAlzdHJ1Y3QgaTJjX2NsaWVudCAqY2xp
ZW50Ow0KPiA+ID4gKwlzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7DQo+ID4gPiArCXN0cnVjdCBkZXZp
Y2UgKmRldjsNCj4gPiA+ICAJc3RydWN0IGJtYzE1MF9hY2NlbF9pbnRlcnJ1cHQNCj4gPiA+IGlu
dGVycnVwdHNbQk1DMTUwX0FDQ0VMX0lOVEVSUlVQVFNdOw0KPiA+ID4gIAlhdG9taWNfdCBhY3Rp
dmVfaW50cjsNCj4gPiA+ICAJc3RydWN0IGJtYzE1MF9hY2NlbF90cmlnZ2VyDQo+ID4gPiB0cmln
Z2Vyc1tCTUMxNTBfQUNDRUxfVFJJR0dFUlNdOw0KPiA+ID4gQEAgLTI0MSw2ICsyNDQsMTEgQEAg
c3RhdGljIGNvbnN0IHN0cnVjdCB7DQo+ID4gPiAgCQkJCSAgICAgICB7NTAwMDAwLA0KPiA+ID4g
Qk1DMTUwX0FDQ0VMX1NMRUVQXzUwMF9NU30sDQo+ID4gPiAgCQkJCSAgICAgICB7MTAwMDAwMCwN
Cj4gPiA+IEJNQzE1MF9BQ0NFTF9TTEVFUF8xX1NFQ30gfTsNCj4gPiA+DQo+ID4gPiArc3RhdGlj
IGNvbnN0IHN0cnVjdCByZWdtYXBfY29uZmlnIGJtYzE1MF9pMmNfcmVnbWFwX2NvbmYgPSB7DQo+
ID4gPiArCS5yZWdfYml0cyA9IDgsDQo+ID4gPiArCS52YWxfYml0cyA9IDgsDQo+ID4gPiArCS5t
YXhfcmVnaXN0ZXIgPSAweDNmLA0KPiA+ID4gK307DQo+ID4gPg0KPiA+ID4gIHN0YXRpYyBpbnQg
Ym1jMTUwX2FjY2VsX3NldF9tb2RlKHN0cnVjdCBibWMxNTBfYWNjZWxfZGF0YSAqZGF0YSwNCj4g
PiA+ICAJCQkJIGVudW0gYm1jMTUwX3Bvd2VyX21vZGVzIG1vZGUsDQo+ID4gPiBAQCAtMjcwLDgg
KzI3OCw3IEBAIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3NldF9tb2RlKHN0cnVjdA0KPiA+ID4g
Ym1jMTUwX2FjY2VsX2RhdGEgKmRhdGEsDQo+ID4gPg0KPiA+ID4gIAlkZXZfZGJnKCZkYXRhLT5j
bGllbnQtPmRldiwgIlNldCBNb2RlIGJpdHMgJXhcbiIsDQo+ID4gPiBscHdfYml0cyk7DQo+ID4g
Pg0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwN
Cj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9SRUdfUE1VX0xQVywNCj4gPiA+IGxwd19iaXRzKTsN
Cj4gPiA+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKGRhdGEtPnJlZ21hcCwgQk1DMTUwX0FDQ0VMX1JF
R19QTVVfTFBXLA0KPiA+ID4gbHB3X2JpdHMpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+
ID4gIAkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB3cml0aW5nDQo+ID4gPiBy
ZWdfcG11X2xwd1xuIik7DQo+ID4gPiAgCQlyZXR1cm4gcmV0Ow0KPiA+ID4gQEAgLTI4OSw4ICsy
OTYsNyBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9zZXRfYncoc3RydWN0DQo+ID4gPiBibWMx
NTBfYWNjZWxfZGF0YSAqZGF0YSwgaW50IHZhbCwNCj4gPiA+ICAJZm9yIChpID0gMDsgaSA8IEFS
UkFZX1NJWkUoYm1jMTUwX2FjY2VsX3NhbXBfZnJlcV90YWJsZSk7DQo+ID4gPiArK2kpIHsNCj4g
PiA+ICAJCWlmIChibWMxNTBfYWNjZWxfc2FtcF9mcmVxX3RhYmxlW2ldLnZhbCA9PSB2YWwgJiYN
Cj4gPiA+ICAJCQkJYm1jMTUwX2FjY2VsX3NhbXBfZnJlcV90YWJsZVtpXS52YQ0KPiA+ID4gbDIg
PT0gdmFsMikgew0KPiA+ID4gLQkJCXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoDQo+
ID4gPiAtCQkJCWRhdGEtPmNsaWVudCwNCj4gPiA+ICsJCQlyZXQgPSByZWdtYXBfd3JpdGUoZGF0
YS0+cmVnbWFwLA0KPiA+ID4gIAkJCQlCTUMxNTBfQUNDRUxfUkVHX1BNVV9CVywNCj4gPiA+ICAJ
CQkJYm1jMTUwX2FjY2VsX3NhbXBfZnJlcV90YWJsZVtpXS5idw0KPiA+ID4gX2JpdHMpOw0KPiA+
ID4gIAkJCWlmIChyZXQgPCAwKQ0KPiA+ID4gQEAgLTMwNywyNiArMzEzLDE5IEBAIHN0YXRpYyBp
bnQgYm1jMTUwX2FjY2VsX3NldF9idyhzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9hY2NlbF9kYXRhICpk
YXRhLCBpbnQgdmFsLA0KPiA+ID4NCj4gPiA+ICBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF91cGRh
dGVfc2xvcGUoc3RydWN0IGJtYzE1MF9hY2NlbF9kYXRhDQo+ID4gPiAqZGF0YSkNCj4gPiA+ICB7
DQo+ID4gPiAtCWludCByZXQsIHZhbDsNCj4gPiA+ICsJaW50IHJldDsNCj4gPiA+DQo+ID4gPiAt
CXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gQk1D
MTUwX0FDQ0VMX1JFR19JTlRfNiwNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3dyaXRlKGRhdGEtPnJl
Z21hcCwgQk1DMTUwX0FDQ0VMX1JFR19JTlRfNiwNCj4gPiA+ICAJCQkJCWRhdGEtPnNsb3BlX3Ro
cmVzKTsNCj4gPiA+ICAJaWYgKHJldCA8IDApIHsNCj4gPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNs
aWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZw0KPiA+ID4gcmVnX2ludF82XG4iKTsNCj4gPiA+ICAJ
CXJldHVybiByZXQ7DQo+ID4gPiAgCX0NCj4gPiA+DQo+ID4gPiAtCXJldCA9IGkyY19zbWJ1c19y
ZWFkX2J5dGVfZGF0YShkYXRhLT5jbGllbnQsDQo+ID4gPiBCTUMxNTBfQUNDRUxfUkVHX0lOVF81
KTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRzKGRhdGEtPnJlZ21hcCwNCj4gPiA+
IEJNQzE1MF9BQ0NFTF9SRUdfSU5UXzUsDQo+ID4gPiArCQkJCSBCTUMxNTBfQUNDRUxfU0xPUEVf
RFVSX01BU0ssIGRhdGENCj4gPiA+IC0+c2xvcGVfZHVyKTsNCj4gPiA+ICAJaWYgKHJldCA8IDAp
IHsNCj4gPiA+IC0JCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiRXJyb3IgcmVhZGluZw0K
PiA+ID4gcmVnX2ludF81XG4iKTsNCj4gPiA+IC0JCXJldHVybiByZXQ7DQo+ID4gPiAtCX0NCj4g
PiA+IC0NCj4gPiA+IC0JdmFsID0gKHJldCAmIH5CTUMxNTBfQUNDRUxfU0xPUEVfRFVSX01BU0sp
IHwgZGF0YQ0KPiA+ID4gLT5zbG9wZV9kdXI7DQo+ID4gPiAtCXJldCA9IGkyY19zbWJ1c193cml0
ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfNSwN
Cj4gPiA+IC0JCQkJCXZhbCk7DQo+ID4gPiAtCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAtCQlkZXZf
ZXJyKCZkYXRhLT5jbGllbnQtPmRldiwgIkVycm9yIHdyaXRlDQo+ID4gPiByZWdfaW50XzVcbiIp
Ow0KPiA+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB1cGRhdGluZw0K
PiA+ID4gcmVnX2ludF81XG4iKTsNCj4gPiA+ICAJCXJldHVybiByZXQ7DQo+ID4gPiAgCX0NCj4g
PiA+DQo+ID4gPiBAQCAtMzQ4LDE3ICszNDcsMTggQEAgc3RhdGljIGludA0KPiA+ID4gYm1jMTUw
X2FjY2VsX2FueV9tb3Rpb25fc2V0dXAoc3RydWN0IGJtYzE1MF9hY2NlbF90cmlnZ2VyICp0LA0K
PiA+ID4gIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX2NoaXBfaW5pdChzdHJ1Y3QgYm1jMTUwX2Fj
Y2VsX2RhdGEgKmRhdGEpDQo+ID4gPiAgew0KPiA+ID4gIAlpbnQgcmV0Ow0KPiA+ID4gKwl1bnNp
Z25lZCBpbnQgdmFsOw0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9k
YXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9SRUdfQ0hJUF9JRCk7DQo+ID4g
PiArCXJldCA9IHJlZ21hcF9yZWFkKGRhdGEtPnJlZ21hcCwgQk1DMTUwX0FDQ0VMX1JFR19DSElQ
X0lELA0KPiA+ID4gJnZhbCk7DQo+ID4gPiAgCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAgCQlkZXZf
ZXJyKCZkYXRhLT5jbGllbnQtPmRldiwNCj4gPiA+ICAJCQkiRXJyb3I6IFJlYWRpbmcgY2hpcCBp
ZFxuIik7DQo+ID4gPiAgCQlyZXR1cm4gcmV0Ow0KPiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4gLQlk
ZXZfZGJnKCZkYXRhLT5jbGllbnQtPmRldiwgIkNoaXAgSWQgJXhcbiIsIHJldCk7DQo+ID4gPiAt
CWlmIChyZXQgIT0gZGF0YS0+Y2hpcF9pbmZvLT5jaGlwX2lkKSB7DQo+ID4gPiAtCQlkZXZfZXJy
KCZkYXRhLT5jbGllbnQtPmRldiwgIkludmFsaWQgY2hpcCAleFxuIiwNCj4gPiA+IHJldCk7DQo+
ID4gPiArCWRldl9kYmcoJmRhdGEtPmNsaWVudC0+ZGV2LCAiQ2hpcCBJZCAleFxuIiwgdmFsKTsN
Cj4gPiA+ICsJaWYgKHZhbCAhPSBkYXRhLT5jaGlwX2luZm8tPmNoaXBfaWQpIHsNCj4gPiA+ICsJ
CWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiSW52YWxpZCBjaGlwICV4XG4iLA0KPiA+ID4g
dmFsKTsNCj4gPiA+ICAJCXJldHVybiAtRU5PREVWOw0KPiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4g
QEAgLTM3Miw5ICszNzIsOCBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9jaGlwX2luaXQoc3Ry
dWN0DQo+ID4gPiBibWMxNTBfYWNjZWxfZGF0YSAqZGF0YSkNCj4gPiA+ICAJCXJldHVybiByZXQ7
DQo+ID4gPg0KPiA+ID4gIAkvKiBTZXQgRGVmYXVsdCBSYW5nZSAqLw0KPiA+ID4gLQlyZXQgPSBp
MmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0JCQkJCUJNQzE1
MF9BQ0NFTF9SRUdfUE1VX1JBTkdFDQo+ID4gPiAsDQo+ID4gPiAtCQkJCQlCTUMxNTBfQUNDRUxf
REVGX1JBTkdFXzRHKQ0KPiA+ID4gOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfd3JpdGUoZGF0YS0+
cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19QTVVfUkFOR0UsDQo+ID4gPiArCQkJICAg
Qk1DMTUwX0FDQ0VMX0RFRl9SQU5HRV80Ryk7DQo+ID4gPiAgCWlmIChyZXQgPCAwKSB7DQo+ID4g
PiAgCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRldiwNCj4gPiA+ICAJCQkJCSJFcnJvciB3cml0
aW5nDQo+ID4gPiByZWdfcG11X3JhbmdlXG4iKTsNCj4gPiA+IEBAIC0zOTEsMTAgKzM5MCw5IEBA
IHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX2NoaXBfaW5pdChzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9h
Y2NlbF9kYXRhICpkYXRhKQ0KPiA+ID4gIAkJcmV0dXJuIHJldDsNCj4gPiA+DQo+ID4gPiAgCS8q
IFNldCBkZWZhdWx0IGFzIGxhdGNoZWQgaW50ZXJydXB0cyAqLw0KPiA+ID4gLQlyZXQgPSBpMmNf
c21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0JCQkJCUJNQzE1MF9B
Q0NFTF9SRUdfSU5UX1JTVF9MDQo+ID4gPiBBVENILA0KPiA+ID4gLQkJCQkJQk1DMTUwX0FDQ0VM
X0lOVF9NT0RFX0xBVEMNCj4gPiA+IEhfSU5UIHwNCj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9J
TlRfTU9ERV9MQVRDDQo+ID4gPiBIX1JFU0VUKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3dyaXRl
KGRhdGEtPnJlZ21hcCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9SRUdfSU5UX1JTVF9MQVRDSCwNCj4g
PiA+ICsJCQkgICBCTUMxNTBfQUNDRUxfSU5UX01PREVfTEFUQ0hfSU5UIHwNCj4gPiA+ICsJCQkg
ICBCTUMxNTBfQUNDRUxfSU5UX01PREVfTEFUQ0hfUkVTRVQpOw0KPiA+ID4gIAlpZiAocmV0IDwg
MCkgew0KPiA+ID4gIAkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsDQo+ID4gPiAgCQkJIkVy
cm9yIHdyaXRpbmcgcmVnX2ludF9yc3RfbGF0Y2hcbiIpOw0KPiA+ID4gQEAgLTUyNywzOCArNTI1
LDE4IEBAIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3NldF9pbnRlcnJ1cHQoc3RydWN0DQo+ID4g
PiBibWMxNTBfYWNjZWxfZGF0YSAqZGF0YSwgaW50IGksDQo+ID4gPiAgCQlyZXR1cm4gcmV0Ow0K
PiA+ID4NCj4gPiA+ICAJLyogbWFwIHRoZSBpbnRlcnJ1cHQgdG8gdGhlIGFwcHJvcHJpYXRlIHBp
bnMgKi8NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3JlYWRfYnl0ZV9kYXRhKGRhdGEtPmNsaWVu
dCwgaW5mbw0KPiA+ID4gLT5tYXBfcmVnKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9i
aXRzKGRhdGEtPnJlZ21hcCwgaW5mby0+bWFwX3JlZywgaW5mbw0KPiA+ID4gLT5tYXBfYml0bWFz
aywNCj4gPiA+ICsJCQkJIChzdGF0ZSA/IGluZm8tPm1hcF9iaXRtYXNrIDogMCkpOw0KPiA+ID4g
IAlpZiAocmV0IDwgMCkgew0KPiA+ID4gLQkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJF
cnJvciByZWFkaW5nDQo+ID4gPiByZWdfaW50X21hcFxuIik7DQo+ID4gPiAtCQlnb3RvIG91dF9m
aXhfcG93ZXJfc3RhdGU7DQo+ID4gPiAtCX0NCj4gPiA+IC0JaWYgKHN0YXRlKQ0KPiA+ID4gLQkJ
cmV0IHw9IGluZm8tPm1hcF9iaXRtYXNrOw0KPiA+ID4gLQllbHNlDQo+ID4gPiAtCQlyZXQgJj0g
fmluZm8tPm1hcF9iaXRtYXNrOw0KPiA+ID4gLQ0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3Jp
dGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwgaW5mbw0KPiA+ID4gLT5tYXBfcmVnLA0KPiA+ID4g
LQkJCQkJcmV0KTsNCj4gPiA+IC0JaWYgKHJldCA8IDApIHsNCj4gPiA+IC0JCWRldl9lcnIoJmRh
dGEtPmNsaWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZw0KPiA+ID4gcmVnX2ludF9tYXBcbiIpOw0K
PiA+ID4gKwkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB1cGRhdGluZw0KPiA+
ID4gcmVnX2ludF9tYXBcbiIpOw0KPiA+ID4gIAkJZ290byBvdXRfZml4X3Bvd2VyX3N0YXRlOw0K
PiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4gIAkvKiBlbmFibGUvZGlzYWJsZSB0aGUgaW50ZXJydXB0
ICovDQo+ID4gPiAtCXJldCA9IGkyY19zbWJ1c19yZWFkX2J5dGVfZGF0YShkYXRhLT5jbGllbnQs
IGluZm8NCj4gPiA+IC0+ZW5fcmVnKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3VwZGF0ZV9iaXRz
KGRhdGEtPnJlZ21hcCwgaW5mby0+ZW5fcmVnLCBpbmZvDQo+ID4gPiAtPmVuX2JpdG1hc2ssDQo+
ID4gPiArCQkJCSAoc3RhdGUgPyBpbmZvLT5lbl9iaXRtYXNrIDogMCkpOw0KPiA+ID4gIAlpZiAo
cmV0IDwgMCkgew0KPiA+ID4gLQkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciBy
ZWFkaW5nDQo+ID4gPiByZWdfaW50X2VuXG4iKTsNCj4gPiA+IC0JCWdvdG8gb3V0X2ZpeF9wb3dl
cl9zdGF0ZTsNCj4gPiA+IC0JfQ0KPiA+ID4gLQ0KPiA+ID4gLQlpZiAoc3RhdGUpDQo+ID4gPiAt
CQlyZXQgfD0gaW5mby0+ZW5fYml0bWFzazsNCj4gPiA+IC0JZWxzZQ0KPiA+ID4gLQkJcmV0ICY9
IH5pbmZvLT5lbl9iaXRtYXNrOw0KPiA+ID4gLQ0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3Jp
dGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwgaW5mbw0KPiA+ID4gLT5lbl9yZWcsIHJldCk7DQo+
ID4gPiAtCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAtCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRl
diwgIkVycm9yIHdyaXRpbmcNCj4gPiA+IHJlZ19pbnRfZW5cbiIpOw0KPiA+ID4gKwkJZGV2X2Vy
cigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB1cGRhdGluZw0KPiA+ID4gcmVnX2ludF9lblxu
Iik7DQo+ID4gPiAgCQlnb3RvIG91dF9maXhfcG93ZXJfc3RhdGU7DQo+ID4gPiAgCX0NCj4gPiA+
DQo+ID4gPiBAQCAtNTgxLDggKzU1OSw3IEBAIHN0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3NldF9z
Y2FsZShzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLCBpbnQgdmFsKQ0KPiA+
ID4NCj4gPiA+ICAJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUoZGF0YS0+Y2hpcF9pbmZvLT5z
Y2FsZV90YWJsZSk7DQo+ID4gPiArK2kpIHsNCj4gPiA+ICAJCWlmIChkYXRhLT5jaGlwX2luZm8t
PnNjYWxlX3RhYmxlW2ldLnNjYWxlID09IHZhbCkNCj4gPiA+IHsNCj4gPiA+IC0JCQlyZXQgPSBp
MmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKA0KPiA+ID4gLQkJCQkgICAgIGRhdGEtPmNsaWVudCwN
Cj4gPiA+ICsJCQlyZXQgPSByZWdtYXBfd3JpdGUoZGF0YS0+cmVnbWFwLA0KPiA+ID4gIAkJCQkg
ICAgIEJNQzE1MF9BQ0NFTF9SRUdfUE1VX1JBTkdFLA0KPiA+ID4gIAkJCQkgICAgIGRhdGEtPmNo
aXBfaW5mbw0KPiA+ID4gLT5zY2FsZV90YWJsZVtpXS5yZWdfcmFuZ2UpOw0KPiA+ID4gIAkJCWlm
IChyZXQgPCAwKSB7DQo+ID4gPiBAQCAtNjAyLDE2ICs1NzksMTcgQEAgc3RhdGljIGludCBibWMx
NTBfYWNjZWxfc2V0X3NjYWxlKHN0cnVjdA0KPiA+ID4gYm1jMTUwX2FjY2VsX2RhdGEgKmRhdGEs
IGludCB2YWwpDQo+ID4gPiAgc3RhdGljIGludCBibWMxNTBfYWNjZWxfZ2V0X3RlbXAoc3RydWN0
IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLA0KPiA+ID4gaW50ICp2YWwpDQo+ID4gPiAgew0KPiA+
ID4gIAlpbnQgcmV0Ow0KPiA+ID4gKwl1bnNpZ25lZCBpbnQgdmFsdWU7DQo+ID4gPg0KPiA+ID4g
IAltdXRleF9sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gPg0KPiA+ID4gLQlyZXQgPSBpMmNfc21i
dXNfcmVhZF9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19U
RU1QKTsNCj4gPiA+ICsJcmV0ID0gcmVnbWFwX3JlYWQoZGF0YS0+cmVnbWFwLCBCTUMxNTBfQUND
RUxfUkVHX1RFTVAsDQo+ID4gPiAmdmFsdWUpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+
ID4gIAkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciByZWFkaW5nDQo+ID4gPiBy
ZWdfdGVtcFxuIik7DQo+ID4gPiAgCQltdXRleF91bmxvY2soJmRhdGEtPm11dGV4KTsNCj4gPiA+
ICAJCXJldHVybiByZXQ7DQo+ID4gPiAgCX0NCj4gPiA+IC0JKnZhbCA9IHNpZ25fZXh0ZW5kMzIo
cmV0LCA3KTsNCj4gPiA+ICsJKnZhbCA9IHNpZ25fZXh0ZW5kMzIodmFsdWUsIDcpOw0KPiA+ID4N
Cj4gPiA+ICAJbXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gPg0KPiA+ID4gQEAgLTYy
NCw2ICs2MDIsNyBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9nZXRfYXhpcyhzdHJ1Y3QNCj4g
PiA+IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLA0KPiA+ID4gIHsNCj4gPiA+ICAJaW50IHJldDsN
Cj4gPiA+ICAJaW50IGF4aXMgPSBjaGFuLT5zY2FuX2luZGV4Ow0KPiA+ID4gKwl1bnNpZ25lZCBp
bnQgcmF3X3ZhbDsNCj4gPiA+DQo+ID4gPiAgCW11dGV4X2xvY2soJmRhdGEtPm11dGV4KTsNCj4g
PiA+ICAJcmV0ID0gYm1jMTUwX2FjY2VsX3NldF9wb3dlcl9zdGF0ZShkYXRhLCB0cnVlKTsNCj4g
PiA+IEBAIC02MzIsMTUgKzYxMSwxNSBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9nZXRfYXhp
cyhzdHJ1Y3QNCj4gPiA+IGJtYzE1MF9hY2NlbF9kYXRhICpkYXRhLA0KPiA+ID4gIAkJcmV0dXJu
IHJldDsNCj4gPiA+ICAJfQ0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3JlYWRfd29y
ZF9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0NCj4gPiA+ICBCTUMxNTBfQUNDRUxfQVhJU19U
T19SRUcoYXhpcykpOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfYnVsa19yZWFkKGRhdGEtPnJlZ21h
cCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9BWElTX1RPX1JFRyhheGlzKSwNCj4gPiA+ICsJCQkgICAg
ICAgJnJhd192YWwsIDIpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJZGV2X2Vy
cigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciByZWFkaW5nIGF4aXMNCj4gPiA+ICVkXG4iLCBh
eGlzKTsNCj4gPiA+ICAJCWJtYzE1MF9hY2NlbF9zZXRfcG93ZXJfc3RhdGUoZGF0YSwgZmFsc2Up
Ow0KPiA+ID4gIAkJbXV0ZXhfdW5sb2NrKCZkYXRhLT5tdXRleCk7DQo+ID4gPiAgCQlyZXR1cm4g
cmV0Ow0KPiA+ID4gIAl9DQo+ID4gPiAtCSp2YWwgPSBzaWduX2V4dGVuZDMyKHJldCA+PiBjaGFu
LT5zY2FuX3R5cGUuc2hpZnQsDQo+ID4gPiArCSp2YWwgPSBzaWduX2V4dGVuZDMyKHJhd192YWwg
Pj4gY2hhbi0+c2Nhbl90eXBlLnNoaWZ0LA0KPiA+ID4gIAkJCSAgICAgY2hhbi0+c2Nhbl90eXBl
LnJlYWxiaXRzIC0gMSk7DQo+ID4gPiAgCXJldCA9IGJtYzE1MF9hY2NlbF9zZXRfcG93ZXJfc3Rh
dGUoZGF0YSwgZmFsc2UpOw0KPiA+ID4gIAltdXRleF91bmxvY2soJmRhdGEtPm11dGV4KTsNCj4g
PiA+IEBAIC05MDQsNTIgKzg4MywzNCBAQCBzdGF0aWMgaW50IGJtYzE1MF9hY2NlbF9zZXRfd2F0
ZXJtYXJrKHN0cnVjdA0KPiA+ID4gaWlvX2RldiAqaW5kaW9fZGV2LCB1bnNpZ25lZCB2YWwpDQo+
ID4gPiAgICogV2UgbXVzdCByZWFkIGF0IGxlYXN0IG9uZSBmdWxsIGZyYW1lIGluIG9uZSBidXJz
dCwgb3RoZXJ3aXNlDQo+ID4gPiB0aGUgcmVzdCBvZiB0aGUNCj4gPiA+ICAgKiBmcmFtZSBkYXRh
IGlzIGRpc2NhcmRlZC4NCj4gPiA+ICAgKi8NCj4gPiA+IC1zdGF0aWMgaW50IGJtYzE1MF9hY2Nl
bF9maWZvX3RyYW5zZmVyKGNvbnN0IHN0cnVjdCBpMmNfY2xpZW50DQo+ID4gPiAqY2xpZW50LA0K
PiA+ID4gK3N0YXRpYyBpbnQgYm1jMTUwX2FjY2VsX2ZpZm9fdHJhbnNmZXIoc3RydWN0IGJtYzE1
MF9hY2NlbF9kYXRhDQo+ID4gPiAqZGF0YSwNCj4gPiA+ICAJCQkJICAgICAgY2hhciAqYnVmZmVy
LCBpbnQgc2FtcGxlcykNCj4gPiA+ICB7DQo+ID4gPiAgCWludCBzYW1wbGVfbGVuZ3RoID0gMyAq
IDI7DQo+ID4gPiAtCXU4IHJlZ19maWZvX2RhdGEgPSBCTUMxNTBfQUNDRUxfUkVHX0ZJRk9fREFU
QTsNCj4gPiA+IC0JaW50IHJldCA9IC1FSU87DQo+ID4gPiAtDQo+ID4gPiAtCWlmIChpMmNfY2hl
Y2tfZnVuY3Rpb25hbGl0eShjbGllbnQtPmFkYXB0ZXIsDQo+ID4gPiBJMkNfRlVOQ19JMkMpKSB7
DQo+ID4gPiAtCQlzdHJ1Y3QgaTJjX21zZyBtc2dbMl0gPSB7DQo+ID4gPiAtCQkJew0KPiA+ID4g
LQkJCQkuYWRkciA9IGNsaWVudC0+YWRkciwNCj4gPiA+IC0JCQkJLmZsYWdzID0gMCwNCj4gPiA+
IC0JCQkJLmJ1ZiA9ICZyZWdfZmlmb19kYXRhLA0KPiA+ID4gLQkJCQkubGVuID0gc2l6ZW9mKHJl
Z19maWZvX2RhdGEpLA0KPiA+ID4gLQkJCX0sDQo+ID4gPiAtCQkJew0KPiA+ID4gLQkJCQkuYWRk
ciA9IGNsaWVudC0+YWRkciwNCj4gPiA+IC0JCQkJLmZsYWdzID0gSTJDX01fUkQsDQo+ID4gPiAt
CQkJCS5idWYgPSAodTggKilidWZmZXIsDQo+ID4gPiAtCQkJCS5sZW4gPSBzYW1wbGVzICogc2Ft
cGxlX2xlbmd0aCwNCj4gPiA+IC0JCQl9DQo+ID4gPiAtCQl9Ow0KPiA+ID4gKwlpbnQgcmV0Ow0K
PiA+ID4gKwlpbnQgdG90YWxfbGVuZ3RoID0gc2FtcGxlcyAqIHNhbXBsZV9sZW5ndGg7DQo+ID4g
PiArCWludCBpOw0KPiA+ID4gKwlpbnQgc3RlcCA9IHJlZ21hcF9nZXRfcmF3X3JlYWRfbWF4KGRh
dGEtPnJlZ21hcCk7DQo+ID4gPg0KPiA+ID4gLQkJcmV0ID0gaTJjX3RyYW5zZmVyKGNsaWVudC0+
YWRhcHRlciwgbXNnLCAyKTsNCj4gPiA+IC0JCWlmIChyZXQgIT0gMikNCj4gPiA+IC0JCQlyZXQg
PSAtRUlPOw0KPiA+ID4gLQkJZWxzZQ0KPiA+ID4gLQkJCXJldCA9IDA7DQo+ID4gPiAtCX0gZWxz
ZSB7DQo+ID4gPiAtCQlpbnQgaSwgc3RlcCA9IEkyQ19TTUJVU19CTE9DS19NQVggLyBzYW1wbGVf
bGVuZ3RoOw0KPiA+ID4gLQ0KPiA+ID4gLQkJZm9yIChpID0gMDsgaSA8IHNhbXBsZXMgKiBzYW1w
bGVfbGVuZ3RoOyBpICs9DQo+ID4gPiBzdGVwKSB7DQo+ID4gPiAtCQkJcmV0ID0NCj4gPiA+IGky
Y19zbWJ1c19yZWFkX2kyY19ibG9ja19kYXRhKGNsaWVudCwNCj4gPiA+IC0NCj4gPiA+ICByZWdf
Zmlmb19kYXRhLCBzdGVwLA0KPiA+ID4gLQ0KPiA+ID4gICZidWZmZXJbaV0pOw0KPiA+ID4gLQkJ
CWlmIChyZXQgIT0gc3RlcCkgew0KPiA+ID4gLQkJCQlyZXQgPSAtRUlPOw0KPiA+ID4gLQkJCQli
cmVhazsNCj4gPiA+IC0JCQl9DQo+ID4gPiArCWlmICghc3RlcCB8fCBzdGVwID4gdG90YWxfbGVu
Z3RoKQ0KPiA+ID4gKwkJc3RlcCA9IHRvdGFsX2xlbmd0aDsNCj4gPiA+ICsJZWxzZSBpZiAoc3Rl
cCA8IHRvdGFsX2xlbmd0aCkNCj4gPiA+ICsJCXN0ZXAgPSBzYW1wbGVfbGVuZ3RoOw0KPiA+ID4N
Cj4gPiA+IC0JCQlyZXQgPSAwOw0KPiA+ID4gLQkJfQ0KPiA+ID4gKwkvKg0KPiA+ID4gKwkgKiBT
ZWVtcyB3ZSBoYXZlIGEgYnVzIHdpdGggc2l6ZSBsaW1pdGF0aW9uIHNvIHdlIGhhdmUgdG8NCj4g
PiA+IGV4ZWN1dGUNCj4gPiA+ICsJICogbXVsdGlwbGUgcmVhZHMNCj4gPiA+ICsJICovDQo+ID4g
PiArCWZvciAoaSA9IDA7IGkgPCB0b3RhbF9sZW5ndGg7IGkgKz0gc3RlcCkgew0KPiA+ID4gKwkJ
cmV0ID0gcmVnbWFwX3Jhd19yZWFkKGRhdGEtPnJlZ21hcCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9S
RUdfRklGT19EQVRBLA0KPiA+ID4gKwkJCQkgICAgICAmYnVmZmVyW2ldLCBzdGVwKTsNCj4gPiA+
ICsJCWlmIChyZXQpDQo+ID4gPiArCQkJYnJlYWs7DQo+ID4gPiAgCX0NCj4gPiA+DQo+ID4gPiAg
CWlmIChyZXQpDQo+ID4gPiAtCQlkZXZfZXJyKCZjbGllbnQtPmRldiwgIkVycm9yIHRyYW5zZmVy
cmluZyBkYXRhDQo+ID4gPiBmcm9tIGZpZm9cbiIpOw0KPiA+ID4gKwkJZGV2X2VycihkYXRhLT5k
ZXYsICJFcnJvciB0cmFuc2ZlcnJpbmcgZGF0YSBmcm9tDQo+ID4gPiBmaWZvIGluIHNpbmdsZSBz
dGVwcyBvZiAlenVcbiIsDQo+ID4gPiArCQkJc3RlcCk7DQo+ID4gPg0KPiA+ID4gIAlyZXR1cm4g
cmV0Ow0KPiA+ID4gIH0NCj4gPiA+IEBAIC05NjMsMTQgKzkyNCwxNSBAQCBzdGF0aWMgaW50IF9f
Ym1jMTUwX2FjY2VsX2ZpZm9fZmx1c2goc3RydWN0DQo+ID4gPiBpaW9fZGV2ICppbmRpb19kZXYs
DQo+ID4gPiAgCXUxNiBidWZmZXJbQk1DMTUwX0FDQ0VMX0ZJRk9fTEVOR1RIICogM107DQo+ID4g
PiAgCWludDY0X3QgdHN0YW1wOw0KPiA+ID4gIAl1aW50NjRfdCBzYW1wbGVfcGVyaW9kOw0KPiA+
ID4gLQlyZXQgPSBpMmNfc21idXNfcmVhZF9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4g
LQ0KPiA+ID4gIEJNQzE1MF9BQ0NFTF9SRUdfRklGT19TVEFUVVMpOw0KPiA+ID4gKwl1bnNpZ25l
ZCBpbnQgdmFsOw0KPiA+ID4gKw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfcmVhZChkYXRhLT5yZWdt
YXAsDQo+ID4gPiBCTUMxNTBfQUNDRUxfUkVHX0ZJRk9fU1RBVFVTLCAmdmFsKTsNCj4gPiA+ICAJ
aWYgKHJldCA8IDApIHsNCj4gPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2LCAiRXJy
b3IgcmVhZGluZw0KPiA+ID4gcmVnX2ZpZm9fc3RhdHVzXG4iKTsNCj4gPiA+ICAJCXJldHVybiBy
ZXQ7DQo+ID4gPiAgCX0NCj4gPiA+DQo+ID4gPiAtCWNvdW50ID0gcmV0ICYgMHg3RjsNCj4gPiA+
ICsJY291bnQgPSB2YWwgJiAweDdGOw0KPiA+ID4NCj4gPiA+ICAJaWYgKCFjb3VudCkNCj4gPiA+
ICAJCXJldHVybiAwOw0KPiA+ID4gQEAgLTEwMDksNyArOTcxLDcgQEAgc3RhdGljIGludCBfX2Jt
YzE1MF9hY2NlbF9maWZvX2ZsdXNoKHN0cnVjdA0KPiA+ID4gaWlvX2RldiAqaW5kaW9fZGV2LA0K
PiA+ID4gIAlpZiAoc2FtcGxlcyAmJiBjb3VudCA+IHNhbXBsZXMpDQo+ID4gPiAgCQljb3VudCA9
IHNhbXBsZXM7DQo+ID4gPg0KPiA+ID4gLQlyZXQgPSBibWMxNTBfYWNjZWxfZmlmb190cmFuc2Zl
cihkYXRhLT5jbGllbnQsICh1OA0KPiA+ID4gKilidWZmZXIsIGNvdW50KTsNCj4gPiA+ICsJcmV0
ID0gYm1jMTUwX2FjY2VsX2ZpZm9fdHJhbnNmZXIoZGF0YSwgKHU4ICopYnVmZmVyLA0KPiA+ID4g
Y291bnQpOw0KPiA+ID4gIAlpZiAocmV0KQ0KPiA+ID4gIAkJcmV0dXJuIHJldDsNCj4gPiA+DQo+
ID4gPiBAQCAtMTIwNiwxNyArMTE2OCwxOSBAQCBzdGF0aWMgaXJxcmV0dXJuX3QNCj4gPiA+IGJt
YzE1MF9hY2NlbF90cmlnZ2VyX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqcCkNCj4gPiA+ICAJc3Ry
dWN0IGlpb19kZXYgKmluZGlvX2RldiA9IHBmLT5pbmRpb19kZXY7DQo+ID4gPiAgCXN0cnVjdCBi
bWMxNTBfYWNjZWxfZGF0YSAqZGF0YSA9IGlpb19wcml2KGluZGlvX2Rldik7DQo+ID4gPiAgCWlu
dCBiaXQsIHJldCwgaSA9IDA7DQo+ID4gPiArCXVuc2lnbmVkIGludCByYXdfdmFsOw0KPiA+ID4N
Cj4gPiA+ICAJbXV0ZXhfbG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ID4gIAlmb3JfZWFjaF9zZXRf
Yml0KGJpdCwgaW5kaW9fZGV2LT5hY3RpdmVfc2Nhbl9tYXNrLA0KPiA+ID4gIAkJCSBpbmRpb19k
ZXYtPm1hc2tsZW5ndGgpIHsNCj4gPiA+IC0JCXJldCA9IGkyY19zbWJ1c19yZWFkX3dvcmRfZGF0
YShkYXRhLT5jbGllbnQsDQo+ID4gPiAtDQo+ID4gPiAgQk1DMTUwX0FDQ0VMX0FYSVNfVE9fUkVH
KGJpdCkpOw0KPiA+ID4gKwkJcmV0ID0gcmVnbWFwX2J1bGtfcmVhZChkYXRhLT5yZWdtYXAsDQo+
ID4gPiArDQo+ID4gPiAgQk1DMTUwX0FDQ0VMX0FYSVNfVE9fUkVHKGJpdCksICZyYXdfdmFsLA0K
PiA+ID4gKwkJCQkgICAgICAgMik7DQo+ID4gPiAgCQlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJ
CW11dGV4X3VubG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ID4gIAkJCWdvdG8gZXJyX3JlYWQ7DQo+
ID4gPiAgCQl9DQo+ID4gPiAtCQlkYXRhLT5idWZmZXJbaSsrXSA9IHJldDsNCj4gPiA+ICsJCWRh
dGEtPmJ1ZmZlcltpKytdID0gcmF3X3ZhbDsNCj4gPiA+ICAJfQ0KPiA+ID4gIAltdXRleF91bmxv
Y2soJmRhdGEtPm11dGV4KTsNCj4gPiA+DQo+ID4gPiBAQCAtMTI0MCwxMCArMTIwNCw5IEBAIHN0
YXRpYyBpbnQgYm1jMTUwX2FjY2VsX3RyaWdfdHJ5X3JlZW4oc3RydWN0DQo+ID4gPiBpaW9fdHJp
Z2dlciAqdHJpZykNCj4gPiA+DQo+ID4gPiAgCW11dGV4X2xvY2soJmRhdGEtPm11dGV4KTsNCj4g
PiA+ICAJLyogY2xlYXIgYW55IGxhdGNoZWQgaW50ZXJydXB0ICovDQo+ID4gPiAtCXJldCA9IGky
Y19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gLQkJCQkJQk1DMTUw
X0FDQ0VMX1JFR19JTlRfUlNUX0wNCj4gPiA+IEFUQ0gsDQo+ID4gPiAtCQkJCQlCTUMxNTBfQUND
RUxfSU5UX01PREVfTEFUQw0KPiA+ID4gSF9JTlQgfA0KPiA+ID4gLQkJCQkJQk1DMTUwX0FDQ0VM
X0lOVF9NT0RFX0xBVEMNCj4gPiA+IEhfUkVTRVQpOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfd3Jp
dGUoZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfUlNUX0xBVENILA0K
PiA+ID4gKwkJCSAgIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9JTlQgfA0KPiA+ID4gKwkJ
CSAgIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9SRVNFVCk7DQo+ID4gPiAgCW11dGV4X3Vu
bG9jaygmZGF0YS0+bXV0ZXgpOw0KPiA+ID4gIAlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJZGV2
X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsDQo+ID4gPiBAQCAtMTMwMCwzNCArMTI2MywzNCBAQCBz
dGF0aWMgaW50DQo+ID4gPiBibWMxNTBfYWNjZWxfaGFuZGxlX3JvY19ldmVudChzdHJ1Y3QgaWlv
X2RldiAqaW5kaW9fZGV2KQ0KPiA+ID4gIAlzdHJ1Y3QgYm1jMTUwX2FjY2VsX2RhdGEgKmRhdGEg
PSBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ID4gIAlpbnQgZGlyOw0KPiA+ID4gIAlpbnQgcmV0
Ow0KPiA+ID4gKwl1bnNpZ25lZCBpbnQgdmFsOw0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3Nt
YnVzX3JlYWRfYnl0ZV9kYXRhKGRhdGEtPmNsaWVudCwNCj4gPiA+IC0NCj4gPiA+ICBCTUMxNTBf
QUNDRUxfUkVHX0lOVF9TVEFUVVNfMik7DQo+ID4gPiArCXJldCA9IHJlZ21hcF9yZWFkKGRhdGEt
PnJlZ21hcCwNCj4gPiA+IEJNQzE1MF9BQ0NFTF9SRUdfSU5UX1NUQVRVU18yLCAmdmFsKTsNCj4g
PiA+ICAJaWYgKHJldCA8IDApIHsNCj4gPiA+ICAJCWRldl9lcnIoJmRhdGEtPmNsaWVudC0+ZGV2
LCAiRXJyb3IgcmVhZGluZw0KPiA+ID4gcmVnX2ludF9zdGF0dXNfMlxuIik7DQo+ID4gPiAgCQly
ZXR1cm4gcmV0Ow0KPiA+ID4gIAl9DQo+ID4gPg0KPiA+ID4gLQlpZiAocmV0ICYgQk1DMTUwX0FD
Q0VMX0FOWV9NT1RJT05fQklUX1NJR04pDQo+ID4gPiArCWlmICh2YWwgJiBCTUMxNTBfQUNDRUxf
QU5ZX01PVElPTl9CSVRfU0lHTikNCj4gPiA+ICAJCWRpciA9IElJT19FVl9ESVJfRkFMTElORzsN
Cj4gPiA+ICAJZWxzZQ0KPiA+ID4gIAkJZGlyID0gSUlPX0VWX0RJUl9SSVNJTkc7DQo+ID4gPg0K
PiA+ID4gLQlpZiAocmV0ICYgQk1DMTUwX0FDQ0VMX0FOWV9NT1RJT05fQklUX1gpDQo+ID4gPiAr
CWlmICh2YWwgJiBCTUMxNTBfQUNDRUxfQU5ZX01PVElPTl9CSVRfWCkNCj4gPiA+ICAJCWlpb19w
dXNoX2V2ZW50KGluZGlvX2RldiwNCj4gPiA+IElJT19NT0RfRVZFTlRfQ09ERShJSU9fQUNDRUws
DQo+ID4gPiAgCQkJCQkJCTAsDQo+ID4gPiAgCQkJCQkJCUlJT19NT0RfWCwNCj4gPiA+ICAJCQkJ
CQkJSUlPX0VWX1RZUA0KPiA+ID4gRV9ST0MsDQo+ID4gPiAgCQkJCQkJCWRpciksDQo+ID4gPiAg
CQkJCQkJCWRhdGENCj4gPiA+IC0+dGltZXN0YW1wKTsNCj4gPiA+IC0JaWYgKHJldCAmIEJNQzE1
MF9BQ0NFTF9BTllfTU9USU9OX0JJVF9ZKQ0KPiA+ID4gKwlpZiAodmFsICYgQk1DMTUwX0FDQ0VM
X0FOWV9NT1RJT05fQklUX1kpDQo+ID4gPiAgCQlpaW9fcHVzaF9ldmVudChpbmRpb19kZXYsDQo+
ID4gPiBJSU9fTU9EX0VWRU5UX0NPREUoSUlPX0FDQ0VMLA0KPiA+ID4gIAkJCQkJCQkwLA0KPiA+
ID4gIAkJCQkJCQlJSU9fTU9EX1ksDQo+ID4gPiAgCQkJCQkJCUlJT19FVl9UWVANCj4gPiA+IEVf
Uk9DLA0KPiA+ID4gIAkJCQkJCQlkaXIpLA0KPiA+ID4gIAkJCQkJCQlkYXRhDQo+ID4gPiAtPnRp
bWVzdGFtcCk7DQo+ID4gPiAtCWlmIChyZXQgJiBCTUMxNTBfQUNDRUxfQU5ZX01PVElPTl9CSVRf
WikNCj4gPiA+ICsJaWYgKHZhbCAmIEJNQzE1MF9BQ0NFTF9BTllfTU9USU9OX0JJVF9aKQ0KPiA+
ID4gIAkJaWlvX3B1c2hfZXZlbnQoaW5kaW9fZGV2LA0KPiA+ID4gSUlPX01PRF9FVkVOVF9DT0RF
KElJT19BQ0NFTCwNCj4gPiA+ICAJCQkJCQkJMCwNCj4gPiA+ICAJCQkJCQkJSUlPX01PRF9aLA0K
PiA+ID4gQEAgLTEzNjAsMTAgKzEzMjMsOSBAQCBzdGF0aWMgaXJxcmV0dXJuX3QNCj4gPiA+IGJt
YzE1MF9hY2NlbF9pcnFfdGhyZWFkX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqcHJpdmF0ZSkNCj4g
PiA+ICAJfQ0KPiA+ID4NCj4gPiA+ICAJaWYgKGFjaykgew0KPiA+ID4gLQkJcmV0ID0gaTJjX3Nt
YnVzX3dyaXRlX2J5dGVfZGF0YShkYXRhLT5jbGllbnQsDQo+ID4gPiAtCQkJCQlCTUMxNTBfQUND
RUxfUkVHX0lOVF9SU1RfTA0KPiA+ID4gQVRDSCwNCj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9J
TlRfTU9ERV9MQVRDDQo+ID4gPiBIX0lOVCB8DQo+ID4gPiAtCQkJCQlCTUMxNTBfQUNDRUxfSU5U
X01PREVfTEFUQw0KPiA+ID4gSF9SRVNFVCk7DQo+ID4gPiArCQlyZXQgPSByZWdtYXBfd3JpdGUo
ZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfUlNUX0xBVENILA0KPiA+
ID4gKwkJCQkgICBCTUMxNTBfQUNDRUxfSU5UX01PREVfTEFUQ0hfSU5UDQo+ID4gPiB8DQo+ID4g
PiArDQo+ID4gPiAgQk1DMTUwX0FDQ0VMX0lOVF9NT0RFX0xBVENIX1JFU0VUKTsNCj4gPiA+ICAJ
CWlmIChyZXQpDQo+ID4gPiAgCQkJZGV2X2VycigmZGF0YS0+Y2xpZW50LT5kZXYsICJFcnJvciB3
cml0aW5nDQo+ID4gPiByZWdfaW50X3JzdF9sYXRjaFxuIik7DQo+ID4gPiAgCQlyZXQgPSBJUlFf
SEFORExFRDsNCj4gPiA+IEBAIC0xNTE2LDcgKzE0NzgsNyBAQCBzdGF0aWMgaW50IGJtYzE1MF9h
Y2NlbF9maWZvX3NldF9tb2RlKHN0cnVjdA0KPiA+ID4gYm1jMTUwX2FjY2VsX2RhdGEgKmRhdGEp
DQo+ID4gPiAgCXU4IHJlZyA9IEJNQzE1MF9BQ0NFTF9SRUdfRklGT19DT05GSUcxOw0KPiA+ID4g
IAlpbnQgcmV0Ow0KPiA+ID4NCj4gPiA+IC0JcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0
YShkYXRhLT5jbGllbnQsIHJlZywgZGF0YQ0KPiA+ID4gLT5maWZvX21vZGUpOw0KPiA+ID4gKwly
ZXQgPSByZWdtYXBfd3JpdGUoZGF0YS0+cmVnbWFwLCByZWcsIGRhdGEtPmZpZm9fbW9kZSk7DQo+
ID4gPiAgCWlmIChyZXQgPCAwKSB7DQo+ID4gPiAgCQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRl
diwgIkVycm9yIHdyaXRpbmcNCj4gPiA+IHJlZ19maWZvX2NvbmZpZzFcbiIpOw0KPiA+ID4gIAkJ
cmV0dXJuIHJldDsNCj4gPiA+IEBAIC0xNTI1LDkgKzE0ODcsOCBAQCBzdGF0aWMgaW50IGJtYzE1
MF9hY2NlbF9maWZvX3NldF9tb2RlKHN0cnVjdA0KPiA+ID4gYm1jMTUwX2FjY2VsX2RhdGEgKmRh
dGEpDQo+ID4gPiAgCWlmICghZGF0YS0+Zmlmb19tb2RlKQ0KPiA+ID4gIAkJcmV0dXJuIDA7DQo+
ID4gPg0KPiA+ID4gLQlyZXQgPSBpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKGRhdGEtPmNsaWVu
dCwNCj4gPiA+IC0JCQkJCUJNQzE1MF9BQ0NFTF9SRUdfRklGT19DT05GDQo+ID4gPiBJRzAsDQo+
ID4gPiAtCQkJCQlkYXRhLT53YXRlcm1hcmspOw0KPiA+ID4gKwlyZXQgPSByZWdtYXBfd3JpdGUo
ZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19GSUZPX0NPTkZJRzAsDQo+ID4g
PiArCQkJICAgZGF0YS0+d2F0ZXJtYXJrKTsNCj4gPiA+ICAJaWYgKHJldCA8IDApDQo+ID4gPiAg
CQlkZXZfZXJyKCZkYXRhLT5jbGllbnQtPmRldiwgIkVycm9yIHdyaXRpbmcNCj4gPiA+IHJlZ19m
aWZvX2NvbmZpZzBcbiIpOw0KPiA+ID4NCj4gPiA+IEBAIC0xNjI3LDYgKzE1ODgsMTMgQEAgc3Rh
dGljIGludCBibWMxNTBfYWNjZWxfcHJvYmUoc3RydWN0DQo+ID4gPiBpMmNfY2xpZW50ICpjbGll
bnQsDQo+ID4gPiAgCWRhdGEgPSBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ID4gIAlpMmNfc2V0
X2NsaWVudGRhdGEoY2xpZW50LCBpbmRpb19kZXYpOw0KPiA+ID4gIAlkYXRhLT5jbGllbnQgPSBj
bGllbnQ7DQo+ID4gPiArCWRhdGEtPmRldiA9ICZjbGllbnQtPmRldjsNCj4gPiA+ICsNCj4gPiA+
ICsJZGF0YS0+cmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMoY2xpZW50LA0KPiA+ID4gJmJt
YzE1MF9pMmNfcmVnbWFwX2NvbmYpOw0KPiA+ID4gKwlpZiAoSVNfRVJSKGRhdGEtPnJlZ21hcCkp
IHsNCj4gPiA+ICsJCWRldl9lcnIoJmNsaWVudC0+ZGV2LCAiRmFpbGVkIHRvIGluaXRpYWxpemUg
aTJjDQo+ID4gPiByZWdtYXBcbiIpOw0KPiA+ID4gKwkJcmV0dXJuIFBUUl9FUlIoZGF0YS0+cmVn
bWFwKTsNCj4gPiA+ICsJfQ0KPiA+ID4NCj4gPiA+ICAJaWYgKGlkKSB7DQo+ID4gPiAgCQluYW1l
ID0gaWQtPm5hbWU7DQo+ID4gPiBAQCAtMTY4MCw5ICsxNjQ4LDggQEAgc3RhdGljIGludCBibWMx
NTBfYWNjZWxfcHJvYmUoc3RydWN0DQo+ID4gPiBpMmNfY2xpZW50ICpjbGllbnQsDQo+ID4gPiAg
CQkgKiB3YW50IHRvIHVzZSBsYXRjaCBtb2RlIHdoZW4gd2UgY2FuIHRvIHByZXZlbnQNCj4gPiA+
IGludGVycnVwdA0KPiA+ID4gIAkJICogZmxvb2RpbmcuDQo+ID4gPiAgCQkgKi8NCj4gPiA+IC0J
CXJldCA9IGkyY19zbWJ1c193cml0ZV9ieXRlX2RhdGEoZGF0YS0+Y2xpZW50LA0KPiA+ID4gLQkJ
CQkJCUJNQzE1MF9BQ0NFTF9SRUdfSQ0KPiA+ID4gTlRfUlNUX0xBVENILA0KPiA+ID4gLQ0KPiA+
ID4gIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9SRVNFVCk7DQo+ID4gPiArCQlyZXQgPSBy
ZWdtYXBfd3JpdGUoZGF0YS0+cmVnbWFwLA0KPiA+ID4gQk1DMTUwX0FDQ0VMX1JFR19JTlRfUlNU
X0xBVENILA0KPiA+ID4gKw0KPiA+ID4gIEJNQzE1MF9BQ0NFTF9JTlRfTU9ERV9MQVRDSF9SRVNF
VCk7DQo+ID4gPiAgCQlpZiAocmV0IDwgMCkgew0KPiA+ID4gIAkJCWRldl9lcnIoJmRhdGEtPmNs
aWVudC0+ZGV2LCAiRXJyb3Igd3JpdGluZw0KPiA+ID4gcmVnX2ludF9yc3RfbGF0Y2hcbiIpOw0K
PiA+ID4gIAkJCWdvdG8gZXJyX2J1ZmZlcl9jbGVhbnVwOw0KPiA+ID4NCj4gPg0K

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

* RE: [PATCH v2 0/4] iio: bmc150 regmap and SPI
  2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
                   ` (3 preceding siblings ...)
  2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
@ 2015-09-09 14:30 ` Tirdea, Irina
  2015-09-16 10:13   ` Markus Pargmann
  4 siblings, 1 reply; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:30 UTC (permalink / raw)
  To: Markus Pargmann, Jonathan Cameron
  Cc: Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de



> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vge=
r.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 0/4] iio: bmc150 regmap and SPI
>=20
> Hi,
>=20

Hi Markus,

I tested your patches with my BMA250E driver connected on the i2c bus .
The code looks good and most of it works. There are a couple of issues I wi=
ll mention
below and in the individual patches.

The patches in this version no longer apply cleanly on the togreg branch of=
 the iio tree.
I did the rebase myself, but since there were many conflicts I will do anot=
her test
when you send the new rebased v3.

> this series converts the bmc150 driver to use regmap and adds an SPI inte=
rface.
>=20
> In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI suppo=
rt".
> It now depends on "regmap: i2c block support".
>=20

I used the patches that were already merged in the regmap tree. This bmc150=
 series should
probably wait until the regmap patches end up in Jonathan's tree, otherwise=
 they will
break the build.

Thanks,
Irina

> Changes in v2:
> - Removed default values for regmap_config fields.
> - Redesigned the fifo_transfer function to avoid running in errors first.
> - Dropped irq checks patch as it is already mainline
> - Core can now be built as module with autoselection of i2c and spi parts
>=20
> As my hardware is missing an interrupt line from the SPI connected bmc150=
 I am
> not able to test the iio buffer code path and the i2c code path. Tests wo=
uld be
> appreciated.
>=20
> Best regards,
>=20
> Markus
>=20
>=20
> Markus Pargmann (4):
>   iio: bmc150: Use i2c regmap
>   iio: bcm150: Remove i2c_client from private data
>   iio: bmc150: Split the driver into core and i2c
>   iio: bmc150: Add SPI driver
>=20
>  drivers/iio/accel/Kconfig                          |  14 +-
>  drivers/iio/accel/Makefile                         |   4 +-
>  .../accel/{bmc150-accel.c =3D> bmc150-accel-core.c}  | 398 ++++++++-----=
--------
>  drivers/iio/accel/bmc150-accel-i2c.c               |  99 +++++
>  drivers/iio/accel/bmc150-accel-spi.c               |  83 +++++
>  drivers/iio/accel/bmc150-accel.h                   |  21 ++
>  6 files changed, 367 insertions(+), 252 deletions(-)
>  rename drivers/iio/accel/{bmc150-accel.c =3D> bmc150-accel-core.c} (81%)
>  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
>  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
>  create mode 100644 drivers/iio/accel/bmc150-accel.h
>=20
> --
> 2.4.6

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

* RE: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
  2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
  2015-08-31 16:11   ` Jonathan Cameron
@ 2015-09-09 14:36   ` Tirdea, Irina
  1 sibling, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:36 UTC (permalink / raw)
  To: Markus Pargmann, Jonathan Cameron
  Cc: Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de



> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vge=
r.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 1/4] iio: bmc150: Use i2c regmap
>=20
> This replaces all usage of direct i2c accesses with regmap accesses.
>=20
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> ---

This patch works, but I would wait for the rebased version and check again.
One minor comment below.

>  drivers/iio/accel/Kconfig        |   2 +
>  drivers/iio/accel/bmc150-accel.c | 219 +++++++++++++++++----------------=
------
>  2 files changed, 95 insertions(+), 126 deletions(-)
>=20
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 00e7bcbdbe24..01dd03d194d1 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -22,6 +22,8 @@ config BMC150_ACCEL
>  	depends on I2C
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
> +	select REGMAP
> +	select REGMAP_I2C
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-=
accel.c
> index 55751d9e1ade..c5c773e75173 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -35,6 +35,7 @@
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/trigger_consumer.h>
>  #include <linux/iio/triggered_buffer.h>
> +#include <linux/regmap.h>
>=20
>  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
>  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
> @@ -185,6 +186,8 @@ enum bmc150_accel_trigger_id {
>=20
>  struct bmc150_accel_data {
>  	struct i2c_client *client;
> +	struct regmap *regmap;
> +	struct device *dev;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -241,6 +244,11 @@ static const struct {
>  				       {500000, BMC150_ACCEL_SLEEP_500_MS},
>  				       {1000000, BMC150_ACCEL_SLEEP_1_SEC} };
>=20
> +static const struct regmap_config bmc150_i2c_regmap_conf =3D {
> +	.reg_bits =3D 8,
> +	.val_bits =3D 8,
> +	.max_register =3D 0x3f,
> +};
>=20
>  static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  				 enum bmc150_power_modes mode,
> @@ -270,8 +278,7 @@ static int bmc150_accel_set_mode(struct bmc150_accel_=
data *data,
>=20
>  	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
>=20
> -	ret =3D i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
> +	ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
>  		return ret;
> @@ -289,8 +296,7 @@ static int bmc150_accel_set_bw(struct bmc150_accel_da=
ta *data, int val,
>  	for (i =3D 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) {
>  		if (bmc150_accel_samp_freq_table[i].val =3D=3D val &&
>  				bmc150_accel_samp_freq_table[i].val2 =3D=3D val2) {
> -			ret =3D i2c_smbus_write_byte_data(
> -				data->client,
> +			ret =3D regmap_write(data->regmap,
>  				BMC150_ACCEL_REG_PMU_BW,
>  				bmc150_accel_samp_freq_table[i].bw_bits);
>  			if (ret < 0)
> @@ -307,26 +313,19 @@ static int bmc150_accel_set_bw(struct bmc150_accel_=
data *data, int val,
>=20
>  static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
>  {
> -	int ret, val;
> +	int ret;
>=20
> -	ret =3D i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6,
> +	ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
>  					data->slope_thres);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error writing reg_int_6\n");
>  		return ret;
>  	}
>=20
> -	ret =3D i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5);
> +	ret =3D regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
> +				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_5\n");
> -		return ret;
> -	}
> -
> -	val =3D (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur;
> -	ret =3D i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5,
> -					val);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error write reg_int_5\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_5\n");
>  		return ret;
>  	}
>=20
> @@ -348,17 +347,18 @@ static int bmc150_accel_any_motion_setup(struct bmc=
150_accel_trigger *t,
>  static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  {
>  	int ret;
> +	unsigned int val;
>=20
> -	ret =3D i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID=
);
> +	ret =3D regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  			"Error: Reading chip id\n");
>  		return ret;
>  	}
>=20
> -	dev_dbg(&data->client->dev, "Chip Id %x\n", ret);
> -	if (ret !=3D data->chip_info->chip_id) {
> -		dev_err(&data->client->dev, "Invalid chip %x\n", ret);
> +	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> +	if (val !=3D data->chip_info->chip_id) {
> +		dev_err(&data->client->dev, "Invalid chip %x\n", val);
>  		return -ENODEV;
>  	}
>=20
> @@ -372,9 +372,8 @@ static int bmc150_accel_chip_init(struct bmc150_accel=
_data *data)
>  		return ret;
>=20
>  	/* Set Default Range */
> -	ret =3D i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_PMU_RANGE,
> -					BMC150_ACCEL_DEF_RANGE_4G);
> +	ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
> +			   BMC150_ACCEL_DEF_RANGE_4G);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  					"Error writing reg_pmu_range\n");
> @@ -391,10 +390,9 @@ static int bmc150_accel_chip_init(struct bmc150_acce=
l_data *data)
>  		return ret;
>=20
>  	/* Set default as latched interrupts */
> -	ret =3D i2c_smbus_write_byte_data(data->client,
> -					BMC150_ACCEL_REG_INT_RST_LATCH,
> -					BMC150_ACCEL_INT_MODE_LATCH_INT |
> -					BMC150_ACCEL_INT_MODE_LATCH_RESET);
> +	ret =3D regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
> +			   BMC150_ACCEL_INT_MODE_LATCH_INT |
> +			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev,
>  			"Error writing reg_int_rst_latch\n");
> @@ -527,38 +525,18 @@ static int bmc150_accel_set_interrupt(struct bmc150=
_accel_data *data, int i,
>  		return ret;
>=20
>  	/* map the interrupt to the appropriate pins */
> -	ret =3D i2c_smbus_read_byte_data(data->client, info->map_reg);
> +	ret =3D regmap_update_bits(data->regmap, info->map_reg, info->map_bitma=
sk,
> +				 (state ? info->map_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_map\n");
> -		goto out_fix_power_state;
> -	}
> -	if (state)
> -		ret |=3D info->map_bitmask;
> -	else
> -		ret &=3D ~info->map_bitmask;
> -
> -	ret =3D i2c_smbus_write_byte_data(data->client, info->map_reg,
> -					ret);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_map\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_map\n");
>  		goto out_fix_power_state;
>  	}
>=20
>  	/* enable/disable the interrupt */
> -	ret =3D i2c_smbus_read_byte_data(data->client, info->en_reg);
> +	ret =3D regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask=
,
> +				 (state ? info->en_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_en\n");
> -		goto out_fix_power_state;
> -	}
> -
> -	if (state)
> -		ret |=3D info->en_bitmask;
> -	else
> -		ret &=3D ~info->en_bitmask;
> -
> -	ret =3D i2c_smbus_write_byte_data(data->client, info->en_reg, ret);
> -	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_en\n");
> +		dev_err(&data->client->dev, "Error updating reg_int_en\n");
>  		goto out_fix_power_state;
>  	}
>=20
> @@ -581,8 +559,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel=
_data *data, int val)
>=20
>  	for (i =3D 0; i < ARRAY_SIZE(data->chip_info->scale_table); ++i) {
>  		if (data->chip_info->scale_table[i].scale =3D=3D val) {
> -			ret =3D i2c_smbus_write_byte_data(
> -				     data->client,
> +			ret =3D regmap_write(data->regmap,
>  				     BMC150_ACCEL_REG_PMU_RANGE,
>  				     data->chip_info->scale_table[i].reg_range);
>  			if (ret < 0) {
> @@ -602,16 +579,17 @@ static int bmc150_accel_set_scale(struct bmc150_acc=
el_data *data, int val)
>  static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *va=
l)
>  {
>  	int ret;
> +	unsigned int value;
>=20
>  	mutex_lock(&data->mutex);
>=20
> -	ret =3D i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP);
> +	ret =3D regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading reg_temp\n");
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> -	*val =3D sign_extend32(ret, 7);
> +	*val =3D sign_extend32(value, 7);
>=20
>  	mutex_unlock(&data->mutex);
>=20
> @@ -624,6 +602,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_=
data *data,
>  {
>  	int ret;
>  	int axis =3D chan->scan_index;
> +	unsigned int raw_val;
>=20
>  	mutex_lock(&data->mutex);
>  	ret =3D bmc150_accel_set_power_state(data, true);
> @@ -632,15 +611,15 @@ static int bmc150_accel_get_axis(struct bmc150_acce=
l_data *data,
>  		return ret;
>  	}
>=20
> -	ret =3D i2c_smbus_read_word_data(data->client,
> -				       BMC150_ACCEL_AXIS_TO_REG(axis));
> +	ret =3D regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
> +			       &raw_val, 2);
>  	if (ret < 0) {
>  		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
>  		bmc150_accel_set_power_state(data, false);
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> -	*val =3D sign_extend32(ret >> chan->scan_type.shift,
> +	*val =3D sign_extend32(raw_val >> chan->scan_type.shift,
>  			     chan->scan_type.realbits - 1);
>  	ret =3D bmc150_accel_set_power_state(data, false);
>  	mutex_unlock(&data->mutex);
> @@ -904,52 +883,34 @@ static int bmc150_accel_set_watermark(struct iio_de=
v *indio_dev, unsigned val)
>   * We must read at least one full frame in one burst, otherwise the rest=
 of the
>   * frame data is discarded.
>   */
> -static int bmc150_accel_fifo_transfer(const struct i2c_client *client,
> +static int bmc150_accel_fifo_transfer(struct bmc150_accel_data *data,
>  				      char *buffer, int samples)
>  {
>  	int sample_length =3D 3 * 2;
> -	u8 reg_fifo_data =3D BMC150_ACCEL_REG_FIFO_DATA;
> -	int ret =3D -EIO;
> -
> -	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> -		struct i2c_msg msg[2] =3D {
> -			{
> -				.addr =3D client->addr,
> -				.flags =3D 0,
> -				.buf =3D &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] 21+ messages in thread

* RE: [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data
  2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
@ 2015-09-09 14:39   ` Tirdea, Irina
  0 siblings, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:39 UTC (permalink / raw)
  To: Markus Pargmann, Jonathan Cameron
  Cc: Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de



> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data
> 
> i2c_client struct is now only used for debugging output. We can use the
> device struct as well so we can remove all struct i2c_client usage.
> 
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> Acked-by: Jonathan Cameron <jic23@kernel.org>
> ---

This patch also works (in my rebased version) .
I have tested the iio buffer code path and the i2c code path.

>  drivers/iio/accel/bmc150-accel.c | 120 +++++++++++++++++++--------------------
>  1 file changed, 58 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c
> index c5c773e75173..e4a0691d9b88 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel.c
> @@ -185,9 +185,9 @@ enum bmc150_accel_trigger_id {
>  };
> 
>  struct bmc150_accel_data {
> -	struct i2c_client *client;
>  	struct regmap *regmap;
>  	struct device *dev;
> +	int irq;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -276,11 +276,11 @@ static int bmc150_accel_set_mode(struct bmc150_accel_data *data,
>  	lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT;
>  	lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT);
> 
> -	dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits);
> +	dev_dbg(data->dev, "Set Mode bits %x\n", lpw_bits);
> 
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_LPW, lpw_bits);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n");
> +		dev_err(data->dev, "Error writing reg_pmu_lpw\n");
>  		return ret;
>  	}
> 
> @@ -318,18 +318,18 @@ static int bmc150_accel_update_slope(struct bmc150_accel_data *data)
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_6,
>  					data->slope_thres);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_int_6\n");
> +		dev_err(data->dev, "Error writing reg_int_6\n");
>  		return ret;
>  	}
> 
>  	ret = regmap_update_bits(data->regmap, BMC150_ACCEL_REG_INT_5,
>  				 BMC150_ACCEL_SLOPE_DUR_MASK, data->slope_dur);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error updating reg_int_5\n");
> +		dev_err(data->dev, "Error updating reg_int_5\n");
>  		return ret;
>  	}
> 
> -	dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres,
> +	dev_dbg(data->dev, "%s: %x %x\n", __func__, data->slope_thres,
>  		data->slope_dur);
> 
>  	return ret;
> @@ -351,14 +351,14 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
> 
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_CHIP_ID, &val);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Error: Reading chip id\n");
>  		return ret;
>  	}
> 
> -	dev_dbg(&data->client->dev, "Chip Id %x\n", val);
> +	dev_dbg(data->dev, "Chip Id %x\n", val);
>  	if (val != data->chip_info->chip_id) {
> -		dev_err(&data->client->dev, "Invalid chip %x\n", val);
> +		dev_err(data->dev, "Invalid chip %x\n", val);
>  		return -ENODEV;
>  	}
> 
> @@ -375,8 +375,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_PMU_RANGE,
>  			   BMC150_ACCEL_DEF_RANGE_4G);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> -					"Error writing reg_pmu_range\n");
> +		dev_err(data->dev, "Error writing reg_pmu_range\n");
>  		return ret;
>  	}
> 
> @@ -394,7 +393,7 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
>  			   BMC150_ACCEL_INT_MODE_LATCH_INT |
>  			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Error writing reg_int_rst_latch\n");
>  		return ret;
>  	}
> @@ -436,16 +435,16 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on)
>  	int ret;
> 
>  	if (on)
> -		ret = pm_runtime_get_sync(&data->client->dev);
> +		ret = pm_runtime_get_sync(data->dev);
>  	else {
> -		pm_runtime_mark_last_busy(&data->client->dev);
> -		ret = pm_runtime_put_autosuspend(&data->client->dev);
> +		pm_runtime_mark_last_busy(data->dev);
> +		ret = pm_runtime_put_autosuspend(data->dev);
>  	}
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Failed: bmc150_accel_set_power_state for %d\n", on);
>  		if (on)
> -			pm_runtime_put_noidle(&data->client->dev);
> +			pm_runtime_put_noidle(data->dev);
> 
>  		return ret;
>  	}
> @@ -528,7 +527,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
>  	ret = regmap_update_bits(data->regmap, info->map_reg, info->map_bitmask,
>  				 (state ? info->map_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error updating reg_int_map\n");
> +		dev_err(data->dev, "Error updating reg_int_map\n");
>  		goto out_fix_power_state;
>  	}
> 
> @@ -536,7 +535,7 @@ static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i,
>  	ret = regmap_update_bits(data->regmap, info->en_reg, info->en_bitmask,
>  				 (state ? info->en_bitmask : 0));
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error updating reg_int_en\n");
> +		dev_err(data->dev, "Error updating reg_int_en\n");
>  		goto out_fix_power_state;
>  	}
> 
> @@ -563,7 +562,7 @@ static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val)
>  				     BMC150_ACCEL_REG_PMU_RANGE,
>  				     data->chip_info->scale_table[i].reg_range);
>  			if (ret < 0) {
> -				dev_err(&data->client->dev,
> +				dev_err(data->dev,
>  					"Error writing pmu_range\n");
>  				return ret;
>  			}
> @@ -585,7 +584,7 @@ static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val)
> 
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_TEMP, &value);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_temp\n");
> +		dev_err(data->dev, "Error reading reg_temp\n");
>  		mutex_unlock(&data->mutex);
>  		return ret;
>  	}
> @@ -614,7 +613,7 @@ static int bmc150_accel_get_axis(struct bmc150_accel_data *data,
>  	ret = regmap_bulk_read(data->regmap, BMC150_ACCEL_AXIS_TO_REG(axis),
>  			       &raw_val, 2);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading axis %d\n", axis);
> +		dev_err(data->dev, "Error reading axis %d\n", axis);
>  		bmc150_accel_set_power_state(data, false);
>  		mutex_unlock(&data->mutex);
>  		return ret;
> @@ -928,7 +927,7 @@ static int __bmc150_accel_fifo_flush(struct iio_dev *indio_dev,
> 
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_FIFO_STATUS, &val);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_fifo_status\n");
> +		dev_err(data->dev, "Error reading reg_fifo_status\n");
>  		return ret;
>  	}
> 
> @@ -1209,7 +1208,7 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig)
>  			   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  	mutex_unlock(&data->mutex);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev,
> +		dev_err(data->dev,
>  			"Error writing reg_int_rst_latch\n");
>  		return ret;
>  	}
> @@ -1267,7 +1266,7 @@ static int bmc150_accel_handle_roc_event(struct iio_dev *indio_dev)
> 
>  	ret = regmap_read(data->regmap, BMC150_ACCEL_REG_INT_STATUS_2, &val);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error reading reg_int_status_2\n");
> +		dev_err(data->dev, "Error reading reg_int_status_2\n");
>  		return ret;
>  	}
> 
> @@ -1327,7 +1326,7 @@ static irqreturn_t bmc150_accel_irq_thread_handler(int irq, void *private)
>  				   BMC150_ACCEL_INT_MODE_LATCH_INT |
>  				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  		if (ret)
> -			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> +			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
>  		ret = IRQ_HANDLED;
>  	} else {
>  		ret = IRQ_NONE;
> @@ -1379,17 +1378,13 @@ static const char *bmc150_accel_match_acpi_device(struct device *dev, int *data)
>  	return dev_name(dev);
>  }
> 
> -static int bmc150_accel_gpio_probe(struct i2c_client *client,
> -					struct bmc150_accel_data *data)
> +static int bmc150_accel_gpio_probe(struct bmc150_accel_data *data)
>  {
>  	struct device *dev;
>  	struct gpio_desc *gpio;
>  	int ret;
> 
> -	if (!client)
> -		return -EINVAL;
> -
> -	dev = &client->dev;
> +	dev = data->dev;
> 
>  	/* data ready gpio interrupt pin */
>  	gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN);
> @@ -1442,7 +1437,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
>  	for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) {
>  		struct bmc150_accel_trigger *t = &data->triggers[i];
> 
> -		t->indio_trig = devm_iio_trigger_alloc(&data->client->dev,
> +		t->indio_trig = devm_iio_trigger_alloc(data->dev,
>  					       bmc150_accel_triggers[i].name,
>  						       indio_dev->name,
>  						       indio_dev->id);
> @@ -1451,7 +1446,7 @@ static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev,
>  			break;
>  		}
> 
> -		t->indio_trig->dev.parent = &data->client->dev;
> +		t->indio_trig->dev.parent = data->dev;
>  		t->indio_trig->ops = &bmc150_accel_trigger_ops;
>  		t->intr = bmc150_accel_triggers[i].intr;
>  		t->data = data;
> @@ -1480,7 +1475,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
> 
>  	ret = regmap_write(data->regmap, reg, data->fifo_mode);
>  	if (ret < 0) {
> -		dev_err(&data->client->dev, "Error writing reg_fifo_config1\n");
> +		dev_err(data->dev, "Error writing reg_fifo_config1\n");
>  		return ret;
>  	}
> 
> @@ -1490,7 +1485,7 @@ static int bmc150_accel_fifo_set_mode(struct bmc150_accel_data *data)
>  	ret = regmap_write(data->regmap, BMC150_ACCEL_REG_FIFO_CONFIG0,
>  			   data->watermark);
>  	if (ret < 0)
> -		dev_err(&data->client->dev, "Error writing reg_fifo_config0\n");
> +		dev_err(data->dev, "Error writing reg_fifo_config0\n");
> 
>  	return ret;
>  }
> @@ -1580,6 +1575,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  	int ret;
>  	const char *name = NULL;
>  	int chip_id = 0;
> +	struct device *dev;
> 
>  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>  	if (!indio_dev)
> @@ -1587,12 +1583,13 @@ static int bmc150_accel_probe(struct i2c_client *client,
> 
>  	data = iio_priv(indio_dev);
>  	i2c_set_clientdata(client, indio_dev);
> -	data->client = client;
>  	data->dev = &client->dev;
> +	dev = &client->dev;
> +	data->irq = client->irq;
> 
>  	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
>  	if (IS_ERR(data->regmap)) {
> -		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> +		dev_err(dev, "Failed to initialize i2c regmap\n");
>  		return PTR_ERR(data->regmap);
>  	}
> 
> @@ -1601,8 +1598,8 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		chip_id = id->driver_data;
>  	}
> 
> -	if (ACPI_HANDLE(&client->dev))
> -		name = bmc150_accel_match_acpi_device(&client->dev, &chip_id);
> +	if (ACPI_HANDLE(dev))
> +		name = bmc150_accel_match_acpi_device(dev, &chip_id);
> 
>  	data->chip_info = &bmc150_accel_chip_info_tbl[chip_id];
> 
> @@ -1612,7 +1609,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> 
>  	mutex_init(&data->mutex);
> 
> -	indio_dev->dev.parent = &client->dev;
> +	indio_dev->dev.parent = dev;
>  	indio_dev->channels = data->chip_info->channels;
>  	indio_dev->num_channels = data->chip_info->num_channels;
>  	indio_dev->name = name;
> @@ -1624,16 +1621,16 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  					 bmc150_accel_trigger_handler,
>  					 &bmc150_accel_buffer_ops);
>  	if (ret < 0) {
> -		dev_err(&client->dev, "Failed: iio triggered buffer setup\n");
> +		dev_err(data->dev, "Failed: iio triggered buffer setup\n");
>  		return ret;
>  	}
> 
> -	if (client->irq < 0)
> -		client->irq = bmc150_accel_gpio_probe(client, data);
> +	if (data->irq <= 0)
> +		data->irq = bmc150_accel_gpio_probe(data);
> 
> -	if (client->irq > 0) {
> +	if (data->irq > 0) {
>  		ret = devm_request_threaded_irq(
> -						&client->dev, client->irq,
> +						data->dev, data->irq,
>  						bmc150_accel_irq_handler,
>  						bmc150_accel_irq_thread_handler,
>  						IRQF_TRIGGER_RISING,
> @@ -1651,7 +1648,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		ret = regmap_write(data->regmap, BMC150_ACCEL_REG_INT_RST_LATCH,
>  				   BMC150_ACCEL_INT_MODE_LATCH_RESET);
>  		if (ret < 0) {
> -			dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n");
> +			dev_err(data->dev, "Error writing reg_int_rst_latch\n");
>  			goto err_buffer_cleanup;
>  		}
> 
> @@ -1672,18 +1669,17 @@ static int bmc150_accel_probe(struct i2c_client *client,
> 
>  	ret = iio_device_register(indio_dev);
>  	if (ret < 0) {
> -		dev_err(&client->dev, "Unable to register iio device\n");
> +		dev_err(data->dev, "Unable to register iio device\n");
>  		goto err_trigger_unregister;
>  	}
> 
> -	ret = pm_runtime_set_active(&client->dev);
> +	ret = pm_runtime_set_active(dev);
>  	if (ret)
>  		goto err_iio_unregister;
> 
> -	pm_runtime_enable(&client->dev);
> -	pm_runtime_set_autosuspend_delay(&client->dev,
> -					 BMC150_AUTO_SUSPEND_DELAY_MS);
> -	pm_runtime_use_autosuspend(&client->dev);
> +	pm_runtime_enable(dev);
> +	pm_runtime_set_autosuspend_delay(dev, BMC150_AUTO_SUSPEND_DELAY_MS);
> +	pm_runtime_use_autosuspend(dev);
> 
>  	return 0;
> 
> @@ -1702,9 +1698,9 @@ static int bmc150_accel_remove(struct i2c_client *client)
>  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> 
> -	pm_runtime_disable(&client->dev);
> -	pm_runtime_set_suspended(&client->dev);
> -	pm_runtime_put_noidle(&client->dev);
> +	pm_runtime_disable(data->dev);
> +	pm_runtime_set_suspended(data->dev);
> +	pm_runtime_put_noidle(data->dev);
> 
>  	iio_device_unregister(indio_dev);
> 
> @@ -1722,7 +1718,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
>  #ifdef CONFIG_PM_SLEEP
>  static int bmc150_accel_suspend(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> 
>  	mutex_lock(&data->mutex);
> @@ -1734,7 +1730,7 @@ static int bmc150_accel_suspend(struct device *dev)
> 
>  static int bmc150_accel_resume(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> 
>  	mutex_lock(&data->mutex);
> @@ -1750,11 +1746,11 @@ static int bmc150_accel_resume(struct device *dev)
>  #ifdef CONFIG_PM
>  static int bmc150_accel_runtime_suspend(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  	int ret;
> 
> -	dev_dbg(&data->client->dev,  __func__);
> +	dev_dbg(data->dev,  __func__);
>  	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0);
>  	if (ret < 0)
>  		return -EAGAIN;
> @@ -1764,12 +1760,12 @@ static int bmc150_accel_runtime_suspend(struct device *dev)
> 
>  static int bmc150_accel_runtime_resume(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
>  	int ret;
>  	int sleep_val;
> 
> -	dev_dbg(&data->client->dev,  __func__);
> +	dev_dbg(data->dev,  __func__);
> 
>  	ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0);
>  	if (ret < 0)
> --
> 2.4.6


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

* RE: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
  2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
  2015-08-31 16:15   ` Jonathan Cameron
@ 2015-09-09 14:45   ` Tirdea, Irina
  1 sibling, 0 replies; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-09 14:45 UTC (permalink / raw)
  To: Markus Pargmann, Jonathan Cameron
  Cc: Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de



> -----Original Message-----
> From: Markus Pargmann [mailto:mpa@pengutronix.de]
> Sent: 20 August, 2015 15:50
> To: Jonathan Cameron
> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; Markus Pargmann
> Subject: [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c
> 
> Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> ---
>  drivers/iio/accel/Kconfig                          |  9 +-
>  drivers/iio/accel/Makefile                         |  3 +-
>  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 95 ++++-----------------
>  drivers/iio/accel/bmc150-accel-i2c.c               | 99 ++++++++++++++++++++++
>  drivers/iio/accel/bmc150-accel.h                   | 21 +++++
>  5 files changed, 144 insertions(+), 83 deletions(-)
>  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (95%)
>  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
>  create mode 100644 drivers/iio/accel/bmc150-accel.h
> 
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 01dd03d194d1..6da4eb0db57b 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -19,21 +19,22 @@ config BMA180
> 
>  config BMC150_ACCEL
>  	tristate "Bosch BMC150 Accelerometer Driver"
> -	depends on I2C
>  	select IIO_BUFFER
>  	select IIO_TRIGGERED_BUFFER
>  	select REGMAP
> -	select REGMAP_I2C
> +	select BMC150_ACCEL_I2C if I2C
>  	help
>  	  Say yes here to build support for the following Bosch accelerometers:
>  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> 
> -	  Currently this only supports the device via an i2c interface.
> -
>  	  This is a combo module with both accelerometer and magnetometer.
>  	  This driver is only implementing accelerometer part, which has
>  	  its own address and register map.
> 
> +config BMC150_ACCEL_I2C
> +	tristate
> +	select REGMAP_I2C
> +
>  config HID_SENSOR_ACCEL_3D
>  	depends on HID_SENSOR_HUB
>  	select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index ebd2675b2a02..5ef8bdbad092 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -4,7 +4,8 @@
> 
>  # When adding new entries keep the list in alphabetical order
>  obj-$(CONFIG_BMA180) += bma180.o
> -obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o
> +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> +obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
>  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
>  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
>  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel-core.c
> similarity index 95%
> rename from drivers/iio/accel/bmc150-accel.c
> rename to drivers/iio/accel/bmc150-accel-core.c
> index e4a0691d9b88..614cf61f0110 100644
> --- a/drivers/iio/accel/bmc150-accel.c
> +++ b/drivers/iio/accel/bmc150-accel-core.c
> @@ -37,6 +37,8 @@
>  #include <linux/iio/triggered_buffer.h>
>  #include <linux/regmap.h>
> 
> +#include "bmc150-accel.h"
> +
>  #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
>  #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
>  #define BMC150_ACCEL_GPIO_NAME			"bmc150_accel_int"
> @@ -187,7 +189,6 @@ enum bmc150_accel_trigger_id {
>  struct bmc150_accel_data {
>  	struct regmap *regmap;
>  	struct device *dev;
> -	int irq;
>  	struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS];
>  	atomic_t active_intr;
>  	struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS];
> @@ -201,6 +202,7 @@ struct bmc150_accel_data {
>  	int ev_enable_state;
>  	int64_t timestamp, old_timestamp; /* Only used in hw fifo mode. */
>  	const struct bmc150_accel_chip_info *chip_info;
> +	int irq;
>  };
> 
>  static const struct {
> @@ -1070,15 +1072,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
>  static const struct iio_chan_spec bma280_accel_channels[] =
>  	BMC150_ACCEL_CHANNELS(14);
> 
> -enum {
> -	bmc150,
> -	bmi055,
> -	bma255,
> -	bma250e,
> -	bma222e,
> -	bma280,
> -};
> -
>  static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
>  	[bmc150] = {
>  		.chip_id = 0xFA,
> @@ -1567,36 +1560,22 @@ static const struct iio_buffer_setup_ops bmc150_accel_buffer_ops = {
>  	.postdisable = bmc150_accel_buffer_postdisable,
>  };
> 
> -static int bmc150_accel_probe(struct i2c_client *client,
> -			      const struct i2c_device_id *id)
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> +			    const char *name, int chip_id, bool block_supported)
>  {
>  	struct bmc150_accel_data *data;
>  	struct iio_dev *indio_dev;
>  	int ret;
> -	const char *name = NULL;
> -	int chip_id = 0;
> -	struct device *dev;
> 
> -	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
>  	if (!indio_dev)
>  		return -ENOMEM;
> 
>  	data = iio_priv(indio_dev);
> -	i2c_set_clientdata(client, indio_dev);
> -	data->dev = &client->dev;
> -	dev = &client->dev;
> -	data->irq = client->irq;
> -
> -	data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> -	if (IS_ERR(data->regmap)) {
> -		dev_err(dev, "Failed to initialize i2c regmap\n");
> -		return PTR_ERR(data->regmap);
> -	}
> -
> -	if (id) {
> -		name = id->name;
> -		chip_id = id->driver_data;
> -	}
> +	dev_set_drvdata(dev, indio_dev);
> +	data->dev = dev;
> +	data->irq = irq;
> +	data->regmap = regmap;
> 
>  	if (ACPI_HANDLE(dev))
>  		name = bmc150_accel_match_acpi_device(dev, &chip_id);
> @@ -1658,9 +1637,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
>  		if (ret)
>  			goto err_buffer_cleanup;
> 
> -		if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> -		    i2c_check_functionality(client->adapter,
> -					    I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
> +		if (block_supported) {
>  			indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
>  			indio_dev->info = &bmc150_accel_info_fifo;
>  			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
> @@ -1669,7 +1646,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
> 
>  	ret = iio_device_register(indio_dev);
>  	if (ret < 0) {
> -		dev_err(data->dev, "Unable to register iio device\n");
> +		dev_err(dev, "Unable to register iio device\n");
>  		goto err_trigger_unregister;
>  	}
> 
> @@ -1692,10 +1669,11 @@ err_buffer_cleanup:
> 
>  	return ret;
>  }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_probe);
> 
> -static int bmc150_accel_remove(struct i2c_client *client)
> +int bmc150_accel_core_remove(struct device *dev)
>  {
> -	struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
>  	struct bmc150_accel_data *data = iio_priv(indio_dev);
> 
>  	pm_runtime_disable(data->dev);
> @@ -1714,6 +1692,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
> 
>  	return 0;
>  }
> +EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
> 
>  #ifdef CONFIG_PM_SLEEP
>  static int bmc150_accel_suspend(struct device *dev)
> @@ -1784,48 +1763,8 @@ static int bmc150_accel_runtime_resume(struct device *dev)
>  }
>  #endif
> 
> -static const struct dev_pm_ops bmc150_accel_pm_ops = {
> +const struct dev_pm_ops bmc150_accel_pm_ops = {
>  	SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
>  	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
>  			   bmc150_accel_runtime_resume, NULL)
>  };
> -
> -static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> -	{"BSBA0150",	bmc150},
> -	{"BMC150A",	bmc150},
> -	{"BMI055A",	bmi055},
> -	{"BMA0255",	bma255},
> -	{"BMA250E",	bma250e},
> -	{"BMA222E",	bma222e},
> -	{"BMA0280",	bma280},
> -	{ },
> -};
> -MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> -
> -static const struct i2c_device_id bmc150_accel_id[] = {
> -	{"bmc150_accel",	bmc150},
> -	{"bmi055_accel",	bmi055},
> -	{"bma255",		bma255},
> -	{"bma250e",		bma250e},
> -	{"bma222e",		bma222e},
> -	{"bma280",		bma280},
> -	{}
> -};
> -
> -MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> -
> -static struct i2c_driver bmc150_accel_driver = {
> -	.driver = {
> -		.name	= BMC150_ACCEL_DRV_NAME,
> -		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> -		.pm	= &bmc150_accel_pm_ops,
> -	},
> -	.probe		= bmc150_accel_probe,
> -	.remove		= bmc150_accel_remove,
> -	.id_table	= bmc150_accel_id,
> -};
> -module_i2c_driver(bmc150_accel_driver);
> -
> -MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> -MODULE_LICENSE("GPL v2");
> -MODULE_DESCRIPTION("BMC150 accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel-i2c.c b/drivers/iio/accel/bmc150-accel-i2c.c
> new file mode 100644
> index 000000000000..e4dd596ba8f2
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel-i2c.c
> @@ -0,0 +1,99 @@
> +/*
> + * 3-axis accelerometer driver supporting following I2C Bosch-Sensortec chips:
> + *  - BMC150
> + *  - BMI055
> + *  - BMA255
> + *  - BMA250E
> + *  - BMA222E
> + *  - BMA280
> + *
> + * Copyright (c) 2014, Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/regmap.h>
> +
> +#include "bmc150-accel.h"
> +
> +static const struct regmap_config bmc150_i2c_regmap_conf = {
> +	.reg_bits = 8,
> +	.val_bits = 8,
> +};
> +
> +static int bmc150_accel_probe(struct i2c_client *client,
> +			      const struct i2c_device_id *id)
> +{
> +	struct regmap *regmap;
> +	bool block_supported =
> +		i2c_check_functionality(client->adapter, I2C_FUNC_I2C) ||
> +		i2c_check_functionality(client->adapter,
> +					I2C_FUNC_SMBUS_READ_I2C_BLOCK);
> +
> +	regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf);
> +	if (IS_ERR(regmap)) {
> +		dev_err(&client->dev, "Failed to initialize i2c regmap\n");
> +		return PTR_ERR(regmap);
> +	}
> +
> +	return bmc150_accel_core_probe(&client->dev, regmap, client->irq,
> +				       id->name, id->driver_data,
> +				       block_supported);
> +}

For ACPI, id will be NULL and the call above will dereference a NULL pointer.
The original code was checking if id is NULL:   
 -	if (id) {
 -		name = id->name;
 -		chip_id = id->driver_data;
 -	}
Please note that the initialization of name and chip_id has changed in the
current version of bmc150.

Thanks,
Irina

> +
> +static int bmc150_accel_remove(struct i2c_client *client)
> +{
> +	return bmc150_accel_core_remove(&client->dev);
> +}
> +
> +static const struct acpi_device_id bmc150_accel_acpi_match[] = {
> +	{"BSBA0150",	bmc150},
> +	{"BMC150A",	bmc150},
> +	{"BMI055A",	bmi055},
> +	{"BMA0255",	bma255},
> +	{"BMA250E",	bma250e},
> +	{"BMA222E",	bma222e},
> +	{"BMA0280",	bma280},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
> +
> +static const struct i2c_device_id bmc150_accel_id[] = {
> +	{"bmc150_accel",	bmc150},
> +	{"bmi055_accel",	bmi055},
> +	{"bma255",		bma255},
> +	{"bma250e",		bma250e},
> +	{"bma222e",		bma222e},
> +	{"bma280",		bma280},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id);
> +
> +static struct i2c_driver bmc150_accel_driver = {
> +	.driver = {
> +		.name	= "bmc150_accel_i2c",
> +		.acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match),
> +		.pm	= &bmc150_accel_pm_ops,
> +	},
> +	.probe		= bmc150_accel_probe,
> +	.remove		= bmc150_accel_remove,
> +	.id_table	= bmc150_accel_id,
> +};
> +module_i2c_driver(bmc150_accel_driver);
> +
> +MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("BMC150 I2C accelerometer driver");
> diff --git a/drivers/iio/accel/bmc150-accel.h b/drivers/iio/accel/bmc150-accel.h
> new file mode 100644
> index 000000000000..988b57573d0c
> --- /dev/null
> +++ b/drivers/iio/accel/bmc150-accel.h
> @@ -0,0 +1,21 @@
> +#ifndef _BMC150_ACCEL_H_
> +#define _BMC150_ACCEL_H_
> +
> +struct regmap;
> +
> +enum {
> +	bmc150,
> +	bmi055,
> +	bma255,
> +	bma250e,
> +	bma222e,
> +	bma280,
> +};
> +
> +int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
> +			    const char *name, int chip_id,
> +			    bool block_supported);
> +int bmc150_accel_core_remove(struct device *dev);
> +extern const struct dev_pm_ops bmc150_accel_pm_ops;
> +
> +#endif  /* _BMC150_ACCEL_H_ */
> --
> 2.4.6


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

* Re: [PATCH v2 4/4] iio: bmc150: Add SPI driver
  2015-09-01 14:10     ` Srinivas Pandruvada
@ 2015-09-16 10:01       ` Markus Pargmann
  0 siblings, 0 replies; 21+ messages in thread
From: Markus Pargmann @ 2015-09-16 10:01 UTC (permalink / raw)
  To: Srinivas Pandruvada
  Cc: Jonathan Cameron, Irina Tirdea, Lars-Peter Clausen, linux-iio,
	linux-kernel, kernel

[-- Attachment #1: Type: text/plain, Size: 6002 bytes --]

On Tue, Sep 01, 2015 at 07:10:57AM -0700, Srinivas Pandruvada wrote:
> On Mon, 2015-08-31 at 17:18 +0100, Jonathan Cameron wrote:
> > On 20/08/15 13:49, Markus Pargmann wrote:
> > > Add a simple SPI driver which initializes the spi regmap for the 
> > > bmc150
> > > core driver.
> > > 
> > > Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
> > Looks good to me, but clearly will have to wait for the earlier
> > patches in the series.
> > 
> > Nearly there!
> > 
> > Jonathan
> > > ---
> > >  drivers/iio/accel/Kconfig            |  5 +++
> > >  drivers/iio/accel/Makefile           |  1 +
> > >  drivers/iio/accel/bmc150-accel-spi.c | 83 
> > > ++++++++++++++++++++++++++++++++++++
> > >  3 files changed, 89 insertions(+)
> > >  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> > > 
> > > diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> > > index 6da4eb0db57b..56d24fa3d34a 100644
> > > --- a/drivers/iio/accel/Kconfig
> > > +++ b/drivers/iio/accel/Kconfig
> > > @@ -23,6 +23,7 @@ config BMC150_ACCEL
> > >  	select IIO_TRIGGERED_BUFFER
> > >  	select REGMAP
> > >  	select BMC150_ACCEL_I2C if I2C
> > > +	select BMC150_ACCEL_SPI if SPI
> > >  	help
> > >  	  Say yes here to build support for the following Bosch 
> > > accelerometers:
> > >  	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
> > > @@ -35,6 +36,10 @@ config BMC150_ACCEL_I2C
> > >  	tristate
> > >  	select REGMAP_I2C
> > >  
> > > +config BMC150_ACCEL_SPI
> > > +	tristate
> > > +	select REGMAP_SPI
> > > +
> > >  config HID_SENSOR_ACCEL_3D
> > >  	depends on HID_SENSOR_HUB
> > >  	select IIO_BUFFER
> > > diff --git a/drivers/iio/accel/Makefile 
> > > b/drivers/iio/accel/Makefile
> > > index 5ef8bdbad092..e579e93bf022 100644
> > > --- a/drivers/iio/accel/Makefile
> > > +++ b/drivers/iio/accel/Makefile
> > > @@ -6,6 +6,7 @@
> > >  obj-$(CONFIG_BMA180) += bma180.o
> > >  obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> > >  obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> > > +obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> > >  obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> > >  obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> > >  obj-$(CONFIG_KXSD9)	+= kxsd9.o
> > > diff --git a/drivers/iio/accel/bmc150-accel-spi.c 
> > > b/drivers/iio/accel/bmc150-accel-spi.c
> > > new file mode 100644
> > > index 000000000000..1c2a4f683da4
> > > --- /dev/null
> > > +++ b/drivers/iio/accel/bmc150-accel-spi.c
> > > @@ -0,0 +1,83 @@
> > > +/*
> > > + * 3-axis accelerometer driver supporting following I2C Bosch
> > > -Sensortec chips:
> > > + *  - BMC150
> > > + *  - BMI055
> > > + *  - BMA255
> > > + *  - BMA250E
> > > + *  - BMA222E
> > > + *  - BMA280
> > > + *
> > > + * Copyright (c) 2014, Intel Corporation.
> > > + *
> > > + * This program is free software; you can redistribute it and/or 
> > > modify it
> > > + * under the terms and conditions of the GNU General Public 
> > > License,
> > > + * version 2, as published by the Free Software Foundation.
> > > + *
> > > + * This program is distributed in the hope it will be useful, but 
> > > WITHOUT
> > > + * ANY WARRANTY; without even the implied warranty of 
> > > MERCHANTABILITY or
> > > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public 
> > > License for
> > > + * more details.
> > > + */
> Not sure If you want to carry Intel Copyright for SPI driver part. If
> you want to use change the year to 2015.

Thanks, will replace that.

Best Regards,

Markus

> > > +
> > > +#include <linux/device.h>
> > > +#include <linux/mod_devicetable.h>
> > > +#include <linux/module.h>
> > > +#include <linux/acpi.h>
> > > +#include <linux/regmap.h>
> > > +#include <linux/spi/spi.h>
> > > +
> > > +#include "bmc150-accel.h"
> > > +
> > > +static const struct regmap_config bmc150_spi_regmap_conf = {
> > > +	.reg_bits = 8,
> > > +	.val_bits = 8,
> > > +	.max_register = 0x3f,
> > > +};
> > > +
> > > +static int bmc150_accel_probe(struct spi_device *spi)
> > > +{
> > > +	struct regmap *regmap;
> > > +	const struct spi_device_id *id = spi_get_device_id(spi);
> > > +
> > > +	regmap = devm_regmap_init_spi(spi, 
> > > &bmc150_spi_regmap_conf);
> > > +	if (IS_ERR(regmap)) {
> > > +		dev_err(&spi->dev, "Failed to initialize spi 
> > > regmap\n");
> > > +		return PTR_ERR(regmap);
> > > +	}
> > > +
> > > +	return bmc150_accel_core_probe(&spi->dev, regmap, spi
> > > ->irq,
> > > +				       id->name, id->driver_data, 
> > > true);
> > > +}
> > > +
> > > +static int bmc150_accel_remove(struct spi_device *spi)
> > > +{
> > > +	return bmc150_accel_core_remove(&spi->dev);
> > > +}
> > > +
> > > +static const struct spi_device_id bmc150_accel_id[] = {
> > > +	{"bmc150_accel",	bmc150},
> > > +	{"bmi055_accel",	bmi055},
> > > +	{"bma255",		bma255},
> > > +	{"bma250e",		bma250e},
> > > +	{"bma222e",		bma222e},
> > > +	{"bma280",		bma280},
> > > +	{}
> > > +};
> > > +
> > > +MODULE_DEVICE_TABLE(spi, bmc150_accel_id);
> > > +
> > > +static struct spi_driver bmc150_accel_driver = {
> > > +	.driver = {
> > > +		.name	= "bmc150_accel_spi",
> > > +		.acpi_match_table = 
> > > ACPI_PTR(bmc150_accel_acpi_match),
> > > +		.pm	= &bmc150_accel_pm_ops,
> > > +	},
> > > +	.probe		= bmc150_accel_probe,
> > > +	.remove		= bmc150_accel_remove,
> > > +	.id_table	= bmc150_accel_id,
> > > +};
> > > +module_spi_driver(bmc150_accel_driver);
> > > +
> > > +MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>");
> > > +MODULE_LICENSE("GPL v2");
> > > +MODULE_DESCRIPTION("BMC150 SPI accelerometer driver");
> > > 
> > 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
  2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
@ 2015-09-16 10:13   ` Markus Pargmann
  2015-09-23 12:44     ` Tirdea, Irina
  0 siblings, 1 reply; 21+ messages in thread
From: Markus Pargmann @ 2015-09-16 10:13 UTC (permalink / raw)
  To: Tirdea, Irina
  Cc: Jonathan Cameron, Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de

[-- Attachment #1: Type: text/plain, Size: 3466 bytes --]

Hi Irina,

On Wed, Sep 09, 2015 at 02:30:30PM +0000, Tirdea, Irina wrote:
> 
> 
> > -----Original Message-----
> > From: Markus Pargmann [mailto:mpa@pengutronix.de]
> > Sent: 20 August, 2015 15:50
> > To: Jonathan Cameron
> > Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
> > kernel@pengutronix.de; Markus Pargmann
> > Subject: [PATCH v2 0/4] iio: bmc150 regmap and SPI
> > 
> > Hi,
> > 
> 
> Hi Markus,
> 
> I tested your patches with my BMA250E driver connected on the i2c bus .
> The code looks good and most of it works. There are a couple of issues I will mention
> below and in the individual patches.
> 
> The patches in this version no longer apply cleanly on the togreg branch of the iio tree.
> I did the rebase myself, but since there were many conflicts I will do another test
> when you send the new rebased v3.

Thank you for review and testing. I will integrate your comments and
send a rebased v3.

> 
> > this series converts the bmc150 driver to use regmap and adds an SPI interface.
> > 
> > In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI support".
> > It now depends on "regmap: i2c block support".
> > 
> 
> I used the patches that were already merged in the regmap tree. This bmc150 series should
> probably wait until the regmap patches end up in Jonathan's tree, otherwise they will
> break the build.

It seems the necessary patches are already in v4.3-rc1:
	29332534e2b6 (regmap-i2c: Add smbus i2c block support)

Best Regards,

Markus

> 
> Thanks,
> Irina
> 
> > Changes in v2:
> > - Removed default values for regmap_config fields.
> > - Redesigned the fifo_transfer function to avoid running in errors first.
> > - Dropped irq checks patch as it is already mainline
> > - Core can now be built as module with autoselection of i2c and spi parts
> > 
> > As my hardware is missing an interrupt line from the SPI connected bmc150 I am
> > not able to test the iio buffer code path and the i2c code path. Tests would be
> > appreciated.
> > 
> > Best regards,
> > 
> > Markus
> > 
> > 
> > Markus Pargmann (4):
> >   iio: bmc150: Use i2c regmap
> >   iio: bcm150: Remove i2c_client from private data
> >   iio: bmc150: Split the driver into core and i2c
> >   iio: bmc150: Add SPI driver
> > 
> >  drivers/iio/accel/Kconfig                          |  14 +-
> >  drivers/iio/accel/Makefile                         |   4 +-
> >  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 398 ++++++++-------------
> >  drivers/iio/accel/bmc150-accel-i2c.c               |  99 +++++
> >  drivers/iio/accel/bmc150-accel-spi.c               |  83 +++++
> >  drivers/iio/accel/bmc150-accel.h                   |  21 ++
> >  6 files changed, 367 insertions(+), 252 deletions(-)
> >  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (81%)
> >  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
> >  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
> >  create mode 100644 drivers/iio/accel/bmc150-accel.h
> > 
> > --
> > 2.4.6
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

* RE: [PATCH v2 0/4] iio: bmc150 regmap and SPI
  2015-09-16 10:13   ` Markus Pargmann
@ 2015-09-23 12:44     ` Tirdea, Irina
  2015-09-27 15:58       ` Jonathan Cameron
  0 siblings, 1 reply; 21+ messages in thread
From: Tirdea, Irina @ 2015-09-23 12:44 UTC (permalink / raw)
  To: Markus Pargmann
  Cc: Jonathan Cameron, Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogTWFya3VzIFBhcmdtYW5u
IFttYWlsdG86bXBhQHBlbmd1dHJvbml4LmRlXQ0KPiBTZW50OiAxNiBTZXB0ZW1iZXIsIDIwMTUg
MTM6MTMNCj4gVG86IFRpcmRlYSwgSXJpbmENCj4gQ2M6IEpvbmF0aGFuIENhbWVyb247IFNyaW5p
dmFzIFBhbmRydXZhZGE7IExhcnMtUGV0ZXIgQ2xhdXNlbjsgbGludXgtaWlvQHZnZXIua2VybmVs
Lm9yZzsgbGludXgta2VybmVsQHZnZXIua2VybmVsLm9yZzsNCj4ga2VybmVsQHBlbmd1dHJvbml4
LmRlDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjIgMC80XSBpaW86IGJtYzE1MCByZWdtYXAgYW5k
IFNQSQ0KPiANCj4gSGkgSXJpbmEsDQo+IA0KPiBPbiBXZWQsIFNlcCAwOSwgMjAxNSBhdCAwMjoz
MDozMFBNICswMDAwLCBUaXJkZWEsIElyaW5hIHdyb3RlOg0KPiA+DQo+ID4NCj4gPiA+IC0tLS0t
T3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4gPiBGcm9tOiBNYXJrdXMgUGFyZ21hbm4gW21haWx0
bzptcGFAcGVuZ3V0cm9uaXguZGVdDQo+ID4gPiBTZW50OiAyMCBBdWd1c3QsIDIwMTUgMTU6NTAN
Cj4gPiA+IFRvOiBKb25hdGhhbiBDYW1lcm9uDQo+ID4gPiBDYzogU3Jpbml2YXMgUGFuZHJ1dmFk
YTsgVGlyZGVhLCBJcmluYTsgTGFycy1QZXRlciBDbGF1c2VuOyBsaW51eC1paW9Admdlci5rZXJu
ZWwub3JnOyBsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnOw0KPiA+ID4ga2VybmVsQHBlbmd1
dHJvbml4LmRlOyBNYXJrdXMgUGFyZ21hbm4NCj4gPiA+IFN1YmplY3Q6IFtQQVRDSCB2MiAwLzRd
IGlpbzogYm1jMTUwIHJlZ21hcCBhbmQgU1BJDQo+ID4gPg0KPiA+ID4gSGksDQo+ID4gPg0KPiA+
DQo+ID4gSGkgTWFya3VzLA0KPiA+DQo+ID4gSSB0ZXN0ZWQgeW91ciBwYXRjaGVzIHdpdGggbXkg
Qk1BMjUwRSBkcml2ZXIgY29ubmVjdGVkIG9uIHRoZSBpMmMgYnVzIC4NCj4gPiBUaGUgY29kZSBs
b29rcyBnb29kIGFuZCBtb3N0IG9mIGl0IHdvcmtzLiBUaGVyZSBhcmUgYSBjb3VwbGUgb2YgaXNz
dWVzIEkgd2lsbCBtZW50aW9uDQo+ID4gYmVsb3cgYW5kIGluIHRoZSBpbmRpdmlkdWFsIHBhdGNo
ZXMuDQo+ID4NCj4gPiBUaGUgcGF0Y2hlcyBpbiB0aGlzIHZlcnNpb24gbm8gbG9uZ2VyIGFwcGx5
IGNsZWFubHkgb24gdGhlIHRvZ3JlZyBicmFuY2ggb2YgdGhlIGlpbyB0cmVlLg0KPiA+IEkgZGlk
IHRoZSByZWJhc2UgbXlzZWxmLCBidXQgc2luY2UgdGhlcmUgd2VyZSBtYW55IGNvbmZsaWN0cyBJ
IHdpbGwgZG8gYW5vdGhlciB0ZXN0DQo+ID4gd2hlbiB5b3Ugc2VuZCB0aGUgbmV3IHJlYmFzZWQg
djMuDQo+IA0KPiBUaGFuayB5b3UgZm9yIHJldmlldyBhbmQgdGVzdGluZy4gSSB3aWxsIGludGVn
cmF0ZSB5b3VyIGNvbW1lbnRzIGFuZA0KPiBzZW5kIGEgcmViYXNlZCB2My4NCj4gDQo+ID4NCj4g
PiA+IHRoaXMgc2VyaWVzIGNvbnZlcnRzIHRoZSBibWMxNTAgZHJpdmVyIHRvIHVzZSByZWdtYXAg
YW5kIGFkZHMgYW4gU1BJIGludGVyZmFjZS4NCj4gPiA+DQo+ID4gPiBJbiB2MSB0aGlzIHdhcyBw
YXJ0IG9mIHRoZSBzZXJpZXMgIlJlZ21hcCBtYXhfcmF3X2lvIGFuZCBibWMxNTAgU1BJIHN1cHBv
cnQiLg0KPiA+ID4gSXQgbm93IGRlcGVuZHMgb24gInJlZ21hcDogaTJjIGJsb2NrIHN1cHBvcnQi
Lg0KPiA+ID4NCj4gPg0KPiA+IEkgdXNlZCB0aGUgcGF0Y2hlcyB0aGF0IHdlcmUgYWxyZWFkeSBt
ZXJnZWQgaW4gdGhlIHJlZ21hcCB0cmVlLiBUaGlzIGJtYzE1MCBzZXJpZXMgc2hvdWxkDQo+ID4g
cHJvYmFibHkgd2FpdCB1bnRpbCB0aGUgcmVnbWFwIHBhdGNoZXMgZW5kIHVwIGluIEpvbmF0aGFu
J3MgdHJlZSwgb3RoZXJ3aXNlIHRoZXkgd2lsbA0KPiA+IGJyZWFrIHRoZSBidWlsZC4NCj4gDQo+
IEl0IHNlZW1zIHRoZSBuZWNlc3NhcnkgcGF0Y2hlcyBhcmUgYWxyZWFkeSBpbiB2NC4zLXJjMToN
Cj4gCTI5MzMyNTM0ZTJiNiAocmVnbWFwLWkyYzogQWRkIHNtYnVzIGkyYyBibG9jayBzdXBwb3J0
KQ0KPiANCg0KQUZBSUssIEpvbmF0aGFuIHdhaXRzIHVudGlsIGNoYW5nZXMgZnJvbSB0aGUgbWFp
biBrZXJuZWwgZ2V0IG1lcmdlZCBiYWNrDQppbnRvIGhpcyB0b2dyZWcgYnJhbmNoLiBTaW5jZSB5
b3UgYXJlIHVzaW5nIHJlZ21hcF9nZXRfcmF3X3JlYWRfbWF4IHRoYXQNCmlzIGludHJvZHVjZWQg
aW4gdGhlIHJlZ21hcCBwYXRjaGVzLCB0aGUgZHJpdmVyIHdvbid0IGJ1aWxkIHdpdGhvdXQgdGhl
bQ0KKGlmIHRoZXkgYXJlIG1lcmdlZCBub3cgaW4gdGhlIGlpbyB0cmVlKS4NCg0KSG93ZXZlciwg
dGhhdCBkb2VzIG5vdCBwcmV2ZW50IG1lIGZyb20gdGVzdGluZyB0aGUgY2hhbmdlcyB1c2luZw0K
dGhlIHJlZ21hcCBjaGFuZ2VzIGZyb20gdjQuMy1yYzEuDQoNClRoYW5rcywNCklyaW5hDQoNCj4g
QmVzdCBSZWdhcmRzLA0KPiANCj4gTWFya3VzDQo+IA0KPiA+DQo+ID4gVGhhbmtzLA0KPiA+IEly
aW5hDQo+ID4NCj4gPiA+IENoYW5nZXMgaW4gdjI6DQo+ID4gPiAtIFJlbW92ZWQgZGVmYXVsdCB2
YWx1ZXMgZm9yIHJlZ21hcF9jb25maWcgZmllbGRzLg0KPiA+ID4gLSBSZWRlc2lnbmVkIHRoZSBm
aWZvX3RyYW5zZmVyIGZ1bmN0aW9uIHRvIGF2b2lkIHJ1bm5pbmcgaW4gZXJyb3JzIGZpcnN0Lg0K
PiA+ID4gLSBEcm9wcGVkIGlycSBjaGVja3MgcGF0Y2ggYXMgaXQgaXMgYWxyZWFkeSBtYWlubGlu
ZQ0KPiA+ID4gLSBDb3JlIGNhbiBub3cgYmUgYnVpbHQgYXMgbW9kdWxlIHdpdGggYXV0b3NlbGVj
dGlvbiBvZiBpMmMgYW5kIHNwaSBwYXJ0cw0KPiA+ID4NCj4gPiA+IEFzIG15IGhhcmR3YXJlIGlz
IG1pc3NpbmcgYW4gaW50ZXJydXB0IGxpbmUgZnJvbSB0aGUgU1BJIGNvbm5lY3RlZCBibWMxNTAg
SSBhbQ0KPiA+ID4gbm90IGFibGUgdG8gdGVzdCB0aGUgaWlvIGJ1ZmZlciBjb2RlIHBhdGggYW5k
IHRoZSBpMmMgY29kZSBwYXRoLiBUZXN0cyB3b3VsZCBiZQ0KPiA+ID4gYXBwcmVjaWF0ZWQuDQo+
ID4gPg0KPiA+ID4gQmVzdCByZWdhcmRzLA0KPiA+ID4NCj4gPiA+IE1hcmt1cw0KPiA+ID4NCj4g
PiA+DQo+ID4gPiBNYXJrdXMgUGFyZ21hbm4gKDQpOg0KPiA+ID4gICBpaW86IGJtYzE1MDogVXNl
IGkyYyByZWdtYXANCj4gPiA+ICAgaWlvOiBiY20xNTA6IFJlbW92ZSBpMmNfY2xpZW50IGZyb20g
cHJpdmF0ZSBkYXRhDQo+ID4gPiAgIGlpbzogYm1jMTUwOiBTcGxpdCB0aGUgZHJpdmVyIGludG8g
Y29yZSBhbmQgaTJjDQo+ID4gPiAgIGlpbzogYm1jMTUwOiBBZGQgU1BJIGRyaXZlcg0KPiA+ID4N
Cj4gPiA+ICBkcml2ZXJzL2lpby9hY2NlbC9LY29uZmlnICAgICAgICAgICAgICAgICAgICAgICAg
ICB8ICAxNCArLQ0KPiA+ID4gIGRyaXZlcnMvaWlvL2FjY2VsL01ha2VmaWxlICAgICAgICAgICAg
ICAgICAgICAgICAgIHwgICA0ICstDQo+ID4gPiAgLi4uL2FjY2VsL3tibWMxNTAtYWNjZWwuYyA9
PiBibWMxNTAtYWNjZWwtY29yZS5jfSAgfCAzOTggKysrKysrKystLS0tLS0tLS0tLS0tDQo+ID4g
PiAgZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFjY2VsLWkyYy5jICAgICAgICAgICAgICAgfCAg
OTkgKysrKysNCj4gPiA+ICBkcml2ZXJzL2lpby9hY2NlbC9ibWMxNTAtYWNjZWwtc3BpLmMgICAg
ICAgICAgICAgICB8ICA4MyArKysrKw0KPiA+ID4gIGRyaXZlcnMvaWlvL2FjY2VsL2JtYzE1MC1h
Y2NlbC5oICAgICAgICAgICAgICAgICAgIHwgIDIxICsrDQo+ID4gPiAgNiBmaWxlcyBjaGFuZ2Vk
LCAzNjcgaW5zZXJ0aW9ucygrKSwgMjUyIGRlbGV0aW9ucygtKQ0KPiA+ID4gIHJlbmFtZSBkcml2
ZXJzL2lpby9hY2NlbC97Ym1jMTUwLWFjY2VsLmMgPT4gYm1jMTUwLWFjY2VsLWNvcmUuY30gKDgx
JSkNCj4gPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9paW8vYWNjZWwvYm1jMTUwLWFj
Y2VsLWkyYy5jDQo+ID4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaWlvL2FjY2VsL2Jt
YzE1MC1hY2NlbC1zcGkuYw0KPiA+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2lpby9h
Y2NlbC9ibWMxNTAtYWNjZWwuaA0KPiA+ID4NCj4gPiA+IC0tDQo+ID4gPiAyLjQuNg0KPiA+DQo+
ID4NCj4gDQo+IC0tDQo+IFBlbmd1dHJvbml4IGUuSy4gICAgICAgICAgICAgICAgICAgICAgICAg
ICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQo+IEluZHVzdHJpYWwgTGludXggU29s
dXRpb25zICAgICAgICAgICAgICAgICB8IGh0dHA6Ly93d3cucGVuZ3V0cm9uaXguZGUvICB8DQo+
IFBlaW5lciBTdHIuIDYtOCwgMzExMzcgSGlsZGVzaGVpbSwgR2VybWFueSB8IFBob25lOiArNDkt
NTEyMS0yMDY5MTctMCAgICB8DQo+IEFtdHNnZXJpY2h0IEhpbGRlc2hlaW0sIEhSQSAyNjg2ICAg
ICAgICAgICB8IEZheDogICArNDktNTEyMS0yMDY5MTctNTU1NSB8DQo=

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

* Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
  2015-09-23 12:44     ` Tirdea, Irina
@ 2015-09-27 15:58       ` Jonathan Cameron
  0 siblings, 0 replies; 21+ messages in thread
From: Jonathan Cameron @ 2015-09-27 15:58 UTC (permalink / raw)
  To: Tirdea, Irina, Markus Pargmann
  Cc: Srinivas Pandruvada, Lars-Peter Clausen,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	kernel@pengutronix.de

On 23/09/15 13:44, Tirdea, Irina wrote:
> 
> 
>> -----Original Message-----
>> From: Markus Pargmann [mailto:mpa@pengutronix.de]
>> Sent: 16 September, 2015 13:13
>> To: Tirdea, Irina
>> Cc: Jonathan Cameron; Srinivas Pandruvada; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
>> kernel@pengutronix.de
>> Subject: Re: [PATCH v2 0/4] iio: bmc150 regmap and SPI
>>
>> Hi Irina,
>>
>> On Wed, Sep 09, 2015 at 02:30:30PM +0000, Tirdea, Irina wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Markus Pargmann [mailto:mpa@pengutronix.de]
>>>> Sent: 20 August, 2015 15:50
>>>> To: Jonathan Cameron
>>>> Cc: Srinivas Pandruvada; Tirdea, Irina; Lars-Peter Clausen; linux-iio@vger.kernel.org; linux-kernel@vger.kernel.org;
>>>> kernel@pengutronix.de; Markus Pargmann
>>>> Subject: [PATCH v2 0/4] iio: bmc150 regmap and SPI
>>>>
>>>> Hi,
>>>>
>>>
>>> Hi Markus,
>>>
>>> I tested your patches with my BMA250E driver connected on the i2c bus .
>>> The code looks good and most of it works. There are a couple of issues I will mention
>>> below and in the individual patches.
>>>
>>> The patches in this version no longer apply cleanly on the togreg branch of the iio tree.
>>> I did the rebase myself, but since there were many conflicts I will do another test
>>> when you send the new rebased v3.
>>
>> Thank you for review and testing. I will integrate your comments and
>> send a rebased v3.
>>
>>>
>>>> this series converts the bmc150 driver to use regmap and adds an SPI interface.
>>>>
>>>> In v1 this was part of the series "Regmap max_raw_io and bmc150 SPI support".
>>>> It now depends on "regmap: i2c block support".
>>>>
>>>
>>> I used the patches that were already merged in the regmap tree. This bmc150 series should
>>> probably wait until the regmap patches end up in Jonathan's tree, otherwise they will
>>> break the build.
>>
>> It seems the necessary patches are already in v4.3-rc1:
>> 	29332534e2b6 (regmap-i2c: Add smbus i2c block support)
>>
> 
> AFAIK, Jonathan waits until changes from the main kernel get merged back
> into his togreg branch. Since you are using regmap_get_raw_read_max that
> is introduced in the regmap patches, the driver won't build without them
> (if they are merged now in the iio tree).
Exactly, I tend not to explicitly pull other trees into mine other than my
upstream (staging-next currently).  Those merges tend to only occur as fast
forward merges after Greg has accepted a pull request from me.  Right
now I have one outstanding.  After / if he takes that I can then fast forward
to a tree based on 4.3-rcX and apply these patches.
> 
> However, that does not prevent me from testing the changes using
> the regmap changes from v4.3-rc1.
> 
> Thanks,
> Irina
> 
>> Best Regards,
>>
>> Markus
>>
>>>
>>> Thanks,
>>> Irina
>>>
>>>> Changes in v2:
>>>> - Removed default values for regmap_config fields.
>>>> - Redesigned the fifo_transfer function to avoid running in errors first.
>>>> - Dropped irq checks patch as it is already mainline
>>>> - Core can now be built as module with autoselection of i2c and spi parts
>>>>
>>>> As my hardware is missing an interrupt line from the SPI connected bmc150 I am
>>>> not able to test the iio buffer code path and the i2c code path. Tests would be
>>>> appreciated.
>>>>
>>>> Best regards,
>>>>
>>>> Markus
>>>>
>>>>
>>>> Markus Pargmann (4):
>>>>   iio: bmc150: Use i2c regmap
>>>>   iio: bcm150: Remove i2c_client from private data
>>>>   iio: bmc150: Split the driver into core and i2c
>>>>   iio: bmc150: Add SPI driver
>>>>
>>>>  drivers/iio/accel/Kconfig                          |  14 +-
>>>>  drivers/iio/accel/Makefile                         |   4 +-
>>>>  .../accel/{bmc150-accel.c => bmc150-accel-core.c}  | 398 ++++++++-------------
>>>>  drivers/iio/accel/bmc150-accel-i2c.c               |  99 +++++
>>>>  drivers/iio/accel/bmc150-accel-spi.c               |  83 +++++
>>>>  drivers/iio/accel/bmc150-accel.h                   |  21 ++
>>>>  6 files changed, 367 insertions(+), 252 deletions(-)
>>>>  rename drivers/iio/accel/{bmc150-accel.c => bmc150-accel-core.c} (81%)
>>>>  create mode 100644 drivers/iio/accel/bmc150-accel-i2c.c
>>>>  create mode 100644 drivers/iio/accel/bmc150-accel-spi.c
>>>>  create mode 100644 drivers/iio/accel/bmc150-accel.h
>>>>
>>>> --
>>>> 2.4.6
>>>
>>>
>>
>> --
>> Pengutronix e.K.                           |                             |
>> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
>> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
>> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
> N�����r��y���b�X��ǧv�^�)޺{.n�+����{��*"��^n�r���z�\x1a��h����&��\x1e�G���h�\x03(�階�ݢj"��\x1a�^[m�����z�ޖ���f���h���~�mml==
> 


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

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

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-08-20 12:49 [PATCH v2 0/4] iio: bmc150 regmap and SPI Markus Pargmann
2015-08-20 12:49 ` [PATCH v2 1/4] iio: bmc150: Use i2c regmap Markus Pargmann
2015-08-31 16:11   ` Jonathan Cameron
2015-08-31 19:38     ` Srinivas Pandruvada
2015-09-08  1:09       ` Tirdea, Irina
2015-09-01 13:57     ` Srinivas Pandruvada
2015-09-09 14:36   ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 2/4] iio: bcm150: Remove i2c_client from private data Markus Pargmann
2015-09-09 14:39   ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 3/4] iio: bmc150: Split the driver into core and i2c Markus Pargmann
2015-08-31 16:15   ` Jonathan Cameron
2015-09-01 14:07     ` Srinivas Pandruvada
2015-09-09 14:45   ` Tirdea, Irina
2015-08-20 12:49 ` [PATCH v2 4/4] iio: bmc150: Add SPI driver Markus Pargmann
2015-08-31 16:18   ` Jonathan Cameron
2015-09-01 14:10     ` Srinivas Pandruvada
2015-09-16 10:01       ` Markus Pargmann
2015-09-09 14:30 ` [PATCH v2 0/4] iio: bmc150 regmap and SPI Tirdea, Irina
2015-09-16 10:13   ` Markus Pargmann
2015-09-23 12:44     ` Tirdea, Irina
2015-09-27 15:58       ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).