summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/intel/common')
-rw-r--r--src/southbridge/intel/common/smbus.c45
-rw-r--r--src/southbridge/intel/common/smbus.h2
2 files changed, 47 insertions, 0 deletions
diff --git a/src/southbridge/intel/common/smbus.c b/src/southbridge/intel/common/smbus.c
index af1eb602a0..e575abc40e 100644
--- a/src/southbridge/intel/common/smbus.c
+++ b/src/southbridge/intel/common/smbus.c
@@ -4,6 +4,7 @@
* Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
* Copyright (C) 2009 coresystems GmbH
* Copyright (C) 2013 Vladimir Serbinenko
+ * Copyright (C) 2018-2019 Eltan B.V.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -410,3 +411,47 @@ int do_i2c_eeprom_read(unsigned int smbus_base, u8 device,
return ret;
}
+
+/*
+ * The caller is responsible of settings HOSTC I2C_EN bit prior to making this
+ * call!
+ */
+int do_i2c_block_write(unsigned int smbus_base, u8 device,
+ unsigned int bytes, u8 *buf)
+{
+ u8 cmd;
+ int ret;
+
+ if (!CONFIG(SOC_INTEL_BRASWELL))
+ return SMBUS_ERROR;
+
+ if (!bytes || (bytes > SMBUS_BLOCK_MAXLEN))
+ return SMBUS_ERROR;
+
+ /* Set up for a block data write. */
+ ret = setup_command(smbus_base, I801_BLOCK_DATA, XMIT_WRITE(device));
+ if (ret < 0)
+ return ret;
+
+ /*
+ * In i2c mode SMBus controller sequence on bus will be:
+ * <SMBXINTADD> <SMBHSTDAT1> <SMBBLKDAT> .. <SMBBLKDAT>
+ * The SMBHSTCMD must be written also to ensure the SMBUs controller
+ * will generate the i2c sequence.
+ */
+ cmd = *buf++;
+ bytes--;
+ outb(cmd, smbus_base + SMBHSTCMD);
+ outb(cmd, smbus_base + SMBHSTDAT1);
+
+ /* Execute block transaction. */
+ ret = block_cmd_loop(smbus_base, buf, bytes, BLOCK_WRITE);
+ if (ret < 0)
+ return ret;
+
+ if (ret < bytes)
+ return SMBUS_ERROR;
+
+ ret++; /* 1st byte has been written using SMBHSTDAT1 */
+ return ret;
+}
diff --git a/src/southbridge/intel/common/smbus.h b/src/southbridge/intel/common/smbus.h
index ded31d0ae2..4875581573 100644
--- a/src/southbridge/intel/common/smbus.h
+++ b/src/southbridge/intel/common/smbus.h
@@ -43,4 +43,6 @@ int do_smbus_block_write(unsigned int smbus_base, u8 device,
/* Only since ICH5 */
int do_i2c_eeprom_read(unsigned int smbus_base, u8 device,
unsigned int offset, unsigned int bytes, u8 *buf);
+int do_i2c_block_write(unsigned int smbus_base, u8 device,
+ unsigned int bytes, u8 *buf);
#endif