Line data Source code
1 1 : /*
2 : * Copyright (c) 2022 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Public SMBus Driver APIs
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
13 : #define ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_
14 :
15 : /**
16 : * @brief SMBus Interface
17 : * @defgroup smbus_interface SMBus Interface
18 : * @since 3.4
19 : * @version 0.1.0
20 : * @ingroup io_interfaces
21 : * @{
22 : */
23 :
24 : #include <errno.h>
25 : #include <zephyr/sys/slist.h>
26 : #include <zephyr/types.h>
27 : #include <zephyr/device.h>
28 :
29 : #ifdef __cplusplus
30 : extern "C" {
31 : #endif
32 :
33 : /**
34 : * @name SMBus Protocol commands
35 : * @{
36 : *
37 : * SMBus Specification defines the following SMBus protocols operations
38 : */
39 :
40 : /**
41 : * SMBus Quick protocol is a very simple command with no data sent or
42 : * received. Peripheral may denote only R/W bit, which can still be
43 : * used for the peripheral management, for example to switch peripheral
44 : * On/Off. Quick protocol can also be used for peripheral devices
45 : * scanning.
46 : *
47 : * @code
48 : * 0 1
49 : * 0 1 2 3 4 5 6 7 8 9 0
50 : * +-+-+-+-+-+-+-+-+-+-+-+
51 : * |S| Periph Addr |D|A|P|
52 : * +-+-+-+-+-+-+-+-+-+-+-+
53 : * @endcode
54 : */
55 1 : #define SMBUS_CMD_QUICK 0b000
56 :
57 : /**
58 : * SMBus Byte protocol can send or receive one byte of data.
59 : *
60 : * @code
61 : * Byte Write
62 : *
63 : * 0 1 2
64 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
65 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66 : * |S| Periph Addr |W|A| Command code |A|P|
67 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68 : *
69 : * Byte Read
70 : *
71 : * 0 1 2
72 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
73 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 : * |S| Periph Addr |R|A| Byte received |N|P|
75 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 : * @endcode
77 : */
78 1 : #define SMBUS_CMD_BYTE 0b001
79 :
80 : /**
81 : * SMBus Byte Data protocol sends the first byte (command) followed
82 : * by read or write one byte.
83 : *
84 : * @code
85 : * Byte Data Write
86 : *
87 : * 0 1 2
88 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
89 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90 : * |S| Periph Addr |W|A| Command code |A| Data Write |A|P|
91 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
92 : *
93 : * Byte Data Read
94 : *
95 : * 0 1 2
96 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
97 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98 : * |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|A|
99 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100 : * | Data Read |N|P|
101 : * +-+-+-+-+-+-+-+-+-+-+
102 : * @endcode
103 : */
104 1 : #define SMBUS_CMD_BYTE_DATA 0b010
105 :
106 : /**
107 : * SMBus Word Data protocol sends the first byte (command) followed
108 : * by read or write two bytes.
109 : *
110 : * @code
111 : * Word Data Write
112 : *
113 : * 0 1 2
114 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
115 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116 : * |S| Periph Addr |W|A| Command code |A| Data Write Low|A|
117 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118 : * | Data Write Hi |A|P|
119 : * +-+-+-+-+-+-+-+-+-+-+
120 : *
121 : * Word Data Read
122 : *
123 : * 0 1 2
124 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
125 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126 : * |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|
127 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128 : * |A| Data Read Low |A| Data Read Hi |N|P|
129 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130 : * @endcode
131 : */
132 1 : #define SMBUS_CMD_WORD_DATA 0b011
133 :
134 : /**
135 : * SMBus Process Call protocol is Write Word followed by
136 : * Read Word. It is named so because the command sends data and waits
137 : * for the peripheral to return a reply.
138 : *
139 : * @code
140 : * 0 1 2
141 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
142 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
143 : * |S| Periph Addr |W|A| Command code |A| Data Write Low|A|
144 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145 : * | Data Write Hi |A|S| Periph Addr |R|A| Data Read Low |A|
146 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
147 : * | Data Read Hi |N|P|
148 : * +-+-+-+-+-+-+-+-+-+-+
149 : * @endcode
150 : */
151 1 : #define SMBUS_CMD_PROC_CALL 0b100
152 :
153 : /**
154 : * SMBus Block protocol reads or writes a block of data up to 32 bytes.
155 : * The Count byte specifies the amount of data.
156 : *
157 : * @code
158 : *
159 : * SMBus Block Write
160 : *
161 : * 0 1 2
162 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
163 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
164 : * |S| Periph Addr |W|A| Command code |A| Send Count=N |A|
165 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 : * | Data Write 1 |A| ... |A| Data Write N |A|P|
167 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
168 : *
169 : * SMBus Block Read
170 : *
171 : * 0 1 2
172 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
173 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
174 : * |S| Periph Addr |W|A| Command code |A|S| Periph Addr |R|
175 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
176 : * |A| Recv Count=N |A| Data Read 1 |A| ... |A|
177 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
178 : * | Data Read N |N|P|
179 : * +-+-+-+-+-+-+-+-+-+-+
180 : * @endcode
181 : */
182 1 : #define SMBUS_CMD_BLOCK 0b101
183 :
184 : /**
185 : * SMBus Block Write - Block Read Process Call protocol is
186 : * Block Write followed by Block Read.
187 : *
188 : * @code
189 : * 0 1 2
190 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
191 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
192 : * |S| Periph Addr |W|A| Command code |A| Count = N |A|
193 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
194 : * | Data Write 1 |A| ... |A| Data Write N |A|S|
195 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
196 : * | Periph Addr |R|A| Recv Count=N |A| Data Read 1 |A| |
197 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
198 : * | ... |A| Data Read N |N|P|
199 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
200 : * @endcode
201 : */
202 1 : #define SMBUS_CMD_BLOCK_PROC 0b111
203 : /** @} */
204 :
205 : /** Maximum number of bytes in SMBus Block protocol */
206 1 : #define SMBUS_BLOCK_BYTES_MAX 32
207 :
208 : /**
209 : * @name SMBus device functionality
210 : * @{
211 : *
212 : * The following parameters describe the functionality of the SMBus device
213 : */
214 :
215 : /** Peripheral to act as Controller. */
216 1 : #define SMBUS_MODE_CONTROLLER BIT(0)
217 :
218 : /** Support Packet Error Code (PEC) checking */
219 1 : #define SMBUS_MODE_PEC BIT(1)
220 :
221 : /** Support Host Notify functionality */
222 1 : #define SMBUS_MODE_HOST_NOTIFY BIT(2)
223 :
224 : /** Support SMBALERT signal functionality */
225 1 : #define SMBUS_MODE_SMBALERT BIT(3)
226 :
227 : /** @} */
228 :
229 : /**
230 : * @name SMBus special reserved addresses
231 : * @{
232 : *
233 : * The following addresses are reserved by SMBus specification
234 : */
235 :
236 : /**
237 : * @brief Alert Response Address (ARA)
238 : *
239 : * A broadcast address used by the system host as part of the
240 : * Alert Response Protocol.
241 : */
242 1 : #define SMBUS_ADDRESS_ARA 0x0c
243 :
244 : /** @} */
245 :
246 : /**
247 : * @name SMBus read / write direction
248 : * @{
249 : */
250 :
251 : /** @brief SMBus read / write direction */
252 1 : enum smbus_direction {
253 : /** Write a message to SMBus peripheral */
254 : SMBUS_MSG_WRITE = 0,
255 : /** Read a message from SMBus peripheral */
256 : SMBUS_MSG_READ = 1,
257 : };
258 :
259 : /** @} */
260 :
261 : /** @cond INTERNAL_HIDDEN */
262 : #define SMBUS_MSG_RW_MASK BIT(0)
263 : /** @endcond */
264 :
265 : struct smbus_callback;
266 :
267 : /**
268 : * @brief Define SMBus callback handler function signature.
269 : *
270 : * @param dev Pointer to the device structure for the SMBus driver instance.
271 : * @param cb Structure smbus_callback owning this handler.
272 : * @param addr Address of the SMBus peripheral device.
273 : */
274 1 : typedef void (*smbus_callback_handler_t)(const struct device *dev,
275 : struct smbus_callback *cb,
276 : uint8_t addr);
277 :
278 : /**
279 : * @brief SMBus callback structure
280 : *
281 : * Used to register a callback in the driver instance callback list.
282 : * As many callbacks as needed can be added as long as each of them
283 : * is a unique pointer of struct smbus_callback.
284 : *
285 : * Note: Such struct should not be allocated on stack.
286 : */
287 1 : struct smbus_callback {
288 : /** This should be used in driver for a callback list management */
289 1 : sys_snode_t node;
290 :
291 : /** Actual callback function being called when relevant */
292 1 : smbus_callback_handler_t handler;
293 :
294 : /** Peripheral device address */
295 1 : uint8_t addr;
296 : };
297 :
298 : /**
299 : * @brief Complete SMBus DT information
300 : */
301 1 : struct smbus_dt_spec {
302 : /** SMBus bus */
303 1 : const struct device *bus;
304 : /** Address of the SMBus peripheral device */
305 1 : uint16_t addr;
306 : };
307 :
308 : /**
309 : * @brief Structure initializer for smbus_dt_spec from devicetree
310 : *
311 : * This helper macro expands to a static initializer for a <tt>struct
312 : * smbus_dt_spec</tt> by reading the relevant bus and address data from
313 : * the devicetree.
314 : *
315 : * @param node_id Devicetree node identifier for the SMBus device whose
316 : * struct smbus_dt_spec to create an initializer for
317 : */
318 1 : #define SMBUS_DT_SPEC_GET(node_id) \
319 : { \
320 : .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
321 : .addr = DT_REG_ADDR(node_id) \
322 : }
323 :
324 : /**
325 : * @brief Structure initializer for smbus_dt_spec from devicetree instance
326 : *
327 : * This is equivalent to
328 : * <tt>SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))</tt>.
329 : *
330 : * @param inst Devicetree instance number
331 : */
332 1 : #define SMBUS_DT_SPEC_INST_GET(inst) SMBUS_DT_SPEC_GET(DT_DRV_INST(inst))
333 :
334 : /**
335 : * @cond INTERNAL_HIDDEN
336 : *
337 : * These are for internal use only, so skip these in
338 : * public documentation.
339 : */
340 :
341 : typedef int (*smbus_api_configure_t)(const struct device *dev,
342 : uint32_t dev_config);
343 : typedef int (*smbus_api_get_config_t)(const struct device *dev,
344 : uint32_t *dev_config);
345 : typedef int (*smbus_api_quick_t)(const struct device *dev,
346 : uint16_t addr, enum smbus_direction);
347 : typedef int (*smbus_api_byte_write_t)(const struct device *dev,
348 : uint16_t addr, uint8_t byte);
349 : typedef int (*smbus_api_byte_read_t)(const struct device *dev,
350 : uint16_t addr, uint8_t *byte);
351 : typedef int (*smbus_api_byte_data_write_t)(const struct device *dev,
352 : uint16_t addr, uint8_t cmd,
353 : uint8_t byte);
354 : typedef int (*smbus_api_byte_data_read_t)(const struct device *dev,
355 : uint16_t addr, uint8_t cmd,
356 : uint8_t *byte);
357 : typedef int (*smbus_api_word_data_write_t)(const struct device *dev,
358 : uint16_t addr, uint8_t cmd,
359 : uint16_t word);
360 : typedef int (*smbus_api_word_data_read_t)(const struct device *dev,
361 : uint16_t addr, uint8_t cmd,
362 : uint16_t *word);
363 : typedef int (*smbus_api_pcall_t)(const struct device *dev,
364 : uint16_t addr, uint8_t cmd,
365 : uint16_t send_word, uint16_t *recv_word);
366 : typedef int (*smbus_api_block_write_t)(const struct device *dev,
367 : uint16_t addr, uint8_t cmd,
368 : uint8_t count, uint8_t *buf);
369 : typedef int (*smbus_api_block_read_t)(const struct device *dev,
370 : uint16_t addr, uint8_t cmd,
371 : uint8_t *count, uint8_t *buf);
372 : typedef int (*smbus_api_block_pcall_t)(const struct device *dev,
373 : uint16_t addr, uint8_t cmd,
374 : uint8_t send_count, uint8_t *send_buf,
375 : uint8_t *recv_count, uint8_t *recv_buf);
376 : typedef int (*smbus_api_smbalert_cb_t)(const struct device *dev,
377 : struct smbus_callback *cb);
378 : typedef int (*smbus_api_host_notify_cb_t)(const struct device *dev,
379 : struct smbus_callback *cb);
380 :
381 : __subsystem struct smbus_driver_api {
382 : smbus_api_configure_t configure;
383 : smbus_api_get_config_t get_config;
384 : smbus_api_quick_t smbus_quick;
385 : smbus_api_byte_write_t smbus_byte_write;
386 : smbus_api_byte_read_t smbus_byte_read;
387 : smbus_api_byte_data_write_t smbus_byte_data_write;
388 : smbus_api_byte_data_read_t smbus_byte_data_read;
389 : smbus_api_word_data_write_t smbus_word_data_write;
390 : smbus_api_word_data_read_t smbus_word_data_read;
391 : smbus_api_pcall_t smbus_pcall;
392 : smbus_api_block_write_t smbus_block_write;
393 : smbus_api_block_read_t smbus_block_read;
394 : smbus_api_block_pcall_t smbus_block_pcall;
395 : smbus_api_smbalert_cb_t smbus_smbalert_set_cb;
396 : smbus_api_smbalert_cb_t smbus_smbalert_remove_cb;
397 : smbus_api_host_notify_cb_t smbus_host_notify_set_cb;
398 : smbus_api_host_notify_cb_t smbus_host_notify_remove_cb;
399 : };
400 :
401 : /**
402 : * @endcond
403 : */
404 :
405 : #if defined(CONFIG_SMBUS_STATS) || defined(__DOXYGEN__)
406 :
407 : #include <zephyr/stats/stats.h>
408 :
409 : /** @cond INTERNAL_HIDDEN */
410 :
411 : STATS_SECT_START(smbus)
412 : STATS_SECT_ENTRY32(bytes_read)
413 : STATS_SECT_ENTRY32(bytes_written)
414 : STATS_SECT_ENTRY32(command_count)
415 : STATS_SECT_END;
416 :
417 : STATS_NAME_START(smbus)
418 : STATS_NAME(smbus, bytes_read)
419 : STATS_NAME(smbus, bytes_written)
420 : STATS_NAME(smbus, command_count)
421 : STATS_NAME_END(smbus);
422 :
423 : struct smbus_device_state {
424 : struct device_state devstate;
425 : struct stats_smbus stats;
426 : };
427 :
428 : /**
429 : * @brief Define a statically allocated and section assigned smbus device state
430 : */
431 : #define Z_SMBUS_DEVICE_STATE_DEFINE(node_id, dev_name) \
432 : static struct smbus_device_state Z_DEVICE_STATE_NAME(dev_name) \
433 : __attribute__((__section__(".z_devstate")));
434 :
435 : /**
436 : * @brief Define an smbus device init wrapper function
437 : *
438 : * This does device instance specific initialization of common data
439 : * (such as stats) and calls the given init_fn
440 : */
441 : #define Z_SMBUS_INIT_FN(dev_name, init_fn) \
442 : static inline int \
443 : UTIL_CAT(dev_name, _init)(const struct device *dev) \
444 : { \
445 : struct smbus_device_state *state = \
446 : CONTAINER_OF(dev->state, \
447 : struct smbus_device_state, \
448 : devstate); \
449 : stats_init(&state->stats.s_hdr, STATS_SIZE_32, 4, \
450 : STATS_NAME_INIT_PARMS(smbus)); \
451 : stats_register(dev->name, &(state->stats.s_hdr)); \
452 : return init_fn(dev); \
453 : }
454 :
455 : /** @endcond */
456 :
457 : /**
458 : * @brief Updates the SMBus stats
459 : *
460 : * @param dev Pointer to the device structure for the SMBus driver instance
461 : * to update stats for.
462 : * @param sent Number of bytes sent
463 : * @param recv Number of bytes received
464 : */
465 1 : static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
466 : uint8_t recv)
467 : {
468 : struct smbus_device_state *state =
469 : CONTAINER_OF(dev->state, struct smbus_device_state, devstate);
470 :
471 : STATS_INC(state->stats, command_count);
472 : STATS_INCN(state->stats, bytes_read, recv);
473 : STATS_INCN(state->stats, bytes_written, sent);
474 : }
475 :
476 : /**
477 : * @brief Like DEVICE_DT_DEFINE() with SMBus specifics.
478 : *
479 : * @details Defines a device which implements the SMBus API. May
480 : * generate a custom device_state container struct and init_fn
481 : * wrapper when needed depending on SMBus @kconfig{CONFIG_SMBUS_STATS}.
482 : *
483 : * @param node_id The devicetree node identifier.
484 : *
485 : * @param init_fn Name of the init function of the driver.
486 : *
487 : * @param pm_device PM device resources reference
488 : * (NULL if device does not use PM).
489 : *
490 : * @param data_ptr Pointer to the device's private data.
491 : *
492 : * @param cfg_ptr The address to the structure containing the
493 : * configuration information for this instance of the driver.
494 : *
495 : * @param level The initialization level. See SYS_INIT() for
496 : * details.
497 : *
498 : * @param prio Priority within the selected initialization level. See
499 : * SYS_INIT() for details.
500 : *
501 : * @param api_ptr Provides an initial pointer to the API function struct
502 : * used by the driver. Can be NULL.
503 : */
504 : #define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
505 : data_ptr, cfg_ptr, level, prio, \
506 1 : api_ptr, ...) \
507 : Z_SMBUS_DEVICE_STATE_DEFINE(node_id, \
508 : Z_DEVICE_DT_DEV_NAME(node_id)); \
509 : Z_SMBUS_INIT_FN(Z_DEVICE_DT_DEV_NAME(node_id), init_fn) \
510 : Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
511 : DEVICE_DT_NAME(node_id), \
512 : &UTIL_CAT(Z_DEVICE_DT_DEV_NAME(node_id), _init),\
513 : pm_device, \
514 : data_ptr, cfg_ptr, level, prio, \
515 : api_ptr, \
516 : &(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME \
517 : (node_id)).devstate), \
518 : __VA_ARGS__)
519 :
520 : #else /* CONFIG_SMBUS_STATS */
521 :
522 : static inline void smbus_xfer_stats(const struct device *dev, uint8_t sent,
523 : uint8_t recv)
524 : {
525 : ARG_UNUSED(dev);
526 : ARG_UNUSED(sent);
527 : ARG_UNUSED(recv);
528 : }
529 :
530 : #define SMBUS_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
531 : data_ptr, cfg_ptr, level, prio, \
532 : api_ptr, ...) \
533 : DEVICE_DT_DEFINE(node_id, &init_fn, pm_device, \
534 : data_ptr, cfg_ptr, level, prio, \
535 : api_ptr, __VA_ARGS__)
536 :
537 : #endif /* CONFIG_SMBUS_STATS */
538 :
539 : /**
540 : * @brief Like SMBUS_DEVICE_DT_DEFINE() for an instance of a DT_DRV_COMPAT
541 : * compatible
542 : *
543 : * @param inst instance number. This is replaced by
544 : * <tt>DT_DRV_COMPAT(inst)</tt> in the call to SMBUS_DEVICE_DT_DEFINE().
545 : *
546 : * @param ... other parameters as expected by SMBUS_DEVICE_DT_DEFINE().
547 : */
548 1 : #define SMBUS_DEVICE_DT_INST_DEFINE(inst, ...) \
549 : SMBUS_DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
550 :
551 : /**
552 : * @brief Configure operation of a SMBus host controller.
553 : *
554 : * @param dev Pointer to the device structure for the SMBus driver instance.
555 : * @param dev_config Bit-packed 32-bit value to the device runtime configuration
556 : * for the SMBus controller.
557 : *
558 : * @retval 0 If successful.
559 : * @retval -EIO General input / output error.
560 : */
561 1 : __syscall int smbus_configure(const struct device *dev, uint32_t dev_config);
562 :
563 : static inline int z_impl_smbus_configure(const struct device *dev,
564 : uint32_t dev_config)
565 : {
566 : const struct smbus_driver_api *api =
567 : (const struct smbus_driver_api *)dev->api;
568 :
569 : return api->configure(dev, dev_config);
570 : }
571 :
572 : /**
573 : * @brief Get configuration of a SMBus host controller.
574 : *
575 : * This routine provides a way to get current configuration. It is allowed to
576 : * call the function before smbus_configure, because some SMBus ports can be
577 : * configured during init process. However, if the SMBus port is not configured,
578 : * smbus_get_config returns an error.
579 : *
580 : * smbus_get_config can return cached config or probe hardware, but it has to be
581 : * up to date with current configuration.
582 : *
583 : * @param dev Pointer to the device structure for the SMBus driver instance.
584 : * @param dev_config Pointer to return bit-packed 32-bit value of
585 : * the SMBus controller configuration.
586 : *
587 : * @retval 0 If successful.
588 : * @retval -EIO General input / output error.
589 : * @retval -ENOSYS If function smbus_get_config() is not implemented
590 : * by the driver.
591 : */
592 1 : __syscall int smbus_get_config(const struct device *dev, uint32_t *dev_config);
593 :
594 : static inline int z_impl_smbus_get_config(const struct device *dev,
595 : uint32_t *dev_config)
596 : {
597 : const struct smbus_driver_api *api =
598 : (const struct smbus_driver_api *)dev->api;
599 :
600 : if (api->get_config == NULL) {
601 : return -ENOSYS;
602 : }
603 :
604 : return api->get_config(dev, dev_config);
605 : }
606 :
607 : /**
608 : * @brief Add SMBUSALERT callback for a SMBus host controller.
609 : *
610 : * @param dev Pointer to the device structure for the SMBus driver instance.
611 : * @param cb Pointer to a callback structure.
612 : *
613 : * @retval 0 If successful.
614 : * @retval -EIO General input / output error.
615 : * @retval -ENOSYS If function smbus_smbalert_set_cb() is not implemented
616 : * by the driver.
617 : */
618 1 : static inline int smbus_smbalert_set_cb(const struct device *dev,
619 : struct smbus_callback *cb)
620 : {
621 : const struct smbus_driver_api *api =
622 : (const struct smbus_driver_api *)dev->api;
623 :
624 : if (api->smbus_smbalert_set_cb == NULL) {
625 : return -ENOSYS;
626 : }
627 :
628 : return api->smbus_smbalert_set_cb(dev, cb);
629 : }
630 :
631 : /**
632 : * @brief Remove SMBUSALERT callback from a SMBus host controller.
633 : *
634 : * @param dev Pointer to the device structure for the SMBus driver instance.
635 : * @param cb Pointer to a callback structure.
636 : *
637 : * @retval 0 If successful.
638 : * @retval -EIO General input / output error.
639 : * @retval -ENOSYS If function smbus_smbalert_remove_cb() is not implemented
640 : * by the driver.
641 : */
642 1 : __syscall int smbus_smbalert_remove_cb(const struct device *dev,
643 : struct smbus_callback *cb);
644 :
645 : static inline int z_impl_smbus_smbalert_remove_cb(const struct device *dev,
646 : struct smbus_callback *cb)
647 : {
648 : const struct smbus_driver_api *api =
649 : (const struct smbus_driver_api *)dev->api;
650 :
651 : if (api->smbus_smbalert_remove_cb == NULL) {
652 : return -ENOSYS;
653 : }
654 :
655 : return api->smbus_smbalert_remove_cb(dev, cb);
656 : }
657 :
658 : /**
659 : * @brief Add Host Notify callback for a SMBus host controller.
660 : *
661 : * @param dev Pointer to the device structure for the SMBus driver instance.
662 : * @param cb Pointer to a callback structure.
663 : *
664 : * @retval 0 If successful.
665 : * @retval -EIO General input / output error.
666 : * @retval -ENOSYS If function smbus_host_notify_set_cb() is not implemented
667 : * by the driver.
668 : */
669 1 : static inline int smbus_host_notify_set_cb(const struct device *dev,
670 : struct smbus_callback *cb)
671 : {
672 : const struct smbus_driver_api *api =
673 : (const struct smbus_driver_api *)dev->api;
674 :
675 : if (api->smbus_host_notify_set_cb == NULL) {
676 : return -ENOSYS;
677 : }
678 :
679 : return api->smbus_host_notify_set_cb(dev, cb);
680 : }
681 :
682 : /**
683 : * @brief Remove Host Notify callback from a SMBus host controller.
684 : *
685 : * @param dev Pointer to the device structure for the SMBus driver instance.
686 : * @param cb Pointer to a callback structure.
687 : *
688 : * @retval 0 If successful.
689 : * @retval -EIO General input / output error.
690 : * @retval -ENOSYS If function smbus_host_notify_remove_cb() is not implemented
691 : * by the driver.
692 : */
693 1 : __syscall int smbus_host_notify_remove_cb(const struct device *dev,
694 : struct smbus_callback *cb);
695 :
696 : static inline int z_impl_smbus_host_notify_remove_cb(const struct device *dev,
697 : struct smbus_callback *cb)
698 : {
699 : const struct smbus_driver_api *api =
700 : (const struct smbus_driver_api *)dev->api;
701 :
702 : if (api->smbus_host_notify_remove_cb == NULL) {
703 : return -ENOSYS;
704 : }
705 :
706 : return api->smbus_host_notify_remove_cb(dev, cb);
707 : }
708 :
709 : /**
710 : * @brief Perform SMBus Quick operation
711 : *
712 : * This routine provides a generic interface to perform SMBus Quick
713 : * operation.
714 : *
715 : * @param dev Pointer to the device structure for the SMBus driver instance.
716 : * driver configured in controller mode.
717 : * @param addr Address of the SMBus peripheral device.
718 : * @param direction Direction Read or Write.
719 : *
720 : * @retval 0 If successful.
721 : * @retval -EIO General input / output error.
722 : * @retval -ENOSYS If function smbus_quick() is not implemented
723 : * by the driver.
724 : */
725 1 : __syscall int smbus_quick(const struct device *dev, uint16_t addr,
726 : enum smbus_direction direction);
727 :
728 : static inline int z_impl_smbus_quick(const struct device *dev, uint16_t addr,
729 : enum smbus_direction direction)
730 : {
731 : const struct smbus_driver_api *api =
732 : (const struct smbus_driver_api *)dev->api;
733 :
734 : if (api->smbus_quick == NULL) {
735 : return -ENOSYS;
736 : }
737 :
738 : if (direction != SMBUS_MSG_READ && direction != SMBUS_MSG_WRITE) {
739 : return -EINVAL;
740 : }
741 :
742 : return api->smbus_quick(dev, addr, direction);
743 : }
744 :
745 : /**
746 : * @brief Perform SMBus Byte Write operation
747 : *
748 : * This routine provides a generic interface to perform SMBus
749 : * Byte Write operation.
750 : *
751 : * @param dev Pointer to the device structure for the SMBus driver instance.
752 : * @param addr Address of the SMBus peripheral device.
753 : * @param byte Byte to be sent to the peripheral device.
754 : *
755 : * @retval 0 If successful.
756 : * @retval -EIO General input / output error.
757 : * @retval -ENOSYS If function smbus_byte_write() is not implemented
758 : * by the driver.
759 : */
760 1 : __syscall int smbus_byte_write(const struct device *dev, uint16_t addr,
761 : uint8_t byte);
762 :
763 : static inline int z_impl_smbus_byte_write(const struct device *dev,
764 : uint16_t addr, uint8_t byte)
765 : {
766 : const struct smbus_driver_api *api =
767 : (const struct smbus_driver_api *)dev->api;
768 :
769 : if (api->smbus_byte_write == NULL) {
770 : return -ENOSYS;
771 : }
772 :
773 : return api->smbus_byte_write(dev, addr, byte);
774 : }
775 :
776 : /**
777 : * @brief Perform SMBus Byte Read operation
778 : *
779 : * This routine provides a generic interface to perform SMBus
780 : * Byte Read operation.
781 : *
782 : * @param dev Pointer to the device structure for the SMBus driver instance.
783 : * @param addr Address of the SMBus peripheral device.
784 : * @param byte Byte received from the peripheral device.
785 : *
786 : * @retval 0 If successful.
787 : * @retval -EIO General input / output error.
788 : * @retval -ENOSYS If function smbus_byte_read() is not implemented
789 : * by the driver.
790 : */
791 1 : __syscall int smbus_byte_read(const struct device *dev, uint16_t addr,
792 : uint8_t *byte);
793 :
794 : static inline int z_impl_smbus_byte_read(const struct device *dev,
795 : uint16_t addr, uint8_t *byte)
796 : {
797 : const struct smbus_driver_api *api =
798 : (const struct smbus_driver_api *)dev->api;
799 :
800 : if (api->smbus_byte_read == NULL) {
801 : return -ENOSYS;
802 : }
803 :
804 : return api->smbus_byte_read(dev, addr, byte);
805 : }
806 :
807 : /**
808 : * @brief Perform SMBus Byte Data Write operation
809 : *
810 : * This routine provides a generic interface to perform SMBus
811 : * Byte Data Write operation.
812 : *
813 : * @param dev Pointer to the device structure for the SMBus driver instance.
814 : * @param addr Address of the SMBus peripheral device.
815 : * @param cmd Command byte which is sent to peripheral device first.
816 : * @param byte Byte to be sent to the peripheral device.
817 : *
818 : * @retval 0 If successful.
819 : * @retval -EIO General input / output error.
820 : * @retval -ENOSYS If function smbus_byte_data_write() is not implemented
821 : * by the driver.
822 : */
823 1 : __syscall int smbus_byte_data_write(const struct device *dev, uint16_t addr,
824 : uint8_t cmd, uint8_t byte);
825 :
826 : static inline int z_impl_smbus_byte_data_write(const struct device *dev,
827 : uint16_t addr, uint8_t cmd,
828 : uint8_t byte)
829 : {
830 : const struct smbus_driver_api *api =
831 : (const struct smbus_driver_api *)dev->api;
832 :
833 : if (api->smbus_byte_data_write == NULL) {
834 : return -ENOSYS;
835 : }
836 :
837 : return api->smbus_byte_data_write(dev, addr, cmd, byte);
838 : }
839 :
840 : /**
841 : * @brief Perform SMBus Byte Data Read operation
842 : *
843 : * This routine provides a generic interface to perform SMBus
844 : * Byte Data Read operation.
845 : *
846 : * @param dev Pointer to the device structure for the SMBus driver instance.
847 : * @param addr Address of the SMBus peripheral device.
848 : * @param cmd Command byte which is sent to peripheral device first.
849 : * @param byte Byte received from the peripheral device.
850 : *
851 : * @retval 0 If successful.
852 : * @retval -EIO General input / output error.
853 : * @retval -ENOSYS If function smbus_byte_data_read() is not implemented
854 : * by the driver.
855 : */
856 1 : __syscall int smbus_byte_data_read(const struct device *dev, uint16_t addr,
857 : uint8_t cmd, uint8_t *byte);
858 :
859 : static inline int z_impl_smbus_byte_data_read(const struct device *dev,
860 : uint16_t addr, uint8_t cmd,
861 : uint8_t *byte)
862 : {
863 : const struct smbus_driver_api *api =
864 : (const struct smbus_driver_api *)dev->api;
865 :
866 : if (api->smbus_byte_data_read == NULL) {
867 : return -ENOSYS;
868 : }
869 :
870 : return api->smbus_byte_data_read(dev, addr, cmd, byte);
871 : }
872 :
873 : /**
874 : * @brief Perform SMBus Word Data Write operation
875 : *
876 : * This routine provides a generic interface to perform SMBus
877 : * Word Data Write operation.
878 : *
879 : * @param dev Pointer to the device structure for the SMBus driver instance.
880 : * @param addr Address of the SMBus peripheral device.
881 : * @param cmd Command byte which is sent to peripheral device first.
882 : * @param word Word (16-bit) to be sent to the peripheral device.
883 : *
884 : * @retval 0 If successful.
885 : * @retval -EIO General input / output error.
886 : * @retval -ENOSYS If function smbus_word_data_write() is not implemented
887 : * by the driver.
888 : */
889 1 : __syscall int smbus_word_data_write(const struct device *dev, uint16_t addr,
890 : uint8_t cmd, uint16_t word);
891 :
892 : static inline int z_impl_smbus_word_data_write(const struct device *dev,
893 : uint16_t addr, uint8_t cmd,
894 : uint16_t word)
895 : {
896 : const struct smbus_driver_api *api =
897 : (const struct smbus_driver_api *)dev->api;
898 :
899 : if (api->smbus_word_data_write == NULL) {
900 : return -ENOSYS;
901 : }
902 :
903 : return api->smbus_word_data_write(dev, addr, cmd, word);
904 : }
905 :
906 : /**
907 : * @brief Perform SMBus Word Data Read operation
908 : *
909 : * This routine provides a generic interface to perform SMBus
910 : * Word Data Read operation.
911 : *
912 : * @param dev Pointer to the device structure for the SMBus driver instance.
913 : * @param addr Address of the SMBus peripheral device.
914 : * @param cmd Command byte which is sent to peripheral device first.
915 : * @param word Word (16-bit) received from the peripheral device.
916 : *
917 : * @retval 0 If successful.
918 : * @retval -EIO General input / output error.
919 : * @retval -ENOSYS If function smbus_word_data_read() is not implemented
920 : * by the driver.
921 : */
922 1 : __syscall int smbus_word_data_read(const struct device *dev, uint16_t addr,
923 : uint8_t cmd, uint16_t *word);
924 :
925 : static inline int z_impl_smbus_word_data_read(const struct device *dev,
926 : uint16_t addr, uint8_t cmd,
927 : uint16_t *word)
928 : {
929 : const struct smbus_driver_api *api =
930 : (const struct smbus_driver_api *)dev->api;
931 :
932 : if (api->smbus_word_data_read == NULL) {
933 : return -ENOSYS;
934 : }
935 :
936 : return api->smbus_word_data_read(dev, addr, cmd, word);
937 : }
938 :
939 : /**
940 : * @brief Perform SMBus Process Call operation
941 : *
942 : * This routine provides a generic interface to perform SMBus
943 : * Process Call operation, which means Write 2 bytes following by
944 : * Read 2 bytes.
945 : *
946 : * @param dev Pointer to the device structure for the SMBus driver instance.
947 : * @param addr Address of the SMBus peripheral device.
948 : * @param cmd Command byte which is sent to peripheral device first.
949 : * @param send_word Word (16-bit) to be sent to the peripheral device.
950 : * @param recv_word Word (16-bit) received from the peripheral device.
951 : *
952 : * @retval 0 If successful.
953 : * @retval -EIO General input / output error.
954 : * @retval -ENOSYS If function smbus_pcall() is not implemented
955 : * by the driver.
956 : */
957 1 : __syscall int smbus_pcall(const struct device *dev, uint16_t addr,
958 : uint8_t cmd, uint16_t send_word, uint16_t *recv_word);
959 :
960 : static inline int z_impl_smbus_pcall(const struct device *dev,
961 : uint16_t addr, uint8_t cmd,
962 : uint16_t send_word, uint16_t *recv_word)
963 : {
964 : const struct smbus_driver_api *api =
965 : (const struct smbus_driver_api *)dev->api;
966 :
967 : if (api->smbus_pcall == NULL) {
968 : return -ENOSYS;
969 : }
970 :
971 : return api->smbus_pcall(dev, addr, cmd, send_word, recv_word);
972 : }
973 :
974 : /**
975 : * @brief Perform SMBus Block Write operation
976 : *
977 : * This routine provides a generic interface to perform SMBus
978 : * Block Write operation.
979 : *
980 : * @param dev Pointer to the device structure for the SMBus driver instance.
981 : * @param addr Address of the SMBus peripheral device.
982 : * @param cmd Command byte which is sent to peripheral device first.
983 : * @param count Size of the data block buffer. Maximum 32 bytes.
984 : * @param buf Data block buffer to be sent to the peripheral device.
985 : *
986 : * @retval 0 If successful.
987 : * @retval -EIO General input / output error.
988 : * @retval -ENOSYS If function smbus_block_write() is not implemented
989 : * by the driver.
990 : */
991 1 : __syscall int smbus_block_write(const struct device *dev, uint16_t addr,
992 : uint8_t cmd, uint8_t count, uint8_t *buf);
993 :
994 : static inline int z_impl_smbus_block_write(const struct device *dev,
995 : uint16_t addr, uint8_t cmd,
996 : uint8_t count, uint8_t *buf)
997 : {
998 : const struct smbus_driver_api *api =
999 : (const struct smbus_driver_api *)dev->api;
1000 :
1001 : if (api->smbus_block_write == NULL) {
1002 : return -ENOSYS;
1003 : }
1004 :
1005 : if (count < 1 || count > SMBUS_BLOCK_BYTES_MAX) {
1006 : return -EINVAL;
1007 : }
1008 :
1009 : return api->smbus_block_write(dev, addr, cmd, count, buf);
1010 : }
1011 :
1012 : /**
1013 : * @brief Perform SMBus Block Read operation
1014 : *
1015 : * This routine provides a generic interface to perform SMBus
1016 : * Block Read operation.
1017 : *
1018 : * @param dev Pointer to the device structure for the SMBus driver instance.
1019 : * @param addr Address of the SMBus peripheral device.
1020 : * @param cmd Command byte which is sent to peripheral device first.
1021 : * @param count Size of the data peripheral sent. Maximum 32 bytes.
1022 : * @param buf Data block buffer received from the peripheral device.
1023 : *
1024 : * @retval 0 If successful.
1025 : * @retval -EIO General input / output error.
1026 : * @retval -ENOSYS If function smbus_block_read() is not implemented
1027 : * by the driver.
1028 : */
1029 1 : __syscall int smbus_block_read(const struct device *dev, uint16_t addr,
1030 : uint8_t cmd, uint8_t *count, uint8_t *buf);
1031 :
1032 : static inline int z_impl_smbus_block_read(const struct device *dev,
1033 : uint16_t addr, uint8_t cmd,
1034 : uint8_t *count, uint8_t *buf)
1035 : {
1036 : const struct smbus_driver_api *api =
1037 : (const struct smbus_driver_api *)dev->api;
1038 :
1039 : if (api->smbus_block_read == NULL) {
1040 : return -ENOSYS;
1041 : }
1042 :
1043 : return api->smbus_block_read(dev, addr, cmd, count, buf);
1044 : }
1045 :
1046 : /**
1047 : * @brief Perform SMBus Block Process Call operation
1048 : *
1049 : * This routine provides a generic interface to perform SMBus
1050 : * Block Process Call operation. This operation is basically
1051 : * Block Write followed by Block Read.
1052 : *
1053 : * @param dev Pointer to the device structure for the SMBus driver instance.
1054 : * @param addr Address of the SMBus peripheral device.
1055 : * @param cmd Command byte which is sent to peripheral device first.
1056 : * @param snd_count Size of the data block buffer to send.
1057 : * @param snd_buf Data block buffer send to the peripheral device.
1058 : * @param rcv_count Size of the data peripheral sent.
1059 : * @param rcv_buf Data block buffer received from the peripheral device.
1060 : *
1061 : * @retval 0 If successful.
1062 : * @retval -EIO General input / output error.
1063 : * @retval -ENOSYS If function smbus_block_pcall() is not implemented
1064 : * by the driver.
1065 : */
1066 1 : __syscall int smbus_block_pcall(const struct device *dev,
1067 : uint16_t addr, uint8_t cmd,
1068 : uint8_t snd_count, uint8_t *snd_buf,
1069 : uint8_t *rcv_count, uint8_t *rcv_buf);
1070 :
1071 : static inline int z_impl_smbus_block_pcall(const struct device *dev,
1072 : uint16_t addr, uint8_t cmd,
1073 : uint8_t snd_count, uint8_t *snd_buf,
1074 : uint8_t *rcv_count, uint8_t *rcv_buf)
1075 : {
1076 : const struct smbus_driver_api *api =
1077 : (const struct smbus_driver_api *)dev->api;
1078 :
1079 : if (api->smbus_block_pcall == NULL) {
1080 : return -ENOSYS;
1081 : }
1082 :
1083 : return api->smbus_block_pcall(dev, addr, cmd, snd_count, snd_buf,
1084 : rcv_count, rcv_buf);
1085 : }
1086 :
1087 : #ifdef __cplusplus
1088 : }
1089 : #endif
1090 :
1091 : /**
1092 : * @}
1093 : */
1094 :
1095 : #include <zephyr/syscalls/smbus.h>
1096 :
1097 : #endif /* ZEPHYR_INCLUDE_DRIVERS_SMBUS_H_ */
|