X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fmisc%2Fcros_ec_i2c.c;h=3de18b2d2ade9e1a18e6e650358fa55747c425f3;hb=9d11d12a16d12caae7f9418322485392a5583423;hp=b0060ac1976b5bd8e7166a3b73c423d22be6464a;hpb=fbbbc86e8ebac4f42f4ca39ceba80cea27c983bc;p=karo-tx-uboot.git diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c index b0060ac197..3de18b2d2a 100644 --- a/drivers/misc/cros_ec_i2c.c +++ b/drivers/misc/cros_ec_i2c.c @@ -2,23 +2,8 @@ * Chromium OS cros_ec driver - I2C interface * * Copyright (c) 2012 The Chromium OS Authors. - * See file CREDITS for list of people who contributed to this - * project. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ /* @@ -29,6 +14,7 @@ */ #include +#include #include #include @@ -38,11 +24,11 @@ #define debug_trace(fmt, b...) #endif -int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, - const uint8_t *dout, int dout_len, - uint8_t **dinp, int din_len) +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) { - int old_bus = 0; + struct cros_ec_dev *dev = dev_get_uclass_priv(udev); /* version8, cmd8, arglen8, out8[dout_len], csum8 */ int out_bytes = dout_len + 4; /* response8, arglen8, in8[din_len], checksum8 */ @@ -50,9 +36,7 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, uint8_t *ptr; /* Receive input data, so that args will be dword aligned */ uint8_t *in_ptr; - int ret; - - old_bus = i2c_get_bus_num(); + int len, csum, ret; /* * Sanity-check I/O sizes given transaction overhead in internal @@ -82,80 +66,62 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, * will be dword aligned. */ in_ptr = dev->din + sizeof(int64_t); - if (!dev->cmd_version_is_supported) { - /* Send an old-style command */ - *ptr++ = cmd; - out_bytes = dout_len + 1; - in_bytes = din_len + 2; - in_ptr--; /* Expect just a status byte */ - } else { - *ptr++ = EC_CMD_VERSION0 + cmd_version; - *ptr++ = cmd; - *ptr++ = dout_len; - in_ptr -= 2; /* Expect status, length bytes */ + + if (dev->protocol_version != 2) { + /* Something we don't support */ + debug("%s: Protocol version %d unsupported\n", + __func__, dev->protocol_version); + return -1; } + + *ptr++ = EC_CMD_VERSION0 + cmd_version; + *ptr++ = cmd; + *ptr++ = dout_len; + in_ptr -= 2; /* Expect status, length bytes */ + memcpy(ptr, dout, dout_len); ptr += dout_len; - if (dev->cmd_version_is_supported) - *ptr++ = (uint8_t) - cros_ec_calc_checksum(dev->dout, dout_len + 3); - - /* Set to the proper i2c bus */ - if (i2c_set_bus_num(dev->bus_num)) { - debug("%s: Cannot change to I2C bus %d\n", __func__, - dev->bus_num); - return -1; - } + *ptr++ = (uint8_t) + cros_ec_calc_checksum(dev->dout, dout_len + 3); /* Send output data */ cros_ec_dump_data("out", -1, dev->dout, out_bytes); - ret = i2c_write(dev->addr, 0, 0, dev->dout, out_bytes); + ret = dm_i2c_write(udev, 0, dev->dout, out_bytes); if (ret) { - debug("%s: Cannot complete I2C write to 0x%x\n", - __func__, dev->addr); + debug("%s: Cannot complete I2C write to %s\n", __func__, + udev->name); ret = -1; } if (!ret) { - ret = i2c_read(dev->addr, 0, 0, in_ptr, in_bytes); + ret = dm_i2c_read(udev, 0, in_ptr, in_bytes); if (ret) { - debug("%s: Cannot complete I2C read from 0x%x\n", - __func__, dev->addr); + debug("%s: Cannot complete I2C read from %s\n", + __func__, udev->name); ret = -1; } } - /* Return to original bus number */ - i2c_set_bus_num(old_bus); - if (ret) - return ret; - if (*in_ptr != EC_RES_SUCCESS) { debug("%s: Received bad result code %d\n", __func__, *in_ptr); return -(int)*in_ptr; } - if (dev->cmd_version_is_supported) { - int len, csum; - - len = in_ptr[1]; - if (len + 3 > sizeof(dev->din)) { - debug("%s: Received length %#02x too large\n", - __func__, len); - return -1; - } - csum = cros_ec_calc_checksum(in_ptr, 2 + len); - if (csum != in_ptr[2 + len]) { - debug("%s: Invalid checksum rx %#02x, calced %#02x\n", - __func__, in_ptr[2 + din_len], csum); - return -1; - } - din_len = min(din_len, len); - cros_ec_dump_data("in", -1, in_ptr, din_len + 3); - } else { - cros_ec_dump_data("in (old)", -1, in_ptr, in_bytes); + len = in_ptr[1]; + if (len + 3 > sizeof(dev->din)) { + debug("%s: Received length %#02x too large\n", + __func__, len); + return -1; + } + csum = cros_ec_calc_checksum(in_ptr, 2 + len); + if (csum != in_ptr[2 + len]) { + debug("%s: Invalid checksum rx %#02x, calced %#02x\n", + __func__, in_ptr[2 + din_len], csum); + return -1; } + din_len = min(din_len, len); + cros_ec_dump_data("in", -1, in_ptr, din_len + 3); /* Return pointer to dword-aligned input data, if any */ *dinp = dev->din + sizeof(int64_t); @@ -163,37 +129,24 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version, return din_len; } -int cros_ec_i2c_decode_fdt(struct cros_ec_dev *dev, const void *blob) +static int cros_ec_probe(struct udevice *dev) { - /* Decode interface-specific FDT params */ - dev->max_frequency = fdtdec_get_int(blob, dev->node, - "i2c-max-frequency", 100000); - dev->bus_num = i2c_get_bus_num_fdt(dev->parent_node); - if (dev->bus_num == -1) { - debug("%s: Failed to read bus number\n", __func__); - return -1; - } - dev->addr = fdtdec_get_int(blob, dev->node, "reg", -1); - if (dev->addr == -1) { - debug("%s: Failed to read device address\n", __func__); - return -1; - } - - return 0; + return cros_ec_register(dev); } -/** - * Initialize I2C protocol. - * - * @param dev CROS_EC device - * @param blob Device tree blob - * @return 0 if ok, -1 on error - */ -int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob) -{ - i2c_init(dev->max_frequency, dev->addr); - - dev->cmd_version_is_supported = 0; - - return 0; -} +static struct dm_cros_ec_ops cros_ec_ops = { + .command = cros_ec_i2c_command, +}; + +static const struct udevice_id cros_ec_ids[] = { + { .compatible = "google,cros-ec-i2c" }, + { } +}; + +U_BOOT_DRIVER(cros_ec_i2c) = { + .name = "cros_ec_i2c", + .id = UCLASS_CROS_EC, + .of_match = cros_ec_ids, + .probe = cros_ec_probe, + .ops = &cros_ec_ops, +};