#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;