I2C libqos and tmp105 qtest support
v2 cover I2C libqos and tmp105 qtest support
Hello,
Here's I2C support for the libqos framework and an OMAP driver. The design was inspired by QEMU's i2c_bus and Linux' i2c_adapter. Seems like low hanging fruit (while we're still waiting for PCI support :)), hopefully motivating more people to contribute qtests for new devices or bug fixes.
I found a bug in omap_i2c related to the SBD bit not getting cleared after a single-byte read; the patch has been dropped as we were not able to verify it against a TRM or hardware. The driver was therefore changed to ignore the SBD bit, like the Linux driver does.
I've split up the proposed tmp105.h header further to facilitate reuse of the register enum in qtest.
The test case itself initially fails; in lack of a v2 patch by Alex I'm appending my own fix proposal that makes the test pass.
I'm also appending a QOM'ish cleanup of the file, replacing the current API with a QOM property.
To do a qom-set for testing a non-zero temperature reading, we'll need either a canonical path for the TMP105 or Jason's qtest_qmp_resp() to iterate over qom-list /machine/unassigned output looking for type "tmp105" with qom-get.
Alex, if you could add a Tested-by (using object_property_set_int()) that would be appreciated.
Regards,
Andreas
v1 -> v2:
* Factor out libqos API for I2C and an OMAP driver
* Avoid casts by using uint8_t* in API, suggested by Blue
* Ignore SBD bit in omap_i2c driver
* Drop omap_i2c patch clearing SBD
* Incorporate Alex' tmp105.h patch
* Split out tmp105_regs.h for qtest, inspired by rtc-test
* Append replacement for Alex' fix
* Append QOM cleanup and turn setter function into QOM property
Alex Horn (1):
tmp105: Create API for TMP105 temperature sensor
Andreas Färber (6):
libqtest: Prepare I2C libqos
tmp105: Split out I2C message constants from header
tests: Add tmp105 qtest test case
tmp105: Fix I2C protocol bug
tmp105: QOM'ify
tmp105: Add temperature QOM property
hw/i2c.h | 3 - hw/tmp105.c | 101 ++++++++++++++++++------------- hw/tmp105.h | 47 +++++++++++++++ hw/tmp105_regs.h | 50 ++++++++++++++++ tests/Makefile | 3 + tests/libi2c-omap.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/libi2c.c | 22 +++++++ tests/libi2c.h | 30 ++++++++++ tests/tmp105-test.c | 76 +++++++++++++++++++++++ 9 Dateien geändert, 453 Zeilen hinzugefügt(+), 45 Zeilen entfernt(-) create mode 100644 hw/tmp105.h create mode 100644 hw/tmp105_regs.h create mode 100644 tests/libi2c-omap.c create mode 100644 tests/libi2c.c create mode 100644 tests/libi2c.h create mode 100644 tests/tmp105-test.c
Signature · 1 line
1.7.10.4
PATCH v2 1/7 tmp105: Create API for TMP105 temperature sensor
From: Alex Horn <[email protected]>
* Define enum for TMP105 registers
* Move tmp105_set() from I2C to TMP105 header
* Document units and range of temperature as preconditions
--- hw/i2c.h | 3 --- hw/tmp105.c | 17 ++++++++------- hw/tmp105.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 Dateien geändert, 76 Zeilen hinzugefügt(+), 11 Zeilen entfernt(-) create mode 100644 hw/tmp105.h
hw/i2c.h +0 -3
@@ -73,9 +73,6 @@ void *wm8750_dac_buffer(void *opaque, int samples);void wm8750_dac_commit (void *opaque);void wm8750_set_bclk_in (void *opaque,int new_hz); -/* tmp105.c */ -void tmp105_set (I2CSlave *i2c,int temp); -/* lm832x.c */ void lm832x_key_event (DeviceState *dev,int key,int state);
hw/tmp105.c +9 -8
@@ -20,6 +20,7 @@#include "hw.h" #include "i2c.h" +#include "tmp105.h" typedef struct { I2CSlave i2c;
@@ -92,22 +93,22 @@ static void tmp105_read(TMP105State *s) }switch (s->pointer &3 ) { -case 0 :/* Temperature */ +case TMP105_REG_TEMPERATURE : s->buf[s->len ++] = (((uint16_t ) s->temperature) >>8 ); s->buf[s->len ++] = (((uint16_t ) s->temperature) >>0 ) & (0xf0 << ((~s->config >>5 ) &3 ));/* R */ break ; -case 1 :/* Configuration */ +case TMP105_REG_CONFIG : s->buf[s->len ++] = s->config;break ; -case 2 :/* T_LOW */ +case TMP105_REG_T_LOW : s->buf[s->len ++] = ((uint16_t ) s->limit[0 ]) >>8 ; s->buf[s->len ++] = ((uint16_t ) s->limit[0 ]) >>0 ;break ; -case 3 :/* T_HIGH */ +case TMP105_REG_T_HIGH : s->buf[s->len ++] = ((uint16_t ) s->limit[1 ]) >>8 ; s->buf[s->len ++] = ((uint16_t ) s->limit[1 ]) >>0 ;break ;
@@ -117,10 +118,10 @@ static void tmp105_read(TMP105State *s)static void tmp105_write (TMP105State *s) {switch (s->pointer &3 ) { -case 0 :/* Temperature */ +case TMP105_REG_TEMPERATURE :break ; -case 1 :/* Configuration */ +case TMP105_REG_CONFIG :if (s->buf[0 ] & ~s->config & (1 <<0 ))/* SD */ printf ("%s: TMP105 shutdown\n" , __FUNCTION__); s->config = s->buf[0 ];
@@ -128,8 +129,8 @@ static void tmp105_write(TMP105State *s)tmp105_alarm_update (s);break ; -case 2 :/* T_LOW */ -case 3 :/* T_HIGH */ +case TMP105_REG_T_LOW : +case TMP105_REG_T_HIGH :if (s->len >=3 ) s->limit[s->pointer &1 ] = (int16_t ) ((((uint16_t ) s->buf[0 ]) <<8 ) | s->buf[1 ]);
hw/tmp105.h new file +67 -0
67 lines not on this page · raw message
Signature · 1 line
1.7.10.4
PATCH v2 2/7 libqtest: Prepare I2C libqos
In reply to Andreas FärberThis adds a simple I2C API and a driver implementation for omap_i2c.
--- tests/Makefile | 1 + tests/libi2c-omap.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/libi2c.c | 22 +++++++ tests/libi2c.h | 30 ++++++++++ 4 Dateien geändert, 219 Zeilen hinzugefügt(+) create mode 100644 tests/libi2c-omap.c create mode 100644 tests/libi2c.c create mode 100644 tests/libi2c.h
tests/Makefile +1 -0
@@ -86,6 +86,7 @@ QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), $(TA check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y)) qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a +qtest-obj-y += tests/libi2c.o tests/libi2c-omap.o $(check-qtest-y): $(qtest-obj-y) .PHONY: check-help
tests/libi2c-omap.c new file +166 -0
166 lines not on this page · raw message
tests/libi2c.c new file +22 -0
@@ -0,0 +1,22 @@ +/* +* QTest I2C driver +* +* Copyright (c) 2012 Andreas Färber +* +* This work is licensed under the terms of the GNU GPL, version 2 or later. +* See the COPYING file in the top-level directory. +*/ +#include "libi2c.h" +#include "libqtest.h" + +void i2c_send (I2CAdapter *i2c,uint8_t addr, +const uint8_t *buf,uint16_t len) +{ + i2c->send (i2c, addr, buf, len); +} + +void i2c_recv (I2CAdapter *i2c,uint8_t addr, +uint8_t *buf,uint16_t len) +{ + i2c->recv (i2c, addr, buf, len); +}
tests/libi2c.h new file +30 -0
@@ -0,0 +1,30 @@ +/* +* I2C libqos +* +* Copyright (c) 2012 Andreas Färber +* +* This work is licensed under the terms of the GNU GPL, version 2 or later. +* See the COPYING file in the top-level directory. +*/ +#ifndef LIBQOS_I2C_H +#define LIBQOS_I2C_H + +#include <stdint.h> + +typedef struct I2CAdapter I2CAdapter ; +struct I2CAdapter { +void (*send)(I2CAdapter *adapter,uint8_t addr, +const uint8_t *buf,uint16_t len); +void (*recv)(I2CAdapter *adapter,uint8_t addr, +uint8_t *buf,uint16_t len); +}; + +void i2c_send (I2CAdapter *i2c,uint8_t addr, +const uint8_t *buf,uint16_t len); +void i2c_recv (I2CAdapter *i2c,uint8_t addr, +uint8_t *buf,uint16_t len); + +/* libi2c-omap.c */ +I2CAdapter *omap_i2c_create (uint64_t addr); + +#endif
Signature · 1 line
1.7.10.4
PATCH v2 3/7 tmp105: Split out I2C message constants from header
In reply to Andreas FärberAllows value sharing with qtest.
--- hw/tmp105.h | 34 +--------------------------------- hw/tmp105_regs.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 Dateien geändert, 51 Zeilen hinzugefügt(+), 33 Zeilen entfernt(-) create mode 100644 hw/tmp105_regs.h
hw/tmp105.h +1 -33
@@ -15,39 +15,7 @@#define QEMU_TMP105_H #include "i2c.h" - -/** -* TMP105Reg: -* @TMP105_REG_TEMPERATURE: Temperature register -* @TMP105_REG_CONFIG: Configuration register -* @TMP105_REG_T_LOW: Low temperature register (also known as T_hyst) -* @TMP105_REG_T_HIGH: High temperature register (also known as T_OS) -* -* The following temperature sensors are -* compatible with the TMP105 registers: -* - adt75 -* - ds1775 -* - ds75 -* - lm75 -* - lm75a -* - max6625 -* - max6626 -* - mcp980x -* - stds75 -* - tcn75 -* - tmp100 -* - tmp101 -* - tmp105 -* - tmp175 -* - tmp275 -* - tmp75 -**/ -typedef enum TMP105Reg { -TMP105_REG_TEMPERATURE =0 , -TMP105_REG_CONFIG , -TMP105_REG_T_LOW , -TMP105_REG_T_HIGH , -}TMP105Reg ; +#include "tmp105_regs.h" /** * tmp105_set:
hw/tmp105_regs.h new file +50 -0
50 lines not on this page · raw message
Signature · 1 line
1.7.10.4
PATCH v2 4/7 tests: Add tmp105 qtest test case
In reply to Andreas FärberExercise all four commands of the TMP105, testing for an issue in the I2C TX path.
The test case uses the N800's OMAP I2C and is the first for ARM.
--- tests/Makefile | 2 ++ tests/tmp105-test.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 Dateien geändert, 78 Zeilen hinzugefügt(+) create mode 100644 tests/tmp105-test.c
tests/Makefile +2 -0
@@ -28,6 +28,7 @@ check-qtest-i386-y += tests/rtc-test$(EXESUF) check-qtest-x86_64-y = $(check-qtest-i386-y) check-qtest-sparc-y = tests/m48t59-test$(EXESUF) check-qtest-sparc64-y = tests/m48t59-test$(EXESUF) +check-qtest-arm-y = tests/tmp105-test$(EXESUF) GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
@@ -78,6 +79,7 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y) tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y) +tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(trace-obj-y) # QTest rules
tests/tmp105-test.c new file +76 -0
76 lines not on this page · raw message
Signature · 1 line
1.7.10.4
PATCH v2 5/7 tmp105: Fix I2C protocol bug
In reply to Andreas FärberAn early length postincrement in the TMP105's I2C TX path led to transfers of more than one byte to place the second byte in the third byte's place within the buffer and the third byte to get discarded.
Fix this by explictly incrementing the length after the checks but before the callback is called, which again checks the length.
Adjust the Coding Style while at it.
--- hw/tmp105.c | 9 ++++++---
1 Datei geändert, 6 Zeilen hinzugefügt(+), 3 Zeilen entfernt(-)
hw/tmp105.c +6 -3
@@ -153,11 +153,14 @@ static int tmp105_tx(I2CSlave *i2c, uint8_t data) {TMP105State *s = (TMP105State *) i2c; -if (!s->len ++) +if (s->len ==0 ) { s->pointer = data; -else { -if (s->len <=2 ) + s->len++; + }else { +if (s->len <=2 ) { s->buf[s->len -1 ] = data; + } + s->len++;tmp105_write (s); }
Signature · 1 line
1.7.10.4
PATCH v2 6/7 tmp105: QOM'ify
In reply to Andreas FärberIntroduce TYPE_ constant and cast macro.
Move the state struct to the new header to allow for future embedding.
--- hw/tmp105.c | 38 +++++++++++++------------------------- hw/tmp105.h | 27 +++++++++++++++++++++++++++
2 Dateien geändert, 40 Zeilen hinzugefügt(+), 25 Zeilen entfernt(-)
hw/tmp105.c +13 -25
@@ -22,20 +22,6 @@#include "i2c.h" #include "tmp105.h" -typedef struct { -I2CSlave i2c; -uint8_t len; -uint8_t buf[2 ]; -qemu_irq pin; - -uint8_t pointer; -uint8_t config; -int16_t temperature; -int16_t limit[2 ]; -int faults; -uint8_t alarm; -}TMP105State ; -static void tmp105_interrupt_update (TMP105State *s) {qemu_set_irq (s->pin, s->alarm ^ ((~s->config >>2 ) &1 ));/* POL */
@@ -68,7 +54,7 @@ static void tmp105_alarm_update(TMP105State *s)/* Units are 0.001 centigrades relative to 0 C. */ void tmp105_set (I2CSlave *i2c,int temp) { -TMP105State *s = (TMP105State *) i2c; +TMP105State *s =TMP105 (i2c);if (temp >=128000 || temp <-128000 ) { fprintf(stderr, "%s: values is out of range (%i.%03i C)\n",
@@ -141,17 +127,18 @@ static void tmp105_write(TMP105State *s)static int tmp105_rx (I2CSlave *i2c) { -TMP105State *s = (TMP105State *) i2c; +TMP105State *s =TMP105 (i2c); -if (s->len <2 ) +if (s->len <2 ) {return s->buf[s->len ++]; -else + }else {return 0xff ; + } }static int tmp105_tx (I2CSlave *i2c,uint8_t data) { -TMP105State *s = (TMP105State *) i2c; +TMP105State *s =TMP105 (i2c);if (s->len ==0 ) { s->pointer = data;
@@ -169,10 +156,11 @@ static int tmp105_tx(I2CSlave *i2c, uint8_t data)static void tmp105_event (I2CSlave *i2c,enum i2c_event event) { -TMP105State *s = (TMP105State *) i2c; +TMP105State *s =TMP105 (i2c); -if (event ==I2C_START_RECV ) +if (event ==I2C_START_RECV ) {tmp105_read (s); + } s->len =0 ; }
@@ -208,7 +196,7 @@ static const VMStateDescription vmstate_tmp105 = {static void tmp105_reset (I2CSlave *i2c) { -TMP105State *s = (TMP105State *) i2c; +TMP105State *s =TMP105 (i2c); s->temperature =0 ; s->pointer =0 ;
@@ -221,7 +209,7 @@ static void tmp105_reset(I2CSlave *i2c)static int tmp105_init (I2CSlave *i2c) { -TMP105State *s =FROM_I2C_SLAVE (TMP105State, i2c); +TMP105State *s =TMP105 (i2c);qdev_init_gpio_out (&i2c->qdev, &s->pin,1 );
@@ -242,8 +230,8 @@ static void tmp105_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_tmp105; } -static TypeInfo tmp105_info = { - .name ="tmp105" , +static const TypeInfo tmp105_info = { + .name =TYPE_TMP105 , .parent =TYPE_I2C_SLAVE , .instance_size =sizeof (TMP105State), .class_init = tmp105_class_init,
hw/tmp105.h +27 -0
@@ -17,6 +17,33 @@#include "i2c.h" #include "tmp105_regs.h" +#define TYPE_TMP105 "tmp105" +#define TMP105 (obj) OBJECT_CHECK(TMP105State, (obj), TYPE_TMP105) + +/** +* TMP105State: +* @config: Bits 5 and 6 (value 32 and 64) determine the precision of the +* temperature. See Table 8 in the data sheet. +* +* @see_also: http://www.ti.com/lit/gpn/tmp105 +*/ +typedef struct TMP105State { +/*< private >*/ +I2CSlave i2c; +/*< public >*/ + +uint8_t len; +uint8_t buf[2 ]; +qemu_irq pin; + +uint8_t pointer; +uint8_t config; +int16_t temperature; +int16_t limit[2 ]; +int faults; +uint8_t alarm; +}TMP105State ; +/** * tmp105_set: * @i2c: dispatcher to TMP105 hardware model
Signature · 1 line
1.7.10.4
PATCH v2 7/7 tmp105: Add temperature QOM property
In reply to Andreas FärberThis obsoletes tmp105_set() and allows for better error handling.
--- hw/tmp105.c | 39 ++++++++++++++++++++++++++++++++------- hw/tmp105.h | 15 ---------------
2 Dateien geändert, 32 Zeilen hinzugefügt(+), 22 Zeilen entfernt(-)
hw/tmp105.c +32 -7
@@ -21,6 +21,7 @@#include "hw.h" #include "i2c.h" #include "tmp105.h" +#include "qapi/qapi-visit-core.h" static void tmp105_interrupt_update (TMP105State *s) {
@@ -51,18 +52,34 @@ static void tmp105_alarm_update(TMP105State *s)tmp105_interrupt_update (s); } +static void tmp105_get_temperature (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +TMP105State *s =TMP105 (obj); +int64_t value = s->temperature; + +visit_type_int (v, &value, name, errp); +} +/* Units are 0.001 centigrades relative to 0 C. */ -void tmp105_set (I2CSlave *i2c,int temp) +static void tmp105_set_temperature (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) { -TMP105State *s =TMP105 (i2c); +TMP105State *s =TMP105 (obj); -if (temp >=128000 || temp <-128000 ) { -fprintf (stderr,"%s: values is out of range (%i.%03i C)\n" , - __FUNCTION__, temp /1000 , temp %1000 ); -exit (-1 ); +int64_t value; + +visit_type_int (v, &value, name, errp); +if (error_is_set (errp)) { +return ; + } +if (value >=128000 || value <-128000 ) { +error_setg (errp,"value %" PRId64".%03" PRIu64" °C is out of range" , + value /1000 , value %1000 ); +return ; } - s->temperature = ((int16_t ) (temp *0x800 /128000 )) <<4 ; + s->temperature = ((int16_t ) (value *0x800 /128000 )) <<4 ;tmp105_alarm_update (s); }
@@ -218,6 +235,13 @@ static int tmp105_init(I2CSlave *i2c)return 0 ; } +static void tmp105_initfn (Object *obj) +{ +object_property_add (obj,"temperature" ,"int" , + tmp105_get_temperature, + tmp105_set_temperature,NULL ,NULL ,NULL ); +} +static void tmp105_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);
@@ -234,6 +258,7 @@ static const TypeInfo tmp105_info = { .name = TYPE_TMP105, .parent = TYPE_I2C_SLAVE, .instance_size = sizeof(TMP105State), + .instance_init = tmp105_initfn, .class_init = tmp105_class_init, };
hw/tmp105.h +0 -15
@@ -44,19 +44,4 @@ typedef struct TMP105State { uint8_t alarm; } TMP105State; -/** -* tmp105_set: -* @i2c: dispatcher to TMP105 hardware model -* @temp: temperature with 0.001 centigrades units in the range -40 C to +125 C -* -* Sets the temperature of the TMP105 hardware model. -* -* Bits 5 and 6 (value 32 and 64) in the register indexed by TMP105_REG_CONFIG -* determine the precision of the temperature. See Table 8 in the data sheet. -* -* @see_also: I2C_SLAVE macro -* @see_also: http://www.ti.com/lit/gpn/tmp105 -*/ -void tmp105_set (I2CSlave *i2c,int temp); -#endif
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH v2 7/7] tmp105: Add temperature QOM property
Quoted 30 lines
hw/tmp105.c +8
-0+static void tmp105_initfn (Object *obj) +{ +object_property_add (obj,"temperature" ,"int" , + tmp105_get_temperature, + tmp105_set_temperature,NULL ,NULL ,NULL ); +} +static void tmp105_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);@@ -234,6 +258,7 @@ static const TypeInfo tmp105_info = { .name = TYPE_TMP105, .parent = TYPE_I2C_SLAVE, .instance_size = sizeof(TMP105State), + .instance_init = tmp105_initfn, .class_init = tmp105_class_init, };hw/tmp105.h +0
-4@@ -44,19 +44,4 @@ typedef struct TMP105State {uint8_t alarm; } TMP105State; -/** -* tmp105_set: -* @i2c: dispatcher to TMP105 hardware model -* @temp: temperature with 0.001 centigrades units in the range -40 C to +125 C
hw/tmp105.h typedef struct TMP105State { · line 60
Quoted 10 lines
hw/tmp105.h +0
-10-* -* Sets the temperature of the TMP105 hardware model. -* -* Bits 5 and 6 (value 32 and 64) in the register indexed by TMP105_REG_CONFIG -* determine the precision of the temperature. See Table 8 in the data sheet. -* -* @see_also: I2C_SLAVE macro -* @see_also: http://www.ti.com/lit/gpn/tmp105 -*/ -void tmp105_set (I2CSlave *i2c,int temp);
Would it be possible to keep the C API? The traditional C API is useful when a project cannot support QOM. These C APIs also simplify unit testing and allow QEMU hardware models to be more easily reused as standalone modules.
With kind regards,
Alex
Quoted 111 lines · Andreas Färber
This obsoletes
tmp105_set()and allows for better error handling.Signed-off-by Andreas Färber <[email protected]>--- hw/tmp105.c | 39 ++++++++++++++++++++++++++++++++------- hw/tmp105.h | 15 ---------------2 Dateien geändert, 32 Zeilen hinzugefügt(+), 22 Zeilen entfernt(-)
hw/tmp105.c +32
-7@@ -21,6 +21,7 @@#include "hw.h" #include "i2c.h" #include "tmp105.h" +#include "qapi/qapi-visit-core.h" static void tmp105_interrupt_update (TMP105State *s) {@@ -51,18 +52,34 @@ static void tmp105_alarm_update(TMP105State *s)tmp105_interrupt_update (s); } +static void tmp105_get_temperature (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) +{ +TMP105State *s =TMP105 (obj); +int64_t value = s->temperature; + +visit_type_int (v, &value, name, errp); +} +/* Units are 0.001 centigrades relative to 0 C. */ -void tmp105_set (I2CSlave *i2c,int temp) +static void tmp105_set_temperature (Object *obj,Visitor *v,void *opaque, +const char *name,Error **errp) { -TMP105State *s =TMP105 (i2c); +TMP105State *s =TMP105 (obj); -if (temp >=128000 || temp <-128000 ) { -fprintf (stderr,"%s: values is out of range (%i.%03i C)\n" , - __FUNCTION__, temp /1000 , temp %1000 ); -exit (-1 ); +int64_t value; + +visit_type_int (v, &value, name, errp); +if (error_is_set (errp)) { +return ; + } +if (value >=128000 || value <-128000 ) { +error_setg (errp,"value %" PRId64".%03" PRIu64" °C is out of range" , + value /1000 , value %1000 ); +return ; } - s->temperature = ((int16_t ) (temp *0x800 /128000 )) <<4 ; + s->temperature = ((int16_t ) (value *0x800 /128000 )) <<4 ;tmp105_alarm_update (s); }@@ -218,6 +235,13 @@ static int tmp105_init(I2CSlave *i2c)return 0 ; } +static void tmp105_initfn (Object *obj) +{ +object_property_add (obj,"temperature" ,"int" , + tmp105_get_temperature, + tmp105_set_temperature,NULL ,NULL ,NULL ); +} +static void tmp105_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);@@ -234,6 +258,7 @@ static const TypeInfo tmp105_info = { .name = TYPE_TMP105, .parent = TYPE_I2C_SLAVE, .instance_size = sizeof(TMP105State), + .instance_init = tmp105_initfn, .class_init = tmp105_class_init, };hw/tmp105.h +0
-16@@ -44,19 +44,4 @@ typedef struct TMP105State { uint8_t alarm; } TMP105State; -/** -* tmp105_set: -* @i2c: dispatcher to TMP105 hardware model -* @temp: temperature with 0.001 centigrades units in the range -40 C to +125 C -* -* Sets the temperature of the TMP105 hardware model. -* -* Bits 5 and 6 (value 32 and 64) in the register indexed by TMP105_REG_CONFIG -* determine the precision of the temperature. See Table 8 in the data sheet. -* -* @see_also: I2C_SLAVE macro -* @see_also: http://www.ti.com/lit/gpn/tmp105 -*/ -void tmp105_set (I2CSlave *i2c,int temp); -#endif --1.7.10.4
Re: [Qemu-devel] [PATCH v2 7/7] tmp105: Add temperature QOM property
Am 15.12.2012 17:52, schrieb Alex Horn:
Quoted 37 lines
Quoted 37 lines
hw/tmp105.c +8
-0+static void tmp105_initfn (Object *obj) +{ +object_property_add (obj,"temperature" ,"int" , + tmp105_get_temperature, + tmp105_set_temperature,NULL ,NULL ,NULL ); +} +static void tmp105_class_init (ObjectClass *klass,void *data) {DeviceClass *dc =DEVICE_CLASS (klass);@@ -234,6 +258,7 @@ static const TypeInfo tmp105_info = { .name = TYPE_TMP105, .parent = TYPE_I2C_SLAVE, .instance_size = sizeof(TMP105State), + .instance_init = tmp105_initfn, .class_init = tmp105_class_init, };hw/tmp105.h +0
-11@@ -44,19 +44,4 @@ typedef struct TMP105State {uint8_t alarm; } TMP105State; -/** -* tmp105_set: -* @i2c: dispatcher to TMP105 hardware model -* @temp: temperature with 0.001 centigrades units in the range -40 C to +125 C -* -* Sets the temperature of the TMP105 hardware model. -* -* Bits 5 and 6 (value 32 and 64) in the register indexed by TMP105_REG_CONFIG -* determine the precision of the temperature. See Table 8 in the data sheet. -* -* @see_also: I2C_SLAVE macro
Quoted 8 lines
hw/tmp105.h typedef struct TMP105State { · line 60
Quoted 3 lines
hw/tmp105.h +0
-3-* @see_also: http://www.ti.com/lit/gpn/tmp105 -*/ -void tmp105_set (I2CSlave *i2c,int temp);Would it be possible to keep the C API? The traditional C API is useful when a project cannot support QOM. These C APIs also simplify unit testing and allow QEMU hardware models to be more easily reused as standalone modules.
QEMU devices are meant to be instantiated through QOM, and the use of QOM is gradually increasing (it was introduced around last Christmas). So while it would be possible to leave tmp105_set() behind as wrapper for
Error *err = NULL; object_property_set_int(OBJECT(i2c), "temperature", temp, err);
if (err != NULL) {
fprintf(stderr, "%s", error_get_pretty(err));
error_free(err);
exit(-1);
}it uses a very fatal way of error handling and, as you said yourself, has zero users in qemu.git.
By comparison the QOM property in this patch allows to set the value via C API or QMP commands, including scripts such as QMP/qom-set or QMP/qom-fuse.
So I don't see why the effort? What project are you trying to reuse QEMU devices in without using QEMU's device infrastructure? Not even Xen did that AFAIK. If you're trying to integrate with SystemC or so there are some (possibly not quite up-to-date) projects (e.g., linked from the Wiki) to bridge worlds.
Regards,
Andreas
Am 14.12.2012 12:34, schrieb Andreas Färber:
Quoted 7 lines
Hello,
Here's I2C support for the libqos framework and an OMAP driver. The design was inspired by QEMU's
i2c_busand Linux'i2c_adapter. Seems like low hanging fruit (while we're still waiting for PCI support :)), hopefully motivating more people to contribute qtests for new devices or bug fixes.
Ping! See below...
Quoted 16 lines
I found a bug in
omap_i2crelated to the SBD bit not getting cleared after a single-byte read; the patch has been dropped as we were not able to verify it against a TRM or hardware. The driver was therefore changed to ignore the SBD bit, like the Linux driver does.I've split up the proposed
tmp105.hheader further to facilitate reuse of the register enum in qtest.The test case itself initially fails; in lack of a v2 patch by Alex I'm appending my own fix proposal that makes the test pass.
I'm also appending a QOM'ish cleanup of the file, replacing the current API with a QOM property.
To do a qom-set for testing a non-zero temperature reading, we'll need either a canonical path for the TMP105 or Jason'sqtest_qmp_resp()to iterate over qom-list /machine/unassigned output looking for type "tmp105" with qom-get.
[...]
Quoted 9 lines
v1 -> v2:
* Factor out libqos API for I2C and an OMAP driver
* Avoid casts by using uint8_t* in API, suggested by Blue
* Ignore SBD bit inomap_i2cdriver
* Dropomap_i2cpatch clearing SBD
* Incorporate Alex'tmp105.hpatch
* Split outtmp105_regs.hfor qtest, inspired by rtc-test
* Append replacement for Alex' fix
* Append QOM cleanup and turn setter function into QOM property
[...]
Quoted 2 lines
Alex Horn (1):
tmp105: Create API for TMP105 temperature sensor
This was applied by Anthony meanwhile.
Quoted 7 lines
Andreas Färber (6):
libqtest: Prepare I2C libqos
tmp105: Split out I2C message constants from header
tests: Add tmp105 qtest test case
tmp105: Fix I2C protocol bug
tmp105: QOM'ify
tmp105: Add temperature QOM property
These need to be rebased due to the header reorganization and gcov. Anyone any feedback, especially on the libqos part? Anthony? Stefan?
Thanks,
Andreas
Quoted 16 lines
hw/i2c.h | 3 - hw/tmp105.c | 101 ++++++++++++++++++------------- hw/tmp105.h | 47 +++++++++++++++ hw/tmp105_regs.h | 50 ++++++++++++++++ tests/Makefile | 3 + tests/libi2c-omap.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/libi2c.c | 22 +++++++ tests/libi2c.h | 30 ++++++++++ tests/tmp105-test.c | 76 +++++++++++++++++++++++ 9 Dateien geändert, 453 Zeilen hinzugefügt(+), 45 Zeilen entfernt(-) create mode 100644 hw/tmp105.h create mode 100644 hw/tmp105_regs.h create mode 100644 tests/libi2c-omap.c create mode 100644 tests/libi2c.c create mode 100644 tests/libi2c.h create mode 100644 tests/tmp105-test.c
Quoted 19 lines · Andreas Färber
Hello,
Here's I2C support for the libqos framework and an OMAP driver. The design was inspired by QEMU's
i2c_busand Linux'i2c_adapter. Seems like low hanging fruit (while we're still waiting for PCI support :)), hopefully motivating more people to contribute qtests for new devices or bug fixes.I found a bug in
omap_i2crelated to the SBD bit not getting cleared after a single-byte read; the patch has been dropped as we were not able to verify it against a TRM or hardware. The driver was therefore changed to ignore the SBD bit, like the Linux driver does.I've split up the proposed
tmp105.hheader further to facilitate reuse of the register enum in qtest.The test case itself initially fails; in lack of a v2 patch by Alex I'm appending my own fix proposal that makes the test pass.
Quoted 8 lines
I'm also appending a QOM'ish cleanup of the file, replacing the current API with a QOM property.
To do a qom-set for testing a non-zero temperature reading, we'll need either a canonical path for the TMP105 or Jason'sqtest_qmp_resp()to iterate over qom-list /machine/unassigned output looking for type "tmp105" with qom-get.Alex, if you could add a Tested-by (using
object_property_set_int()) that would be appreciated.
Looks good. Whole series:
Regards,
Anthony Liguori
Quoted 53 lines
Regards,
Andreasv1 -> v2:
* Factor out libqos API for I2C and an OMAP driver
* Avoid casts by using uint8_t* in API, suggested by Blue
* Ignore SBD bit inomap_i2cdriver
* Dropomap_i2cpatch clearing SBD
* Incorporate Alex'tmp105.hpatch
* Split outtmp105_regs.hfor qtest, inspired by rtc-test
* Append replacement for Alex' fix
* Append QOM cleanup and turn setter function into QOM propertyCc Anthony Liguori <[email protected]>Cc Alex Horn <[email protected]>Cc Andrzej Zaborowski <[email protected]>Cc Peter Maydell <[email protected]>Cc Blue Swirl <[email protected]>Cc Jason Baron <[email protected]>Cc Paolo Bonzini <[email protected]>Alex Horn (1):
tmp105: Create API for TMP105 temperature sensorAndreas Färber (6):
libqtest: Prepare I2C libqos
tmp105: Split out I2C message constants from header
tests: Add tmp105 qtest test case
tmp105: Fix I2C protocol bug
tmp105: QOM'ify
tmp105: Add temperature QOM propertyhw/i2c.h | 3 - hw/tmp105.c | 101 ++++++++++++++++++------------- hw/tmp105.h | 47 +++++++++++++++ hw/tmp105_regs.h | 50 ++++++++++++++++ tests/Makefile | 3 + tests/libi2c-omap.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/libi2c.c | 22 +++++++ tests/libi2c.h | 30 ++++++++++ tests/tmp105-test.c | 76 +++++++++++++++++++++++ 9 Dateien geändert, 453 Zeilen hinzugefügt(+), 45 Zeilen entfernt(-) create mode 100644 hw/tmp105.h create mode 100644 hw/tmp105_regs.h create mode 100644 tests/libi2c-omap.c create mode 100644 tests/libi2c.c create mode 100644 tests/libi2c.h create mode 100644 tests/tmp105-test.cSignature · 1 line
1.7.10.4
Quoted 19 lines · Andreas Färber
Hello,
Here's I2C support for the libqos framework and an OMAP driver. The design was inspired by QEMU's
i2c_busand Linux'i2c_adapter. Seems like low hanging fruit (while we're still waiting for PCI support :)), hopefully motivating more people to contribute qtests for new devices or bug fixes.I found a bug in
omap_i2crelated to the SBD bit not getting cleared after a single-byte read; the patch has been dropped as we were not able to verify it against a TRM or hardware. The driver was therefore changed to ignore the SBD bit, like the Linux driver does.I've split up the proposed
tmp105.hheader further to facilitate reuse of the register enum in qtest.The test case itself initially fails; in lack of a v2 patch by Alex I'm appending my own fix proposal that makes the test pass.
Quoted 8 lines
I'm also appending a QOM'ish cleanup of the file, replacing the current API with a QOM property.
To do a qom-set for testing a non-zero temperature reading, we'll need either a canonical path for the TMP105 or Jason'sqtest_qmp_resp()to iterate over qom-list /machine/unassigned output looking for type "tmp105" with qom-get.Alex, if you could add a Tested-by (using
object_property_set_int()) that would be appreciated.
BTW, this series doesn't apply anymore. If you resubmit, I'll commit it.
Regards,
Anthony Liguori
Quoted 53 lines
Regards,
Andreasv1 -> v2:
* Factor out libqos API for I2C and an OMAP driver
* Avoid casts by using uint8_t* in API, suggested by Blue
* Ignore SBD bit inomap_i2cdriver
* Dropomap_i2cpatch clearing SBD
* Incorporate Alex'tmp105.hpatch
* Split outtmp105_regs.hfor qtest, inspired by rtc-test
* Append replacement for Alex' fix
* Append QOM cleanup and turn setter function into QOM propertyCc Anthony Liguori <[email protected]>Cc Alex Horn <[email protected]>Cc Andrzej Zaborowski <[email protected]>Cc Peter Maydell <[email protected]>Cc Blue Swirl <[email protected]>Cc Jason Baron <[email protected]>Cc Paolo Bonzini <[email protected]>Alex Horn (1):
tmp105: Create API for TMP105 temperature sensorAndreas Färber (6):
libqtest: Prepare I2C libqos
tmp105: Split out I2C message constants from header
tests: Add tmp105 qtest test case
tmp105: Fix I2C protocol bug
tmp105: QOM'ify
tmp105: Add temperature QOM propertyhw/i2c.h | 3 - hw/tmp105.c | 101 ++++++++++++++++++------------- hw/tmp105.h | 47 +++++++++++++++ hw/tmp105_regs.h | 50 ++++++++++++++++ tests/Makefile | 3 + tests/libi2c-omap.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/libi2c.c | 22 +++++++ tests/libi2c.h | 30 ++++++++++ tests/tmp105-test.c | 76 +++++++++++++++++++++++ 9 Dateien geändert, 453 Zeilen hinzugefügt(+), 45 Zeilen entfernt(-) create mode 100644 hw/tmp105.h create mode 100644 hw/tmp105_regs.h create mode 100644 tests/libi2c-omap.c create mode 100644 tests/libi2c.c create mode 100644 tests/libi2c.h create mode 100644 tests/tmp105-test.cSignature · 1 line
1.7.10.4