GPIO refactored (#495)
* **Refactor** * GPIO subsystem moved to a descriptor-based model for per-pin ownership and runtime pin management; many platform drivers now acquire/release descriptors. * Device trees and drivers now use GPIO phandle-style pin specifications across all boards and all drivers. * **Behavior** * Device list now encodes per-device status (ok/disabled); boot will skip disabled devices accordingly. * **Deprecation** * Legacy GPIO HAL marked deprecated and replaced with descriptor-based interfaces. * **Chores** * Bindings and platform configs updated to the new GPIO pin-spec format.
This commit is contained in:
committed by
GitHub
parent
dff93cb655
commit
26c17986c6
@@ -43,16 +43,6 @@ struct Device {
|
||||
struct DeviceInternal* internal;
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds a device pointer and a compatible string.
|
||||
* The device must not be constructed, added or started yet.
|
||||
* This is used by the devicetree code generator and the application init sequence.
|
||||
*/
|
||||
struct CompatibleDevice {
|
||||
struct Device* device;
|
||||
const char* compatible;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the properties of a device.
|
||||
*
|
||||
|
||||
@@ -10,24 +10,24 @@ extern "C" {
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define GPIO_OPTIONS_MASK 0x1f
|
||||
|
||||
#define GPIO_ACTIVE_HIGH (0 << 0)
|
||||
#define GPIO_ACTIVE_LOW (1 << 0)
|
||||
|
||||
#define GPIO_DIRECTION_INPUT (1 << 1)
|
||||
#define GPIO_DIRECTION_OUTPUT (1 << 2)
|
||||
#define GPIO_DIRECTION_INPUT_OUTPUT (GPIO_DIRECTION_INPUT | GPIO_DIRECTION_OUTPUT)
|
||||
|
||||
#define GPIO_PULL_UP (0 << 3)
|
||||
#define GPIO_PULL_DOWN (1 << 4)
|
||||
|
||||
#define GPIO_INTERRUPT_BITMASK (0b111 << 5) // 3 bits to hold the values [0, 5]
|
||||
#define GPIO_INTERRUPT_FROM_OPTIONS(options) (gpio_int_type_t)((options & GPIO_INTERRUPT_BITMASK) >> 5)
|
||||
#define GPIO_INTERRUPT_TO_OPTIONS(options, interrupt) (options | (interrupt << 5))
|
||||
#define GPIO_FLAGS_MASK 0x1f
|
||||
|
||||
#define GPIO_PIN_NONE -1
|
||||
|
||||
#define GPIO_PIN_SPEC_NONE ((struct GpioPinSpec) { NULL, 0, GPIO_FLAG_NONE })
|
||||
|
||||
#define GPIO_FLAG_NONE 0
|
||||
#define GPIO_FLAG_ACTIVE_HIGH (0 << 0)
|
||||
#define GPIO_FLAG_ACTIVE_LOW (1 << 0)
|
||||
#define GPIO_FLAG_DIRECTION_INPUT (1 << 1)
|
||||
#define GPIO_FLAG_DIRECTION_OUTPUT (1 << 2)
|
||||
#define GPIO_FLAG_DIRECTION_INPUT_OUTPUT (GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_DIRECTION_OUTPUT)
|
||||
#define GPIO_FLAG_PULL_UP (0 << 3)
|
||||
#define GPIO_FLAG_PULL_DOWN (1 << 4)
|
||||
#define GPIO_FLAG_INTERRUPT_BITMASK (0b111 << 5) // 3 bits to hold the values [0, 5]
|
||||
#define GPIO_FLAG_INTERRUPT_FROM_OPTIONS(options) (gpio_int_type_t)((options & GPIO_FLAG_INTERRUPT_BITMASK) >> 5)
|
||||
#define GPIO_FLAG_INTERRUPT_TO_OPTIONS(options, interrupt) (options | (interrupt << 5))
|
||||
|
||||
typedef enum {
|
||||
GPIO_INTERRUPT_DISABLE = 0,
|
||||
GPIO_INTERRUPT_POS_EDGE = 1,
|
||||
@@ -35,35 +35,39 @@ typedef enum {
|
||||
GPIO_INTERRUPT_ANY_EDGE = 3,
|
||||
GPIO_INTERRUPT_LOW_LEVEL = 4,
|
||||
GPIO_INTERRUPT_HIGH_LEVEL = 5,
|
||||
GPIO__MAX,
|
||||
GPIO_MAX,
|
||||
} GpioInterruptType;
|
||||
|
||||
enum GpioOwnerType {
|
||||
/** @brief Pin is unclaimed/free */
|
||||
GPIO_OWNER_NONE,
|
||||
/** @brief Pin is owned by a hog */
|
||||
GPIO_OWNER_HOG,
|
||||
/** @brief Pin is claimed by a regular consumer */
|
||||
GPIO_OWNER_GPIO,
|
||||
/** @brief Pin is owned by SPI. This is a special case because of CS pin transfer from hog to SPI controller. */
|
||||
GPIO_OWNER_SPI
|
||||
};
|
||||
|
||||
/** The index of a GPIO pin on a GPIO Controller */
|
||||
typedef uint8_t gpio_pin_t;
|
||||
|
||||
/** Specifies the configuration flags for a GPIO pin (or set of pins) */
|
||||
typedef uint16_t gpio_flags_t;
|
||||
|
||||
/** A configuration for a single GPIO pin */
|
||||
struct GpioPinConfig {
|
||||
/**
|
||||
* Specifies a pin and its properties for a specific GPIO controller.
|
||||
* Used by the devicetree, drivers and application code to refer to GPIO pins and acquire them via the gpio_controller API.
|
||||
*/
|
||||
struct GpioPinSpec {
|
||||
/** GPIO device controlling the pin */
|
||||
const struct Device* port;
|
||||
struct Device* gpio_controller;
|
||||
/** The pin's number on the device */
|
||||
gpio_pin_t pin;
|
||||
/** The pin's configuration flags as specified in devicetree */
|
||||
gpio_flags_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the pin is ready to be used.
|
||||
*
|
||||
* @param pinConfig the specifications of the pin
|
||||
* @return true if the pin is ready to be used
|
||||
*/
|
||||
static inline bool gpio_is_ready(const struct GpioPinConfig* pinConfig) {
|
||||
return device_is_ready(pinConfig->port);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -10,106 +10,136 @@ extern "C" {
|
||||
#include <tactility/error.h>
|
||||
|
||||
struct Device;
|
||||
struct GpioDescriptor;
|
||||
|
||||
struct GpioControllerApi {
|
||||
/**
|
||||
* @brief Sets the logical level of a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[in,out] descriptor the pin descriptor
|
||||
* @param[in] high true to set the pin high, false to set it low
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t (*set_level)(struct Device* device, gpio_pin_t pin, bool high);
|
||||
error_t (*set_level)(struct GpioDescriptor* descriptor, bool high);
|
||||
|
||||
/**
|
||||
* @brief Gets the logical level of a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] high pointer to store the pin level
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t (*get_level)(struct Device* device, gpio_pin_t pin, bool* high);
|
||||
error_t (*get_level)(struct GpioDescriptor* descriptor, bool* high);
|
||||
|
||||
/**
|
||||
* @brief Configures the options for a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[in] options configuration flags (direction, pull-up/down, etc.)
|
||||
* @param[in,out] descriptor the pin descriptor
|
||||
* @param[in] flags configuration flags (direction, pull-up/down, etc.)
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t (*set_options)(struct Device* device, gpio_pin_t pin, gpio_flags_t options);
|
||||
error_t (*set_flags)(struct GpioDescriptor* descriptor, gpio_flags_t flags);
|
||||
|
||||
/**
|
||||
* @brief Gets the configuration options for a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[out] options pointer to store the configuration flags
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] flags pointer to store the configuration flags
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t (*get_options)(struct Device* device, gpio_pin_t pin, gpio_flags_t* options);
|
||||
error_t (*get_flags)(struct GpioDescriptor* descriptor, gpio_flags_t* flags);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of pins supported by the controller.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[out] count pointer to store the number of pins
|
||||
* @brief Gets the native pin number associated with a descriptor.
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] pin_number pointer to store the pin number
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t (*get_pin_count)(struct Device* device, uint32_t* count);
|
||||
error_t (*get_native_pin_number)(struct GpioDescriptor* descriptor, void* pin_number);
|
||||
};
|
||||
|
||||
struct GpioDescriptor* gpio_descriptor_acquire(
|
||||
struct Device* controller,
|
||||
gpio_pin_t pin_number,
|
||||
enum GpioOwnerType owner
|
||||
);
|
||||
|
||||
error_t gpio_descriptor_release(struct GpioDescriptor* descriptor);
|
||||
|
||||
/**
|
||||
* @brief Gets the pin number associated with a descriptor.
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] pin pointer to store the pin number
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_descriptor_get_pin_number(struct GpioDescriptor* descriptor, gpio_pin_t* pin);
|
||||
|
||||
/**
|
||||
* @brief Gets the pin owner type associated with a descriptor.
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] owner_type pointer to output owner type
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_descriptor_get_owner_type(struct GpioDescriptor* descriptor, enum GpioOwnerType* owner_type);
|
||||
|
||||
/**
|
||||
* @brief Sets the logical level of a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[in] high true to set the pin high, false to set it low
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_controller_set_level(struct Device* device, gpio_pin_t pin, bool high);
|
||||
error_t gpio_descriptor_set_level(struct GpioDescriptor* descriptor, bool high);
|
||||
|
||||
/**
|
||||
* @brief Gets the logical level of a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] high pointer to store the pin level
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_controller_get_level(struct Device* device, gpio_pin_t pin, bool* high);
|
||||
error_t gpio_descriptor_get_level(struct GpioDescriptor* descriptor, bool* high);
|
||||
|
||||
/**
|
||||
* @brief Configures the options for a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[in] options configuration flags (direction, pull-up/down, etc.)
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[in] flags configuration flags (direction, pull-up/down, etc.)
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_controller_set_options(struct Device* device, gpio_pin_t pin, gpio_flags_t options);
|
||||
error_t gpio_descriptor_set_flags(struct GpioDescriptor* descriptor, gpio_flags_t flags);
|
||||
|
||||
/**
|
||||
* @brief Gets the configuration options for a GPIO pin.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] pin the pin index
|
||||
* @param[out] options pointer to store the configuration flags
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] flags pointer to store the configuration flags
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_controller_get_options(struct Device* device, gpio_pin_t pin, gpio_flags_t* options);
|
||||
error_t gpio_descriptor_get_flags(struct GpioDescriptor* descriptor, gpio_flags_t* flags);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of pins supported by the controller.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[out] count pointer to store the number of pins
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
* @brief Gets the native pin number associated with a descriptor.
|
||||
* @param[in] descriptor the pin descriptor
|
||||
* @param[out] pin_number pointer to store the pin number
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_descriptor_get_native_pin_number(struct GpioDescriptor* descriptor, void* pin_number);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of pins supported by the controller.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[out] count pointer to store the number of pins
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_controller_get_pin_count(struct Device* device, uint32_t* count);
|
||||
|
||||
/**
|
||||
* @brief Configures the options for a GPIO pin using a pin configuration structure.
|
||||
* @param[in] device the GPIO controller device
|
||||
* @param[in] config the pin configuration structure
|
||||
* @brief Initializes GPIO descriptors for a controller.
|
||||
* @param[in,out] device the GPIO controller device
|
||||
* @param[in] controller_context pointer to store in the controller's internal data
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
static inline error_t gpio_set_options_config(struct Device* device, const struct GpioPinConfig* config) {
|
||||
return gpio_controller_set_options(device, config->pin, config->flags);
|
||||
}
|
||||
error_t gpio_controller_init_descriptors(struct Device* device, uint32_t pin_count, void* controller_context);
|
||||
|
||||
/**
|
||||
* @brief Deinitializes GPIO descriptors for a controller.
|
||||
* @param[in,out] device the GPIO controller device
|
||||
* @return ERROR_NONE if successful
|
||||
*/
|
||||
error_t gpio_controller_deinit_descriptors(struct Device* device);
|
||||
|
||||
extern const struct DeviceType GPIO_CONTROLLER_TYPE;
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
struct Device;
|
||||
|
||||
struct GpioDescriptor {
|
||||
/** @brief The controller that owns this pin */
|
||||
struct Device* controller;
|
||||
/** @brief Physical pin number */
|
||||
gpio_pin_t pin;
|
||||
/** @brief Current owner */
|
||||
enum GpioOwnerType owner_type;
|
||||
/** @brief Implementation-specific context (e.g. from esp32 controller internally) */
|
||||
void* controller_context;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct Device;
|
||||
|
||||
/** Signals the intended state of a device. */
|
||||
enum DtsDeviceStatus {
|
||||
/** Device should be constructed, added and started. */
|
||||
DTS_DEVICE_STATUS_OKAY,
|
||||
/** Device should be constructed and added, but not started. */
|
||||
DTS_DEVICE_STATUS_DISABLED
|
||||
};
|
||||
|
||||
/**
|
||||
* Holds a device pointer and a compatible string.
|
||||
* The device must not be constructed, added or started yet.
|
||||
* This is used by the devicetree code generator and the application init sequence.
|
||||
*/
|
||||
struct DtsDevice {
|
||||
/** A pointer to a device. */
|
||||
struct Device* device;
|
||||
/** The compatible string contains the identifier of the driver that this device is compatible with. */
|
||||
const char* compatible;
|
||||
/** The intended state of the device. */
|
||||
const enum DtsDeviceStatus status;
|
||||
};
|
||||
|
||||
/** Signals the end of the device array in the generated dts code. */
|
||||
#define DTS_DEVICE_TERMINATOR { NULL, NULL, DTS_DEVICE_STATUS_DISABLED }
|
||||
@@ -12,10 +12,10 @@ extern "C" {
|
||||
* Initialize the kernel with platform and device modules, and a device tree.
|
||||
* @param platform_module The platform module to start. This module should not be constructed yet.
|
||||
* @param device_module The device module to start. This module should not be constructed yet. This parameter can be NULL.
|
||||
* @param devicetree_devices The list of generated devices from the devicetree. The array must be terminated by an entry { NULL, NULL }. This parameter can be NULL.
|
||||
* @param dts_devices The list of generated devices from the devicetree. The array must be terminated with DTS_DEVICE_TERMINATOR. This parameter can be NULL.
|
||||
* @return ERROR_NONE on success, otherwise an error code
|
||||
*/
|
||||
error_t kernel_init(struct Module* platform_module, struct Module* device_module, struct CompatibleDevice devicetree_devices[]);
|
||||
error_t kernel_init(struct Module* platform_module, struct Module* device_module, struct DtsDevice dts_devices[]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -3,33 +3,136 @@
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/drivers/gpio_controller.h>
|
||||
|
||||
#define GPIO_DRIVER_API(driver) ((struct GpioControllerApi*)driver->api)
|
||||
#include <tactility/concurrent/mutex.h>
|
||||
#include <tactility/drivers/gpio_descriptor.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
#define GPIO_INTERNAL_API(driver) ((struct GpioControllerApi*)(driver)->api)
|
||||
|
||||
extern "C" {
|
||||
|
||||
error_t gpio_controller_set_level(Device* device, gpio_pin_t pin, bool high) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GPIO_DRIVER_API(driver)->set_level(device, pin, high);
|
||||
struct GpioControllerData {
|
||||
struct Mutex mutex {};
|
||||
uint32_t pin_count;
|
||||
struct GpioDescriptor* descriptors = nullptr;
|
||||
|
||||
explicit GpioControllerData(uint32_t pin_count) : pin_count(pin_count) {
|
||||
mutex_construct(&mutex);
|
||||
}
|
||||
|
||||
error_t init_descriptors(Device* device, void* controller_context) {
|
||||
descriptors = (struct GpioDescriptor*)calloc(pin_count, sizeof(struct GpioDescriptor));
|
||||
if (!descriptors) return ERROR_OUT_OF_MEMORY;
|
||||
for (uint32_t i = 0; i < pin_count; ++i) {
|
||||
descriptors[i].controller = device;
|
||||
descriptors[i].pin = (gpio_pin_t)i;
|
||||
descriptors[i].owner_type = GPIO_OWNER_NONE;
|
||||
descriptors[i].controller_context = controller_context;
|
||||
}
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
~GpioControllerData() {
|
||||
if (descriptors != nullptr) {
|
||||
free(descriptors);
|
||||
}
|
||||
mutex_destruct(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
struct GpioDescriptor* gpio_descriptor_acquire(
|
||||
struct Device* controller,
|
||||
gpio_pin_t pin_number,
|
||||
enum GpioOwnerType owner
|
||||
) {
|
||||
check(owner != GPIO_OWNER_NONE);
|
||||
|
||||
auto* data = (struct GpioControllerData*)device_get_driver_data(controller);
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
if (pin_number >= data->pin_count) {
|
||||
mutex_unlock(&data->mutex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct GpioDescriptor* desc = &data->descriptors[pin_number];
|
||||
if (desc->owner_type != GPIO_OWNER_NONE) {
|
||||
mutex_unlock(&data->mutex);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
desc->owner_type = owner;
|
||||
mutex_unlock(&data->mutex);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
error_t gpio_controller_get_level(Device* device, gpio_pin_t pin, bool* high) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GPIO_DRIVER_API(driver)->get_level(device, pin, high);
|
||||
}
|
||||
|
||||
error_t gpio_controller_set_options(Device* device, gpio_pin_t pin, gpio_flags_t options) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GPIO_DRIVER_API(driver)->set_options(device, pin, options);
|
||||
}
|
||||
|
||||
error_t gpio_controller_get_options(Device* device, gpio_pin_t pin, gpio_flags_t* options) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GPIO_DRIVER_API(driver)->get_options(device, pin, options);
|
||||
error_t gpio_descriptor_release(struct GpioDescriptor* descriptor) {
|
||||
descriptor->owner_type = GPIO_OWNER_NONE;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t gpio_controller_get_pin_count(struct Device* device, uint32_t* count) {
|
||||
const auto* driver = device_get_driver(device);
|
||||
return GPIO_DRIVER_API(driver)->get_pin_count(device, count);
|
||||
auto* data = (struct GpioControllerData*)device_get_driver_data(device);
|
||||
*count = data->pin_count;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t gpio_controller_init_descriptors(struct Device* device, uint32_t pin_count, void* controller_context) {
|
||||
auto* data = new(std::nothrow) GpioControllerData(pin_count);
|
||||
if (!data) return ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (data->init_descriptors(device, controller_context) != ERROR_NONE) {
|
||||
delete data;
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
device_set_driver_data(device, data);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t gpio_controller_deinit_descriptors(struct Device* device) {
|
||||
auto* data = static_cast<struct GpioControllerData*>(device_get_driver_data(device));
|
||||
delete data;
|
||||
device_set_driver_data(device, nullptr);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_set_level(struct GpioDescriptor* descriptor, bool high) {
|
||||
const auto* driver = device_get_driver(descriptor->controller);
|
||||
return GPIO_INTERNAL_API(driver)->set_level(descriptor, high);
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_get_level(struct GpioDescriptor* descriptor, bool* high) {
|
||||
const auto* driver = device_get_driver(descriptor->controller);
|
||||
return GPIO_INTERNAL_API(driver)->get_level(descriptor, high);
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_set_flags(struct GpioDescriptor* descriptor, gpio_flags_t flags) {
|
||||
const auto* driver = device_get_driver(descriptor->controller);
|
||||
return GPIO_INTERNAL_API(driver)->set_flags(descriptor, flags);
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_get_flags(struct GpioDescriptor* descriptor, gpio_flags_t* flags) {
|
||||
const auto* driver = device_get_driver(descriptor->controller);
|
||||
return GPIO_INTERNAL_API(driver)->get_flags(descriptor, flags);
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_get_pin_number(struct GpioDescriptor* descriptor, gpio_pin_t* pin) {
|
||||
*pin = descriptor->pin;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_get_native_pin_number(struct GpioDescriptor* descriptor, void* pin_number) {
|
||||
const auto* driver = device_get_driver(descriptor->controller);
|
||||
return GPIO_INTERNAL_API(driver)->get_native_pin_number(descriptor, pin_number);
|
||||
}
|
||||
|
||||
error_t gpio_descriptor_get_owner_type(struct GpioDescriptor* descriptor, GpioOwnerType* owner_type) {
|
||||
*owner_type = descriptor->owner_type;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
const struct DeviceType GPIO_CONTROLLER_TYPE {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "tactility/dts.h"
|
||||
#include <tactility/kernel_init.h>
|
||||
#include <tactility/log.h>
|
||||
|
||||
@@ -27,7 +28,7 @@ struct Module root_module = {
|
||||
.internal = nullptr
|
||||
};
|
||||
|
||||
error_t kernel_init(struct Module* platform_module, struct Module* device_module, struct CompatibleDevice devicetree_devices[]) {
|
||||
error_t kernel_init(struct Module* platform_module, struct Module* device_module, struct DtsDevice dts_devices[]) {
|
||||
LOG_I(TAG, "init");
|
||||
|
||||
if (module_construct_add_start(&root_module) != ERROR_NONE) {
|
||||
@@ -47,14 +48,23 @@ error_t kernel_init(struct Module* platform_module, struct Module* device_module
|
||||
}
|
||||
}
|
||||
|
||||
if (devicetree_devices) {
|
||||
CompatibleDevice* compatible_device = devicetree_devices;
|
||||
while (compatible_device->device != nullptr) {
|
||||
if (device_construct_add_start(compatible_device->device, compatible_device->compatible) != ERROR_NONE) {
|
||||
LOG_E(TAG, "kernel_init failed to construct device: %s (%s)", compatible_device->device->name, compatible_device->compatible);
|
||||
return ERROR_RESOURCE;
|
||||
if (dts_devices) {
|
||||
DtsDevice* dts_device = dts_devices;
|
||||
while (dts_device->device != nullptr) {
|
||||
if (dts_device->status == DTS_DEVICE_STATUS_OKAY) {
|
||||
if (device_construct_add_start(dts_device->device, dts_device->compatible) != ERROR_NONE) {
|
||||
LOG_E(TAG, "kernel_init failed to construct+add+start device: %s (%s)", dts_device->device->name, dts_device->compatible);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
} else if (dts_device->status == DTS_DEVICE_STATUS_DISABLED) {
|
||||
if (device_construct_add(dts_device->device, dts_device->compatible) != ERROR_NONE) {
|
||||
LOG_E(TAG, "kernel_init failed to construct+add device: %s (%s)", dts_device->device->name, dts_device->compatible);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
} else {
|
||||
check(false, "DTS status not implemented");
|
||||
}
|
||||
compatible_device++;
|
||||
dts_device++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,11 +59,18 @@ const struct ModuleSymbol KERNEL_SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(driver_find_compatible),
|
||||
DEFINE_MODULE_SYMBOL(driver_get_device_type),
|
||||
// drivers/gpio_controller
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_set_level),
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_get_level),
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_set_options),
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_get_options),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_acquire),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_release),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_set_level),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_level),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_set_flags),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_flags),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_native_pin_number),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_pin_number),
|
||||
DEFINE_MODULE_SYMBOL(gpio_descriptor_get_owner_type),
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_get_pin_count),
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_init_descriptors),
|
||||
DEFINE_MODULE_SYMBOL(gpio_controller_deinit_descriptors),
|
||||
DEFINE_MODULE_SYMBOL(GPIO_CONTROLLER_TYPE),
|
||||
// drivers/i2c_controller
|
||||
DEFINE_MODULE_SYMBOL(i2c_controller_read),
|
||||
|
||||
Reference in New Issue
Block a user