i2c driver develpment with diolan DLN-2 / ACPI?

Martin Kepplinger martink at posteo.de
Wed Apr 27 07:36:58 EDT 2016


Hi roberta or anyone who uses a diolan i2c/spi bridge device,

I try to do get the kernel driver for the connected chip loaded, but I'm
having some trouble getting it right.

Cables are connected to the device (i2c), and the (mainline) kernel
driver for the diolan DLN-2 device is compiled and loaded on plugin.

I don't use any of their (userspace) software.

Now I get a new i2c bus and can manually instanciate my driver

root at laptop:/sys/bus/i2c/devices/i2c-7# echo mma8452 0x1c > new_device

and the driver loads. (Now for development, later maybe for merging) I
added acpi support, I guess I'd need it, but ACPI_HANDLE(&client->dev)
isn't true (during probe) hence we don't continue. I append my
adding-acpi-patch below.

How do you do it?

Do *you* manually instantiate your i2c-driver during development with
your diolan device or should it somehow even get loaded automatically?

thanks so much for any help,

                     martin


--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -33,6 +33,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/pm_runtime.h>
+#include <linux/acpi.h>

 #define MMA8452_STATUS				0x00
 #define  MMA8452_STATUS_DRDY			(BIT(2) | BIT(1) | BIT(0))
@@ -1434,6 +1435,19 @@ static const struct of_device_id mma8452_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mma8452_dt_ids);

+static const char *mma8452_match_acpi_device(struct device *dev, int *data)
+{
+        const struct acpi_device_id *id;
+
+        id = acpi_match_device(dev->driver->acpi_match_table, dev);
+        if (!id)
+                return NULL;
+
+        *data = (int)id->driver_data;
+
+        return dev_name(dev);
+}
+
 static int mma8452_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -1441,21 +1455,35 @@ static int mma8452_probe(struct i2c_client *client,
 	struct iio_dev *indio_dev;
 	int ret;
 	const struct of_device_id *match;
+	const char *name = NULL;
+	int dev_id = 0;

-	match = of_match_device(mma8452_dt_ids, &client->dev);
-	if (!match) {
-		dev_err(&client->dev, "unknown device model\n");
-		return -ENODEV;
-	}
+pr_info("mma probe running!!\n");

 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 	if (!indio_dev)
 		return -ENOMEM;

 	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
 	data->client = client;
+
+	match = of_match_device(mma8452_dt_ids, &client->dev);
+	if (match) {
+		if (id)
+			name = id->name;
+		data->chip_info = match->data;
+	} else if (ACPI_HANDLE(&client->dev)) {
+		name = mma8452_match_acpi_device(&client->dev, &dev_id);
+		pr_info("mma acpi ok. found id %d\n", dev_id);
+		/* TODO chip_info setting*/
+		data->chip_info = &mma_chip_info_table[dev_id];
+	} else {
+		dev_err(&client->dev, "unknown device model\n");
+		return -ENODEV;
+	}
+
 	mutex_init(&data->lock);
-	data->chip_info = match->data;

 	ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
 	if (ret < 0)
@@ -1475,11 +1503,10 @@ static int mma8452_probe(struct i2c_client *client,
 	}

 	dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n",
-		 match->compatible, data->chip_info->chip_id);
+		 name, data->chip_info->chip_id);

-	i2c_set_clientdata(client, indio_dev);
 	indio_dev->info = &mma8452_info;
-	indio_dev->name = id->name;
+	indio_dev->name = name;
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = data->chip_info->channels;
@@ -1669,6 +1696,17 @@ static const struct dev_pm_ops mma8452_pm_ops = {
 			   mma8452_runtime_resume, NULL)
 };

+static const struct acpi_device_id mma8452_acpi_match[] = {
+	{ "MMA8451", mma8451 },
+	{ "MMA8452", mma8452 },
+	{ "MMA8453", mma8453 },
+	{ "MMA8652", mma8652 },
+	{ "MMA8653", mma8653 },
+	{ "FXLS8471", fxls8471 },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, mma8452_acpi_match);
+
 static const struct i2c_device_id mma8452_id[] = {
 	{ "mma8451", mma8451 },
 	{ "mma8452", mma8452 },
@@ -1684,6 +1722,7 @@ static struct i2c_driver mma8452_driver = {
 	.driver = {
 		.name	= "mma8452",
 		.of_match_table = of_match_ptr(mma8452_dt_ids),
+		.acpi_match_table = ACPI_PTR(mma8452_acpi_match),
 		.pm	= &mma8452_pm_ops,
 	},
 	.probe = mma8452_probe,
-- 
2.1.4




More information about the Kernelnewbies mailing list