/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2007, 2008 Bartosz Fabianowski <freebsd@chillt.de>
* All rights reserved.
*
* Financed by the "Irish Research Council for Science, Engineering and
* Technology: funded by the National Development Plan"
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Lennart Augustsson (lennart@augustsson.net) at
* Carlstedt Research & Technology.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* debugging information */
static void
{
switch (type) {
case EVT_SYN:
return;
break;
case EVT_BTN:
return;
break;
case EVT_ABS:
return;
}
}
return;
}
break;
case EVT_REL:
if (!val)
return;
break;
case EVT_MSC:
break;
default:
return;
}
} else {
return;
}
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
}
static void
{
}
static void
{
"unknown report type %02x received\n",
PACKET_BITS(0, 0, 8));
return;
}
/* Tool in proximity */
} else {
}
} else {
} else {
}
distance);
}
/* Tool leaving proximity */
} else if (sc->sc_tool_id[0]) {
uwacom_pos_events_graphire(usbwcmp, 0, 0);
uwacom_mouse_events_graphire(usbwcmp, 0, 0, 0, 0, 0);
else
uwacom_pen_events_graphire(usbwcmp, 0, 0, 0);
sc->sc_tool_id[0] = 0;
uwacom_tool_events_graphire(usbwcmp, 0, 0);
}
/* Finger on pad: Graphire4 */
/* Finger on pad: MyOffice */
/* Finger leaving pad */
uwacom_pad_events_graphire4(usbwcmp, 0, 0, 0, 0, 0, 0);
}
}
static void
{
}
static void
{
case INTUOS4S:
case INTUOS4L:
break;
default:
break;
}
}
static void
{
case INTUOS4S:
case INTUOS4L:
break;
default:
break;
}
}
static void
{
}
static void
{
case INTUOS4L:
/*FALLTHRU*/
case INTUOS4S:
if (whl) {
}
break;
default:
break;
}
}
static void
{
switch (PACKET_BITS(0, 0, 8)) {
case 0x02:
/* Tool entering proximity */
case 0x2:
switch (sc->sc_tool_id[0]) {
case 0x802: /* Intuos4 Grip Pen */
case 0x804: /* Intuos4 Art Marker */
case 0x823: /* Intuos3 Grip Pen */
case 0x885: /* Intuos3 Art Marker */
break;
case 0x80a: /* Intuos4 Grip Pen eraser */
case 0x82b: /* Intuos3 Grip Pen eraser */
break;
case 0x017: /* Intuos3 2D mouse */
case 0x806: /* Intuos4 2D mouse */
break;
default:
"unknown tool ID %03x seen\n",
sc->sc_tool_id[0]);
}
break;
/* Tool leaving proximity */
case 0x0:
uwacom_pos_events_intuos(usbwcmp, 0, 0, 0);
else
sc->sc_tool_id[0] = 0;
uwacom_tool_events_intuos(usbwcmp, 0, 0);
break;
/* Tool motion, outbound */
case 0x1:
/* Outbound tracking is unreliable on the Cintiq */
break;
/* Tool motion */
/*FALLTHRU*/
case 0x3:
}
break;
} else {
"unsupported motion packet type %x "
}
break;
}
break;
case 0x0c:
break;
default:
"unknown report type %02x received\n",
PACKET_BITS(0, 0, 8));
}
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static void
{
}
static int
{
for (int i = 0; i < EVT_USED; ++i)
KM_SLEEP);
0, 0);
case CINTIQ:
case INTUOS3L:
/*FALLTHRU*/
case INTUOS3S:
break;
case INTUOS4L:
/*FALLTHRU*/
case INTUOS4S:
break;
case MYOFFICE:
/*FALLTHRU*/
case GRAPHIRE4:
/*FALLTHRU*/
case GRAPHIRE:
break;
}
return (0);
}
/*
* usbwcm_match() :
* Match device with it's parameters.
*/
static const struct uwacom_type *
{
dev = uwacom_devs;
return (dev);
}
dev++;
}
return (NULL);
}
/*
* usbwcm_probe() :
* Check the device type and protocol.
*/
static int
{
/* check device IDs */
return (ENOMEM);
}
if (qwait_sig(q) == 0) {
usbwcmp->usbwcm_flags = 0;
return (EINTR);
}
}
"unsupported tablet model\n");
return (ENXIO);
}
if (uwacom_init(usbwcmp) != 0) {
return (ENXIO);
}
/* set feature: tablet mode */
/*
* Waiting for response of HID_SET_REPORT
* mctl for setting the feature.
*/
qwait(q);
}
} else {
"enable tablet mode failed\n");
}
return (0);
}
/*
* usbwcm_copyreq() :
* helper function for usbwcm ioctls
*/
static int
{
}
return (EINVAL);
}
if (pvtsize) {
return (EAGAIN);
}
} else {
/*
* Here we need to set cq_private even if there's
* no private data, otherwise its value will be
* TRANSPARENT (-1) on 64bit systems because it
* overlaps iocp->ioc_count. If user address (cq_addr)
* is invalid, it would cause panic later in
* usbwcm_copyin:
* freemsg((mblk_t *)copyresp->cp_private);
*/
}
if (state) {
if (pvtsize) { /* M_COPYIN */
} else {
}
}
if (contsize) {
return (EAGAIN);
}
}
}
return (0);
}
static void
{
}
}
/*
* usbwcm_iocpy() :
* M_IOCDATA processing for IOCTL's
*/
static void
{
int err = 0;
goto out;
}
default: {
return;
break;
}
switch (num) {
case EUWACOMGETVERSION:
break;
}
USBWCM_GETRESULT, sizeof (int), 0,
M_COPYOUT)) {
goto out;
}
usbwcm_miocack(q, mp, 0);
return;
}
break;
case EUWACOMGETID:
break;
}
sizeof (struct event_dev_id));
sizeof (struct event_dev_id), 0,
M_COPYOUT)) {
goto out;
}
usbwcm_miocack(q, mp, 0);
return;
}
break;
default:
if (num >= EUWACOMGETBM &&
break;
}
length);
USBWCM_GETRESULT, length, 0,
M_COPYOUT)) {
goto out;
}
return;
}
break;
} else if (num >= EUWACOMGETABS &&
break;
}
sizeof (struct event_abs_axis));
sizeof (struct event_abs_axis), 0,
M_COPYOUT)) {
goto out;
}
usbwcm_miocack(q, mp, 0);
return;
}
break;
} else {
break;
}
}
}
}
out:
if (err) {
}
if (copyresp->cp_private) {
}
}
}
/*
* usbwcm_ioctl() :
* Process ioctls we recognize and own. Otherwise, NAK.
*/
static void
{
int err = 0;
return;
}
default: {
return;
break;
}
switch (num) {
case EUWACOMGETVERSION:
sizeof (usbwcm_copyin_t), USBWCM_GETSTRUCT,
sizeof (int), 0, M_COPYIN)) {
break;
}
return;
}
break;
}
break;
case EUWACOMGETID:
sizeof (usbwcm_copyin_t), USBWCM_GETSTRUCT,
sizeof (struct event_dev_id), 0,
M_COPYIN)) {
break;
}
return;
}
break;
}
sizeof (struct event_dev_id));
break;
default:
if (num >= EUWACOMGETBM &&
sizeof (usbwcm_copyin_t),
USBWCM_GETSTRUCT, length, 0,
M_COPYIN)) {
break;
}
return;
}
break;
}
break;
} else if (num >= EUWACOMGETABS &&
sizeof (usbwcm_copyin_t),
sizeof (struct event_abs_axis), 0,
M_COPYIN)) {
break;
}
return;
}
sizeof (struct event_abs_axis)) {
break;
}
sizeof (struct event_abs_axis));
break;
} else {
break;
}
}
}
}
if (err != 0)
else {
/* REMOVE */
}
return;
}
/*
* usbwcm_input() :
*
* Wacom input routine; process data received from a device and
* assemble into a input event for the window system.
*
* Watch out for overflow!
*/
static void
{
case GRAPHIRE:
case GRAPHIRE4:
case MYOFFICE:
break;
case INTUOS3S:
case INTUOS3L:
case INTUOS4S:
case INTUOS4L:
case CINTIQ:
break;
}
}
/*
* usbwcm_flush() :
* Resets the soft state to default values
* and sends M_FLUSH above.
*/
static void
{
queue_t *q;
}
}
/*
* usbwcm_mctl() :
* Handle M_CTL messages from hid. If
* we don't understand the command, free message.
*/
static void
{
case HID_GET_VID_PID:
}
break;
case HID_CONNECT_EVENT:
/* set feature: tablet mode */
} else {
"enable tablet mode failed\n");
}
break;
case HID_SET_REPORT:
/* FALLTHRU */
case HID_SET_PROTOCOL:
/* FALLTHRU */
default:
}
}
/*
* usbwcm_open() :
* open() entry point for the USB wacom module.
*/
/*ARGSUSED*/
static int
{
/* Clone opens are not allowed */
return (EINVAL);
/* If the module is already open, just return */
if (q->q_ptr) {
return (0);
}
/* allocate usbwcm state structure */
qprocson(q);
if (usbwcm_probe(usbwcmp) != 0) {
qprocsoff(q);
return (EINVAL);
}
return (0);
}
/*
* usbwcm_close() :
* close() entry point for the USB wacom module.
*/
/*ARGSUSED*/
static int
{
qprocsoff(q);
if (usbwcmp->usbwcm_bufcall) {
usbwcmp->usbwcm_bufcall = 0;
}
/*
* We were holding an "ioctl" response pending the
* availability of an "mblk" to hold data to be passed up;
* another "ioctl" came through, which means that "ioctl"
* must have timed out or been aborted.
*/
}
for (int i = 0; i < EVT_USED; i++)
return (0);
}
/*
* usbwcm_wput() :
* wput() routine for the wacom module.
* Module below : hid, module above : consms
*/
static int
{
case M_FLUSH: /* Canonical flush handling */
}
}
break;
case M_IOCTL:
usbwcm_ioctl(q, mp);
break;
case M_IOCDATA:
usbwcm_iocpy(q, mp);
break;
default:
}
return (0);
}
/*
* usbwcm_rput() :
* Put procedure for input from driver end of stream (read queue).
*/
static void
{
int limit;
if (usbwcmp == 0) {
return;
}
case M_FLUSH:
return;
case M_BREAK:
/*
* We don't have to handle this
* because nothing is sent from the downstream
*/
return;
case M_DATA:
return;
}
/*
* Make sure there are at least "limit" number of bytes.
*/
do {
/* REMOVE */
}
break;
case M_CTL:
usbwcm_mctl(q, mp);
return;
case M_ERROR:
/* REMOVE */
return;
default:
return;
}
}
/* STREAMS entry points */
/* read side queue */
(int (*)())usbwcm_rput, /* put procedure not needed */
NULL, /* service procedure */
usbwcm_open, /* called on startup */
usbwcm_close, /* called on finish */
NULL, /* for future use */
&modinfo, /* module information structure */
NULL /* module statistics structure */
};
/* write side queue */
usbwcm_wput, /* put procedure */
NULL, /* no service proecedure needed */
NULL, /* open not used on write side */
NULL, /* close not used on write side */
NULL, /* for future use */
&modinfo, /* module information structure */
NULL /* module statistics structure */
};
/* STREAMS table */
&rinit,
&winit,
NULL, /* not a MUX */
NULL /* not a MUX */
};
/* Module linkage information */
"usbwcm",
&strtab,
};
"USB Wacom STRMOD",
};
(void *)&modlstr,
};
0x0ffff, /* module id number */
"usbwcm", /* module name */
0, /* min packet size accepted */
INFPSZ, /* max packet size accepted */
512, /* hi-water mark */
128 /* lo-water mark */
};
/* Module entry points */
int
_init(void)
{
if (rval == 0) {
}
return (rval);
}
int
_fini(void)
{
if (rval == 0) {
}
return (rval);
}
int
{
}