diff options
Diffstat (limited to 'driver/mp2964.c')
-rw-r--r-- | driver/mp2964.c | 152 |
1 files changed, 0 insertions, 152 deletions
diff --git a/driver/mp2964.c b/driver/mp2964.c deleted file mode 100644 index 21a23a8f4c..0000000000 --- a/driver/mp2964.c +++ /dev/null @@ -1,152 +0,0 @@ -/* Copyright 2021 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. - */ - -/* Driver for tuning the MP2964 IMVP8 - IMVP9.1 parameters */ - -#include "console.h" -#include "i2c.h" -#include "mp2964.h" -#include "timer.h" -#include "util.h" - -#define MP2964_STARTUP_WAIT_US (50 * MSEC) -#define MP2964_STORE_WAIT_US (300 * MSEC) -#define MP2964_RESTORE_WAIT_US (2 * MSEC) - -enum reg_page { - REG_PAGE_0, - REG_PAGE_1, - REG_PAGE_COUNT -}; - -static int mp2964_write8(uint8_t reg, uint8_t value) -{ - const uint8_t tx[2] = { reg, value }; - - return i2c_xfer_unlocked(I2C_PORT_MP2964, I2C_ADDR_MP2964_FLAGS, - tx, sizeof(tx), NULL, 0, I2C_XFER_SINGLE); -} - -static void mp2964_read16(uint8_t reg, uint16_t *value) -{ - const uint8_t tx[1] = { reg }; - uint8_t rx[2]; - - i2c_xfer_unlocked(I2C_PORT_MP2964, I2C_ADDR_MP2964_FLAGS, - tx, sizeof(tx), rx, sizeof(rx), I2C_XFER_SINGLE); - *value = (rx[1] << 8) | rx[0]; -} - -static void mp2964_write16(uint8_t reg, uint16_t value) -{ - const uint8_t tx[3] = { reg, value & 0xff, value >> 8 }; - - i2c_xfer_unlocked(I2C_PORT_MP2964, I2C_ADDR_MP2964_FLAGS, - tx, sizeof(tx), NULL, 0, I2C_XFER_SINGLE); -} - -static int mp2964_select_page(enum reg_page page) -{ - int status; - - if (page >= REG_PAGE_COUNT) - return EC_ERROR_INVAL; - - status = mp2964_write8(MP2964_PAGE, page); - if (status != EC_SUCCESS) { - ccprintf("%s: could not select page 0x%02x, error %d\n", - __func__, page, status); - } - return status; -} - -static void mp2964_write_vec16(const struct mp2964_reg_val *init_list, - int count, int *delta) -{ - const struct mp2964_reg_val *reg_val; - uint16_t outval; - int i; - - reg_val = init_list; - for (i = 0; i < count; ++i, ++reg_val) { - mp2964_read16(reg_val->reg, &outval); - if (outval == reg_val->val) { - ccprintf("mp2964: reg 0x%02x already 0x%04x\n", - reg_val->reg, outval); - continue; - } - ccprintf("mp2964: tuning reg 0x%02x from 0x%04x to 0x%04x\n", - reg_val->reg, outval, reg_val->val); - mp2964_write16(reg_val->reg, reg_val->val); - *delta += 1; - } -} - -static int mp2964_store_user_all(void) -{ - const uint8_t wr = MP2964_STORE_USER_ALL; - const uint8_t rd = MP2964_RESTORE_USER_ALL; - int status; - - ccprintf("%s: updating persistent settings\n", __func__); - - status = i2c_xfer_unlocked(I2C_PORT_MP2964, I2C_ADDR_MP2964_FLAGS, - &wr, sizeof(wr), NULL, 0, I2C_XFER_SINGLE); - if (status != EC_SUCCESS) - return status; - - usleep(MP2964_STORE_WAIT_US); - - status = i2c_xfer_unlocked(I2C_PORT_MP2964, I2C_ADDR_MP2964_FLAGS, - &rd, sizeof(rd), NULL, 0, I2C_XFER_SINGLE); - if (status != EC_SUCCESS) - return status; - - usleep(MP2964_RESTORE_WAIT_US); - - return EC_SUCCESS; -} - -static void mp2964_patch_rail(enum reg_page page, - const struct mp2964_reg_val *page_vals, - int count, - int *delta) -{ - if (mp2964_select_page(page) != EC_SUCCESS) - return; - mp2964_write_vec16(page_vals, count, delta); -} - -int mp2964_tune(const struct mp2964_reg_val *rail_a, int count_a, - const struct mp2964_reg_val *rail_b, int count_b) -{ - int tries = 2; - int delta; - - udelay(MP2964_STARTUP_WAIT_US); - - i2c_lock(I2C_PORT_MP2964, 1); - - do { - int status; - - delta = 0; - mp2964_patch_rail(REG_PAGE_0, rail_a, count_a, &delta); - mp2964_patch_rail(REG_PAGE_1, rail_b, count_b, &delta); - if (delta == 0) - break; - - status = mp2964_store_user_all(); - if (status != EC_SUCCESS) - ccprintf("%s: STORE_USER_ALL failed\n", __func__); - } while (--tries > 0); - - i2c_lock(I2C_PORT_MP2964, 0); - - if (delta) - return EC_ERROR_UNKNOWN; - else - return EC_SUCCESS; -} |