Index: usbdevs =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs,v retrieving revision 1.581 diff -u -p -r1.581 usbdevs --- usbdevs 17 Jul 2012 09:46:22 -0000 1.581 +++ usbdevs 15 Mar 2013 13:50:35 -0000 @@ -2743,6 +2743,7 @@ product MSI BLUETOOTH_3 0xa97a Bluetoot /* Microdia / Sonix Techonology Co., Ltd. products */ product MICRODIA YUREX 0x1010 YUREX product MICRODIA CAM_1 0x62c0 CAM_1 +product MICRODIA TEMPER 0x7401 TEMPer sensor /* Micronet Communications products */ product MICRONET SP128AR 0x0003 SP128AR EtherFast Index: usbdevs.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v retrieving revision 1.591 diff -u -p -r1.591 usbdevs.h --- usbdevs.h 17 Jul 2012 09:48:22 -0000 1.591 +++ usbdevs.h 15 Mar 2013 13:50:37 -0000 @@ -2750,6 +2750,7 @@ /* Microdia / Sonix Techonology Co., Ltd. products */ #define USB_PRODUCT_MICRODIA_YUREX 0x1010 /* YUREX */ #define USB_PRODUCT_MICRODIA_CAM_1 0x62c0 /* CAM_1 */ +#define USB_PRODUCT_MICRODIA_TEMPER 0x7401 /* TEMPer sensor */ /* Micronet Communications products */ #define USB_PRODUCT_MICRONET_SP128AR 0x0003 /* SP128AR EtherFast */ Index: usbdevs_data.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v retrieving revision 1.585 diff -u -p -r1.585 usbdevs_data.h --- usbdevs_data.h 17 Jul 2012 09:48:22 -0000 1.585 +++ usbdevs_data.h 15 Mar 2013 13:50:39 -0000 @@ -6570,6 +6570,10 @@ const struct usb_known_product usb_known "CAM_1", }, { + USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_TEMPER, + "TEMPer sensor", + }, + { USB_VENDOR_MICRONET, USB_PRODUCT_MICRONET_SP128AR, "SP128AR EtherFast", }, Index: uthum.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uthum.c,v retrieving revision 1.17 diff -u -p -r1.17 uthum.c --- uthum.c 3 Jul 2011 15:47:17 -0000 1.17 +++ uthum.c 15 Mar 2013 13:50:39 -0000 @@ -54,6 +54,7 @@ int uthumdebug = 0; #define UTHUM_TYPE_TEMPER1 0x5758 /* TEMPer1 and HID TEMPer */ #define UTHUM_TYPE_TEMPER2 0x5759 #define UTHUM_TYPE_TEMPERNTC 0x575b +#define UTHUM_TYPE_TEMPERGOLD 0xff00 #define UTHUM_TYPE_UNKNOWN 0xffff /* Common */ @@ -105,6 +106,14 @@ static uint8_t cmd_issue[8] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x00, 0x02, 0x00 }; static uint8_t cmd_query[8] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x00, 0x01, 0x00 }; +static uint8_t cmd_init0_gold[2] = + { 0x01, 0x00 }; +static uint8_t cmd_init1_gold[8] = + { 0x01, 0x82, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t cmd_init2_gold[8] = + { 0x01, 0x86, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00 }; +static uint8_t cmd_query_gold[8] = + { 0x01, 0x80, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00 }; struct uthum_sensor { struct ksensor sensor; @@ -127,6 +136,8 @@ struct uthum_softc { size_t sc_ilen; /* input report length */ size_t sc_olen; /* output report length */ + uint8_t *sc_ibuf; + /* sensor framework */ struct uthum_sensor sc_sensor[UTHUM_MAX_SENSORS]; struct ksensordev sc_sensordev; @@ -136,6 +147,7 @@ struct uthum_softc { const struct usb_devno uthum_devs[] = { /* XXX: various TEMPer variants are using same VID/PID */ { USB_VENDOR_TENX, USB_PRODUCT_TENX_TEMPER}, + { USB_VENDOR_MICRODIA, USB_PRODUCT_MICRODIA_TEMPER}, }; #define uthum_lookup(v, p) usb_lookup(uthum_devs, v, p) @@ -147,6 +159,9 @@ int uthum_activate(struct device *, int int uthum_issue_cmd(struct uthum_softc *, uint8_t, int); int uthum_read_data(struct uthum_softc *, uint8_t, uint8_t *, size_t, int); int uthum_check_device_info(struct uthum_softc *); +int uthum_issue_read_cmd_gold(struct uthum_softc *); +int uthum_read_data_gold(struct uthum_softc *, uint8_t *, size_t); +int uthum_init_device_gold(struct uthum_softc *); void uthum_setup_sensors(struct uthum_softc *); void uthum_intr(struct uhidev *, void *, u_int); @@ -154,6 +169,7 @@ void uthum_refresh(void *); void uthum_refresh_temper(struct uthum_softc *, int); void uthum_refresh_temperhum(struct uthum_softc *); void uthum_refresh_temperntc(struct uthum_softc *, int); +void uthum_refresh_tempergold(struct uthum_softc *); int uthum_ntc_getdata(struct uthum_softc *, int *); int uthum_ntc_tuning(struct uthum_softc *, int, int *); @@ -205,7 +221,7 @@ uthum_attach(struct device *parent, stru struct usb_attach_arg *uaa = aux; struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa; usbd_device_handle dev = uha->parent->sc_udev; - int i, size, repid; + int i, size, repid, err; void *desc; sc->sc_udev = dev; @@ -219,19 +235,48 @@ uthum_attach(struct device *parent, stru sc->sc_ilen = hid_report_size(desc, size, hid_input, repid); sc->sc_olen = hid_report_size(desc, size, hid_output, repid); sc->sc_flen = hid_report_size(desc, size, hid_feature, repid); + sc->sc_ibuf = NULL; printf("\n"); - if (sc->sc_flen < 32) { - /* not sensor interface, just attach */ - return; - } + if (uha->uaa->vendor == USB_VENDOR_TENX && + uha->uaa->product == USB_PRODUCT_TENX_TEMPER) { + if (sc->sc_flen < 32) { + /* not sensor interface, just attach */ + return; + } + + /* sensor data comes from control pipe */ + + /* maybe unsupported device */ + if (uthum_check_device_info(sc) < 0) { + DPRINTF(("uthum: unknown device\n")); + return; + } + } else if (uha->uaa->vendor == USB_VENDOR_MICRODIA && + uha->uaa->product == USB_PRODUCT_MICRODIA_TEMPER) { + if (sc->sc_flen < 8) { + /* not sensor interface, just attach */ + return; + } - /* maybe unsupported device */ - if (uthum_check_device_info(sc) < 0) { - DPRINTF(("uthum: unknown device\n")); + /* sensor data comes from interrupt pipe */ + err = uhidev_open(&sc->sc_hdev); + if (err) { + printf("uthum: uhidev_open %d\n", err); + return; + } + sc->sc_ibuf = malloc(sc->sc_ilen, M_USBDEV, M_WAITOK); + + /* maybe unsupported device */ + if (uthum_init_device_gold(sc) < 0) { + DPRINTF(("uthum: device initialize failed\n")); + return; + } + } else { + /* unsupported device */ return; - }; + } /* attach sensor */ strlcpy(sc->sc_sensordev.xname, sc->sc_hdev.sc_dev.dv_xname, @@ -280,6 +325,11 @@ uthum_detach(struct device *self, int fl sensor_task_unregister(sc->sc_sensortask); } + if (sc->sc_ibuf != NULL) { + free(sc->sc_ibuf, M_USBDEV); + sc->sc_ibuf = NULL; + } + return (rv); } @@ -299,7 +349,15 @@ uthum_activate(struct device *self, int void uthum_intr(struct uhidev *addr, void *ibuf, u_int len) { - /* do nothing */ + struct uthum_softc *sc = (struct uthum_softc *)addr; + + if (sc->sc_ibuf == NULL) + return; + + /* receive sensor data */ + memcpy(sc->sc_ibuf, ibuf, len); + + return; } int @@ -440,6 +498,85 @@ uthum_check_device_info(struct uthum_sof return 0; }; +int +uthum_issue_read_cmd_gold(struct uthum_softc *sc) +{ + usb_device_request_t req; + + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = UR_SET_REPORT; + USETW(req.wValue, 0x0200); + USETW(req.wIndex, 0x0001); + USETW(req.wLength, sizeof(cmd_query_gold)); + if (usbd_do_request(sc->sc_udev, &req, cmd_query_gold)) + return EIO; + + return 0; +} + +int +uthum_read_data_gold(struct uthum_softc *sc, uint8_t *buf, size_t len) +{ + /* capture received data */ + if ((buf != NULL) && len != 0) + memcpy(buf, sc->sc_ibuf, len); + + /* issue next read command */ + if (uthum_issue_read_cmd_gold(sc)) + return EIO; + + return 0; +} + +int +uthum_init_device_gold(struct uthum_softc *sc) +{ + usb_device_request_t req; + usbd_status error; + + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = UR_SET_REPORT; + USETW(req.wValue, 0x0201); + USETW(req.wIndex, 0x0000); + USETW(req.wLength, sizeof(cmd_init0_gold)); + error = usbd_do_request(sc->sc_udev, &req, cmd_init0_gold); + if (error) + return EIO; + + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = UR_SET_REPORT; + USETW(req.wValue, 0x0200); + USETW(req.wIndex, 0x0001); + USETW(req.wLength, sizeof(cmd_init1_gold)); + error = usbd_do_request(sc->sc_udev, &req, cmd_init1_gold); + if (error) + return EIO; + + /* receive one interrupt message (discarded) */ + tsleep(cmd_init1_gold, 0, "uthum", (100 * hz) / 1000); + + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = UR_SET_REPORT; + USETW(req.wValue, 0x0200); + USETW(req.wIndex, 0x0001); + USETW(req.wLength, sizeof(cmd_init2_gold)); + error = usbd_do_request(sc->sc_udev, &req, cmd_init2_gold); + if (error) + return EIO; + + /* receive two interrupt messages (discarded) */ + tsleep(cmd_init2_gold, 0, "uthum", (200 * hz) / 1000); + + /* issue read command */ + if (uthum_issue_read_cmd_gold(sc)) + return EIO; + + sc->sc_sensor[0].cal_offset = 0; // XXX + sc->sc_device_type = UTHUM_TYPE_TEMPERGOLD; + + return 0; +} + void uthum_setup_sensors(struct uthum_softc *sc) { @@ -459,6 +596,7 @@ uthum_setup_sensors(struct uthum_softc * sizeof(sc->sc_sensor[UTHUM_TEMPER_OUTER].sensor.desc)); /* fall down */ case UTHUM_TYPE_TEMPER1: /* 1 temperature sensor */ + case UTHUM_TYPE_TEMPERGOLD: /* 1 temperature sensor */ sc->sc_sensor[UTHUM_TEMPER_INNER].dev_type = UTHUM_SENSOR_DS75; sc->sc_sensor[UTHUM_TEMPER_INNER].sensor.type = @@ -631,6 +769,9 @@ uthum_refresh(void *arg) case UTHUM_TYPE_TEMPERHUM: uthum_refresh_temperhum(sc); break; + case UTHUM_TYPE_TEMPERGOLD: + uthum_refresh_tempergold(sc); + break; default: break; /* never reach */ @@ -736,6 +877,32 @@ uthum_refresh_temperntc(struct uthum_sof sc->sc_sensor[sensor].sensor.value = temp; sc->sc_sensor[sensor].sensor.flags &= ~SENSOR_FINVALID; } +} + +void +uthum_refresh_tempergold(struct uthum_softc *sc) +{ + uint8_t buf[8]; + int temp; + + /* get sensor data */ + if (uthum_read_data_gold(sc, buf, sizeof(buf)) != 0) { + DPRINTF(("uthum: data read fail\n")); + sc->sc_sensor[UTHUM_TEMPER_INNER].sensor.flags + |= SENSOR_FINVALID; + return; + } + + /* check integrity */ + // XXX + temp = uthum_ds75_temp(buf[2], buf[3]); + + /* apply calibration offset */ + temp += sc->sc_sensor[UTHUM_TEMPER_INNER].cal_offset; + + sc->sc_sensor[UTHUM_TEMPER_INNER].sensor.value = + (temp * 10000) + 273150000; + sc->sc_sensor[UTHUM_TEMPER_INNER].sensor.flags &= ~SENSOR_FINVALID; } /* return C-degree * 100 value */