BigW Consortium Gitlab

Commit a790ca50 by David Frey

Copy iio kernel code from legato kernel source

parent aab97bcb
IIO Kernel Module Definitions
=============================
The source for the IIO kernel modules is part of the standard Legato Linux
kernel source tree, but the module is not built by default. As a result, we
build this as an out of tree kernel module, but we don't want to version a copy
of the source files.
Instead, it is suggested to put a symlink to each of the sdef files in `[yocto
working copy]/kernel/drivers/iio/` and then refer to the mdef files in the sdef
using an environment variable. For example:
`${LEGATO_KERNELSRC}/drivers/iio/iio`.
The IIO modules are required by the BMP280 pressure sensor driver module.
The source for the IIO kernel modules comes from the standard Legato Linux kernel source tree. The
source is copied into this directory so that it isn't necessary to have the full kernel source code
in order to build the mangOH SDEF.
The kernel source in this folder was copied from the tag `SWI9X15Y_07.12.01.00`
cflags:
{
-DCONFIG_IIO
-DCONFIG_IIO_BUFFER
-DCONFIG_IIO_TRIGGER
-DCONFIG_IIO_KFIFO_BUF
-DCONFIG_IIO_TRIGGERED_BUFFER
}
sources:
{
// IIO_KFIFO_BUF
industrialio-triggered-buffer.c
}
/* The industrial I/O core function defs.
*
* Copyright (c) 2008 Jonathan Cameron
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* These definitions are meant for use only within the IIO core, not individual
* drivers.
*/
#ifndef _IIO_CORE_H_
#define _IIO_CORE_H_
#include <linux/kernel.h>
#include <linux/device.h>
struct iio_chan_spec;
struct iio_dev;
extern struct device_type iio_device_type;
int __iio_add_chan_devattr(const char *postfix,
struct iio_chan_spec const *chan,
ssize_t (*func)(struct device *dev,
struct device_attribute *attr,
char *buf),
ssize_t (*writefunc)(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t len),
u64 mask,
enum iio_shared_by shared_by,
struct device *dev,
struct list_head *attr_list);
void iio_free_chan_devattr_list(struct list_head *attr_list);
ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2);
/* Event interface flags */
#define IIO_BUSY_BIT_POS 1
#ifdef CONFIG_IIO_BUFFER
struct poll_table_struct;
unsigned int iio_buffer_poll(struct file *filp,
struct poll_table_struct *wait);
ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
size_t n, loff_t *f_ps);
#define iio_buffer_poll_addr (&iio_buffer_poll)
#define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
void iio_disable_all_buffers(struct iio_dev *indio_dev);
void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
#else
#define iio_buffer_poll_addr NULL
#define iio_buffer_read_first_n_outer_addr NULL
static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {}
#endif
int iio_device_register_eventset(struct iio_dev *indio_dev);
void iio_device_unregister_eventset(struct iio_dev *indio_dev);
void iio_device_wakeup_eventset(struct iio_dev *indio_dev);
int iio_event_getfd(struct iio_dev *indio_dev);
#endif
/* The industrial I/O core, trigger consumer handling functions
*
* Copyright (c) 2008 Jonathan Cameron
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#ifdef CONFIG_IIO_TRIGGER
/**
* iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
* @indio_dev: iio_dev associated with the device that will consume the trigger
**/
void iio_device_register_trigger_consumer(struct iio_dev *indio_dev);
/**
* iio_device_unregister_trigger_consumer() - reverse the registration process
* @indio_dev: iio_dev associated with the device that consumed the trigger
**/
void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev);
#else
/**
* iio_device_register_trigger_consumer() - set up an iio_dev to use triggers
* @indio_dev: iio_dev associated with the device that will consume the trigger
**/
static int iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
{
return 0;
}
/**
* iio_device_unregister_trigger_consumer() - reverse the registration process
* @indio_dev: iio_dev associated with the device that consumed the trigger
**/
static void iio_device_unregister_trigger_consumer(struct iio_dev *indio_dev)
{
}
#endif /* CONFIG_TRIGGER_CONSUMER */
/*
* Copyright (c) 2012 Analog Devices, Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
.postenable = &iio_triggered_buffer_postenable,
.predisable = &iio_triggered_buffer_predisable,
};
/**
* iio_triggered_buffer_setup() - Setup triggered buffer and pollfunc
* @indio_dev: IIO device structure
* @pollfunc_bh: Function which will be used as pollfunc bottom half
* @pollfunc_th: Function which will be used as pollfunc top half
* @setup_ops: Buffer setup functions to use for this device.
* If NULL the default setup functions for triggered
* buffers will be used.
*
* This function combines some common tasks which will normally be performed
* when setting up a triggered buffer. It will allocate the buffer and the
* pollfunc, as well as register the buffer with the IIO core.
*
* Before calling this function the indio_dev structure should already be
* completely initialized, but not yet registered. In practice this means that
* this function should be called right before iio_device_register().
*
* To free the resources allocated by this function call
* iio_triggered_buffer_cleanup().
*/
int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
irqreturn_t (*pollfunc_bh)(int irq, void *p),
irqreturn_t (*pollfunc_th)(int irq, void *p),
const struct iio_buffer_setup_ops *setup_ops)
{
struct iio_buffer *buffer;
int ret;
buffer = iio_kfifo_allocate(indio_dev);
if (!buffer) {
ret = -ENOMEM;
goto error_ret;
}
iio_device_attach_buffer(indio_dev, buffer);
indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh,
pollfunc_th,
IRQF_ONESHOT,
indio_dev,
"%s_consumer%d",
indio_dev->name,
indio_dev->id);
if (indio_dev->pollfunc == NULL) {
ret = -ENOMEM;
goto error_kfifo_free;
}
/* Ring buffer functions - here trigger setup related */
if (setup_ops)
indio_dev->setup_ops = setup_ops;
else
indio_dev->setup_ops = &iio_triggered_buffer_setup_ops;
/* Flag that polled ring buffering is possible */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
ret = iio_buffer_register(indio_dev,
indio_dev->channels,
indio_dev->num_channels);
if (ret)
goto error_dealloc_pollfunc;
return 0;
error_dealloc_pollfunc:
iio_dealloc_pollfunc(indio_dev->pollfunc);
error_kfifo_free:
iio_kfifo_free(indio_dev->buffer);
error_ret:
return ret;
}
EXPORT_SYMBOL(iio_triggered_buffer_setup);
/**
* iio_triggered_buffer_cleanup() - Free resources allocated by iio_triggered_buffer_setup()
* @indio_dev: IIO device structure
*/
void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
{
iio_buffer_unregister(indio_dev);
iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_kfifo_free(indio_dev->buffer);
}
EXPORT_SYMBOL(iio_triggered_buffer_cleanup);
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("IIO helper functions for setting up triggered buffers");
MODULE_LICENSE("GPL");
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/kfifo.h>
#include <linux/mutex.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/sched.h>
#include <linux/poll.h>
struct iio_kfifo {
struct iio_buffer buffer;
struct kfifo kf;
struct mutex user_lock;
int update_needed;
};
#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
int bytes_per_datum, int length)
{
if ((length == 0) || (bytes_per_datum == 0))
return -EINVAL;
return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
bytes_per_datum, GFP_KERNEL);
}
static int iio_request_update_kfifo(struct iio_buffer *r)
{
int ret = 0;
struct iio_kfifo *buf = iio_to_kfifo(r);
mutex_lock(&buf->user_lock);
if (buf->update_needed) {
kfifo_free(&buf->kf);
ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
buf->buffer.length);
buf->update_needed = false;
} else {
kfifo_reset_out(&buf->kf);
}
mutex_unlock(&buf->user_lock);
return ret;
}
static int iio_get_length_kfifo(struct iio_buffer *r)
{
return r->length;
}
static IIO_BUFFER_ENABLE_ATTR;
static IIO_BUFFER_LENGTH_ATTR;
static struct attribute *iio_kfifo_attributes[] = {
&dev_attr_length.attr,
&dev_attr_enable.attr,
NULL,
};
static struct attribute_group iio_kfifo_attribute_group = {
.attrs = iio_kfifo_attributes,
.name = "buffer",
};
static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r)
{
return r->bytes_per_datum;
}
static int iio_mark_update_needed_kfifo(struct iio_buffer *r)
{
struct iio_kfifo *kf = iio_to_kfifo(r);
kf->update_needed = true;
return 0;
}
static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
{
if (r->bytes_per_datum != bpd) {
r->bytes_per_datum = bpd;
iio_mark_update_needed_kfifo(r);
}
return 0;
}
static int iio_set_length_kfifo(struct iio_buffer *r, int length)
{
/* Avoid an invalid state */
if (length < 2)
length = 2;
if (r->length != length) {
r->length = length;
iio_mark_update_needed_kfifo(r);
}
return 0;
}
static int iio_store_to_kfifo(struct iio_buffer *r,
const void *data)
{
int ret;
struct iio_kfifo *kf = iio_to_kfifo(r);
ret = kfifo_in(&kf->kf, data, 1);
if (ret != 1)
return -EBUSY;
wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM);
return 0;
}
static int iio_read_first_n_kfifo(struct iio_buffer *r,
size_t n, char __user *buf)
{
int ret, copied;
struct iio_kfifo *kf = iio_to_kfifo(r);
if (mutex_lock_interruptible(&kf->user_lock))
return -ERESTARTSYS;
if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
ret = -EINVAL;
else
ret = kfifo_to_user(&kf->kf, buf, n, &copied);
mutex_unlock(&kf->user_lock);
if (ret < 0)
return ret;
return copied;
}
static bool iio_kfifo_buf_data_available(struct iio_buffer *r)
{
struct iio_kfifo *kf = iio_to_kfifo(r);
bool empty;
mutex_lock(&kf->user_lock);
empty = kfifo_is_empty(&kf->kf);
mutex_unlock(&kf->user_lock);
return !empty;
}
static void iio_kfifo_buffer_release(struct iio_buffer *buffer)
{
struct iio_kfifo *kf = iio_to_kfifo(buffer);
mutex_destroy(&kf->user_lock);
kfifo_free(&kf->kf);
kfree(kf);
}
static const struct iio_buffer_access_funcs kfifo_access_funcs = {
.store_to = &iio_store_to_kfifo,
.read_first_n = &iio_read_first_n_kfifo,
.data_available = iio_kfifo_buf_data_available,
.request_update = &iio_request_update_kfifo,
.get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
.set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
.get_length = &iio_get_length_kfifo,
.set_length = &iio_set_length_kfifo,
.release = &iio_kfifo_buffer_release,
};
struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
{
struct iio_kfifo *kf;
kf = kzalloc(sizeof *kf, GFP_KERNEL);
if (!kf)
return NULL;
kf->update_needed = true;
iio_buffer_init(&kf->buffer);
kf->buffer.attrs = &iio_kfifo_attribute_group;
kf->buffer.access = &kfifo_access_funcs;
kf->buffer.length = 2;
mutex_init(&kf->user_lock);
return &kf->buffer;
}
EXPORT_SYMBOL(iio_kfifo_allocate);
void iio_kfifo_free(struct iio_buffer *r)
{
iio_buffer_put(r);
}
EXPORT_SYMBOL(iio_kfifo_free);
MODULE_LICENSE("GPL");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment