i2c driver develpment with diolan DLN-2 / ACPI?

Martin Kepplinger martink at posteo.de
Sat Apr 30 11:10:30 EDT 2016


Am 2016-04-27 um 13:51 schrieb Daniel Baluta:
> 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?
> 

Those patches don't apply anymore, also because of API changes. I save
them but I'll ignore the ACPI problem for now. Oh well, for development
only, I skip it and go ahead and try to write and read registers.

Different problem:

i2c_smbus_read_byte_data always returns with "Protocol Error".

DLN-2 jumpers are correct. Is there anything special to consider, using
the DLN-2, regardless of which chip you are talking to?

thanks
                      martin


>> 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.
> 
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
> 




More information about the Kernelnewbies mailing list