summaryrefslogtreecommitdiff
path: root/tools/proxyclient/experiments/i2c.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/proxyclient/experiments/i2c.py')
-rwxr-xr-xtools/proxyclient/experiments/i2c.py124
1 files changed, 124 insertions, 0 deletions
diff --git a/tools/proxyclient/experiments/i2c.py b/tools/proxyclient/experiments/i2c.py
new file mode 100755
index 0000000..4100964
--- /dev/null
+++ b/tools/proxyclient/experiments/i2c.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: MIT
+import sys, pathlib
+sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
+
+import struct
+
+from m1n1.setup import *
+from m1n1 import asm
+
+base = 0x235010000
+
+# register defines from https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-pasemi.c
+# Copyright (C) 2006-2007 PA Semi, Inc
+# SMBus host driver for PA Semi PWRficient
+REG_MTXFIFO = 0x00
+REG_MRXFIFO = 0x04
+REG_SMSTA = 0x14
+REG_CTL = 0x1c
+
+MTXFIFO_READ = 0x00000400
+MTXFIFO_STOP = 0x00000200
+MTXFIFO_START = 0x00000100
+MTXFIFO_DATA_M = 0x000000ff
+
+MRXFIFO_EMPTY = 0x00000100
+MRXFIFO_DATA_M = 0x000000ff
+
+SMSTA_XEN = 0x08000000
+SMSTA_MTN = 0x00200000
+
+CTL_MRR = 0x00000400
+CTL_MTR = 0x00000200
+CTL_CLK_M = 0x000000ff
+
+CLK_100K_DIV = 84
+CLK_400K_DIV = 21
+
+
+def i2c_read_reg(addr, reg, reg_size):
+ p.set32(base + REG_CTL, CTL_MTR | CTL_MRR)
+ p.write32(base + REG_SMSTA, 0xffffffff)
+
+ p.write32(base + REG_MTXFIFO, MTXFIFO_START | (addr << 1))
+ p.write32(base + REG_MTXFIFO, MTXFIFO_STOP | reg)
+
+ while not (p.read32(base + REG_SMSTA) & SMSTA_XEN):
+ pass
+
+ p.write32(base + REG_MTXFIFO, MTXFIFO_START | (addr << 1) | 1)
+ p.write32(base + REG_MTXFIFO, MTXFIFO_READ | MTXFIFO_STOP | reg_size + 1)
+
+ res = []
+ while len(res) < reg_size+1:
+ v = p.read32(base + REG_MRXFIFO)
+ if v & 0x100:
+ continue
+ res.append(v)
+
+ if res[0] < reg_size:
+ print("only read %d instead of %d bytes" % (res[0], reg_size))
+ return res[1:]
+
+
+def i2c_write_reg(addr, reg, data):
+ p.set32(base + REG_CTL, CTL_MTR | CTL_MRR)
+ p.write32(base + REG_SMSTA, 0xffffffff)
+
+ p.write32(base + REG_MTXFIFO, MTXFIFO_START | (addr << 1))
+ p.write32(base + REG_MTXFIFO, reg)
+ for i in range(len(data)-1):
+ p.write32(base + REG_MTXFIFO, data[i])
+ p.write32(base + REG_MTXFIFO, data[-1] | MTXFIFO_STOP)
+
+ while not (p.read32(base + REG_SMSTA) & SMSTA_XEN):
+ pass
+
+
+def i2c_read16(addr, reg):
+ data = struct.pack(">2b", *i2c_read_reg(addr, reg, 2))
+ return struct.unpack(">H", data)[0]
+
+
+def i2c_read32(addr, reg):
+ data = struct.pack(">4b", *i2c_read_reg(addr, reg, 4))
+ return struct.unpack(">I", data)[0]
+
+
+def tps6598x_exec_cmd(addr, cmd, data_in, out_len):
+ if data_in:
+ data = [len(data_in)] + data_in
+
+ # TPS_REG_DATA1
+ i2c_write_reg(addr, 0x09, data)
+
+ # TPS_REG_CMD1
+ cmd = [4] + list(map(ord, cmd))
+ i2c_write_reg(addr, 0x08, cmd)
+
+ # TPS_REG_CMD1
+ v = i2c_read32(addr, 0x08)
+ while v != 0:
+ if v == 0x21434d44: # !CMD
+ raise Exception("Invalid command!")
+ v = i2c_read32(addr, 0x08)
+
+ if not out_len:
+ return
+
+ # TPS_REG_DATA1
+ return i2c_read_reg(addr, 0x09, out_len)
+
+
+print("make sure to run pmgr_adt_clocks_enable for /arm-io/i2c0 before this script.")
+
+# apple-specific command to bring the power state to zero
+# (or any other value specified as an argument)
+tps6598x_exec_cmd(0x3f, "SSPS", [0], 0)
+tps6598x_exec_cmd(0x38, "SSPS", [0], 0)
+
+tps6598x_exec_cmd(0x3f, "SWDF", None, 0)
+tps6598x_exec_cmd(0x3f, "SWSr", None, 0)
+tps6598x_exec_cmd(0x38, "SWDF", None, 0)
+tps6598x_exec_cmd(0x38, "SWSr", None, 0)