#ifndef LNXALL_HAL_H
#define LNXALL_HAL_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>

/***************************************************************************/
/*                      Get Device Hardware Info                           */
/***************************************************************************/

enum lnxhal_hwtype {
	LNXHAL_HWTYPE_UNKNOWN      = 0,
	LNXHAL_HWTYPE_RK3568,
	LNXHAL_HWTYPE_RK3568_BAU,
	LNXHAL_HWTYPE_RK3568_XDDL,
	LNXHAL_HWYTPE_IMX6UL_5F8280,
	LNXHAL_HWTYPE_EM1000,
	LNXHAL_HWTYPE_RK3588,
	LNXHAL_HWTYPE_ECU1170,
	LNXHAL_HWTYPE_MOXA_VM1220T,
	LNXHAL_HWTYPE_MA35D1,
};
typedef enum lnxhal_hwtype lnxhal_hw_t;

lnxhal_hw_t lnxhal_hw_gettype(void);

/*
 * get current device name: like `WLOSANY_RK3568'
 *		if devices not support, return `unknown'
 */
const char * lnxhal_hw_getname(lnxhal_hw_t hwt);

#define LNXHAL_HWCAP_POWER_DETECT    0x55AA0001
#define LNXHAL_HWCAP_LED_RUN         0x55AA0002
#define LNXHAL_HWCAP_4G_POWER        0x55AA0004
#define LNXHAL_HWCAP_SSD             0x55AA0008

/*
 * Hardware Capability Set
 *
 * RETURN VALUE
 *  0 on negative
 *  1 when the hardware component `hwc does exists.
 */
int lnxhal_hw_has(int hwc);


/***************************************************************************/
/*                       Set and Get LED State                             */
/***************************************************************************/

/* which led to be control */
#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);
/* only lnxall ems devices support below */
int lnxhal_led_attach_trigger_netdev(int id, const char *netdev);
int lnxhal_led_attach_trigger_cpu(int id);


/***************************************************************************/
/*                        WWAN Module Management                           */
/***************************************************************************/

/*
 * wwan modem power set and get
 *
 * RETURN VALUE
 *	0 if success, -1 when error occurrd, and errno be set
 */
int lnxhal_wwan_set_power(int enable);
int lnxhal_wwan_get_power(void);

/* get the network interface name of 4G such as `usb0' */
int lnxhal_wwan_get_ifname(char *ifname, size_t len);

/* standard num of cardno is 21 bytes */
int lnxhal_wwan_read_ccid(char *cardno, size_t len);


/***************************************************************************/
/*                         CAN Device Info                                 */
/***************************************************************************/

/*
 * get the num and interface-name of can
 *  id: should be in range(1, ...), not zero begin
 *		it determined by the case of devices
 *
 * RETURN VALUE
 *  0 when success, -1 if error occurrd, and errno be set
 */
int lnxhal_can_count(void);

int lnxhal_can_get_ifname(int id, char *iface, size_t len);


/***************************************************************************/
/*                        NETIFACE Devices Info                            */
/***************************************************************************/

typedef enum {
	LNXHAL_INET_WAN		= 0,
	LNXHAL_INET_LAN,
	LNXHAL_INET_WIFI,
} lnxhal_netif_t;

/*
 * count num of WAN and LAN devices
 *	It is determined by the marking of case, not interfaces actually in use
 *
 * RETURN VALUE
 * 0 when success, -1 if error occurrd and set errno
 */
int lnxhal_netif_count(int *nwan, int *nlan);

/*
 * Get device name of WAN, LAN, WIFI
 *@param:
 *	id: 1, 2, 3 ...  if hwt == WIFI, id will be an invalid value
 *
 */
int lnxhal_netif_get_ifname(lnxhal_netif_t hwt, int id, char *ifname, size_t len);


/***************************************************************************/
/*                         Block Device Info                               */
/***************************************************************************/

typedef enum {
	LNXHAL_DISK_ROOT    = 0,
	LNXHAL_DISK_TFCARD,
	LNXHAL_DISK_USBDISK,
	LNXHAL_DISK_SSD,
} lnxhal_disk_t;

struct lnxhal_diskstat {
	uint64_t	total;
	uint64_t	used;
};
typedef struct lnxhal_diskstat 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                            */
/***************************************************************************/

/*
 * RETURN VALUE
 *  lnxhal_rtc_reliable() returns 1 if the rtc is reliable, or 0 indicates not reliable
 *	lnxhal_rtc_get() returns 1 if successfully get time, 0 indicates time not reliable, or -1 if an error occurred
 */
int lnxhal_rtc_reliable(void);

int lnxhal_rtc_get(uint64_t *utc, int *msec);
int lnxhal_rtc_set(uint64_t utc);


/***************************************************************************/
/*                           RS485 Device Info                             */
/***************************************************************************/

int lnxhal_rs485_num_get(void);

/*
 * get the device path of rs485, like `/dev/ttylnx1'
 *
 * RETURN VALUE
 *	0 success, -1 if error occurrd and errno set
 */
int lnxhal_rs485_get_device(int id, char *name, size_t len);


/***************************************************************************/
/*                       Display Devices Interface                         */
/***************************************************************************/

typedef enum {
	LNXHAL_DISP_DSI	= 0,
	LNXHAL_DISP_HDMI,
} lnxhal_display_t;

/*
 * get resolutions of HDMI connected
 *
 * RETURN VALUE
 *  0 if HDMI connected
 *  -1 if device not detected or error occurrd
 *
 * ERROR
 *  ENODEV:  no HDMI device detected
 *  ENOTSUP: device has not been support
 */
int lnxhal_disp_get_mode(lnxhal_display_t hwt, int *width, int *height);

/*
 * set or get the backlight of DSI ... (Current HDMI devices not support)
 *  brightness in range(0, 255)
 *
 * RETURN VALUE
 *	0 if success
 *	-1 when error occurrd, and errno be set
 */
int lnxhal_disp_set_backlight(lnxhal_display_t hwt, int brightness);
int lnxhal_disp_get_backlight(lnxhal_display_t hwt);


/***************************************************************************/
/*                      Detect Whether Power is off                        */
/***************************************************************************/

typedef void * lnxhal_power_detect_t;

lnxhal_power_detect_t lnxhal_powerd_get(lnxhal_hw_t hwt);

/*
 * RETURN VALUE
 *          -1 on error
 *          0 if device has external power on
 *          1 if device has external power off
 */
int lnxhal_powerd_poll(lnxhal_power_detect_t pdet,
	int timeout, int * ispowerdown);

void lnxhal_powerd_put(lnxhal_power_detect_t pdet);


/***************************************************************************/
/*                             GPIO Number Get                             */
/***************************************************************************/

typedef enum {
	LNXHAL_GPIO_RESET,
	LNXHAL_GPIO_RESET_MULTIFUNCTION,
} lnxhal_gpio_t;

/*
 * RETURN VALUE
 *         -1 on error
 *         else return number of gpio
 */
int lnxhal_gpio_num_get(lnxhal_gpio_t gpio);

int lnxhal_gpio_chipline_get(lnxhal_gpio_t gpio, char *chip, size_t chip_len, int *line);


#ifdef __cplusplus
};
#endif
#endif
