#define GB_CONTROL_VERSION_MINOR       1
 
 
+int gb_control_get_version(struct gb_control *control)
+{
+       struct gb_interface *intf = control->connection->intf;
+       struct gb_control_version_request request;
+       struct gb_control_version_response response;
+       int ret;
+
+       request.major = GB_CONTROL_VERSION_MAJOR;
+       request.minor = GB_CONTROL_VERSION_MINOR;
+
+       ret = gb_operation_sync(control->connection,
+                               GB_CONTROL_TYPE_VERSION,
+                               &request, sizeof(request), &response,
+                               sizeof(response));
+       if (ret) {
+               dev_err(&intf->dev,
+                               "failed to get control-protocol version: %d\n",
+                               ret);
+               return ret;
+       }
+
+       if (response.major > request.major) {
+               dev_err(&intf->dev,
+                               "unsupported major control-protocol version (%u > %u)\n",
+                               response.major, request.major);
+               return -ENOTSUPP;
+       }
+
+       control->protocol_major = response.major;
+       control->protocol_minor = response.minor;
+
+       dev_dbg(&intf->dev, "%s - %u.%u\n", __func__, response.major,
+                       response.minor);
+
+       return 0;
+}
+
 /* Get Manifest's size from the interface */
 int gb_control_get_manifest_size_operation(struct gb_interface *intf)
 {
 
        dev_dbg(&control->connection->intf->dev, "%s\n", __func__);
 
-       ret = gb_connection_legacy_init(control->connection);
+       ret = gb_connection_enable_tx(control->connection);
        if (ret) {
                dev_err(&control->connection->intf->dev,
                                "failed to enable control connection: %d\n",
                return ret;
        }
 
+       ret = gb_control_get_version(control);
+       if (ret)
+               goto err_disable_connection;
+
        return 0;
+
+err_disable_connection:
+       gb_connection_disable(control->connection);
+
+       return ret;
 }
 
 void gb_control_disable(struct gb_control *control)
 {
        dev_dbg(&control->connection->intf->dev, "%s\n", __func__);
 
-       gb_connection_legacy_exit(control->connection);
+       gb_connection_disable(control->connection);
 }
 
 void gb_control_destroy(struct gb_control *control)
        gb_connection_destroy(control->connection);
        kfree(control);
 }
-
-static int gb_control_connection_init(struct gb_connection *connection)
-{
-       dev_dbg(&connection->intf->dev, "%s\n", __func__);
-
-       return 0;
-}
-
-static void gb_control_connection_exit(struct gb_connection *connection)
-{
-       dev_dbg(&connection->intf->dev, "%s\n", __func__);
-}
-
-static struct gb_protocol control_protocol = {
-       .name                   = "control",
-       .id                     = GREYBUS_PROTOCOL_CONTROL,
-       .major                  = GB_CONTROL_VERSION_MAJOR,
-       .minor                  = GB_CONTROL_VERSION_MINOR,
-       .connection_init        = gb_control_connection_init,
-       .connection_exit        = gb_control_connection_exit,
-};
-gb_builtin_protocol_driver(control_protocol);
 
 /* Control Protocol */
 
 /* Greybus control request types */
+#define GB_CONTROL_TYPE_VERSION                        0x01
 #define GB_CONTROL_TYPE_PROBE_AP               0x02
 #define GB_CONTROL_TYPE_GET_MANIFEST_SIZE      0x03
 #define GB_CONTROL_TYPE_GET_MANIFEST           0x04
 #define GB_CONTROL_TYPE_DISCONNECTED           0x06
 #define GB_CONTROL_TYPE_INTERFACE_VERSION      0x0a
 
+struct gb_control_version_request {
+       __u8    major;
+       __u8    minor;
+} __packed;
+
+struct gb_control_version_response {
+       __u8    major;
+       __u8    minor;
+} __packed;
+
 /* Control protocol manifest get size request has no payload*/
 struct gb_control_get_manifest_size_response {
        __le16                  size;