Commit 8d928138 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

POSIX: Add proper I2C driver (via /dev/i2c)

parent 560b3555
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 Daniel Friesel
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#ifndef I2C_H
#define I2C_H

class I2C {
	private:
		I2C(const I2C &copy);
		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
+4 −0
Original line number Diff line number Diff line
@@ -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
+5 −0
Original line number Diff line number Diff line
@@ -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
+60 −0
Original line number Diff line number Diff line
/*
 * 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");