0

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

Georgi
  • 53
  • 2
  • 7
  • The struct you're trying to initialize is probably [this one](https://elixir.bootlin.com/linux/latest/source/include/linux/iio/iio.h#L396); please also provide the declaration of `ccuss_iio_write_raw`. – Murphy May 02 '19 at 15:44
  • Actually the structure is [this one](https://elixir.bootlin.com/linux/v4.9.79/source/include/linux/iio/iio.h#L381). The declaration is: static int ccuss_iio_write_raw(struct iio_dev *iio, struct iio_chan_spec const *channel, int *val1, int *val2, long mask); – Georgi May 02 '19 at 19:59

1 Answers1

0

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.

Murphy
  • 3,827
  • 4
  • 21
  • 35
  • I was just writing my own answer. Never read the documentation only and take a detailed look at the interfaces fields. – Georgi May 03 '19 at 15:32
  • Nevertheless you always have to implement write_raw_get_fmt() too when you make write_raw. it caused me a lot of headaches because in iio_write_channel_info it puts some scaling to the value written... Thank you again – Georgi May 03 '19 at 15:36
  • @Georgi, you don't need to. The format is described in corresponding data structures AFAIR. – 0andriy May 04 '19 at 22:04
  • @Georgi, yes, I can confirm, that `write_raw_get_fmt()` is not necessary to have. One may define the format via `struc iio_chan_spec` https://elixir.bootlin.com/linux/v5.2-rc1/source/include/linux/iio/iio.h#L239 – 0andriy May 21 '19 at 19:55
  • @0andrriy thanks , I already implemented it. Because the value written must be scaled by me so I implemented write_raw_get_fmt(). But you are right it is not mandatory...Just a good option :-) – Georgi May 23 '19 at 07:12