1 /*
2  * Copyright (c) 2024 ENE Technology Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ene_kb1200_adc
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/adc.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <errno.h>
13 #include <reg/adc.h>
14 #include <zephyr/logging/log.h>
15 
16 #define ADC_CONTEXT_USES_KERNEL_TIMER
17 #include "adc_context.h"
18 
19 LOG_MODULE_REGISTER(adc_ene_kb1200, CONFIG_ADC_LOG_LEVEL);
20 
21 struct adc_kb1200_config {
22 	/* ADC Register base address */
23 	struct adc_regs *adc;
24 	/* Pin control */
25 	const struct pinctrl_dev_config *pcfg;
26 };
27 
28 struct adc_kb1200_data {
29 	struct adc_context ctx;
30 	const struct device *adc_dev;
31 	uint16_t *buffer;
32 	uint16_t *repeat_buffer;
33 	uint16_t *buf_end;
34 };
35 
36 /* ADC local functions */
adc_kb1200_validate_buffer_size(const struct adc_sequence * sequence)37 static bool adc_kb1200_validate_buffer_size(const struct adc_sequence *sequence)
38 {
39 	int chan_count = 0;
40 	size_t buff_need;
41 	uint32_t chan_mask;
42 
43 	for (chan_mask = 0x80; chan_mask != 0; chan_mask >>= 1) {
44 		if (chan_mask & sequence->channels) {
45 			chan_count++;
46 		}
47 	}
48 
49 	buff_need = chan_count * sizeof(uint16_t);
50 
51 	if (sequence->options) {
52 		buff_need *= 1 + sequence->options->extra_samplings;
53 	}
54 
55 	if (buff_need > sequence->buffer_size) {
56 		return false;
57 	}
58 
59 	return true;
60 }
61 /* ADC Sample Flow (by using adc_context.h api function)
62  *  1. Start ADC sampling (set up flag ctx->sync)
63  *     adc_context_start_read() -> adc_context_start_sampling()
64  *  2. Wait ADC sample finish (by monitor flag ctx->sync)
65  *     adc_context_wait_for_completion
66  *  3. Finish ADC sample (isr clear flag ctx->sync)
67  *     adc_context_on_sampling_done -> adc_context_complete
68  */
adc_kb1200_start_read(const struct device * dev,const struct adc_sequence * sequence)69 static int adc_kb1200_start_read(const struct device *dev, const struct adc_sequence *sequence)
70 {
71 	const struct adc_kb1200_config *config = dev->config;
72 	struct adc_kb1200_data *data = dev->data;
73 	int error = 0;
74 
75 	if (!sequence->channels || (sequence->channels & ~BIT_MASK(ADC_MAX_CHAN))) {
76 		LOG_ERR("Invalid ADC channels.");
77 		return -EINVAL;
78 	}
79 	/* Fixed 10 bit resolution of ene ADC */
80 	if (sequence->resolution != ADC_RESOLUTION) {
81 		LOG_ERR("Unfixed 10 bit ADC resolution.");
82 		return -ENOTSUP;
83 	}
84 	/* Check sequence->buffer_size is enough */
85 	if (!adc_kb1200_validate_buffer_size(sequence)) {
86 		LOG_ERR("ADC buffer size too small.");
87 		return -ENOMEM;
88 	}
89 
90 	/* assign record buffer pointer */
91 	data->buffer = sequence->buffer;
92 	data->buf_end = data->buffer + sequence->buffer_size / sizeof(uint16_t);
93 	/* store device for adc_context_start_read() */
94 	data->adc_dev = dev;
95 	/* Inform adc start sampling */
96 	adc_context_start_read(&data->ctx, sequence);
97 	/* Since kb1200 adc has no irq. So need polling the adc conversion
98 	 * flag to be valid, then record adc value.
99 	 */
100 	uint32_t channels = (config->adc->ADCCFG & ADC_CHANNEL_BIT_MASK) >> ADC_CHANNEL_BIT_POS;
101 
102 	while (channels) {
103 		int count;
104 		int ch_num;
105 
106 		count = 0;
107 		ch_num = find_lsb_set(channels) - 1;
108 		/* wait valid flag */
109 		while (config->adc->ADCDAT[ch_num] & ADC_INVALID_VALUE) {
110 			k_busy_wait(ADC_WAIT_TIME);
111 			count++;
112 			if (count >= ADC_WAIT_CNT) {
113 				LOG_ERR("ADC busy timeout...");
114 				error = -EBUSY;
115 				break;
116 			}
117 		}
118 		/* check buffer size is enough then record adc value */
119 		if (data->buffer < data->buf_end) {
120 			*data->buffer = (uint16_t)(config->adc->ADCDAT[ch_num]);
121 			data->buffer++;
122 		} else {
123 			error = -EINVAL;
124 			break;
125 		}
126 
127 		/* clear completed channel */
128 		channels &= ~BIT(ch_num);
129 	}
130 	/* Besause polling the adc conversion flag. don't need wait_for_completion*/
131 
132 	/* Inform adc sampling is done */
133 	adc_context_on_sampling_done(&data->ctx, dev);
134 	return error;
135 }
136 
137 /* ADC api functions */
adc_kb1200_channel_setup(const struct device * dev,const struct adc_channel_cfg * channel_cfg)138 static int adc_kb1200_channel_setup(const struct device *dev,
139 				    const struct adc_channel_cfg *channel_cfg)
140 {
141 	if (channel_cfg->channel_id >= ADC_MAX_CHAN) {
142 		LOG_ERR("Invalid channel %d.", channel_cfg->channel_id);
143 		return -EINVAL;
144 	}
145 
146 	if (channel_cfg->acquisition_time != ADC_ACQ_TIME_DEFAULT) {
147 		LOG_ERR("Unsupported channel acquisition time.");
148 		return -ENOTSUP;
149 	}
150 
151 	if (channel_cfg->differential) {
152 		LOG_ERR("Differential channels are not supported.");
153 		return -ENOTSUP;
154 	}
155 
156 	if (channel_cfg->gain != ADC_GAIN_1) {
157 		LOG_ERR("Unsupported channel gain %d.", channel_cfg->gain);
158 		return -ENOTSUP;
159 	}
160 
161 	if (channel_cfg->reference != ADC_REF_INTERNAL) {
162 		LOG_ERR("Unsupported channel reference.");
163 		return -ENOTSUP;
164 	}
165 	LOG_DBG("ADC channel %d configured.", channel_cfg->channel_id);
166 	return 0;
167 }
168 
adc_kb1200_read(const struct device * dev,const struct adc_sequence * sequence)169 static int adc_kb1200_read(const struct device *dev, const struct adc_sequence *sequence)
170 {
171 	struct adc_kb1200_data *data = dev->data;
172 	int error;
173 
174 	adc_context_lock(&data->ctx, false, NULL);
175 	error = adc_kb1200_start_read(dev, sequence);
176 	adc_context_release(&data->ctx, error);
177 
178 	return error;
179 }
180 
181 #if defined(CONFIG_ADC_ASYNC)
adc_kb1200_read_async(const struct device * dev,const struct adc_sequence * sequence,struct k_poll_signal * async)182 static int adc_kb1200_read_async(const struct device *dev, const struct adc_sequence *sequence,
183 				 struct k_poll_signal *async)
184 {
185 	struct adc_kb1200_data *data = dev->data;
186 	int error;
187 
188 	adc_context_lock(&data->ctx, true, async);
189 	error = adc_kb1200_start_read(dev, sequence);
190 	adc_context_release(&data->ctx, error);
191 
192 	return error;
193 }
194 #endif /* CONFIG_ADC_ASYNC */
195 
196 /* ADC api function (using by adc_context.H function) */
adc_context_start_sampling(struct adc_context * ctx)197 static void adc_context_start_sampling(struct adc_context *ctx)
198 {
199 	struct adc_kb1200_data *data = CONTAINER_OF(ctx, struct adc_kb1200_data, ctx);
200 	const struct device *dev = data->adc_dev;
201 	const struct adc_kb1200_config *config = dev->config;
202 
203 	data->repeat_buffer = data->buffer;
204 	config->adc->ADCCFG = (config->adc->ADCCFG & ~ADC_CHANNEL_BIT_MASK) |
205 			      (ctx->sequence.channels << ADC_CHANNEL_BIT_POS);
206 	config->adc->ADCCFG |= ADC_FUNCTION_ENABLE;
207 }
208 
adc_context_update_buffer_pointer(struct adc_context * ctx,bool repeat_sampling)209 static void adc_context_update_buffer_pointer(struct adc_context *ctx, bool repeat_sampling)
210 {
211 	struct adc_kb1200_data *data = CONTAINER_OF(ctx, struct adc_kb1200_data, ctx);
212 
213 	if (repeat_sampling) {
214 		data->buffer = data->repeat_buffer;
215 	}
216 }
217 
218 static DEVICE_API(adc, adc_kb1200_api) = {
219 	.channel_setup = adc_kb1200_channel_setup,
220 	.read = adc_kb1200_read,
221 	.ref_internal = ADC_VREF_ANALOG,
222 #if defined(CONFIG_ADC_ASYNC)
223 	.read_async = adc_kb1200_read_async,
224 #endif
225 };
226 
adc_kb1200_init(const struct device * dev)227 static int adc_kb1200_init(const struct device *dev)
228 {
229 	const struct adc_kb1200_config *config = dev->config;
230 	struct adc_kb1200_data *data = dev->data;
231 	int ret;
232 
233 	adc_context_unlock_unconditionally(&data->ctx);
234 	/* Configure pin-mux for ADC device */
235 	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
236 	if (ret < 0) {
237 		LOG_ERR("ADC pinctrl setup failed (%d).", ret);
238 		return ret;
239 	}
240 
241 	return 0;
242 }
243 
244 #define ADC_KB1200_DEVICE(inst)                                                                    \
245 	PINCTRL_DT_INST_DEFINE(inst);                                                              \
246 	static struct adc_kb1200_data adc_kb1200_data_##inst = {                                   \
247 		ADC_CONTEXT_INIT_TIMER(adc_kb1200_data_##inst, ctx),                               \
248 		ADC_CONTEXT_INIT_LOCK(adc_kb1200_data_##inst, ctx),                                \
249 		ADC_CONTEXT_INIT_SYNC(adc_kb1200_data_##inst, ctx),                                \
250 	};                                                                                         \
251 	static const struct adc_kb1200_config adc_kb1200_config_##inst = {                         \
252 		.adc = (struct adc_regs *)DT_INST_REG_ADDR(inst),                                  \
253 		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),                                      \
254 	};                                                                                         \
255 	DEVICE_DT_INST_DEFINE(inst, adc_kb1200_init, NULL, &adc_kb1200_data_##inst,                \
256 			      &adc_kb1200_config_##inst, PRE_KERNEL_1,                             \
257 			      CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &adc_kb1200_api);
258 
259 DT_INST_FOREACH_STATUS_OKAY(ADC_KB1200_DEVICE)
260