1 /*
2  * Copyright (c) 2019 Centaur Analytics, Inc
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ti_tmp11x
8 
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/sensor.h>
12 #include <zephyr/pm/device.h>
13 #include <zephyr/drivers/sensor/tmp11x.h>
14 #include <zephyr/dt-bindings/sensor/tmp11x.h>
15 #include <zephyr/sys/util.h>
16 #include <zephyr/sys/byteorder.h>
17 #include <zephyr/sys/__assert.h>
18 #include <zephyr/logging/log.h>
19 #include <zephyr/kernel.h>
20 
21 #include "tmp11x.h"
22 
23 #define EEPROM_SIZE_REG        sizeof(uint16_t)
24 #define EEPROM_TMP117_RESERVED (2 * sizeof(uint16_t))
25 #define EEPROM_MIN_BUSY_MS     7
26 #define RESET_MIN_BUSY_MS      2
27 
28 LOG_MODULE_REGISTER(TMP11X, CONFIG_SENSOR_LOG_LEVEL);
29 
tmp11x_reg_read(const struct device * dev,uint8_t reg,uint16_t * val)30 int tmp11x_reg_read(const struct device *dev, uint8_t reg, uint16_t *val)
31 {
32 	const struct tmp11x_dev_config *cfg = dev->config;
33 
34 	if (i2c_burst_read_dt(&cfg->bus, reg, (uint8_t *)val, 2) < 0) {
35 		return -EIO;
36 	}
37 
38 	*val = sys_be16_to_cpu(*val);
39 
40 	return 0;
41 }
42 
tmp11x_reg_write(const struct device * dev,uint8_t reg,uint16_t val)43 int tmp11x_reg_write(const struct device *dev, uint8_t reg, uint16_t val)
44 {
45 	const struct tmp11x_dev_config *cfg = dev->config;
46 	uint8_t tx_buf[3] = {reg, val >> 8, val & 0xFF};
47 
48 	return i2c_write_dt(&cfg->bus, tx_buf, sizeof(tx_buf));
49 }
50 
tmp11x_write_config(const struct device * dev,uint16_t mask,uint16_t conf)51 int tmp11x_write_config(const struct device *dev, uint16_t mask, uint16_t conf)
52 {
53 	uint16_t config = 0;
54 	int result;
55 
56 	result = tmp11x_reg_read(dev, TMP11X_REG_CFGR, &config);
57 
58 	if (result < 0) {
59 		return result;
60 	}
61 
62 	config &= ~mask;
63 	config |= conf;
64 
65 	return tmp11x_reg_write(dev, TMP11X_REG_CFGR, config);
66 }
67 
tmp11x_is_offset_supported(const struct tmp11x_data * drv_data)68 static inline bool tmp11x_is_offset_supported(const struct tmp11x_data *drv_data)
69 {
70 	return drv_data->id == TMP117_DEVICE_ID || drv_data->id == TMP119_DEVICE_ID;
71 }
72 
73 /**
74  * @brief Convert sensor_value temperature to TMP11X register format
75  *
76  * This function converts a temperature from sensor_value format (val1 in degrees C,
77  * val2 in micro-degrees C) to the TMP11X register format. It uses 64-bit arithmetic
78  * to prevent overflow and clamps the result to the valid int16_t range.
79  *
80  * @param val Pointer to sensor_value containing temperature
81  * @return Temperature value in TMP11X register format (int16_t)
82  */
tmp11x_sensor_value_to_reg_format(const struct sensor_value * val)83 static inline int16_t tmp11x_sensor_value_to_reg_format(const struct sensor_value *val)
84 {
85 	int64_t temp_micro = ((int64_t)val->val1 * 1000000) + val->val2;
86 	int64_t temp_scaled = (temp_micro * 10) / TMP11X_RESOLUTION;
87 
88 	/* Clamp to int16_t range */
89 	if (temp_scaled > INT16_MAX) {
90 		return INT16_MAX;
91 	} else if (temp_scaled < INT16_MIN) {
92 		return INT16_MIN;
93 	} else {
94 		return (int16_t)temp_scaled;
95 	}
96 }
97 
check_eeprom_bounds(const struct device * dev,off_t offset,size_t len)98 static bool check_eeprom_bounds(const struct device *dev, off_t offset, size_t len)
99 {
100 	struct tmp11x_data *drv_data = dev->data;
101 
102 	if ((offset + len) > EEPROM_TMP11X_SIZE || offset % EEPROM_SIZE_REG != 0 ||
103 	    len % EEPROM_SIZE_REG != 0) {
104 		return false;
105 	}
106 
107 	/* TMP117 and TMP119 uses EEPROM[2] as temperature offset register */
108 	if ((drv_data->id == TMP117_DEVICE_ID || drv_data->id == TMP119_DEVICE_ID) &&
109 	    offset <= EEPROM_TMP117_RESERVED && (offset + len) > EEPROM_TMP117_RESERVED) {
110 		return false;
111 	}
112 
113 	return true;
114 }
115 
tmp11x_eeprom_await(const struct device * dev)116 int tmp11x_eeprom_await(const struct device *dev)
117 {
118 	int res;
119 	uint16_t val;
120 
121 	k_sleep(K_MSEC(EEPROM_MIN_BUSY_MS));
122 
123 	WAIT_FOR((res = tmp11x_reg_read(dev, TMP11X_REG_EEPROM_UL, &val)) != 0 ||
124 			 val & TMP11X_EEPROM_UL_BUSY,
125 		 100, k_msleep(1));
126 
127 	return res;
128 }
129 
tmp11x_eeprom_write(const struct device * dev,off_t offset,const void * data,size_t len)130 int tmp11x_eeprom_write(const struct device *dev, off_t offset, const void *data, size_t len)
131 {
132 	uint8_t reg;
133 	const uint16_t *src = data;
134 	int res;
135 
136 	if (!check_eeprom_bounds(dev, offset, len)) {
137 		return -EINVAL;
138 	}
139 
140 	res = tmp11x_reg_write(dev, TMP11X_REG_EEPROM_UL, TMP11X_EEPROM_UL_UNLOCK);
141 	if (res) {
142 		return res;
143 	}
144 
145 	for (reg = (offset / 2); reg < offset / 2 + len / 2; reg++) {
146 		uint16_t val = *src;
147 
148 		res = tmp11x_reg_write(dev, reg + TMP11X_REG_EEPROM1, val);
149 		if (res != 0) {
150 			break;
151 		}
152 
153 		res = tmp11x_eeprom_await(dev);
154 		src++;
155 
156 		if (res != 0) {
157 			break;
158 		}
159 	}
160 
161 	res = tmp11x_reg_write(dev, TMP11X_REG_EEPROM_UL, 0);
162 
163 	return res;
164 }
165 
tmp11x_eeprom_read(const struct device * dev,off_t offset,void * data,size_t len)166 int tmp11x_eeprom_read(const struct device *dev, off_t offset, void *data, size_t len)
167 {
168 	uint8_t reg;
169 	uint16_t *dst = data;
170 	int res = 0;
171 
172 	if (!check_eeprom_bounds(dev, offset, len)) {
173 		return -EINVAL;
174 	}
175 
176 	for (reg = (offset / 2); reg < offset / 2 + len / 2; reg++) {
177 		res = tmp11x_reg_read(dev, reg + TMP11X_REG_EEPROM1, dst);
178 		if (res != 0) {
179 			break;
180 		}
181 		dst++;
182 	}
183 
184 	return res;
185 }
186 
187 /**
188  * @brief Check the Device ID
189  *
190  * @param[in]   dev     Pointer to the device structure
191  * @param[in]	id	Pointer to the variable for storing the device id
192  *
193  * @retval 0 on success
194  * @retval -EIO Otherwise
195  */
tmp11x_device_id_check(const struct device * dev,uint16_t * id)196 static inline int tmp11x_device_id_check(const struct device *dev, uint16_t *id)
197 {
198 	if (tmp11x_reg_read(dev, TMP11X_REG_DEVICE_ID, id) != 0) {
199 		LOG_ERR("%s: Failed to get Device ID register!", dev->name);
200 		return -EIO;
201 	}
202 
203 	if ((*id != TMP116_DEVICE_ID) && (*id != TMP117_DEVICE_ID) && (*id != TMP119_DEVICE_ID)) {
204 		LOG_ERR("%s: Failed to match the device IDs!", dev->name);
205 		return -EINVAL;
206 	}
207 
208 	return 0;
209 }
210 
tmp11x_sample_fetch(const struct device * dev,enum sensor_channel chan)211 static int tmp11x_sample_fetch(const struct device *dev, enum sensor_channel chan)
212 {
213 	struct tmp11x_data *drv_data = dev->data;
214 	uint16_t value;
215 	uint16_t cfg_reg = 0;
216 	int rc;
217 
218 	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL || chan == SENSOR_CHAN_AMBIENT_TEMP);
219 
220 	/* clear sensor values */
221 	drv_data->sample = 0U;
222 
223 	/* Make sure that a data is available */
224 	rc = tmp11x_reg_read(dev, TMP11X_REG_CFGR, &cfg_reg);
225 	if (rc < 0) {
226 		LOG_ERR("%s, Failed to read from CFGR register", dev->name);
227 		return rc;
228 	}
229 
230 	if ((cfg_reg & TMP11X_CFGR_DATA_READY) == 0) {
231 		LOG_DBG("%s: no data ready", dev->name);
232 		return -EBUSY;
233 	}
234 
235 	/* Get the most recent temperature measurement */
236 	rc = tmp11x_reg_read(dev, TMP11X_REG_TEMP, &value);
237 	if (rc < 0) {
238 		LOG_ERR("%s: Failed to read from TEMP register!", dev->name);
239 		return rc;
240 	}
241 
242 	/* store measurements to the driver */
243 	drv_data->sample = (int16_t)value;
244 
245 	return 0;
246 }
247 
248 /*
249  * See datasheet "Temperature Results and Limits" section for more
250  * details on processing sample data.
251  */
tmp11x_temperature_to_sensor_value(int16_t temperature,struct sensor_value * val)252 static void tmp11x_temperature_to_sensor_value(int16_t temperature, struct sensor_value *val)
253 {
254 	int32_t tmp;
255 
256 	tmp = (temperature * (int32_t)TMP11X_RESOLUTION) / 10;
257 	val->val1 = tmp / 1000000; /* uCelsius */
258 	val->val2 = tmp % 1000000;
259 }
260 
tmp11x_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)261 static int tmp11x_channel_get(const struct device *dev, enum sensor_channel chan,
262 			      struct sensor_value *val)
263 {
264 	struct tmp11x_data *drv_data = dev->data;
265 
266 	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
267 		return -ENOTSUP;
268 	}
269 
270 	tmp11x_temperature_to_sensor_value(drv_data->sample, val);
271 
272 	return 0;
273 }
274 
tmp11x_conv_value(const struct sensor_value * val)275 static int16_t tmp11x_conv_value(const struct sensor_value *val)
276 {
277 	uint32_t freq_micro = sensor_value_to_micro(val);
278 
279 	switch (freq_micro) {
280 	case 64000000: /* 1 / 15.5 ms has been rounded down */
281 		return TMP11X_DT_ODR_15_5_MS;
282 	case 8000000:
283 		return TMP11X_DT_ODR_125_MS;
284 	case 4000000:
285 		return TMP11X_DT_ODR_250_MS;
286 	case 2000000:
287 		return TMP11X_DT_ODR_500_MS;
288 	case 1000000:
289 		return TMP11X_DT_ODR_1000_MS;
290 	case 250000:
291 		return TMP11X_DT_ODR_4000_MS;
292 	case 125000:
293 		return TMP11X_DT_ODR_8000_MS;
294 	case 62500:
295 		return TMP11X_DT_ODR_16000_MS;
296 	default:
297 		LOG_ERR("%" PRIu32 " uHz not supported", freq_micro);
298 		return -EINVAL;
299 	}
300 }
301 
tmp11x_is_attr_store_supported(enum sensor_attribute attr)302 static bool tmp11x_is_attr_store_supported(enum sensor_attribute attr)
303 {
304 	switch ((int)attr) {
305 	case SENSOR_ATTR_SAMPLING_FREQUENCY:
306 	case SENSOR_ATTR_LOWER_THRESH:
307 	case SENSOR_ATTR_UPPER_THRESH:
308 	case SENSOR_ATTR_OFFSET:
309 	case SENSOR_ATTR_OVERSAMPLING:
310 	case SENSOR_ATTR_TMP11X_SHUTDOWN_MODE:
311 	case SENSOR_ATTR_TMP11X_CONTINUOUS_CONVERSION_MODE:
312 	case SENSOR_ATTR_TMP11X_ALERT_PIN_POLARITY:
313 	case SENSOR_ATTR_TMP11X_ALERT_MODE:
314 		return true;
315 	case SENSOR_ATTR_TMP11X_ONE_SHOT_MODE:
316 		return false;
317 	}
318 
319 	return false;
320 }
321 
tmp11x_attr_store_reload(const struct device * dev)322 static int tmp11x_attr_store_reload(const struct device *dev)
323 {
324 	int await_res = tmp11x_eeprom_await(dev);
325 	int reset_res = tmp11x_reg_write(dev, TMP11X_REG_CFGR, TMP11X_CFGR_RESET);
326 
327 	k_sleep(K_MSEC(RESET_MIN_BUSY_MS));
328 
329 	return await_res != 0 ? await_res : reset_res;
330 }
331 
tmp11x_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)332 static int tmp11x_attr_set(const struct device *dev, enum sensor_channel chan,
333 			   enum sensor_attribute attr, const struct sensor_value *val)
334 {
335 	const struct tmp11x_dev_config *cfg = dev->config;
336 	struct tmp11x_data *drv_data = dev->data;
337 	int16_t value;
338 	int res = 0;
339 	bool store;
340 	int store_res = 0;
341 
342 	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
343 		return -ENOTSUP;
344 	}
345 
346 	store = cfg->store_attr_values && tmp11x_is_attr_store_supported(attr);
347 	if (store) {
348 		store_res = tmp11x_reg_write(dev, TMP11X_REG_EEPROM_UL, TMP11X_EEPROM_UL_UNLOCK);
349 		if (store_res != 0) {
350 			return store_res;
351 		}
352 	}
353 
354 	switch ((int)attr) {
355 	case SENSOR_ATTR_SAMPLING_FREQUENCY:
356 		value = tmp11x_conv_value(val);
357 		if (value < 0) {
358 			return value;
359 		}
360 
361 		res = tmp11x_write_config(dev, TMP11X_CFGR_CONV, value);
362 		break;
363 
364 	case SENSOR_ATTR_OFFSET:
365 		if (!tmp11x_is_offset_supported(drv_data)) {
366 			LOG_ERR("%s: Offset is not supported", dev->name);
367 			return -EINVAL;
368 		}
369 		/*
370 		 * The offset is encoded into the temperature register format.
371 		 */
372 		value = tmp11x_sensor_value_to_reg_format(val);
373 
374 		res = tmp11x_reg_write(dev, TMP117_REG_TEMP_OFFSET, value);
375 		break;
376 
377 	case SENSOR_ATTR_OVERSAMPLING:
378 		/* sensor supports averaging 1, 8, 32 and 64 samples */
379 		switch (val->val1) {
380 		case 1:
381 			value = TMP11X_AVG_1_SAMPLE;
382 			break;
383 
384 		case 8:
385 			value = TMP11X_AVG_8_SAMPLES;
386 			break;
387 
388 		case 32:
389 			value = TMP11X_AVG_32_SAMPLES;
390 			break;
391 
392 		case 64:
393 			value = TMP11X_AVG_64_SAMPLES;
394 			break;
395 
396 		default:
397 			res = -EINVAL;
398 			break;
399 		}
400 
401 		if (res == 0) {
402 			res = tmp11x_write_config(dev, TMP11X_CFGR_AVG, value);
403 		}
404 
405 		break;
406 
407 	case SENSOR_ATTR_TMP11X_SHUTDOWN_MODE:
408 		res = tmp11x_write_config(dev, TMP11X_CFGR_MODE, TMP11X_MODE_SHUTDOWN);
409 		break;
410 
411 	case SENSOR_ATTR_TMP11X_CONTINUOUS_CONVERSION_MODE:
412 		res = tmp11x_write_config(dev, TMP11X_CFGR_MODE, TMP11X_MODE_CONTINUOUS);
413 		break;
414 
415 	case SENSOR_ATTR_TMP11X_ONE_SHOT_MODE:
416 		res = tmp11x_write_config(dev, TMP11X_CFGR_MODE, TMP11X_MODE_ONE_SHOT);
417 		break;
418 
419 #ifdef CONFIG_TMP11X_TRIGGER
420 	case SENSOR_ATTR_TMP11X_ALERT_PIN_POLARITY:
421 		if (val->val1 == TMP11X_ALERT_PIN_ACTIVE_HIGH) {
422 			res = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_POL,
423 						  TMP11X_CFGR_ALERT_PIN_POL);
424 		} else {
425 			res = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_POL, 0);
426 		}
427 		break;
428 
429 	case SENSOR_ATTR_TMP11X_ALERT_MODE:
430 		if (val->val1 == TMP11X_ALERT_THERM_MODE) {
431 			res = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_MODE,
432 						  TMP11X_CFGR_ALERT_MODE);
433 		} else {
434 			res = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_MODE, 0);
435 		}
436 		break;
437 
438 	case SENSOR_ATTR_UPPER_THRESH:
439 		/* Convert temperature to register format */
440 		value = tmp11x_sensor_value_to_reg_format(val);
441 		res = tmp11x_reg_write(dev, TMP11X_REG_HIGH_LIM, value);
442 		break;
443 
444 	case SENSOR_ATTR_LOWER_THRESH:
445 		/* Convert temperature to register format */
446 		value = tmp11x_sensor_value_to_reg_format(val);
447 		res = tmp11x_reg_write(dev, TMP11X_REG_LOW_LIM, value);
448 		break;
449 
450 	case SENSOR_ATTR_TMP11X_ALERT_PIN_SELECT:
451 		if (val->val1 == TMP11X_ALERT_PIN_ALERT_SEL) {
452 			res = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_DR_SEL, 0);
453 		} else {
454 			res = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_DR_SEL,
455 						  TMP11X_CFGR_ALERT_DR_SEL);
456 		}
457 		break;
458 #endif /* CONFIG_TMP11X_TRIGGER */
459 
460 	default:
461 		res = -ENOTSUP;
462 		break;
463 	}
464 
465 	if (store) {
466 		store_res = tmp11x_attr_store_reload(dev);
467 	}
468 
469 	return res != 0 ? res : store_res;
470 }
471 
tmp11x_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)472 static int tmp11x_attr_get(const struct device *dev, enum sensor_channel chan,
473 			   enum sensor_attribute attr, struct sensor_value *val)
474 {
475 	uint16_t data;
476 	int rc;
477 
478 	if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
479 		return -ENOTSUP;
480 	}
481 
482 	switch (attr) {
483 	case SENSOR_ATTR_CONFIGURATION:
484 		rc = tmp11x_reg_read(dev, TMP11X_REG_CFGR, &data);
485 
486 		if (rc == 0) {
487 			val->val1 = data;
488 			val->val2 = 0;
489 		}
490 
491 		return rc;
492 
493 	case SENSOR_ATTR_OFFSET:
494 		if (!tmp11x_is_offset_supported(dev->data)) {
495 			LOG_ERR("%s: Offset is not supported", dev->name);
496 			return -EINVAL;
497 		}
498 
499 		rc = tmp11x_reg_read(dev, TMP117_REG_TEMP_OFFSET, &data);
500 		if (rc == 0) {
501 			tmp11x_temperature_to_sensor_value(data, val);
502 		}
503 
504 		return rc;
505 
506 #ifdef CONFIG_TMP11X_TRIGGER
507 	case SENSOR_ATTR_UPPER_THRESH:
508 		rc = tmp11x_reg_read(dev, TMP11X_REG_HIGH_LIM, &data);
509 		if (rc == 0) {
510 			tmp11x_temperature_to_sensor_value(data, val);
511 		}
512 
513 		return rc;
514 
515 	case SENSOR_ATTR_LOWER_THRESH:
516 		rc = tmp11x_reg_read(dev, TMP11X_REG_LOW_LIM, &data);
517 		if (rc == 0) {
518 			tmp11x_temperature_to_sensor_value(data, val);
519 		}
520 
521 		return rc;
522 #endif /* CONFIG_TMP11X_TRIGGER */
523 
524 	default:
525 		return -ENOTSUP;
526 	}
527 }
528 
529 static DEVICE_API(sensor, tmp11x_driver_api) = {
530 	.attr_set = tmp11x_attr_set,
531 	.attr_get = tmp11x_attr_get,
532 	.sample_fetch = tmp11x_sample_fetch,
533 	.channel_get = tmp11x_channel_get,
534 #ifdef CONFIG_TMP11X_TRIGGER
535 	.trigger_set = tmp11x_trigger_set,
536 #endif
537 };
538 
tmp11x_init(const struct device * dev)539 static int tmp11x_init(const struct device *dev)
540 {
541 	struct tmp11x_data *drv_data = dev->data;
542 	const struct tmp11x_dev_config *cfg = dev->config;
543 	int rc;
544 	uint16_t id;
545 
546 	if (!device_is_ready(cfg->bus.bus)) {
547 		LOG_ERR("I2C dev %s not ready", cfg->bus.bus->name);
548 		return -EINVAL;
549 	}
550 
551 	/* Check the Device ID */
552 	rc = tmp11x_device_id_check(dev, &id);
553 	if (rc < 0) {
554 		return rc;
555 	}
556 	LOG_DBG("Got device ID: %x", id);
557 	drv_data->id = id;
558 
559 	rc = tmp11x_write_config(dev, TMP11X_CFGR_CONV, cfg->odr);
560 	if (rc < 0) {
561 		return rc;
562 	}
563 
564 	rc = tmp11x_write_config(dev, TMP11X_CFGR_AVG, cfg->oversampling);
565 	if (rc < 0) {
566 		return rc;
567 	}
568 
569 	int8_t value = cfg->alert_pin_polarity ? TMP11X_CFGR_ALERT_PIN_POL : 0;
570 
571 	rc = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_POL, value);
572 	if (rc < 0) {
573 		return rc;
574 	}
575 
576 	value = cfg->alert_mode ? TMP11X_CFGR_ALERT_MODE : 0;
577 	rc = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_MODE, value);
578 	if (rc < 0) {
579 		return rc;
580 	}
581 
582 	value = cfg->alert_dr_sel ? TMP11X_CFGR_ALERT_DR_SEL : 0;
583 	rc = tmp11x_write_config(dev, TMP11X_CFGR_ALERT_DR_SEL, value);
584 	if (rc < 0) {
585 		return rc;
586 	}
587 
588 #ifdef CONFIG_TMP11X_TRIGGER
589 	drv_data->dev = dev;
590 	rc = tmp11x_init_interrupt(dev);
591 	if (rc < 0) {
592 		LOG_ERR("%s: Failed to initialize alert pin", dev->name);
593 		return rc;
594 	}
595 #endif /* CONFIG_TMP11X_TRIGGER */
596 
597 	return rc;
598 }
599 
600 #ifdef CONFIG_PM_DEVICE
601 BUILD_ASSERT(!DT_INST_NODE_HAS_PROP(_num, power_domains), "Driver does not support power domain");
tmp11x_pm_control(const struct device * dev,enum pm_device_action action)602 static int tmp11x_pm_control(const struct device *dev, enum pm_device_action action)
603 {
604 	int ret = 0;
605 
606 	switch (action) {
607 	case PM_DEVICE_ACTION_RESUME: {
608 		const struct tmp11x_dev_config *cfg = dev->config;
609 
610 		ret = tmp11x_write_config(dev, TMP11X_CFGR_CONV, cfg->odr);
611 		if (ret < 0) {
612 			LOG_ERR("Failed to resume TMP11X");
613 		}
614 		break;
615 	}
616 	case PM_DEVICE_ACTION_SUSPEND: {
617 		ret = tmp11x_write_config(dev, TMP11X_CFGR_MODE, TMP11X_MODE_SHUTDOWN);
618 		if (ret < 0) {
619 			LOG_ERR("Failed to suspend TMP11X");
620 		}
621 		break;
622 	}
623 	default:
624 		ret = -ENOTSUP;
625 	}
626 
627 	return ret;
628 }
629 #endif /* CONFIG_PM_DEVICE */
630 
631 #ifdef CONFIG_TMP11X_TRIGGER
632 #define DEFINE_TMP11X_TRIGGER(_num) .alert_gpio = GPIO_DT_SPEC_INST_GET_OR(_num, alert_gpios, {}),
633 #else
634 #define DEFINE_TMP11X_TRIGGER(_num)
635 #endif
636 
637 #define DEFINE_TMP11X(_num)                                                                        \
638 	static struct tmp11x_data tmp11x_data_##_num;                                              \
639 	static const struct tmp11x_dev_config tmp11x_config_##_num = {                             \
640 		.bus = I2C_DT_SPEC_INST_GET(_num),                                                 \
641 		.odr = DT_INST_PROP(_num, odr),                                                    \
642 		.oversampling = DT_INST_PROP(_num, oversampling),                                  \
643 		.alert_pin_polarity = DT_INST_PROP(_num, alert_polarity),                          \
644 		.alert_mode = DT_INST_PROP(_num, alert_mode),                                      \
645 		.alert_dr_sel = DT_INST_PROP(_num, alert_dr_sel),                                  \
646 		.store_attr_values = DT_INST_PROP(_num, store_attr_values),                        \
647 		DEFINE_TMP11X_TRIGGER(_num)};                                                      \
648                                                                                                    \
649 	PM_DEVICE_DT_INST_DEFINE(_num, tmp11x_pm_control);                                         \
650                                                                                                    \
651 	SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp11x_init, PM_DEVICE_DT_INST_GET(_num),               \
652 				     &tmp11x_data_##_num, &tmp11x_config_##_num, POST_KERNEL,      \
653 				     CONFIG_SENSOR_INIT_PRIORITY, &tmp11x_driver_api);
654 
655 DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMP11X)
656