coreboot-libre-fam15h-rdimm/3rdparty/chromeec/driver/led/max695x.c

124 lines
3.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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 (D3D0), disregarding bits D7D4. 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");
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