#ifndef _OPENPCD_PROTO_H
#define _OPENPCD_PROTO_H

/* This header file describes the USB protocol of the OpenPCD RFID reader */

#include <sys/types.h>

struct openpcd_hdr {
	u_int8_t cmd;		/* command. high nibble: class,
				 *	     low nibble: cmd */
	u_int8_t flags;
	u_int8_t reg;		/* register */
	u_int8_t val;		/* value (in case of write *) */
	u_int8_t data[0];
} __attribute__ ((packed));

#define OPCD_REV_LEN	16
struct openpcd_compile_version {
	char svnrev[OPCD_REV_LEN];
	char by[OPCD_REV_LEN];
	char date[OPCD_REV_LEN];
} __attribute__ ((packed));

#define OPENPCD_FLAG_RESPOND	0x01	/* Response requested */
#define OPENPCD_FLAG_ERROR	0x80	/* An error occurred */

enum openpcd_cmd_class {
	OPENPCD_CMD_CLS_GENERIC		= 0x0,
	/* PCD (reader) side */
	OPENPCD_CMD_CLS_RC632		= 0x1,
	//OPENPCD_CMD_CLS_LED		= 0x2,
	OPENPCD_CMD_CLS_SSC		= 0x3,
	OPENPCD_CMD_CLS_PWM		= 0x4,
	OPENPCD_CMD_CLS_ADC		= 0x5,
	OPENPCD_CMD_CLS_LIBRFID		= 0x6,
        OPENPCD_CMD_CLS_PRESENCE        = 0x7,
	/* SIM SCAN */
	OPENPCD_CMD_CLS_SIM		= 0x8,
	/* PICC (transponder) side */
	OPENPCD_CMD_CLS_PICC		= 0xe,

	OPENPCD_CMD_CLS_USBTEST		= 0xf,
};

#define OPENPCD_REG_MAX	0x3f

#define OPENPCD_CMD_CLS(x)	(x >> 4)
#define OPENPCD_CMD(x)		(x & 0xf)

#define OPENPCD_CLS2CMD(x)	(x << 4)

/* Generic */
#define OPENPCD_CMD_GET_VERSION		(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))
#define OPENPCD_CMD_SET_LED		(0x2|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))
#define OPENPCD_CMD_GET_SERIAL		(0x3|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))
#define OPENPCD_CMD_GET_API_VERSION	(0x4|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))
#define OPENPCD_CMD_GET_ENVIRONMENT	(0x5|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))
#define OPENPCD_CMD_SET_ENVIRONMENT	(0x6|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))
#define OPENPCD_CMD_RESET		(0x7|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_GENERIC))

/* CMD_CLS_RC632 */
#define OPENPCD_CMD_WRITE_REG		(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_WRITE_FIFO		(0x2|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_WRITE_VFIFO		(0x3|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_REG_BITS_CLEAR	(0x4|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_REG_BITS_SET	(0x5|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_READ_REG		(0x6|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_READ_FIFO		(0x7|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_READ_VFIFO		(0x8|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_DUMP_REGS		(0x9|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_IRQ			(0xa|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))
#define OPENPCD_CMD_WRITE_REG_SET	(0xb|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_RC632))

/* CMD_CLS_SSC */
#define OPENPCD_CMD_SSC_READ		(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_SSC))
#define OPENPCD_CMD_SSC_WRITE		(0x2|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_SSC))

/* CMD_CLS_PWM */
#define OPENPCD_CMD_PWM_ENABLE		(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PWM))
#define OPENPCD_CMD_PWM_DUTY_SET	(0x2|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PWM))
#define OPENPCD_CMD_PWM_DUTY_GET	(0x3|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PWM))
#define OPENPCD_CMD_PWM_FREQ_SET	(0x4|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PWM))
#define OPENPCD_CMD_PWM_FREQ_GET	(0x5|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PWM))

/* CMD_CLS_PICC */
#define OPENPCD_CMD_PICC_REG_WRITE	(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PICC))
#define OPENPCD_CMD_PICC_REG_READ	(0x2|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PICC))

/* CMD_CLS_ADC */
#define OPENPCD_CMD_ADC_READ		(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_ADC))

/* CMD_CLS_LIBRFID */
#define OPENPCD_CMD_LRFID_DETECT_IRQ	(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_LIBRFID))

/* CMD_CLS_LIBRFID */
#define OPENPCD_CMD_PRESENCE_UID_GET    (0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_PRESENCE))

/* CMD_CLS_USBTEST */
#define OPENPCD_CMD_USBTEST_IN		(0x1|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_USBTEST))
#define OPENPCD_CMD_USBTEST_OUT		(0x2|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_USBTEST))

/* FIXME */
#define OPENPCD_CMD_PIO_IRQ		(0x3|OPENPCD_CLS2CMD(OPENPCD_CMD_CLS_USBTEST))


#define OPENPCD_VENDOR_ID	0x16c0
#define SIMTRACE_PRODUCT_ID	0x0762
#define OPENPCD_PRODUCT_ID	0x076b
#define OPENPICC_PRODUCT_ID	0x076c
#define OPENPCD_OUT_EP		0x01
#define OPENPCD_IN_EP		0x82
#define OPENPCD_IRQ_EP		0x83

#endif
