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 struct i2c_msg * msg,const uint8_t addr)43 static int i2c_cc13xx_cc26xx_transmit(const struct device *dev, const struct i2c_msg *msg,
44 				      const uint8_t addr)
45 {
46 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
47 	const uint32_t base = config->base;
48 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
49 
50 	I2CMasterSlaveAddrSet(base, addr, false);
51 
52 	for (int i = 0; i < msg->len; i++) {
53 		uint32_t command = I2C_MCTRL_RUN;
54 
55 		if (i == 0 && msg->flags & I2C_MSG_RESTART) {
56 			command |= I2C_MCTRL_START;
57 		}
58 
59 		if (i == msg->len - 1 && msg->flags & I2C_MSG_STOP) {
60 			command |= I2C_MCTRL_STOP;
61 		}
62 
63 		I2CMasterDataPut(base, msg->buf[i]);
64 		I2CMasterControl(base, command);
65 		k_sem_take(&data->complete, K_FOREVER);
66 
67 		if (data->error != I2C_MASTER_ERR_NONE) {
68 			if ((command & I2C_MCTRL_STOP) == 0) {
69 				I2CMasterControl(base, I2C_MCTRL_STOP);
70 			}
71 			return -EIO;
72 		}
73 	}
74 
75 	return 0;
76 }
77 
i2c_cc13xx_cc26xx_receive(const struct device * dev,const struct i2c_msg * msg,const uint8_t addr)78 static int i2c_cc13xx_cc26xx_receive(const struct device *dev, const struct i2c_msg *msg,
79 				     const uint8_t addr)
80 {
81 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
82 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
83 	const uint32_t base = config->base;
84 
85 	I2CMasterSlaveAddrSet(base, addr, true);
86 
87 	for (int i = 0; i < msg->len; i++) {
88 		uint32_t command = I2C_MCTRL_RUN;
89 
90 		if (i == 0 && msg->flags & I2C_MSG_RESTART) {
91 			command |= I2C_MCTRL_START;
92 		}
93 
94 		if (i == msg->len - 1 && msg->flags & I2C_MSG_STOP) {
95 			command |= I2C_MCTRL_STOP;
96 		} else if (i < msg->len - 1) {
97 			command |= I2C_MCTRL_ACK;
98 		}
99 
100 		I2CMasterControl(base, command);
101 
102 		k_sem_take(&data->complete, K_FOREVER);
103 
104 		if (data->error != I2C_MASTER_ERR_NONE) {
105 			if ((command & I2C_MCTRL_STOP) == 0) {
106 				I2CMasterControl(base, I2C_MCTRL_STOP);
107 			}
108 			return -EIO;
109 		}
110 
111 		msg->buf[i] = I2CMasterDataGet(base);
112 	}
113 
114 	return 0;
115 }
116 
i2c_cc13xx_cc26xx_transfer(const struct device * dev,struct i2c_msg * msgs,const uint8_t num_msgs,const uint16_t addr)117 static int i2c_cc13xx_cc26xx_transfer(const struct device *dev, struct i2c_msg *msgs,
118 				      const uint8_t num_msgs, const uint16_t addr)
119 {
120 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
121 	int ret = 0;
122 
123 	if (num_msgs == 0) {
124 		return 0;
125 	}
126 
127 	/* Always a start condition in the first message */
128 	msgs[0].flags |= I2C_MSG_RESTART;
129 
130 	k_sem_take(&data->lock, K_FOREVER);
131 
132 	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
133 
134 	for (int i = 0; i < num_msgs; i++) {
135 		/* Not supported by hardware */
136 		if (msgs[i].flags & I2C_MSG_ADDR_10_BITS) {
137 			ret = -EIO;
138 			break;
139 		}
140 
141 		/* Sending address without data is not supported */
142 		if (msgs[i].len == 0) {
143 			ret = -EIO;
144 			break;
145 		}
146 
147 		if ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
148 			ret = i2c_cc13xx_cc26xx_transmit(dev, &msgs[i], addr);
149 		} else {
150 			ret = i2c_cc13xx_cc26xx_receive(dev, &msgs[i], addr);
151 		}
152 
153 		if (ret) {
154 			break;
155 		}
156 	}
157 
158 	pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
159 
160 	k_sem_give(&data->lock);
161 
162 	return ret;
163 }
164 
165 #define CPU_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
i2c_cc13xx_cc26xx_configure(const struct device * dev,uint32_t dev_config)166 static int i2c_cc13xx_cc26xx_configure(const struct device *dev,
167 				       uint32_t dev_config)
168 {
169 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
170 	bool fast;
171 
172 	switch (I2C_SPEED_GET(dev_config)) {
173 	case I2C_SPEED_STANDARD:
174 		fast = false;
175 		break;
176 	case I2C_SPEED_FAST:
177 		fast = true;
178 		break;
179 	default:
180 		LOG_ERR("Unsupported speed");
181 		return -EIO;
182 	}
183 
184 	/* Support for slave mode has not been implemented */
185 	if (!(dev_config & I2C_MODE_CONTROLLER)) {
186 		LOG_ERR("Slave mode is not supported");
187 		return -EIO;
188 	}
189 
190 	/* This is deprecated and could be ignored in the future */
191 	if (dev_config & I2C_ADDR_10_BITS) {
192 		LOG_ERR("10-bit addressing mode is not supported");
193 		return -EIO;
194 	}
195 
196 	/* Enables and configures I2C master */
197 	I2CMasterInitExpClk(config->base, CPU_FREQ, fast);
198 
199 #ifdef CONFIG_PM
200 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
201 
202 	data->dev_config = dev_config;
203 #endif
204 
205 	return 0;
206 }
207 
i2c_cc13xx_cc26xx_isr(const struct device * dev)208 static void i2c_cc13xx_cc26xx_isr(const struct device *dev)
209 {
210 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
211 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
212 	const uint32_t base = config->base;
213 
214 	if (I2CMasterIntStatus(base, true)) {
215 		I2CMasterIntClear(base);
216 
217 		data->error = I2CMasterErr(base);
218 
219 		k_sem_give(&data->complete);
220 	}
221 }
222 
223 #ifdef CONFIG_PM
224 /*
225  *  ======== postNotifyFxn ========
226  *  Called by Power module when waking up the CPU from Standby. The i2c needs
227  *  to be reconfigured afterwards, unless Zephyr's device PM turned it off, in
228  *  which case it'd be responsible for turning it back on and reconfigure it.
229  */
postNotifyFxn(unsigned int eventType,uintptr_t eventArg,uintptr_t clientArg)230 static int postNotifyFxn(unsigned int eventType, uintptr_t eventArg,
231 	uintptr_t clientArg)
232 {
233 	const struct device *dev = (const struct device *)clientArg;
234 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
235 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
236 	int ret = Power_NOTIFYDONE;
237 	int16_t res_id;
238 
239 	/* Reconfigure the hardware if returning from sleep */
240 	if (eventType == PowerCC26XX_AWAKE_STANDBY) {
241 		res_id = PowerCC26XX_PERIPH_I2C0;
242 
243 		if (Power_getDependencyCount(res_id) != 0) {
244 			/* Reconfigure and enable I2C only if powered */
245 			if (i2c_cc13xx_cc26xx_configure(dev,
246 				data->dev_config) != 0) {
247 				ret = Power_NOTIFYERROR;
248 			}
249 
250 			I2CMasterIntEnable(config->base);
251 		}
252 	}
253 
254 	return (ret);
255 }
256 #endif
257 
258 #ifdef CONFIG_PM_DEVICE
i2c_cc13xx_cc26xx_pm_action(const struct device * dev,enum pm_device_action action)259 static int i2c_cc13xx_cc26xx_pm_action(const struct device *dev,
260 				       enum pm_device_action action)
261 {
262 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
263 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
264 	int ret = 0;
265 
266 	switch (action) {
267 	case PM_DEVICE_ACTION_RESUME:
268 		Power_setDependency(PowerCC26XX_PERIPH_I2C0);
269 		ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
270 		if (ret < 0) {
271 			return ret;
272 		}
273 		ret = i2c_cc13xx_cc26xx_configure(dev, data->dev_config);
274 		if (ret == 0) {
275 			I2CMasterIntEnable(config->base);
276 		}
277 		break;
278 	case PM_DEVICE_ACTION_SUSPEND:
279 		I2CMasterIntDisable(config->base);
280 		I2CMasterDisable(config->base);
281 		/* Reset pin type to default GPIO configuration */
282 		ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
283 		if (ret < 0) {
284 			return ret;
285 		}
286 		Power_releaseDependency(PowerCC26XX_PERIPH_I2C0);
287 		break;
288 	default:
289 		return -ENOTSUP;
290 	}
291 
292 	return ret;
293 }
294 #endif /* CONFIG_PM_DEVICE */
295 
i2c_cc13xx_cc26xx_init(const struct device * dev)296 static int i2c_cc13xx_cc26xx_init(const struct device *dev)
297 {
298 	const struct i2c_cc13xx_cc26xx_config *config = dev->config;
299 	uint32_t cfg;
300 	int err;
301 
302 #ifdef CONFIG_PM
303 	struct i2c_cc13xx_cc26xx_data *data = dev->data;
304 
305 	/* Set Power dependencies & constraints */
306 	Power_setDependency(PowerCC26XX_PERIPH_I2C0);
307 
308 	/* Register notification function */
309 	Power_registerNotify(&data->postNotify,
310 		PowerCC26XX_AWAKE_STANDBY,
311 		postNotifyFxn, (uintptr_t)dev);
312 #else
313 	/* Enable I2C power domain */
314 	PRCMPowerDomainOn(PRCM_DOMAIN_SERIAL);
315 
316 	/* Enable I2C peripheral clock */
317 	PRCMPeripheralRunEnable(PRCM_PERIPH_I2C0);
318 	/* Enable in sleep mode until proper power management is added */
319 	PRCMPeripheralSleepEnable(PRCM_PERIPH_I2C0);
320 	PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_I2C0);
321 
322 	/* Load PRCM settings */
323 	PRCMLoadSet();
324 	while (!PRCMLoadGet()) {
325 		continue;
326 	}
327 
328 	/* I2C should not be accessed until power domain is on. */
329 	while (PRCMPowerDomainsAllOn(PRCM_DOMAIN_SERIAL) !=
330 	       PRCM_DOMAIN_POWER_ON) {
331 		continue;
332 	}
333 #endif
334 
335 	IRQ_CONNECT(DT_INST_IRQN(0),
336 		    DT_INST_IRQ(0, priority),
337 		    i2c_cc13xx_cc26xx_isr, DEVICE_DT_INST_GET(0), 0);
338 	irq_enable(DT_INST_IRQN(0));
339 
340 	err = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
341 	if (err < 0) {
342 		LOG_ERR("Failed to configure pinctrl state");
343 		return err;
344 	}
345 
346 	cfg = i2c_map_dt_bitrate(DT_INST_PROP(0, clock_frequency));
347 	err = i2c_cc13xx_cc26xx_configure(dev, cfg | I2C_MODE_CONTROLLER);
348 	if (err) {
349 		LOG_ERR("Failed to configure");
350 		return err;
351 	}
352 
353 	I2CMasterIntEnable(config->base);
354 
355 	return 0;
356 }
357 
358 static DEVICE_API(i2c, i2c_cc13xx_cc26xx_driver_api) = {
359 	.configure = i2c_cc13xx_cc26xx_configure,
360 	.transfer = i2c_cc13xx_cc26xx_transfer,
361 #ifdef CONFIG_I2C_RTIO
362 	.iodev_submit = i2c_iodev_submit_fallback,
363 #endif
364 };
365 
366 PINCTRL_DT_INST_DEFINE(0);
367 
368 static const struct i2c_cc13xx_cc26xx_config i2c_cc13xx_cc26xx_config = {
369 	.base = DT_INST_REG_ADDR(0),
370 	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
371 };
372 
373 static struct i2c_cc13xx_cc26xx_data i2c_cc13xx_cc26xx_data = {
374 	.lock = Z_SEM_INITIALIZER(i2c_cc13xx_cc26xx_data.lock, 1, 1),
375 	.complete = Z_SEM_INITIALIZER(i2c_cc13xx_cc26xx_data.complete, 0, 1),
376 	.error = I2C_MASTER_ERR_NONE
377 };
378 
379 PM_DEVICE_DT_INST_DEFINE(0, i2c_cc13xx_cc26xx_pm_action);
380 
381 I2C_DEVICE_DT_INST_DEFINE(0,
382 		i2c_cc13xx_cc26xx_init,
383 		PM_DEVICE_DT_INST_GET(0),
384 		&i2c_cc13xx_cc26xx_data, &i2c_cc13xx_cc26xx_config,
385 		POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,
386 		&i2c_cc13xx_cc26xx_driver_api);
387