summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-08-23 02:48:05 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-08-23 02:48:05 +0000
commit2c80c3c26f475056eb4a9edc7ba16e0656c6117c (patch)
treea66453755255f231cc0def4c543378708360a137
parent4597103f1a7e2f234a9416853046746566a65d6c (diff)
"correctly" activate high-power charging on (hopefully) all devices,
based on work in barry/bcharge; tested on a few units. still not tested on pearl-style units... if someone has one, contact me please
-rw-r--r--sys/dev/usb/uberry.c67
1 files changed, 63 insertions, 4 deletions
diff --git a/sys/dev/usb/uberry.c b/sys/dev/usb/uberry.c
index cac18528e4a..8704c9ee2f5 100644
--- a/sys/dev/usb/uberry.c
+++ b/sys/dev/usb/uberry.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uberry.c,v 1.10 2007/06/14 10:11:15 mbalmer Exp $ */
+/* $OpenBSD: uberry.c,v 1.11 2007/08/23 02:48:04 deraadt Exp $ */
/*-
* Copyright (c) 2006 Theo de Raadt <deraadt@openbsd.org>
@@ -34,6 +34,7 @@
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
@@ -43,10 +44,12 @@ struct uberry_softc {
usbd_interface_handle sc_iface;
};
-#define UBERRY_CONFIG_NO 0
+#define UBERRY_CONFIG_NO 1
struct usb_devno const uberry_devices[] = {
- { USB_VENDOR_RIM, USB_PRODUCT_RIM_BLACKBERRY }
+ { USB_VENDOR_RIM, USB_PRODUCT_RIM_BLACKBERRY },
+ { USB_VENDOR_RIM, USB_PRODUCT_RIM_PEARL_DUAL },
+ { USB_VENDOR_RIM, USB_PRODUCT_RIM_PEARL }
};
int uberry_match(struct device *, void *, void *);
@@ -54,6 +57,9 @@ void uberry_attach(struct device *, struct device *, void *);
int uberry_detach(struct device *, int);
int uberry_activate(struct device *, enum devact);
+void uberry_pearlmode(struct uberry_softc *);
+void uberry_charge(struct uberry_softc *);
+
struct cfdriver uberry_cd = {
NULL, "uberry", DV_DULL
};
@@ -83,10 +89,13 @@ uberry_attach(struct device *parent, struct device *self, void *aux)
{
struct uberry_softc *sc = (struct uberry_softc *)self;
struct usb_attach_arg *uaa = aux;
+ usb_device_descriptor_t *dd;
char *devinfop;
sc->sc_udev = uaa->device;
+ dd = usbd_get_device_descriptor(uaa->device);
+
devinfop = usbd_devinfo_alloc(uaa->device, 0);
printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
usbd_devinfo_free(devinfop);
@@ -97,7 +106,22 @@ uberry_attach(struct device *parent, struct device *self, void *aux)
sc->sc_dev.dv_xname);
return;
}
- printf("%s: Charging enabled\n", sc->sc_dev.dv_xname);
+
+ printf("%s: Charging at %dmA", sc->sc_dev.dv_xname,
+ sc->sc_udev->power);
+ if (sc->sc_udev->power >= 250)
+ printf("\n");
+ else {
+ printf("... requesting higher-power charging\n");
+ uberry_charge(sc);
+ usb_needs_reattach(sc->sc_udev);
+ }
+
+ if (UGETW(dd->idProduct) == USB_PRODUCT_RIM_PEARL) {
+ /* Request a change to Dual mode */
+ uberry_pearlmode(sc);
+ usb_needs_reattach(sc->sc_udev);
+ }
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
&sc->sc_dev);
@@ -126,3 +150,38 @@ uberry_activate(struct device *self, enum devact act)
}
return 0;
}
+
+void
+uberry_pearlmode(struct uberry_softc *sc)
+{
+ usb_device_request_t req;
+ char buffer[256];
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = 0xa9;
+ USETW(req.wValue, 1);
+ USETW(req.wIndex, 1);
+ USETW(req.wLength, 2);
+ (void) usbd_do_request(sc->sc_udev, &req, &buffer);
+}
+
+void
+uberry_charge(struct uberry_softc *sc)
+{
+ usb_device_request_t req;
+ char buffer[256];
+
+ req.bmRequestType = UT_READ_VENDOR_DEVICE;
+ req.bRequest = 0xa5;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, 1);
+ USETW(req.wLength, 2);
+ (void) usbd_do_request(sc->sc_udev, &req, &buffer);
+
+ req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
+ req.bRequest = 0xa2;
+ USETW(req.wValue, 0);
+ USETW(req.wIndex, 1);
+ USETW(req.wLength, 0);
+ (void) usbd_do_request(sc->sc_udev, &req, &buffer);
+}