greybus: svc: implement svc_intf_{vsys,refclk,unipro}_{enable,disable} operations
authorJeffrey Carlyle <jcarlyle@google.com>
Fri, 6 May 2016 19:43:52 +0000 (12:43 -0700)
committerGreg Kroah-Hartman <gregkh@google.com>
Mon, 9 May 2016 06:47:18 +0000 (08:47 +0200)
Add SVC operations for fine grain control over vsys, refclk, and unipro
port power.

Testing done: used "new" firmware boot sequence to verify that modules
              were correctly detected and booted.

Signed-off-by: Jeffrey Carlyle <jcarlyle@google.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/greybus_protocols.h
drivers/staging/greybus/svc.c

index 9b21a35..c77fb25 100644 (file)
@@ -840,6 +840,12 @@ struct gb_spi_transfer_response {
 #define GB_SVC_TYPE_TIMESYNC_PING              0x1a
 #define GB_SVC_TYPE_MODULE_INSERTED            0x1f
 #define GB_SVC_TYPE_MODULE_REMOVED             0x20
+#define GB_SVC_TYPE_INTF_VSYS_ENABLE           0x21
+#define GB_SVC_TYPE_INTF_VSYS_DISABLE          0x22
+#define GB_SVC_TYPE_INTF_REFCLK_ENABLE         0x23
+#define GB_SVC_TYPE_INTF_REFCLK_DISABLE                0x24
+#define GB_SVC_TYPE_INTF_UNIPRO_ENABLE         0x25
+#define GB_SVC_TYPE_INTF_UNIPRO_DISABLE                0x26
 #define GB_SVC_TYPE_INTF_ACTIVATE              0x27
 #define GB_SVC_TYPE_INTF_MAILBOX_EVENT         0x29
 
@@ -954,6 +960,43 @@ struct gb_svc_route_destroy_request {
 } __packed;
 /* route destroy response has no payload */
 
+/* used for svc_intf_vsys_{enable,disable} */
+struct gb_svc_intf_vsys_request {
+       __u8    intf_id;
+} __packed;
+
+struct gb_svc_intf_vsys_response {
+       __u8    result_code;
+#define GB_SVC_INTF_VSYS_OK                            0x00
+#define GB_SVC_INTF_VSYS_BUSY                          0x01
+#define GB_SVC_INTF_VSYS_FAIL                          0x02
+} __packed;
+
+/* used for svc_intf_refclk_{enable,disable} */
+struct gb_svc_intf_refclk_request {
+       __u8    intf_id;
+} __packed;
+
+struct gb_svc_intf_refclk_response {
+       __u8    result_code;
+#define GB_SVC_INTF_REFCLK_OK                          0x00
+#define GB_SVC_INTF_REFCLK_BUSY                                0x01
+#define GB_SVC_INTF_REFCLK_FAIL                                0x02
+} __packed;
+
+/* used for svc_intf_unipro_{enable,disable} */
+struct gb_svc_intf_unipro_request {
+       __u8    intf_id;
+} __packed;
+
+struct gb_svc_intf_unipro_response {
+       __u8    result_code;
+#define GB_SVC_INTF_UNIPRO_OK                          0x00
+#define GB_SVC_INTF_UNIPRO_BUSY                                0x01
+#define GB_SVC_INTF_UNIPRO_FAIL                                0x02
+#define GB_SVC_INTF_UNIPRO_NOT_OFF                     0x03
+} __packed;
+
 struct gb_svc_timesync_enable_request {
        __u8    count;
        __le64  frame_time;
index f3ee94e..1e6cab0 100644 (file)
@@ -257,22 +257,70 @@ int gb_svc_intf_eject(struct gb_svc *svc, u8 intf_id)
 
 int gb_svc_intf_vsys_set(struct gb_svc *svc, u8 intf_id, bool enable)
 {
-       /* FIXME: implement */
+       struct gb_svc_intf_vsys_request request;
+       struct gb_svc_intf_vsys_response response;
+       int type, ret;
+
+       request.intf_id = intf_id;
 
+       if (enable)
+               type = GB_SVC_TYPE_INTF_VSYS_ENABLE;
+       else
+               type = GB_SVC_TYPE_INTF_VSYS_DISABLE;
+
+       ret = gb_operation_sync(svc->connection, type,
+                       &request, sizeof(request),
+                       &response, sizeof(response));
+       if (ret < 0)
+               return ret;
+       if (response.result_code != GB_SVC_INTF_VSYS_OK)
+               return -EREMOTEIO;
        return 0;
 }
 
 int gb_svc_intf_refclk_set(struct gb_svc *svc, u8 intf_id, bool enable)
 {
-       /* FIXME: implement */
+       struct gb_svc_intf_refclk_request request;
+       struct gb_svc_intf_refclk_response response;
+       int type, ret;
 
+       request.intf_id = intf_id;
+
+       if (enable)
+               type = GB_SVC_TYPE_INTF_REFCLK_ENABLE;
+       else
+               type = GB_SVC_TYPE_INTF_REFCLK_DISABLE;
+
+       ret = gb_operation_sync(svc->connection, type,
+                       &request, sizeof(request),
+                       &response, sizeof(response));
+       if (ret < 0)
+               return ret;
+       if (response.result_code != GB_SVC_INTF_REFCLK_OK)
+               return -EREMOTEIO;
        return 0;
 }
 
 int gb_svc_intf_unipro_set(struct gb_svc *svc, u8 intf_id, bool enable)
 {
-       /* FIXME: implement */
+       struct gb_svc_intf_unipro_request request;
+       struct gb_svc_intf_unipro_response response;
+       int type, ret;
+
+       request.intf_id = intf_id;
+
+       if (enable)
+               type = GB_SVC_TYPE_INTF_UNIPRO_ENABLE;
+       else
+               type = GB_SVC_TYPE_INTF_UNIPRO_DISABLE;
 
+       ret = gb_operation_sync(svc->connection, type,
+                       &request, sizeof(request),
+                       &response, sizeof(response));
+       if (ret < 0)
+               return ret;
+       if (response.result_code != GB_SVC_INTF_UNIPRO_OK)
+               return -EREMOTEIO;
        return 0;
 }