| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 | #ifndef ABCIO_H#define ABCIO_H#include "common.h"#include "config.h"#define DEVSEL_NONE 64		/* No device at all selected */struct abc_dev;/* Called from an interrupt handler, so hot */#define ABC_CALLBACK_DECL(func)						\    void func(struct abc_dev *dev __unused,				\	      uint8_t data __unused,					\	      uint8_t addr __unused)#define ABC_CALLBACK(func)			\    __hot ABC_CALLBACK_DECL(func)typedef ABC_CALLBACK_DECL((*abc_callback_t));struct abc_dev {    uint8_t *out_buf;    size_t out_cnt;    const uint8_t *inp_buf;    size_t inp_cnt;    uint16_t callback_mask;    uint16_t event_mask;	/* Can be a superset of callback_mask */    uint8_t status_first_out_mask;    uint8_t status_first_inp_mask;    uint8_t out_data[6];	/* [1] is devsel, all 8 bits */    union {	struct {	    uint8_t inp_data[2];	    uint8_t inp_en;	    uint8_t inp_data_def; /* inp_data[0] when no queue active */	};	uint32_t inp_data_w;    };    abc_callback_t callback_out[6];    abc_callback_t callback_inp[2];    abc_callback_t callback_rst;    unsigned int devsel;    const char *name;};extern struct abc_dev *_abc_selected_dev;static inline struct abc_dev *abc_selected_dev(void){    return _abc_selected_dev;}void abc_setup_out_queue(struct abc_dev *dev, void *buf, size_t len,			 uint8_t status);void abc_setup_inp_queue(struct abc_dev *dev, const void *buf, size_t len,			 uint8_t status);void abc_set_inp_default(struct abc_dev *dev, uint8_t val);void abc_set_inp_status(struct abc_dev *dev, uint8_t val);/* * The _ versions can be used from interrupt handlers or when ABC_IRQ * is known to be masked already; for the _inp_data() functions this ALSO * requires that dev->inp_cnt is known to be zero (no currently configured * queue.) * * The __ versions can be used when it is *also* known that the device * in question is already selected (e.g. inside a callback.) */static inline void _abc_set_inp_data(struct abc_dev *dev, uint8_t val){    dev->inp_data[0] = dev->inp_data_def = val;    if (dev == abc_selected_dev())	ABC_INP0_DATA = val;}static inline void _abc_set_inp_status(struct abc_dev *dev, uint8_t val){    dev->inp_data[1] = val;    if (dev == abc_selected_dev())	ABC_INP1_DATA = val;}static inline void __abc_set_inp_data(struct abc_dev *dev, uint8_t val){    ABC_INP0_DATA = dev->inp_data[0] = dev->inp_data_def = val;}static inline void __abc_set_inp_status(struct abc_dev *dev, uint8_t val){    ABC_INP1_DATA = dev->inp_data[1] = val;}static inline bool is_abc800(void){    unsigned long int host = getvar_uint(config_abc_hosttype);    if (host)	return host >= ABC_ABC800CM;    else	return !!(ABC_STATUS & ABC_STATUS_800);}void abc_register(struct abc_dev *dev, unsigned int devsel);void abc_init(void);void abcdisk_init(void);void abcdisk_config(void);void abcdisk_io_poll(void);void abcdisk_shutdown(void);void rtc_abc_init(void);void rtc_abc_config(void);void rtc_abc_io_poll(void);void pun80_init(void);void pun80_config(void);void abc_init_memmap(void);#endif /* ABCIO_H */
 |