Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Jeremy Katz <katzj@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Jeremy Katz and committed by
Greg Kroah-Hartman
49bb607f 165fe97e

+35
+35
drivers/usb/misc/berry_charge.c
··· 26 26 27 27 #define RIM_VENDOR 0x0fca 28 28 #define BLACKBERRY 0x0001 29 + #define BLACKBERRY_PEARL_DUAL 0x0004 30 + #define BLACKBERRY_PEARL 0x0006 29 31 30 32 static int debug; 33 + static int pearl_dual_mode = 1; 31 34 32 35 #ifdef dbg 33 36 #undef dbg ··· 41 38 42 39 static struct usb_device_id id_table [] = { 43 40 { USB_DEVICE(RIM_VENDOR, BLACKBERRY) }, 41 + { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) }, 42 + { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) }, 44 43 { }, /* Terminating entry */ 45 44 }; 46 45 MODULE_DEVICE_TABLE(usb, id_table); ··· 91 86 return retval; 92 87 } 93 88 89 + static int magic_dual_mode(struct usb_device *udev) 90 + { 91 + char *dummy_buffer = kzalloc(2, GFP_KERNEL); 92 + int retval; 93 + 94 + if (!dummy_buffer) 95 + return -ENOMEM; 96 + 97 + /* send magic command so that the Blackberry Pearl device exposes 98 + * two interfaces: both the USB mass-storage one and one which can 99 + * be used for database access. */ 100 + dbg(&udev->dev, "Sending magic pearl command\n"); 101 + retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 102 + 0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100); 103 + dbg(&udev->dev, "Magic pearl command returned %d\n", retval); 104 + 105 + dbg(&udev->dev, "Calling set_configuration\n"); 106 + retval = usb_driver_set_configuration(udev, 1); 107 + if (retval) 108 + dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); 109 + 110 + return retval; 111 + } 112 + 94 113 static int berry_probe(struct usb_interface *intf, 95 114 const struct usb_device_id *id) 96 115 { ··· 133 104 134 105 /* turn the power on */ 135 106 magic_charge(udev); 107 + 108 + if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) && 109 + (pearl_dual_mode)) 110 + magic_dual_mode(udev); 136 111 137 112 /* we don't really want to bind to the device, userspace programs can 138 113 * handle the syncing just fine, so get outta here. */ ··· 171 138 MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>"); 172 139 module_param(debug, bool, S_IRUGO | S_IWUSR); 173 140 MODULE_PARM_DESC(debug, "Debug enabled or not"); 141 + module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR); 142 + MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode");