linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitriy Geels <dmitriy.geels@gmail.com>
To: linux-input@vger.kernel.org
Subject: Need advice on USB device interaction
Date: Wed, 21 Jan 2009 19:07:31 +0300	[thread overview]
Message-ID: <78f5d6bf0901210807x10666e93na53bf5c6453494c3@mail.gmail.com> (raw)

Hello everybody!

I'm working on force feedback support for Saitek gamepad devices. I
base my work on Jérôme Poisson (goffi@goffi.org) Saitek P2500 driver,
which was written pretty dirty and should be loaded before usbhid to
work.
Logitech/Thrustmaster/ZeroPlus/etc force feedback drivers are
informative enough to build my own driver, but there are still 2
things that I need to clear up:

1. there is always some init code in _probe() function, e.g. for hid-zpff:

>  zpff->report = report;
>  zpff->report->field[0]->value[0] = 0x00;
>  zpff->report->field[1]->value[0] = 0x02;
>  zpff->report->field[2]->value[0] = 0x00;
>  zpff->report->field[3]->value[0] = 0x00;
>  usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);

Jérôme used this code in open() function (input_dev::open field):

>  struct usb_device *udev;
>  char buf[2];
>
> ...
>
>  buf[0]=0x15;
>  buf[1]=0x01;
>  usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x09, 0x21, 0x315, 0, &buf, 2, 50);

May this be replaced by usbhid_submit_report() call and how report
should look like then?

2. in kernell FF drivers all interaction with the device made using
usbhid_submit_report() call, but Jérôme used usb_submit_urb():

> static int SP2500_playback(struct input_dev *dev, int code, int value)
> {
>     struct usb_SP2500* sp2500 = (struct usb_SP2500*)(dev->private);
>     struct urb *urb = NULL;
>     char *buf = NULL;
>     int count=4;
>     int retval;
>
>     urb = usb_alloc_urb(0, GFP_KERNEL);
>     if (!urb) {
>         retval = -ENOMEM;
>         goto error;
>     }
>
>     buf = usb_buffer_alloc(sp2500->udev, count, GFP_KERNEL, &urb->transfer_dma);
>     if (!buf) {
>         retval = -ENOMEM;
>         goto error;
>     }
>
>     if (code < 0 || code >= MAX_FF)
>         return -EINVAL;
>
>     buf[0]=0x51;
>     buf[1]=(__u8)code;
>
>     if (value > 0)
>         buf[2]=02;  //play
>     else
>         buf[2]=01;  //stop
>
>     buf[3]=01;
>     count=4;
>
>     usb_fill_int_urb(urb, sp2500->udev,
>                     usb_sndintpipe(sp2500->udev, sp2500->int_out_endpointAddr),
>                     buf, count, SP2500_write_int_callback, sp2500, 20);
>     urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
>
>
>     retval = usb_submit_urb(urb, GFP_KERNEL);
>     if (retval) {
>         err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
>         goto error;
>     }
>
>     usb_free_urb(urb);
>
>     return 0;
>
> error:
>     err ("playback error");
>     usb_buffer_free(sp2500->udev, count, buf, urb->transfer_dma);
>     usb_free_urb(urb);
>     return retval;
> }

Is following my replacement for this function correct? Mainly, I want
to know, if data packet is formed correctly.

> static int stff_play(struct input_dev *idev, int code, int value)
> {
>     struct hid_device *hid = input_get_drvdata(idev);
>     struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
>     struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
>
>     report->field[0]->value[0] = 0x51;
>     report->field[0]->value[1] = (__u8)code;
>
>     if (value > 0)
>         report->field[0]->value[2] = 02;  //play
>     else
>         report->field[0]->value[2] = 01;  //stop
>
>     report->field[0]->value[3]=01;
>
>     usbhid_submit_report(hid, report, USB_DIR_OUT);
>
>     return 0;
> }


P.S. you can find SP2500 driver source here:
http://www.goffi.org/index.php?post/2006/09/14/Pilote-Linux-pour-le-joypad-Saitek-P2501
P.P.S. original driver contains quirk from original saitek driver --
d-pad and first analog stick swap on button press; I don't wan't to
implement this quirk at the moment
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

                 reply	other threads:[~2009-01-21 16:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=78f5d6bf0901210807x10666e93na53bf5c6453494c3@mail.gmail.com \
    --to=dmitriy.geels@gmail.com \
    --cc=linux-input@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).