summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-12-15 21:28:39 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-23 22:10:56 +0000
commitb9b457173ea7f194c13a2d025496c3c49cf05792 (patch)
treef840953f110167bb9b591887b8c115f065dfcdc8
parentdc1a89a70aa27d90f0538a87f1cf20b284563397 (diff)
downloadchrome-ec-b9b457173ea7f194c13a2d025496c3c49cf05792.tar.gz
pd: hoho: mcdp28x0 serial driver.
Add initial serial driver for mdcp2850 dp->hdmi converter. Driver implements 'get information' (cmd:0x40) to provide rudimentary method to test mcdp for functionality and assert GPIO if successful. Future CLs may expose more serial functionality if necessary. Signed-off-by: Todd Broch <tbroch@chromium.org> BRANCH=samus BUG=chrome-os-partner:34122 TEST=manual, when compiles with #define MCDP_DEBUG see successful serial communication and result from get info. buf:[00]0x04 [01]0x40 [02]0x00 [03]0xbc ... buf:[00]0x0f [01]0x40 [02]0x00 [03]0x0e [04]0x00 [05]0x01 [06]0x01 [07]0x00 [08]0x00 [09]0x00 [10]0x00 [11]0x00 [12]0x00 [13]0x00 family:000e chipid:0001 irom:1.0.0 fw:0.0.0 Change-Id: I35f9d9b0437633d1bd6a6c9fa14413bedb12f5c2 Reviewed-on: https://chromium-review.googlesource.com/235930 Trybot-Ready: Todd Broch <tbroch@chromium.org> Tested-by: Todd Broch <tbroch@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Todd Broch <tbroch@chromium.org>
-rw-r--r--board/hoho/board.c20
-rw-r--r--board/hoho/board.h5
-rw-r--r--driver/build.mk3
-rw-r--r--driver/mcdp28x0.c149
-rw-r--r--driver/mcdp28x0.h56
5 files changed, 231 insertions, 2 deletions
diff --git a/board/hoho/board.c b/board/hoho/board.c
index 406bdebd77..324f79b2ef 100644
--- a/board/hoho/board.c
+++ b/board/hoho/board.c
@@ -10,6 +10,7 @@
#include "ec_version.h"
#include "gpio.h"
#include "hooks.h"
+#include "mcdp28x0.h"
#include "registers.h"
#include "task.h"
#include "usb.h"
@@ -131,6 +132,21 @@ static void board_init_spi2(void)
}
#endif /* CONFIG_SPI_FLASH */
+static void factory_validation_deferred(void)
+{
+ struct mcdp_info info;
+
+ mcdp_enable();
+
+ /* test mcdp via serial to validate function */
+ if (!mcdp_get_info(&info) && (MCDP_FAMILY(info.family) == 0xe) &&
+ (MCDP_CHIPID(info.chipid) == 0x1))
+ gpio_set_level(GPIO_MCDP_READY, 1);
+
+ mcdp_disable();
+}
+DECLARE_DEFERRED(factory_validation_deferred);
+
/* Initialize board. */
static void board_init(void)
{
@@ -144,8 +160,8 @@ static void board_init(void)
gpio_enable_interrupt(GPIO_DP_HPD);
gpio_set_level(GPIO_STM_READY, 1); /* factory test only */
- /* TODO(crosbug.com/p/34122): Add real check for MCDP function */
- gpio_set_level(GPIO_MCDP_READY, 1); /* factory test only */
+ /* Delay needed to allow HDMI MCU to boot. */
+ hook_call_deferred(factory_validation_deferred, 200*MSEC);
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
diff --git a/board/hoho/board.h b/board/hoho/board.h
index 1345c4e1b7..1b43a4fe5a 100644
--- a/board/hoho/board.h
+++ b/board/hoho/board.h
@@ -43,6 +43,11 @@
#define CONFIG_USB_PD_IDENTITY_HW_VERS 1
#define CONFIG_USB_PD_IDENTITY_SW_VERS 1
#define CONFIG_USB_PD_NO_VBUS_DETECT
+/* mcdp2850 serial interface */
+#define CONFIG_MCDP28X0 usart3_hw
+#define CONFIG_STREAM
+#define CONFIG_STREAM_USART
+#define CONFIG_STREAM_USART3
#undef CONFIG_WATCHDOG_HELP
#undef CONFIG_LID_SWITCH
#undef CONFIG_TASK_PROFILING
diff --git a/driver/build.mk b/driver/build.mk
index 2d5de551a8..923be6ac1a 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -53,3 +53,6 @@ driver-$(CONFIG_USB_SWITCH_TSU6721)+=usb_switch_tsu6721.o
# Firmware Update
driver-$(CONFIG_SB_FIRMWARE_UPDATE)+=battery/sb_fw_update.o
+
+# video converters
+driver-$(CONFIG_MCDP28X0)+=mcdp28x0.o
diff --git a/driver/mcdp28x0.c b/driver/mcdp28x0.c
new file mode 100644
index 0000000000..de334b5c59
--- /dev/null
+++ b/driver/mcdp28x0.c
@@ -0,0 +1,149 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Megachips DisplayPort to HDMI protocol converter / level shifter driver.
+ */
+
+#include "config.h"
+#include "console.h"
+#include "common.h"
+#include "mcdp28x0.h"
+#include "timer.h"
+#include "usart-stm32f0.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
+
+#undef MCDP_DEBUG
+
+#ifdef MCDP_DEBUG
+static inline void print_buffer(uint8_t *buf, int cnt)
+{
+ int i;
+ CPRINTF("buf:");
+ for (i = 0; i < cnt; i++) {
+ if (i && !(i % 4))
+ CPRINTF("\n ");
+ CPRINTF("[%02d]0x%02x ", i, buf[i]);
+ }
+ CPRINTF("\n");
+}
+#else
+static inline void print_buffer(uint8_t *buf, int cnt) {}
+#endif
+
+USART_CONFIG(usart_mcdp, CONFIG_MCDP28X0, 115200, MCDP_INBUF_MAX,
+ MCDP_OUTBUF_MAX, NULL, NULL);
+
+/**
+ * Compute checksum.
+ *
+ * @msg message bytes to compute checksum on.
+ * @cnt count of message bytes.
+ * @return partial checksum.
+ */
+static uint8_t compute_checksum(const uint8_t *msg, int cnt)
+{
+ int i;
+ /* 1st byte (not in msg) is always cnt + 2, so seed chksum with that */
+ uint8_t chksum = cnt + 2;
+
+ for (i = 0; i < cnt; i++)
+ chksum += msg[i];
+ return ~chksum + 1;
+}
+
+/**
+ * transmit message over serial
+ *
+ * Packet consists of:
+ * msg[0] == length including this byte + cnt + chksum
+ * msg[1] == 1st message byte
+ * msg[cnt+1] == last message byte
+ * msg[cnt+2] == checksum
+ *
+ * @msg message bytes
+ * @cnt count of message bytes
+ * @return zero if success, error code otherwise
+ */
+static int tx_serial(const uint8_t *msg, int cnt)
+{
+ uint8_t out = cnt + 2;
+ uint8_t chksum = compute_checksum(msg, cnt);
+
+ if (out_stream_write(&usart_mcdp.out, &out, 1) != 1)
+ return EC_ERROR_UNKNOWN;
+
+ if (out_stream_write(&usart_mcdp.out, msg, cnt) != cnt)
+ return EC_ERROR_UNKNOWN;
+
+ if (out_stream_write(&usart_mcdp.out, &chksum, 1) != 1)
+ return EC_ERROR_UNKNOWN;
+
+ print_buffer(usart_mcdp_tx_buffer, cnt + 2);
+
+ return EC_SUCCESS;
+}
+
+/**
+ * receive message over serial
+ *
+ * @msg pointer to buffer to read message into
+ * @cnt count of message bytes
+ * @return zero if success, error code otherwise
+ */
+static int rx_serial(uint8_t *msg, int cnt)
+{
+ size_t read;
+ int retry = 2;
+
+ read = in_stream_read(&usart_mcdp.in, msg, cnt);
+ while ((read < cnt) && retry) {
+ usleep(100*MSEC);
+ read += in_stream_read(&usart_mcdp.in, msg + read,
+ cnt - read);
+ retry--;
+ }
+
+ print_buffer(msg, cnt);
+
+ return !(read == cnt);
+}
+
+void mcdp_enable(void)
+{
+ usart_init(&usart_mcdp);
+}
+
+void mcdp_disable(void)
+{
+ usart_shutdown(&usart_mcdp);
+}
+
+int mcdp_get_info(struct mcdp_info *info)
+{
+ uint8_t inbuf[MCDP_RSP_LEN(MCDP_LEN_GETINFO)];
+ const uint8_t msg[2] = {MCDP_CMD_GETINFO, 0x00}; /* cmd + msg type */
+
+ if (tx_serial(msg, sizeof(msg)))
+ return EC_ERROR_UNKNOWN;
+
+ if (rx_serial(inbuf, sizeof(inbuf)))
+ return EC_ERROR_UNKNOWN;
+
+ /* check length & returned command ... no checksum provided */
+ if (((inbuf[0] - 1) != sizeof(inbuf)) ||
+ (inbuf[1] != MCDP_CMD_GETINFO))
+ return EC_ERROR_UNKNOWN;
+
+ memcpy(info, &inbuf[2], MCDP_LEN_GETINFO);
+
+#ifdef MCDP_DEBUG
+ CPRINTF("family:%04x chipid:%04x irom:%d.%d.%d fw:%d.%d.%d\n",
+ MCDP_FAMILY(info->family), MCDP_CHIPID(info->chipid),
+ info->irom.major, info->irom.minor, info->irom.build,
+ info->fw.major, info->fw.minor, info->fw.build);
+#endif
+ return EC_SUCCESS;
+}
diff --git a/driver/mcdp28x0.h b/driver/mcdp28x0.h
new file mode 100644
index 0000000000..c753816495
--- /dev/null
+++ b/driver/mcdp28x0.h
@@ -0,0 +1,56 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Megachips DisplayPort to HDMI protocol converter / level shifter driver.
+ */
+
+#ifndef MCDP28X0_H
+#define MCDP28X0_H
+
+#include <util.h>
+
+#define MCDP_OUTBUF_MAX 16
+#define MCDP_INBUF_MAX 16
+
+#define MCDP_CHIPID(chipid) ((chipid[0] << 8) | chipid[1])
+#define MCDP_FAMILY(family) ((family[0] << 8) | family[1])
+
+#define MCDP_CMD_GETINFO 0x40
+#define MCDP_LEN_GETINFO 12
+
+/* length byte + cmd byte + data len */
+#define MCDP_RSP_LEN(len) (len + 2)
+
+struct mcdp_version {
+ uint8_t major;
+ uint8_t minor;
+ uint16_t build;
+};
+
+struct mcdp_info {
+ uint8_t family[2];
+ uint8_t chipid[2];
+ struct mcdp_version irom;
+ struct mcdp_version fw;
+};
+
+/**
+ * Enable mcdp driver.
+ */
+void mcdp_enable(void);
+
+/**
+ * Disable mcdp driver.
+ */
+void mcdp_disable(void);
+
+/**
+ * get get information command from mcdp.
+ *
+ * @info pointer to mcdp_info structure
+ * @return zero if success, error code otherwise.
+ */
+int mcdp_get_info(struct mcdp_info *info);
+
+#endif