diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-08-23 02:48:05 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-08-23 02:48:05 +0000 |
commit | 2c80c3c26f475056eb4a9edc7ba16e0656c6117c (patch) | |
tree | a66453755255f231cc0def4c543378708360a137 /sys/dev | |
parent | 4597103f1a7e2f234a9416853046746566a65d6c (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
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/uberry.c | 67 |
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); +} |