/* usb/driver/hid/input/device.h
 *
 * (c) 2002 Simtec Electronics
 *
 * Ben Dooks
 *
 * HID Input Driver - Device structure definition
 *
 * $Id: device.h,v 1.27 2003/08/08 11:17:17 ben Exp $
 *
 * This Library file is part of the Simtec Electronics USB stack development
 *   suite.
 * Specific licence is granted to use this file by third parties for the
 *   development of USB device drivers.
 *
*/

#ifndef __USB_DRIVER_HID_DEVICE_H
#define __USB_DRIVER_HID_DEVICE_H "$Id: device.h,v 1.27 2003/08/08 11:17:17 ben Exp $"

struct hid_dev;

#ifdef HID_CONFIG_MOUSE
#include "usb/hid/mouse.h"
#endif

#ifdef HID_CONFIG_KEYBOARD
#include "usb/hid/keyb.h"
#endif

#include "usb/hid/external.h"

#ifdef HID_CONFIG_JOYSTICK
#include "usb/hid/joystk.h"
#endif

/* enum hid_phase
 *
 * this is the current state of what we are doing with this device.
 * once HID_PHASE_GETREPORT is reached, we are polling the device for
 * information about what it is doing, anything prior to this is part of
 * the setup of the device
*/

enum hid_phase {
  HID_PHASE_GETPROTOCOL,
  HID_PHASE_GETINFO,
  HID_PHASE_SETPROTOCOL,
  HID_PHASE_SETIDLE,
  HID_PHASE_GETDESCRIPTOR,
  HID_PHASE_GETDESCRIPTOR2,
  HID_PHASE_GETREPORT
};

/* enum hid_type_code
 *
*/

enum hid_type_code {
  HID_TYPE_NONE,
  HID_TYPE_KEYBOARD,
  HID_TYPE_MOUSE,
  HID_TYPE_JOYSTICK
};

struct hid_dev_type {
  const char           *name;      /* constant for device name */
                                   /* ie, keyboard, mouse, etc */
  enum hid_type_code    code;      /* unique code number */
};

/* struct hid_dev_handlers
 *
 * handler functions for hid devices.. these get called for various
 * events, such as device deletion, timer events, etc
*/

struct hid_dev_handlers {
  void                     (*close)(struct hid_dev *);
  void                     (*slow_timer)(struct hid_dev *dev);
  void                     (*ctrl_done)(struct hid_dev *dev);
  void                     *unused_b;
  void                     *unused_c;
  void                     *unused_d;
};

#define USBHID_FLAG_IRQSAFE            (0x01)
#define USBHID_FLAG_MULTIPLE_REPORTS   (0x02)    /* >1 report */
#define USBHID_FLAG_SLOWTIMER_NEEDED   (0x04)    /* call via new slowtimer*/
#define USBHID_FLAG_CTRLFREE           (0x08)    /* control buffers free */
#define USBHID_FLAG_SENTCTRL           (0x10)    /* control buffers free */

#include "usb/lib/log.h"

extern usb_log_t hid_log;

struct hid_dev {
  struct hid_dev           *list;
  struct hid_dev_type      *type;
  struct hid_dev_handlers  *handlers;

  struct usbmsg_new_device *newdev_msg;   /* launched by */

  usb_log_t                 log;          /* log */

  int                       interface;    /* interface number this is on */
  int                       protocol;     /* protocol for this device */

  unsigned long             devnumber;    /* copy of device number */
  usb_device_t              device_ref;   /* device reference */

  int report_descriptor_len;  /* length of a 'report descriptors' req */

  struct hid_reports       *descriptor;
  struct hid_defn_set      *defns;
  int                       default_length;

  struct hid_report_proc_s *rep_proc;   /* report processor */

  enum hid_phase            phase;

  unsigned int              flags;
  unsigned int              timer;
  unsigned int              retries;
  unsigned int              stopping;    /* set when device removed */

  usb_wait_t               *result;      /* transaction result pointer */
  usb_wait_t               *ctrl_result; /* for control messages */

  /* input request pipe */

  usb_endpoint_t            in_endpoint;
  usb_pipe_t               *in_pipe;

  usb_buffer_t             *in_req;     /* input request buffer */
  usb_buffer_t             *in_data;    /* input request buffer */

  /* control pipe */

  usb_pipe_t               *pipe;                   /* pipe */
  usb_endpoint_t            default_endpoint;       /* pipe */

  usb_buffer_t             *req_buff;   /* control request buffer */
  usb_buffer_t             *data_buff;  /* control request buffer */

  /* current state of the system */

  union {
#ifdef HID_CONFIG_MOUSE
    struct hid_state_mouse     mouse;
#endif
#ifdef HID_CONFIG_KEYBOARD
    struct hid_state_keyb      keyb;
#endif
#ifdef HID_CONFIG_JOYSTICK
    struct hid_state_joystick  joystick;
#endif
    struct hid_state_ext       external;
  } state;
};

#define hid_dev_setphase(dev,ph) do { \
  debugf(("hid_dev_setphase: "__FILE__ ":%d: %08x: %d -> %d\n", __LINE__, (int)dev, dev->phase, ph)); \
  dev->phase = ph; } while(0)

extern struct hid_dev *devlist;

extern struct hid_dev *hid_new_dev(void);

extern struct hid_dev *hid_find_by_ref(void *);

extern void hid_dev_delete(struct hid_dev *dev);
extern int  hid_dev_init(struct hid_dev *dev);

extern void hid_dev_remove_all(void);

extern int  hid_dev_start(struct hid_dev *dev);
extern int  hid_dev_close(struct hid_dev *dev);

extern void hid_dev_timeout(struct hid_dev *dev);

extern int  hid_service_dev(struct hid_dev *dev);

extern int  hid_find_unclaimed_devices(void);

extern void hid_dev_show(struct hid_dev *dev);
extern void hid_dev_showall(void);

extern void hid_dev_clearflags(struct hid_dev *dev, int flags);
extern void hid_dev_setflags(struct hid_dev *dev, int flags);

#endif /* __USB_DRIVER_HID_DEVICE_H */
