7
7
#define DT_DRV_COMPAT ti_tmp11x
8
8
9
9
#include <zephyr/device.h>
10
- #include <zephyr/drivers/i2c.h>
11
10
#include <zephyr/drivers/sensor.h>
12
11
#include <zephyr/drivers/sensor/tmp11x.h>
13
12
#include <zephyr/dt-bindings/sensor/tmp11x.h>
25
24
26
25
LOG_MODULE_REGISTER (TMP11X , CONFIG_SENSOR_LOG_LEVEL );
27
26
28
- static int tmp11x_reg_read (const struct device * dev , uint8_t reg ,
29
- uint16_t * val )
27
+ int tmp11x_reg_read (const struct device * dev , uint8_t reg , uint16_t * val )
30
28
{
31
29
const struct tmp11x_dev_config * cfg = dev -> config ;
32
30
@@ -40,8 +38,7 @@ static int tmp11x_reg_read(const struct device *dev, uint8_t reg,
40
38
return 0 ;
41
39
}
42
40
43
- static int tmp11x_reg_write (const struct device * dev , uint8_t reg ,
44
- uint16_t val )
41
+ int tmp11x_reg_write (const struct device * dev , uint8_t reg , uint16_t val )
45
42
{
46
43
const struct tmp11x_dev_config * cfg = dev -> config ;
47
44
uint8_t tx_buf [3 ] = {reg , val >> 8 , val & 0xFF };
@@ -71,6 +68,31 @@ static inline bool tmp11x_is_offset_supported(const struct tmp11x_data *drv_data
71
68
return drv_data -> id == TMP117_DEVICE_ID || drv_data -> id == TMP119_DEVICE_ID ;
72
69
}
73
70
71
+ /**
72
+ * @brief Convert sensor_value temperature to TMP11X register format
73
+ *
74
+ * This function converts a temperature from sensor_value format (val1 in degrees C,
75
+ * val2 in micro-degrees C) to the TMP11X register format. It uses 64-bit arithmetic
76
+ * to prevent overflow and clamps the result to the valid int16_t range.
77
+ *
78
+ * @param val Pointer to sensor_value containing temperature
79
+ * @return Temperature value in TMP11X register format (int16_t)
80
+ */
81
+ static inline int16_t tmp11x_sensor_value_to_reg_format (const struct sensor_value * val )
82
+ {
83
+ int64_t temp_micro = ((int64_t )val -> val1 * 1000000 ) + val -> val2 ;
84
+ int64_t temp_scaled = (temp_micro * 10 ) / TMP11X_RESOLUTION ;
85
+
86
+ /* Clamp to int16_t range */
87
+ if (temp_scaled > INT16_MAX ) {
88
+ return INT16_MAX ;
89
+ } else if (temp_scaled < INT16_MIN ) {
90
+ return INT16_MIN ;
91
+ } else {
92
+ return (int16_t )temp_scaled ;
93
+ }
94
+ }
95
+
74
96
static bool check_eeprom_bounds (const struct device * dev , off_t offset ,
75
97
size_t len )
76
98
{
@@ -310,8 +332,7 @@ static int tmp11x_attr_set(const struct device *dev,
310
332
/*
311
333
* The offset is encoded into the temperature register format.
312
334
*/
313
- value = (((val -> val1 ) * 10000000 ) + ((val -> val2 ) * 10 ))
314
- / (int32_t )TMP11X_RESOLUTION ;
335
+ value = tmp11x_sensor_value_to_reg_format (val );
315
336
316
337
return tmp11x_reg_write (dev , TMP117_REG_TEMP_OFFSET , value );
317
338
@@ -347,6 +368,34 @@ static int tmp11x_attr_set(const struct device *dev,
347
368
case SENSOR_ATTR_TMP11X_ONE_SHOT_MODE :
348
369
return tmp11x_write_config (dev , TMP11X_CFGR_MODE , TMP11X_MODE_ONE_SHOT );
349
370
371
+ #ifdef CONFIG_TMP11X_TRIGGER
372
+ case SENSOR_ATTR_TMP11X_ALERT_PIN_POLARITY :
373
+ if (val -> val1 == TMP11X_ALERT_PIN_ACTIVE_HIGH ) {
374
+ return tmp11x_write_config (dev , TMP11X_CFGR_ALERT_PIN_POL ,
375
+ TMP11X_CFGR_ALERT_PIN_POL );
376
+ } else {
377
+ return tmp11x_write_config (dev , TMP11X_CFGR_ALERT_PIN_POL , 0 );
378
+ }
379
+
380
+ case SENSOR_ATTR_TMP11X_ALERT_PIN_MODE :
381
+ if (val -> val1 == TMP11X_ALERT_PIN_THERM_MODE ) {
382
+ return tmp11x_write_config (dev , TMP11X_CFGR_ALERT_PIN_MODE ,
383
+ TMP11X_CFGR_ALERT_PIN_MODE );
384
+ } else {
385
+ return tmp11x_write_config (dev , TMP11X_CFGR_ALERT_PIN_MODE , 0 );
386
+ }
387
+
388
+ case SENSOR_ATTR_UPPER_THRESH :
389
+ /* Convert temperature to register format */
390
+ value = tmp11x_sensor_value_to_reg_format (val );
391
+ return tmp11x_reg_write (dev , TMP11X_REG_HIGH_LIM , value );
392
+
393
+ case SENSOR_ATTR_LOWER_THRESH :
394
+ /* Convert temperature to register format */
395
+ value = tmp11x_sensor_value_to_reg_format (val );
396
+ return tmp11x_reg_write (dev , TMP11X_REG_LOW_LIM , value );
397
+ #endif /* CONFIG_TMP11X_TRIGGER */
398
+
350
399
default :
351
400
return - ENOTSUP ;
352
401
}
@@ -385,6 +434,25 @@ static int tmp11x_attr_get(const struct device *dev, enum sensor_channel chan,
385
434
}
386
435
387
436
return rc ;
437
+
438
+ #ifdef CONFIG_TMP11X_TRIGGER
439
+ case SENSOR_ATTR_UPPER_THRESH :
440
+ rc = tmp11x_reg_read (dev , TMP11X_REG_HIGH_LIM , & data );
441
+ if (rc == 0 ) {
442
+ tmp11x_temperature_to_sensor_value (data , val );
443
+ }
444
+
445
+ return rc ;
446
+
447
+ case SENSOR_ATTR_LOWER_THRESH :
448
+ rc = tmp11x_reg_read (dev , TMP11X_REG_LOW_LIM , & data );
449
+ if (rc == 0 ) {
450
+ tmp11x_temperature_to_sensor_value (data , val );
451
+ }
452
+
453
+ return rc ;
454
+ #endif /* CONFIG_TMP11X_TRIGGER */
455
+
388
456
default :
389
457
return - ENOTSUP ;
390
458
}
@@ -394,7 +462,10 @@ static DEVICE_API(sensor, tmp11x_driver_api) = {
394
462
.attr_set = tmp11x_attr_set ,
395
463
.attr_get = tmp11x_attr_get ,
396
464
.sample_fetch = tmp11x_sample_fetch ,
397
- .channel_get = tmp11x_channel_get
465
+ .channel_get = tmp11x_channel_get ,
466
+ #ifdef CONFIG_TMP11X_TRIGGER
467
+ .trigger_set = tmp11x_trigger_set ,
468
+ #endif
398
469
};
399
470
400
471
static int tmp11x_init (const struct device * dev )
@@ -424,18 +495,28 @@ static int tmp11x_init(const struct device *dev)
424
495
425
496
rc = tmp11x_write_config (dev , TMP11X_CFGR_AVG , cfg -> oversampling );
426
497
498
+ #ifdef CONFIG_TMP11X_TRIGGER
499
+ drv_data -> dev = dev ;
500
+ rc = tmp11x_init_interrupt (dev );
501
+ if (rc < 0 ) {
502
+ LOG_ERR ("%s: Failed to initialize alert pin" , dev -> name );
503
+ return rc ;
504
+ }
505
+ #endif /* CONFIG_TMP11X_TRIGGER */
506
+
427
507
return rc ;
428
508
}
429
509
430
- #define DEFINE_TMP11X (_num ) \
431
- static struct tmp11x_data tmp11x_data_##_num; \
432
- static const struct tmp11x_dev_config tmp11x_config_##_num = { \
433
- .bus = I2C_DT_SPEC_INST_GET(_num), \
434
- .odr = DT_INST_PROP(_num, odr), \
435
- .oversampling = DT_INST_PROP(_num, oversampling), \
436
- }; \
437
- SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp11x_init, NULL, \
438
- &tmp11x_data_##_num, &tmp11x_config_##_num, POST_KERNEL, \
439
- CONFIG_SENSOR_INIT_PRIORITY, &tmp11x_driver_api);
510
+ #define DEFINE_TMP11X (_num ) \
511
+ static struct tmp11x_data tmp11x_data_##_num; \
512
+ static const struct tmp11x_dev_config tmp11x_config_##_num = { \
513
+ .bus = I2C_DT_SPEC_INST_GET(_num), \
514
+ .odr = DT_INST_PROP(_num, odr), \
515
+ .oversampling = DT_INST_PROP(_num, oversampling), \
516
+ IF_ENABLED(CONFIG_TMP11X_TRIGGER, \
517
+ (.alert_gpio = GPIO_DT_SPEC_INST_GET_OR(_num, alert_gpios, {}),)) }; \
518
+ SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp11x_init, NULL, &tmp11x_data_##_num, \
519
+ &tmp11x_config_##_num, POST_KERNEL, \
520
+ CONFIG_SENSOR_INIT_PRIORITY, &tmp11x_driver_api);
440
521
441
522
DT_INST_FOREACH_STATUS_OKAY (DEFINE_TMP11X )
0 commit comments