1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2023 Carl Zeiss Meditec AG
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #define DT_DRV_COMPAT adi_adltc2990
7
8 #include <zephyr/sys/util.h>
9 #include <zephyr/drivers/i2c.h>
10
11 #include "adltc2990_reg.h"
12 #include "adltc2990.h"
13
14 #include <zephyr/logging/log.h>
15 LOG_MODULE_REGISTER(adltc2990, CONFIG_SENSOR_LOG_LEVEL);
16
adltc2990_get_v1_v2_measurement_modes(uint8_t mode_4_3,uint8_t mode_2_0)17 static enum adltc2990_monitoring_type adltc2990_get_v1_v2_measurement_modes(uint8_t mode_4_3,
18 uint8_t mode_2_0)
19 {
20 if (mode_2_0 > ADLTC2990_MODE_2_0_MAX_VALUE || mode_4_3 > ADLTC2990_MODE_4_3_MAX_VALUE) {
21 LOG_ERR("Invalid Measurement Mode");
22 return -EINVAL;
23 }
24 if (mode_4_3 == ADLTC2990_MEASURE_INTERNAL_TEMPERATURE_ONLY ||
25 mode_4_3 == ADLTC2990_MEASURE_PINS_V3_V4_ONLY) {
26 return NOTHING;
27 }
28
29 enum adltc2990_monitoring_type type = NOTHING;
30
31 switch (mode_2_0) {
32 case ADLTC2990_MODE_V1_V2_TR2:
33 case ADLTC2990_MODE_V1_V2_V3_V4: {
34 type = VOLTAGE_SINGLEENDED;
35 break;
36 }
37 case ADLTC2990_MODE_V1_MINUS_V2_TR2:
38 case ADLTC2990_MODE_V1_MINUS_V2_V3_V4:
39 case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: {
40 type = VOLTAGE_DIFFERENTIAL;
41 break;
42 }
43 case ADLTC2990_MODE_TR1_V3_V4:
44 case ADLTC2990_MODE_TR1_V3_MINUS_V4: {
45 case ADLTC2990_MODE_TR1_TR2:
46 type = TEMPERATURE;
47 break;
48 }
49 default: {
50 break;
51 }
52 }
53 return type;
54 }
55
adltc2990_get_v3_v4_measurement_modes(uint8_t mode_4_3,uint8_t mode_2_0)56 static enum adltc2990_monitoring_type adltc2990_get_v3_v4_measurement_modes(uint8_t mode_4_3,
57 uint8_t mode_2_0)
58 {
59 if (mode_2_0 > ADLTC2990_MODE_2_0_MAX_VALUE || mode_4_3 > ADLTC2990_MODE_4_3_MAX_VALUE) {
60 LOG_ERR("Invalid Measurement Mode");
61 return -EINVAL;
62 }
63 if (mode_4_3 == ADLTC2990_MEASURE_INTERNAL_TEMPERATURE_ONLY ||
64 mode_4_3 == ADLTC2990_MEASURE_PINS_V1_V2_ONLY) {
65 return NOTHING;
66 }
67
68 enum adltc2990_monitoring_type type = NOTHING;
69
70 switch (mode_2_0) {
71 case ADLTC2990_MODE_V1_V2_TR2:
72 case ADLTC2990_MODE_V1_MINUS_V2_TR2:
73 case ADLTC2990_MODE_TR1_TR2: {
74 type = TEMPERATURE;
75 break;
76 }
77
78 case ADLTC2990_MODE_V1_MINUS_V2_V3_V4:
79 case ADLTC2990_MODE_TR1_V3_V4:
80 case ADLTC2990_MODE_V1_V2_V3_V4: {
81 type = VOLTAGE_SINGLEENDED;
82 break;
83 }
84 case ADLTC2990_MODE_TR1_V3_MINUS_V4:
85 case ADLTC2990_MODE_V1_MINUS_V2_V3_MINUS_V4: {
86 type = VOLTAGE_DIFFERENTIAL;
87 break;
88 }
89 default: {
90 break;
91 }
92 }
93 return type;
94 }
95
adltc2990_is_busy(const struct device * dev,bool * is_busy)96 static int adltc2990_is_busy(const struct device *dev, bool *is_busy)
97 {
98 const struct adltc2990_config *cfg = dev->config;
99 uint8_t status_reg = 0;
100 int ret;
101
102 ret = i2c_reg_read_byte_dt(&cfg->bus, ADLTC2990_REG_STATUS, &status_reg);
103 if (ret) {
104 return ret;
105 }
106
107 *is_busy = status_reg & BIT(0);
108
109 return 0;
110 }
111
adltc2990_get_v1_v2_val(const struct device * dev,struct sensor_value * val,uint8_t num_values,uint8_t * const offset_index)112 static void adltc2990_get_v1_v2_val(const struct device *dev, struct sensor_value *val,
113 uint8_t num_values, uint8_t *const offset_index)
114 {
115 struct adltc2990_data *data = dev->data;
116
117 for (uint8_t index = 0; index < num_values; index++) {
118 val[index].val1 = data->pins_v1_v2_values[index] / 1000000;
119 val[index].val2 = data->pins_v1_v2_values[index] % 1000000;
120 *offset_index = index + 1;
121 }
122 }
123
adltc2990_get_v3_v4_val(const struct device * dev,struct sensor_value * val,uint8_t num_values,uint8_t const * const offset)124 static void adltc2990_get_v3_v4_val(const struct device *dev, struct sensor_value *val,
125 uint8_t num_values, uint8_t const *const offset)
126 {
127 struct adltc2990_data *data = dev->data;
128
129 uint8_t offset_index = *offset;
130
131 for (uint8_t index = 0; index < num_values; index++) {
132 val[index + offset_index].val1 = data->pins_v3_v4_values[index] / 1000000;
133 val[index + offset_index].val2 = data->pins_v3_v4_values[index] % 1000000;
134 }
135 }
136
adltc2990_trigger_measurement(const struct device * dev)137 static int adltc2990_trigger_measurement(const struct device *dev)
138 {
139 const struct adltc2990_config *cfg = dev->config;
140
141 return i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_TRIGGER, 0x1);
142 }
143
adltc2990_fetch_property_value(const struct device * dev,enum adltc2990_monitoring_type type,enum adltc2990_monitor_pins pin,int32_t * output)144 static int adltc2990_fetch_property_value(const struct device *dev,
145 enum adltc2990_monitoring_type type,
146 enum adltc2990_monitor_pins pin,
147 int32_t *output)
148 {
149 const struct adltc2990_config *cfg = dev->config;
150
151 uint8_t msb_value = 0, lsb_value = 0;
152 uint8_t msb_address, lsb_address;
153
154 switch (pin) {
155 case V1: {
156 msb_address = ADLTC2990_REG_V1_MSB;
157 lsb_address = ADLTC2990_REG_V1_LSB;
158 break;
159 }
160 case V2: {
161 msb_address = ADLTC2990_REG_V2_MSB;
162 lsb_address = ADLTC2990_REG_V2_LSB;
163 break;
164 }
165 case V3: {
166 msb_address = ADLTC2990_REG_V3_MSB;
167 lsb_address = ADLTC2990_REG_V3_LSB;
168 break;
169 }
170 case V4: {
171 msb_address = ADLTC2990_REG_V4_MSB;
172 lsb_address = ADLTC2990_REG_V4_LSB;
173 break;
174 }
175 case INTERNAL_TEMPERATURE: {
176 msb_address = ADLTC2990_REG_INTERNAL_TEMP_MSB;
177 lsb_address = ADLTC2990_REG_INTERNAL_TEMP_LSB;
178 break;
179 }
180 case SUPPLY_VOLTAGE: {
181 msb_address = ADLTC2990_REG_VCC_MSB;
182 lsb_address = ADLTC2990_REG_VCC_LSB;
183 break;
184 }
185 default: {
186 LOG_ERR("Trying to access illegal register");
187 return -EINVAL;
188 }
189 }
190 int ret;
191
192 ret = i2c_reg_read_byte_dt(&cfg->bus, msb_address, &msb_value);
193 if (ret) {
194 return ret;
195 }
196
197 ret = i2c_reg_read_byte_dt(&cfg->bus, lsb_address, &lsb_value);
198 if (ret) {
199 return ret;
200 }
201 uint16_t conversion_factor;
202 uint8_t negative_bit_index = 14U, sensor_val_divisor = 100U;
203
204 if (type == VOLTAGE_SINGLEENDED) {
205 conversion_factor = ADLTC2990_VOLTAGE_SINGLEENDED_CONVERSION_FACTOR;
206 } else if (type == VOLTAGE_DIFFERENTIAL) {
207 conversion_factor = ADLTC2990_VOLTAGE_DIFFERENTIAL_CONVERSION_FACTOR;
208 } else if (type == TEMPERATURE) {
209 conversion_factor = ADLTC2990_TEMPERATURE_CONVERSION_FACTOR;
210 if (cfg->temp_format == ADLTC2990_TEMPERATURE_FORMAT_CELSIUS) {
211 negative_bit_index = 12U;
212 }
213 sensor_val_divisor = 1U;
214 } else {
215 LOG_ERR("unknown type");
216 return -EINVAL;
217 }
218
219 int16_t value = (msb_value << 8) + lsb_value;
220
221 int32_t voltage_value = (value << (31 - negative_bit_index)) >> (31 - negative_bit_index);
222
223 *output = (voltage_value * conversion_factor) / sensor_val_divisor;
224
225 return 0;
226 }
227
adltc2990_init(const struct device * dev)228 static int adltc2990_init(const struct device *dev)
229 {
230 const struct adltc2990_config *cfg = dev->config;
231
232 if (!i2c_is_ready_dt(&cfg->bus)) {
233 LOG_ERR("I2C bus %s not ready", cfg->bus.bus->name);
234 return -ENODEV;
235 }
236
237 const uint8_t ctrl_reg_setting = cfg->temp_format << 7 | cfg->acq_format << 6 | 0 << 5 |
238 cfg->measurement_mode[1] << 3 | cfg->measurement_mode[0];
239
240 LOG_DBG("Setting Control Register to: 0x%x", ctrl_reg_setting);
241 int err = i2c_reg_write_byte_dt(&cfg->bus, ADLTC2990_REG_CONTROL, ctrl_reg_setting);
242
243 if (err < 0) {
244 LOG_ERR("configuring for single bus failed: %d", err);
245 return err;
246 }
247 LOG_INF("Initializing ADLTC2990 with name %s", dev->name);
248 return 0;
249 }
250
adltc2990_sample_fetch(const struct device * dev,enum sensor_channel chan)251 static int adltc2990_sample_fetch(const struct device *dev, enum sensor_channel chan)
252 {
253 struct adltc2990_data *data = dev->data;
254 const struct adltc2990_config *cfg = dev->config;
255 enum adltc2990_monitoring_type mode_v1_v2 = adltc2990_get_v1_v2_measurement_modes(
256 cfg->measurement_mode[1], cfg->measurement_mode[0]);
257 enum adltc2990_monitoring_type mode_v3_v4 = adltc2990_get_v3_v4_measurement_modes(
258 cfg->measurement_mode[1], cfg->measurement_mode[0]);
259
260 float voltage_divider_ratio;
261 int ret;
262 int32_t value;
263
264 switch (chan) {
265 case SENSOR_CHAN_DIE_TEMP: {
266 ret = adltc2990_fetch_property_value(dev, TEMPERATURE, INTERNAL_TEMPERATURE,
267 &value);
268 if (ret) {
269 return ret;
270 }
271 data->internal_temperature = value;
272 break;
273 }
274 case SENSOR_CHAN_CURRENT: {
275 if (!(mode_v1_v2 == VOLTAGE_DIFFERENTIAL || mode_v3_v4 == VOLTAGE_DIFFERENTIAL)) {
276 LOG_ERR("Sensor is not configured to measure Current");
277 return -EINVAL;
278 }
279 if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) {
280 ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1, &value);
281 if (ret) {
282 return ret;
283 }
284 data->pins_v1_v2_values[0] =
285 value * (ADLTC2990_MICROOHM_CONVERSION_FACTOR /
286 (float)cfg->pins_v1_v2.pins_current_resistor);
287 }
288 if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) {
289 ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3, &value);
290 if (ret) {
291 return ret;
292 }
293 data->pins_v3_v4_values[0] = value * (ADLTC2990_MICROOHM_CONVERSION_FACTOR /
294 (float)cfg->pins_v3_v4.pins_current_resistor);
295 }
296 break;
297 }
298 case SENSOR_CHAN_VOLTAGE: {
299 ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, SUPPLY_VOLTAGE,
300 &value);
301 if (ret) {
302 return ret;
303 }
304 data->supply_voltage = value + 2500000;
305
306 if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) {
307 ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V1, &value);
308 if (ret) {
309 return ret;
310 }
311 data->pins_v1_v2_values[0] = value;
312 } else if (mode_v1_v2 == VOLTAGE_SINGLEENDED) {
313 uint32_t v1_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[0];
314
315 uint32_t v1_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v1_r1_r2[1];
316
317 voltage_divider_ratio = (v1_r1 + v1_r2) / (float)v1_r2;
318 ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V1, &value);
319 if (ret) {
320 return ret;
321 }
322 data->pins_v1_v2_values[0] = value * voltage_divider_ratio;
323
324 uint32_t v2_r1 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[0];
325
326 uint32_t v2_r2 = cfg->pins_v1_v2.voltage_divider_resistors.v2_r1_r2[1];
327
328 voltage_divider_ratio = (v2_r1 + v2_r2) / (float)v2_r2;
329 ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V2, &value);
330 if (ret) {
331 return ret;
332 }
333 data->pins_v1_v2_values[1] = value * voltage_divider_ratio;
334 }
335
336 if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) {
337 ret = adltc2990_fetch_property_value(dev, VOLTAGE_DIFFERENTIAL, V3, &value);
338 if (ret) {
339 return ret;
340 }
341 data->pins_v3_v4_values[0] = value;
342 } else if (mode_v3_v4 == VOLTAGE_SINGLEENDED) {
343 uint32_t v3_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[0];
344
345 uint32_t v3_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v3_r1_r2[1];
346
347 voltage_divider_ratio = (v3_r1 + v3_r2) / (float)v3_r2;
348 ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V3, &value);
349 if (ret) {
350 return ret;
351 }
352 data->pins_v3_v4_values[0] = value * voltage_divider_ratio;
353
354 uint32_t v4_r1 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[0];
355
356 uint32_t v4_r2 = cfg->pins_v3_v4.voltage_divider_resistors.v4_r1_r2[1];
357
358 voltage_divider_ratio = (v4_r1 + v4_r2) / (float)v4_r2;
359
360 ret = adltc2990_fetch_property_value(dev, VOLTAGE_SINGLEENDED, V4, &value);
361 if (ret) {
362 return ret;
363 }
364 data->pins_v3_v4_values[1] = value * voltage_divider_ratio;
365 }
366 break;
367 }
368 case SENSOR_CHAN_AMBIENT_TEMP: {
369 if (!(mode_v1_v2 == TEMPERATURE || mode_v3_v4 == TEMPERATURE)) {
370 LOG_ERR("Sensor is not configured to measure Ambient Temperature");
371 return -EINVAL;
372 }
373 if (mode_v1_v2 == TEMPERATURE) {
374 ret = adltc2990_fetch_property_value(dev, TEMPERATURE, V1, &value);
375 if (ret) {
376 return ret;
377 }
378 data->pins_v1_v2_values[0] = value;
379 }
380 if (mode_v3_v4 == TEMPERATURE) {
381 ret = adltc2990_fetch_property_value(dev, TEMPERATURE, V3, &value);
382 if (ret) {
383 return ret;
384 }
385 data->pins_v3_v4_values[0] = value;
386 }
387 break;
388 }
389 case SENSOR_CHAN_ALL: {
390 bool is_busy;
391
392 ret = adltc2990_is_busy(dev, &is_busy);
393 if (ret) {
394 return ret;
395 }
396
397 if (is_busy) {
398 LOG_INF("ADLTC2990 conversion ongoing");
399 return -EBUSY;
400 }
401 adltc2990_trigger_measurement(dev);
402 break;
403 }
404 default: {
405 LOG_ERR("does not measure channel: %d", chan);
406 return -ENOTSUP;
407 }
408 }
409
410 return 0;
411 }
412
adltc2990_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)413 static int adltc2990_channel_get(const struct device *dev, enum sensor_channel chan,
414 struct sensor_value *val)
415 {
416 if (val == NULL) {
417 LOG_ERR("Argument of type sensor_value* cannot be null ");
418 return -EINVAL;
419 }
420 struct adltc2990_data *data = dev->data;
421 const struct adltc2990_config *cfg = dev->config;
422 enum adltc2990_monitoring_type mode_v1_v2 = adltc2990_get_v1_v2_measurement_modes(
423 cfg->measurement_mode[1], cfg->measurement_mode[0]);
424 enum adltc2990_monitoring_type mode_v3_v4 = adltc2990_get_v3_v4_measurement_modes(
425 cfg->measurement_mode[1], cfg->measurement_mode[0]);
426
427 uint8_t offset_index = 0, num_values_v1_v2 = 0, num_values_v3_v4 = 0;
428
429 switch (chan) {
430 case SENSOR_CHAN_DIE_TEMP: {
431 val->val1 = (data->internal_temperature) / 1000000;
432 val->val2 = (data->internal_temperature) % 1000000;
433 LOG_DBG("Internal Temperature Value is:%d.%d", val->val1, val->val2);
434 break;
435 }
436 case SENSOR_CHAN_VOLTAGE: {
437 if (mode_v1_v2 == VOLTAGE_SINGLEENDED) {
438 LOG_DBG("Getting V1,V2");
439 num_values_v1_v2 = ADLTC2990_VOLTAGE_SINGLE_ENDED_VALUES;
440 } else if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) {
441 LOG_DBG("Getting V3-V4");
442 num_values_v1_v2 = ADLTC2990_VOLTAGE_DIFF_VALUES;
443 }
444 if (mode_v3_v4 == VOLTAGE_SINGLEENDED) {
445 LOG_DBG("Getting V3,V4");
446 num_values_v3_v4 = ADLTC2990_VOLTAGE_SINGLE_ENDED_VALUES;
447 } else if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) {
448 LOG_DBG("Getting V3-V4");
449 num_values_v3_v4 = ADLTC2990_VOLTAGE_DIFF_VALUES;
450 }
451 /* Add VCC to the last index */
452 val[num_values_v1_v2 + num_values_v3_v4].val1 = data->supply_voltage / 1000000;
453 val[num_values_v1_v2 + num_values_v3_v4].val2 = data->supply_voltage % 1000000;
454 break;
455 }
456 case SENSOR_CHAN_CURRENT: {
457 if (!(mode_v1_v2 == VOLTAGE_DIFFERENTIAL || mode_v3_v4 == VOLTAGE_DIFFERENTIAL)) {
458 LOG_ERR("Sensor is not configured to measure Current");
459 return -EINVAL;
460 }
461 if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL && mode_v3_v4 == VOLTAGE_DIFFERENTIAL) {
462 LOG_DBG("Getting I12 and I34");
463 num_values_v1_v2 = ADLTC2990_CURRENT_VALUES;
464 num_values_v3_v4 = ADLTC2990_CURRENT_VALUES;
465 } else if (mode_v1_v2 == VOLTAGE_DIFFERENTIAL) {
466 LOG_DBG("Getting I12");
467 num_values_v1_v2 = ADLTC2990_CURRENT_VALUES;
468 } else if (mode_v3_v4 == VOLTAGE_DIFFERENTIAL) {
469 LOG_DBG("Getting I34");
470 num_values_v3_v4 = ADLTC2990_CURRENT_VALUES;
471 }
472 break;
473 }
474 case SENSOR_CHAN_AMBIENT_TEMP: {
475 if (!(mode_v1_v2 == TEMPERATURE || mode_v3_v4 == TEMPERATURE)) {
476 LOG_ERR("Sensor is not configured to measure Ambient Temperature");
477 return -EINVAL;
478 }
479 if (mode_v1_v2 == TEMPERATURE && mode_v3_v4 == TEMPERATURE) {
480 LOG_DBG("Getting T12 and T34");
481 num_values_v1_v2 = ADLTC2990_TEMP_VALUES;
482 num_values_v3_v4 = ADLTC2990_TEMP_VALUES;
483 } else if (mode_v1_v2 == TEMPERATURE) {
484 LOG_DBG("Getting T12");
485 num_values_v1_v2 = ADLTC2990_TEMP_VALUES;
486 } else if (mode_v3_v4 == TEMPERATURE) {
487 LOG_DBG("Getting T34");
488 num_values_v3_v4 = ADLTC2990_TEMP_VALUES;
489 }
490 break;
491 }
492 default: {
493 return -ENOTSUP;
494 }
495 }
496
497 adltc2990_get_v1_v2_val(dev, val, num_values_v1_v2, &offset_index);
498 adltc2990_get_v3_v4_val(dev, val, num_values_v3_v4, &offset_index);
499 return 0;
500 }
501
502 static const struct sensor_driver_api adltc2990_driver_api = {
503 .sample_fetch = adltc2990_sample_fetch,
504 .channel_get = adltc2990_channel_get,
505 };
506
507 #define ADLTC2990_DEFINE(inst) \
508 static struct adltc2990_data adltc2990_data_##inst; \
509 static const struct adltc2990_config adltc2990_config_##inst = { \
510 .bus = I2C_DT_SPEC_INST_GET(inst), \
511 .temp_format = DT_INST_PROP(inst, temperature_format), \
512 .acq_format = DT_INST_PROP(inst, acquistion_format), \
513 .measurement_mode = DT_INST_PROP(inst, measurement_mode), \
514 .pins_v1_v2.pins_current_resistor = \
515 DT_INST_PROP_OR(inst, pins_v1_v2_current_resistor, 1), \
516 .pins_v1_v2.voltage_divider_resistors.v1_r1_r2 = \
517 DT_INST_PROP_OR(inst, pin_v1_voltage_divider_resistors, NULL), \
518 .pins_v1_v2.voltage_divider_resistors.v2_r1_r2 = \
519 DT_INST_PROP_OR(inst, pin_v2_voltage_divider_resistors, NULL), \
520 .pins_v3_v4.pins_current_resistor = \
521 DT_INST_PROP_OR(inst, pins_v3_v4_current_resistor, 1), \
522 .pins_v3_v4.voltage_divider_resistors.v3_r1_r2 = \
523 DT_INST_PROP_OR(inst, pin_v3_voltage_divider_resistors, NULL), \
524 .pins_v3_v4.voltage_divider_resistors.v4_r1_r2 = \
525 DT_INST_PROP_OR(inst, pin_v4_voltage_divider_resistors, NULL)}; \
526 \
527 SENSOR_DEVICE_DT_INST_DEFINE(inst, adltc2990_init, NULL, &adltc2990_data_##inst, \
528 &adltc2990_config_##inst, POST_KERNEL, \
529 CONFIG_SENSOR_INIT_PRIORITY, &adltc2990_driver_api);
530
531 DT_INST_FOREACH_STATUS_OKAY(ADLTC2990_DEFINE)
532