diff options
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/cros_ec.c | 2 | ||||
-rw-r--r-- | drivers/misc/cros_ec_i2c.c | 110 | ||||
-rw-r--r-- | drivers/misc/cros_ec_sandbox.c | 4 | ||||
-rw-r--r-- | drivers/misc/i2c_eeprom_emul.c | 4 | ||||
-rw-r--r-- | drivers/misc/qfw.c | 4 | ||||
-rw-r--r-- | drivers/misc/tegra186_bpmp.c | 8 | ||||
-rw-r--r-- | drivers/misc/tegra_car.c | 4 |
7 files changed, 112 insertions, 24 deletions
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c index 759bb46c57..3d449b2a55 100644 --- a/drivers/misc/cros_ec.c +++ b/drivers/misc/cros_ec.c @@ -998,7 +998,7 @@ int cros_ec_register(struct udevice *dev) { struct cros_ec_dev *cdev = dev_get_uclass_priv(dev); const void *blob = gd->fdt_blob; - int node = dev->of_offset; + int node = dev_of_offset(dev); char id[MSG_BYTES]; cdev->dev = dev; diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c index 3de18b2d2a..6e0934017a 100644 --- a/drivers/misc/cros_ec_i2c.c +++ b/drivers/misc/cros_ec_i2c.c @@ -24,11 +24,96 @@ #define debug_trace(fmt, b...) #endif +/** + * Request format for protocol v3 + * byte 0 0xda (EC_COMMAND_PROTOCOL_3) + * byte 1-8 struct ec_host_request + * byte 10- response data + */ +struct ec_host_request_i2c { + /* Always 0xda to backward compatible with v2 struct */ + uint8_t command_protocol; + struct ec_host_request ec_request; +} __packed; + +/* + * Response format for protocol v3 + * byte 0 result code + * byte 1 packet_length + * byte 2-9 struct ec_host_response + * byte 10- response data + */ +struct ec_host_response_i2c { + uint8_t result; + uint8_t packet_length; + struct ec_host_response ec_response; +} __packed; + +static int cros_ec_i2c_packet(struct udevice *udev, int out_bytes, int in_bytes) +{ + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(udev); + struct ec_host_request_i2c *ec_request_i2c = + (struct ec_host_request_i2c *)dev->dout; + struct ec_host_response_i2c *ec_response_i2c = + (struct ec_host_response_i2c *)dev->din; + struct i2c_msg i2c_msg[2]; + int ret; + + i2c_msg[0].addr = chip->chip_addr; + i2c_msg[0].flags = 0; + i2c_msg[1].addr = chip->chip_addr; + i2c_msg[1].flags = I2C_M_RD; + + /* one extra byte, to indicate v3 */ + i2c_msg[0].len = out_bytes + 1; + i2c_msg[0].buf = dev->dout; + + /* stitch on EC_COMMAND_PROTOCOL_3 */ + memmove(&ec_request_i2c->ec_request, dev->dout, out_bytes); + ec_request_i2c->command_protocol = EC_COMMAND_PROTOCOL_3; + + /* two extra bytes for v3 */ + i2c_msg[1].len = in_bytes + 2; + i2c_msg[1].buf = dev->din; + + ret = dm_i2c_xfer(udev, &i2c_msg[0], 2); + if (ret) { + printf("%s: Could not execute transfer: %d\n", __func__, ret); + return ret; + } + + /* When we send a v3 request to v2 ec, ec won't recognize the 0xda + * (EC_COMMAND_PROTOCOL_3) and will return with status + * EC_RES_INVALID_COMMAND with zero data length + * + * In case of invalid command for v3 protocol the data length + * will be at least sizeof(struct ec_host_response) + */ + if (ec_response_i2c->result == EC_RES_INVALID_COMMAND && + ec_response_i2c->packet_length == 0) + return -EPROTONOSUPPORT; + + if (ec_response_i2c->packet_length < sizeof(struct ec_host_response)) { + printf("%s: response of %u bytes too short; not a full hdr\n", + __func__, ec_response_i2c->packet_length); + return -EBADMSG; + } + + + /* drop result and packet_len */ + memmove(dev->din, &ec_response_i2c->ec_response, in_bytes); + + return in_bytes; +} + static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd, int cmd_version, const uint8_t *dout, int dout_len, uint8_t **dinp, int din_len) { struct cros_ec_dev *dev = dev_get_uclass_priv(udev); + struct dm_i2c_chip *chip = dev_get_parent_platdata(udev); + struct i2c_msg i2c_msg[2]; /* version8, cmd8, arglen8, out8[dout_len], csum8 */ int out_bytes = dout_len + 4; /* response8, arglen8, in8[din_len], checksum8 */ @@ -53,6 +138,11 @@ static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd, assert(dout_len >= 0); assert(dinp); + i2c_msg[0].addr = chip->chip_addr; + i2c_msg[0].len = out_bytes; + i2c_msg[0].buf = dev->dout; + i2c_msg[0].flags = 0; + /* * Copy command and data into output buffer so we can do a single I2C * burst transaction. @@ -85,24 +175,21 @@ static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd, *ptr++ = (uint8_t) cros_ec_calc_checksum(dev->dout, dout_len + 3); + i2c_msg[1].addr = chip->chip_addr; + i2c_msg[1].len = in_bytes; + i2c_msg[1].buf = in_ptr; + i2c_msg[1].flags = I2C_M_RD; + /* Send output data */ cros_ec_dump_data("out", -1, dev->dout, out_bytes); - ret = dm_i2c_write(udev, 0, dev->dout, out_bytes); + + ret = dm_i2c_xfer(udev, &i2c_msg[0], 2); if (ret) { - debug("%s: Cannot complete I2C write to %s\n", __func__, + debug("%s: Could not execute transfer to %s\n", __func__, udev->name); ret = -1; } - if (!ret) { - ret = dm_i2c_read(udev, 0, in_ptr, in_bytes); - if (ret) { - debug("%s: Cannot complete I2C read from %s\n", - __func__, udev->name); - ret = -1; - } - } - if (*in_ptr != EC_RES_SUCCESS) { debug("%s: Received bad result code %d\n", __func__, *in_ptr); return -(int)*in_ptr; @@ -136,6 +223,7 @@ static int cros_ec_probe(struct udevice *dev) static struct dm_cros_ec_ops cros_ec_ops = { .command = cros_ec_i2c_command, + .packet = cros_ec_i2c_packet, }; static const struct udevice_id cros_ec_ids[] = { diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c index c4fbca0d3a..848c67bc23 100644 --- a/drivers/misc/cros_ec_sandbox.c +++ b/drivers/misc/cros_ec_sandbox.c @@ -522,7 +522,7 @@ int cros_ec_probe(struct udevice *dev) int err; memcpy(ec, &s_state, sizeof(*ec)); - err = cros_ec_decode_ec_flash(blob, dev->of_offset, &ec->ec_config); + err = cros_ec_decode_ec_flash(blob, dev_of_offset(dev), &ec->ec_config); if (err) return err; @@ -531,7 +531,7 @@ int cros_ec_probe(struct udevice *dev) keyb_dev; device_find_next_child(&keyb_dev)) { if (device_get_uclass_id(keyb_dev) == UCLASS_KEYBOARD) { - node = keyb_dev->of_offset; + node = dev_of_offset(keyb_dev); break; } } diff --git a/drivers/misc/i2c_eeprom_emul.c b/drivers/misc/i2c_eeprom_emul.c index 4410d0357f..02de8d7df3 100644 --- a/drivers/misc/i2c_eeprom_emul.c +++ b/drivers/misc/i2c_eeprom_emul.c @@ -115,9 +115,9 @@ static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev) { struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev); - plat->size = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + plat->size = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "sandbox,size", 32); - plat->filename = fdt_getprop(gd->fdt_blob, dev->of_offset, + plat->filename = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "sandbox,filename", NULL); if (!plat->filename) { debug("%s: No filename for device '%s'\n", __func__, diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c index d43d1d300a..a8af9e0c53 100644 --- a/drivers/misc/qfw.c +++ b/drivers/misc/qfw.c @@ -32,7 +32,7 @@ static LIST_HEAD(fw_list); * be ignored. * @return: 0 on success, or negative value on failure */ -static int bios_linker_allocate(struct bios_linker_entry *entry, u32 *addr) +static int bios_linker_allocate(struct bios_linker_entry *entry, ulong *addr) { uint32_t size, align; struct fw_file *file; @@ -147,7 +147,7 @@ static int bios_linker_add_checksum(struct bios_linker_entry *entry) } /* This function loads and patches ACPI tables provided by QEMU */ -u32 write_acpi_tables(u32 addr) +ulong write_acpi_tables(ulong addr) { int i, ret = 0; struct fw_file *file; diff --git a/drivers/misc/tegra186_bpmp.c b/drivers/misc/tegra186_bpmp.c index f4ddbea376..bd8b9602e0 100644 --- a/drivers/misc/tegra186_bpmp.c +++ b/drivers/misc/tegra186_bpmp.c @@ -112,19 +112,19 @@ static int tegra186_bpmp_bind(struct udevice *dev) debug("%s(dev=%p)\n", __func__, dev); ret = device_bind_driver_to_node(dev, "tegra186_clk", "tegra186_clk", - dev->of_offset, &child); + dev_of_offset(dev), &child); if (ret) return ret; ret = device_bind_driver_to_node(dev, "tegra186_reset", - "tegra186_reset", dev->of_offset, + "tegra186_reset", dev_of_offset(dev), &child); if (ret) return ret; ret = device_bind_driver_to_node(dev, "tegra186_power_domain", "tegra186_power_domain", - dev->of_offset, &child); + dev_of_offset(dev), &child); if (ret) return ret; @@ -141,7 +141,7 @@ static ulong tegra186_bpmp_get_shmem(struct udevice *dev, int index) struct fdtdec_phandle_args args; fdt_addr_t reg; - ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset, + ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "shmem", NULL, 0, index, &args); if (ret < 0) { error("fdtdec_parse_phandle_with_args() failed: %d\n", ret); diff --git a/drivers/misc/tegra_car.c b/drivers/misc/tegra_car.c index 0eb009657c..5db3c374ce 100644 --- a/drivers/misc/tegra_car.c +++ b/drivers/misc/tegra_car.c @@ -22,12 +22,12 @@ static int tegra_car_bpmp_bind(struct udevice *dev) debug("%s(dev=%p)\n", __func__, dev); ret = device_bind_driver_to_node(dev, "tegra_car_clk", "tegra_car_clk", - dev->of_offset, &child); + dev_of_offset(dev), &child); if (ret) return ret; ret = device_bind_driver_to_node(dev, "tegra_car_reset", - "tegra_car_reset", dev->of_offset, + "tegra_car_reset", dev_of_offset(dev), &child); if (ret) return ret; |