drivers: sensor: ntc-thermistor: Simplify comp lookup

bsearch() tries to find the exact match for the key, otherwise it
returns NULL. However, here we want to find two elements our key lies
in-between. This requires some rather complicated logic that pretends
it found the exact match even if it didn't. Replace this with a simple
implementation of binary search.

Signed-off-by: Paweł Anikiel <pan@semihalf.com>
This commit is contained in:
Paweł Anikiel 2023-08-04 10:36:23 +00:00 committed by Maureen Helm
commit 83be5fb596
3 changed files with 19 additions and 74 deletions

View file

@ -96,8 +96,6 @@ static int ntc_thermistor_init(const struct device *dev)
}
#define NTC_THERMISTOR_DEFINE0(inst, id, _comp, _n_comp) \
static int compare_ohm_##id##inst(const void *key, const void *element); \
\
static struct ntc_thermistor_data ntc_thermistor_driver_##id##inst; \
\
static const struct ntc_thermistor_config ntc_thermistor_cfg_##id##inst = { \
@ -112,17 +110,10 @@ static int ntc_thermistor_init(const struct device *dev)
.type = { \
.comp = _comp, \
.n_comp = _n_comp, \
.ohm_cmp = compare_ohm_##id##inst, \
}, \
}, \
}; \
\
static int compare_ohm_##id##inst(const void *key, const void *element) \
{ \
return ntc_compensation_compare_ohm( \
&ntc_thermistor_cfg_##id##inst.ntc_cfg.type, key, element); \
} \
\
SENSOR_DEVICE_DT_INST_DEFINE( \
inst, ntc_thermistor_init, NULL, &ntc_thermistor_driver_##id##inst, \
&ntc_thermistor_cfg_##id##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \

View file

@ -17,7 +17,6 @@ struct ntc_compensation {
struct ntc_type {
const struct ntc_compensation *comp;
int n_comp;
int (*ohm_cmp)(const void *key, const void *element);
};
struct ntc_config {
@ -29,19 +28,6 @@ struct ntc_config {
struct ntc_type type;
};
/**
* @brief Helper comparison function for bsearch for specific
* ntc_type
*
* Ohms are sorted in descending order, perform comparison to find
* interval indexes where key falls between
*
* @param type: Pointer to ntc_type table info
* @param key: Key value bsearch is looking for
* @param element: Array element bsearch is searching
*/
int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element);
/**
* @brief Converts ohm to temperature in milli centigrade
*

View file

@ -30,47 +30,6 @@ static int ntc_fixp_linear_interpolate(int x0, int y0, int x1, int y1, int x)
return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
}
/**
* ntc_compensation_compare_ohm() - Helper comparison function for bsearch
*
* Ohms are sorted in descending order, perform comparison to find
* interval indexes where key falls between
*
* @type: Pointer to ntc_type table info
* @key: Key value bsearch is looking for
* @element: Array element bsearch is searching
*/
int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element)
{
int sgn = 0;
const struct ntc_compensation *ntc_key = key;
const struct ntc_compensation *element_val = element;
int element_idx = element_val - type->comp;
if (ntc_key->ohm > element_val->ohm) {
if (element_idx == 0) {
sgn = 0;
} else {
sgn = -1;
}
} else if (ntc_key->ohm == element_val->ohm) {
sgn = 0;
} else if (ntc_key->ohm < element_val->ohm) {
if (element_idx == (type->n_comp / 2) - 1) {
sgn = 0;
} else {
if (element_idx != (type->n_comp / 2) - 1 &&
ntc_key->ohm > type->comp[element_idx + 1].ohm) {
sgn = 0;
} else {
sgn = 1;
}
}
}
return sgn;
}
/**
* ntc_lookup_comp() - Finds indicies where ohm falls between
*
@ -80,18 +39,27 @@ int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, c
*/
static void ntc_lookup_comp(const struct ntc_type *type, unsigned int ohm, int *i_low, int *i_high)
{
const struct ntc_compensation *ptr;
struct ntc_compensation search_ohm_key = {.ohm = ohm};
int low = 0;
int high = type->n_comp - 1;
ptr = bsearch(&search_ohm_key, type->comp, type->n_comp, sizeof(type->comp[0]),
type->ohm_cmp);
if (ptr) {
*i_low = ptr - type->comp;
*i_high = *i_low + 1;
} else {
*i_low = 0;
*i_high = 0;
if (ohm > type->comp[low].ohm) {
high = low;
} else if (ohm < type->comp[high].ohm) {
low = high;
}
while (high - low > 1) {
int mid = (low + high) / 2;
if (ohm > type->comp[mid].ohm) {
high = mid;
} else {
low = mid;
}
}
*i_low = low;
*i_high = high;
}
/**