summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/build.mk3
-rw-r--r--driver/led/max695x.c123
-rw-r--r--driver/led/max695x.h44
-rw-r--r--include/config.h4
-rw-r--r--include/display_7seg.h27
5 files changed, 201 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk
index 57b111f8c9..5945c281eb 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -83,6 +83,9 @@ driver-$(CONFIG_LED_DRIVER_LM3630A)+=led/lm3630a.o
driver-$(CONFIG_LED_DRIVER_LP5562)+=led/lp5562.o
driver-$(CONFIG_LED_DRIVER_OZ554)+=led/oz554.o
+# 7-segment display
+driver-$(CONFIG_MAX695X_SEVEN_SEGMENT_DISPLAY)+=led/max695x.o
+
# Voltage regulators
driver-$(CONFIG_REGULATOR_IR357X)+=regulator_ir357x.o
diff --git a/driver/led/max695x.c b/driver/led/max695x.c
new file mode 100644
index 0000000000..a563edaf26
--- /dev/null
+++ b/driver/led/max695x.c
@@ -0,0 +1,123 @@
+/* Copyright 2019 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.
+ *
+ * MAX6958/MAX6959 7-Segment LED Display Driver
+ */
+
+#include "common.h"
+#include "console.h"
+#include "display_7seg.h"
+#include "hooks.h"
+#include "i2c.h"
+#include "max695x.h"
+#include "util.h"
+
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
+
+static inline int max695x_i2c_write8(uint8_t offset, uint8_t data)
+{
+ return i2c_write8(I2C_PORT_PORT80, PORT80_I2C_ADDR,
+ offset, (int)data);
+}
+
+static inline int max695x_i2c_write(uint8_t offset, uint8_t *data, int len)
+{
+ /*
+ * The address pointer stored in the MAX695x increments after
+ * each data byte is written unless the address equals 01111111
+ */
+ return i2c_write_block(I2C_PORT_PORT80, PORT80_I2C_ADDR,
+ offset, data, len);
+}
+
+int display_7seg_write(enum seven_seg_module_display module, uint16_t data)
+{
+ uint8_t buf[4];
+
+ /*
+ * Convert the data into binary coded hexadecimal value i.e.
+ * in hexadecimal code-decode mode, the decoder prints 1 byte
+ * on two segments. It checks the lower nibble of the data in
+ * the digit register (D3–D0), disregarding bits D7–D4. Hence,
+ * preparing the hexadecimal buffer to be sent.
+ *
+ * Segment 3-2 : Module name
+ * 0xEC : EC
+ * 0x80 : PORT80
+ * Segment 1-0 : Data
+ * For console Command segment 3-0 : Data
+ */
+ switch (module) {
+ case SEVEN_SEG_CONSOLE_DISPLAY:
+ /* Segment - 3 */
+ buf[0] = (data >> 12) & 0x0F;
+ /* Segment - 2 */
+ buf[1] = (data >> 8) & 0x0F;
+ break;
+ case SEVEN_SEG_EC_DISPLAY:
+ /* Segment - 3 */
+ buf[0] = 0x0E;
+ /* Segment - 2 */
+ buf[1] = 0x0C;
+ break;
+ case SEVEN_SEG_PORT80_DISPLAY:
+ /* Segment - 3 */
+ buf[0] = 0x08;
+ /* Segment - 2 */
+ buf[1] = 0x00;
+ break;
+ default:
+ CPRINTS("Unknown Module\n");
+ return EC_ERROR_UNKNOWN;
+ }
+ /* Segment - 1 */
+ buf[2] = (data >> 4) & 0x0F;
+ /* Segment - 0 */
+ buf[3] = data & 0x0F;
+
+ return max695x_i2c_write(MAX695X_DIGIT0_ADDR, buf, ARRAY_SIZE(buf));
+}
+
+/**
+ * Initialise MAX656x 7-segment display.
+ */
+static void max695x_init(void)
+{
+ uint8_t buf[4] = {
+ [0] = MAX695X_DECODE_MODE_HEX_DECODE,
+ [1] = MAX695X_INTENSITY_MEDIUM,
+ [2] = MAX695X_SCAN_LIMIT_4,
+ [3] = MAX695X_CONFIG_OPR_NORMAL
+ };
+ max695x_i2c_write(MAX695X_REG_DECODE_MODE, buf, ARRAY_SIZE(buf));
+}
+DECLARE_HOOK(HOOK_INIT, max695x_init, HOOK_PRIO_DEFAULT);
+
+static void max695x_shutdown(void)
+{
+ max695x_i2c_write8(MAX695X_REG_CONFIG,
+ MAX695X_CONFIG_OPR_SHUTDOWN);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, max695x_shutdown, HOOK_PRIO_DEFAULT);
+
+#ifdef CONFIG_CMD_SEVEN_SEG_DISPLAY
+static int console_command_max695x_write(int argc, char **argv)
+{
+ char *e;
+ int val;
+
+ if (argc < 2)
+ return EC_ERROR_PARAM_COUNT;
+
+ /* Get value to be written to the seven segment display*/
+ val = strtoi(argv[1], &e, 0);
+ if (*e || val < 0 || val > UINT16_MAX)
+ return EC_ERROR_PARAM1;
+
+ return display_7seg_write(SEVEN_SEG_CONSOLE_DISPLAY, val);
+}
+DECLARE_CONSOLE_COMMAND(seg, console_command_max695x_write,
+ "<val>",
+ "Write to 7 segment display in hex");
+#endif
diff --git a/driver/led/max695x.h b/driver/led/max695x.h
new file mode 100644
index 0000000000..d7e6d26bbf
--- /dev/null
+++ b/driver/led/max695x.h
@@ -0,0 +1,44 @@
+/* Copyright 2019 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.
+ *
+ * MAX6958/MAX6959 7-Segment LED Display Driver header
+ */
+
+#ifndef __CROS_EC_MAX656X_H
+#define __CROS_EC_MAX656X_H
+
+/* I2C interface */
+#define MAX695X_I2C_ADDR1 (0x38 << 1)
+#define MAX695X_I2C_ADDR2 (0x39 << 1)
+
+/* Decode mode register */
+#define MAX695X_REG_DECODE_MODE 0x01
+/* Hexadecimal decode for digits 3–0 */
+#define MAX695X_DECODE_MODE_HEX_DECODE 0x0f
+
+/* Intensity register */
+#define MAX695X_REG_INTENSITY 0x02
+/* Setting meduim intensity */
+#define MAX695X_INTENSITY_MEDIUM 0x20
+
+/* Scan limit register value */
+#define MAX695X_REG_SCAN_LIMIT 0x03
+
+/* Scanning digits 0-3 */
+#define MAX695X_SCAN_LIMIT_4 0x03
+
+/* Configuration register */
+#define MAX695X_REG_CONFIG 0x04
+/* Shutdown seven segment display */
+#define MAX695X_CONFIG_OPR_SHUTDOWN 0x00
+/* Start seven segment display */
+#define MAX695X_CONFIG_OPR_NORMAL 0x01
+
+/* Digit addresses */
+#define MAX695X_DIGIT0_ADDR 0x20
+#define MAX695X_DIGIT1_ADDR 0x21
+#define MAX695X_DIGIT2_ADDR 0x22
+#define MAX695X_DIGIT3_ADDR 0x23
+
+#endif /* __CROS_EC_MAX656X_H */
diff --git a/include/config.h b/include/config.h
index 171938d9cc..30d3416da0 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1120,6 +1120,7 @@
#undef CONFIG_CMD_RTC_ALARM
#define CONFIG_CMD_RW
#undef CONFIG_CMD_SCRATCHPAD
+#undef CONFIG_CMD_SEVEN_SEG_DISPLAY
#define CONFIG_CMD_SHMEM
#undef CONFIG_CMD_SLEEP
#define CONFIG_CMD_SLEEPMASK
@@ -2650,6 +2651,9 @@
*/
#define CONFIG_PORT80_PRINT_IN_INT 0
+/* MAX695x 7 segment driver */
+#undef CONFIG_MAX695X_SEVEN_SEGMENT_DISPLAY
+
/* Compile common code to support power button debouncing */
#undef CONFIG_POWER_BUTTON
diff --git a/include/display_7seg.h b/include/display_7seg.h
new file mode 100644
index 0000000000..9574518cb3
--- /dev/null
+++ b/include/display_7seg.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2019 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.
+ */
+
+/* Seven Segment Display module for Chrome EC */
+
+#ifndef __CROS_EC_DISPLAY_7SEG_H
+#define __CROS_EC_DISPLAY_7SEG_H
+
+enum seven_seg_module_display {
+ SEVEN_SEG_CONSOLE_DISPLAY, /* Console data */
+ SEVEN_SEG_EC_DISPLAY, /* power state */
+ SEVEN_SEG_PORT80_DISPLAY, /* port80 data */
+};
+
+/**
+ * Write register to MAX656x 7-segment display.
+ *
+ * @param module which is writing to the display
+ * @param data to be displayed
+ * @return EC_SUCCESS is write is successful
+ */
+int display_7seg_write(enum seven_seg_module_display module, uint16_t data);
+
+#endif /* __CROS_EC_DISPLAY_7SEG_H */
+