greybus: svc: Implement DME peer get/set attributes helpers
authorViresh Kumar <viresh.kumar@linaro.org>
Wed, 9 Sep 2015 15:38:29 +0000 (21:08 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Tue, 15 Sep 2015 04:52:16 +0000 (21:52 -0700)
These are required to get/set DME attributes of the modules. This is
implemented based on the greybus specifications.

Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-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
drivers/staging/greybus/svc.h

index 76fea9a8ef273cf39b64c3c97fe80b14134dd108..6fd20bdc94af4cd15525fd118595acf06ac5ff6f 100644 (file)
@@ -742,6 +742,8 @@ struct gb_spi_transfer_response {
 #define GB_SVC_TYPE_INTF_RESET         0x06
 #define GB_SVC_TYPE_CONN_CREATE                0x07
 #define GB_SVC_TYPE_CONN_DESTROY       0x08
+#define GB_SVC_TYPE_DME_PEER_GET       0x09
+#define GB_SVC_TYPE_DME_PEER_SET       0x0a
 #define GB_SVC_TYPE_ROUTE_CREATE       0x0b
 #define GB_SVC_TYPE_ROUTE_DESTROY      0x0c
 
@@ -799,6 +801,28 @@ struct gb_svc_conn_destroy_request {
 } __packed;
 /* connection destroy response has no payload */
 
+struct gb_svc_dme_peer_get_request {
+       __u8    intf_id;
+       __u16   attr;
+       __u16   selector;
+} __packed;
+
+struct gb_svc_dme_peer_get_response {
+       __u16   result_code;
+       __u32   attr_value;
+} __packed;
+
+struct gb_svc_dme_peer_set_request {
+       __u8    intf_id;
+       __u16   attr;
+       __u16   selector;
+       __u32   value;
+} __packed;
+
+struct gb_svc_dme_peer_set_response {
+       __u16   result_code;
+} __packed;
+
 struct gb_svc_route_create_request {
        __u8    intf1_id;
        __u8    dev1_id;
index 73fad4a735f2581be8b85de060c6e5afd7aee912..241b9da2f8238d80942c5551bab32c916f049d98 100644 (file)
@@ -104,6 +104,78 @@ int gb_svc_intf_reset(struct gb_svc *svc, u8 intf_id)
 }
 EXPORT_SYMBOL_GPL(gb_svc_intf_reset);
 
+int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+                       u32 *value)
+{
+       struct gb_svc_dme_peer_get_request request;
+       struct gb_svc_dme_peer_get_response response;
+       u16 result;
+       int ret;
+
+       request.intf_id = intf_id;
+       request.attr = cpu_to_le16(attr);
+       request.selector = cpu_to_le16(selector);
+
+       ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_DME_PEER_GET,
+                               &request, sizeof(request),
+                               &response, sizeof(response));
+       if (ret) {
+               dev_err(&svc->connection->dev,
+                       "failed to get DME attribute (%hhu %hx %hu) %d\n",
+                       intf_id, attr, selector, ret);
+               return ret;
+       }
+
+       result = le16_to_cpu(response.result_code);
+       if (result) {
+               dev_err(&svc->connection->dev,
+                       "Unipro error %hu while getting DME attribute (%hhu %hx %hu)\n",
+                       result, intf_id, attr, selector);
+               return -EINVAL;
+       }
+
+       if (value)
+               *value = le32_to_cpu(response.attr_value);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gb_svc_dme_peer_get);
+
+int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+                       u32 value)
+{
+       struct gb_svc_dme_peer_set_request request;
+       struct gb_svc_dme_peer_set_response response;
+       u16 result;
+       int ret;
+
+       request.intf_id = intf_id;
+       request.attr = cpu_to_le16(attr);
+       request.selector = cpu_to_le16(selector);
+       request.value = cpu_to_le32(value);
+
+       ret = gb_operation_sync(svc->connection, GB_SVC_TYPE_DME_PEER_SET,
+                               &request, sizeof(request),
+                               &response, sizeof(response));
+       if (ret) {
+               dev_err(&svc->connection->dev,
+                       "failed to set DME attribute (%hhu %hx %hu %u) %d\n",
+                       intf_id, attr, selector, value, ret);
+               return ret;
+       }
+
+       result = le16_to_cpu(response.result_code);
+       if (result) {
+               dev_err(&svc->connection->dev,
+                       "Unipro error %hu while setting DME attribute (%hhu %hx %hu %u)\n",
+                       result, intf_id, attr, selector, value);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gb_svc_dme_peer_set);
+
 int gb_svc_connection_create(struct gb_svc *svc,
                                u8 intf1_id, u16 cport1_id,
                                u8 intf2_id, u16 cport2_id)
index f1acb82523d15955e80069e7e9eef2bcb593c037..75518f8a199e430ee1246d94c056fba3bb34db9a 100644 (file)
@@ -17,6 +17,10 @@ int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
                                                u8 intf2_id, u16 cport2_id);
 void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
                               u8 intf2_id, u16 cport2_id);
+int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+                       u32 *value);
+int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,
+                       u32 value);
 
 int gb_svc_protocol_init(void);
 void gb_svc_protocol_exit(void);