i2c-tiny-usb is a small usb to i2c bridge
PATCH RESEND v5 1/1 i2c-tiny-usb is a small usb to i2c bridge
Hi
Probably due to my less then stellar patch to mail handling i think this patch got forgotten. I think its ok to resend.
The patch itself is unchanged. It should incorperate all sugestions but the one of Peter due not beeing mainlined:
https://lists.gnu.org/archive/html/qemu-devel/2015-10/msg04237.html
Here are some pointers to the old discussion:
https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg00111.html
https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg02634.html
Best regards
Tim
i2c-tiny-usb is a small usb to i2c bridge:
http://www.harbaum.org/till/i2c_tiny_usb/index.shtml
It is pretty simple and has no usb endpoints just a control. Reasons for adding this device:
* Linux device driver available
* adding an additional i2c bus via command line e.g. -device usb-i2c-tiny,id=i2c-0 -device tmp105,bus=i2c,address=0x50
---
default-configs/usb.mak | 1 + hw/usb/Makefile.objs | 1 + hw/usb/dev-i2c-tiny.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 11 ++ 4 files changed, 327 insertions(+) create mode 100644 hw/usb/dev-i2c-tiny.c
default-configs/usb.mak +1 -0
@@ -8,3 +8,4 @@ CONFIG_USB_AUDIO=y CONFIG_USB_SERIAL=y CONFIG_USB_NETWORK=y CONFIG_USB_BLUETOOTH=y +CONFIG_USB_I2C_TINY=y
hw/usb/Makefile.objs +1 -0
@@ -20,6 +20,7 @@ common-obj-$(CONFIG_USB_AUDIO) += dev-audio.o common-obj-$(CONFIG_USB_SERIAL) += dev-serial.o common-obj-$(CONFIG_USB_NETWORK) += dev-network.o common-obj-$(CONFIG_USB_BLUETOOTH) += dev-bluetooth.o +common-obj-$(CONFIG_USB_I2C_TINY) += dev-i2c-tiny.o ifeq ($(CONFIG_USB_SMARTCARD),y) common-obj-y += dev-smartcard-reader.o
hw/usb/dev-i2c-tiny.c new file +61 -0
61 lines not on this page · raw message
*/
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /*1-byte reg.
addr.*/
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /*I2C-like blk-
xfer*/
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte
regadr*/
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */
+
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
+ I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
+ I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
+ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+
+#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \
+ I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_I2C_BLOCK)
+
+#define DeviceOutVendor ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) +#define DeviceInVendor ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) +
+typedef struct {
+ USBDevice dev;
+ I2CBus *i2cbus;
+} USBI2CTinyState;
+
+#define TYPE_USB_I2C_TINY "usb-i2c"
+#define USB_I2C_TINY_DEV(obj) OBJECT_CHECK(USBI2CTinyState, \
+ (obj), TYPE_USB_I2C_TINY)
+
+enum {
+ STR_MANUFACTURER = 1,
+ STR_PRODUCT_SERIAL,
+ STR_SERIALNUMBER,
+};
+
+static const USBDescStrings desc_strings = {
+ [STR_MANUFACTURER] = "QEMU",
+ [STR_PRODUCT_SERIAL] = "QEMU USB I2C Tiny",
+ [STR_SERIALNUMBER] = "1",
+};
+
+static const USBDescIface desc_iface0 = {
+ .bInterfaceNumber = 1,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = 0xff,
+ .bInterfaceSubClass = 0xff,
+ .bInterfaceProtocol = 0xff,
+ .eps = (USBDescEndpoint[]) {
+ }
+};
+
+static const USBDescDevice desc_device = {
+ .bcdUSB = 0x0110,
+ .bMaxPacketSize0 = 8,
+ .bNumConfigurations = 1,
+ .confs = (const USBDescConfig[]) {
+ {
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .bmAttributes = USB_CFG_ATT_ONE,
+ .bMaxPower = 50,
+ .nif = 1,
+ .ifs = &desc_iface0,+ },
+ },
+};
+
+static const USBDesc desc_usb_i2c = {
+ .id = {
+ .idVendor = 0x0403, + .idProduct = 0xc631, + .bcdDevice = 0x0205, + .iManufacturer = STR_MANUFACTURER, + .iProduct = STR_PRODUCT_SERIAL, + .iSerialNumber = STR_SERIALNUMBER, + }, + .full = &desc_device, + .str = desc_strings,
+};
+
+static void usb_i2c_handle_reset(USBDevice *dev)
+{
+ trace_usb_i2c_tiny_reset();
+}
+
+static void usb_i2c_handle_control(USBDevice *dev, USBPacket *p,
+ int request, int value, int index, int length, uint8_t *data)
+{
+ USBI2CTinyState *s = (USBI2CTinyState *)dev; + int ret,i, i2c_value; + uint32_t func;
+
+ ret = usb_desc_handle_control(dev, p, request, value, index, length,
data);
+ if (ret >= 0) {
+ return;
+ }
+
+ switch (request) {
+ case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
+ break;
+ case 0x4102:
+ /* set clock, ignore */ + trace_usb_i2c_tiny_set_clock(); + break;
+
+ case 0x4105:
+ trace_usb_i2c_tiny_unknown_request(index, request, value, length);
+ break;
+
+ case 0x4107:
+ /* this seems to be a byte type access */
+ if (i2c_start_transfer(s->i2cbus, /*address*/index, 0)) {
+ trace_usb_i2c_tiny_i2c_start_transfer_failed(); + p->actual_length = 0; /* write failure */ + break;
+ }
+ for (i = 0; i < length; i++) {
+ trace_usb_i2c_tiny_write(request, index, i, data[i]);
+ i2c_send(s->i2cbus, data[i]);
+ } + p->actual_length = length; + i2c_end_transfer(s->i2cbus); + break;
+
+ case 0xc101:
+ /* thats what the real thing reports, FIXME: can we do better here?
*/
+ func = htole32(I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL); + memcpy(data, &func, sizeof(func)); + p->actual_length = sizeof(func); + trace_usb_i2c_tiny_functionality_read(length); + break; + + case 0xc103: + trace_usb_i2c_tiny_unknown_request(index, request, value, length); + p->actual_length = 1; + break;
+
+ case 0xc106:
+ case 0xc107:
+ if (i2c_start_transfer(s->i2cbus, /*address*/ index, 1)) {
+ trace_usb_i2c_tiny_i2c_start_transfer_failed(); + p->actual_length = 0; + break;
+ }
+ if(request&1) {
+ i2c_send(s->i2cbus, data[0]);
+ i2c_start_transfer(s->i2cbus, /*address*/ index, 1);
+ }
+ for (i = 0; i < length; i++) {
+ i2c_value = i2c_recv(s->i2cbus);
+ if (i2c_value < 0) {
+ break;
+ }
+ data[i] = i2c_value;
+ trace_usb_i2c_tiny_read(request, index, i, data[i]);
+ }
+ if(request&1) {
+ i2c_nack(s->i2cbus);
+ }
+ p->actual_length = length;
+ i2c_end_transfer(s->i2cbus);
+ break;
+
+ default:
+ p->status = USB_RET_STALL;
+ trace_usb_i2c_tiny_unknown_request(index, request, value, length);
+ break;+ }
+}
+
+static void usb_i2c_handle_data(USBDevice *dev, USBPacket *p) +{
+ trace_usb_i2c_tiny_usb_i2c_handle_data();
+}
+
+static void usb_i2c_realize(USBDevice *dev, Error **errp) +{
+ USBI2CTinyState *s = (USBI2CTinyState *)dev;
+ Error *local_err = NULL;
+
+ usb_desc_create_serial(dev);
+ usb_desc_init(dev);
+
+ usb_check_attach(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ } + s->i2cbus = i2c_init_bus(&dev->qdev, "i2c"); + usb_i2c_handle_reset(dev);
+}
+
+static const VMStateDescription vmstate_usb_i2c = {
+ .name = "usb-i2c-tiny",
+};
+
+static Property usbi2c_properties[] = {
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void usb_i2c_dev_class_init(ObjectClass *klass, void *data) +{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+ uc->realize = usb_i2c_realize;
+ uc->handle_reset = usb_i2c_handle_reset;
+ uc->handle_control = usb_i2c_handle_control;
+ uc->handle_data = usb_i2c_handle_data;
+ dc->vmsd = &vmstate_usb_i2c;
+ set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+}
+
+static const TypeInfo usb_i2c_dev_type_info = {
+ .name = TYPE_USB_I2C_TINY,
+ .parent = TYPE_USB_DEVICE,
+ .instance_size = sizeof(USBI2CTinyState),
+ .abstract = true,
+ .class_init = usb_i2c_dev_class_init,+};
+
+static void usb_i2c_class_initfn(ObjectClass *klass, void *data) +{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+ uc->product_desc = "QEMU USB I2C Tiny";
+ uc->usb_desc = &desc_usb_i2c;
+ dc->props = usbi2c_properties;
+}
+
+static const TypeInfo usbi2c_info = {
+ .name = "usb-i2c-tiny",
+ .parent = TYPE_USB_I2C_TINY,
+ .class_init = usb_i2c_class_initfn,+};
+
+static void usb_i2c_register_types(void)
+{
+ type_register_static(&usb_i2c_dev_type_info);
+ type_register_static(&usbi2c_info);
+}
+
+type_init(usb_i2c_register_types)
trace-events +0 -0
@@ -328,6 +328,17 @@ usb_port_attach(int bus, const char *port, const char
*devspeed, const char *por
usb_port_detach(int bus, const char *port) "bus %d, port %s" usb_port_release(int bus, const char *port) "bus %d, port %s"
+# hw/usb/dev-tiny-i2c.c
+usb_i2c_tiny_read(int request, int address,int offset,int data) "request:0x%x address:%i offset:%i data:%i"
+usb_i2c_tiny_write(int request, int address,int offset,int data) "request:0x%x address:%i offset:%i data:%i"
+usb_i2c_tiny_functionality_read(int length) "length:%i" +usb_i2c_tiny_reset(void) ""
+usb_i2c_tiny_set_clock(void) "" +usb_i2c_tiny_usb_i2c_handle_data(void) "" +usb_i2c_tiny_i2c_start_transfer_failed(void) "i2c start transfer failed" +usb_i2c_tiny_ignored_request(int index,int request,int value,int length) "index:%i request:0x%x value:%i length:%i" +usb_i2c_tiny_unknown_request(int index,int request,int value,int length) "index:%i request:0x%x value:%i length:%i"
+
# hw/usb/hcd-ohci.c usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at %x" usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count 0x%.8x relative %d"
Signature · 1 line
1.9.1
Quoted 3 lines · Tim Sander
Probably due to my less then stellar patch to mail handling i think this
patch got forgotten. I think its ok to resend.
Yes, it is ok to avoid it being lost just because the maintainer (/me) was a bit busy.
I'd strongly suggest to configure git-send-email and to use that to send patches. Your email client seems to have mangled the patch, git-am refuses to apply it and complains about a malformed patch.
thanks,
Gerd
PATCH v6 1/1 i2c-tiny-usb: a small usb to i2c bridge
Oh my, so many stupid little errors. Due to firewall impairment i am sending these patches manually. Last time i forgot to disable the newline breaks which made the patch v5 unusable. Sorry for this inconvenience.
i2c-tiny-usb is a small usb to i2c bridge:
http://www.harbaum.org/till/i2c_tiny_usb/index.shtml
It is pretty simple and has no usb endpoints just a control. Reasons for adding this device:
* Linux device driver available
* adding an additional i2c bus via command line e.g. -device usb-i2c-tiny,id=i2c-0 -device tmp105,bus=i2c,address=0x50
--- default-configs/usb.mak | 1 + hw/usb/Makefile.objs | 1 + hw/usb/dev-i2c-tiny.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 11 ++ 4 files changed, 327 insertions(+) create mode 100644 hw/usb/dev-i2c-tiny.c
default-configs/usb.mak +1 -0
@@ -8,3 +8,4 @@ CONFIG_USB_AUDIO=y CONFIG_USB_SERIAL=y CONFIG_USB_NETWORK=y CONFIG_USB_BLUETOOTH=y +CONFIG_USB_I2C_TINY=y
hw/usb/Makefile.objs +1 -0
@@ -20,6 +20,7 @@ common-obj-$(CONFIG_USB_AUDIO) += dev-audio.o common-obj-$(CONFIG_USB_SERIAL) += dev-serial.o common-obj-$(CONFIG_USB_NETWORK) += dev-network.o common-obj-$(CONFIG_USB_BLUETOOTH) += dev-bluetooth.o +common-obj-$(CONFIG_USB_I2C_TINY) += dev-i2c-tiny.o ifeq ($(CONFIG_USB_SMARTCARD),y) common-obj-y += dev-smartcard-reader.o
hw/usb/dev-i2c-tiny.c new file +314 -0
314 lines not on this page · raw message
trace-events +11 -0
@@ -328,6 +328,17 @@ usb_port_attach(int bus, const char *port, const char *devspeed, const char *por usb_port_detach(int bus, const char *port) "bus %d, port %s" usb_port_release(int bus, const char *port) "bus %d, port %s" +# hw/usb/dev-tiny-i2c.c +usb_i2c_tiny_read(int request, int address,int offset,int data) "request:0x%x address:%i offset:%i data:%i" +usb_i2c_tiny_write(int request, int address,int offset,int data) "request:0x%x address:%i offset:%i data:%i" +usb_i2c_tiny_functionality_read(int length) "length:%i" +usb_i2c_tiny_reset(void) "" +usb_i2c_tiny_set_clock(void) "" +usb_i2c_tiny_usb_i2c_handle_data(void) "" +usb_i2c_tiny_i2c_start_transfer_failed(void) "i2c start transfer failed" +usb_i2c_tiny_ignored_request(int index,int request,int value,int length) "index:%i request:0x%x value:%i length:%i" +usb_i2c_tiny_unknown_request(int index,int request,int value,int length) "index:%i request:0x%x value:%i length:%i" + # hw/usb/hcd-ohci.c usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at %x" usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count 0x%.8x relative %d"
Signature · 1 line
1.9.1
Re: [Qemu-devel] [PATCH v6] i2c-tiny-usb: a small usb to i2c bridge
Quoted 3 lines · Tim Sander
Oh my, so many stupid little errors. Due to firewall impairment i am sending these patches manually. Last time i forgot to disable the newline breaks which made the patch v5 unusable. Sorry for this inconvenience.
Please run ${QEMU_SRC}/scripts/checkpatch.pl on your patch and correct the stylistic errors it reports. I'll echo Gerd's comments about the value of using git send-email to send patches. If you can glean you email clients SMTP settings then you should be able to get git-send-email to do this as well. It's much less error prone once you have it working.
Quoted 371 lines
i2c-tiny-usb is a small usb to i2c bridge:
http://www.harbaum.org/till/i2c_tiny_usb/index.shtmlIt is pretty simple and has no usb endpoints just a control. Reasons for adding this device:
* Linux device driver available
* adding an additional i2c bus via command line e.g. -device usb-i2c-tiny,id=i2c-0 -device tmp105,bus=i2c,address=0x50Signed-off-by [email protected]--- default-configs/usb.mak | 1 + hw/usb/Makefile.objs | 1 + hw/usb/dev-i2c-tiny.c | 314 ++++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 11 ++ 4 files changed, 327 insertions(+) create mode 100644 hw/usb/dev-i2c-tiny.cdefault-configs/usb.mak +1
-0@@ -8,3 +8,4 @@ CONFIG_USB_AUDIO=y CONFIG_USB_SERIAL=y CONFIG_USB_NETWORK=y CONFIG_USB_BLUETOOTH=y +CONFIG_USB_I2C_TINY=yhw/usb/Makefile.objs +1
-0@@ -20,6 +20,7 @@ common-obj-$(CONFIG_USB_AUDIO) += dev-audio.o common-obj-$(CONFIG_USB_SERIAL) += dev-serial.o common-obj-$(CONFIG_USB_NETWORK) += dev-network.o common-obj-$(CONFIG_USB_BLUETOOTH) += dev-bluetooth.o +common-obj-$(CONFIG_USB_I2C_TINY) += dev-i2c-tiny.o ifeq ($(CONFIG_USB_SMARTCARD),y) common-obj-y += dev-smartcard-reader.ohw/usb/dev-i2c-tiny.c new file +314
-0@@ -0,0 +1,314 @@ +/* +* I2C tiny usb device emulation +* +* i2c-tiny-usb is a small usb to i2c bridge: +* +* http://www.harbaum.org/till/i2c_tiny_usb/index.shtml +* +* The simulated device is pretty simple and has no usb endpoints. +* There is a Linux device driver available named i2c-tiny-usb. +* +* Below is an example how to use this device from command line: +* -device usb-i2c-tiny,id=i2c-0 -device tmp105,bus=i2c,address=0x50 +* +* Copyright (c) 2015 Tim Sander <[email protected]> +* +* Loosly based on usb dev-serial.c: +* Copyright (c) 2006 CodeSourcery. +* Copyright (c) 2008 Samuel Thibault <[email protected]> +* Written by Paul Brook, reused for FTDI by Samuel Thibault +* +* This code is licensed under the LGPL. +* +*/ + +#include "trace.h" +#include "qemu-common.h" +#include "qemu/error-report.h" +#include "hw/usb.h" +#include "hw/usb/desc.h" +#include "hw/i2c/i2c.h" +#include "hw/i2c/smbus.h" +#include "sysemu/char.h" +#include "endian.h" + +/* commands from USB, must e.g. match command ids in kernel driver */ +#define CMD_ECHO 0 +#define CMD_GET_FUNC 1 +#define CMD_SET_DELAY 2 +#define CMD_GET_STATUS 3 + +/* To determine what functionality is present */ +#define I2C_FUNC_I2C 0x00000001 +#define I2C_FUNC_10BIT_ADDR 0x00000002 +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 +#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_QUICK 0x00010000 +#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 +#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 +#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 +#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 +#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 +#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 +#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000/*I2C-like blk-xfr */ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000/*1-byte reg. addr.*/ +#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000/*I2C-like blk-xfer*/ +#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000/* w/ 2-byte regadr*/ +#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000/* SMBus 2.0 */ +#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000/* SMBus 2.0 */ + +#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE) +#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA) +#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA) +#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) +#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) + +#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_I2C_BLOCK) + +#define DeviceOutVendor ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) +#define DeviceInVendor ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) + +typedef struct { +USBDevice dev; +I2CBus *i2cbus; +}USBI2CTinyState ; + +#define TYPE_USB_I2C_TINY "usb-i2c" +#define USB_I2C_TINY_DEV (obj) OBJECT_CHECK(USBI2CTinyState, \ + (obj), TYPE_USB_I2C_TINY) + +enum { +STR_MANUFACTURER =1 , +STR_PRODUCT_SERIAL , +STR_SERIALNUMBER , +}; + +static const USBDescStrings desc_strings = { + [STR_MANUFACTURER ] ="QEMU" , + [STR_PRODUCT_SERIAL ] ="QEMU USB I2C Tiny" , + [STR_SERIALNUMBER ] ="1" , +}; + +static const USBDescIface desc_iface0 = { + .bInterfaceNumber =1 , + .bNumEndpoints =0 , + .bInterfaceClass =0xff , + .bInterfaceSubClass =0xff , + .bInterfaceProtocol =0xff , + .eps = (USBDescEndpoint []) { + } +}; + +static const USBDescDevice desc_device = { + .bcdUSB =0x0110 , + .bMaxPacketSize0 =8 , + .bNumConfigurations =1 , + .confs = (const USBDescConfig []) { + { + .bNumInterfaces =1 , + .bConfigurationValue =1 , + .bmAttributes =USB_CFG_ATT_ONE , + .bMaxPower =50 , + .nif =1 , + .ifs = &desc_iface0, + }, + }, +}; + +static const USBDesc desc_usb_i2c = { + .id = { + .idVendor =0x0403 , + .idProduct =0xc631 , + .bcdDevice =0x0205 , + .iManufacturer =STR_MANUFACTURER , + .iProduct =STR_PRODUCT_SERIAL , + .iSerialNumber =STR_SERIALNUMBER , + }, + .full = &desc_device, + .str = desc_strings, +}; + +static void usb_i2c_handle_reset (USBDevice *dev) +{ +trace_usb_i2c_tiny_reset (); +} + +static void usb_i2c_handle_control (USBDevice *dev,USBPacket *p, +int request,int value,int index,int length,uint8_t *data) +{ +USBI2CTinyState *s = (USBI2CTinyState *)dev; +int ret,i, i2c_value; +uint32_t func; + + ret =usb_desc_handle_control (dev, p, request, value, index, length, data); +if (ret >=0 ) { +return ; + } + +switch (request) { +case EndpointOutRequest |USB_REQ_CLEAR_FEATURE : +break ; +case 0x4102 : +/* set clock, ignore */ +trace_usb_i2c_tiny_set_clock (); +break ; + +case 0x4105 : +trace_usb_i2c_tiny_unknown_request (index, request, value, length); +break ; + +case 0x4107 : +/* this seems to be a byte type access */ +if (i2c_start_transfer (s->i2cbus,/*address*/ index,0 )) { +trace_usb_i2c_tiny_i2c_start_transfer_failed (); + p->actual_length =0 ;/* write failure */ +break ; + } +for (i =0 ; i < length; i++) { +trace_usb_i2c_tiny_write (request, index, i, data[i]); +i2c_send (s->i2cbus, data[i]); + } + p->actual_length = length; +i2c_end_transfer (s->i2cbus); +break ; + +case 0xc101 : +/* thats what the real thing reports, FIXME: can we do better here? */ + func =htole32 (I2C_FUNC_I2C |I2C_FUNC_SMBUS_EMUL ); +memcpy (data, &func,sizeof (func)); + p->actual_length =sizeof (func); +trace_usb_i2c_tiny_functionality_read (length); +break ; + +case 0xc103 : +trace_usb_i2c_tiny_unknown_request (index, request, value, length); + p->actual_length =1 ; +break ; + +case 0xc106 : +case 0xc107 : +if (i2c_start_transfer (s->i2cbus,/*address*/ index,1 )) { +trace_usb_i2c_tiny_i2c_start_transfer_failed (); + p->actual_length =0 ; +break ; + } +if (request&1 ) { +i2c_send (s->i2cbus, data[0 ]); +i2c_start_transfer (s->i2cbus,/*address*/ index,1 ); + } +for (i =0 ; i < length; i++) { + i2c_value =i2c_recv (s->i2cbus); +if (i2c_value <0 ) { +break ; + } + data[i] = i2c_value; +trace_usb_i2c_tiny_read (request, index, i, data[i]); + } +if (request&1 ) { +i2c_nack (s->i2cbus); + } + p->actual_length = length; +i2c_end_transfer (s->i2cbus); +break ; + +default : + p->status =USB_RET_STALL ; +trace_usb_i2c_tiny_unknown_request (index, request, value, length); +break ; + } +} + +static void usb_i2c_handle_data (USBDevice *dev,USBPacket *p) +{ +trace_usb_i2c_tiny_usb_i2c_handle_data (); +} + +static void usb_i2c_realize (USBDevice *dev,Error **errp) +{ +USBI2CTinyState *s = (USBI2CTinyState *)dev; +Error *local_err =NULL ; + +usb_desc_create_serial (dev); +usb_desc_init (dev); + +usb_check_attach (dev, &local_err); +if (local_err) { +error_propagate (errp, local_err); +return ; + } + s->i2cbus =i2c_init_bus (&dev->qdev,"i2c" ); +usb_i2c_handle_reset (dev); +} + +static const VMStateDescription vmstate_usb_i2c = { + .name ="usb-i2c-tiny" , +}; + +static Property usbi2c_properties[] = { +DEFINE_PROP_END_OF_LIST (), +}; + +static void usb_i2c_dev_class_init (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); +USBDeviceClass *uc =USB_DEVICE_CLASS (klass); + + uc->realize = usb_i2c_realize; + uc->handle_reset = usb_i2c_handle_reset; + uc->handle_control = usb_i2c_handle_control; + uc->handle_data = usb_i2c_handle_data; + dc->vmsd = &vmstate_usb_i2c; +set_bit (DEVICE_CATEGORY_INPUT , dc->categories); +} + +static const TypeInfo usb_i2c_dev_type_info = { + .name =TYPE_USB_I2C_TINY , + .parent =TYPE_USB_DEVICE , + .instance_size =sizeof (USBI2CTinyState), + .abstract = true, + .class_init = usb_i2c_dev_class_init, +}; + +static void usb_i2c_class_initfn (ObjectClass *klass,void *data) +{ +DeviceClass *dc =DEVICE_CLASS (klass); +USBDeviceClass *uc =USB_DEVICE_CLASS (klass); + + uc->product_desc ="QEMU USB I2C Tiny" ; + uc->usb_desc = &desc_usb_i2c; + dc->props = usbi2c_properties; +} + +static const TypeInfo usbi2c_info = { + .name ="usb-i2c-tiny" , + .parent =TYPE_USB_I2C_TINY , + .class_init = usb_i2c_class_initfn, +}; + +static void usb_i2c_register_types (void ) +{ +type_register_static (&usb_i2c_dev_type_info); +type_register_static (&usbi2c_info); +} + +type_init (usb_i2c_register_types)trace-events +4
-0@@ -328,6 +328,17 @@ usb_port_attach(int bus, const char *port, const char *devspeed, const char *por usb_port_detach(int bus, const char *port) "bus %d, port %s" usb_port_release(int bus, const char *port) "bus %d, port %s" +# hw/usb/dev-tiny-i2c.c +usb_i2c_tiny_read(int request, int address,int offset,int data) "request:0x%x address:%i offset:%i data:%i" +usb_i2c_tiny_write(int request, int address,int offset,int data) "request:0x%x address:%i offset:%i data:%i" +usb_i2c_tiny_functionality_read(int length) "length:%i"
trace-events usb_port_attach(int bus, const char *port, const char *devspeed, const char *por · line 344
Quoted 10 lines
trace-events +7
-0+usb_i2c_tiny_reset(void) "" +usb_i2c_tiny_set_clock(void) "" +usb_i2c_tiny_usb_i2c_handle_data(void) "" +usb_i2c_tiny_i2c_start_transfer_failed(void) "i2c start transfer failed" +usb_i2c_tiny_ignored_request(int index,int request,int value,int length) "index:%i request:0x%x value:%i length:%i" +usb_i2c_tiny_unknown_request(int index,int request,int value,int length) "index:%i request:0x%x value:%i length:%i" + # hw/usb/hcd-ohci.c usb_ohci_iso_td_read_failed(uint32_t addr) "ISO_TD read error at %x" usb_ohci_iso_td_head(uint32_t head, uint32_t tail, uint32_t flags, uint32_t bp, uint32_t next, uint32_t be, uint32_t framenum, uint32_t startframe, uint32_t framecount, int rel_frame_num) "ISO_TD ED head 0x%.8x tailp 0x%.8x\n0x%.8x 0x%.8x 0x%.8x 0x%.8x\nframe_number 0x%.8x starting_frame 0x%.8x\nframe_count 0x%.8x relative %d"
--
Alex Bennée
Re: [Qemu-devel] [PATCH v6] i2c-tiny-usb: a small usb to i2c bridge
Quoted 5 lines · Alex Bennée
Quoted 3 lines · Tim Sander
Oh my, so many stupid little errors. Due to firewall impairment i am sending these patches manually. Last time i forgot to disable the newline breaks which made the patch v5 unusable. Sorry for this inconvenience.
"git am" accepts this one, but ...
Quoted 2 lines
Please run
${QEMU_SRC}/scripts/checkpatch.plon your patch and correct the stylistic errors it reports.
... checkpatch.pl indeed throws a bunch of codestyle warnings.
Quoted 4 lines
I'll echo Gerd's comments about the
value of using git send-email to send patches. If you can glean you email clients SMTP settings then you should be able to get git-send-email to do this as well.
Yes, you can configure git send-email to use your internal mail server to send out patches. Best place it in the global config ($HOME/.gitconfig instead of $repo/.git/config) so you don't have to repeat the procedure for every git tree you have.
Alternatively you can configure a mail daemon such as postfix on your workstation to deliver mails using your internal mail server as relay.
cheers,
Gerd
Re: [Qemu-devel] [PATCH v6] i2c-tiny-usb: a small usb to i2c bridge
In reply to Tim SanderQuoted 3 lines · Tim Sander
Oh my, so many stupid little errors. Due to firewall impairment i am sending these patches manually. Last time i forgot to disable the newline breaks which made the patch v5 unusable. Sorry for this inconvenience.
Didn't work again:
nilsson kraxel ~/projects/qemu (queue/usb)# patches apply -s id:2351494.kn6DdoE8y3@dabox
Applying: i2c-tiny-usb is a small usb to i2c bridge
fatal: corrupt patch at line 101
cheers,
Gerd