linux-device-driverembedded-linuxiio

How to add write_raw function in my iio_info structure


I am writing a driver using iio framework. So far it goes well. All the inputs and sysfs entries are working perfectly and the values measured are fine. (It is very well documented and it is easy). But I need a small extension to be able to write on one of the channels. When I add my function in iio_info the compiler issues me an error:

drivers/iio/adc/iio-ccuss.c:197:15: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
  .write_raw = ccuss_iio_write_raw,
               ^~~~~~~~~~~~~~~~~~~

It is very weird for me. I even can't believe I am asking shamelessly this here but I am very frustrated. I lost almost half day with that. My structure is:

static const struct iio_info ccuss_iio_info = {
    .driver_module = THIS_MODULE,
    .attrs = &ccuss_iio_attribute_group,
    .read_raw = ccuss_iio_read_raw,
    .write_raw = ccuss_iio_write_raw,
};

my channel types are IIO_VOLTAGE, IIO_TEMP and IIO_HUMIDITYRELATIVE. I am start thinking to make it as an device attribute :-( if I do not receive an answer in the next 12 hours.

Update: just to be more visible, according Murphy's comment.

static int ccuss_iio_write_raw(struct iio_dev *iio,
                        struct iio_chan_spec const *channel, int *val1,
                        int *val2, long mask);

P.S. I do not want to remove this error by the most known way. The QA (and me) will be unhappy. Thanks


Solution

  • According to the reference the write_raw() function is declared as follows:

    int (*write_raw)(
        struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan,
        int val,
        int val2,
        long mask);
    

    Your implementation is declared like this:

     static int ccuss_iio_write_raw(
         struct iio_dev *iio,
         struct iio_chan_spec const *channel,
         int *val1,
         int *val2,
         long mask);
    

    So you declare the two integer parameters as pointers, but they are expected to be passed by value. I think that's the mismatch that causes the "incompatible pointer type" error.