summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hurst <shurst@google.com>2020-05-26 10:37:09 -0700
committerCommit Bot <commit-bot@chromium.org>2020-07-31 20:54:09 +0000
commit6689d7d829f3fa7315bd7fb6bc7f38402b180af3 (patch)
treefecd074515ad4a7ac0689201044fa3c045b0f237
parent7d705d23e34f2031e94461a7dc35b98701f81778 (diff)
downloadchrome-ec-6689d7d829f3fa7315bd7fb6bc7f38402b180af3.tar.gz
servo_v4p1: Add CC DAC functionality
This functionality is available in both RO and RW. BRANCH=none BUG=b:146793000 TEST=make -j buildall Signed-off-by: Sam Hurst <shurst@google.com> Change-Id: Iace11bd64fe9db2fd7ff14827cb412dae1abcbca Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2216407 Reviewed-by: Wai-Hong Tam <waihong@google.com> (cherry picked from commit c2981839b8879c43896ac8ba726564ce9fe7cf36) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2332244
-rw-r--r--board/servo_v4p1/board.c2
-rw-r--r--board/servo_v4p1/build.mk1
-rw-r--r--board/servo_v4p1/dacs.c138
-rw-r--r--board/servo_v4p1/dacs.h37
4 files changed, 178 insertions, 0 deletions
diff --git a/board/servo_v4p1/board.c b/board/servo_v4p1/board.c
index 72c95049d1..0ccf596ddd 100644
--- a/board/servo_v4p1/board.c
+++ b/board/servo_v4p1/board.c
@@ -10,6 +10,7 @@
#include "chg_control.h"
#include "common.h"
#include "console.h"
+#include "dacs.h"
#include "ec_version.h"
#include "gpio.h"
#include "hooks.h"
@@ -307,6 +308,7 @@ static void board_init(void)
usleep(MSEC);
init_ioexpanders();
+ init_dacs();
/* Clear BBRAM, we don't want any PD state carried over on reset. */
system_set_bbram(SYSTEM_BBRAM_IDX_PD0, 0);
diff --git a/board/servo_v4p1/build.mk b/board/servo_v4p1/build.mk
index 3d5712ed59..09711e0beb 100644
--- a/board/servo_v4p1/build.mk
+++ b/board/servo_v4p1/build.mk
@@ -16,6 +16,7 @@ test-list-y=
# These files are compiled into RO and RW
board-y=board.o tca6416a.o tca6424a.o
board-y+=ioexpanders.o
+board-y+=dacs.o
# These files are compiled into RO only
board-ro+=ccd_measure_sbu.o
diff --git a/board/servo_v4p1/dacs.c b/board/servo_v4p1/dacs.c
new file mode 100644
index 0000000000..b5c62bb438
--- /dev/null
+++ b/board/servo_v4p1/dacs.c
@@ -0,0 +1,138 @@
+/* Copyright 2020 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.
+ */
+
+#include "dacs.h"
+#include "i2c.h"
+#include "ioexpanders.h"
+#include "util.h"
+
+#define MAX_MV 5000
+
+#define CC1_DAC_ADDR 0x48
+#define CC2_DAC_ADDR 0x49
+
+#define REG_NOOP 0
+#define REG_DEVID 1
+#define REG_SYNC 2
+#define REG_CONFIG 3
+#define REG_GAIN 4
+#define REG_TRIGGER 5
+#define REG_STATUS 7
+#define REG_DAC 8
+
+#define DAC1 BIT(0)
+#define DAC2 BIT(1)
+
+static uint8_t dac_enabled;
+
+void init_dacs(void)
+{
+ /* Disable both DACS by default */
+ enable_dac(CC1_DAC, 0);
+ enable_dac(CC2_DAC, 0);
+ dac_enabled = 0;
+}
+
+void enable_dac(enum dac_t dac, uint8_t en)
+{
+ switch (dac) {
+ case CC1_DAC:
+ if (en) {
+ fault_clear_cc(1);
+ fault_clear_cc(0);
+ en_vout_buf_cc1(1);
+ /* Power ON DAC */
+ i2c_write8(1, CC1_DAC_ADDR, REG_CONFIG, 0);
+ dac_enabled |= DAC1;
+ } else {
+ en_vout_buf_cc1(0);
+ /* Power OFF DAC */
+ i2c_write8(1, CC1_DAC_ADDR, REG_CONFIG, 1);
+ dac_enabled &= ~DAC1;
+ }
+ break;
+ case CC2_DAC:
+ if (en) {
+ fault_clear_cc(1);
+ fault_clear_cc(0);
+ en_vout_buf_cc2(1);
+ i2c_write8(1, CC2_DAC_ADDR, REG_CONFIG, 0);
+ dac_enabled |= DAC2;
+ } else {
+ en_vout_buf_cc2(0);
+ /* Power down DAC */
+ i2c_write8(1, CC2_DAC_ADDR, REG_CONFIG, 1);
+ dac_enabled &= ~DAC2;
+ }
+ break;
+ }
+}
+
+int write_dac(enum dac_t dac, uint16_t value)
+{
+ uint16_t tmp;
+
+ /*
+ * Data are MSB aligned in straight binary format, and
+ * use the following format: DATA[13:0], 0, 0
+ */
+ tmp = (value << 8) & 0xff00;
+ tmp |= (value >> 8) & 0xff;
+ tmp <<= 2;
+
+ switch (dac) {
+ case CC1_DAC:
+ if (!(dac_enabled & DAC1)) {
+ ccprintf("CC1_DAC is disabled\n");
+ return EC_ERROR_ACCESS_DENIED;
+ }
+ i2c_write16(1, CC1_DAC_ADDR, REG_DAC, tmp);
+ break;
+ case CC2_DAC:
+ if (!(dac_enabled & DAC2)) {
+ ccprintf("CC2_DAC is disabled\n");
+ return EC_ERROR_ACCESS_DENIED;
+ }
+ i2c_write16(1, CC2_DAC_ADDR, REG_DAC, tmp);
+ break;
+ }
+ return EC_SUCCESS;
+}
+
+static int cmd_cc_dac(int argc, char *argv[])
+{
+ uint8_t dac;
+ uint64_t mv;
+ uint64_t round_up;
+ char *e;
+
+ if (argc < 3)
+ return EC_ERROR_PARAM_COUNT;
+
+ dac = strtoi(argv[1], &e, 10);
+ if (*e || (dac != CC1_DAC && dac != CC2_DAC))
+ return EC_ERROR_PARAM2;
+
+ if (!strcasecmp(argv[2], "on")) {
+ enable_dac(dac, 1);
+ } else if (!strcasecmp(argv[2], "off")) {
+ enable_dac(dac, 0);
+ } else {
+ /* get value in mV */
+ mv = strtoi(argv[2], &e, 10);
+ /* 5000 mV max */
+ if (*e || mv > MAX_MV)
+ return EC_ERROR_PARAM3;
+ /* 305176 = (5V / 2^14) * 1000000 */
+ /* 152588 = 305176 / 2 : used for round up after division */
+ round_up = (((mv * 1000000) + 152588) / 305176);
+ if (!write_dac(dac, (uint16_t)round_up))
+ ccprintf("Setting DAC to %lld counts\n", round_up);
+ }
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(cc_dac, cmd_cc_dac,
+ "dac <\"on\"|\"off\"|mv>",
+ "Set Servo v4.1 CC dacs");
diff --git a/board/servo_v4p1/dacs.h b/board/servo_v4p1/dacs.h
new file mode 100644
index 0000000000..bd0ecd67da
--- /dev/null
+++ b/board/servo_v4p1/dacs.h
@@ -0,0 +1,37 @@
+/* Copyright 2020 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.
+ */
+#ifndef __CROS_EC_DACS_H
+#define __CROS_EC_DACS_H
+
+#include <stdint.h>
+
+enum dac_t {
+ CC1_DAC = 1,
+ CC2_DAC,
+};
+
+/*
+ * Initialize the DACs
+ */
+void init_dacs(void);
+
+/*
+ * Enable/Disable one of the DACs
+ *
+ * @param dac DAC to enable or disable
+ * @param en 0 to disable or 1 to enable
+ */
+void enable_dac(enum dac_t dac, uint8_t en);
+
+/*
+ * Write a value to the DAC
+ *
+ * @param dac DAC to write to
+ * @param value to write to the DAC in mV. (0 to 5000mV)
+ * @return EC_SUCCESS or EC_ERROR_ACCESS_DENIED on failure
+ */
+int write_dac(enum dac_t dac, uint16_t value);
+
+#endif /* __CROS_EC_DACS_H */