From 6689d7d829f3fa7315bd7fb6bc7f38402b180af3 Mon Sep 17 00:00:00 2001 From: Sam Hurst Date: Tue, 26 May 2020 10:37:09 -0700 Subject: 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 Change-Id: Iace11bd64fe9db2fd7ff14827cb412dae1abcbca Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2216407 Reviewed-by: Wai-Hong Tam (cherry picked from commit c2981839b8879c43896ac8ba726564ce9fe7cf36) Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2332244 --- board/servo_v4p1/board.c | 2 + board/servo_v4p1/build.mk | 1 + board/servo_v4p1/dacs.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ board/servo_v4p1/dacs.h | 37 +++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 board/servo_v4p1/dacs.c create mode 100644 board/servo_v4p1/dacs.h 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 + +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 */ -- cgit v1.2.1