linux/drivers/iio/accel/st_accel_i2c.c
Linus Walleij 762227721f iio: accel: st_accel: handle deprecated bindings
The earlier deployed LIS3LV02DL driver had already defined a few
DT bindings that need to be supported by the new more generic
driver and listed as compatible but deprecated bindings in the
documentation.

After this we can start to activate the new driver with the old
systems where applicable.

As part of this enablement: make us depend on the old drivers
not being in use so we don't get a kernel with two competing
drivers.

Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
2017-01-10 19:54:16 +00:00

191 lines
4.3 KiB
C

/*
* STMicroelectronics accelerometers driver
*
* Copyright 2012-2013 STMicroelectronics Inc.
*
* Denis Ciocca <denis.ciocca@st.com>
*
* Licensed under the GPL-2.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/common/st_sensors.h>
#include <linux/iio/common/st_sensors_i2c.h>
#include "st_accel.h"
#ifdef CONFIG_OF
static const struct of_device_id st_accel_of_match[] = {
{
/* An older compatible */
.compatible = "st,lis3lv02d",
.data = LIS3LV02DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lis3lv02dl-accel",
.data = LIS3LV02DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303dlh-accel",
.data = LSM303DLH_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303dlhc-accel",
.data = LSM303DLHC_ACCEL_DEV_NAME,
},
{
.compatible = "st,lis3dh-accel",
.data = LIS3DH_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm330d-accel",
.data = LSM330D_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm330dl-accel",
.data = LSM330DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm330dlc-accel",
.data = LSM330DLC_ACCEL_DEV_NAME,
},
{
.compatible = "st,lis331dl-accel",
.data = LIS331DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lis331dlh-accel",
.data = LIS331DLH_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303dl-accel",
.data = LSM303DL_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303dlm-accel",
.data = LSM303DLM_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm330-accel",
.data = LSM330_ACCEL_DEV_NAME,
},
{
.compatible = "st,lsm303agr-accel",
.data = LSM303AGR_ACCEL_DEV_NAME,
},
{
.compatible = "st,lis2dh12-accel",
.data = LIS2DH12_ACCEL_DEV_NAME,
},
{
.compatible = "st,h3lis331dl-accel",
.data = H3LIS331DL_DRIVER_NAME,
},
{
.compatible = "st,lis3l02dq",
.data = LIS3L02DQ_ACCEL_DEV_NAME,
},
{
.compatible = "st,lng2dm-accel",
.data = LNG2DM_ACCEL_DEV_NAME,
},
{},
};
MODULE_DEVICE_TABLE(of, st_accel_of_match);
#else
#define st_accel_of_match NULL
#endif
#ifdef CONFIG_ACPI
static const struct acpi_device_id st_accel_acpi_match[] = {
{"SMO8A90", LNG2DM},
{ },
};
MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match);
#else
#define st_accel_acpi_match NULL
#endif
static const struct i2c_device_id st_accel_id_table[] = {
{ LSM303DLH_ACCEL_DEV_NAME, LSM303DLH },
{ LSM303DLHC_ACCEL_DEV_NAME, LSM303DLHC },
{ LIS3DH_ACCEL_DEV_NAME, LIS3DH },
{ LSM330D_ACCEL_DEV_NAME, LSM330D },
{ LSM330DL_ACCEL_DEV_NAME, LSM330DL },
{ LSM330DLC_ACCEL_DEV_NAME, LSM330DLC },
{ LIS331DLH_ACCEL_DEV_NAME, LIS331DLH },
{ LSM303DL_ACCEL_DEV_NAME, LSM303DL },
{ LSM303DLM_ACCEL_DEV_NAME, LSM303DLM },
{ LSM330_ACCEL_DEV_NAME, LSM330 },
{ LSM303AGR_ACCEL_DEV_NAME, LSM303AGR },
{ LIS2DH12_ACCEL_DEV_NAME, LIS2DH12 },
{ LIS3L02DQ_ACCEL_DEV_NAME, LIS3L02DQ },
{ LNG2DM_ACCEL_DEV_NAME, LNG2DM },
{},
};
MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
static int st_accel_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct st_sensor_data *adata;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));
if (!indio_dev)
return -ENOMEM;
adata = iio_priv(indio_dev);
if (client->dev.of_node) {
st_sensors_of_i2c_probe(client, st_accel_of_match);
} else if (ACPI_HANDLE(&client->dev)) {
ret = st_sensors_match_acpi_device(&client->dev);
if ((ret < 0) || (ret >= ST_ACCEL_MAX))
return -ENODEV;
strncpy(client->name, st_accel_id_table[ret].name,
sizeof(client->name));
client->name[sizeof(client->name) - 1] = '\0';
} else if (!id)
return -ENODEV;
st_sensors_i2c_configure(indio_dev, client, adata);
ret = st_accel_common_probe(indio_dev);
if (ret < 0)
return ret;
return 0;
}
static int st_accel_i2c_remove(struct i2c_client *client)
{
st_accel_common_remove(i2c_get_clientdata(client));
return 0;
}
static struct i2c_driver st_accel_driver = {
.driver = {
.name = "st-accel-i2c",
.of_match_table = of_match_ptr(st_accel_of_match),
.acpi_match_table = ACPI_PTR(st_accel_acpi_match),
},
.probe = st_accel_i2c_probe,
.remove = st_accel_i2c_remove,
.id_table = st_accel_id_table,
};
module_i2c_driver(st_accel_driver);
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics accelerometers i2c driver");
MODULE_LICENSE("GPL v2");