From b98ec6896ee88f1dcdd7098af25bcb6ee0fc50f0 Mon Sep 17 00:00:00 2001 From: Patrick Venture Date: Mon, 12 Apr 2021 12:45:19 -0700 Subject: hw/i2c: name I2CNode list in I2CBus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To enable passing the current_devs field as a parameter, we need to use a named struct type. Tested: BMC firmware with i2c devices booted to userspace. Signed-off-by: Patrick Venture Reviewed-by: Hao Wu Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210412194522.664594-2-venture@google.com> Signed-off-by: Corey Minyard --- include/hw/i2c/i2c.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 277dd9f..1f7c268 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -58,9 +58,11 @@ struct I2CNode { QLIST_ENTRY(I2CNode) next; }; +typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList; + struct I2CBus { BusState qbus; - QLIST_HEAD(, I2CNode) current_devs; + I2CNodeList current_devs; uint8_t saved_address; bool broadcast; }; -- cgit v1.1 From 513ca82d8982463aca98aa01dcf584e0b4fc0982 Mon Sep 17 00:00:00 2001 From: Patrick Venture Date: Mon, 12 Apr 2021 12:45:20 -0700 Subject: hw/i2c: add match method for device search At the start of an i2c transaction, the i2c bus searches its list of children to identify which devices correspond to the address (or broadcast). Now the I2CSlave device has a method "match" that encapsulates the lookup behavior. This allows the behavior to be changed to support devices, such as i2c muxes. Tested: A BMC firmware was booted to userspace and i2c devices were detected. Signed-off-by: Patrick Venture Reviewed-by: Hao Wu Message-Id: <20210412194522.664594-3-venture@google.com> Signed-off-by: Corey Minyard --- include/hw/i2c/i2c.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 1f7c268..9b8b95f 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -16,6 +16,7 @@ enum i2c_event { I2C_NACK /* Masker NACKed a receive byte. */ }; +typedef struct I2CNodeList I2CNodeList; #define TYPE_I2C_SLAVE "i2c-slave" OBJECT_DECLARE_TYPE(I2CSlave, I2CSlaveClass, @@ -39,6 +40,16 @@ struct I2CSlaveClass { * return code is not used and should be zero. */ int (*event)(I2CSlave *s, enum i2c_event event); + + /* + * Check if this device matches the address provided. Returns bool of + * true if it matches (or broadcast), and updates the device list, false + * otherwise. + * + * If broadcast is true, match should add the device and return true. + */ + bool (*match_and_add)(I2CSlave *candidate, uint8_t address, bool broadcast, + I2CNodeList *current_devs); }; struct I2CSlave { -- cgit v1.1 From 3f9b32595e785c79720ed174198472c3d4d32c03 Mon Sep 17 00:00:00 2001 From: Patrick Venture Date: Mon, 12 Apr 2021 12:45:21 -0700 Subject: hw/i2c: move search to i2c_scan_bus method Moves the search for matching devices on an i2c bus into a separate method. This allows for an object that owns an I2CBus can avoid duplicating this method. Tested: A BMC firmware was booted to userspace and i2c devices were detected. Signed-off-by: Patrick Venture Reviewed-by: Hao Wu Message-Id: <20210412194522.664594-4-venture@google.com> Signed-off-by: Corey Minyard --- include/hw/i2c/i2c.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 9b8b95f..ff4129e 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -87,6 +87,8 @@ void i2c_nack(I2CBus *bus); int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send); int i2c_send(I2CBus *bus, uint8_t data); uint8_t i2c_recv(I2CBus *bus); +bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast, + I2CNodeList *current_devs); /** * Create an I2C slave device on the heap. -- cgit v1.1 From 065177eeceff552a5316bff9435188b50a2da1b6 Mon Sep 17 00:00:00 2001 From: Patrick Venture Date: Mon, 12 Apr 2021 12:45:22 -0700 Subject: hw/i2c: add pca954x i2c-mux switch The pca954x is an i2c mux, and this adds support for two variants of this device: the pca9546 and pca9548. This device is very common on BMCs to route a different channel to each PCIe i2c bus downstream from the BMC. Signed-off-by: Patrick Venture Reviewed-by: Hao Wu Reviewed-by: Havard Skinnemoen Message-Id: <20210412194522.664594-5-venture@google.com> Signed-off-by: Corey Minyard --- include/hw/i2c/i2c_mux_pca954x.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 include/hw/i2c/i2c_mux_pca954x.h (limited to 'include') diff --git a/include/hw/i2c/i2c_mux_pca954x.h b/include/hw/i2c/i2c_mux_pca954x.h new file mode 100644 index 0000000..8aaf9bb --- /dev/null +++ b/include/hw/i2c/i2c_mux_pca954x.h @@ -0,0 +1,19 @@ +#ifndef QEMU_I2C_MUX_PCA954X +#define QEMU_I2C_MUX_PCA954X + +#include "hw/i2c/i2c.h" + +#define TYPE_PCA9546 "pca9546" +#define TYPE_PCA9548 "pca9548" + +/** + * Retrieves the i2c bus associated with the specified channel on this i2c + * mux. + * @mux: an i2c mux device. + * @channel: the i2c channel requested + * + * Returns: a pointer to the associated i2c bus. + */ +I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel); + +#endif -- cgit v1.1