|
7 | 7 | * Author: Peter Rosin <[email protected]>
|
8 | 8 | */
|
9 | 9 |
|
| 10 | +#include <linux/cleanup.h> |
10 | 11 | #include <linux/err.h>
|
11 | 12 | #include <linux/iio/consumer.h>
|
12 | 13 | #include <linux/iio/iio.h>
|
@@ -237,49 +238,18 @@ static ssize_t mux_write_ext_info(struct iio_dev *indio_dev, uintptr_t private,
|
237 | 238 | return ret;
|
238 | 239 | }
|
239 | 240 |
|
240 |
| -static int mux_configure_channel(struct device *dev, struct mux *mux, |
241 |
| - u32 state, const char *label, int idx) |
| 241 | +static int mux_configure_chan_ext_info(struct device *dev, struct mux *mux, |
| 242 | + int idx, int num_ext_info) |
242 | 243 | {
|
243 | 244 | struct mux_child *child = &mux->child[idx];
|
244 |
| - struct iio_chan_spec *chan = &mux->chan[idx]; |
245 | 245 | struct iio_chan_spec const *pchan = mux->parent->channel;
|
246 |
| - char *page = NULL; |
247 |
| - int num_ext_info; |
248 | 246 | int i;
|
249 | 247 | int ret;
|
250 | 248 |
|
251 |
| - chan->indexed = 1; |
252 |
| - chan->output = pchan->output; |
253 |
| - chan->datasheet_name = label; |
254 |
| - chan->ext_info = mux->ext_info; |
255 |
| - |
256 |
| - ret = iio_get_channel_type(mux->parent, &chan->type); |
257 |
| - if (ret < 0) { |
258 |
| - dev_err(dev, "failed to get parent channel type\n"); |
259 |
| - return ret; |
260 |
| - } |
261 |
| - |
262 |
| - if (iio_channel_has_info(pchan, IIO_CHAN_INFO_RAW)) |
263 |
| - chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW); |
264 |
| - if (iio_channel_has_info(pchan, IIO_CHAN_INFO_SCALE)) |
265 |
| - chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE); |
266 |
| - |
267 |
| - if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW)) |
268 |
| - chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW); |
269 |
| - |
270 |
| - if (state >= mux_control_states(mux->control)) { |
271 |
| - dev_err(dev, "too many channels\n"); |
272 |
| - return -EINVAL; |
273 |
| - } |
274 |
| - |
275 |
| - chan->channel = state; |
| 249 | + char *page __free(kfree) = kzalloc(PAGE_SIZE, GFP_KERNEL); |
| 250 | + if (!page) |
| 251 | + return -ENOMEM; |
276 | 252 |
|
277 |
| - num_ext_info = iio_get_channel_ext_info_count(mux->parent); |
278 |
| - if (num_ext_info) { |
279 |
| - page = devm_kzalloc(dev, PAGE_SIZE, GFP_KERNEL); |
280 |
| - if (!page) |
281 |
| - return -ENOMEM; |
282 |
| - } |
283 | 253 | child->ext_info_cache = devm_kcalloc(dev,
|
284 | 254 | num_ext_info,
|
285 | 255 | sizeof(*child->ext_info_cache),
|
@@ -318,8 +288,46 @@ static int mux_configure_channel(struct device *dev, struct mux *mux,
|
318 | 288 | child->ext_info_cache[i].size = ret;
|
319 | 289 | }
|
320 | 290 |
|
321 |
| - if (page) |
322 |
| - devm_kfree(dev, page); |
| 291 | + return 0; |
| 292 | +} |
| 293 | + |
| 294 | +static int mux_configure_channel(struct device *dev, struct mux *mux, u32 state, |
| 295 | + const char *label, int idx) |
| 296 | +{ |
| 297 | + struct iio_chan_spec *chan = &mux->chan[idx]; |
| 298 | + struct iio_chan_spec const *pchan = mux->parent->channel; |
| 299 | + int num_ext_info; |
| 300 | + int ret; |
| 301 | + |
| 302 | + chan->indexed = 1; |
| 303 | + chan->output = pchan->output; |
| 304 | + chan->datasheet_name = label; |
| 305 | + chan->ext_info = mux->ext_info; |
| 306 | + |
| 307 | + ret = iio_get_channel_type(mux->parent, &chan->type); |
| 308 | + if (ret < 0) { |
| 309 | + dev_err(dev, "failed to get parent channel type\n"); |
| 310 | + return ret; |
| 311 | + } |
| 312 | + |
| 313 | + if (iio_channel_has_info(pchan, IIO_CHAN_INFO_RAW)) |
| 314 | + chan->info_mask_separate |= BIT(IIO_CHAN_INFO_RAW); |
| 315 | + if (iio_channel_has_info(pchan, IIO_CHAN_INFO_SCALE)) |
| 316 | + chan->info_mask_separate |= BIT(IIO_CHAN_INFO_SCALE); |
| 317 | + |
| 318 | + if (iio_channel_has_available(pchan, IIO_CHAN_INFO_RAW)) |
| 319 | + chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW); |
| 320 | + |
| 321 | + if (state >= mux_control_states(mux->control)) { |
| 322 | + dev_err(dev, "too many channels\n"); |
| 323 | + return -EINVAL; |
| 324 | + } |
| 325 | + |
| 326 | + chan->channel = state; |
| 327 | + |
| 328 | + num_ext_info = iio_get_channel_ext_info_count(mux->parent); |
| 329 | + if (num_ext_info) |
| 330 | + return mux_configure_chan_ext_info(dev, mux, idx, num_ext_info); |
323 | 331 |
|
324 | 332 | return 0;
|
325 | 333 | }
|
|
0 commit comments