1 /*
2  * Copyright (c) 2022 Intel Corporation
3  *
4  * Intel I/O Controller Hub (ICH) later renamed to Intel Platform Controller
5  * Hub (PCH) SMBus driver.
6  *
7  * PCH provides SMBus 2.0 - compliant Host Controller.
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 #include <zephyr/types.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/device.h>
15 
16 #include <zephyr/drivers/smbus.h>
17 #include <zephyr/drivers/pcie/pcie.h>
18 
19 #define DT_DRV_COMPAT intel_pch_smbus
20 
21 #include <zephyr/logging/log.h>
22 LOG_MODULE_REGISTER(intel_pch, CONFIG_SMBUS_LOG_LEVEL);
23 
24 #include "smbus_utils.h"
25 #include "intel_pch_smbus.h"
26 
27 /**
28  * @note Following notions are used:
29  *  * periph_addr - Peripheral address (Slave address mentioned in the Specs)
30  *  * command - First byte to send in the SMBus protocol operations except for
31  *              Quick and Byte Read. Also known as register.
32  */
33 
34 /**
35  * Intel PCH configuration acquired from DTS during device initialization
36  */
37 struct pch_config {
38 	/* IRQ configuration function */
39 	void (*config_func)(const struct device *dev);
40 	struct pcie_dev *pcie;
41 };
42 
43 /**
44  * Intel PCH internal driver data
45  */
46 struct pch_data {
47 	DEVICE_MMIO_RAM;
48 	io_port_t sba;
49 	uint32_t config;
50 	uint8_t status;
51 
52 	struct k_mutex mutex;
53 	struct k_sem completion_sync;
54 	const struct device *dev;
55 
56 #if defined(CONFIG_SMBUS_INTEL_PCH_SMBALERT)
57 	/* smbalert callback list */
58 	sys_slist_t smbalert_cbs;
59 	/* smbalert work */
60 	struct k_work smb_alert_work;
61 #endif /* CONFIG_SMBUS_INTEL_PCH_SMBALERT */
62 
63 #if defined(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)
64 	/* Host Notify callback list */
65 	sys_slist_t host_notify_cbs;
66 	/* Host Notify work */
67 	struct k_work host_notify_work;
68 	/* Host Notify peripheral device address */
69 	uint8_t notify_addr;
70 	/* Host Notify data received */
71 	uint16_t notify_data;
72 #endif /* CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY */
73 };
74 
75 /**
76  * Helpers for accessing Intel PCH SMBus registers. Depending on
77  * configuration option MMIO or IO method will be used.
78  */
79 #if defined(CONFIG_SMBUS_INTEL_PCH_ACCESS_MMIO)
pch_reg_read(const struct device * dev,uint8_t reg)80 static uint8_t pch_reg_read(const struct device *dev, uint8_t reg)
81 {
82 	return sys_read8(DEVICE_MMIO_GET(dev) + reg);
83 }
84 
pch_reg_write(const struct device * dev,uint8_t reg,uint8_t val)85 static void pch_reg_write(const struct device *dev, uint8_t reg, uint8_t val)
86 {
87 	sys_write8(val, DEVICE_MMIO_GET(dev) + reg);
88 }
89 #elif defined(CONFIG_SMBUS_INTEL_PCH_ACCESS_IO)
pch_reg_read(const struct device * dev,uint8_t reg)90 static uint8_t pch_reg_read(const struct device *dev, uint8_t reg)
91 {
92 	struct pch_data *data = dev->data;
93 
94 	return sys_in8(data->sba + reg);
95 }
96 
pch_reg_write(const struct device * dev,uint8_t reg,uint8_t val)97 static void pch_reg_write(const struct device *dev, uint8_t reg, uint8_t val)
98 {
99 	struct pch_data *data = dev->data;
100 
101 	sys_out8(val, data->sba + reg);
102 }
103 #else
104 #error Wrong PCH Register Access Mode
105 #endif
106 
107 #if defined(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)
host_notify_work(struct k_work * work)108 static void host_notify_work(struct k_work *work)
109 {
110 	struct pch_data *data = CONTAINER_OF(work, struct pch_data,
111 					     host_notify_work);
112 	const struct device *dev = data->dev;
113 	uint8_t addr = data->notify_addr;
114 
115 	smbus_fire_callbacks(&data->host_notify_cbs, dev, addr);
116 }
117 
pch_smbus_host_notify_set_cb(const struct device * dev,struct smbus_callback * cb)118 static int pch_smbus_host_notify_set_cb(const struct device *dev,
119 					struct smbus_callback *cb)
120 {
121 	struct pch_data *data = dev->data;
122 
123 	LOG_DBG("dev %p cb %p", dev, cb);
124 
125 	return smbus_callback_set(&data->host_notify_cbs, cb);
126 }
127 
pch_smbus_host_notify_remove_cb(const struct device * dev,struct smbus_callback * cb)128 static int pch_smbus_host_notify_remove_cb(const struct device *dev,
129 					   struct smbus_callback *cb)
130 {
131 	struct pch_data *data = dev->data;
132 
133 	LOG_DBG("dev %p cb %p", dev, cb);
134 
135 	return smbus_callback_remove(&data->host_notify_cbs, cb);
136 }
137 #endif /* CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY */
138 
139 #if defined(CONFIG_SMBUS_INTEL_PCH_SMBALERT)
smbalert_work(struct k_work * work)140 static void smbalert_work(struct k_work *work)
141 {
142 	struct pch_data *data = CONTAINER_OF(work, struct pch_data,
143 					     smb_alert_work);
144 	const struct device *dev = data->dev;
145 
146 	/**
147 	 * There might be several peripheral devices and the he highest
148 	 * priority (lowest address) device wins arbitration, we need to
149 	 * read them all.
150 	 *
151 	 * The format of the transaction is:
152 	 *
153 	 *  0                   1                   2
154 	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
155 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156 	 *  |S|  Alert Addr |R|A|   Address   |X|N|P|
157 	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158 	 */
159 	do {
160 		uint8_t addr;
161 		int ret;
162 
163 		ret = smbus_byte_read(dev, SMBUS_ADDRESS_ARA, &addr);
164 		if (ret < 0) {
165 			LOG_DBG("Cannot read peripheral address (anymore)");
166 			return;
167 		}
168 
169 		LOG_DBG("Read addr 0x%02x, ret %d", addr, ret);
170 
171 		smbus_fire_callbacks(&data->smbalert_cbs, dev, addr);
172 	} while (true);
173 }
174 
pch_smbus_smbalert_set_sb(const struct device * dev,struct smbus_callback * cb)175 static int pch_smbus_smbalert_set_sb(const struct device *dev,
176 				     struct smbus_callback *cb)
177 {
178 	struct pch_data *data = dev->data;
179 
180 	LOG_DBG("dev %p cb %p", dev, cb);
181 
182 	return smbus_callback_set(&data->smbalert_cbs, cb);
183 }
184 
pch_smbus_smbalert_remove_sb(const struct device * dev,struct smbus_callback * cb)185 static int pch_smbus_smbalert_remove_sb(const struct device *dev,
186 					struct smbus_callback *cb)
187 {
188 	struct pch_data *data = dev->data;
189 
190 	LOG_DBG("dev %p cb %p", dev, cb);
191 
192 	return smbus_callback_remove(&data->smbalert_cbs, cb);
193 }
194 #endif /* CONFIG_SMBUS_INTEL_PCH_SMBALERT */
195 
pch_configure(const struct device * dev,uint32_t config)196 static int pch_configure(const struct device *dev, uint32_t config)
197 {
198 	struct pch_data *data = dev->data;
199 
200 	LOG_DBG("dev %p config 0x%x", dev, config);
201 
202 	if (config & SMBUS_MODE_HOST_NOTIFY) {
203 		uint8_t status;
204 
205 		if (!IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)) {
206 			LOG_ERR("Error configuring Host Notify");
207 			return -EINVAL;
208 		}
209 
210 		/* Enable Host Notify interrupts */
211 		status = pch_reg_read(dev, PCH_SMBUS_SCMD);
212 		status |= PCH_SMBUS_SCMD_HNI_EN;
213 		pch_reg_write(dev, PCH_SMBUS_SCMD, status);
214 	}
215 
216 	if (config & SMBUS_MODE_SMBALERT) {
217 		uint8_t status;
218 
219 		if (!IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_SMBALERT)) {
220 			LOG_ERR("Error configuring SMBALERT");
221 			return -EINVAL;
222 		}
223 
224 		/* Disable SMBALERT_DIS */
225 		status = pch_reg_read(dev, PCH_SMBUS_SCMD);
226 		status &= ~PCH_SMBUS_SCMD_SMBALERT_DIS;
227 		pch_reg_write(dev, PCH_SMBUS_SCMD, status);
228 	}
229 
230 	/* Keep config for a moment */
231 	data->config = config;
232 
233 	return 0;
234 }
235 
pch_get_config(const struct device * dev,uint32_t * config)236 static int pch_get_config(const struct device *dev, uint32_t *config)
237 {
238 	struct pch_data *data = dev->data;
239 
240 	*config = data->config;
241 
242 	return 0;
243 }
244 
245 /* Device initialization function */
pch_smbus_init(const struct device * dev)246 static int pch_smbus_init(const struct device *dev)
247 {
248 	const struct pch_config * const config = dev->config;
249 	struct pch_data *data = dev->data;
250 	struct pcie_bar mbar;
251 	uint32_t val;
252 
253 	if (config->pcie->bdf == PCIE_BDF_NONE) {
254 		LOG_ERR("Cannot probe PCI device");
255 		return -ENODEV;
256 	}
257 
258 	val = pcie_conf_read(config->pcie->bdf, PCIE_CONF_CMDSTAT);
259 	if (val & PCIE_CONF_CMDSTAT_INTERRUPT) {
260 		LOG_WRN("Pending interrupt, continuing");
261 	}
262 
263 	if (IS_ENABLED(CONFIG_SMBUS_INTEL_PCH_ACCESS_MMIO)) {
264 		pcie_probe_mbar(config->pcie->bdf, 0, &mbar);
265 		pcie_set_cmd(config->pcie->bdf, PCIE_CONF_CMDSTAT_MEM, true);
266 
267 		device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size,
268 			   K_MEM_CACHE_NONE);
269 
270 		LOG_DBG("Mapped 0x%lx size 0x%lx to 0x%lx",
271 			mbar.phys_addr, mbar.size, DEVICE_MMIO_GET(dev));
272 	} else {
273 		pcie_set_cmd(config->pcie->bdf, PCIE_CONF_CMDSTAT_IO, true);
274 		val = pcie_conf_read(config->pcie->bdf, PCIE_CONF_BAR4);
275 		if (!PCIE_CONF_BAR_IO(val)) {
276 			LOG_ERR("Cannot read IO BAR");
277 			return -EINVAL;
278 		}
279 
280 		data->sba = PCIE_CONF_BAR_ADDR(val);
281 
282 		LOG_DBG("Using I/O address 0x%x", data->sba);
283 	}
284 
285 	val = pcie_conf_read(config->pcie->bdf, PCH_SMBUS_HCFG);
286 	if ((val & PCH_SMBUS_HCFG_HST_EN) == 0) {
287 		LOG_ERR("SMBus Host Controller is disabled");
288 		return -EINVAL;
289 	}
290 
291 	/* Initialize mutex and semaphore */
292 	k_mutex_init(&data->mutex);
293 	k_sem_init(&data->completion_sync, 0, 1);
294 
295 	data->dev = dev;
296 
297 	/* Initialize work structures */
298 
299 #if defined(CONFIG_SMBUS_INTEL_PCH_SMBALERT)
300 	k_work_init(&data->smb_alert_work, smbalert_work);
301 #endif /* CONFIG_SMBUS_INTEL_PCH_SMBALERT */
302 
303 #if defined(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)
304 	k_work_init(&data->host_notify_work, host_notify_work);
305 #endif /* CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY */
306 
307 	config->config_func(dev);
308 
309 	if (pch_configure(dev, SMBUS_MODE_CONTROLLER)) {
310 		LOG_ERR("SMBus: Cannot set default configuration");
311 		return -EIO;
312 	}
313 
314 	return 0;
315 }
316 
pch_prepare_transfer(const struct device * dev)317 static int pch_prepare_transfer(const struct device *dev)
318 {
319 	uint8_t hsts;
320 
321 	hsts = pch_reg_read(dev, PCH_SMBUS_HSTS);
322 
323 	pch_dump_register_hsts(hsts);
324 
325 	if (hsts & PCH_SMBUS_HSTS_HOST_BUSY) {
326 		LOG_ERR("Return BUSY status");
327 		return -EBUSY;
328 	}
329 
330 	/* Check and clear HSTS status bits */
331 	hsts &= PCH_SMBUS_HSTS_ERROR | PCH_SMBUS_HSTS_BYTE_DONE |
332 		PCH_SMBUS_HSTS_INTERRUPT;
333 	if (hsts) {
334 		pch_reg_write(dev, PCH_SMBUS_HSTS, hsts);
335 	}
336 
337 	/* TODO: Clear also CRC check bits */
338 
339 	return 0;
340 }
341 
pch_check_status(const struct device * dev)342 static int pch_check_status(const struct device *dev)
343 {
344 	struct pch_data *data = dev->data;
345 	uint8_t status = data->status;
346 
347 	/**
348 	 * Device Error means following:
349 	 * - unsupported Command Field Unclaimed Cycle
350 	 * - Host Device timeout
351 	 * - CRC Error
352 	 */
353 	if (status & PCH_SMBUS_HSTS_DEV_ERROR) {
354 		uint8_t auxs = pch_reg_read(dev, PCH_SMBUS_AUXS);
355 
356 		LOG_WRN("Device Error (DERR) received");
357 
358 		if (auxs & PCH_SMBUS_AUXS_CRC_ERROR) {
359 			LOG_DBG("AUXS register 0x%02x", auxs);
360 			/* Clear CRC error status bit */
361 			pch_reg_write(dev, PCH_SMBUS_AUXS,
362 				      PCH_SMBUS_AUXS_CRC_ERROR);
363 		}
364 
365 		return -EIO;
366 	}
367 
368 	/**
369 	 * Transaction collision, several masters are trying to access
370 	 * the bus and PCH detects arbitration lost.
371 	 */
372 	if (status & PCH_SMBUS_HSTS_BUS_ERROR) {
373 		LOG_WRN("Bus Error (BERR) received");
374 
375 		return -EAGAIN;
376 	}
377 
378 	/**
379 	 * Source of interrupt is failed bus transaction. This is set in
380 	 * response to KILL set to terminate the host transaction
381 	 */
382 	if (status & PCH_SMBUS_HSTS_FAILED) {
383 		LOG_WRN("Failed (FAIL) received");
384 
385 		return -EIO;
386 	}
387 
388 	return 0;
389 }
390 
pch_smbus_block_start(const struct device * dev,uint16_t periph_addr,uint8_t rw,uint8_t command,uint8_t count,uint8_t * buf,uint8_t protocol)391 static int pch_smbus_block_start(const struct device *dev, uint16_t periph_addr,
392 				 uint8_t rw, uint8_t command, uint8_t count,
393 				 uint8_t *buf, uint8_t protocol)
394 {
395 	uint8_t reg;
396 	int ret;
397 
398 	LOG_DBG("addr %x rw %d command %x", periph_addr, rw, command);
399 
400 	/* Set TSA register */
401 	reg = PCH_SMBUS_TSA_ADDR_SET(periph_addr);
402 	reg |= rw & SMBUS_MSG_RW_MASK;
403 	pch_reg_write(dev, PCH_SMBUS_TSA, reg);
404 
405 	/* Set HCMD register */
406 	pch_reg_write(dev, PCH_SMBUS_HCMD, command);
407 
408 	/* Enable 32-byte buffer mode (E32b) to send block of data */
409 	reg = pch_reg_read(dev, PCH_SMBUS_AUXC);
410 	reg |= PCH_SMBUS_AUXC_EN_32BUF;
411 	pch_reg_write(dev, PCH_SMBUS_AUXC, reg);
412 
413 	/* In E32B mode read and write to PCH_SMBUS_HBD translates to
414 	 * read and write to 32 byte storage array, index needs to be
415 	 * cleared by reading HCTL
416 	 */
417 	reg = pch_reg_read(dev, PCH_SMBUS_HCTL);
418 	ARG_UNUSED(reg); /* Avoid 'Dead assignment' warning */
419 
420 	if (rw == SMBUS_MSG_WRITE) {
421 		/* Write count */
422 		pch_reg_write(dev, PCH_SMBUS_HD0, count);
423 
424 		/* Write data to send */
425 		for (int i = 0; i < count; i++) {
426 			pch_reg_write(dev, PCH_SMBUS_HBD, buf[i]);
427 		}
428 	}
429 
430 	ret = pch_prepare_transfer(dev);
431 	if (ret < 0) {
432 		return ret;
433 	}
434 
435 	/* Set HCTL register */
436 	reg = PCH_SMBUS_HCTL_CMD_SET(protocol);
437 	reg |= PCH_SMBUS_HCTL_START;
438 	reg |= PCH_SMBUS_HCTL_INTR_EN;
439 	pch_reg_write(dev, PCH_SMBUS_HCTL, reg);
440 
441 	return 0;
442 }
443 
444 /* Start PCH SMBus operation */
pch_smbus_start(const struct device * dev,uint16_t periph_addr,enum smbus_direction rw,uint8_t command,uint8_t * buf,uint8_t protocol)445 static int pch_smbus_start(const struct device *dev, uint16_t periph_addr,
446 			   enum smbus_direction rw, uint8_t command,
447 			   uint8_t *buf, uint8_t protocol)
448 {
449 	uint8_t reg;
450 	int ret;
451 
452 	LOG_DBG("addr 0x%02x rw %d command %x", periph_addr, rw, command);
453 
454 	/* Set TSA register */
455 	reg = PCH_SMBUS_TSA_ADDR_SET(periph_addr);
456 	reg |= rw & SMBUS_MSG_RW_MASK;
457 	pch_reg_write(dev, PCH_SMBUS_TSA, reg);
458 
459 	/* Write command for every but QUICK op */
460 	if (protocol != SMBUS_CMD_QUICK) {
461 		/* Set HCMD register */
462 		pch_reg_write(dev, PCH_SMBUS_HCMD, command);
463 
464 		/* Set Host Data 0 (HD0) register */
465 		if (rw == SMBUS_MSG_WRITE && protocol != SMBUS_CMD_BYTE) {
466 			pch_reg_write(dev, PCH_SMBUS_HD0, buf[0]);
467 
468 			/* If we need to write second byte */
469 			if (protocol == SMBUS_CMD_WORD_DATA ||
470 			    protocol == SMBUS_CMD_PROC_CALL) {
471 				pch_reg_write(dev, PCH_SMBUS_HD1, buf[1]);
472 			}
473 		}
474 	}
475 
476 	ret = pch_prepare_transfer(dev);
477 	if (ret < 0) {
478 		return ret;
479 	}
480 
481 	/* Set HCTL register */
482 	reg = PCH_SMBUS_HCTL_CMD_SET(protocol);
483 	reg |= PCH_SMBUS_HCTL_START;
484 	reg |= PCH_SMBUS_HCTL_INTR_EN;
485 	pch_reg_write(dev, PCH_SMBUS_HCTL, reg);
486 
487 	return 0;
488 }
489 
490 /* Implementation of PCH SMBus API */
491 
492 /* Implementation of SMBus Quick */
pch_smbus_quick(const struct device * dev,uint16_t periph_addr,enum smbus_direction rw)493 static int pch_smbus_quick(const struct device *dev, uint16_t periph_addr,
494 			   enum smbus_direction rw)
495 {
496 	struct pch_data *data = dev->data;
497 	int ret;
498 
499 	LOG_DBG("dev %p addr 0x%02x direction %x", dev, periph_addr, rw);
500 
501 	k_mutex_lock(&data->mutex, K_FOREVER);
502 
503 	ret = pch_smbus_start(dev, periph_addr, rw, 0, NULL, SMBUS_CMD_QUICK);
504 	if (ret < 0) {
505 		goto unlock;
506 	}
507 
508 	/* Wait for completion from ISR */
509 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
510 	if (ret != 0) {
511 		LOG_ERR("SMBus Quick timed out");
512 		ret = -ETIMEDOUT;
513 		goto unlock;
514 	}
515 
516 	ret = pch_check_status(dev);
517 
518 unlock:
519 	k_mutex_unlock(&data->mutex);
520 
521 	return ret;
522 }
523 
524 /* Implementation of SMBus Byte Write */
pch_smbus_byte_write(const struct device * dev,uint16_t periph_addr,uint8_t command)525 static int pch_smbus_byte_write(const struct device *dev, uint16_t periph_addr,
526 				uint8_t command)
527 {
528 	struct pch_data *data = dev->data;
529 	int ret;
530 
531 	LOG_DBG("dev %p addr 0x%02x command 0x%02x", dev, periph_addr, command);
532 
533 	k_mutex_lock(&data->mutex, K_FOREVER);
534 
535 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_WRITE, command, NULL,
536 			      SMBUS_CMD_BYTE);
537 	if (ret < 0) {
538 		goto unlock;
539 	}
540 
541 	/* Wait for completion from ISR */
542 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
543 	if (ret != 0) {
544 		LOG_ERR("SMBus Byte Write timed out");
545 		ret = -ETIMEDOUT;
546 		goto unlock;
547 	}
548 
549 	ret = pch_check_status(dev);
550 
551 unlock:
552 	k_mutex_unlock(&data->mutex);
553 
554 	return ret;
555 }
556 
557 /* Implementation of SMBus Byte Read */
pch_smbus_byte_read(const struct device * dev,uint16_t periph_addr,uint8_t * byte)558 static int pch_smbus_byte_read(const struct device *dev, uint16_t periph_addr,
559 			       uint8_t *byte)
560 {
561 	struct pch_data *data = dev->data;
562 	int ret;
563 
564 	LOG_DBG("dev %p addr 0x%02x", dev, periph_addr);
565 
566 	k_mutex_lock(&data->mutex, K_FOREVER);
567 
568 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_READ, 0, NULL,
569 			      SMBUS_CMD_BYTE);
570 	if (ret < 0) {
571 		goto unlock;
572 	}
573 
574 	/* Wait for completion from ISR */
575 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
576 	if (ret != 0) {
577 		LOG_ERR("SMBus Byte Read timed out");
578 		ret = -ETIMEDOUT;
579 		goto unlock;
580 	}
581 
582 	ret = pch_check_status(dev);
583 	if (ret < 0) {
584 		goto unlock;
585 	}
586 
587 	*byte = pch_reg_read(dev, PCH_SMBUS_HD0);
588 
589 unlock:
590 	k_mutex_unlock(&data->mutex);
591 
592 	return ret;
593 }
594 
595 /* Implementation of SMBus Byte Data Write */
pch_smbus_byte_data_write(const struct device * dev,uint16_t periph_addr,uint8_t command,uint8_t byte)596 static int pch_smbus_byte_data_write(const struct device *dev,
597 				     uint16_t periph_addr,
598 				     uint8_t command, uint8_t byte)
599 {
600 	struct pch_data *data = dev->data;
601 	int ret;
602 
603 	LOG_DBG("dev %p addr 0x%02x command 0x%02x", dev, periph_addr, command);
604 
605 	k_mutex_lock(&data->mutex, K_FOREVER);
606 
607 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_WRITE, command,
608 			      &byte, SMBUS_CMD_BYTE_DATA);
609 	if (ret < 0) {
610 		goto unlock;
611 	}
612 
613 	/* Wait for completion from ISR */
614 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
615 	if (ret != 0) {
616 		LOG_ERR("SMBus Byte Data Write timed out");
617 		ret = -ETIMEDOUT;
618 		goto unlock;
619 	}
620 
621 	ret = pch_check_status(dev);
622 
623 unlock:
624 	k_mutex_unlock(&data->mutex);
625 
626 	return ret;
627 }
628 
629 /* Implementation of SMBus Byte Data Read */
pch_smbus_byte_data_read(const struct device * dev,uint16_t periph_addr,uint8_t command,uint8_t * byte)630 static int pch_smbus_byte_data_read(const struct device *dev,
631 				    uint16_t periph_addr,
632 				    uint8_t command, uint8_t *byte)
633 {
634 	struct pch_data *data = dev->data;
635 	int ret;
636 
637 	LOG_DBG("dev %p addr 0x%02x command 0x%02x", dev, periph_addr, command);
638 
639 	k_mutex_lock(&data->mutex, K_FOREVER);
640 
641 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_READ, command,
642 			      NULL, SMBUS_CMD_BYTE_DATA);
643 	if (ret < 0) {
644 		goto unlock;
645 	}
646 
647 	/* Wait for completion from ISR */
648 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
649 	if (ret != 0) {
650 		LOG_ERR("SMBus Byte Data Read timed out");
651 		ret = -ETIMEDOUT;
652 		goto unlock;
653 	}
654 
655 	ret = pch_check_status(dev);
656 	if (ret < 0) {
657 		goto unlock;
658 	}
659 
660 	*byte = pch_reg_read(dev, PCH_SMBUS_HD0);
661 
662 unlock:
663 	k_mutex_unlock(&data->mutex);
664 
665 	return ret;
666 }
667 
668 /* Implementation of SMBus Word Data Write */
pch_smbus_word_data_write(const struct device * dev,uint16_t periph_addr,uint8_t command,uint16_t word)669 static int pch_smbus_word_data_write(const struct device *dev,
670 				     uint16_t periph_addr,
671 				     uint8_t command, uint16_t word)
672 {
673 	struct pch_data *data = dev->data;
674 	int ret;
675 
676 	LOG_DBG("dev %p addr 0x%02x command 0x%02x", dev, periph_addr, command);
677 
678 	k_mutex_lock(&data->mutex, K_FOREVER);
679 
680 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_WRITE, command,
681 			      (uint8_t *)&word, SMBUS_CMD_WORD_DATA);
682 	if (ret < 0) {
683 		goto unlock;
684 	}
685 
686 	/* Wait for completion from ISR */
687 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
688 	if (ret != 0) {
689 		LOG_ERR("SMBus Word Data Write timed out");
690 		ret = -ETIMEDOUT;
691 		goto unlock;
692 	}
693 
694 	ret = pch_check_status(dev);
695 
696 unlock:
697 	k_mutex_unlock(&data->mutex);
698 
699 	return ret;
700 }
701 
702 /* Implementation of SMBus Word Data Read */
pch_smbus_word_data_read(const struct device * dev,uint16_t periph_addr,uint8_t command,uint16_t * word)703 static int pch_smbus_word_data_read(const struct device *dev,
704 				    uint16_t periph_addr,
705 				    uint8_t command, uint16_t *word)
706 {
707 	struct pch_data *data = dev->data;
708 	uint8_t *p = (uint8_t *)word;
709 	int ret;
710 
711 	LOG_DBG("dev %p addr 0x%02x command 0x%02x", dev, periph_addr, command);
712 
713 	k_mutex_lock(&data->mutex, K_FOREVER);
714 
715 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_READ, command,
716 			      NULL, SMBUS_CMD_WORD_DATA);
717 	if (ret < 0) {
718 		goto unlock;
719 	}
720 
721 	/* Wait for completion from ISR */
722 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
723 	if (ret != 0) {
724 		LOG_ERR("SMBus Word Data Read timed out");
725 		ret = -ETIMEDOUT;
726 		goto unlock;
727 	}
728 
729 	ret = pch_check_status(dev);
730 	if (ret < 0) {
731 		goto unlock;
732 	}
733 
734 	p[0] = pch_reg_read(dev, PCH_SMBUS_HD0);
735 	p[1] = pch_reg_read(dev, PCH_SMBUS_HD1);
736 
737 unlock:
738 	k_mutex_unlock(&data->mutex);
739 
740 	return ret;
741 }
742 
743 /* Implementation of SMBus Process Call */
pch_smbus_pcall(const struct device * dev,uint16_t periph_addr,uint8_t command,uint16_t send_word,uint16_t * recv_word)744 static int pch_smbus_pcall(const struct device *dev,
745 			   uint16_t periph_addr, uint8_t command,
746 			   uint16_t send_word, uint16_t *recv_word)
747 {
748 	struct pch_data *data = dev->data;
749 	uint8_t *p = (uint8_t *)recv_word;
750 	int ret;
751 
752 	LOG_DBG("dev %p addr 0x%02x command 0x%02x", dev, periph_addr, command);
753 
754 	k_mutex_lock(&data->mutex, K_FOREVER);
755 
756 	ret = pch_smbus_start(dev, periph_addr, SMBUS_MSG_WRITE, command,
757 			      (uint8_t *)&send_word, SMBUS_CMD_PROC_CALL);
758 	if (ret < 0) {
759 		goto unlock;
760 	}
761 
762 	/* Wait for completion from ISR */
763 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
764 	if (ret != 0) {
765 		LOG_ERR("SMBus Proc Call timed out");
766 		ret = -ETIMEDOUT;
767 		goto unlock;
768 	}
769 
770 	ret = pch_check_status(dev);
771 	if (ret < 0) {
772 		goto unlock;
773 	}
774 
775 	p[0] = pch_reg_read(dev, PCH_SMBUS_HD0);
776 	p[1] = pch_reg_read(dev, PCH_SMBUS_HD1);
777 
778 unlock:
779 	k_mutex_unlock(&data->mutex);
780 
781 	return ret;
782 }
783 
784 /* Implementation of SMBus Block Write */
pch_smbus_block_write(const struct device * dev,uint16_t periph_addr,uint8_t command,uint8_t count,uint8_t * buf)785 static int pch_smbus_block_write(const struct device *dev, uint16_t periph_addr,
786 				 uint8_t command, uint8_t count, uint8_t *buf)
787 {
788 	struct pch_data *data = dev->data;
789 	int ret;
790 
791 	LOG_DBG("dev %p addr 0x%02x command 0x%02x count %u",
792 		dev, periph_addr, command, count);
793 
794 	k_mutex_lock(&data->mutex, K_FOREVER);
795 
796 	ret = pch_smbus_block_start(dev, periph_addr, SMBUS_MSG_WRITE, command,
797 				    count, buf, SMBUS_CMD_BLOCK);
798 	if (ret < 0) {
799 		goto unlock;
800 	}
801 
802 	/* Wait for completion from ISR */
803 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
804 	if (ret != 0) {
805 		LOG_ERR("SMBus Block Write timed out");
806 		ret = -ETIMEDOUT;
807 		goto unlock;
808 	}
809 
810 	ret = pch_check_status(dev);
811 
812 unlock:
813 	k_mutex_unlock(&data->mutex);
814 
815 	return ret;
816 }
817 
818 /* Implementation of SMBus Block Read */
pch_smbus_block_read(const struct device * dev,uint16_t periph_addr,uint8_t command,uint8_t * count,uint8_t * buf)819 static int pch_smbus_block_read(const struct device *dev, uint16_t periph_addr,
820 				uint8_t command, uint8_t *count, uint8_t *buf)
821 {
822 	struct pch_data *data = dev->data;
823 	int ret;
824 
825 	LOG_DBG("dev %p addr 0x%02x command 0x%02x",
826 		dev, periph_addr, command);
827 
828 	k_mutex_lock(&data->mutex, K_FOREVER);
829 
830 	ret = pch_smbus_block_start(dev, periph_addr, SMBUS_MSG_READ, command,
831 				    0, buf, SMBUS_CMD_BLOCK);
832 	if (ret < 0) {
833 		goto unlock;
834 	}
835 
836 	/* Wait for completion from ISR */
837 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
838 	if (ret != 0) {
839 		LOG_ERR("SMBus Block Read timed out");
840 		ret = -ETIMEDOUT;
841 		goto unlock;
842 	}
843 
844 	ret = pch_check_status(dev);
845 	if (ret < 0) {
846 		goto unlock;
847 	}
848 
849 	*count = pch_reg_read(dev, PCH_SMBUS_HD0);
850 	if (*count == 0 || *count > SMBUS_BLOCK_BYTES_MAX) {
851 		ret = -ENODATA;
852 		goto unlock;
853 	}
854 
855 	for (int i = 0; i < *count; i++) {
856 		buf[i] = pch_reg_read(dev, PCH_SMBUS_HBD);
857 	}
858 
859 unlock:
860 	k_mutex_unlock(&data->mutex);
861 
862 	return ret;
863 }
864 
865 /* Implementation of SMBus Block Process Call */
pch_smbus_block_pcall(const struct device * dev,uint16_t periph_addr,uint8_t command,uint8_t send_count,uint8_t * send_buf,uint8_t * recv_count,uint8_t * recv_buf)866 static int pch_smbus_block_pcall(const struct device *dev,
867 				 uint16_t periph_addr, uint8_t command,
868 				 uint8_t send_count, uint8_t *send_buf,
869 				 uint8_t *recv_count, uint8_t *recv_buf)
870 {
871 	struct pch_data *data = dev->data;
872 	int ret;
873 
874 	LOG_DBG("dev %p addr 0x%02x command 0x%02x",
875 		dev, periph_addr, command);
876 
877 	k_mutex_lock(&data->mutex, K_FOREVER);
878 
879 	ret = pch_smbus_block_start(dev, periph_addr, SMBUS_MSG_WRITE, command,
880 				    send_count, send_buf, SMBUS_CMD_BLOCK_PROC);
881 	if (ret < 0) {
882 		goto unlock;
883 	}
884 
885 	/* Wait for completion from ISR */
886 	ret = k_sem_take(&data->completion_sync, K_MSEC(30));
887 	if (ret != 0) {
888 		LOG_ERR("SMBus Block Process Call timed out");
889 		ret = -ETIMEDOUT;
890 		goto unlock;
891 	}
892 
893 	ret = pch_check_status(dev);
894 	if (ret < 0) {
895 		goto unlock;
896 	}
897 
898 	*recv_count = pch_reg_read(dev, PCH_SMBUS_HD0);
899 	if (*recv_count == 0 ||
900 	    *recv_count + send_count > SMBUS_BLOCK_BYTES_MAX) {
901 		ret = -ENODATA;
902 		goto unlock;
903 	}
904 
905 	for (int i = 0; i < *recv_count; i++) {
906 		recv_buf[i] = pch_reg_read(dev, PCH_SMBUS_HBD);
907 	}
908 
909 unlock:
910 	k_mutex_unlock(&data->mutex);
911 
912 	return ret;
913 }
914 
915 static const struct smbus_driver_api funcs = {
916 	.configure = pch_configure,
917 	.get_config = pch_get_config,
918 	.smbus_quick = pch_smbus_quick,
919 	.smbus_byte_write = pch_smbus_byte_write,
920 	.smbus_byte_read = pch_smbus_byte_read,
921 	.smbus_byte_data_write = pch_smbus_byte_data_write,
922 	.smbus_byte_data_read = pch_smbus_byte_data_read,
923 	.smbus_word_data_write = pch_smbus_word_data_write,
924 	.smbus_word_data_read = pch_smbus_word_data_read,
925 	.smbus_pcall = pch_smbus_pcall,
926 	.smbus_block_write = pch_smbus_block_write,
927 	.smbus_block_read = pch_smbus_block_read,
928 	.smbus_block_pcall = pch_smbus_block_pcall,
929 #if defined(CONFIG_SMBUS_INTEL_PCH_SMBALERT)
930 	.smbus_smbalert_set_cb = pch_smbus_smbalert_set_sb,
931 	.smbus_smbalert_remove_cb = pch_smbus_smbalert_remove_sb,
932 #endif /* CONFIG_SMBUS_INTEL_PCH_SMBALERT */
933 #if defined(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)
934 	.smbus_host_notify_set_cb = pch_smbus_host_notify_set_cb,
935 	.smbus_host_notify_remove_cb = pch_smbus_host_notify_remove_cb,
936 #endif /* CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY */
937 };
938 
smbus_isr(const struct device * dev)939 static void smbus_isr(const struct device *dev)
940 {
941 	const struct pch_config * const config = dev->config;
942 	struct pch_data *data = dev->data;
943 	uint32_t sts;
944 	uint8_t status;
945 
946 	sts = pcie_conf_read(config->pcie->bdf, PCIE_CONF_CMDSTAT);
947 	if (!(sts & PCIE_CONF_CMDSTAT_INTERRUPT)) {
948 		LOG_ERR("Not our interrupt");
949 		return;
950 	}
951 
952 	/**
953 	 * Handle first Host Notify since for that we need to read SSTS
954 	 * register and for all other sources HSTS.
955 	 *
956 	 * Intel PCH implements Host Notify protocol in hardware.
957 	 */
958 #if defined(CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY)
959 	if (data->config & SMBUS_MODE_HOST_NOTIFY) {
960 		status = pch_reg_read(dev, PCH_SMBUS_SSTS);
961 		if (status & PCH_SMBUS_SSTS_HNS) {
962 			/* Notify address */
963 			data->notify_addr =
964 				pch_reg_read(dev, PCH_SMBUS_NDA) >> 1;
965 
966 			/* Notify data */
967 			data->notify_data = pch_reg_read(dev, PCH_SMBUS_NDLB);
968 			data->notify_data |=
969 				pch_reg_read(dev, PCH_SMBUS_NDHB) << 8;
970 
971 			k_work_submit(&data->host_notify_work);
972 
973 			/* Clear Host Notify */
974 			pch_reg_write(dev, PCH_SMBUS_SSTS, PCH_SMBUS_SSTS_HNS);
975 
976 			return;
977 		}
978 	}
979 #endif /* CONFIG_SMBUS_INTEL_PCH_HOST_NOTIFY */
980 
981 	status = pch_reg_read(dev, PCH_SMBUS_HSTS);
982 
983 	/* HSTS dump if logging is enabled */
984 	pch_dump_register_hsts(status);
985 
986 	if (status & PCH_SMBUS_HSTS_BYTE_DONE) {
987 		LOG_WRN("BYTE_DONE interrupt is not used");
988 	}
989 
990 	/* Handle SMBALERT# signal */
991 #if defined(CONFIG_SMBUS_INTEL_PCH_SMBALERT)
992 	if (data->config & SMBUS_MODE_SMBALERT &&
993 	    status & PCH_SMBUS_HSTS_SMB_ALERT) {
994 		k_work_submit(&data->smb_alert_work);
995 	}
996 #endif /* CONFIG_SMBUS_INTEL_PCH_SMBALERT */
997 
998 	/* Clear IRQ sources */
999 	pch_reg_write(dev, PCH_SMBUS_HSTS, status);
1000 
1001 	data->status = status;
1002 
1003 	k_sem_give(&data->completion_sync);
1004 }
1005 
1006 /* Device macro initialization  / DTS hackery */
1007 
1008 #define SMBUS_PCH_IRQ_FLAGS(n)                                                 \
1009 	COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, sense),                            \
1010 		    (DT_INST_IRQ(n, sense)),                                   \
1011 		    (0))
1012 
1013 #define SMBUS_IRQ_CONFIG(n)                                                    \
1014 	BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS),                    \
1015 		     "SMBus PCIe requires dynamic interrupts");                \
1016 	static void pch_config_##n(const struct device *dev)                   \
1017 	{                                                                      \
1018 		const struct pch_config * const config = dev->config;          \
1019 		unsigned int irq;                                              \
1020 		if (DT_INST_IRQN(n) == PCIE_IRQ_DETECT) {                      \
1021 			irq = pcie_alloc_irq(config->pcie->bdf);               \
1022 			if (irq == PCIE_CONF_INTR_IRQ_NONE) {                  \
1023 				return;                                        \
1024 			}                                                      \
1025 		} else {                                                       \
1026 			irq = DT_INST_IRQN(n);                                 \
1027 			pcie_conf_write(config->pcie->bdf,                     \
1028 					PCIE_CONF_INTR, irq);                  \
1029 		}                                                              \
1030 		pcie_connect_dynamic_irq(config->pcie->bdf, irq,               \
1031 					 DT_INST_IRQ(n, priority),             \
1032 					 (void (*)(const void *))smbus_isr,    \
1033 					 DEVICE_DT_INST_GET(n),                \
1034 					 SMBUS_PCH_IRQ_FLAGS(n));              \
1035 		pcie_irq_enable(config->pcie->bdf, irq);                       \
1036 		LOG_DBG("Configure irq %d", irq);                              \
1037 	}
1038 
1039 #define SMBUS_DEVICE_INIT(n)                                                   \
1040 	DEVICE_PCIE_INST_DECLARE(n);                                           \
1041 	static void pch_config_##n(const struct device *dev);                  \
1042 	static const struct pch_config pch_config_data_##n = {                 \
1043 		DEVICE_PCIE_INST_INIT(n, pcie),                                \
1044 		.config_func = pch_config_##n,                                 \
1045 	};                                                                     \
1046 	static struct pch_data smbus_##n##_data;                               \
1047 	SMBUS_DEVICE_DT_INST_DEFINE(n, pch_smbus_init, NULL,                   \
1048 				    &smbus_##n##_data, &pch_config_data_##n,   \
1049 				    POST_KERNEL, CONFIG_SMBUS_INIT_PRIORITY,   \
1050 				    &funcs);                                   \
1051 	SMBUS_IRQ_CONFIG(n);
1052 
1053 DT_INST_FOREACH_STATUS_OKAY(SMBUS_DEVICE_INIT)
1054