#ifndef _SR_HAL_DEVICE_H
#define _SR_HAL_DEVICE_H

#include "sr_config.h"
#include "sr_stddef.h"
#include "sr_list.h"

#ifdef __cplusplus
extern "C"
{
#endif

#define SR_DEVICE_FLAG_RX_BLOCKING 0x1000
#define SR_DEVICE_FLAG_RX_NON_BLOCKING 0x2000

#define SR_DEVICE_FLAG_TX_BLOCKING 0x4000
#define SR_DEVICE_FLAG_TX_NON_BLOCKING 0x8000

#define SR_DEVICE_NAME(dev) ((dev)->name)

typedef struct SR_DEVICE SR_DEVICE_T;

typedef enum SR_DEVICE_TYPE
{
    SR_DEVICE_TYPE_CHAR = 0,      /* character device. */
    SR_DEVICE_TYPE_BLOCK,         /* block device. */
    SR_DEVICE_TYPE_NETIF,         /* Net interface. */
    SR_DEVICE_TYPE_MTD,           /* Memory device. */
    SR_DEVICE_TYPE_CAN,           /* CAN device. */
    SR_DEVICE_TYPE_RTC,           /* RTC device. */
    SR_DEVICE_TYPE_SOUND,         /* Sound device. */
    SR_DEVICE_TYPE_GRAPHIC,       /* Graphic device. */
    SR_DEVICE_TYPE_I2CBUS,        /* I2C bus device. */
    SR_DEVICE_TYPE_USBDEVICE,     /* USB slave device. */
    SR_DEVICE_TYPE_USBHOST,       /* USB host bus. */
    SR_DEVICE_TYPE_SPIBUS,        /* SPI bus device. */
    SR_DEVICE_TYPE_SPIDEVICE,     /* SPI device. */
    SR_DEVICE_TYPE_SDIO,          /* SDIO bus device. */
    SR_DEVICE_TYPE_PM,            /* PM pseudo device. */
    SR_DEVICE_TYPE_PIPE,          /* Pipe device. */
    SR_DEVICE_TYPE_PORTAL,        /* Portal device. */
    SR_DEVICE_TYPE_CLOCKSOURCE,   /* ClockSource device. */
    SR_DEVICE_TYPE_CLOCKEVENT,    /* ClockEvent device. */
    SR_DEVICE_TYPE_MISCELLANEOUS, /* Miscellaneous device. */
    SR_DEVICE_TYPE_SENSOR,        /* Sensor device. */
    SR_DEVICE_TYPE_TOUCH,         /* Touch device. */
    SR_DEVICE_TYPE_INFRARED,      /* Infrared device. */
    SR_DEVICE_TYPE_WLAN,          /* Wlan device. */
    SR_DEVICE_TYPE_PWM,           /* PWM device. */
    SR_DEVICE_TYPE_ENCODER,       /* Encoder device. */
    SR_DEVICE_TYPE_GENERIC        /* Generic device. */
} SR_DEVICE_TYPE_E;

typedef struct SR_DEVICE_OPS
{
    int (*open)(SR_DEVICE_T *dev);
    int (*close)(SR_DEVICE_T *dev);
    srSSize_t (*read)(SR_DEVICE_T *dev, srOff_t pos, void *buffer, srSize_t size);
    srSSize_t (*write)(SR_DEVICE_T *dev, srOff_t pos, void *buffer, srSize_t size);
    int (*control)(SR_DEVICE_T *dev, int cmd, void *args);
} SR_DEVICE_OPS_T;

struct SR_DEVICE
{
    const char *name;

    SR_DEVICE_TYPE_E type;
    int32_t refCount;

    const SR_DEVICE_OPS_T *ops;

    os_list_node_t list; // 链表
    uint32_t oflags;     // 打开标志，open函数传入的

    void *deviceData;   // 子类设备私有数据
    void *deviceConfig; // 子类设备的私有配置
};

int SR_DeviceRegister(SR_DEVICE_T *dev, const char *name);
SR_DEVICE_T *SR_DeviceFind(const char *name);
int SR_DeviceOpen(SR_DEVICE_T *dev);
int SR_DeviceClose(SR_DEVICE_T *dev);
srSSize_t SR_DeviceRead(SR_DEVICE_T *dev, srOff_t pos, void *buffer, srSize_t size);
srSSize_t SR_DeviceWrite(SR_DEVICE_T *dev, srOff_t pos, void *buffer, srSize_t size);
int SR_DeviceControl(SR_DEVICE_T *dev, int cmd, void *arg);

#ifdef __cplusplus
}
#endif

#endif
