Commit bbb09330 authored by Romain Liévin's avatar Romain Liévin Committed by Greg Kroah-Hartman

[PATCH] USB: tiglusb.c: add direct USB support on some new TI handhelds

I have extended my driver to add support of the embedded USB port provided by
some new Texas Instruments' handhelds. Things are the same except for the
maximum packet size.

Description: add support of the USB port embedded on some new TI handhelds (TI84+ and TI89 Titanium).

Thanks, Romain.
Signed-off-by: default avatarRomain Lievin <lkml@lievin.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 5260bb1c
------------------------------------------------------------------------- -------------------------------------------------------------------------
Readme for Linux device driver for the Texas Instruments SilverLink cable Readme for Linux device driver for the Texas Instruments SilverLink cable
and direct USB cable provided by some TI's handhelds.
------------------------------------------------------------------------- -------------------------------------------------------------------------
Author: Romain Liévin & Julien Blache Author: Romain Liévin & Julien Blache
...@@ -9,7 +10,8 @@ INTRODUCTION: ...@@ -9,7 +10,8 @@ INTRODUCTION:
This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable This is a driver for the TI-GRAPH LINK USB (aka SilverLink) cable, a cable
designed by TI for connecting their TI8x/9x calculators to a computer designed by TI for connecting their TI8x/9x calculators to a computer
(PC or Mac usually). (PC or Mac usually). It has been extended to support the USB port offered by
some latest TI handhelds (TI84+ and TI89 Titanium).
If you need more information, please visit the 'SilverLink drivers' homepage If you need more information, please visit the 'SilverLink drivers' homepage
at the above URL. at the above URL.
...@@ -73,4 +75,4 @@ this driver but he better knows the Mac OS-X driver. ...@@ -73,4 +75,4 @@ this driver but he better knows the Mac OS-X driver.
CREDITS: CREDITS:
The code is based on dabusb.c, printer.c and scanner.c ! The code is based on dabusb.c, printer.c and scanner.c !
The driver has been developed independently of Texas Instruments. The driver has been developed independently of Texas Instruments Inc.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Target: Texas Instruments graphing calculators (http://lpg.ticalc.org). * Target: Texas Instruments graphing calculators (http://lpg.ticalc.org).
* *
* Copyright (C) 2001-2004: * Copyright (C) 2001-2004:
* Romain Lievin <roms@lpg.ticalc.org> * Romain Lievin <roms@tilp.info>
* Julien BLACHE <jb@technologeek.org> * Julien BLACHE <jb@technologeek.org>
* under the terms of the GNU General Public License. * under the terms of the GNU General Public License.
* *
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* and the website at: http://lpg.ticalc.org/prj_usb/ * and the website at: http://lpg.ticalc.org/prj_usb/
* for more info. * for more info.
* *
* History : * History:
* 1.0x, Romain & Julien: initial submit. * 1.0x, Romain & Julien: initial submit.
* 1.03, Greg Kroah: modifications. * 1.03, Greg Kroah: modifications.
* 1.04, Julien: clean-up & fixes; Romain: 2.4 backport. * 1.04, Julien: clean-up & fixes; Romain: 2.4 backport.
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
* 1.06, Romain: synched with 2.5, version/firmware changed (confusing). * 1.06, Romain: synched with 2.5, version/firmware changed (confusing).
* 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument); * 1.07, Romain: fixed bad use of usb_clear_halt (invalid argument);
* timeout argument checked in ioctl + clean-up. * timeout argument checked in ioctl + clean-up.
* 1.08, Romain: added support of USB port embedded on some TI's handhelds.
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -41,7 +42,7 @@ ...@@ -41,7 +42,7 @@
/* /*
* Version Information * Version Information
*/ */
#define DRIVER_VERSION "1.07" #define DRIVER_VERSION "1.08"
#define DRIVER_AUTHOR "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>" #define DRIVER_AUTHOR "Romain Lievin <roms@tilp.info> & Julien Blache <jb@jblache.org>"
#define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver" #define DRIVER_DESC "TI-GRAPH LINK USB (aka SilverLink) driver"
#define DRIVER_LICENSE "GPL" #define DRIVER_LICENSE "GPL"
...@@ -178,11 +179,11 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos) ...@@ -178,11 +179,11 @@ tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
if (!s->dev) if (!s->dev)
return -EIO; return -EIO;
buffer = kmalloc(BULK_RCV_MAX, GFP_KERNEL); buffer = kmalloc (s->max_ps, GFP_KERNEL);
if (!buffer) if (!buffer)
return -ENOMEM; return -ENOMEM;
bytes_to_read = (count >= BULK_RCV_MAX) ? BULK_RCV_MAX : count; bytes_to_read = (count >= s->max_ps) ? s->max_ps : count;
pipe = usb_rcvbulkpipe (s->dev, 1); pipe = usb_rcvbulkpipe (s->dev, 1);
result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read, result = usb_bulk_msg (s->dev, pipe, buffer, bytes_to_read,
...@@ -235,11 +236,11 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * ...@@ -235,11 +236,11 @@ tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t *
if (!s->dev) if (!s->dev)
return -EIO; return -EIO;
buffer = kmalloc(BULK_SND_MAX, GFP_KERNEL); buffer = kmalloc (s->max_ps, GFP_KERNEL);
if (!buffer) if (!buffer)
return -ENOMEM; return -ENOMEM;
bytes_to_write = (count >= BULK_SND_MAX) ? BULK_SND_MAX : count; bytes_to_write = (count >= s->max_ps) ? s->max_ps : count;
if (copy_from_user (buffer, buf, bytes_to_write)) { if (copy_from_user (buffer, buf, bytes_to_write)) {
ret = -EFAULT; ret = -EFAULT;
goto out; goto out;
...@@ -309,6 +310,15 @@ tiglusb_ioctl (struct inode *inode, struct file *filp, ...@@ -309,6 +310,15 @@ tiglusb_ioctl (struct inode *inode, struct file *filp,
if (clear_pipes (s->dev)) if (clear_pipes (s->dev))
ret = -EIO; ret = -EIO;
break; break;
case IOCTL_TIUSB_GET_MAXPS:
if (copy_to_user((int *) arg, &s->max_ps, sizeof(int)))
return -EFAULT;
break;
case IOCTL_TIUSB_GET_DEVID:
if (copy_to_user((int *) arg, &s->dev->descriptor.idProduct,
sizeof(int)))
return -EFAULT;
break;
default: default:
ret = -ENOTTY; ret = -ENOTTY;
break; break;
...@@ -341,6 +351,9 @@ tiglusb_probe (struct usb_interface *intf, ...@@ -341,6 +351,9 @@ tiglusb_probe (struct usb_interface *intf,
int minor = -1; int minor = -1;
int i, err = 0; int i, err = 0;
ptiglusb_t s; ptiglusb_t s;
struct usb_host_config *conf;
struct usb_host_interface *ifdata = NULL;
int max_ps;
dbg ("probing vendor id 0x%x, device id 0x%x", dbg ("probing vendor id 0x%x, device id 0x%x",
dev->descriptor.idVendor, dev->descriptor.idProduct); dev->descriptor.idVendor, dev->descriptor.idProduct);
...@@ -355,20 +368,32 @@ tiglusb_probe (struct usb_interface *intf, ...@@ -355,20 +368,32 @@ tiglusb_probe (struct usb_interface *intf,
goto out; goto out;
} }
if ((dev->descriptor.idProduct != 0xe001) if (dev->descriptor.idVendor != 0x451) {
&& (dev->descriptor.idVendor != 0x451)) {
err = -ENODEV; err = -ENODEV;
goto out; goto out;
} }
// NOTE: it's already in this config, this shouldn't be needed. if ((dev->descriptor.idProduct != 0xe001) &&
// is this working around some hardware bug? (dev->descriptor.idProduct != 0xe004) &&
if (usb_reset_configuration (dev) < 0) { (dev->descriptor.idProduct != 0xe008)) {
err ("tiglusb_probe: reset_configuration failed");
err = -ENODEV; err = -ENODEV;
goto out; goto out;
} }
/*
* TI introduced some new handhelds with embedded USB port.
* Port advertises same config as SilverLink cable but with a
* different maximum packet size (64 rather than 32).
*/
conf = dev->actconfig;
ifdata = conf->interface[0]->cur_altsetting;
max_ps = ifdata->endpoint[0].desc.wMaxPacketSize;
info("max packet size of %d/%d bytes\n",
ifdata->endpoint[0].desc.wMaxPacketSize,
ifdata->endpoint[1].desc.wMaxPacketSize);
/* /*
* Find a tiglusb struct * Find a tiglusb struct
*/ */
...@@ -390,6 +415,7 @@ tiglusb_probe (struct usb_interface *intf, ...@@ -390,6 +415,7 @@ tiglusb_probe (struct usb_interface *intf,
down (&s->mutex); down (&s->mutex);
s->remove_pending = 0; s->remove_pending = 0;
s->dev = dev; s->dev = dev;
s->max_ps = max_ps;
up (&s->mutex); up (&s->mutex);
dbg ("bound to interface"); dbg ("bound to interface");
......
...@@ -17,12 +17,6 @@ ...@@ -17,12 +17,6 @@
*/ */
#define MAXTIGL 16 #define MAXTIGL 16
/*
* Max. packetsize for IN and OUT pipes
*/
#define BULK_RCV_MAX 32
#define BULK_SND_MAX 32
/* /*
* The driver context... * The driver context...
*/ */
...@@ -42,6 +36,8 @@ typedef struct ...@@ -42,6 +36,8 @@ typedef struct
driver_state_t state; /* started/stopped */ driver_state_t state; /* started/stopped */
int opened; /* tru if open */ int opened; /* tru if open */
int remove_pending; int remove_pending;
int max_ps; /* max packet size */
} tiglusb_t, *ptiglusb_t; } tiglusb_t, *ptiglusb_t;
#endif #endif
...@@ -38,5 +38,7 @@ ...@@ -38,5 +38,7 @@
#define IOCTL_TIUSB_TIMEOUT _IOW('N', 0x20, int) /* set timeout */ #define IOCTL_TIUSB_TIMEOUT _IOW('N', 0x20, int) /* set timeout */
#define IOCTL_TIUSB_RESET_DEVICE _IOW('N', 0x21, int) /* reset device */ #define IOCTL_TIUSB_RESET_DEVICE _IOW('N', 0x21, int) /* reset device */
#define IOCTL_TIUSB_RESET_PIPES _IOW('N', 0x22, int) /* reset both pipes*/ #define IOCTL_TIUSB_RESET_PIPES _IOW('N', 0x22, int) /* reset both pipes*/
#define IOCTL_TIUSB_GET_MAXPS _IOR('N', 0x23, int) /* max packet size */
#define IOCTL_TIUSB_GET_DEVID _IOR('N', 0x24, int) /* get device type */
#endif /* TICABLE_H */ #endif /* TICABLE_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment