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