From: johann d. <jd...@us...> - 2002-06-09 11:06:45
|
Update of /cvsroot/linuxconsole/ruby/linux/drivers/usb/input In directory usw-pr-cvs1:/tmp/cvs-serv5109/drivers/usb/input Modified Files: hid-core.c hid-ff.c hid-lg3dff.c Added Files: fixp-arith.h Log Message: Added basic (and still buggy) support for constant effects for Logitech 3D devices. --- NEW FILE: fixp-arith.h --- #ifndef _FIXP_ARITH_H #define _FIXP_ARITH_H /* * $$ * * Simplistic fixed-point arithmetics. * Hmm, I'm probably duplicating some code :( * * Copyright (c) 2002 Johann Deneux */ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so by * e-mail - mail your message to <de...@if...> */ #include <linux/types.h> // The type representing fixed-point values typedef s16 fixp_t; #define FRAC_N 8 #define FRAC_MASK ((1<<FRAC_N)-1) // Not to be used directly. Use fixp_{cos,sin} fixp_t cos_table[45] = { 0x0100, 0x00FF, 0x00FF, 0x00FE, 0x00FD, 0x00FC, 0x00FA, 0x00F8, 0x00F6, 0x00F3, 0x00F0, 0x00ED, 0x00E9, 0x00E6, 0x00E2, 0x00DD, 0x00D9, 0x00D4, 0x00CF, 0x00C9, 0x00C4, 0x00BE, 0x00B8, 0x00B1, 0x00AB, 0x00A4, 0x009D, 0x0096, 0x008F, 0x0087, 0x0080, 0x0078, 0x0070, 0x0068, 0x005F, 0x0057, 0x004F, 0x0046, 0x003D, 0x0035, 0x002C, 0x0023, 0x001A, 0x0011, 0x0008 }; /* a: 123 -> 123.0 */ inline fixp_t fixp_new(s16 a) { return a<<FRAC_N; } /* a: 0xFFFF -> -1.0 0x8000 -> 1.0 0x0000 -> 0.0 */ inline fixp_t fixp_new16(s16 a) { return ((s32)a)>>(16-FRAC_N); } inline fixp_t fixp_cos(unsigned int degrees) { int quadrant = (degrees / 90) & 3; unsigned int i = (degrees % 90) >> 1; return (quadrant == 1 || quadrant == 2)? -cos_table[i] : cos_table[i]; } inline fixp_t fixp_sin(unsigned int degrees) { return -fixp_cos(degrees + 90); } inline fixp_t fixp_mult(fixp_t a, fixp_t b) { return ((s32)(a*b))>>FRAC_N; } #endif Index: hid-core.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/input/hid-core.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- hid-core.c 2 Jun 2002 17:19:21 -0000 1.4 +++ hid-core.c 9 Jun 2002 11:06:38 -0000 1.5 @@ -1420,8 +1420,10 @@ dbg("HID probe called for ifnum %d", ifnum); - if (!(hid = usb_hid_configure(dev, ifnum))) + if (!(hid = usb_hid_configure(dev, ifnum))) { + err("usb_hid_configure failed"); return NULL; + } hid_init_reports(hid); hid_dump_device(hid); Index: hid-ff.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/input/hid-ff.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- hid-ff.c 18 Apr 2002 22:02:47 -0000 1.2 +++ hid-ff.c 9 Jun 2002 11:06:38 -0000 1.3 @@ -53,6 +53,9 @@ #ifdef CONFIG_LOGITECH_RUMBLE {0x46d, 0xc211, hid_lgff_init}, #endif +#ifdef CONFIG_LOGITECH_3D + {0x46d, 0xc283, hid_lg3d_init}, +#endif #ifdef CONFIG_HID_PID {0x45e, 0x001b, hid_pid_init}, #endif @@ -79,5 +82,9 @@ init = hid_get_ff_init(hid->dev->descriptor.idVendor, hid->dev->descriptor.idProduct); - return init? init->init(hid) : -ENOSYS; + if (!init) { + warn("hid_ff_init could not find initializer"); + return -ENOSYS; + } + return init->init(hid); } Index: hid-lg3dff.c =================================================================== RCS file: /cvsroot/linuxconsole/ruby/linux/drivers/usb/input/hid-lg3dff.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- hid-lg3dff.c 2 Jun 2002 17:34:22 -0000 1.3 +++ hid-lg3dff.c 9 Jun 2002 11:06:38 -0000 1.4 @@ -34,6 +34,7 @@ #include <linux/circ_buf.h> #include "hid.h" +#include "fixp-arith.h" #define RUN_AT(t) (jiffies + (t)) @@ -341,8 +342,6 @@ int i; int err; - x = 0; - y = 0; spin_lock_irqsave(&lg3d->lock, flags); if (test_bit(DEVICE_USB_XMIT, lg3d->flags)) { @@ -361,12 +360,21 @@ return; } + x = 0x7f; + y = 0x7f; + for (i=0; i<N_EFFECTS; ++i) { struct lg3d_effect* effect = lg3d->effects +i; if (test_bit(EFFECT_PLAYING, effect->flags)) { + if (effect->effect.type == FF_CONSTANT) { - x = y = 0x60; /*TODO: actual implementation */ + //TODO: handle envelopes + int degrees = effect->effect.direction * 360 >> 16; + x += fixp_mult(fixp_sin(degrees), + fixp_new16(effect->effect.u.constant.level)); + y += fixp_mult(-fixp_cos(degrees), + fixp_new16(effect->effect.u.constant.level)); } /* One run of the effect is finished playing */ @@ -374,9 +382,13 @@ effect->started_at + effect->effect.replay.delay*HZ/1000 + effect->effect.replay.length*HZ/1000)) { - if (--effect->count <= 0) + dbg("Finished playing once"); + if (--effect->count <= 0) { + dbg("Stopped"); clear_bit(EFFECT_PLAYING, effect->flags); + } else { + dbg("Start again"); if (effect->effect.replay.length != 0) { clear_bit(EFFECT_PLAYING, effect->flags); set_bit(EFFECT_STARTED, effect->flags); @@ -386,16 +398,23 @@ } } else if (test_bit(EFFECT_STARTED, lg3d->effects[i].flags)) { + dbg("Started"); /* Check if we should start playing the effect */ if (time_after(jiffies, lg3d->effects[i].started_at + lg3d->effects[i].effect.replay.delay*HZ/1000)) { + dbg("Now playing"); clear_bit(EFFECT_STARTED, lg3d->effects[i].flags); set_bit(EFFECT_PLAYING, lg3d->effects[i].flags); } } } + if (x < 0) x = 0; + if (x > 0xff) x = 0xff; + if (y < 0) y = 0; + if (y > 0xff) y = 0xff; + lg3d->urbffout->pipe = usb_sndctrlpipe(hid->dev, 0); lg3d->ffcr.bRequestType = USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE; lg3d->urbffout->transfer_buffer_length = lg3d->ffcr.wLength = 8; |