micetools/src/micetools/dll/smbus.h

172 lines
4.6 KiB
C

#pragma once
#include "common.h"
// PCA9535 (DIPSW)
#define PCA9535_IN0 0x00
#define PCA9535_IN1 0x01
#define PCA9535_OUT0 0x02
#define PCA9535_OUT1 0x03
#define PCA9535_INV0 0x04
#define PCA9535_INV1 0x05
#define PCA9535_CONF0 0x06
#define PCA9535_CONF1 0x07
/*
W83627UHG:
Configuration is based on HEFRAS
Configuration 0:
[Logical index port] 0x2e
[Logical data port] 0x2f
Configuration 1:
[Logical index port] 0x4e
[Logical data port] 0x4f
Setup:
! Select logical device 0 = FDC (in this case, we don't care)
index = 0x07, data = 0x00
index = 0x20, read data (Chip ID MSB)
index = 0x21, read data (Chip ID LSB)
[merge two bytes to get chip ID]
! Select logical device B = HM
* Read base address of address and data ports
* Address = xxxh + 5h, Data = xxxh + 6h
index = 0x07, data = 0x0b
index = 0x60, read data (Base MSB)
index = 0x61, read data (Base LSB)
[merge two bytes to get address]
ICH9 Smbus Controller:
mxsmbus.sys -> io-controller-hub-9-datasheet.pdf, page 759
PEC is disabled
Requests are made using a virtual address.
The physical address is *2 of the virtual, +1 for read.
Commands:
0: paddr = vaddr * 2 ; smb_cmd = quick
1: paddr = vaddr * 2 + 1; smb_cmd = quick
2: paddr = vaddr * 2 ; smb_cmd = byte
3: paddr = vaddr * 2 + 1; smb_cmd = byte
4: paddr = vaddr * 2 ; smb_cmd = byte data
5: paddr = vaddr * 2 + 1; smb_cmd = byte data
6: paddr = vaddr * 2 ; smb_cmd = word data
7: paddr = vaddr * 2 + 1; smb_cmd = word data
8: paddr = vaddr * 2 ; smb_cmd = block
9: paddr = vaddr * 2 + 1; smb_cmd = block
10: paddr = vaddr * 2 ; smb_cmd = process call
11: paddr = vaddr * 2 ; smb_cmd = i2c read
IOCTL_MXSMBUS_REQUEST:
assert command <= 11
0x25 bytes
IOCTL_MXSMBUS_I2C:
assert command <= 10
0x27 bytes
LPC device 0x00 = FPC
LPC device 0x07 = W83627UHG
smbus:
0x801:
PCA9535: 0000 100[Wr] | 8 bit addr/reg | [...
amHmI2C: 0000 100[Wr] | 8 bit addr/reg | [...
superio:
0x803:
amHmLPC:
IOCTL_MXSUPERIO_READ:
read 1: -> .. 0B 20 00
<- .. .. .. XX
read 2: -> .. 0B 21 00
<- .. .. .. YY
assert XXYY == 0xA020 (case 1) or 0xA230 (case 2)
! SMBUS is I2C
- ICH9: **host** (schematics, sheet 11)
- EEPROM AT24C64AN: 0AE (schematics, sheet 10)
- DDR2 DIMM A1: 0A0 (schematics, sheet 13)
- DDR2 DIMM B1: 0A4 (schematics, sheet 14)
- ICS9LPRS908: 0x?? (schematics, sheet 15)
- W83627UHG LPC I/O: 0x?? (schematics, sheet 16) ((2E / 4E on a toggle?))
- Mystery chips on the mezanine and keychip (schematics, sheet 17)
- VRMs: 0x?? (schematics, sheet 27)
! ??? is SPI
! System SPI
- SPI Flash ROM: ??? (schematics, sheet 11)
-
! LPC (superio) is its own thing?
- ICH9: **host** (schematics, sheet 11)
- TPM (schematics, sheet 10)
- W83627UHC (schematics, sheet 16)
*/
// Keychip
// #define DS_REG_ID 0xA0
// #define DS_REG_ID_END 0xA7
// #define DS_REG_STATUS 0xA8
// #define DS_STATUS_FLAG_BUSY 2
// #define DS_I2C_CHALLENGE_RESPONSE 0xB0
#pragma pack(push, 1)
typedef struct _MXSMBUS_REQUEST_PACKET {
BYTE status;
BYTE command;
BYTE v_addr;
BYTE command_code;
BYTE nbytes;
BYTE data[32];
} MXSMBUS_REQUEST_PACKET, *PMXSMBUS_REQUEST_PACKET;
typedef struct _MXSMBUS_I2C_PACKET {
BYTE status;
BYTE command;
WORD v_addr;
WORD command_code;
BYTE nbytes;
BYTE data[32];
} MXSMBUS_I2C_PACKET, *PMXSMBUS_I2C_PACKET;
#pragma pack(pop)
typedef enum {
ICH9_CMD_QUICK = 0b000,
ICH9_CMD_BYTE = 0b001,
ICH9_CMD_BYTE_DATA = 0b010,
ICH9_CMD_WORD_DATA = 0b011,
ICH9_CMD_PROCESS_CALL = 0b100,
ICH9_CMD_BLOCK = 0b101,
ICH9_CMD_I2C_READ = 0b110,
ICH9_CMD_BLOCK_PROCESS = 0b111,
} ich9_cmd_t;
typedef enum {
MXSMBUS_CMD_WRITE_QUICK = 0,
MXSMBUS_CMD_READ_QUICK = 1,
MXSMBUS_CMD_WRITE_BYTE = 2,
MXSMBUS_CMD_READ_BYTE = 3,
MXSMBUS_CMD_WRITE_BYTE_DATA = 4,
MXSMBUS_CMD_READ_BYTE_DATA = 5,
MXSMBUS_CMD_WRITE_WORD_DATA = 6,
MXSMBUS_CMD_READ_WORD_DATA = 7,
MXSMBUS_CMD_WRITE_BLOCK = 8,
MXSMBUS_CMD_READ_BLOCK = 9,
MXSMBUS_CMD_PROCESS_CALL = 10,
MXSMBUS_CMD_I2C = 11,
} mxsmbus_cmd_t;
typedef BOOL smbus_callback_t(ich9_cmd_t cmd, WORD code, BYTE nbytes, BYTE* data);
void smbus_install(BYTE v_addr, smbus_callback_t* write, smbus_callback_t* read);