diff options
author | Daniel Friesel <derf@finalrewind.org> | 2021-11-21 22:33:33 +0100 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2021-11-21 22:33:33 +0100 |
commit | 8d92813827c5979c9298cbdd98b0503c427fd42a (patch) | |
tree | b6c101c47476e841020d7d2454d7325cf89f05ca | |
parent | 560b35559fb810ba3c0a85c24de59735c74e784e (diff) |
POSIX: Add proper I2C driver (via /dev/i2c)
-rw-r--r-- | include/arch/posix/driver/i2c.h | 24 | ||||
-rw-r--r-- | src/arch/posix/Kconfig | 4 | ||||
-rw-r--r-- | src/arch/posix/Makefile.inc | 5 | ||||
-rw-r--r-- | src/arch/posix/driver/i2c.cc | 60 |
4 files changed, 93 insertions, 0 deletions
diff --git a/include/arch/posix/driver/i2c.h b/include/arch/posix/driver/i2c.h new file mode 100644 index 0000000..e1f596c --- /dev/null +++ b/include/arch/posix/driver/i2c.h @@ -0,0 +1,24 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#ifndef I2C_H +#define I2C_H + +class I2C { + private: + I2C(const I2C ©); + const char *i2cbus; + + public: + I2C (const char *i2cbus) : i2cbus(i2cbus) {} + signed char setup(); + signed char xmit(unsigned char address, + unsigned char tx_len, unsigned char *tx_buf, + unsigned char rx_len, unsigned char *rx_buf); +}; + +extern I2C i2c; + +#endif diff --git a/src/arch/posix/Kconfig b/src/arch/posix/Kconfig index ad5e85e..42ed413 100644 --- a/src/arch/posix/Kconfig +++ b/src/arch/posix/Kconfig @@ -8,6 +8,10 @@ config arch_posix_driver_counter bool "Cycle counter" select meta_driver_counter +config arch_posix_driver_i2c +bool "I2C via /dev/i2c" +select meta_driver_i2c + config arch_posix_driver_uptime bool "Uptime counter" select meta_driver_uptime diff --git a/src/arch/posix/Makefile.inc b/src/arch/posix/Makefile.inc index 2f938a8..539e5f4 100644 --- a/src/arch/posix/Makefile.inc +++ b/src/arch/posix/Makefile.inc @@ -5,6 +5,7 @@ # SPDX-License-Identifier: BSD-2-Clause COMMON_FLAGS += -DMULTIPASS_ARCH_posix +COMMON_FLAGS += -DMULTIPASS_ARCH_HAS_I2C CC = gcc CXX = g++ @@ -27,6 +28,10 @@ ifeq (${timer_s}, 1) CONFIG_arch_posix_driver_uptime = y endif +ifdef CONFIG_arch_posix_driver_i2c + CXX_TARGETS += src/arch/posix/driver/i2c.cc +endif + ifdef CONFIG_arch_posix_driver_counter CXX_TARGETS += src/arch/posix/driver/counter.cc endif diff --git a/src/arch/posix/driver/i2c.cc b/src/arch/posix/driver/i2c.cc new file mode 100644 index 0000000..b408320 --- /dev/null +++ b/src/arch/posix/driver/i2c.cc @@ -0,0 +1,60 @@ +/* + * Copyright 2021 Daniel Friesel + * + * SPDX-License-Identifier: BSD-2-Clause + */ +#include "driver/i2c.h" +#include "arch.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <linux/i2c-dev.h> +#include <i2c/smbus.h> + + +signed char I2C::setup() +{ + return 0; +} + +signed char I2C::xmit(unsigned char address, + unsigned char tx_len, unsigned char *tx_buf, + unsigned char rx_len, unsigned char *rx_buf) +{ + struct i2c_msg messages[2]; + struct i2c_rdwr_ioctl_data transaction; + transaction.nmsgs = 0; + transaction.msgs = messages; + + if (tx_len) { + messages[transaction.nmsgs].addr = address; + messages[transaction.nmsgs].flags = 0; + messages[transaction.nmsgs].len = tx_len; + messages[transaction.nmsgs].buf = tx_buf; + transaction.nmsgs++; + } + if (rx_len) { + messages[transaction.nmsgs].addr = address; + messages[transaction.nmsgs].flags = I2C_M_RD; + messages[transaction.nmsgs].len = rx_len; + messages[transaction.nmsgs].buf = rx_buf; + transaction.nmsgs++; + } + + int fh = open(i2cbus, O_RDWR); + + if (fh < 0) { + return -1; + } + + if (ioctl(fh, I2C_RDWR, &transaction) == -1) { + return -1; + } + + close(fh); + return 0; +} + +I2C i2c("/dev/i2c-1"); |