diff options
author | Ivan T. Ivanov <iivanov@mm-sol.com> | 2014-10-22 11:29:43 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2014-10-25 06:03:40 -0400 |
commit | acd8256723f286b7217801fbed24503f8565b91e (patch) | |
tree | 1cde7b390ee2e9afb3981a0c6368b6f9042ebcc3 | |
parent | a9bef750135cc261bfceff6840a30a3f357df8da (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.c | 33 | ||||
-rw-r--r-- | include/linux/iio/iio.h | 8 |
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 | */ | ||
113 | static 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 | |||
103 | static int __of_iio_channel_get(struct iio_channel *channel, | 125 | static 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 | ||
134 | err_put: | 157 | err_put: |
135 | iio_device_put(indio_dev); | 158 | iio_device_put(indio_dev); |
136 | return err; | 159 | return index; |
137 | } | 160 | } |
138 | 161 | ||
139 | static struct iio_channel *of_iio_channel_get(struct device_node *np, int index) | 162 | static 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 | **/ |
330 | struct iio_info { | 336 | struct 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 | /** |