ove/
i2c.rs

1// Copyright (C) 2026 Kamil Lulko <kamil.lulko@gmail.com>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4//
5// This file is part of oveRTOS.
6
7//! I2C bus master driver.
8//!
9//! Provides a safe wrapper around the oveRTOS I2C API with thread-safe bus
10//! locking, register-level convenience functions, and device probing.
11
12use crate::bindings;
13use crate::error::{Error, Result, WAIT_FOREVER};
14
15/// I2C bus speed grade.
16#[repr(u32)]
17#[derive(Debug, Copy, Clone, PartialEq, Eq)]
18pub enum Speed {
19    /// Standard mode — 100 kHz.
20    Standard = 0,
21    /// Fast mode — 400 kHz.
22    Fast = 1,
23    /// Fast-mode Plus — 1 MHz.
24    FastPlus = 2,
25}
26
27/// Write data to an I2C device.
28pub fn write(i2c: bindings::ove_i2c_t, addr: u16, data: &[u8], timeout_ms: u32) -> Result<()> {
29    let rc = unsafe {
30        bindings::ove_i2c_write(i2c, addr, data.as_ptr().cast(), data.len(), timeout_ms)
31    };
32    Error::from_code(rc)
33}
34
35/// Read data from an I2C device.
36pub fn read(i2c: bindings::ove_i2c_t, addr: u16, buf: &mut [u8], timeout_ms: u32) -> Result<()> {
37    let rc = unsafe {
38        bindings::ove_i2c_read(i2c, addr, buf.as_mut_ptr().cast(), buf.len(), timeout_ms)
39    };
40    Error::from_code(rc)
41}
42
43/// Combined write-then-read with I2C repeated start.
44pub fn write_read(
45    i2c: bindings::ove_i2c_t,
46    addr: u16,
47    tx: &[u8],
48    rx: &mut [u8],
49    timeout_ms: u32,
50) -> Result<()> {
51    let rc = unsafe {
52        bindings::ove_i2c_write_read(
53            i2c, addr,
54            tx.as_ptr().cast(), tx.len(),
55            rx.as_mut_ptr().cast(), rx.len(),
56            timeout_ms,
57        )
58    };
59    Error::from_code(rc)
60}
61
62/// Write to a single-byte-addressed register.
63pub fn reg_write(
64    i2c: bindings::ove_i2c_t,
65    addr: u16,
66    reg: u8,
67    data: &[u8],
68    timeout_ms: u32,
69) -> Result<()> {
70    let rc = unsafe {
71        bindings::ove_i2c_reg_write(
72            i2c, addr, reg,
73            data.as_ptr().cast(), data.len(),
74            timeout_ms,
75        )
76    };
77    Error::from_code(rc)
78}
79
80/// Read from a single-byte-addressed register.
81pub fn reg_read(
82    i2c: bindings::ove_i2c_t,
83    addr: u16,
84    reg: u8,
85    buf: &mut [u8],
86    timeout_ms: u32,
87) -> Result<()> {
88    let rc = unsafe {
89        bindings::ove_i2c_reg_read(
90            i2c, addr, reg,
91            buf.as_mut_ptr().cast(), buf.len(),
92            timeout_ms,
93        )
94    };
95    Error::from_code(rc)
96}
97
98/// Probe for a device at the given address (zero-length write, check ACK).
99pub fn probe(i2c: bindings::ove_i2c_t, addr: u16, timeout_ms: u32) -> Result<()> {
100    let rc = unsafe { bindings::ove_i2c_probe(i2c, addr, timeout_ms) };
101    Error::from_code(rc)
102}