From 19151c3dd4cfcced6f173a9b1e5aba07d7d1d9b9 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 9 Sep 2015 21:08:29 +0530 Subject: [PATCH] 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 Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/greybus_protocols.h | 24 ++++++++++ drivers/staging/greybus/svc.c | 72 +++++++++++++++++++++++++++++ drivers/staging/greybus/svc.h | 4 ++ 3 files changed, 100 insertions(+) diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 76fea9a..6fd20bd 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 73fad4a..241b9da 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 f1acb82..75518f8 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); -- 2.7.4