Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at for-next 206 lines 6.3 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* gain-time-scale conversion helpers for IIO light sensors 3 * 4 * Copyright (c) 2023 Matti Vaittinen <mazziesaccount@gmail.com> 5 */ 6 7#ifndef __IIO_GTS_HELPER__ 8#define __IIO_GTS_HELPER__ 9 10#include <linux/types.h> 11 12struct device; 13 14/** 15 * struct iio_gain_sel_pair - gain - selector values 16 * 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) 20 * 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. 25 */ 26struct iio_gain_sel_pair { 27 int gain; 28 int sel; 29}; 30 31/** 32 * struct iio_itime_sel_mul - integration time description 33 * 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 38 * (register value). 39 * 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. 45 * 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. 52 */ 53struct iio_itime_sel_mul { 54 int time_us; 55 int sel; 56 int mul; 57}; 58 59struct iio_gts { 60 u64 max_scale; 61 const struct iio_gain_sel_pair *hwgain_table; 62 int num_hwgain; 63 const struct iio_itime_sel_mul *itime_table; 64 int num_itime; 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; 70}; 71 72#define GAIN_SCALE_GAIN(_gain, _sel) \ 73{ \ 74 .gain = (_gain), \ 75 .sel = (_sel), \ 76} 77 78#define GAIN_SCALE_ITIME_US(_itime, _sel, _mul) \ 79{ \ 80 .time_us = (_itime), \ 81 .sel = (_sel), \ 82 .mul = (_mul), \ 83} 84 85static inline const struct iio_itime_sel_mul * 86iio_gts_find_itime_by_time(struct iio_gts *gts, int time) 87{ 88 int i; 89 90 if (!gts->num_itime) 91 return NULL; 92 93 for (i = 0; i < gts->num_itime; i++) 94 if (gts->itime_table[i].time_us == time) 95 return &gts->itime_table[i]; 96 97 return NULL; 98} 99 100static inline const struct iio_itime_sel_mul * 101iio_gts_find_itime_by_sel(struct iio_gts *gts, int sel) 102{ 103 int i; 104 105 for (i = 0; i < gts->num_itime; i++) 106 if (gts->itime_table[i].sel == sel) 107 return &gts->itime_table[i]; 108 109 return NULL; 110} 111 112int 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); 116/** 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 120 * 121 * Return: integration time matching given selector or -EINVAL if 122 * integration time was not found. 123 */ 124static inline int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel) 125{ 126 const struct iio_itime_sel_mul *itime; 127 128 itime = iio_gts_find_itime_by_sel(gts, sel); 129 if (!itime) 130 return -EINVAL; 131 132 return itime->time_us; 133} 134 135/** 136 * iio_gts_find_sel_by_int_time - find selector matching integration time 137 * @gts: Gain time scale descriptor 138 * @time: Integration time for which matching selector is searched for 139 * 140 * Return: a selector matching given integration time or -EINVAL if 141 * selector was not found. 142 */ 143static inline int iio_gts_find_sel_by_int_time(struct iio_gts *gts, int time) 144{ 145 const struct iio_itime_sel_mul *itime; 146 147 itime = iio_gts_find_itime_by_time(gts, time); 148 if (!itime) 149 return -EINVAL; 150 151 return itime->sel; 152} 153 154/** 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 158 * 159 * Return: True if given time is supported by device. False if not. 160 */ 161static inline bool iio_gts_valid_time(struct iio_gts *gts, int time_us) 162{ 163 return iio_gts_find_itime_by_time(gts, time_us) != NULL; 164} 165 166int iio_gts_find_sel_by_gain(struct iio_gts *gts, int gain); 167 168/** 169 * iio_gts_valid_gain - check if given HW-gain is valid 170 * @gts: Gain time scale descriptor 171 * @gain: HW-gain to check 172 * 173 * Return: True if given time is supported by device. False if not. 174 */ 175static inline bool iio_gts_valid_gain(struct iio_gts *gts, int gain) 176{ 177 return iio_gts_find_sel_by_gain(gts, gain) >= 0; 178} 179 180int iio_find_closest_gain_low(struct iio_gts *gts, int gain, bool *in_range); 181int iio_gts_find_gain_by_sel(struct iio_gts *gts, int sel); 182int iio_gts_get_min_gain(struct iio_gts *gts); 183int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel); 184int iio_gts_find_sel_by_int_time(struct iio_gts *gts, int time); 185 186int iio_gts_total_gain_to_scale(struct iio_gts *gts, int total_gain, 187 int *scale_int, int *scale_nano); 188int iio_gts_find_gain_sel_for_scale_using_time(struct iio_gts *gts, int time_sel, 189 int scale_int, int scale_nano, 190 int *gain_sel); 191int iio_gts_get_scale(struct iio_gts *gts, int gain, int time, int *scale_int, 192 int *scale_nano); 193int 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); 196int iio_gts_find_new_gain_by_old_gain_time(struct iio_gts *gts, int old_gain, 197 int old_time, int new_time, 198 int *new_gain); 199int iio_gts_avail_times(struct iio_gts *gts, const int **vals, int *type, 200 int *length); 201int iio_gts_all_avail_scales(struct iio_gts *gts, const int **vals, int *type, 202 int *length); 203int iio_gts_avail_scales_for_time(struct iio_gts *gts, int time, 204 const int **vals, int *type, int *length); 205 206#endif