浏览代码

iio: bmc150: Split the driver into core and i2c

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Irina Tirdea <irina.tirdea@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Markus Pargmann 10 年之前
父节点
当前提交
55637c3837

+ 5 - 4
drivers/iio/accel/Kconfig

@@ -19,21 +19,22 @@ config BMA180
 
 
 config BMC150_ACCEL
 config BMC150_ACCEL
 	tristate "Bosch BMC150 Accelerometer Driver"
 	tristate "Bosch BMC150 Accelerometer Driver"
-	depends on I2C
 	select IIO_BUFFER
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select IIO_TRIGGERED_BUFFER
 	select REGMAP
 	select REGMAP
-	select REGMAP_I2C
+	select BMC150_ACCEL_I2C if I2C
 	help
 	help
 	  Say yes here to build support for the following Bosch accelerometers:
 	  Say yes here to build support for the following Bosch accelerometers:
 	  BMC150, BMI055, BMA250E, BMA222E, BMA255, BMA280.
 	  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 is a combo module with both accelerometer and magnetometer.
 	  This driver is only implementing accelerometer part, which has
 	  This driver is only implementing accelerometer part, which has
 	  its own address and register map.
 	  its own address and register map.
 
 
+config BMC150_ACCEL_I2C
+	tristate
+	select REGMAP_I2C
+
 config HID_SENSOR_ACCEL_3D
 config HID_SENSOR_ACCEL_3D
 	depends on HID_SENSOR_HUB
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
 	select IIO_BUFFER

+ 2 - 1
drivers/iio/accel/Makefile

@@ -4,7 +4,8 @@
 
 
 # When adding new entries keep the list in alphabetical order
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_BMA180) += bma180.o
 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_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o

+ 17 - 69
drivers/iio/accel/bmc150-accel.c → drivers/iio/accel/bmc150-accel-core.c

@@ -37,6 +37,8 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/triggered_buffer.h>
 #include <linux/regmap.h>
 #include <linux/regmap.h>
 
 
+#include "bmc150-accel.h"
+
 #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
 #define BMC150_ACCEL_DRV_NAME			"bmc150_accel"
 #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
 #define BMC150_ACCEL_IRQ_NAME			"bmc150_accel_event"
 
 
@@ -1014,15 +1016,6 @@ static const struct iio_chan_spec bmc150_accel_channels[] =
 static const struct iio_chan_spec bma280_accel_channels[] =
 static const struct iio_chan_spec bma280_accel_channels[] =
 	BMC150_ACCEL_CHANNELS(14);
 	BMC150_ACCEL_CHANNELS(14);
 
 
-enum {
-	bmc150,
-	bmi055,
-	bma255,
-	bma250e,
-	bma222e,
-	bma280,
-};
-
 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 static const struct bmc150_accel_chip_info bmc150_accel_chip_info_tbl[] = {
 	[bmc150] = {
 	[bmc150] = {
 		.name = "BMC150A",
 		.name = "BMC150A",
@@ -1553,33 +1546,23 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data)
 	return 0;
 	return 0;
 }
 }
 
 
-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, bool block_supported)
 {
 {
 	struct bmc150_accel_data *data;
 	struct bmc150_accel_data *data;
 	struct iio_dev *indio_dev;
 	struct iio_dev *indio_dev;
 	int ret;
 	int ret;
-	const char *name = NULL;
-	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)
 	if (!indio_dev)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	data = iio_priv(indio_dev);
 	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);
-	}
+	dev_set_drvdata(dev, indio_dev);
+	data->dev = dev;
+	data->irq = irq;
 
 
-	if (id)
-		name = id->name;
+	data->regmap = regmap;
 
 
 	ret = bmc150_accel_chip_init(data);
 	ret = bmc150_accel_chip_init(data);
 	if (ret < 0)
 	if (ret < 0)
@@ -1633,9 +1616,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 		if (ret)
 		if (ret)
 			goto err_buffer_cleanup;
 			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->modes |= INDIO_BUFFER_SOFTWARE;
 			indio_dev->info = &bmc150_accel_info_fifo;
 			indio_dev->info = &bmc150_accel_info_fifo;
 			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
 			indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
@@ -1644,7 +1625,7 @@ static int bmc150_accel_probe(struct i2c_client *client,
 
 
 	ret = iio_device_register(indio_dev);
 	ret = iio_device_register(indio_dev);
 	if (ret < 0) {
 	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;
 		goto err_trigger_unregister;
 	}
 	}
 
 
@@ -1667,10 +1648,11 @@ err_buffer_cleanup:
 
 
 	return ret;
 	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);
 	struct bmc150_accel_data *data = iio_priv(indio_dev);
 
 
 	pm_runtime_disable(data->dev);
 	pm_runtime_disable(data->dev);
@@ -1689,6 +1671,7 @@ static int bmc150_accel_remove(struct i2c_client *client)
 
 
 	return 0;
 	return 0;
 }
 }
+EXPORT_SYMBOL_GPL(bmc150_accel_core_remove);
 
 
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
 static int bmc150_accel_suspend(struct device *dev)
 static int bmc150_accel_suspend(struct device *dev)
@@ -1759,47 +1742,12 @@ static int bmc150_accel_runtime_resume(struct device *dev)
 }
 }
 #endif
 #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_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume)
 	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
 	SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend,
 			   bmc150_accel_runtime_resume, NULL)
 			   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);
+EXPORT_SYMBOL_GPL(bmc150_accel_pm_ops);
 
 
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_LICENSE("GPL v2");

+ 102 - 0
drivers/iio/accel/bmc150-accel-i2c.c

@@ -0,0 +1,102 @@
+/*
+ * 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;
+	const char *name = NULL;
+	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);
+	}
+
+	if (id)
+		name = id->name;
+
+	return bmc150_accel_core_probe(&client->dev, regmap, client->irq, name,
+				       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");

+ 20 - 0
drivers/iio/accel/bmc150-accel.h

@@ -0,0 +1,20 @@
+#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, 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_ */