iio: Add buffer enable/disable callbacks
This patch adds a enable and disable callback that is called when the buffer is enabled/disabled. This can be used by buffer implementations that need to do some setup or teardown work. E.g. a DMA based buffer can use this to start/stop the DMA transfer. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
This commit is contained in:
parent
b440655b89
commit
e18a2ad45c
|
@ -568,6 +568,22 @@ static void iio_buffer_deactivate_all(struct iio_dev *indio_dev)
|
||||||
iio_buffer_deactivate(buffer);
|
iio_buffer_deactivate(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iio_buffer_enable(struct iio_buffer *buffer,
|
||||||
|
struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
if (!buffer->access->enable)
|
||||||
|
return 0;
|
||||||
|
return buffer->access->enable(buffer, indio_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iio_buffer_disable(struct iio_buffer *buffer,
|
||||||
|
struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
if (!buffer->access->disable)
|
||||||
|
return 0;
|
||||||
|
return buffer->access->disable(buffer, indio_dev);
|
||||||
|
}
|
||||||
|
|
||||||
static void iio_buffer_update_bytes_per_datum(struct iio_dev *indio_dev,
|
static void iio_buffer_update_bytes_per_datum(struct iio_dev *indio_dev,
|
||||||
struct iio_buffer *buffer)
|
struct iio_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
@ -719,6 +735,7 @@ static int iio_verify_update(struct iio_dev *indio_dev,
|
||||||
static int iio_enable_buffers(struct iio_dev *indio_dev,
|
static int iio_enable_buffers(struct iio_dev *indio_dev,
|
||||||
struct iio_device_config *config)
|
struct iio_device_config *config)
|
||||||
{
|
{
|
||||||
|
struct iio_buffer *buffer;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
indio_dev->active_scan_mask = config->scan_mask;
|
indio_dev->active_scan_mask = config->scan_mask;
|
||||||
|
@ -753,6 +770,12 @@ static int iio_enable_buffers(struct iio_dev *indio_dev,
|
||||||
indio_dev->info->hwfifo_set_watermark(indio_dev,
|
indio_dev->info->hwfifo_set_watermark(indio_dev,
|
||||||
config->watermark);
|
config->watermark);
|
||||||
|
|
||||||
|
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
|
||||||
|
ret = iio_buffer_enable(buffer, indio_dev);
|
||||||
|
if (ret)
|
||||||
|
goto err_disable_buffers;
|
||||||
|
}
|
||||||
|
|
||||||
indio_dev->currentmode = config->mode;
|
indio_dev->currentmode = config->mode;
|
||||||
|
|
||||||
if (indio_dev->setup_ops->postenable) {
|
if (indio_dev->setup_ops->postenable) {
|
||||||
|
@ -760,12 +783,16 @@ static int iio_enable_buffers(struct iio_dev *indio_dev,
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_dbg(&indio_dev->dev,
|
dev_dbg(&indio_dev->dev,
|
||||||
"Buffer not started: postenable failed (%d)\n", ret);
|
"Buffer not started: postenable failed (%d)\n", ret);
|
||||||
goto err_run_postdisable;
|
goto err_disable_buffers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_disable_buffers:
|
||||||
|
list_for_each_entry_continue_reverse(buffer, &indio_dev->buffer_list,
|
||||||
|
buffer_list)
|
||||||
|
iio_buffer_disable(buffer, indio_dev);
|
||||||
err_run_postdisable:
|
err_run_postdisable:
|
||||||
indio_dev->currentmode = INDIO_DIRECT_MODE;
|
indio_dev->currentmode = INDIO_DIRECT_MODE;
|
||||||
if (indio_dev->setup_ops->postdisable)
|
if (indio_dev->setup_ops->postdisable)
|
||||||
|
@ -778,6 +805,7 @@ err_undo_config:
|
||||||
|
|
||||||
static int iio_disable_buffers(struct iio_dev *indio_dev)
|
static int iio_disable_buffers(struct iio_dev *indio_dev)
|
||||||
{
|
{
|
||||||
|
struct iio_buffer *buffer;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int ret2;
|
int ret2;
|
||||||
|
|
||||||
|
@ -798,6 +826,12 @@ static int iio_disable_buffers(struct iio_dev *indio_dev)
|
||||||
ret = ret2;
|
ret = ret2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
|
||||||
|
ret2 = iio_buffer_disable(buffer, indio_dev);
|
||||||
|
if (ret2 && !ret)
|
||||||
|
ret = ret2;
|
||||||
|
}
|
||||||
|
|
||||||
indio_dev->currentmode = INDIO_DIRECT_MODE;
|
indio_dev->currentmode = INDIO_DIRECT_MODE;
|
||||||
|
|
||||||
if (indio_dev->setup_ops->postdisable) {
|
if (indio_dev->setup_ops->postdisable) {
|
||||||
|
|
|
@ -33,6 +33,11 @@ struct iio_buffer;
|
||||||
* storage.
|
* storage.
|
||||||
* @set_bytes_per_datum:set number of bytes per datum
|
* @set_bytes_per_datum:set number of bytes per datum
|
||||||
* @set_length: set number of datums in buffer
|
* @set_length: set number of datums in buffer
|
||||||
|
* @enable: called if the buffer is attached to a device and the
|
||||||
|
* device starts sampling. Calls are balanced with
|
||||||
|
* @disable.
|
||||||
|
* @disable: called if the buffer is attached to a device and the
|
||||||
|
* device stops sampling. Calles are balanced with @enable.
|
||||||
* @release: called when the last reference to the buffer is dropped,
|
* @release: called when the last reference to the buffer is dropped,
|
||||||
* should free all resources allocated by the buffer.
|
* should free all resources allocated by the buffer.
|
||||||
* @modes: Supported operating modes by this buffer type
|
* @modes: Supported operating modes by this buffer type
|
||||||
|
@ -58,6 +63,9 @@ struct iio_buffer_access_funcs {
|
||||||
int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
|
int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
|
||||||
int (*set_length)(struct iio_buffer *buffer, int length);
|
int (*set_length)(struct iio_buffer *buffer, int length);
|
||||||
|
|
||||||
|
int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
|
||||||
|
int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
|
||||||
|
|
||||||
void (*release)(struct iio_buffer *buffer);
|
void (*release)(struct iio_buffer *buffer);
|
||||||
|
|
||||||
unsigned int modes;
|
unsigned int modes;
|
||||||
|
|
Loading…
Reference in New Issue