1 /*
2  * Copyright (c) 2019 Brett Witherspoon
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ti_cc13xx_cc26xx_i2c
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/i2c.h>
11 #include <zephyr/drivers/pinctrl.h>
12 #include <zephyr/pm/device.h>
13 #include <zephyr/pm/policy.h>
14 
15 #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(i2c_cc13xx_cc26xx);
18 
19 #include <driverlib/i2c.h>
20 #include <driverlib/prcm.h>
21 
22 #include <ti/drivers/Power.h>
23 #include <ti/drivers/power/PowerCC26X2.h>
24 #include <zephyr/irq.h>
25 
26 #include "i2c-priv.h"
27 
28 struct i2c_cc13xx_cc26xx_data {
29 	struct k_sem lock;
30 	struct k_sem complete;
31 	volatile uint32_t error;
32 #ifdef CONFIG_PM
33 	Power_NotifyObj postNotify;
34 	uint32_t dev_config;
35 #endif
36 };
37 
38 struct i2c_cc13xx_cc26xx_config {
39 	uint32_t base;
40 	const struct pinctrl_dev_config *pcfg;
41 };
42 
i2c_cc13xx_cc26xx_transmit(const struct device * dev,const uint8_t * buf,uint32_t len,uint16_t addr)43 static int i2c_cc13xx_cc26xx_transmit(const struct device *dev,
44 				      const uint8_t *buf,
45 				      uint32_t len, uint16_t addr)
46 {
47 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
48 	const uint32_t base = config->base;
49 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
50 
51 	/* Sending address without data is not supported */
52 	if (len == 0) {
53 		return -EIO;
54 	}
55 
56 	I2CMasterSlaveAddrSet(base, addr, false);
57 
58 	/* The following assumes a single master. Use I2CMasterBusBusy() if
59 	 * wanting to implement multiple master support.
60 	 */
61 
62 	/* Single transmission */
63 	if (len == 1) {
64 		I2CMasterDataPut(base, *buf);
65 
66 		I2CMasterControl(base, I2C_MASTER_CMD_SINGLE_SEND);
67 
68 		k_sem_take(&data->complete, K_FOREVER);
69 
70 		return data->error == I2C_MASTER_ERR_NONE ? 0 : -EIO;
71 	}
72 
73 	/* Burst transmission */
74 	I2CMasterDataPut(base, buf[0]);
75 
76 	I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_START);
77 
78 	k_sem_take(&data->complete, K_FOREVER);
79 
80 	if (data->error != I2C_MASTER_ERR_NONE) {
81 		goto send_error_stop;
82 	}
83 
84 	for (int i = 1; i < len - 1; i++) {
85 		I2CMasterDataPut(base, buf[i]);
86 
87 		I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_CONT);
88 
89 		k_sem_take(&data->complete, K_FOREVER);
90 
91 		if (data->error != I2C_MASTER_ERR_NONE) {
92 			goto send_error_stop;
93 		}
94 	}
95 
96 	I2CMasterDataPut(base, buf[len - 1]);
97 
98 	I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_FINISH);
99 
100 	k_sem_take(&data->complete, K_FOREVER);
101 
102 	if (data->error != I2C_MASTER_ERR_NONE) {
103 		return -EIO;
104 	}
105 
106 	return 0;
107 
108 send_error_stop:
109 	I2CMasterControl(base, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
110 	return -EIO;
111 }
112 
i2c_cc13xx_cc26xx_receive(const struct device * dev,uint8_t * buf,uint32_t len,uint16_t addr)113 static int i2c_cc13xx_cc26xx_receive(const struct device *dev, uint8_t *buf,
114 				     uint32_t len,
115 				     uint16_t addr)
116 {
117 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
118 	const uint32_t base = config->base;
119 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
120 
121 	/* Sending address without data is not supported */
122 	if (len == 0) {
123 		return -EIO;
124 	}
125 
126 	I2CMasterSlaveAddrSet(base, addr, true);
127 
128 	/* The following assumes a single master. Use I2CMasterBusBusy() if
129 	 * wanting to implement multiple master support.
130 	 */
131 
132 	/* Single receive */
133 	if (len == 1) {
134 		I2CMasterControl(base, I2C_MASTER_CMD_SINGLE_RECEIVE);
135 
136 		k_sem_take(&data->complete, K_FOREVER);
137 
138 		if (data->error != I2C_MASTER_ERR_NONE) {
139 			return -EIO;
140 		}
141 
142 		*buf = I2CMasterDataGet(base);
143 
144 		return 0;
145 	}
146 
147 	/* Burst receive */
148 	I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_START);
149 
150 	k_sem_take(&data->complete, K_FOREVER);
151 
152 	if (data->error != I2C_MASTER_ERR_NONE) {
153 		goto recv_error_stop;
154 	}
155 
156 	buf[0] = I2CMasterDataGet(base);
157 
158 	for (int i = 1; i < len - 1; i++) {
159 		I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
160 
161 		k_sem_take(&data->complete, K_FOREVER);
162 
163 		if (data->error != I2C_MASTER_ERR_NONE) {
164 			goto recv_error_stop;
165 		}
166 
167 		buf[i] = I2CMasterDataGet(base);
168 	}
169 
170 	I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
171 
172 	k_sem_take(&data->complete, K_FOREVER);
173 
174 	if (data->error != I2C_MASTER_ERR_NONE) {
175 		return -EIO;
176 	}
177 
178 	buf[len - 1] = I2CMasterDataGet(base);
179 
180 	return 0;
181 
182 recv_error_stop:
183 	I2CMasterControl(base, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
184 	return -EIO;
185 }
186 
i2c_cc13xx_cc26xx_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)187 static int i2c_cc13xx_cc26xx_transfer(const struct device *dev,
188 				      struct i2c_msg *msgs,
189 				      uint8_t num_msgs, uint16_t addr)
190 {
191 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
192 	int ret = 0;
193 
194 	if (num_msgs == 0) {
195 		return 0;
196 	}
197 
198 	k_sem_take(&data->lock, K_FOREVER);
199 
200 	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
201 
202 	for (int i = 0; i < num_msgs; i++) {
203 		/* Not supported by hardware */
204 		if (msgs[i].flags & I2C_MSG_ADDR_10_BITS) {
205 			ret = -EIO;
206 			break;
207 		}
208 
209 		if ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
210 			ret = i2c_cc13xx_cc26xx_transmit(dev, msgs[i].buf,
211 							 msgs[i].len, addr);
212 		} else {
213 			ret = i2c_cc13xx_cc26xx_receive(dev, msgs[i].buf,
214 							msgs[i].len, addr);
215 		}
216 
217 		if (ret) {
218 			break;
219 		}
220 	}
221 
222 	pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
223 
224 	k_sem_give(&data->lock);
225 
226 	return ret;
227 }
228 
229 #define CPU_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
i2c_cc13xx_cc26xx_configure(const struct device * dev,uint32_t dev_config)230 static int i2c_cc13xx_cc26xx_configure(const struct device *dev,
231 				       uint32_t dev_config)
232 {
233 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
234 	bool fast;
235 
236 	switch (I2C_SPEED_GET(dev_config)) {
237 	case I2C_SPEED_STANDARD:
238 		fast = false;
239 		break;
240 	case I2C_SPEED_FAST:
241 		fast = true;
242 		break;
243 	default:
244 		LOG_ERR("Unsupported speed");
245 		return -EIO;
246 	}
247 
248 	/* Support for slave mode has not been implemented */
249 	if (!(dev_config & I2C_MODE_CONTROLLER)) {
250 		LOG_ERR("Slave mode is not supported");
251 		return -EIO;
252 	}
253 
254 	/* This is deprecated and could be ignored in the future */
255 	if (dev_config & I2C_ADDR_10_BITS) {
256 		LOG_ERR("10-bit addressing mode is not supported");
257 		return -EIO;
258 	}
259 
260 	/* Enables and configures I2C master */
261 	I2CMasterInitExpClk(config->base, CPU_FREQ, fast);
262 
263 #ifdef CONFIG_PM
264 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
265 
266 	data->dev_config = dev_config;
267 #endif
268 
269 	return 0;
270 }
271 
i2c_cc13xx_cc26xx_isr(const struct device * dev)272 static void i2c_cc13xx_cc26xx_isr(const struct device *dev)
273 {
274 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
275 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
276 	const uint32_t base = config->base;
277 
278 	if (I2CMasterIntStatus(base, true)) {
279 		I2CMasterIntClear(base);
280 
281 		data->error = I2CMasterErr(base);
282 
283 		k_sem_give(&data->complete);
284 	}
285 }
286 
287 #ifdef CONFIG_PM
288 /*
289  *  ======== postNotifyFxn ========
290  *  Called by Power module when waking up the CPU from Standby. The i2c needs
291  *  to be reconfigured afterwards, unless Zephyr's device PM turned it off, in
292  *  which case it'd be responsible for turning it back on and reconfigure it.
293  */
postNotifyFxn(unsigned int eventType,uintptr_t eventArg,uintptr_t clientArg)294 static int postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
295 	uintptr_t clientArg)
296 {
297 	const struct device *dev = (const struct device *)clientArg;
298 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
299 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
300 	int ret = Power_NOTIFYDONE;
301 	int16_t res_id;
302 
303 	/* Reconfigure the hardware if returning from sleep */
304 	if (eventType == PowerCC26XX_AWAKE_STANDBY) {
305 		res_id = PowerCC26XX_PERIPH_I2C0;
306 
307 		if (Power_getDependencyCount(res_id) != 0) {
308 			/* Reconfigure and enable I2C only if powered */
309 			if (i2c_cc13xx_cc26xx_configure(dev,
310 				data->dev_config) != 0) {
311 				ret = Power_NOTIFYERROR;
312 			}
313 
314 			I2CMasterIntEnable(config->base);
315 		}
316 	}
317 
318 	return (ret);
319 }
320 #endif
321 
322 #ifdef CONFIG_PM_DEVICE
i2c_cc13xx_cc26xx_pm_action(const struct device * dev,enum pm_device_action action)323 static int i2c_cc13xx_cc26xx_pm_action(const struct device *dev,
324 				       enum pm_device_action action)
325 {
326 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
327 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
328 	int ret = 0;
329 
330 	switch (action) {
331 	case PM_DEVICE_ACTION_RESUME:
332 		Power_setDependency(PowerCC26XX_PERIPH_I2C0);
333 		ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
334 		if (ret < 0) {
335 			return ret;
336 		}
337 		ret = i2c_cc13xx_cc26xx_configure(dev, data->dev_config);
338 		if (ret == 0) {
339 			I2CMasterIntEnable(config->base);
340 		}
341 		break;
342 	case PM_DEVICE_ACTION_SUSPEND:
343 		I2CMasterIntDisable(config->base);
344 		I2CMasterDisable(config->base);
345 		/* Reset pin type to default GPIO configuration */
346 		ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
347 		if (ret < 0) {
348 			return ret;
349 		}
350 		Power_releaseDependency(PowerCC26XX_PERIPH_I2C0);
351 		break;
352 	default:
353 		return -ENOTSUP;
354 	}
355 
356 	return ret;
357 }
358 #endif /* CONFIG_PM_DEVICE */
359 
i2c_cc13xx_cc26xx_init(const struct device * dev)360 static int i2c_cc13xx_cc26xx_init(const struct device *dev)
361 {
362 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
363 	uint32_t cfg;
364 	int err;
365 
366 #ifdef CONFIG_PM
367 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
368 
369 	/* Set Power dependencies & constraints */
370 	Power_setDependency(PowerCC26XX_PERIPH_I2C0);
371 
372 	/* Register notification function */
373 	Power_registerNotify(&data->postNotify,
374 		PowerCC26XX_AWAKE_STANDBY,
375 		postNotifyFxn, (uintptr_t)dev);
376 #else
377 	/* Enable I2C power domain */
378 	PRCMPowerDomainOn(PRCM_DOMAIN_SERIAL);
379 
380 	/* Enable I2C peripheral clock */
381 	PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0);
382 	/* Enable in sleep mode until proper power management is added */
383 	PRCMPeripheralSleepEnable(PRCM_PERIPH_I2C0);
384 	PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_I2C0);
385 
386 	/* Load PRCM settings */
387 	PRCMLoadSet();
388 	while (!PRCMLoadGet()) {
389 		continue;
390 	}
391 
392 	/* I2C should not be accessed until power domain is on. */
393 	while (PRCMPowerDomainsAllOn(PRCM_DOMAIN_SERIAL) !=
394 	       PRCM_DOMAIN_POWER_ON) {
395 		continue;
396 	}
397 #endif
398 
399 	IRQ_CONNECT(DT_INST_IRQN(0),
400 		    DT_INST_IRQ(0, priority),
401 		    i2c_cc13xx_cc26xx_isr, DEVICE_DT_INST_GET(0), 0);
402 	irq_enable(DT_INST_IRQN(0));
403 
404 	err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
405 	if (err < 0) {
406 		LOG_ERR("Failed to configure pinctrl state");
407 		return err;
408 	}
409 
410 	cfg = i2c_map_dt_bitrate(DT_INST_PROP(0, clock_frequency));
411 	err = i2c_cc13xx_cc26xx_configure(dev, cfg | I2C_MODE_CONTROLLER);
412 	if (err) {
413 		LOG_ERR("Failed to configure");
414 		return err;
415 	}
416 
417 	I2CMasterIntEnable(config->base);
418 
419 	return 0;
420 }
421 
422 static DEVICE_API(i2c, i2c_cc13xx_cc26xx_driver_api) = {
423 	.configure = i2c_cc13xx_cc26xx_configure,
424 	.transfer = i2c_cc13xx_cc26xx_transfer,
425 #ifdef CONFIG_I2C_RTIO
426 	.iodev_submit = i2c_iodev_submit_fallback,
427 #endif
428 };
429 
430 PINCTRL_DT_INST_DEFINE(0);
431 
432 static const struct i2c_cc13xx_cc26xx_config i2c_cc13xx_cc26xx_config = {
433 	.base = DT_INST_REG_ADDR(0),
434 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
435 };
436 
437 static struct i2c_cc13xx_cc26xx_data i2c_cc13xx_cc26xx_data = {
438 	.lock = Z_SEM_INITIALIZER(i2c_cc13xx_cc26xx_data.lock, 1, 1),
439 	.complete = Z_SEM_INITIALIZER(i2c_cc13xx_cc26xx_data.complete, 0, 1),
440 	.error = I2C_MASTER_ERR_NONE
441 };
442 
443 PM_DEVICE_DT_INST_DEFINE(0, i2c_cc13xx_cc26xx_pm_action);
444 
445 I2C_DEVICE_DT_INST_DEFINE(0,
446 		i2c_cc13xx_cc26xx_init,
447 		PM_DEVICE_DT_INST_GET(0),
448 		&i2c_cc13xx_cc26xx_data, &i2c_cc13xx_cc26xx_config,
449 		POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,
450 		&i2c_cc13xx_cc26xx_driver_api);
451