1 /*
2  * Copyright (c) 2019 Thomas Schmid <tom@lfence.de>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT meas_ms5607
8 
9 #include <string.h>
10 #include <zephyr/drivers/spi.h>
11 #include <zephyr/kernel.h>
12 #include <zephyr/sys/byteorder.h>
13 #include "ms5607.h"
14 
15 #define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_DECLARE(ms5607);
18 
19 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
20 
ms5607_spi_raw_cmd(const struct ms5607_config * config,uint8_t cmd)21 static int ms5607_spi_raw_cmd(const struct ms5607_config *config, uint8_t cmd)
22 {
23 	const struct spi_buf buf = {
24 		.buf = &cmd,
25 		.len = 1,
26 	};
27 
28 	const struct spi_buf_set buf_set = {
29 		.buffers = &buf,
30 		.count = 1,
31 	};
32 
33 	return spi_write_dt(&config->bus_cfg.spi, &buf_set);
34 }
35 
ms5607_spi_reset(const struct ms5607_config * config)36 static int ms5607_spi_reset(const struct ms5607_config *config)
37 {
38 	int err = ms5607_spi_raw_cmd(config, MS5607_CMD_RESET);
39 
40 	if (err < 0) {
41 		return err;
42 	}
43 
44 	k_sleep(K_MSEC(3));
45 	return 0;
46 }
47 
ms5607_spi_read_prom(const struct ms5607_config * config,uint8_t cmd,uint16_t * val)48 static int ms5607_spi_read_prom(const struct ms5607_config *config, uint8_t cmd,
49 				uint16_t *val)
50 {
51 	int err;
52 
53 	uint8_t tx[3] = { cmd, 0, 0 };
54 	const struct spi_buf tx_buf = {
55 		.buf = tx,
56 		.len = 3,
57 	};
58 
59 	union {
60 		struct {
61 			uint8_t pad;
62 			uint16_t prom_value;
63 		} __packed;
64 		uint8_t rx[3];
65 	} rx;
66 
67 
68 	const struct spi_buf rx_buf = {
69 		.buf = &rx,
70 		.len = 3,
71 	};
72 
73 	const struct spi_buf_set rx_buf_set = {
74 		.buffers = &rx_buf,
75 		.count = 1,
76 	};
77 
78 	const struct spi_buf_set tx_buf_set = {
79 		.buffers = &tx_buf,
80 		.count = 1,
81 	};
82 
83 	err = spi_transceive_dt(&config->bus_cfg.spi, &tx_buf_set, &rx_buf_set);
84 	if (err < 0) {
85 		return err;
86 	}
87 
88 	*val = sys_be16_to_cpu(rx.prom_value);
89 
90 	return 0;
91 }
92 
93 
ms5607_spi_start_conversion(const struct ms5607_config * config,uint8_t cmd)94 static int ms5607_spi_start_conversion(const struct ms5607_config *config, uint8_t cmd)
95 {
96 	return ms5607_spi_raw_cmd(config, cmd);
97 }
98 
ms5607_spi_read_adc(const struct ms5607_config * config,uint32_t * val)99 static int ms5607_spi_read_adc(const struct ms5607_config *config, uint32_t *val)
100 {
101 	int err;
102 
103 	uint8_t tx[4] = { MS5607_CMD_CONV_READ_ADC, 0, 0, 0 };
104 	const struct spi_buf tx_buf = {
105 		.buf = tx,
106 		.len = 4,
107 	};
108 
109 	union {
110 		struct {
111 			uint32_t adc_value;
112 		} __packed;
113 		uint8_t rx[4];
114 	} rx;
115 
116 	const struct spi_buf rx_buf = {
117 		.buf = &rx,
118 		.len = 4,
119 	};
120 
121 	const struct spi_buf_set rx_buf_set = {
122 		.buffers = &rx_buf,
123 		.count = 1,
124 	};
125 
126 	const struct spi_buf_set tx_buf_set = {
127 		.buffers = &tx_buf,
128 		.count = 1,
129 	};
130 
131 	err = spi_transceive_dt(&config->bus_cfg.spi, &tx_buf_set, &rx_buf_set);
132 	if (err < 0) {
133 		return err;
134 	}
135 
136 	rx.rx[0] = 0;
137 	*val = sys_be32_to_cpu(rx.adc_value);
138 	return 0;
139 }
140 
ms5607_spi_check(const struct ms5607_config * config)141 static int ms5607_spi_check(const struct ms5607_config *config)
142 {
143 	if (!spi_is_ready_dt(&config->bus_cfg.spi)) {
144 		LOG_DBG("SPI bus not ready");
145 		return -ENODEV;
146 	}
147 
148 	return 0;
149 }
150 
151 const struct ms5607_transfer_function ms5607_spi_transfer_function = {
152 	.bus_check = ms5607_spi_check,
153 	.reset = ms5607_spi_reset,
154 	.read_prom = ms5607_spi_read_prom,
155 	.start_conversion = ms5607_spi_start_conversion,
156 	.read_adc = ms5607_spi_read_adc,
157 };
158 
159 #endif
160