Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 48728
b: refs/heads/master
c: df23fa0
h: refs/heads/master
v: v3
  • Loading branch information
Greg Kroah-Hartman committed Feb 16, 2007
1 parent 1656fef commit 990c6ca
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8903795a5275e0366acf961190c57074ad27f9bb
refs/heads/master: df23fa01acc77444453633e1dec59cd7a4ea8ec3
1 change: 1 addition & 0 deletions trunk/drivers/usb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB_ADUTUX) += misc/
obj-$(CONFIG_USB_APPLEDISPLAY) += misc/
obj-$(CONFIG_USB_AUERSWALD) += misc/
obj-$(CONFIG_USB_BERRY_CHARGE) += misc/
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/
Expand Down
11 changes: 11 additions & 0 deletions trunk/drivers/usb/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ config USB_LCD
To compile this driver as a module, choose M here: the
module will be called usblcd.

config USB_BERRY_CHARGE
tristate "USB BlackBerry recharge support"
depends on USB
help
Say Y here if you want to connect a BlackBerry device to your
computer's USB port and have it automatically switch to "recharge"
mode.

To compile this driver as a module, choose M here: the
module will be called berry_charge.

config USB_LED
tristate "USB LED driver support"
depends on USB
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
obj-$(CONFIG_USB_ADUTUX) += adutux.o
obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
obj-$(CONFIG_USB_CYTHERM) += cytherm.o
obj-$(CONFIG_USB_EMI26) += emi26.o
Expand Down
140 changes: 140 additions & 0 deletions trunk/drivers/usb/misc/berry_charge.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* USB BlackBerry charging module
*
* Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
*
* 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, version 2.
*
* Information on how to switch configs was taken by the bcharge.cc file
* created by the barry.sf.net project.
*
* bcharge.cc has the following copyright:
* Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
* and is released under the GPLv2.
*
*
*/

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>

#define RIM_VENDOR 0x0fca
#define BLACKBERRY 0x0001

static int debug;

#ifdef dbg
#undef dbg
#endif
#define dbg(dev, format, arg...) \
if (debug) \
dev_printk(KERN_DEBUG , dev , format , ## arg)

static struct usb_device_id id_table [] = {
{ USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);

static int magic_charge(struct usb_device *udev)
{
char *dummy_buffer = kzalloc(2, GFP_KERNEL);
int retval;

if (!dummy_buffer)
return -ENOMEM;

/* send two magic commands and then set the configuration. The device
* will then reset itself with the new power usage and should start
* charging. */

/* Note, with testing, it only seems that the first message is really
* needed (at least for the 8700c), but to be safe, we emulate what
* other operating systems seem to be sending to their device. We
* really need to get some specs for this device to be sure about what
* is going on here.
*/
dbg(&udev->dev, "Sending first magic command\n");
retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
if (retval != 2) {
dev_err(&udev->dev, "First magic command failed: %d.\n",
retval);
return retval;
}

dbg(&udev->dev, "Sending first magic command\n");
retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
if (retval != 0) {
dev_err(&udev->dev, "Second magic command failed: %d.\n",
retval);
return 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,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);

dbg(&udev->dev, "Power is set to %dmA\n",
udev->actconfig->desc.bMaxPower * 2);

/* check the power usage so we don't try to enable something that is
* already enabled */
if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
dbg(&udev->dev, "device is already charging, power is "
"set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
return -ENODEV;
}

/* turn the power on */
magic_charge(udev);

/* we don't really want to bind to the device, userspace programs can
* handle the syncing just fine, so get outta here. */
return -ENODEV;
}

static void berry_disconnect(struct usb_interface *intf)
{
}

static struct usb_driver berry_driver = {
.name = "berry_charge",
.probe = berry_probe,
.disconnect = berry_disconnect,
.id_table = id_table,
};

static int __init berry_init(void)
{
return usb_register(&berry_driver);
}

static void __exit berry_exit(void)
{
usb_deregister(&berry_driver);
}

module_init(berry_init);
module_exit(berry_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");

0 comments on commit 990c6ca

Please sign in to comment.