summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2015-09-09 21:08:29 +0530
committerGreg Kroah-Hartman <gregkh@google.com>2015-09-14 21:52:16 -0700
commit19151c3dd4cfcced6f173a9b1e5aba07d7d1d9b9 (patch)
treeccbe2308121b0078907964ea973f8d61f2768b9e /drivers
parent26717ed328b5d238b5c6268912d45703b99b79d0 (diff)
greybus: svc: Implement DME peer get/set attributes helpers
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/greybus/greybus_protocols.h24
-rw-r--r--drivers/staging/greybus/svc.c72
-rw-r--r--drivers/staging/greybus/svc.h4
3 files changed, 100 insertions, 0 deletions
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
index 76fea9a8ef27..6fd20bdc94af 100644
--- a/drivers/staging/greybus/greybus_protocols.h
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -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;
diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c
index 73fad4a735f2..241b9da2f823 100644
--- a/drivers/staging/greybus/svc.c
+++ b/drivers/staging/greybus/svc.c
@@ -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)
diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h
index f1acb82523d1..75518f8a199e 100644
--- a/drivers/staging/greybus/svc.h
+++ b/drivers/staging/greybus/svc.h
@@ -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);