/*
 * 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");
