Hi Jonathan, Below the content of all the files under scan_elements to check if something is odd (using iio_info). I cannot distribute all the source code, but I will re-make and share as below. Thanks again for any suggestion. --------------------- Library version: 0.6 (git tag: 9d8aa76) IIO context created with local backend. Backend version: 0.6 (git tag: 9d8aa76) Backend description string: Linux Board Custom 3.10.53-1.1.0_ga-boardcustom #94 SMP PREEMPT Sun Dec 13 16:17:57 CST 2015 armv7l IIO context has 2 devices: trigger0: customdevice-dev0 0 channels found: iio:device0: customdevice 9 channels found: voltage0: 0 (input) 3 channel-specific attributes found: attr 0: en value: 1 attr 1: index value: 0 attr 2: type value: be:u24/32>>0 voltage1: 1 (input) 3 channel-specific attributes found: attr 0: en value: 1 attr 1: type value: be:u24/32>>0 attr 2: index value: 1 voltage2: 2 (input) 3 channel-specific attributes found: attr 0: en value: 1 attr 1: type value: be:u24/32>>0 attr 2: index value: 2 voltage3: 3 (input) 3 channel-specific attributes found: attr 0: type value: be:u24/32>>0 attr 1: index value: 3 attr 2: en value: 1 voltage4: 4 (input) 3 channel-specific attributes found: attr 0: en value: 1 attr 1: type value: be:u24/32>>0 attr 2: index value: 4 voltage5: 5 (input) 3 channel-specific attributes found: attr 0: en value: 1 attr 1: index value: 5 attr 2: type value: be:u24/32>>0 voltage6: 6 (input) 3 channel-specific attributes found: attr 0: index value: 6 attr 1: type value: be:u24/32>>0 attr 2: en value: 1 voltage7: 7 (input) 3 channel-specific attributes found: attr 0: index value: 7 attr 1: type value: be:u24/32>>0 attr 2: en value: 1 voltage8: 8 (input) 3 channel-specific attributes found: attr 0: index value: 8 attr 1: type value: be:u24/32>>0 attr 2: en value: 1 1 device-specific attributes found: attr 0: config1 value: 133 Current trigger: trigger0(customde --------------------- -------------------- struct customdevice_state { struct spi_device *spi; bool sampling; bool irq_enabled; uint8_t *samples_data; struct iio_trigger *trig; struct mutex lock; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ uint8_t rx_buf[customdevice_SPI_MAX_FRAMESIZE] ____cacheline_aligned; uint8_t tx_buf[customdevice_SPI_MAX_FRAMESIZE] ____cacheline_aligned; }; static int customdevice_send_command(struct iio_dev *indio_dev, unsigned char command) { struct customdevice_state *st = iio_priv(indio_dev); int ret; if (iio_buffer_enabled(indio_dev)) return -EBUSY; mutex_lock(&st->lock); st->tx_buf[0] = command; ret = spi_write(st->spi, &st->tx_buf, 1); mutex_unlock(&st->lock); return ret; }; static int customdevice_read_register(struct iio_dev *indio_dev, unsigned char address, unsigned char *value) { struct customdevice_state *st = iio_priv(indio_dev); struct spi_transfer xfer; struct spi_message msg; int ret; if (iio_buffer_enabled(indio_dev)) return -EBUSY; memset(&xfer, 0, sizeof(xfer)); xfer.tx_buf = &st->tx_buf; xfer.rx_buf = &st->rx_buf; xfer.len = 3; xfer.delay_usecs = 2; xfer.cs_change = 0; xfer.bits_per_word = 8; spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); mutex_lock(&st->lock); st->tx_buf[0] = customdevice_CMD_RREG | address; st->tx_buf[1] = 0; st->tx_buf[2] = 0; ret = spi_sync(st->spi, &msg); if (ret) goto out; *value = st->rx_buf[2]; out: mutex_unlock(&st->lock); return ret; }; static int customdevice_write_register(struct iio_dev *indio_dev, unsigned char address, unsigned char value) { struct customdevice_state *st = iio_priv(indio_dev); struct spi_transfer xfer; struct spi_message msg; int ret; if (iio_buffer_enabled(indio_dev)) return -EBUSY; memset(&xfer, 0, sizeof(xfer)); xfer.tx_buf = &st->tx_buf; xfer.rx_buf = &st->rx_buf; xfer.len = 3; xfer.delay_usecs = 2; xfer.cs_change = 0; xfer.bits_per_word = 8; spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); mutex_lock(&st->lock); st->tx_buf[0] = customdevice_CMD_WREG | address; st->tx_buf[1] = 0; st->tx_buf[2] = value; ret = spi_sync(st->spi, &msg); if (ret) goto out; out: mutex_unlock(&st->lock); return ret; }; struct gpio customdevice_gpio_reset = { .label = "reset-gpio", .flags = GPIOF_OUT_INIT_HIGH }; struct gpio customdevice_gpio_acquire = { .label = "acquire-gpio", .flags =GPIOF_OUT_INIT_LOW }; static void customdevice_reset_by_gpio(void) { gpio_set_value_cansleep(customdevice_gpio_reset.gpio, 0); udelay(5); gpio_set_value_cansleep(customdevice_gpio_reset.gpio, 1); udelay(20); printk(KERN_ALERT "DEBUG: Passed %s %d GPIO setting %s\n",__FUNCTION__,__LINE__, customdevice_gpio_reset.label); } static void customdevice_acquire_by_gpio(bool enable) { gpio_set_value_cansleep(customdevice_gpio_acquire.gpio, enable); printk(KERN_ALERT "DEBUG: Passed %s %d GPIO setting %s\n",__FUNCTION__,__LINE__, customdevice_gpio_acquire.label); } static int customdevice_init_io_from_dt(struct device *dev, struct gpio *pgpio) { struct device_node *np = dev->of_node; int ret; pgpio->gpio = of_get_named_gpio(np, pgpio->label, 0); if (!gpio_is_valid(pgpio->gpio)) { return -EINVAL; } else { ret = devm_gpio_request_one(dev, pgpio->gpio, pgpio->flags, pgpio->label); if (ret < 0) { return ret; } } return 0; }; static int customdevice_init_gpio_pins(struct iio_dev *indio_dev) { struct customdevice_state *st = iio_priv(indio_dev); struct device *dev = &st->spi->dev; int ret; ret = customdevice_init_io_from_dt(dev, &customdevice_gpio_reset); printk(KERN_ALERT "DEBUG: Passed %s %d init GPIO RESET return %d \n",__FUNCTION__,__LINE__, ret); ret = customdevice_init_io_from_dt(dev, &customdevice_gpio_acquire); printk(KERN_ALERT "DEBUG: Passed %s %d init GPIO START return %d \n",__FUNCTION__,__LINE__, ret); if (ret < 0) goto out; gpio_set_value_cansleep(customdevice_gpio_acquire.gpio, 0); printk(KERN_ALERT "DEBUG: Passed %s %d GPIO setting %s\n",__FUNCTION__,__LINE__, customdevice_gpio_acquire.label); gpio_set_value_cansleep(customdevice_gpio_reset.gpio, 1); printk(KERN_ALERT "DEBUG: Passed %s %d GPIO setting %s\n",__FUNCTION__,__LINE__, customdevice_gpio_reset.label); return 0; out: return ret; }; #ifdef CONFIG_DEBUG_FS static void customdevice_debugfs_init(struct iio_dev *indio_dev) { printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); } static int customdevice_debugfs_reg_access(struct iio_dev *indio_dev, unsigned reg, unsigned writeval, unsigned *readval) { unsigned char readdata; int ret; if (readval == NULL) { printk(KERN_ALERT "DEBUG: Passed %s %d WRITE reg = %x val = %x\n",__FUNCTION__,__LINE__, (unsigned char)reg, (unsigned char)writeval); return customdevice_write_register(indio_dev, (unsigned char)reg, (unsigned char)writeval); } ret = customdevice_read_register(indio_dev, (unsigned char)reg, &readdata); if (ret) return ret; *readval = (unsigned)readdata; printk(KERN_ALERT "DEBUG: Passed %s %d READ reg = %x val = %x\n",__FUNCTION__,__LINE__, (unsigned char)reg, (unsigned char)writeval); return 0; } #else static inline void customdevice_debugfs_init(struct iio_dev *indio_dev) {}; #define customdevice_debugfs_reg_access NULL #endif static int customdevice_startup(struct iio_dev *indio_dev, unsigned long mask) { unsigned char reg; int ret; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); // enable conversions customdevice_acquire_by_gpio(true); return 0; } static int customdevice_shutdown(struct iio_dev *indio_dev) { int ret; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); // stop conversions customdevice_acquire_by_gpio(false); return 0; } static int customdevice_preenable(struct iio_dev *indio_dev) { struct customdevice_state *st = iio_priv(indio_dev); int ret; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ret = iio_sw_buffer_preenable(indio_dev); if (ret) return ret; ret = customdevice_startup(indio_dev, *indio_dev->active_scan_mask); if (ret) return ret; st->sampling = true; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); return ret; } static int customdevice_postenable(struct iio_dev *indio_dev) { struct customdevice_state *st = iio_priv(indio_dev); printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); iio_triggered_buffer_postenable(indio_dev); if (st->spi->irq) { st->irq_enabled = true; enable_irq(st->spi->irq); } printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); return 0; } static int customdevice_postdisable(struct iio_dev *indio_dev) { struct customdevice_state *st = iio_priv(indio_dev); printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); st->sampling = false; return customdevice_shutdown(indio_dev); } static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { .preenable = &customdevice_preenable, .postenable = &customdevice_postenable, .predisable = &iio_triggered_buffer_predisable, .postdisable = &customdevice_postdisable, }; unsigned long int test = 0; static irqreturn_t customdevice_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct customdevice_state *st = iio_priv(indio_dev); struct spi_transfer xfer; struct spi_message msg; int ret; memset(&xfer, 0, sizeof(xfer)); xfer.tx_buf = &st->tx_buf; xfer.rx_buf = &st->rx_buf; xfer.len = indio_dev->num_channels*3; /*assuming all channels enabled*/ xfer.delay_usecs = 2; xfer.cs_change = 0; xfer.bits_per_word = 8; spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->spi, &msg); if (ret) goto err; /* Unpacking data */ test++; st->samples_data[0] = (unsigned char)(test & 0xFF); st->samples_data[1] = (unsigned char)(test >> 8 & 0xFF); st->samples_data[2] = (unsigned char)(test >> 16 & 0xFF); st->samples_data[3] = (unsigned char)(test >> 24 & 0xFF); iio_push_to_buffers(indio_dev, st->samples_data); err: iio_trigger_notify_done(indio_dev->trig); enable_irq(st->spi->irq); return IRQ_HANDLED; } static int customdevice_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct customdevice_state *st = iio_priv(indio_dev); /* We have to make sure to output all zeros on the SDO line */ memset(st->tx_buf, 0x00, customdevice_SPI_MAX_FRAMESIZE); st->samples_data = krealloc(st->samples_data, indio_dev->scan_bytes, GFP_KERNEL); if (!st->samples_data) return -ENOMEM; return 0; } // data leads channels enum customdevice_channel_leads { CUSTOMDEVICE_1, CUSTOMDEVICE_2, CUSTOMDEVICE_3, CUSTOMDEVICE_4, CUSTOMDEVICE_5, CUSTOMDEVICE_6, CUSTOMDEVICE_7, CUSTOMDEVICE_8, CUSTOMDEVICE_9, }; #define customdevice_ADC_CHAN(_chan1, _scan_index, _extend_name) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .differential = 1, \ .channel = (_chan1), \ .scan_index = (_scan_index), \ .scan_type = { \ .sign = 'u', \ .realbits = 24, \ .storagebits = 32, \ .shift = 0, \ .endianness = IIO_BE, \ }, \ .extend_name = (_extend_name), \ } static const struct iio_chan_spec customdevice_channels[] = { customdevice_ADC_CHAN(CUSTOMDEVICE_1, 0, "1"), customdevice_ADC_CHAN(CUSTOMDEVICE_2, 1, "2"), customdevice_ADC_CHAN(CUSTOMDEVICE_3, 2, "3"), customdevice_ADC_CHAN(CUSTOMDEVICE_4, 3, "4"), customdevice_ADC_CHAN(CUSTOMDEVICE_5, 4, "5"), customdevice_ADC_CHAN(CUSTOMDEVICE_6, 5, "6"), customdevice_ADC_CHAN(CUSTOMDEVICE_7, 6, "7"), customdevice_ADC_CHAN(CUSTOMDEVICE_8, 7, "8"), customdevice_ADC_CHAN(CUSTOMDEVICE_9, 8, "9"), }; static const struct iio_trigger_ops customdevice_trigger_ops = { .owner = THIS_MODULE, }; static irqreturn_t customdevice_trigger_irq(int irq, void *data) { struct customdevice_state *st = data; struct iio_trigger *trig = st->trig; if (!st->sampling) { disable_irq_nosync(irq); st->irq_enabled = false; return IRQ_HANDLED; } iio_trigger_poll(trig, iio_get_time_ns()); disable_irq_nosync(irq); return IRQ_HANDLED; } static struct iio_trigger *customdevice_allocate_trigger(struct iio_dev *indio_dev, int irq) { struct customdevice_state *st = iio_priv(indio_dev); struct iio_trigger *trig; int ret; trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, indio_dev->id); if (!trig) return NULL; trig->dev.parent = indio_dev->dev.parent; trig->ops = &customdevice_trigger_ops; ret = request_irq(irq, customdevice_trigger_irq, IRQF_TRIGGER_LOW, trig->name, st); if (ret) return NULL; indio_dev->trig = trig; iio_trigger_get(indio_dev->trig); ret = iio_trigger_register(trig); if (ret) { free_irq(irq, trig); return NULL; } return trig; } static const struct iio_info customdevice_info = { .update_scan_mode = customdevice_update_scan_mode, .debugfs_reg_access = customdevice_debugfs_reg_access, .driver_module = THIS_MODULE, }; static int customdevice_inital_setup(struct iio_dev *indio_dev, struct customdevice_platform_data *pdata) { int ret; unsigned char id; ret = customdevice_init_gpio_pins(indio_dev); if (ret) return ret; // reset device customdevice_reset_by_gpio(); customdevice_acquire_by_gpio(false); return ret; } static int customdevice_probe(struct spi_device *spi) { struct customdevice_platform_data *pdata = spi->dev.platform_data; struct iio_dev *indio_dev; struct customdevice_state *st; int ret; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); indio_dev = iio_device_alloc(sizeof(*st)); if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); mutex_init(&st->lock); spi_set_drvdata(spi, indio_dev); st->spi = spi; indio_dev->dev.parent = &spi->dev; indio_dev->name = spi_get_device_id(spi)->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &customdevice_info; indio_dev->channels = customdevice_channels; indio_dev->num_channels = ARRAY_SIZE(customdevice_channels); printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ret = customdevice_inital_setup(indio_dev, pdata); if (ret) goto error_free; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, &customdevice_trigger_handler, &iio_triggered_buffer_setup_ops); if (ret) goto error_free; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); st->irq_enabled = true; if (spi->irq) st->trig = customdevice_allocate_trigger(indio_dev, spi->irq); ret = iio_device_register(indio_dev); if (ret) goto error_buffer_cleanup; printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); customdevice_debugfs_init(indio_dev); printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); return 0; error_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); error_free: iio_device_free(indio_dev); printk(KERN_ALERT "DEBUG: Passed %s %d \n",__FUNCTION__,__LINE__); return ret; } static int customdevice_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct customdevice_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); iio_triggered_buffer_cleanup(indio_dev); kfree(st->samples_data); mutex_destroy(&st->lock); iio_device_free(indio_dev); return 0; } static const struct of_device_id customdevice_dt_ids[] = { { .compatible = "customdevice" }, { } }; MODULE_DEVICE_TABLE(of, customdevice_dt_ids); static const struct spi_device_id customdevice_ids[] = { {"customdevice", 0}, { } }; MODULE_DEVICE_TABLE(spi, customdevice_ids); static struct spi_driver customdevice_driver = { .driver = { .name = "customdevice", .owner = THIS_MODULE, .of_match_table = of_match_ptr(customdevice_dt_ids), }, .probe = customdevice_probe, .remove = customdevice_remove, .id_table = customdevice_ids, }; module_spi_driver(customdevice_driver); -------------------- On Sun, Dec 13, 2015 at 8:14 PM, Jonathan Cameron <jic23@xxxxxxxxxxxxxxxxxxxxx> wrote: > > > On 13 December 2015 10:44:29 GMT+00:00, Julio Cruz <jcsistemas2001@xxxxxxxxx> wrote: >>Hi Jonathan, >> >>Right now, the app is able to read the data from /dev/iio:device0 with >>success (not data loss). Currently, the app read 1 sample (with 9 >>channels of 4 bytes each one) every time (using "read" function). >> >>I still have some doubts about my implementation, because, sometimes >>there is data lost. >> >>For example, when the app try to read more than 1 sample (for example, >>2 samples: 72 bytes, using "read"), the results are strange. For >>instance, when the app is using libiio, the function iio_buffer_refill >>return -1 and is not able to receive data. > That is definitely odd. > Perhaps you could post the content of all the files under scan_elements so we can > check nothing odd has happened with the channel definitions. > > > In this case, the buffer >>(at iio_device_create_buffer) need to be setup with 1 sample to work. >> >>Below some assumptions/questions: >> >>- The buffer/length define the kfifo length (in samples, not in >>bytes)? > Number and of scans where a scan is one sample from all enabled channels. > >> In this case, the buffer must be multiple of 36 bytes right? > The one you are reading into should be. >>- At user space, the application can read 36 bytes or more (i.e. 72, >>...) (/dev/iio:device0) (but not less)? According with the buffer >>length. > Yes. > > So I have no idea what is going on. Can only suggest you add printks to find out > what exactly is causing that error return > > Any chance you could post the driver? >> >>Thanks >> >> >>On Sat, Dec 12, 2015 at 8:41 PM, Julio Cruz <jcsistemas2001@xxxxxxxxx> >>wrote: >>> OK, I understood! Thanks >>> >>> I will use 32 bits for storage in all the channels >>> >>> On Sat, Dec 12, 2015 at 8:35 PM, Jonathan Cameron >>> <jic23@xxxxxxxxxxxxxxxxxxxxx> wrote: >>>> On 12/12/15 12:24, Julio Cruz wrote: >>>>> HI Jonathan, >>>> Hi Julio >>>> >>>> I've kept the list cc'd as this sort of conversation acts as >>>> 'free' documentation solving other people's problems in future. >>>> >>>>> >>>>> Thanks for your quick reply. >>>>> >>>>> When you mention the alignment, I remember some things that I did >>>>> about it, as below. >>>>> >>>>> When I started testing the _trigger_handler, I found that the >>driver >>>>> calculate indio_dev->scan_bytes. This value is not clear to me >>>>> because, for example, 1 channel is 3 bytes, >>>> It shouldn't be. Padding is to the nearest power of 2 bytes so >>should >>>> be 4. The non power of two realbits may have resulted in an >>unexpected >>>> path in which case we should add a sanity check to catch this. >>>>> and for 2 channels is 8 >>>>> bytes (1 byte padding). The channel spec are realbits = 24 and >>>>> storagebits = 24. >>>> Storage bits should be a power of 2. So in this case 32 bytes. >>>> Might seem wasteful but processors handle aligned data a lot >>>> more easily so to keep rates up it is usually better to burn a small >>>> amount of memory and keep everything aligned. >>>> >>>> At that point, I fixed the frame buffer size to 27 >>>>> (used at iio_push_to_buffers) assuming that the same buffer could >>be >>>>> read at user space. >>>>> >>>>> Please, may I know if this approach is correct? >>>> Sorry nope, the buffer structure assumes power of 2 alignment >>everywhere. >>>>> >>>>> The SPI device send 9 channels, 3 bytes each one (for a total of 27 >>>>> bytes) and each channels is 24 bits width. >>>> Unfortunately you'll have to do unpacking of this before pushing to >>the buffer. >>>> It'll have to happen somewhere anyway (as userspace code would need >>to unpack >>>> it otherwise). >>>> >>>> It's actually relatively unusual to find a device that does this >>sort of >>>> packing. We have talked in the past about allowing this sort of >>packing and >>>> modifying the buffer infrastructure to accept it, but I'm >>unconvinced that >>>> it is worth the added complexity + cost in userspace complexity. >>>> >>>> Jonathan >>>>> >>>>> Thanks >>>>> >>>>> Julio >>>>> >>>>> >>>>> On Sat, Dec 12, 2015 at 7:51 PM, Jonathan Cameron >><jic23@xxxxxxxxxx> wrote: >>>>>> On 12/12/15 08:36, Julio Cruz wrote: >>>>>>> Hi, >>>>>>> >>>>>>> I get an error trying to read /dev/iio:device0 in a custom >>application >>>>>>> (C/C++), however in a terminal the command "cat /dev/iio_device0" >>>>>>> return data. >>>>>>> >>>>>>> Below the procedure: >>>>>>> >>>>>>> - enable channels >>>>>>> - setup trigger >>>>>>> - setup buffer lenght >>>>>>> - enable buffer (the SPI interrupt is setup properly and all the >>>>>>> trigger handler are done) >>>>>>> - read /dev/iio_device0 >>>>>>> >>>>>>> It's a SPI device acquiring 27 bytes @ 1KHz. >>>>>> Reading this again after point 4 below this makes me ask the >>question >>>>>> what are you pushing into the buffer? 27 bytes seems unlikely >>given >>>>>> the alignment requirements. >>>>>> >>>>>>> >>>>>>> Results: >>>>>>> >>>>>>> 1. Custom application (based on generic_buffer.c): function >>'read' >>>>>>> return -1 and strerror(errno) return "Invalid argument" >>>>>>> 2. iio_readdev (libiio): show the message "Unable to refill >>buffer: >>>>>>> Input/output error" >>>>>>> 3. In terminal, the command "cat /dev/iio_device0" show values >>(no >>>>>>> readable) while the buffer is enable. >>>>>>> >>>>>>> Any suggestion? >>>>>>> >>>>>>> Thanks for your help! >>>>>> Sounds like you are ultimately getting that error from a call to >>>>>> iio_buffer_read_first_n_outer >>>>>> so what can return -EINVAL (which is -1)? >>>>>> >>>>>> 1) Buffer not being allocated (seems unlikely - that's really just >>to >>>>>> pick up on bugs in side the driver) >>>>>> 2) read_first_n from the buffer not supplied - again not likely. >>>>>> 3) wait_event_interruptible returns it - unlikely. >>>>>> 4) read_first_n which comes from the buffer implementation is >>returning -EINVAL >>>>>> This last one seems most likely. >>>>>> >>>>>> So I am guessing you are using the kfifo buffer (most common >>option). >>>>>> Reasons this can return -EINVAL are >>>>>> 1) kfifo not initialized (unlikely) >>>>>> 2) Read length is less than the buffer element size (which is the >>full scan storage >>>>>> size) >>>>>> 3) an error from kfifo_to_user (unlikely) >>>>>> >>>>>> So I'm guessing you are reading too small an amount of data. >>(tricky to chase >>>>>> down without adding further printk's etc to the relevant bits of >>kernel code) >>>>>> If I've 'guessed' right, interesting question is how this came >>about. >>>>>> How many bytes is it trying to read? >>>>>> >>>>>> Note that IIO has strict alignment requirements - any element must >>be aligned >>>>>> to it's own size and this will in some case add lots of padding. >>The full buffer >>>>>> element will be a multiple of the largest element in the scan. If >>you have a timestamp >>>>>> for example at 64bits the whole buffer element will be a multiple >>of 8bytes. >>>>>> >>>>>> Jonathan >>>>>>> -- >>>>>>> To unsubscribe from this list: send the line "unsubscribe >>linux-iio" in >>>>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx >>>>>>> More majordomo info at >>http://vger.kernel.org/majordomo-info.html >>>>>>> >>>>>> >>>> > > -- > Sent from my Android device with K-9 Mail. Please excuse my brevity. -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html