imx: mx6ul_14x14_evk: configure for 24bpp display
[oweals/u-boot.git] / drivers / misc / cros_ec_lpc.c
index 0e02671c93d46652864d9e83bf4a7d3d9f658e2e..71d03bfba2be0f831658866d68095d02a86101de 100644 (file)
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Chromium OS cros_ec driver - LPC interface
  *
  * Copyright (c) 2012 The Chromium OS Authors.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /*
@@ -14,6 +13,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <command.h>
 #include <cros_ec.h>
 #include <asm/io.h>
@@ -40,10 +40,43 @@ static int wait_for_sync(struct cros_ec_dev *dev)
        return 0;
 }
 
-int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
+int cros_ec_lpc_packet(struct udevice *udev, int out_bytes, int in_bytes)
+{
+       struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
+       uint8_t *d;
+       int i;
+
+       if (out_bytes > EC_LPC_HOST_PACKET_SIZE)
+               return log_msg_ret("Cannot send that many bytes\n", -E2BIG);
+
+       if (in_bytes > EC_LPC_HOST_PACKET_SIZE)
+               return log_msg_ret("Cannot receive that many bytes\n", -E2BIG);
+
+       if (wait_for_sync(dev))
+               return log_msg_ret("Timeout waiting ready\n", -ETIMEDOUT);
+
+       /* Write data */
+       for (i = 0, d = (uint8_t *)dev->dout; i < out_bytes; i++, d++)
+               outb(*d, EC_LPC_ADDR_HOST_PACKET + i);
+
+       /* Start the command */
+       outb(EC_COMMAND_PROTOCOL_3, EC_LPC_ADDR_HOST_CMD);
+
+       if (wait_for_sync(dev))
+               return log_msg_ret("Timeout waiting ready\n", -ETIMEDOUT);
+
+       /* Read back args */
+       for (i = 0, d = dev->din; i < in_bytes; i++, d++)
+               *d = inb(EC_LPC_ADDR_HOST_PACKET + i);
+
+       return in_bytes;
+}
+
+int cros_ec_lpc_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);
        const int cmd_addr = EC_LPC_ADDR_HOST_CMD;
        const int data_addr = EC_LPC_ADDR_HOST_DATA;
        const int args_addr = EC_LPC_ADDR_HOST_ARGS;
@@ -54,7 +87,7 @@ int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        int csum;
        int i;
 
-       if (dout_len > EC_HOST_PARAM_SIZE) {
+       if (dout_len > EC_PROTO2_MAX_PARAM_SIZE) {
                debug("%s: Cannot send %d bytes\n", __func__, dout_len);
                return -1;
        }
@@ -159,7 +192,7 @@ int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob)
        byte = 0xff;
        byte &= inb(EC_LPC_ADDR_HOST_CMD);
        byte &= inb(EC_LPC_ADDR_HOST_DATA);
-       for (i = 0; i < EC_HOST_PARAM_SIZE && (byte == 0xff); i++)
+       for (i = 0; i < EC_PROTO2_MAX_PARAM_SIZE && (byte == 0xff); i++)
                byte &= inb(EC_LPC_ADDR_HOST_PARAM + i);
        if (byte == 0xff) {
                debug("%s: CROS_EC device not found on LPC bus\n",
@@ -178,7 +211,7 @@ int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob)
  * seeing whether the EC sets the EC_HOST_ARGS_FLAG_FROM_HOST flag
  * in args when it responds.
  */
-int cros_ec_lpc_check_version(struct cros_ec_dev *dev)
+static int cros_ec_lpc_check_version(struct udevice *dev)
 {
        if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) == 'E' &&
                        inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1)
@@ -192,3 +225,27 @@ int cros_ec_lpc_check_version(struct cros_ec_dev *dev)
        printf("%s: ERROR: old EC interface not supported\n", __func__);
        return -1;
 }
+
+static int cros_ec_probe(struct udevice *dev)
+{
+       return cros_ec_register(dev);
+}
+
+static struct dm_cros_ec_ops cros_ec_ops = {
+       .packet = cros_ec_lpc_packet,
+       .command = cros_ec_lpc_command,
+       .check_version = cros_ec_lpc_check_version,
+};
+
+static const struct udevice_id cros_ec_ids[] = {
+       { .compatible = "google,cros-ec-lpc" },
+       { }
+};
+
+U_BOOT_DRIVER(cros_ec_lpc) = {
+       .name           = "cros_ec_lpc",
+       .id             = UCLASS_CROS_EC,
+       .of_match       = cros_ec_ids,
+       .probe          = cros_ec_probe,
+       .ops            = &cros_ec_ops,
+};