diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 1345da97b23b..73dc52e114eb 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -83,6 +83,7 @@ static unsigned short SMBHSTCFG = 0xD2;
 #define VT596_BYTE		0x04
 #define VT596_BYTE_DATA		0x08
 #define VT596_WORD_DATA		0x0C
+#define VT596_PROC_CALL		0x10
 #define VT596_BLOCK_DATA	0x14
 #define VT596_I2C_BLOCK_DATA	0x34
 
@@ -233,6 +234,12 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
 		}
 		size = VT596_WORD_DATA;
 		break;
+	case I2C_SMBUS_PROC_CALL:
+		outb_p(command, SMBHSTCMD);
+		outb_p(data->word & 0xff, SMBHSTDAT0);
+		outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
+		size = VT596_PROC_CALL;
+		break;
 	case I2C_SMBUS_I2C_BLOCK_DATA:
 		if (!(vt596_features & FEATURE_I2CBLOCK))
 			goto exit_unsupported;
@@ -263,6 +270,9 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
 	if (status)
 		return status;
 
+	if (size == VT596_PROC_CALL)
+		read_write = I2C_SMBUS_READ;
+
 	if ((read_write == I2C_SMBUS_WRITE) || (size == VT596_QUICK))
 		return 0;
 
@@ -272,6 +282,7 @@ static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
 		data->byte = inb_p(SMBHSTDAT0);
 		break;
 	case VT596_WORD_DATA:
+	case VT596_PROC_CALL:
 		data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
 		break;
 	case VT596_I2C_BLOCK_DATA:
@@ -296,7 +307,7 @@ static u32 vt596_func(struct i2c_adapter *adapter)
 {
 	u32 func = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
 	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-	    I2C_FUNC_SMBUS_BLOCK_DATA;
+	    I2C_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_BLOCK_DATA;
 
 	if (vt596_features & FEATURE_I2CBLOCK)
 		func |= I2C_FUNC_SMBUS_I2C_BLOCK;