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>
This commit is contained in:
Viresh Kumar 2015-09-09 21:08:29 +05:30 committed by Greg Kroah-Hartman
parent 26717ed328
commit 19151c3dd4
3 changed files with 100 additions and 0 deletions

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

View 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)

View 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);