2014-10-28 18:36:00 -06:00
|
|
|
/*
|
|
|
|
* Greybus protocol handling
|
|
|
|
*
|
|
|
|
* Copyright 2014 Google Inc.
|
2014-12-12 11:08:42 -07:00
|
|
|
* Copyright 2014 Linaro Ltd.
|
2014-10-28 18:36:00 -06:00
|
|
|
*
|
|
|
|
* Released under the GPLv2 only.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __PROTOCOL_H
|
|
|
|
#define __PROTOCOL_H
|
|
|
|
|
2015-05-19 03:22:41 -06:00
|
|
|
struct gb_connection;
|
2014-11-05 15:12:55 -07:00
|
|
|
struct gb_operation;
|
|
|
|
|
2015-01-21 05:42:36 -07:00
|
|
|
/* version request has no payload */
|
|
|
|
struct gb_protocol_version_response {
|
|
|
|
__u8 major;
|
|
|
|
__u8 minor;
|
|
|
|
};
|
|
|
|
|
2014-11-05 15:12:54 -07:00
|
|
|
typedef int (*gb_connection_init_t)(struct gb_connection *);
|
|
|
|
typedef void (*gb_connection_exit_t)(struct gb_connection *);
|
2015-03-27 05:45:49 -06:00
|
|
|
typedef int (*gb_request_recv_t)(u8, struct gb_operation *);
|
2014-11-05 15:12:54 -07:00
|
|
|
|
2014-11-05 15:12:50 -07:00
|
|
|
/*
|
|
|
|
* Protocols having the same id but different major and/or minor
|
|
|
|
* version numbers are treated as distinct protocols. If it makes
|
|
|
|
* sense someday we could group protocols having the same id.
|
|
|
|
*/
|
2014-10-28 18:36:00 -06:00
|
|
|
struct gb_protocol {
|
2014-11-05 15:12:50 -07:00
|
|
|
u8 id;
|
|
|
|
u8 major;
|
|
|
|
u8 minor;
|
2014-11-05 15:12:51 -07:00
|
|
|
u8 count;
|
2014-11-05 15:12:50 -07:00
|
|
|
|
|
|
|
struct list_head links; /* global list */
|
2014-11-05 15:12:54 -07:00
|
|
|
|
|
|
|
gb_connection_init_t connection_init;
|
|
|
|
gb_connection_exit_t connection_exit;
|
2014-11-05 15:12:55 -07:00
|
|
|
gb_request_recv_t request_recv;
|
2014-12-24 14:01:40 -07:00
|
|
|
struct module *owner;
|
2014-12-24 14:01:45 -07:00
|
|
|
char *name;
|
2014-10-28 18:36:00 -06:00
|
|
|
};
|
|
|
|
|
2014-12-24 14:01:40 -07:00
|
|
|
int __gb_protocol_register(struct gb_protocol *protocol, struct module *module);
|
2014-12-23 16:16:51 -07:00
|
|
|
int gb_protocol_deregister(struct gb_protocol *protocol);
|
2014-10-28 18:36:00 -06:00
|
|
|
|
2014-12-24 14:01:40 -07:00
|
|
|
#define gb_protocol_register(protocol) \
|
|
|
|
__gb_protocol_register(protocol, THIS_MODULE)
|
|
|
|
|
2014-11-05 15:12:51 -07:00
|
|
|
struct gb_protocol *gb_protocol_get(u8 id, u8 major, u8 minor);
|
2015-01-21 05:42:36 -07:00
|
|
|
int gb_protocol_get_version(struct gb_connection *connection, int type,
|
|
|
|
void *request, int request_size,
|
|
|
|
struct gb_protocol_version_response *response,
|
|
|
|
__u8 major);
|
|
|
|
|
2014-11-05 15:12:51 -07:00
|
|
|
void gb_protocol_put(struct gb_protocol *protocol);
|
2014-10-28 18:36:00 -06:00
|
|
|
|
2014-11-05 15:12:53 -07:00
|
|
|
/*
|
|
|
|
* These are defined in their respective protocol source files.
|
|
|
|
* Declared here for now. They could be added via modules, or maybe
|
|
|
|
* just use initcalls (which level?).
|
|
|
|
*/
|
2014-12-23 16:16:51 -07:00
|
|
|
extern int gb_gpio_protocol_init(void);
|
2014-11-05 15:12:53 -07:00
|
|
|
extern void gb_gpio_protocol_exit(void);
|
|
|
|
|
2014-12-23 16:16:51 -07:00
|
|
|
extern int gb_pwm_protocol_init(void);
|
2014-11-13 07:14:13 -07:00
|
|
|
extern void gb_pwm_protocol_exit(void);
|
|
|
|
|
2014-12-23 16:16:51 -07:00
|
|
|
extern int gb_uart_protocol_init(void);
|
2014-11-05 15:12:53 -07:00
|
|
|
extern void gb_uart_protocol_exit(void);
|
|
|
|
|
2014-12-23 16:16:51 -07:00
|
|
|
extern int gb_sdio_protocol_init(void);
|
2014-11-05 15:12:53 -07:00
|
|
|
extern void gb_sdio_protocol_exit(void);
|
|
|
|
|
2014-12-23 16:16:51 -07:00
|
|
|
extern int gb_usb_protocol_init(void);
|
2014-11-25 17:59:21 -07:00
|
|
|
extern void gb_usb_protocol_exit(void);
|
|
|
|
|
2014-12-24 14:01:44 -07:00
|
|
|
extern int gb_i2c_protocol_init(void);
|
|
|
|
extern void gb_i2c_protocol_exit(void);
|
|
|
|
|
2015-01-23 00:37:45 -07:00
|
|
|
extern int gb_spi_protocol_init(void);
|
|
|
|
extern void gb_spi_protocol_exit(void);
|
|
|
|
|
2015-03-16 05:19:37 -06:00
|
|
|
extern int gb_hid_protocol_init(void);
|
|
|
|
extern void gb_hid_protocol_exit(void);
|
|
|
|
|
2015-05-08 13:57:36 -06:00
|
|
|
extern int gb_audio_protocol_init(void);
|
|
|
|
extern void gb_audio_protocol_exit(void);
|
|
|
|
|
2015-05-20 05:50:09 -06:00
|
|
|
/* __protocol: Pointer to struct gb_protocol */
|
2014-12-23 16:16:54 -07:00
|
|
|
#define gb_protocol_driver(__protocol) \
|
|
|
|
static int __init protocol_init(void) \
|
|
|
|
{ \
|
|
|
|
return gb_protocol_register(__protocol); \
|
|
|
|
} \
|
|
|
|
module_init(protocol_init); \
|
|
|
|
static void __exit protocol_exit(void) \
|
|
|
|
{ \
|
|
|
|
gb_protocol_deregister(__protocol); \
|
|
|
|
} \
|
2015-05-01 13:05:50 -06:00
|
|
|
module_exit(protocol_exit)
|
2014-12-23 16:16:54 -07:00
|
|
|
|
2015-05-20 05:50:09 -06:00
|
|
|
/* __protocol: string matching name of struct gb_protocol */
|
2015-07-01 00:43:52 -06:00
|
|
|
#define gb_builtin_protocol_driver(__protocol) \
|
2015-05-20 05:50:09 -06:00
|
|
|
int __init gb_##__protocol##_init(void) \
|
|
|
|
{ \
|
|
|
|
return gb_protocol_register(&__protocol); \
|
|
|
|
} \
|
2015-05-21 03:47:24 -06:00
|
|
|
void gb_##__protocol##_exit(void) \
|
2015-05-20 05:50:09 -06:00
|
|
|
{ \
|
|
|
|
gb_protocol_deregister(&__protocol); \
|
|
|
|
} \
|
|
|
|
|
2015-01-21 05:42:36 -07:00
|
|
|
/*
|
|
|
|
* Macro to create get_version() routine for protocols
|
|
|
|
* @__device: name of the device struct
|
|
|
|
* @__protocol: name of protocol in CAPITALS
|
|
|
|
*/
|
|
|
|
#define define_get_version(__device, __protocol) \
|
|
|
|
static int get_version(struct __device *dev) \
|
|
|
|
{ \
|
|
|
|
struct gb_protocol_version_response response; \
|
|
|
|
int retval; \
|
|
|
|
\
|
2015-05-01 13:06:12 -06:00
|
|
|
retval = gb_protocol_get_version(dev->connection, \
|
|
|
|
GB_##__protocol##_TYPE_PROTOCOL_VERSION,\
|
|
|
|
NULL, 0, &response, \
|
|
|
|
GB_##__protocol##_VERSION_MAJOR); \
|
2015-01-21 05:42:36 -07:00
|
|
|
if (retval) \
|
|
|
|
return retval; \
|
|
|
|
\
|
|
|
|
dev->version_major = response.major; \
|
|
|
|
dev->version_minor = response.minor; \
|
|
|
|
return 0; \
|
|
|
|
}
|
|
|
|
|
2014-10-28 18:36:00 -06:00
|
|
|
#endif /* __PROTOCOL_H */
|