1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* gain-time-scale conversion helpers for IIO light sensors
4 * Copyright (c) 2023 Matti Vaittinen <mazziesaccount@gmail.com>
7 #ifndef __IIO_GTS_HELPER__
8 #define __IIO_GTS_HELPER__
10 #include <linux/types.h>
15 * struct iio_gain_sel_pair - gain - selector values
17 * In many cases devices like light sensors allow setting signal amplification
18 * (gain) using a register interface. This structure describes amplification
19 * and corresponding selector (register value)
21 * @gain: Gain (multiplication) value. Gain must be positive, negative
22 * values are reserved for error handling.
23 * @sel: Selector (usually register value) used to indicate this gain.
24 * NOTE: Only selectors >= 0 supported.
26 struct iio_gain_sel_pair {
32 * struct iio_itime_sel_mul - integration time description
34 * In many cases devices like light sensors allow setting the duration of
35 * collecting data. Typically this duration has also an impact to the magnitude
36 * of measured values (gain). This structure describes the relation of
37 * integration time and amplification as well as corresponding selector
40 * An example could be a sensor allowing 50, 100, 200 and 400 mS times. The
41 * respective multiplication values could be 50 mS => 1, 100 mS => 2,
42 * 200 mS => 4 and 400 mS => 8 assuming the impact of integration time would be
43 * linear in a way that when collecting data for 50 mS caused value X, doubling
44 * the data collection time caused value 2X etc.
46 * @time_us: Integration time in microseconds. Time values must be positive,
47 * negative values are reserved for error handling.
48 * @sel: Selector (usually register value) used to indicate this time
49 * NOTE: Only selectors >= 0 supported.
50 * @mul: Multiplication to the values caused by this time.
51 * NOTE: Only multipliers > 0 supported.
53 struct iio_itime_sel_mul {
61 const struct iio_gain_sel_pair *hwgain_table;
63 const struct iio_itime_sel_mul *itime_table;
65 int **per_time_avail_scale_tables;
66 int *avail_all_scales_table;
67 int num_avail_all_scales;
68 int *avail_time_tables;
69 int num_avail_time_tables;
72 #define GAIN_SCALE_GAIN(_gain, _sel) \
78 #define GAIN_SCALE_ITIME_US(_itime, _sel, _mul) \
80 .time_us = (_itime), \
85 static inline const struct iio_itime_sel_mul *
86 iio_gts_find_itime_by_time(struct iio_gts *gts, int time)
93 for (i = 0; i < gts->num_itime; i++)
94 if (gts->itime_table[i].time_us == time)
95 return >s->itime_table[i];
100 static inline const struct iio_itime_sel_mul *
101 iio_gts_find_itime_by_sel(struct iio_gts *gts, int sel)
105 for (i = 0; i < gts->num_itime; i++)
106 if (gts->itime_table[i].sel == sel)
107 return >s->itime_table[i];
112 int devm_iio_init_iio_gts(struct device *dev, int max_scale_int, int max_scale_nano,
113 const struct iio_gain_sel_pair *gain_tbl, int num_gain,
114 const struct iio_itime_sel_mul *tim_tbl, int num_times,
115 struct iio_gts *gts);
117 * iio_gts_find_int_time_by_sel - find integration time matching a selector
118 * @gts: Gain time scale descriptor
119 * @sel: selector for which matching integration time is searched for
121 * Return: integration time matching given selector or -EINVAL if
122 * integration time was not found.
124 static inline int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel)
126 const struct iio_itime_sel_mul *itime;
128 itime = iio_gts_find_itime_by_sel(gts, sel);
132 return itime->time_us;
136 * iio_gts_find_sel_by_int_time - find selector matching integration time
137 * @gts: Gain time scale descriptor
138 * @gain: HW-gain for which matching selector is searched for
140 * Return: a selector matching given integration time or -EINVAL if
141 * selector was not found.
143 static inline int iio_gts_find_sel_by_int_time(struct iio_gts *gts, int time)
145 const struct iio_itime_sel_mul *itime;
147 itime = iio_gts_find_itime_by_time(gts, time);
155 * iio_gts_valid_time - check if given integration time is valid
156 * @gts: Gain time scale descriptor
157 * @time_us: Integration time to check
159 * Return: True if given time is supported by device. False if not.
161 static inline bool iio_gts_valid_time(struct iio_gts *gts, int time_us)
163 return iio_gts_find_itime_by_time(gts, time_us) != NULL;
166 int iio_gts_find_sel_by_gain(struct iio_gts *gts, int gain);
169 * iio_gts_valid_gain - check if given HW-gain is valid
170 * @gts: Gain time scale descriptor
171 * @gain: HW-gain to check
173 * Return: True if given time is supported by device. False if not.
175 static inline bool iio_gts_valid_gain(struct iio_gts *gts, int gain)
177 return iio_gts_find_sel_by_gain(gts, gain) >= 0;
180 int iio_find_closest_gain_low(struct iio_gts *gts, int gain, bool *in_range);
181 int iio_gts_find_gain_by_sel(struct iio_gts *gts, int sel);
182 int iio_gts_get_min_gain(struct iio_gts *gts);
183 int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel);
184 int iio_gts_find_sel_by_int_time(struct iio_gts *gts, int time);
186 int iio_gts_total_gain_to_scale(struct iio_gts *gts, int total_gain,
187 int *scale_int, int *scale_nano);
188 int iio_gts_find_gain_sel_for_scale_using_time(struct iio_gts *gts, int time_sel,
189 int scale_int, int scale_nano,
191 int iio_gts_get_scale(struct iio_gts *gts, int gain, int time, int *scale_int,
193 int iio_gts_find_new_gain_sel_by_old_gain_time(struct iio_gts *gts,
194 int old_gain, int old_time_sel,
195 int new_time_sel, int *new_gain);
196 int iio_gts_find_new_gain_by_old_gain_time(struct iio_gts *gts, int old_gain,
197 int old_time, int new_time,
199 int iio_gts_avail_times(struct iio_gts *gts, const int **vals, int *type,
201 int iio_gts_all_avail_scales(struct iio_gts *gts, const int **vals, int *type,
203 int iio_gts_avail_scales_for_time(struct iio_gts *gts, int time,
204 const int **vals, int *type, int *length);