Lines Matching +full:full +full:- +full:scale
1 // SPDX-License-Identifier: GPL-2.0
33 *val *= rescale->numerator; in rescale_process_scale()
34 if (rescale->denominator == 1) in rescale_process_scale()
36 *val2 = rescale->denominator; in rescale_process_scale()
44 if (!check_mul_overflow(*val, rescale->numerator, &_val) && in rescale_process_scale()
45 !check_mul_overflow(*val2, rescale->denominator, &_val2)) { in rescale_process_scale()
53 tmp = div_s64(tmp, rescale->denominator); in rescale_process_scale()
54 tmp *= rescale->numerator; in rescale_process_scale()
80 * For IIO_VAL_INT_PLUS_{MICRO,NANO} scale types if either *val in rescale_process_scale()
81 * OR *val2 is negative the schan scale is negative, i.e. in rescale_process_scale()
82 * *val = 1 and *val2 = -0.5 yields -1.5 not -0.5. in rescale_process_scale()
86 tmp = (s64)abs(*val) * abs(rescale->numerator); in rescale_process_scale()
87 *val = div_s64_rem(tmp, abs(rescale->denominator), &rem); in rescale_process_scale()
89 tmp = (s64)rem * mult + (s64)abs(*val2) * abs(rescale->numerator); in rescale_process_scale()
90 tmp = div_s64(tmp, abs(rescale->denominator)); in rescale_process_scale()
95 * If only one of the rescaler elements or the schan scale is in rescale_process_scale()
96 * negative, the combined scale is negative. in rescale_process_scale()
98 if (neg ^ ((rescale->numerator < 0) ^ (rescale->denominator < 0))) { in rescale_process_scale()
100 *val = -*val; in rescale_process_scale()
102 *val2 = -*val2; in rescale_process_scale()
107 return -EOPNOTSUPP; in rescale_process_scale()
113 int scale, int scale2, int schan_off, in rescale_process_offset()
120 tmp = (s64)rescale->offset * scale2; in rescale_process_offset()
121 *val = div_s64(tmp, scale) + schan_off; in rescale_process_offset()
124 *val = div_s64(rescale->offset, scale) + schan_off; in rescale_process_offset()
127 tmp = (s64)rescale->offset * (1 << scale2); in rescale_process_offset()
128 *val = div_s64(tmp, scale) + schan_off; in rescale_process_offset()
131 tmp = (s64)rescale->offset * 1000000000LL; in rescale_process_offset()
132 tmp2 = ((s64)scale * 1000000000LL) + scale2; in rescale_process_offset()
136 tmp = (s64)rescale->offset * 1000000LL; in rescale_process_offset()
137 tmp2 = ((s64)scale * 1000000LL) + scale2; in rescale_process_offset()
141 return -EOPNOTSUPP; in rescale_process_offset()
151 int scale, scale2; in rescale_read_raw() local
157 if (rescale->chan_processed) in rescale_read_raw()
160 * read the processed data and scale it by 1/1 in rescale_read_raw()
163 return iio_read_channel_processed(rescale->source, val); in rescale_read_raw()
165 return iio_read_channel_raw(rescale->source, val); in rescale_read_raw()
168 if (rescale->chan_processed) { in rescale_read_raw()
170 * Processed channels are scaled 1-to-1 in rescale_read_raw()
176 ret = iio_read_channel_scale(rescale->source, val, val2); in rescale_read_raw()
181 * Processed channels are scaled 1-to-1 and source offset is in rescale_read_raw()
201 * scale = schan_scale * rescaler_scale in rescale_read_raw()
204 if (rescale->chan_processed) { in rescale_read_raw()
205 *val = rescale->offset; in rescale_read_raw()
209 if (iio_channel_has_info(rescale->source->channel, in rescale_read_raw()
211 ret = iio_read_channel_offset(rescale->source, in rescale_read_raw()
214 return ret < 0 ? ret : -EOPNOTSUPP; in rescale_read_raw()
217 if (iio_channel_has_info(rescale->source->channel, in rescale_read_raw()
219 ret = iio_read_channel_scale(rescale->source, &scale, &scale2); in rescale_read_raw()
220 return rescale_process_offset(rescale, ret, scale, scale2, in rescale_read_raw()
225 * If we get here we have no scale so scale 1:1 but apply in rescale_read_raw()
231 return -EINVAL; in rescale_read_raw()
245 return iio_read_avail_channel_raw(rescale->source, in rescale_read_avail()
248 return -EINVAL; in rescale_read_avail()
264 return iio_read_channel_ext_info(rescale->source, in rescale_read_ext_info()
265 rescale->ext_info[private].name, in rescale_read_ext_info()
276 return iio_write_channel_ext_info(rescale->source, in rescale_write_ext_info()
277 rescale->ext_info[private].name, in rescale_write_ext_info()
284 struct iio_chan_spec *chan = &rescale->chan; in rescale_configure_channel()
285 struct iio_chan_spec const *schan = rescale->source->channel; in rescale_configure_channel()
287 chan->indexed = 1; in rescale_configure_channel()
288 chan->output = schan->output; in rescale_configure_channel()
289 chan->ext_info = rescale->ext_info; in rescale_configure_channel()
290 chan->type = rescale->cfg->type; in rescale_configure_channel()
295 dev_info(dev, "using raw+scale/offset source channel\n"); in rescale_configure_channel()
298 rescale->chan_processed = true; in rescale_configure_channel()
301 return -EINVAL; in rescale_configure_channel()
304 chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | in rescale_configure_channel()
307 if (rescale->offset) in rescale_configure_channel()
308 chan->info_mask_separate |= BIT(IIO_CHAN_INFO_OFFSET); in rescale_configure_channel()
316 !rescale->chan_processed) in rescale_configure_channel()
317 chan->info_mask_separate_available |= BIT(IIO_CHAN_INFO_RAW); in rescale_configure_channel()
331 ret = device_property_read_u32(dev, "sense-resistor-micro-ohms", in rescale_current_sense_amplifier_props()
338 device_property_read_u32(dev, "sense-gain-mult", &gain_mult); in rescale_current_sense_amplifier_props()
339 device_property_read_u32(dev, "sense-gain-div", &gain_div); in rescale_current_sense_amplifier_props()
347 rescale->numerator = 1000000 / factor; in rescale_current_sense_amplifier_props()
348 rescale->denominator = sense / factor; in rescale_current_sense_amplifier_props()
350 factor = gcd(rescale->numerator, gain_mult); in rescale_current_sense_amplifier_props()
351 rescale->numerator /= factor; in rescale_current_sense_amplifier_props()
352 rescale->denominator *= gain_mult / factor; in rescale_current_sense_amplifier_props()
354 factor = gcd(rescale->denominator, gain_div); in rescale_current_sense_amplifier_props()
355 rescale->numerator *= gain_div / factor; in rescale_current_sense_amplifier_props()
356 rescale->denominator /= factor; in rescale_current_sense_amplifier_props()
368 ret = device_property_read_u32(dev, "shunt-resistor-micro-ohms", in rescale_current_sense_shunt_props()
376 rescale->numerator = 1000000 / factor; in rescale_current_sense_shunt_props()
377 rescale->denominator = shunt / factor; in rescale_current_sense_shunt_props()
388 ret = device_property_read_u32(dev, "output-ohms", in rescale_voltage_divider_props()
389 &rescale->denominator); in rescale_voltage_divider_props()
391 dev_err(dev, "failed to read output-ohms: %d\n", ret); in rescale_voltage_divider_props()
395 ret = device_property_read_u32(dev, "full-ohms", in rescale_voltage_divider_props()
396 &rescale->numerator); in rescale_voltage_divider_props()
398 dev_err(dev, "failed to read full-ohms: %d\n", ret); in rescale_voltage_divider_props()
402 factor = gcd(rescale->numerator, rescale->denominator); in rescale_voltage_divider_props()
403 rescale->numerator /= factor; in rescale_voltage_divider_props()
404 rescale->denominator /= factor; in rescale_voltage_divider_props()
419 ret = device_property_read_u32(dev, "excitation-current-microamp", in rescale_temp_sense_rtd_props()
422 dev_err(dev, "failed to read excitation-current-microamp: %d\n", in rescale_temp_sense_rtd_props()
427 ret = device_property_read_u32(dev, "alpha-ppm-per-celsius", &alpha); in rescale_temp_sense_rtd_props()
429 dev_err(dev, "failed to read alpha-ppm-per-celsius: %d\n", in rescale_temp_sense_rtd_props()
434 ret = device_property_read_u32(dev, "r-naught-ohms", &r0); in rescale_temp_sense_rtd_props()
436 dev_err(dev, "failed to read r-naught-ohms: %d\n", ret); in rescale_temp_sense_rtd_props()
442 rescale->numerator = 1000000 / factor; in rescale_temp_sense_rtd_props()
443 rescale->denominator = tmp / factor; in rescale_temp_sense_rtd_props()
445 rescale->offset = -1 * ((r0 * iexc) / 1000); in rescale_temp_sense_rtd_props()
458 device_property_read_u32(dev, "sense-offset-millicelsius", &offset); in rescale_temp_transducer_props()
459 device_property_read_u32(dev, "sense-resistor-ohms", &sense); in rescale_temp_transducer_props()
460 ret = device_property_read_u32(dev, "alpha-ppm-per-celsius", &alpha); in rescale_temp_transducer_props()
462 dev_err(dev, "failed to read alpha-ppm-per-celsius: %d\n", ret); in rescale_temp_transducer_props()
466 rescale->numerator = 1000000; in rescale_temp_transducer_props()
467 rescale->denominator = alpha * sense; in rescale_temp_transducer_props()
469 rescale->offset = div_s64((s64)offset * rescale->denominator, in rescale_temp_transducer_props()
470 rescale->numerator); in rescale_temp_transducer_props()
507 { .compatible = "current-sense-amplifier",
509 { .compatible = "current-sense-shunt",
511 { .compatible = "voltage-divider",
513 { .compatible = "temperature-sense-rtd",
515 { .compatible = "temperature-transducer",
523 struct device *dev = &pdev->dev; in rescale_probe()
540 sizeof_ext_info *= sizeof(*rescale->ext_info); in rescale_probe()
547 return -ENOMEM; in rescale_probe()
551 rescale->cfg = device_get_match_data(dev); in rescale_probe()
552 rescale->numerator = 1; in rescale_probe()
553 rescale->denominator = 1; in rescale_probe()
554 rescale->offset = 0; in rescale_probe()
556 ret = rescale->cfg->props(dev, rescale); in rescale_probe()
560 if (!rescale->numerator || !rescale->denominator) { in rescale_probe()
562 return -EINVAL; in rescale_probe()
567 rescale->source = source; in rescale_probe()
569 indio_dev->name = dev_name(dev); in rescale_probe()
570 indio_dev->info = &rescale_info; in rescale_probe()
571 indio_dev->modes = INDIO_DIRECT_MODE; in rescale_probe()
572 indio_dev->channels = &rescale->chan; in rescale_probe()
573 indio_dev->num_channels = 1; in rescale_probe()
575 rescale->ext_info = devm_kmemdup(dev, in rescale_probe()
576 source->channel->ext_info, in rescale_probe()
578 if (!rescale->ext_info) in rescale_probe()
579 return -ENOMEM; in rescale_probe()
581 for (i = 0; rescale->ext_info[i].name; ++i) { in rescale_probe()
583 &rescale->ext_info[i]; in rescale_probe()
585 if (source->channel->ext_info[i].read) in rescale_probe()
586 ext_info->read = rescale_read_ext_info; in rescale_probe()
587 if (source->channel->ext_info[i].write) in rescale_probe()
588 ext_info->write = rescale_write_ext_info; in rescale_probe()
589 ext_info->private = i; in rescale_probe()
603 .name = "iio-rescale",