/*
- Pegasus Mobile Notetaker Pen input tablet driver
*/
/*
- request packet (control endpoint):
- |-------------------------------------|
- | Report ID | Nr of bytes | command |
- | (1 byte) | (1 byte) | (n bytes) |
- |-------------------------------------|
- | 0x02 | n | |
- |-------------------------------------|
- data packet after set xy mode command, 0x80 0xb5 0x02 0x01
- and pen is in range:
- byte byte name value (bits)
-
- 0 status 0 1 0 0 0 0 X X
- 1 color 0 0 0 0 H 0 S T
- 2 X low
- 3 X high
- 4 Y low
- 5 Y high
- X X battery state:
- no state reported 0x00
- battery low 0x01
- battery good 0x02
- H Hovering
- S Switch 1 (pen button)
- T Tip
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/usb/input.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
/* USB HID defines */
#define USB_REQ_GET_REPORT 0x01
#define USB_REQ_SET_REPORT 0x09
#define USB_VENDOR_ID_PEGASUSTECH 0x0e20
#define USB_DEVICE_ID_PEGASUS_NOTETAKER_EN100 0x0101
/* device specific defines */
#define NOTETAKER_REPORT_ID 0x02
#define NOTETAKER_SET_CMD 0x80
#define NOTETAKER_SET_MODE 0xb5
#define NOTETAKER_LED_MOUSE 0x02
#define PEN_MODE_XY 0x01
#define SPECIAL_COMMAND 0x80
#define BUTTON_PRESSED 0xb5
#define COMMAND_VERSION 0xa9
/* in xy data packet */
#define BATTERY_NO_REPORT 0x40
#define BATTERY_LOW 0x41
#define BATTERY_GOOD 0x42
#define PEN_BUTTON_PRESSED BIT(1)
#define PEN_TIP BIT(0)
struct pegasus {
unsigned char *data;
u8 data_len;
dma_addr_t data_dma;
struct input_dev *dev;
struct usb_device *usbdev;
struct usb_interface *intf;
struct urb *irq;
/* serialize access to open/suspend */
struct mutex pm_mutex;
bool is_open;
char name[128];
char phys[64];
struct work_struct init;
};
static int pegasus_control_msg(struct pegasus *pegasus, u8 *data, int len)
{
const int sizeof_buf = len + 2;
int result;
int error;
u8 *cmd_buf;
cmd_buf = kmalloc(sizeof_buf, GFP_KERNEL);
if (!cmd_buf)
return -ENOMEM;
cmd_buf[0] = NO