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>
This commit is contained in:
Markus Pargmann 2015-09-21 12:55:15 +02:00 committed by Jonathan Cameron
parent 19c95d63e7
commit 55637c3837
5 changed files with 146 additions and 74 deletions

View File

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

View File

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

View File

@ -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, int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
const struct i2c_device_id *id) 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); dev_set_drvdata(dev, indio_dev);
data->dev = &client->dev; data->dev = dev;
dev = &client->dev; data->irq = irq;
data->irq = client->irq;
data->regmap = devm_regmap_init_i2c(client, &bmc150_i2c_regmap_conf); data->regmap = regmap;
if (IS_ERR(data->regmap)) {
dev_err(dev, "Failed to initialize i2c regmap\n");
return PTR_ERR(data->regmap);
}
if (id)
name = id->name;
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) || if (block_supported) {
i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
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)
}; };
EXPORT_SYMBOL_GPL(bmc150_accel_pm_ops);
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_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");

View File

@ -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");

View File

@ -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_ */