diff --git a/repos/os/run/i2c_mcp9808.run b/repos/os/run/i2c_mcp9808.run deleted file mode 100644 index e21a3a4160..0000000000 --- a/repos/os/run/i2c_mcp9808.run +++ /dev/null @@ -1,84 +0,0 @@ -assert_spec arm_v8a - -create_boot_directory - -import_from_depot [depot_user]/src/[base_src] -import_from_depot [depot_user]/src/init -import_from_depot [depot_user]/src/platform - -build { - core - timer - driver/i2c - test/i2c_mcp9808 -} - -install_config { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -} - -file copy [select_from_repositories board/[board]/devices] [run_dir]/genode/devices - -build_boot_image [build_artifacts] - -run_genode_until forever diff --git a/repos/os/src/driver/i2c/README b/repos/os/src/driver/i2c/README deleted file mode 100644 index 5bf031ddd5..0000000000 --- a/repos/os/src/driver/i2c/README +++ /dev/null @@ -1,72 +0,0 @@ -This directory contains the implementation of the I2C driver component. - -Brief -===== - -The driver supports I2C bus controller for imx8q_evk only for master mode. -A platform connection is used to retrieve device's capabilities. -The platform driver must provide a device with the following configuration: - -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! - -The io_mem address, irq number and clock might change from one I2C bus -controller to another. The io_mem address for iomux configuration may -remain the same across I2C bus controllers. - -The driver can be extended to another platform. An 'I2c::Driver_base' -interface is provided in 'i2c_interface.h'. The specific platform -implementation must expose a 'driver.h' header file that contains a -declaration of 'I2c::Driver' that implements the 'I2c::Driver_base' -interface. An example of a specific platform implementation can be found -in 'os/src/driver/i2c/imx8q_evk'. - -Configuration -============= - -The driver acts as a server that must be configured via a policy, that states -which client can access a certain device(s) on the bus: - -! -! -! -! -! -! -! -! -! -! -! -! - -The driver's config must contain the 'bus_no' (bus number) attribute, -'bus_no="2"' for bus 2. And device(s) policy with two attributes -'label_prefix' and 'bus_address' which is an address of a slave -device on the bus. A 'verbose' boolean attribute might be specified -if you want the driver to log error messages. - -Example -======= - -An example of how to use the I2C driver can be found in the test -script 'os/run/i2c_mcp9808.run'. diff --git a/repos/os/src/driver/i2c/component.h b/repos/os/src/driver/i2c/component.h deleted file mode 100644 index c3fe296188..0000000000 --- a/repos/os/src/driver/i2c/component.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * \brief I2C session component - * \author Jean-Adrien Domage - * \date 2021-02-26 - */ - -/* - * Copyright (C) 2013-2021 Genode Labs GmbH - * Copyright (C) 2021 gapfruit AG - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _I2C_DRIVER__COMPONENT_H_ -#define _I2C_DRIVER__COMPONENT_H_ - -#include -#include -#include -#include "i2c_interface.h" - -namespace I2c { - using namespace Genode; - class Session_component; - class Root; -} - - -class I2c::Session_component : public Rpc_object -{ - private: - - Rpc_entrypoint &_ep; - I2c::Driver_base &_driver; - uint8_t const _device_address; - - public: - - Session_component(Rpc_entrypoint &ep, - I2c::Driver_base &driver, - uint8_t device_address) - : - _ep(ep), _driver(driver), _device_address(device_address) - { } - - void transmit(Transaction & t) override { - _driver.transmit(_device_address, t); } -}; - - -class I2c::Root : public Root_component -{ - private: - - Rpc_entrypoint &_ep; - I2c::Driver_base &_driver; - Xml_node const _config; - - protected: - - Session_component *_create_session(char const *args) override - { - char device_name_c_string[I2c::Device_name::capacity()] { }; - Arg_string::find_arg(args, "label").string(device_name_c_string, sizeof(device_name_c_string), ""); - Device_name const device_name(device_name_c_string); - - Genode::Session_policy policy(device_name, _config); - uint8_t const device_address = policy.attribute_value("bus_address", static_cast(0)); - - /* address 0x0 is reserved, so if we return 0x0 it is an error */ - if (device_address == 0) { - warning("Session with label '", - device_name, - "' could not be created, no such policy"); - throw Service_denied(); - } - - return new (md_alloc()) I2c::Session_component(_ep, _driver, device_address); - } - - public: - - Root(Rpc_entrypoint &ep, Allocator &md_alloc, - I2c::Driver_base &driver, Xml_node const &config) - : - Root_component(&ep, &md_alloc), - _ep(ep), _driver(driver), _config(config) - { } -}; - -#endif /* _I2C_DRIVER__COMPONENT_H_ */ diff --git a/repos/os/src/driver/i2c/i2c_interface.h b/repos/os/src/driver/i2c/i2c_interface.h deleted file mode 100644 index 35a4fef552..0000000000 --- a/repos/os/src/driver/i2c/i2c_interface.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * \brief I2C driver base class to be implemented by platform specific - * \author Jean-Adrien Domage - * \date 2021-02-08 - */ - -/* - * Copyright (C) 2013-2021 Genode Labs GmbH - * Copyright (C) 2021 gapfruit AG - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _I2C_DRIVER__INTERFACE_H_ -#define _I2C_DRIVER__INTERFACE_H_ - -/* Genode includes */ -#include -#include -#include - -namespace I2c { - using namespace Genode; - using Device_name = String<64>; - class Driver_base; -} - - -/** - * Base class for platform specific driver to implement - * - * Note about the endianess: the driver is transparent. - * - * The driver read/write bytes to memory in the order they are - * read/write to the bus. - * It is the responsability of the component interacting with - * a slave device on the bus to figure out how to interpret the data. - */ -struct I2c::Driver_base : Interface -{ - class Bad_bus_no: Exception {}; - - /** - * Transaction on the I2C bus - * - * \param address device address - * \param t transaction to perform - * - * \throw I2c::Session::Bus_error An error occure while performing an operation on the bus - */ - virtual void transmit(uint8_t address, I2c::Session::Transaction & t) = 0; - - /** - * Driver name getter - * - * \return Driver name string - * - * Details this method is overridable to customise the name based on the platform. - */ - virtual char const *name() const { return "i2c driver"; } -}; - -#endif /* _I2C_INTERFACE_H_ */ diff --git a/repos/os/src/driver/i2c/imx8q_evk/driver.cc b/repos/os/src/driver/i2c/imx8q_evk/driver.cc deleted file mode 100644 index bc324e6ca2..0000000000 --- a/repos/os/src/driver/i2c/imx8q_evk/driver.cc +++ /dev/null @@ -1,194 +0,0 @@ -/* - * \brief Platform specific I2C's driver for imx8q_evk - * \author Jean-Adrien Domage - * \author Stefan Kalkowski - * \date 2021-02-08 - */ - -/* - * Copyright (C) 2013-2021 Genode Labs GmbH - * Copyright (C) 2021 gapfruit AG - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#include -#include "driver.h" - - -namespace { - - Genode::uint8_t _bus_speed_to_divider(Genode::uint16_t bus_speed_khz) - { - /* the table can be found: - * IMX8MMRM.pdf on 5233 - * - * The bus base frequency is 25MHz. - */ - - if (bus_speed_khz >= 400) return 0x2a; /* divide by 64 maximal speed supported */ - if (bus_speed_khz >= 200) return 0x2f; /* divide by 128 */ - if (bus_speed_khz >= 100) return 0x33; /* divide by 256 */ - if (bus_speed_khz >= 50) return 0x37; /* divide by 512 */ - if (bus_speed_khz >= 25) return 0x3B; /* divide by 1024 */ - - return 0x3F; /* divide by 2048 minimal speed */ - } -} - - -void I2c::Driver::_wait_for_irq() -{ - _sem_cnt++; - while (_sem_cnt > 0) - _env.ep().wait_and_dispatch_one_io_signal(); - - if (_mmio.read() == 0) { - _bus_stop(); - if (_args.verbose) { - error("Arbitration lost on bus ", _args.bus_no); - } - throw I2c::Session::Bus_error(); - } -} - - -void I2c::Driver::_bus_busy() -{ - uint64_t const start_time = _timer.elapsed_ms(); - while (!_mmio.read()) { - uint64_t const current = _timer.elapsed_ms(); - if (current - start_time > 1000) { - _bus_stop(); - if (_args.verbose) { - error("Timeout on bus ", _args.bus_no); - } - throw I2c::Session::Bus_error(); - } - } -} - - -void I2c::Driver::_bus_reset() -{ - _mmio.write(0); - _mmio.write(0); -} - - -void I2c::Driver::_bus_start() -{ - /* input root 90 is 25Mhz select divisor to approximate desired bus speed */ - _mmio.write(_bus_speed_to_divider(_args.bus_speed_khz)); - _mmio.write(0); - _mmio.write(Mmio::Control::Enable::bits(1)); - - uint64_t const start_time = _timer.elapsed_ms(); - while (!_mmio.read()) { - uint64_t const current = _timer.elapsed_ms(); - if (current - start_time > 1000) { - _bus_stop(); - if (_args.verbose) { - error("Timeout on bus ", _args.bus_no); - } - throw I2c::Session::Bus_error(); - } - } - - _mmio.write(1); - - _bus_busy(); - - _mmio.write(Mmio::Control::Tx_rx_select::bits(1) | - Mmio::Control::Tx_ack_enable::bits(1) | - Mmio::Control::Irq_enable::bits(1) | - Mmio::Control::Master_slave_select::bits(1) | - Mmio::Control::Enable::bits(1)); - - _mmio.write(0); -} - - -void I2c::Driver::_bus_stop() -{ - _mmio.write(0); -} - - -void I2c::Driver::_bus_write(uint8_t data) -{ - _mmio.write(data); - - do { _wait_for_irq(); } - while (!_mmio.read()); - - _mmio.write(0); - _irq.ack(); - - if (_mmio.read()) { - _bus_stop(); - if (_args.verbose) { - error("Slave did not acknowledge on bus ", _args.bus_no); - } - throw I2c::Session::Bus_error(); - } -} - - -void I2c::Driver::_write(uint8_t address, I2c::Session::Message & m) -{ - /* LSB must be 0 for writing on the bus, address is on the 7 hightest bits */ - _bus_write(address << 1); - m.for_each([&] (unsigned, uint8_t & byte) { _bus_write(byte); }); -} - - -void I2c::Driver::_read(uint8_t address, I2c::Session::Message & m) -{ - /* LSB must be 1 for reading on the bus, address is on the 7 hightest bits */ - _bus_write((uint8_t)(address << 1 | 1)); - - _mmio.write(0); - if (m.count() > 1) { - _mmio.write(0); - } - _mmio.read(); - - m.for_each([&] (unsigned idx, uint8_t & byte) { - - do { _wait_for_irq(); } - while (!_mmio.read()); - - _mmio.write(0); - - if (idx == m.count() - 1) { - _mmio.write(0); - _mmio.write(0); - while (_mmio.read()); - } else if (idx == m.count() - 2) { - _mmio.write(1); - } - - byte = (uint8_t)_mmio.read(); - _irq.ack(); - }); -} - - -void I2c::Driver::transmit(uint8_t address, I2c::Session::Transaction & t) -{ - _bus_start(); - - t.for_each([&] (unsigned idx, I2c::Session::Message & m) { - if (idx > 0) { - _mmio.write(1); - _bus_busy(); - } - - if (m.type == I2c::Session::Message::READ) { _read(address, m); - } else { _write(address, m); } - }); - - _bus_stop(); -} diff --git a/repos/os/src/driver/i2c/imx8q_evk/driver.h b/repos/os/src/driver/i2c/imx8q_evk/driver.h deleted file mode 100644 index 169de0fb8f..0000000000 --- a/repos/os/src/driver/i2c/imx8q_evk/driver.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * \brief Platform specific I2C's driver for imx8q_evk - * \author Jean-Adrien Domage - * \date 2021-02-08 - */ - -/* - * Copyright (C) 2013-2021 Genode Labs GmbH - * Copyright (C) 2021 gapfruit AG - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _I2C_DRIVER__IMX8Q_EVK_H_ -#define _I2C_DRIVER__IMX8Q_EVK_H_ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include - -/* Local include */ -#include -#include "mmio.h" - -namespace I2c { - using namespace Genode; - class Driver; -} - - -class I2c::Driver: public I2c::Driver_base -{ - public: - - struct Args - { - bool verbose; - unsigned bus_no; - Device_name device_name; - uint16_t bus_speed_khz; - }; - - private: - - Env &_env; - Args const _args; - - Platform::Connection _platform { _env }; - Platform::Device _device { _platform }; - I2c::Mmio _mmio { _device }; - Platform::Device::Irq _irq { _device }; - Io_signal_handler _irq_handler; - - unsigned _sem_cnt = 1; - Timer::Connection _timer { _env }; - - void _bus_reset(); - void _bus_start(); - void _bus_stop(); - void _bus_write(Genode::uint8_t data); - void _bus_busy(); - - void _wait_for_irq(); - void _irq_handle() { _sem_cnt = 0; } - - void _write(uint8_t, I2c::Session::Message&); - void _read(uint8_t, I2c::Session::Message&); - - public: - - Driver(Env &env, Args const &args) - : - _env(env), _args(args), - _irq_handler(_env.ep(), *this, &Driver::_irq_handle) - { - _irq.sigh(_irq_handler); - _irq_handle(); - _irq.ack(); - _bus_reset(); - } - - void transmit(uint8_t address, I2c::Session::Transaction & t) override; -}; - -#endif /* _I2C_DRIVER__IMX8Q_EVK_H_ */ diff --git a/repos/os/src/driver/i2c/imx8q_evk/mmio.h b/repos/os/src/driver/i2c/imx8q_evk/mmio.h deleted file mode 100644 index a807446e51..0000000000 --- a/repos/os/src/driver/i2c/imx8q_evk/mmio.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * \brief I2C mmio region for platform imx8q_evk - * \author Jean-Adrien Domage - * \date 2021-02-08 - */ - -/* - * Copyright (C) 2013-2021 Genode Labs GmbH - * Copyright (C) 2021 gapfruit AG - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#ifndef _I2C_MMIO_H_ -#define _I2C_MMIO_H_ - -#include - -namespace I2c { struct Mmio; } - - -struct I2c::Mmio: Platform::Device::Mmio<0x12> -{ - struct Address : Mmio::Register<0x0, 16> { - struct Adr : Mmio::Register<0x0, 16>::Bitfield<1, 7> {}; - }; - - struct Freq_divider : Mmio::Register<0x4, 16> {}; - - struct Control : Mmio::Register<0x8, 16> { - struct Repeat_start : Mmio::Register<0x8, 16>::Bitfield<2, 1> {}; - struct Tx_ack_enable : Mmio::Register<0x8, 16>::Bitfield<3, 1> {}; - struct Tx_rx_select : Mmio::Register<0x8, 16>::Bitfield<4, 1> {}; - struct Master_slave_select : Mmio::Register<0x8, 16>::Bitfield<5, 1> {}; - struct Irq_enable : Mmio::Register<0x8, 16>::Bitfield<6, 1> {}; - struct Enable : Mmio::Register<0x8, 16>::Bitfield<7, 1> {}; - }; - - struct Status : Mmio::Register<0x0C, 16> { - struct Rcv_ack : Mmio::Register<0x0C, 16>::Bitfield<0, 1> {}; - struct Irq : Mmio::Register<0x0C, 16>::Bitfield<1, 1> {}; - struct Srw : Mmio::Register<0x0C, 16>::Bitfield<2, 1> {}; - struct Ial : Mmio::Register<0x0C, 16>::Bitfield<4, 1> {}; - struct Busy : Mmio::Register<0x0C, 16>::Bitfield<5, 1> {}; - struct Iaas : Mmio::Register<0x0C, 16>::Bitfield<6, 1> {}; - struct Icf : Mmio::Register<0x0C, 16>::Bitfield<7, 1> {}; - }; - - struct Data : Mmio::Register<0x10, 16> {}; - - Mmio(Platform::Device &device) : Platform::Device::Mmio { device } { } -}; - -#endif /* _I2C_MMIO_H_ */ diff --git a/repos/os/src/driver/i2c/imx8q_evk/target.mk b/repos/os/src/driver/i2c/imx8q_evk/target.mk deleted file mode 100644 index ebef37b4a3..0000000000 --- a/repos/os/src/driver/i2c/imx8q_evk/target.mk +++ /dev/null @@ -1,9 +0,0 @@ -TARGET = imx8q_evk_i2c - -REQUIRES = arm_v8 - -SRC_CC += driver.cc - -INC_DIR += $(PRG_DIR)/src/driver/i2c/imx8q_evk - -include $(REP_DIR)/src/driver/i2c/target.inc diff --git a/repos/os/src/driver/i2c/main.cc b/repos/os/src/driver/i2c/main.cc deleted file mode 100644 index b855dc10c8..0000000000 --- a/repos/os/src/driver/i2c/main.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * \brief I2C driver main - * \author Jean-Adrien Domage - * \date 2021-02-08 - */ - -/* - * Copyright (C) 2013-2021 Genode Labs GmbH - * Copyright (C) 2021 gapfruit AG - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include - -/* Local includes */ -#include "component.h" -#include "driver.h" - -namespace I2c { struct Main; } - - -struct I2c::Main -{ - private: - - Env &_env; - Sliced_heap _sliced_heap { _env.ram(), _env.rm() }; - - Attached_rom_dataspace _config { _env, "config" }; - - static I2c::Driver::Args _driver_args_from_config(Xml_node config) - { - constexpr uint16_t const default_bus_speed_khz { 400 }; - return { - .verbose = config.attribute_value("verbose", false), - .bus_no = config.attribute_value("bus_no", 0u), - .device_name = config.attribute_value("device_name", Device_name()), - .bus_speed_khz = config.attribute_value("bus_speed_khz", default_bus_speed_khz) - }; - } - - I2c::Driver _driver { _env, _driver_args_from_config(_config.xml()) }; - I2c::Root _root { _env.ep().rpc_ep(), _sliced_heap, - _driver, _config.xml() }; - - public: - - Main(Env &env) : _env(env) - { - _env.parent().announce(env.ep().manage(_root)); - - log(_driver.name(), " started"); - } -}; - - -void Component::construct(Genode::Env &env) { static I2c::Main main(env); } diff --git a/repos/os/src/driver/i2c/target.inc b/repos/os/src/driver/i2c/target.inc deleted file mode 100644 index fd1839cab0..0000000000 --- a/repos/os/src/driver/i2c/target.inc +++ /dev/null @@ -1,9 +0,0 @@ -LIBS += base - -INC_DIR += $(PRG_DIR) -INC_DIR += $(REP_DIR)/src/driver/i2c - -SRC_CC += main.cc - -vpath %.cc $(REP_DIR)/src/driver/i2c -vpath %.cc $(REP_DIR)