44#include <sys/condvar.h>
47#include <sys/kernel.h>
49#include <sys/module.h>
54#include <dev/gpio/gpiobusvar.h>
56#include <dev/iicbus/iiconf.h>
57#include <dev/iicbus/iicbus.h>
66#define USB_DEBUG_VAR usb_debug
69#define SIZEOF_FIELD(_s, _f) sizeof(((struct _s *)NULL)->_f)
71#define CP2112GPIO_LOCK(sc) sx_xlock(&sc->gpio_lock)
72#define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock)
73#define CP2112GPIO_LOCKED(sc) sx_assert(&sc->gpio_lock, SX_XLOCKED)
75#define CP2112_PART_NUM 0x0c
76#define CP2112_GPIO_COUNT 8
77#define CP2112_REPORT_SIZE 64
79#define CP2112_REQ_RESET 0x1
80#define CP2112_REQ_GPIO_CFG 0x2
81#define CP2112_REQ_GPIO_GET 0x3
82#define CP2112_REQ_GPIO_SET 0x4
83#define CP2112_REQ_VERSION 0x5
84#define CP2112_REQ_SMB_CFG 0x6
86#define CP2112_REQ_SMB_READ 0x10
87#define CP2112_REQ_SMB_WRITE_READ 0x11
88#define CP2112_REQ_SMB_READ_FORCE_SEND 0x12
89#define CP2112_REQ_SMB_READ_RESPONSE 0x13
90#define CP2112_REQ_SMB_WRITE 0x14
91#define CP2112_REQ_SMB_XFER_STATUS_REQ 0x15
92#define CP2112_REQ_SMB_XFER_STATUS_RESP 0x16
93#define CP2112_REQ_SMB_CANCEL 0x17
95#define CP2112_REQ_LOCK 0x20
96#define CP2112_REQ_USB_CFG 0x21
98#define CP2112_IIC_MAX_READ_LEN 512
99#define CP2112_IIC_REPSTART_VER 2
101#define CP2112_GPIO_SPEC_CLK7 1
102#define CP2112_GPIO_SPEC_TX0 2
103#define CP2112_GPIO_SPEC_RX1 4
105#define CP2112_IIC_STATUS0_IDLE 0
106#define CP2112_IIC_STATUS0_BUSY 1
107#define CP2112_IIC_STATUS0_CMP 2
108#define CP2112_IIC_STATUS0_ERROR 3
110#define CP2112_IIC_STATUS1_TIMEOUT_NACK 0
111#define CP2112_IIC_STATUS1_TIMEOUT_BUS 1
112#define CP2112_IIC_STATUS1_ARB_LOST 2
263 {
USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) },
264 {
USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) },
273 sc = device_get_softc(
dev);
285 sc = device_get_softc(
dev);
286 *(uint8_t *)
data =
id;
297 uaa = device_get_ivars(
dev);
304 return (BUS_PROBE_DEFAULT);
316 uaa = device_get_ivars(
dev);
317 sc = device_get_softc(
dev);
327 device_printf(
dev,
"part number 0x%02x, version 0x%02x\n",
330 device_printf(
dev,
"unsupported part number\n");
338 device_printf(
dev,
"failed to attach gpio child\n");
341 device_printf(
dev,
"failed to create gpio child\n");
346 err = device_probe_and_attach(sc->
sc_iic_dev);
348 device_printf(
dev,
"failed to attach iic child\n");
351 device_printf(
dev,
"failed to create iic child\n");
366 err = bus_generic_detach(
dev);
369 device_delete_children(
dev);
380 sc = device_get_softc(
dev);
387 *on = (
data.state & ((uint8_t)1 << pin_num)) != 0;
400 sc = device_get_softc(
dev);
403 data.state = (uint8_t)on << pin_num;
404 data.mask = (uint8_t)1 << pin_num;
426 sc = device_get_softc(
dev);
434 mask = (uint8_t)1 << pin_num;
439 data.pushpull |= mask;
442 data.pushpull &= ~mask;
448 data.output &= ~mask;
462 if (((
data.output & mask) != 0) != output)
467 if ((
data.pushpull & mask) == 0)
471 if ((
data.pushpull & mask) != 0)
475 *mode = (
data.pushpull & mask) != 0 ?
488 sc = device_get_softc(
dev);
509 sc = device_get_softc(
dev);
527 sc = device_get_softc(
dev);
547 sc = device_get_softc(
dev);
565 sc = device_get_softc(
dev);
581 sc = device_get_softc(
dev);
583 *flags = sc->
pins[pin_num].gp_flags;
597 sc = device_get_softc(
dev);
599 memcpy(
name, sc->
pins[pin_num].gp_name, GPIOMAXNAME);
609 struct gpio_pin *
pin;
616 sc = device_get_softc(
dev);
620 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 0)
622 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) ==
623 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
626 if ((flags & GPIO_PIN_INPUT) != 0) {
627 if ((flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) != 0)
630 if ((flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) ==
631 (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL))
640 if ((flags & GPIO_PIN_OUTPUT) != 0) {
641 if ((flags & GPIO_PIN_OPENDRAIN) != 0)
643 if ((flags & GPIO_PIN_PUSHPULL) != 0)
650 (flags & GPIO_PIN_OUTPUT) != 0, &out_mode);
657 if ((flags & GPIO_PIN_OUTPUT) != 0 &&
658 (flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0) {
660 (
"impossible current output mode"));
662 flags |= GPIO_PIN_OPENDRAIN;
664 flags |= GPIO_PIN_PUSHPULL;
666 pin->gp_flags = flags;
676 device_set_desc(
dev,
"CP2112 GPIO interface");
677 return (BUS_PROBE_SPECIFIC);
690 cp2112 = device_get_parent(
dev);
691 sc = device_get_softc(
dev);
694 sc->
gpio_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN |
703 struct gpio_pin *
pin;
705 mask = (uint8_t)1 << i;
709 snprintf(
pin->gp_name, GPIOMAXNAME,
"GPIO%u", i);
710 pin->gp_name[GPIOMAXNAME - 1] =
'\0';
716 }
else if ((
data.output & mask) != 0) {
717 pin->gp_flags |= GPIO_PIN_OUTPUT;
718 if ((
data.pushpull & mask) != 0)
719 pin->gp_flags |= GPIO_PIN_PUSHPULL;
721 pin->gp_flags |= GPIO_PIN_OPENDRAIN;
723 pin->gp_flags |= GPIO_PIN_INPUT;
729 device_printf(
dev,
"gpiobus_attach_bus failed\n");
744 sc = device_get_softc(
dev);
746 gpiobus_detach_bus(
dev);
759 psc = device_get_softc(device_get_parent(sc->
dev));
761 mtx_assert(&sc->
io.
lock, MA_OWNED);
774 cv_signal(&sc->
io.
cv);
777 device_printf(sc->
dev,
"write intr state %d error %d\n",
780 cv_signal(&sc->
io.
cv);
796 mtx_assert(&sc->
io.
lock, MA_OWNED);
802 device_printf(sc->
dev,
803 "interrupt while previous is pending, ignored\n");
804 }
else if (sc->
io.
in.
len == 0) {
813 if (device_is_attached(sc->
dev)) {
814 device_printf(sc->
dev,
815 "unsolicited interrupt, ignored\n");
818 len = MIN(
sizeof(buf), act_len);
820 device_printf(sc->
dev,
"data: %*D\n",
825 len = MIN(
sizeof(buf), act_len);
828 device_printf(sc->
dev,
829 "initial bus status0 = 0x%02x, "
830 "status1 = 0x%02x\n",
840 device_printf(sc->
dev,
841 "unexpected input report length %u\n", act_len);
845 cv_signal(&sc->
io.
cv);
853 device_printf(sc->
dev,
"read intr state %d error %d\n",
858 cv_signal(&sc->
io.
cv);
873 .flags = { .pipe_bof = 1, .no_pipe_ok = 1, },
881 .flags = { .pipe_bof = 1, .short_xfer_ok = 1, },
893 mtx_assert(&sc->
io.
lock, MA_OWNED);
894 KASSERT(sc->
io.
out.
done == 0, (
"%s: conflicting request", __func__));
899 DTRACE_PROBE1(send__req, uint8_t, *(
const uint8_t *)
data);
913 device_printf(sc->
dev,
"output report 0x%02x failed: %d\n",
914 *(
const uint8_t*)
data, err);
921 uint16_t req_len,
void *resp_data, uint16_t resp_len)
925 mtx_assert(&sc->
io.
lock, MA_OWNED);
931 KASSERT(sc->
io.
in.
done == 0, (
"%s: conflicting request", __func__));
960 mtx_assert(&sc->
io.
lock, MA_OWNED);
966 &xfer_status_req,
sizeof(xfer_status_req),
967 &xfer_status_resp,
sizeof(xfer_status_resp));
970 device_printf(sc->
dev,
971 "unexpected response 0x%02x to status request\n",
972 xfer_status_resp.
id);
977 DTRACE_PROBE4(xfer__status, uint8_t, xfer_status_resp.
status0,
978 uint8_t, xfer_status_resp.
status1,
979 uint16_t, be16toh(xfer_status_resp.
status2),
980 uint16_t, be16toh(xfer_status_resp.
status3));
982 switch (xfer_status_resp.
status0) {
993 switch (xfer_status_resp.
status1) {
1004 device_printf(sc->
dev,
1005 "i2c error, status = 0x%02x\n",
1012 device_printf(sc->
dev,
1013 "unknown i2c xfer status0 0x%02x\n",
1019 }
while (err == ERESTART);
1032 mtx_assert(&sc->
io.
lock, MA_OWNED);
1039 if (in_len >
sizeof(data_read_resp.
data))
1040 in_len =
sizeof(data_read_resp.
data);
1042 data_read_force_send.
len = htobe16(in_len);
1044 &data_read_force_send,
sizeof(data_read_force_send),
1045 &data_read_resp,
sizeof(data_read_resp));
1050 device_printf(sc->
dev,
1051 "unexpected response 0x%02x to data read request\n",
1057 DTRACE_PROBE2(read__response, uint8_t, data_read_resp.
status,
1058 uint8_t, data_read_resp.
len);
1070 if (data_read_resp.
len > in_len) {
1071 device_printf(sc->
dev,
"device returns more data than asked\n");
1072 err = IIC_EOVERFLOW;
1076 *out_len = data_read_resp.
len;
1078 memcpy(
data, data_read_resp.
data, *out_len);
1088 const char *reason = NULL;
1090 uint16_t read_off, to_read;
1105 for (i = 0; i < nmsgs; i++) {
1106 if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
1107 reason =
"first message without start";
1110 if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
1111 reason =
"last message without stop";
1114 if (msgs[i].
len == 0) {
1115 reason =
"message with no data";
1118 if ((msgs[i].flags & IIC_M_RD) != 0 &&
1120 reason =
"too long read";
1123 if ((msgs[i].flags & IIC_M_RD) == 0 &&
1125 reason =
"too long write";
1128 if ((msgs[i].flags & IIC_M_NOSTART) != 0) {
1129 reason =
"message without start or repeated start";
1132 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
1133 (msgs[i].flags & IIC_M_RD) != 0) {
1134 reason =
"read without stop";
1137 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
1139 reason =
"write without stop";
1142 if ((msgs[i].flags & IIC_M_NOSTOP) != 0 &&
1144 reason =
"too long write without stop";
1148 if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
1149 msgs[i].slave != msgs[i - 1].slave) {
1150 reason =
"change of slave without stop";
1153 if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
1154 (msgs[i].flags & IIC_M_RD) == 0) {
1155 reason =
"write after repeated start";
1160 if (reason != NULL) {
1162 device_printf(
dev,
"unsupported i2c message: %s\n",
1164 return (IIC_ENOTSUPP);
1169 for (i = 0; i < nmsgs; i++) {
1170 if (i + 1 < nmsgs && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
1177 KASSERT((msgs[i].flags & IIC_M_RD) == 0,
1178 (
"read without stop"));
1179 KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0,
1180 (
"write after write without stop"));
1182 req.slave = msgs[i].slave & ~LSB;
1183 to_read = msgs[i + 1].len;
1184 req.rlen = htobe16(to_read);
1185 req.wlen = msgs[i].len;
1186 memcpy(
req.wdata, msgs[i].buf, msgs[i].len);
1194 }
else if ((msgs[i].flags & IIC_M_RD) != 0) {
1198 req.slave = msgs[i].slave & ~LSB;
1199 to_read = msgs[i].len;
1200 req.len = htobe16(to_read);
1206 req.slave = msgs[i].slave & ~LSB;
1207 req.len = msgs[i].len;
1208 memcpy(
req.data, msgs[i].buf, msgs[i].len);
1220 while (to_read > 0) {
1224 to_read, &act_read);
1227 KASSERT(act_read <= to_read, (
"cp2112iic_read_data "
1228 "returned more data than asked"));
1229 read_off += act_read;
1230 to_read -= act_read;
1236 mtx_unlock(&sc->
io.
lock);
1249 sc = device_get_softc(
dev);
1250 cp2112 = device_get_parent(
dev);
1254 busfreq = IICBUS_GET_FREQUENCY(sc->
iicbus_dev, speed);
1257 &i2c_cfg,
sizeof(i2c_cfg));
1259 device_printf(
dev,
"failed to get CP2112_REQ_SMB_CFG report\n");
1263 if (oldaddr != NULL)
1277 i2c_cfg.
speed = htobe32(busfreq);
1284 device_printf(
dev,
"speed %d Hz\n", be32toh(i2c_cfg.
speed));
1285 device_printf(
dev,
"slave addr 0x%02x\n", i2c_cfg.
slave_addr);
1286 device_printf(
dev,
"auto send read %s\n",
1288 device_printf(
dev,
"write timeout %d ms (0 - disabled)\n",
1290 device_printf(
dev,
"read timeout %d ms (0 - disabled)\n",
1292 device_printf(
dev,
"scl low timeout %s\n",
1294 device_printf(
dev,
"retry count %d (0 - no limit)\n",
1298 &i2c_cfg,
sizeof(i2c_cfg));
1300 device_printf(
dev,
"failed to set CP2112_REQ_SMB_CFG report\n");
1309 device_set_desc(
dev,
"CP2112 I2C interface");
1310 return (BUS_PROBE_SPECIFIC);
1321 sc = device_get_softc(
dev);
1323 cp2112 = device_get_parent(
dev);
1324 psc = device_get_softc(cp2112);
1326 mtx_init(&sc->
io.
lock,
"cp2112iic lock", NULL, MTX_DEF | MTX_RECURSE);
1327 cv_init(&sc->
io.
cv,
"cp2112iic cv");
1333 device_printf(
dev,
"usbd_transfer_setup failed %d\n", err);
1340 mtx_unlock(&sc->
io.
lock);
1344 device_printf(
dev,
"iicbus creation failed\n");
1348 bus_generic_attach(
dev);
1362 sc = device_get_softc(
dev);
1363 err = bus_generic_detach(
dev);
1366 device_delete_children(
dev);
1370 mtx_unlock(&sc->
io.
lock);
1373 cv_destroy(&sc->
io.
cv);
1374 mtx_destroy(&sc->
io.
lock);
1388 .name =
"cp2112hid",
1442 DEVMETHOD(iicbus_callback, iicbus_null_callback),
static device_method_t cp2112hid_methods[]
#define CP2112_GPIO_COUNT
#define CP2112_REQ_SMB_READ_FORCE_SEND
#define CP2112_IIC_STATUS1_ARB_LOST
USB_PNP_HOST_INFO(cp2112_devs)
static int cp2112iic_check_req_status(struct cp2112iic_softc *sc)
#define CP2112GPIO_LOCKED(sc)
#define CP2112_REQ_SMB_CFG
#define CP2112_GPIO_SPEC_TX0
static int cp2112iic_attach(device_t dev)
static int cp2112_gpio_pin_getname(device_t dev, uint32_t pin_num, char *name)
static driver_t cp2112hid_driver
static int cp2112_gpio_pin_getcaps(device_t dev, uint32_t pin_num, uint32_t *caps)
static int cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num, bool output, enum cp2112_out_mode *mode)
static void cp2112iic_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
#define CP2112GPIO_UNLOCK(sc)
static int cp2112_gpio_pin_set(device_t dev, uint32_t pin_num, uint32_t pin_value)
static driver_t cp2112iic_driver
static int cp2112gpio_probe(device_t dev)
#define CP2112_REQ_SMB_WRITE
static int cp2112gpio_detach(device_t dev)
static const STRUCT_USB_HOST_ID cp2112_devs[]
static int cp2112_attach(device_t dev)
MODULE_DEPEND(cp2112hid, usb, 1, 1, 1)
DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass, NULL, NULL)
static device_t cp2112_gpio_get_bus(device_t dev)
static int cp2112iic_send_req(struct cp2112iic_softc *sc, const void *data, uint16_t len)
#define CP2112_IIC_STATUS0_BUSY
static int cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on)
static int cp2112_gpio_pin_toggle(device_t dev, uint32_t pin_num)
static int cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
static int cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on)
static void cp2112iic_intr_write_callback(struct usb_xfer *xfer, usb_error_t error)
static int cp2112_set_report(device_t dev, uint8_t id, void *data, uint16_t len)
static int cp2112_gpio_pin_get(device_t dev, uint32_t pin_num, uint32_t *pin_value)
#define CP2112_REQ_SMB_READ_RESPONSE
static int cp2112_gpio_pin_max(device_t dev, int *maxpin)
MODULE_VERSION(cp2112hid, 1)
static devclass_t cp2112gpio_devclass
#define CP2112GPIO_LOCK(sc)
static devclass_t cp2112iic_devclass
static device_method_t cp2112iic_methods[]
static int cp2112_detach(device_t dev)
#define CP2112_IIC_MAX_READ_LEN
static int cp2112_probe(device_t dev)
static devclass_t cp2112hid_devclass
#define SIZEOF_FIELD(_s, _f)
static const struct usb_config cp2112iic_config[CP2112_N_TRANSFER]
#define CP2112_IIC_STATUS0_ERROR
static int cp2112gpio_attach(device_t dev)
struct version_request __packed
#define CP2112_IIC_STATUS0_CMP
#define CP2112_REQ_SMB_WRITE_READ
static int cp2112iic_req_resp(struct cp2112iic_softc *sc, const void *req_data, uint16_t req_len, void *resp_data, uint16_t resp_len)
static driver_t cp2112gpio_driver
#define CP2112_REQ_SMB_XFER_STATUS_REQ
#define CP2112_REQ_SMB_READ
static int cp2112iic_probe(device_t dev)
static int cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len, uint16_t *out_len)
static device_method_t cp2112gpio_methods[]
#define CP2112_REQ_GPIO_SET
static int cp2112iic_detach(device_t dev)
#define CP2112_IIC_REPSTART_VER
#define CP2112_IIC_STATUS1_TIMEOUT_BUS
#define CP2112_REQ_GPIO_GET
#define CP2112_REQ_VERSION
#define CP2112_REPORT_SIZE
#define CP2112_GPIO_SPEC_CLK7
#define CP2112_GPIO_SPEC_RX1
#define CP2112_REQ_GPIO_CFG
#define CP2112_REQ_SMB_XFER_STATUS_RESP
#define CP2112_IIC_STATUS0_IDLE
static int cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
static int cp2112_gpio_pin_getflags(device_t dev, uint32_t pin_num, uint32_t *flags)
static int cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags)
#define CP2112_IIC_STATUS1_TIMEOUT_NACK
static int cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len)
struct usb_device * sc_udev
struct gpio_pin pins[CP2112_GPIO_COUNT]
struct usb_xfer * xfers[CP2112_N_TRANSFER]
struct cp2112iic_softc::@20 io
struct cp2112iic_softc::@20::@21 in
struct cp2112iic_softc::@20::@22 out
enum usb_hc_mode usb_mode
struct usbd_lookup_info info
struct usb_device * device
void usbd_copy_in(struct usb_page_cache *cache, usb_frlength_t offset, const void *ptr, usb_frlength_t len)
void usbd_copy_out(struct usb_page_cache *cache, usb_frlength_t offset, void *ptr, usb_frlength_t len)
int usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id, struct usb_attach_arg *uaa)
usb_error_t usbd_req_set_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
usb_error_t usbd_req_get_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id)
void usbd_transfer_submit(struct usb_xfer *xfer)
void usbd_xfer_set_frames(struct usb_xfer *xfer, usb_frcount_t n)
void usbd_transfer_unsetup(struct usb_xfer **pxfer, uint16_t n_setup)
void usbd_xfer_set_frame_len(struct usb_xfer *xfer, usb_frcount_t frindex, usb_frlength_t len)
struct usb_page_cache * usbd_xfer_get_frame(struct usb_xfer *xfer, usb_frcount_t frindex)
usb_error_t usbd_transfer_setup(struct usb_device *udev, const uint8_t *ifaces, struct usb_xfer **ppxfer, const struct usb_config *setup_start, uint16_t n_setup, void *priv_sc, struct mtx *xfer_mtx)
void usbd_transfer_start(struct usb_xfer *xfer)
void * usbd_xfer_softc(struct usb_xfer *xfer)
void usbd_xfer_set_stall(struct usb_xfer *xfer)
void usbd_transfer_stop(struct usb_xfer *xfer)
void usbd_xfer_status(struct usb_xfer *xfer, int *actlen, int *sumlen, int *aframes, int *nframes)
usb_frlength_t usbd_xfer_max_len(struct usb_xfer *xfer)
void device_set_usb_desc(device_t dev)
#define USB_VP(vend, prod)
#define USB_ST_TRANSFERRED
#define STRUCT_USB_HOST_ID
#define USB_GET_STATE(xfer)
#define UHID_FEATURE_REPORT