Post Go back to editing

Device tree bindings for ADT7516

I have a BeagleBone green and ADT7516's evaluation board connected with SDA and SCL pins.

When I do i2cdetect -y -r 2, I can see the i2c address as 0x4b and I am able to probe the adt7316 driver present in IIO subsystem.

adt7316 driver uses platform data to get the hardware description. But my goal is to remove platform data and use DT bindings.

I understand some basic things about the DT bindings like..

1. Compatible
2. reg

But when I have a close look at the driver, I can see that there are certain
things which are taken from the platform data and are used in the whole driver.

So my question is that how do I replace those things in the driver if I remove platform data and use DT bindings.

I am putting probe function's code here.

int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
const char *name)
{
struct adt7316_chip_info *chip;
struct iio_dev *indio_dev;
unsigned short *adt7316_platform_data = dev->platform_data;
int ret = 0;

indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
if (!indio_dev)
return -ENOMEM;
chip = iio_priv(indio_dev);
/* this is only used for device removal purposes */
dev_set_drvdata(dev, indio_dev);

chip->bus = *bus;

if (name[4] == '3')
chip->id = ID_ADT7316 + (name[6] - '6');
else if (name[4] == '5')
chip->id = ID_ADT7516 + (name[6] - '6');
else
return -ENODEV;

chip->ldac_pin = adt7316_platform_data[1];
if (chip->ldac_pin) {
chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA;
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
chip->config1 |= ADT7516_SEL_AIN3;
}
chip->int_mask = ADT7316_TEMP_INT_MASK | ADT7316_VDD_INT_MASK;
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
chip->int_mask |= ADT7516_AIN_INT_MASK;

indio_dev->dev.parent = dev;
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
indio_dev->info = &adt7516_info;
else
indio_dev->info = &adt7316_info;
indio_dev->name = name;
indio_dev->modes = INDIO_DIRECT_MODE;

if (chip->bus.irq > 0) {
if (adt7316_platform_data[0])
chip->bus.irq_flags = adt7316_platform_data[0];

ret = devm_request_threaded_irq(dev, chip->bus.irq,
NULL,
adt7316_event_handler,
chip->bus.irq_flags |
IRQF_ONESHOT,
indio_dev->name,
indio_dev);
if (ret)
return ret;

if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
chip->config1 |= ADT7316_INT_POLARITY;
}

ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
if (ret)
return -EIO;

ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
if (ret)
return -EIO;

ret = devm_iio_device_register(dev, indio_dev);
if (ret)
return ret;

dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
indio_dev->name);

return 0;
}
EXPORT_SYMBOL(adt7316_probe);

So in the code we can see that chip->ldac_pin and chip->bus.irq_flags uses platform data.
If I use DT bindings then platform data will have NULL value in it.

So how do I design my DT bindings here and how can I fetch that data in the driver?

I have seen many examples of DT bindings but I need specific help with adt7516 sensor.

**Datasheet of adt7516 sensor**

www.analog.com/.../ADT7516_7517_7519.pdf

  • Hey,

    You can use the GPIO framework for this.

    The typical functions for this are devm_gpiod_get() or devm_gpiod_get_optional().  The latter should be used if the pin configuration can be omitted and is not required for the device to operate.

    There is a new pinctrl framework now that looks interesting, and that could also be used, but I'm not sure about it [ since it's very new ].

    The GPIO framework has been around for quite some time now and is what you need.

    A quick example is that if you define in your DT

    ldac-gpio = <&gpio 7 0>;

    then you can call it by   devm_gpiod_get_optional(dev, "ldac", GPIOD_OUT_LOW);

    But you should be able to find good examples and some good docs about this.

    Thanks

    Alex

  • I forgot to add.

    I think you can remove the line that deals with adt7316_platform_data[0].

    The IRQ flags should be taken from the device-tree and that code looks like it should already handle that.

    The assignment

                   if (adt7316_platform_data[0])
                            chip->bus.irq_flags = adt7316_platform_data[0];

    looks a bit erroneous

  • Hey Alex,

    Thanks for your answer.

    ldac-gpio = <&gpio 7 0>;

    From the above example can you please explain me that how did you get that number 7 and 0?

    This is exactly what I was looking for but I didn't get any proper explanation for this.

    Also, what about the interrupt and interrupt-parent property?

    We have got status registers associated with interrupts and hence I think we might need interrupt and

    interrupt-parent property?

    I am taking an example here with which I can ask my questions

    accelerometer@2a {
    compatible = "adi,adxl345";
    reg = <0x53>;
    interrupt-parent = <&gpio1>;
    interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
    };

    In this example I can see that interrupt-parent has &gpio1
    How do we identify that gpio number? Like, here we have gpio1.


    Basically, I want to learn that how should I look at the datasheet with
    which I can write this device tree binding.

    I know that this is not possible to teach here but maybe some doubts can be
    cleared ;)

    Sorry for such silly questions!!

          
  • Hey,

    So,

               ldac-gpio = <&gpio 7 0>;

    is just an example. You need to search for the gpio entry defined for your Beaglebone board.

    Some boards have 2 GPIO controllers so, they may have gpio0 & gpio1.

    Interrupt DT bindings are detailed here:

    https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt

    In any case, the scope of this question is now falling outside of the scope of this forum.

    We try to offer support/help to help people get stuck out of specific situations [with ADI products], and not necessarily have it as a learning platform.

    Thanks

    Alex