Commit 49bb607f authored by Jeremy Katz's avatar Jeremy Katz Committed by Greg Kroah-Hartman

USB: Support Blackberry Pearl with berry_charge

The Blackberry Pearl (8100) needs similar tweaks as older Blackberry models
to be able to charge when connected via USB.  The Pearl also adds an
additional need to go into a separate mode for fully accessing the device;
do that by default as well.

Changes based on the changes from bcharge in the barry project
(http://barry.sf.net)
Signed-off-by: default avatarJeremy Katz <katzj@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 165fe97e
...@@ -26,8 +26,11 @@ ...@@ -26,8 +26,11 @@
#define RIM_VENDOR 0x0fca #define RIM_VENDOR 0x0fca
#define BLACKBERRY 0x0001 #define BLACKBERRY 0x0001
#define BLACKBERRY_PEARL_DUAL 0x0004
#define BLACKBERRY_PEARL 0x0006
static int debug; static int debug;
static int pearl_dual_mode = 1;
#ifdef dbg #ifdef dbg
#undef dbg #undef dbg
...@@ -38,6 +41,8 @@ static int debug; ...@@ -38,6 +41,8 @@ static int debug;
static struct usb_device_id id_table [] = { static struct usb_device_id id_table [] = {
{ USB_DEVICE(RIM_VENDOR, BLACKBERRY) }, { USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
{ USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) },
{ USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) },
{ }, /* Terminating entry */ { }, /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, id_table); MODULE_DEVICE_TABLE(usb, id_table);
...@@ -86,6 +91,30 @@ static int magic_charge(struct usb_device *udev) ...@@ -86,6 +91,30 @@ static int magic_charge(struct usb_device *udev)
return retval; return retval;
} }
static int magic_dual_mode(struct usb_device *udev)
{
char *dummy_buffer = kzalloc(2, GFP_KERNEL);
int retval;
if (!dummy_buffer)
return -ENOMEM;
/* send magic command so that the Blackberry Pearl device exposes
* two interfaces: both the USB mass-storage one and one which can
* be used for database access. */
dbg(&udev->dev, "Sending magic pearl command\n");
retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100);
dbg(&udev->dev, "Magic pearl command returned %d\n", retval);
dbg(&udev->dev, "Calling set_configuration\n");
retval = usb_driver_set_configuration(udev, 1);
if (retval)
dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
return retval;
}
static int berry_probe(struct usb_interface *intf, static int berry_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
...@@ -105,6 +134,10 @@ static int berry_probe(struct usb_interface *intf, ...@@ -105,6 +134,10 @@ static int berry_probe(struct usb_interface *intf,
/* turn the power on */ /* turn the power on */
magic_charge(udev); magic_charge(udev);
if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) &&
(pearl_dual_mode))
magic_dual_mode(udev);
/* we don't really want to bind to the device, userspace programs can /* we don't really want to bind to the device, userspace programs can
* handle the syncing just fine, so get outta here. */ * handle the syncing just fine, so get outta here. */
return -ENODEV; return -ENODEV;
...@@ -138,3 +171,5 @@ MODULE_LICENSE("GPL"); ...@@ -138,3 +171,5 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>"); MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
module_param(debug, bool, S_IRUGO | S_IWUSR); module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not"); MODULE_PARM_DESC(debug, "Debug enabled or not");
module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode");
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