aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan T. Ivanov <iivanov@mm-sol.com>2014-10-22 11:29:43 -0400
committerJonathan Cameron <jic23@kernel.org>2014-10-25 06:03:40 -0400
commitacd8256723f286b7217801fbed24503f8565b91e (patch)
tree1cde7b390ee2e9afb3981a0c6368b6f9042ebcc3
parenta9bef750135cc261bfceff6840a30a3f357df8da (diff)
iio: inkern: Add of_xlate function to struct iio_info
When #iio-cells is greater than '0', the driver could provide a custom of_xlate function that reads the *args* and returns the appropriate index in registered IIO channels array. Add simple translation function, suitable for the most 1:1 mapped channels in IIO chips, and use it when driver did not provide custom implementation. Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/inkern.c33
-rw-r--r--include/linux/iio/iio.h8
2 files changed, 36 insertions, 5 deletions
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index c7497009d60a..0cc505d98686 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -100,6 +100,28 @@ static int iio_dev_node_match(struct device *dev, void *data)
100 return dev->of_node == data && dev->type == &iio_device_type; 100 return dev->of_node == data && dev->type == &iio_device_type;
101} 101}
102 102
103/**
104 * __of_iio_simple_xlate - translate iiospec to the IIO channel index
105 * @indio_dev: pointer to the iio_dev structure
106 * @iiospec: IIO specifier as found in the device tree
107 *
108 * This is simple translation function, suitable for the most 1:1 mapped
109 * channels in IIO chips. This function performs only one sanity check:
110 * whether IIO index is less than num_channels (that is specified in the
111 * iio_dev).
112 */
113static int __of_iio_simple_xlate(struct iio_dev *indio_dev,
114 const struct of_phandle_args *iiospec)
115{
116 if (!iiospec->args_count)
117 return 0;
118
119 if (iiospec->args[0] >= indio_dev->num_channels)
120 return -EINVAL;
121
122 return iiospec->args[0];
123}
124
103static int __of_iio_channel_get(struct iio_channel *channel, 125static int __of_iio_channel_get(struct iio_channel *channel,
104 struct device_node *np, int index) 126 struct device_node *np, int index)
105{ 127{
@@ -122,18 +144,19 @@ static int __of_iio_channel_get(struct iio_channel *channel,
122 144
123 indio_dev = dev_to_iio_dev(idev); 145 indio_dev = dev_to_iio_dev(idev);
124 channel->indio_dev = indio_dev; 146 channel->indio_dev = indio_dev;
125 index = iiospec.args_count ? iiospec.args[0] : 0; 147 if (indio_dev->info->of_xlate)
126 if (index >= indio_dev->num_channels) { 148 index = indio_dev->info->of_xlate(indio_dev, &iiospec);
127 err = -EINVAL; 149 else
150 index = __of_iio_simple_xlate(indio_dev, &iiospec);
151 if (index < 0)
128 goto err_put; 152 goto err_put;
129 }
130 channel->channel = &indio_dev->channels[index]; 153 channel->channel = &indio_dev->channels[index];
131 154
132 return 0; 155 return 0;
133 156
134err_put: 157err_put:
135 iio_device_put(indio_dev); 158 iio_device_put(indio_dev);
136 return err; 159 return index;
137} 160}
138 161
139static struct iio_channel *of_iio_channel_get(struct device_node *np, int index) 162static struct iio_channel *of_iio_channel_get(struct device_node *np, int index)
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 15dc6bc2bdd2..3642ce7ef512 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/cdev.h> 14#include <linux/cdev.h>
15#include <linux/iio/types.h> 15#include <linux/iio/types.h>
16#include <linux/of.h>
16/* IIO TODO LIST */ 17/* IIO TODO LIST */
17/* 18/*
18 * Provide means of adjusting timer accuracy. 19 * Provide means of adjusting timer accuracy.
@@ -326,6 +327,11 @@ struct iio_dev;
326 * @update_scan_mode: function to configure device and scan buffer when 327 * @update_scan_mode: function to configure device and scan buffer when
327 * channels have changed 328 * channels have changed
328 * @debugfs_reg_access: function to read or write register value of device 329 * @debugfs_reg_access: function to read or write register value of device
330 * @of_xlate: function pointer to obtain channel specifier index.
331 * When #iio-cells is greater than '0', the driver could
332 * provide a custom of_xlate function that reads the
333 * *args* and returns the appropriate index in registered
334 * IIO channels array.
329 **/ 335 **/
330struct iio_info { 336struct iio_info {
331 struct module *driver_module; 337 struct module *driver_module;
@@ -385,6 +391,8 @@ struct iio_info {
385 int (*debugfs_reg_access)(struct iio_dev *indio_dev, 391 int (*debugfs_reg_access)(struct iio_dev *indio_dev,
386 unsigned reg, unsigned writeval, 392 unsigned reg, unsigned writeval,
387 unsigned *readval); 393 unsigned *readval);
394 int (*of_xlate)(struct iio_dev *indio_dev,
395 const struct of_phandle_args *iiospec);
388}; 396};
389 397
390/** 398/**