| /* |
| * Copyright (c) 2013-2015 Travis Geiselbrecht |
| * Copyright (c) 2017 The Fuchsia Authors |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files |
| * (the "Software"), to deal in the Software without restriction, |
| * including without limitation the rights to use, copy, modify, merge, |
| * publish, distribute, sublicense, and/or sell copies of the Software, |
| * and to permit persons to whom the Software is furnished to do so, |
| * subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| #include <app/zedmon/usb.h> |
| #include <lk/debug.h> |
| #include <dev/gpio.h> |
| #include <dev/i2c.h> |
| #include <dev/usb.h> |
| #include <dev/usbc.h> |
| #include <dev/usb/class/cdcserial.h> |
| #include <lk/err.h> |
| #include <hw/usb.h> |
| #include <lib/cdcconsole/cdcconsole.h> |
| #include <lk/init.h> |
| #include <stdio.h> |
| #include <stm32f0xx.h> |
| #include <target.h> |
| #include <target/gpioconfig.h> |
| #include <lk/trace.h> |
| |
| #define LOCAL_TRACE 0 |
| |
| #define W(w) (w & 0xff), (w >> 8) |
| #define W3(w) (w & 0xff), ((w >> 8) & 0xff), ((w >> 16) & 0xff) |
| |
| /* top level device descriptor */ |
| static const uint8_t dev_descr[] = { |
| 0x12, /* descriptor length */ |
| DEVICE, /* Device Descriptor type */ |
| W(0x0200), /* USB Version */ |
| 239, /* class */ |
| 2, /* subclass */ |
| 1, /* protocol */ |
| 64, /* max packet size, ept0 */ |
| W(0x18d1), /* vendor */ |
| W(0xaf00), /* product */ |
| W(0x0000), /* release */ |
| 0x2, /* manufacturer string */ |
| 0x1, /* product string */ |
| 0x3, /* serialno string */ |
| 0x1, /* num configs */ |
| }; |
| |
| /* high/low speed device qualifier */ |
| static const uint8_t devqual_descr[] = { |
| 0x0a, /* len */ |
| DEVICE_QUALIFIER, /* Device Qualifier type */ |
| W(0x0200), /* USB version */ |
| 0x00, /* class */ |
| 0x00, /* subclass */ |
| 0x00, /* protocol */ |
| 64, /* max packet size, ept0 */ |
| 0x01, /* num configs */ |
| 0x00 /* reserved */ |
| }; |
| |
| static const uint8_t cfg_descr[] = { |
| 0x09, /* Length of Cfg Descr */ |
| CONFIGURATION, /* Type of Cfg Descr */ |
| W(0x09), /* Total Length (incl ifc, ept) */ |
| 0x00, /* # Interfaces */ |
| 0x01, /* Cfg Value */ |
| 0x00, /* Cfg String */ |
| 0xc0, /* Attributes -- self powered */ |
| 250, /* Power Consumption - 500mA */ |
| }; |
| |
| static const uchar langid[] = { 0x04, 0x03, 0x09, 0x04 }; |
| |
| usb_config config = { |
| .lowspeed = { |
| .device = USB_DESC_STATIC(dev_descr), |
| .device_qual = USB_DESC_STATIC(devqual_descr), |
| .config = USB_DESC_STATIC(cfg_descr), |
| }, |
| .highspeed = { |
| .device = USB_DESC_STATIC(dev_descr), |
| .device_qual = USB_DESC_STATIC(devqual_descr), |
| .config = USB_DESC_STATIC(cfg_descr), |
| }, |
| |
| .langid = USB_DESC_STATIC(langid), |
| }; |
| |
| static const char *hex_digits = "0123456789abcdef"; |
| static cdcconsole_t cdc_console; |
| |
| static const uint8_t SX1509_ADDR = 0x3e; |
| static uint8_t gpio_state = 0; |
| |
| static status_t sx1509_write(uint8_t reg, uint8_t val) { |
| status_t ret = i2c_write_reg_bytes(INA_BUS, SX1509_ADDR, reg, &val, 1); |
| if (ret != NO_ERROR) { |
| return ret; |
| } |
| |
| return NO_ERROR; |
| } |
| |
| static status_t sx1509_read(uint8_t reg, uint8_t *val) { |
| status_t ret = i2c_read_reg_bytes(INA_BUS, SX1509_ADDR, reg, val, 1); |
| if (ret != NO_ERROR) { |
| return ret; |
| } |
| return NO_ERROR; |
| } |
| void set_serial_substr(uint32_t val, char *str) { |
| int i; |
| for (i = 0; i < 8; i++) { |
| *str++ = hex_digits[(val >> 28) & 0xf]; |
| val <<= 4; |
| } |
| } |
| |
| void zedmon_usb_set_target_out(int index, bool value) { |
| if (index == 0) { |
| gpio_set(GPIO_POWER_ENABLE_J, !value); |
| } else if (0 < index && index <=4 ) { |
| uint8_t mask = 1 << (index - 1); |
| if (value) { |
| gpio_state |= mask; |
| } else { |
| gpio_state &= ~mask; |
| } |
| sx1509_write(0x11, gpio_state); |
| } |
| } |
| |
| void target_usb_setup(void) |
| { |
| sx1509_write(0x0f, 0x00); |
| |
| usb_setup(&config); |
| printf("appending interfaces\n"); |
| #ifdef ZEDMON_USB_CONSOLE |
| cdcconsole_init(&cdc_console, 0x1, 0x2); |
| zedmon_usb_init(0x3); |
| #else |
| zedmon_usb_init(0x1); |
| #endif |
| |
| usb_add_string("Zedmon", 1); |
| usb_add_string("Google Inc.", 2); |
| |
| char serial_no[25]; |
| volatile uint32_t *uid_regs = (volatile uint32_t *)UID_BASE; |
| int i; |
| for (i = 0; i < 3; i++) { |
| set_serial_substr(uid_regs[i], &serial_no[(2 - i) * 8]); |
| } |
| serial_no[24] = '\0'; |
| usb_add_string(serial_no, 3); |
| |
| usb_start(); |
| } |