diff options
author | Ayushee <ayushee.shah@intel.com> | 2019-04-05 11:39:51 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-02 16:12:40 -0700 |
commit | b7a7ad3ffc436fc074c79b62194c33980e746586 (patch) | |
tree | 7332a81c666c66db9f6af9fc4422aae105c5f1b5 | |
parent | 34366869bbab2e7c27a037b4c7d3c15ee5bf151a (diff) | |
download | chrome-ec-b7a7ad3ffc436fc074c79b62194c33980e746586.tar.gz |
driver/max695x: Add 7 segment display driver
Port80 information and power sequencing states can be displayed on the
7-segment so that we can observe its information without connecting a
debugger. Adding this CL to initialize and write to the 7-segment display.
For port80, 80(data) gets displayed on the seven segment, for the
power states, EC(state) gets displayed on the seven segment.
The MAX6958/MAX6959 is a compact multiplexed common - cathode display
designed to interface microprocessors with seven - segment numerical LED
digits or to discrete LEDs via a 2-wire serial interface compatible with
SMBusTM and I2C. The 2-wire serial interface uses fixed logic thresholds
of 0.8V/2.1V when the display driver is powered from a 5V supply for
compatibility with 2.5V and 3.3V systems.
BRANCH=None
BUG=b:130738086
TEST=Manually tested on intelrvp, able to write to the 7 segment display
Change-Id: I82ba3aca40640e094463669aa1ff106ce7b99b7b
Signed-off-by: Ayushee <ayushee.shah@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/1574665
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Ayushee Shah <ayushee.shah@intel.com>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r-- | driver/build.mk | 3 | ||||
-rw-r--r-- | driver/led/max695x.c | 123 | ||||
-rw-r--r-- | driver/led/max695x.h | 44 | ||||
-rw-r--r-- | include/config.h | 4 | ||||
-rw-r--r-- | include/display_7seg.h | 27 |
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 */ + |