@@ -22,7 +22,7 @@ INCS = -I$(GBDIR)
LFLAGS =
LIBS = -lpthread -lusbg -lsoc
-SRCS = main.c gadget.c functionfs.c inotify.c manifest.c cport.c i2c.c gpio.c pwm.c
+SRCS = main.c gadget.c functionfs.c inotify.c manifest.c cport.c i2c.c gpio.c pwm.c i2s.c
OBJS = $(SRCS:.c=.o)
MAIN = gbsim
@@ -31,6 +31,12 @@ static char *get_protocol(__le16 id)
return "I2C";
case GREYBUS_PROTOCOL_PWM:
return "PWM";
+ case GREYBUS_PROTOCOL_I2S_MGMT:
+ return "I2S_MGMT";
+ case GREYBUS_PROTOCOL_I2S_RECEIVER:
+ return "I2S_RECEIVER";
+ case GREYBUS_PROTOCOL_I2S_TRANSMITTER:
+ return "I2S_TRANSMITTER";
}
}
}
@@ -53,6 +59,13 @@ static void exec_subdev_handler(__le16 id, __u8 *rbuf, size_t size)
case GREYBUS_PROTOCOL_PWM:
pwm_handler(rbuf, size);
break;
+ case GREYBUS_PROTOCOL_I2S_MGMT:
+ i2s_mgmt_handler(rbuf, size);
+ break;
+ case GREYBUS_PROTOCOL_I2S_RECEIVER:
+ case GREYBUS_PROTOCOL_I2S_TRANSMITTER:
+ i2s_data_handler(rbuf, size);
+ break;
default:
gbsim_error("subdev handler not found for cport %d\n",
id);
@@ -286,4 +286,8 @@ void i2c_init(void);
void pwm_handler(__u8 *, size_t);
void pwm_init(void);
+void i2s_mgmt_handler(__u8 *, size_t);
+void i2s_data_handler(__u8 *, size_t);
+void i2s_init(void);
+
bool manifest_parse(void *data, size_t size);
new file mode 100644
@@ -0,0 +1,177 @@
+/*
+ * Greybus Simulator
+ *
+ * Copyright 2014, 2015 Google Inc.
+ * Copyright 2014, 2015 Linaro Ltd.
+ *
+ * Provided under the three clause BSD license found in the LICENSE file.
+ */
+
+#include <fcntl.h>
+#include <libsoc_gpio.h>
+#include <linux/fs.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "gbsim.h"
+
+#define GB_I2S_MGMT_TYPE_PROTOCOL_VERSION 0x01
+#define GB_I2S_MGMT_TYPE_GET_SUPPORTED_CONFIGURATIONS 0x02
+#define GB_I2S_MGMT_TYPE_SET_CONFIGURATION 0x03
+#define GB_I2S_MGMT_TYPE_SET_SAMPLES_PER_MESSAGE 0x04
+#define GB_I2S_MGMT_TYPE_GET_PROCESSING_DELAY 0x05
+#define GB_I2S_MGMT_TYPE_SET_START_DELAY 0x06
+#define GB_I2S_MGMT_TYPE_ACTIVATE_CPORT 0x07
+#define GB_I2S_MGMT_TYPE_DEACTIVATE_CPORT 0x08
+#define GB_I2S_MGMT_TYPE_REPORT_EVENT 0x09
+
+#define GB_I2S_DATA_TYPE_SEND_DATA 0x02
+
+void i2s_mgmt_handler(__u8 *rbuf, size_t size)
+{
+ struct op_header *oph;
+ char *tbuf;
+ struct op_msg *op_req, *op_rsp;
+ struct cport_msg *cport_req, *cport_rsp;
+ size_t sz;
+
+ tbuf = malloc(4 * 1024);
+ if (!tbuf) {
+ gbsim_error("failed to allocate i2s handler tx buf\n");
+ return;
+ }
+ cport_req = (struct cport_msg *)rbuf;
+ op_req = (struct op_msg *)cport_req->data;
+ cport_rsp = (struct cport_msg *)tbuf;
+ cport_rsp->cport = cport_req->cport;
+ op_rsp = (struct op_msg *)cport_rsp->data;
+ oph = (struct op_header *)&op_req->header;
+
+ switch (oph->type) {
+ case GB_I2S_MGMT_TYPE_SET_CONFIGURATION:
+ sz = sizeof(struct op_header);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_MGMT_TYPE_SET_CONFIGURATION;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ gbsim_debug("Module %d -> AP CPort %d I2S SET_CONFIGURATION response\n ",
+ cport_to_module_id(cport_req->cport), cport_rsp->cport);
+ if (verbose)
+ gbsim_dump((__u8 *)op_rsp, op_rsp->header.size);
+ write(cport_in, cport_rsp, op_rsp->header.size + 1);
+ break;
+ case GB_I2S_MGMT_TYPE_SET_SAMPLES_PER_MESSAGE:
+ sz = sizeof(struct op_header);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_MGMT_TYPE_SET_SAMPLES_PER_MESSAGE;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ gbsim_debug("Module %d -> AP CPort %d I2S SET_SAMPLES_PER_MESSAGE response\n ",
+ cport_to_module_id(cport_req->cport), cport_rsp->cport);
+ if (verbose)
+ gbsim_dump((__u8 *)op_rsp, op_rsp->header.size);
+ write(cport_in, cport_rsp, op_rsp->header.size + 1);
+ break;
+ case GB_I2S_MGMT_TYPE_SET_START_DELAY:
+ sz = sizeof(struct op_header);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_MGMT_TYPE_SET_START_DELAY;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ gbsim_debug("Module %d -> AP CPort %d I2S SET_START_DELAY response\n ",
+ cport_to_module_id(cport_req->cport), cport_rsp->cport);
+ if (verbose)
+ gbsim_dump((__u8 *)op_rsp, op_rsp->header.size);
+ write(cport_in, cport_rsp, op_rsp->header.size + 1);
+ break;
+ case GB_I2S_MGMT_TYPE_ACTIVATE_CPORT:
+ sz = sizeof(struct op_header);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_MGMT_TYPE_ACTIVATE_CPORT;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ gbsim_debug("Module %d -> AP CPort %d I2S ACTIVATE_CPORT response\n ",
+ cport_to_module_id(cport_req->cport), cport_rsp->cport);
+ if (verbose)
+ gbsim_dump((__u8 *)op_rsp, op_rsp->header.size);
+ write(cport_in, cport_rsp, op_rsp->header.size + 1);
+ break;
+ case GB_I2S_MGMT_TYPE_DEACTIVATE_CPORT:
+ sz = sizeof(struct op_header);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_MGMT_TYPE_DEACTIVATE_CPORT;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ gbsim_debug("Module %d -> AP CPort %d I2S DEACTIVATE_CPORT response\n ",
+ cport_to_module_id(cport_req->cport), cport_rsp->cport);
+ if (verbose)
+ gbsim_dump((__u8 *)op_rsp, op_rsp->header.size);
+ write(cport_in, cport_rsp, op_rsp->header.size + 1);
+ break;
+ default:
+ gbsim_error("i2s mgmt operation type %02x not supported\n", oph->type);
+ }
+
+ free(tbuf);
+}
+
+
+void i2s_data_handler(__u8 *rbuf, size_t size)
+{
+ struct op_header *oph;
+ char *tbuf;
+ struct op_msg *op_req, *op_rsp;
+ struct cport_msg *cport_req, *cport_rsp;
+ size_t sz;
+
+ tbuf = malloc(4 * 1024);
+ if (!tbuf) {
+ gbsim_error("failed to allocate i2s handler tx buf\n");
+ return;
+ }
+ cport_req = (struct cport_msg *)rbuf;
+ op_req = (struct op_msg *)cport_req->data;
+ cport_rsp = (struct cport_msg *)tbuf;
+ cport_rsp->cport = cport_req->cport;
+ op_rsp = (struct op_msg *)cport_rsp->data;
+ oph = (struct op_header *)&op_req->header;
+
+ switch (oph->type) {
+ case GB_I2S_DATA_TYPE_SEND_DATA:
+ sz = sizeof(struct op_header);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_DATA_TYPE_SEND_DATA;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ gbsim_debug("Module %d -> AP CPort %d I2S SEND_DATA response\n ",
+ cport_to_module_id(cport_req->cport), cport_rsp->cport);
+ if (verbose)
+ gbsim_dump((__u8 *)op_rsp, op_rsp->header.size);
+ write(cport_in, cport_rsp, op_rsp->header.size + 1);
+ break;
+ default:
+ gbsim_error("i2s data operation type %02x not supported\n", oph->type);
+ }
+
+ free(tbuf);
+}
+
+void i2s_init(void)
+{
+
+}
@@ -111,6 +111,7 @@ int main(int argc, char *argv[])
/* Protocol handlers */
gpio_init();
i2c_init();
+ i2s_init();
ret = functionfs_loop();
Add initial i2s support. This only supports I2S SEND_DATA and some simple I2S mgmt calls. I'll be working to add the mgmt calls that actually provide data in responses tomorrow. v2: Just a quick resend to fix some issues pointed out and add basic support for trivial I2S mgmt calls. Cc: Alex Elder <alex.elder@linaro.org> Cc: Greg Kroah-Hartman <greg@kroah.com> Cc: mark greer <mark.greer@animalcreek.com> Signed-off-by: John Stultz <john.stultz@linaro.org> --- Makefile | 2 +- cport.c | 13 +++++ gbsim.h | 4 ++ i2s.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 1 + 5 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 i2s.c