i2c driver develpment with diolan DLN-2 / ACPI?
Daniel Baluta
daniel.baluta at gmail.com
Wed Apr 27 07:51:47 EDT 2016
On Wed, Apr 27, 2016 at 2:36 PM, Martin Kepplinger <martink at posteo.de> wrote:
> 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?
>
Hi Martin,
Please also use the following two patches:
https://lkml.org/lkml/2014/12/16/290
https://lkml.org/lkml/2014/12/16/289
How does your setup looks like?
> 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,
This looks fine to me.
Daniel.
More information about the Kernelnewbies
mailing list