/*
 * lnxall_hal.h - public C ABI for lnxhal-rs
 *
 * This header describes the ABI exported by liblnxhal-rs.so.  It is written
 * independently from the legacy C implementation so the public contract matches
 * the Rust driver-core based HAL instead of carrying declarations for
 * unsupported entry points.
 *
 * Numeric enum values and function signatures are ABI.  Keep them stable unless
 * a coordinated ABI break is intended.
 */

#ifndef LNXALL_HAL_H
#define LNXALL_HAL_H 1

#include <stddef.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Hardware identity
 *
 * Names returned by lnxhal_hw_getname() point to static read-only storage owned
 * by the library.  Callers must not free or modify the returned pointer.
 */
typedef enum lnxhal_hwtype {
	LNXHAL_HWTYPE_UNKNOWN		= 0,
	LNXHAL_HWTYPE_RK3568		= 1,	// EMS-1000(S), CC-500, LC-200
	LNXHAL_HWTYPE_RK3568_BAU	= 2,
	LNXHAL_HWTYPE_RK3568_XDDL	= 3,
	LNXHAL_HWYTPE_IMX6UL_5F8280 = 4,	// EMS-500, LC-100
	LNXHAL_HWTYPE_IMX6UL_WL2004 = 5,
	LNXHAL_HWTYPE_EM1000		= 6,
	LNXHAL_HWTYPE_RK3588		= 7,	// EMS-2000(S)
	LNXHAL_HWTYPE_ECU1170		= 8,
	LNXHAL_HWTYPE_MOXA_VM1220T	= 9,
	LNXHAL_HWTYPE_MA35D1		= 10,	// EMS-500X
	LNXHAL_HWTYPE_X86_YENTEK_V3	= 11,
	LNXHAL_HWTYPE_EMS1000E		= 12,
	LNXHAL_HWTYPE_X86_UNO247_V2	= 13,
} lnxhal_hw_t;

lnxhal_hw_t lnxhal_hw_gettype(void);
const char *lnxhal_hw_getname(lnxhal_hw_t hwt);

/*
 * CPU and architecture information
 *
 * Architecture describes the target architecture this library was built for.
 * CPU model describes the SoC family declared by the bound platform driver,
 * not the free-form text exposed by /proc/cpuinfo.
 */
typedef enum {
	LNXHAL_ARCH_UNKNOWN		= 0,
	LNXHAL_ARCH_ARM			= 1,
	LNXHAL_ARCH_AARCH64		= 2,
	LNXHAL_ARCH_X86			= 3,
	LNXHAL_ARCH_X86_64		= 4,
	LNXHAL_ARCH_MIPS		= 5,
	LNXHAL_ARCH_MIPSEL		= 6,
	LNXHAL_ARCH_RISCV64		= 7,
} lnxhal_arch_t;

typedef enum {
	LNXHAL_CPU_UNKNOWN	= 0,
	LNXHAL_CPU_RK3568	= 1,
	LNXHAL_CPU_RK3588	= 2,
	LNXHAL_CPU_IMX6UL	= 3,
	LNXHAL_CPU_AM654	= 4,
	LNXHAL_CPU_MA35D1	= 5,
} lnxhal_cpu_model_t;

typedef struct lnxhal_cpuinfo {
	lnxhal_arch_t arch;
	lnxhal_cpu_model_t model;
	int logical_cpus;
} lnxhal_cpuinfo_t;

/*
 * Return 0 on success and -1 on error.  logical_cpus is 0 when the platform
 * cannot report the visible logical CPU count.
 */
int lnxhal_cpuinfo_get(lnxhal_cpuinfo_t *info);

/*
 * Hardware capability query
 *
 * Capability values are bit flags and may be OR'ed together.  lnxhal_hw_has()
 * returns 1 only when the bound board has every requested capability bit.  The
 * TF card, USB disk, and SSD bits reflect whether their backing device is
 * currently present. A zero mask or a mask containing unknown bits returns 0.
 */
typedef uint64_t lnxhal_hwcap_t;

#define LNXHAL_HWCAP_POWER_DETECT			(1ULL << 0)
#define LNXHAL_HWCAP_LED_TRIGGER_NETDEV		(1ULL << 1)
#define LNXHAL_HWCAP_4G_POWER				(1ULL << 2)
#define LNXHAL_HWCAP_SSD					(1ULL << 3)
#define LNXHAL_HWCAP_RESET_CAUSE			(1ULL << 4)
#define LNXHAL_HWCAP_TFCARD					(1ULL << 5)		// sdisk
#define LNXHAL_HWCAP_USBDISK				(1ULL << 6)

int lnxhal_hw_has(lnxhal_hwcap_t hwc);

/*
 * Reset cause
 *
 * UNKNOWN is a valid successful result when the board driver can read the
 * reset-status source but the value cannot be classified by the portable HAL
 * model.  I/O errors and unsupported boards are reported by the function
 * return value instead.
 */
typedef enum {
	LNXHAL_RESET_CAUSE_UNKNOWN  = 0,
	LNXHAL_RESET_CAUSE_POWER_ON = 1,
	LNXHAL_RESET_CAUSE_SOFTWARE = 2,
	LNXHAL_RESET_CAUSE_WATCHDOG = 3,
} lnxhal_reset_cause_t;

/*
 * Return 0 on success and -1 on error.  On success, cause receives one
 * lnxhal_reset_cause_t value.  On error, callers must ignore cause.
 */
int lnxhal_reset_cause(lnxhal_reset_cause_t *cause);

/*
 * LED control
 *
 * LED identifiers are logical board roles.  A board may expose fewer physical
 * LEDs than the enum reserves; unsupported ids return an error from operations.
 */
#define LNXHAL_LED_ID_RUN          0
#define LNXHAL_LED_ID_WIFI         1
#define LNXHAL_LED_ID_NET          2
#define LNXHAL_LED_ID_RESERVED1    3
#define LNXHAL_LED_ID_RESERVED2    4
#define LNXHAL_LED_ID_RESERVED3    5
#define LNXHAL_LED_ID_RESERVED4    6

int lnxhal_led_set_brightness(int id, int brightness);
int lnxhal_led_get_brightness(int id);
int lnxhal_led_set_blink(int id, int delay);
int lnxhal_led_set_trigger_heartbeat(int id);
int lnxhal_led_attach_trigger_netdev(int id, const char *netdev);
int lnxhal_led_attach_trigger_cpu(int id);

/*
 * User-facing GPIO lookup
 *
 * This is the public GPIO inventory API.  It is separate from the internal GPIO
 * control helper used by HAL drivers.
 */
typedef enum {
	LNXHAL_GPIO_RESET = 0,
	LNXHAL_GPIO_RESET_MULTIFUNCTION = 1,
} lnxhal_gpio_t;

/*
 * Return the legacy Linux GPIO number, or -1 on error.
 */
int lnxhal_gpio_num_get(lnxhal_gpio_t gpio);

/*
 * Return the gpiochip path and line for a logical GPIO.
 *
 * chip_len is the size of chip in bytes and must include space for the trailing
 * NUL byte.  The function returns 0 on success and -1 on error.
 */
int lnxhal_gpio_chipline_get(lnxhal_gpio_t gpio, char *chip, size_t chip_len,
			     int *line);

/*
 * Power-down detection
 *
 * The handle is opaque and owned by the library.  A non-NULL handle returned by
 * lnxhal_powerd_get() must be released exactly once with lnxhal_powerd_put().
 */
typedef void *lnxhal_power_detect_t;

lnxhal_power_detect_t lnxhal_powerd_get(lnxhal_hw_t hwt);

/*
 * Return -1 on error, 0 when external power is present, and 1 when external
 * power is down.  When ispowerdown is non-NULL, it receives the same 0/1 power
 * state on success.
 */
int lnxhal_powerd_poll(lnxhal_power_detect_t pdet, int timeout,
		       int *ispowerdown);

void lnxhal_powerd_put(lnxhal_power_detect_t pdet);

/*
 * Block device information
 *
 * Disk ids are logical board roles, not raw kernel device numbers.  Formatting
 * is destructive and should only be used when the selected logical disk maps to
 * a formatter-supported backing block device.
 */
typedef enum {
	LNXHAL_DISK_ROOT	= 0,
	LNXHAL_DISK_TFCARD	= 1,
	LNXHAL_DISK_USBDISK	= 2,
	LNXHAL_DISK_SSD		= 3,
} lnxhal_disk_t;

typedef struct lnxhal_diskstat {
	uint64_t total;
	uint64_t used;
} lnxhal_diskstat_t;

int lnxhal_disk_stat(lnxhal_disk_t hwt, lnxhal_diskstat_t *stat);
int lnxhal_disk_format(lnxhal_disk_t hwt);

/*
 * RTC clock management
 *
 * lnxhal_rtc_get() returns 1 when a reliable time was read, 0 when the RTC time
 * is not considered reliable, and -1 on error.
 */
int lnxhal_rtc_reliable(void);
int lnxhal_rtc_get(uint64_t *utc, int *msec);
int lnxhal_rtc_set(uint64_t utc);

/*
 * RS485 inventory
 *
 * RS485 ids are 1-based to match the legacy ABI and board labels.
 */
int lnxhal_rs485_num_get(void);

/*
 * name receives a NUL-terminated device path such as "/dev/ttylnx1".  len must
 * include space for the trailing NUL byte.  Returns 0 on success and -1 on
 * error.
 */
int lnxhal_rs485_get_device(int id, char *name, size_t len);

/*
 * WWAN management
 *
 * Power state uses the legacy integer convention: non-zero enables power for
 * set_power(); get_power() returns 0/1 on success or -1 on error.
 */
int lnxhal_wwan_set_power(int enable);
int lnxhal_wwan_get_power(void);

/*
 * ifname receives the WWAN network interface name, for example "usb0".  len
 * must include space for the trailing NUL byte.  Returns 0 on success and -1 on
 * error.
 */
int lnxhal_wwan_get_ifname(char *ifname, size_t len);

/*
 * CAN inventory
 *
 * CAN ids are 1-based to match board labels.  Interface names are resolved from
 * sysfs by the bound platform driver when required.
 */
int lnxhal_can_count(void);
int lnxhal_can_get_ifname(int id, char *iface, size_t len);

/*
 * Network interface inventory
 *
 * WAN and LAN ids are 1-based.  WIFI ignores id in the current ABI because each
 * board exposes at most one logical Wi-Fi interface.
 */
typedef enum {
	LNXHAL_INET_WAN		= 0,
	LNXHAL_INET_LAN		= 1,
	LNXHAL_INET_WIFI	= 2,
} lnxhal_netif_t;

int lnxhal_netif_count(int *nwan, int *nlan);
int lnxhal_netif_get_ifname(lnxhal_netif_t hwt, int id, char *ifname,
			    size_t len);

/*
 * Screen backlight information
 *
 * Connector support is platform-specific.
 */
typedef enum {
	LNXHAL_CONN_MIPI_DSI	= 0,
	LNXHAL_CONN_HDMI		= 1,
	LNXHAL_CONN_DP			= 2,
	LNXHAL_CONN_VGA			= 3,
	LNXHAL_CONN_LVDS		= 4,
} lnxhal_connector_t;

int lnxhal_get_backlight(lnxhal_connector_t conn);
int lnxhal_set_backlight(lnxhal_connector_t conn, int brightness);

#ifdef __cplusplus
}
#endif

#endif /* LNXALL_HAL_H */
