@@ -198,14 +198,45 @@ struct pwm_disable_req {
__u8 which;
};
+struct gb_i2s_mgmt_configuration {
+ __le32 sample_frequency;
+ __u8 num_channels;
+ __u8 bytes_per_channel;
+ __u8 byte_order;
+ __u8 pad;
+ __le32 spatial_locations;
+ __le32 ll_protocol;
+ __u8 ll_bclk_role;
+ __u8 ll_wclk_role;
+ __u8 ll_wclk_polarity;
+ __u8 ll_wclk_change_edge;
+ __u8 ll_wclk_tx_edge;
+ __u8 ll_wclk_rx_edge;
+ __u8 ll_data_offset;
+ __u8 ll_pad;
+};
+
+struct gb_i2s_mgmt_get_supported_configurations_response {
+ __u8 config_count;
+ __u8 pad[3];
+ struct gb_i2s_mgmt_configuration config[0];
+};
+
+/* get processing request delay has no payload */
+struct gb_i2s_mgmt_get_processing_delay_response {
+ __le32 microseconds;
+};
+
+
+
/* Ops */
struct op_msg {
struct op_header header;
union {
struct protocol_version_rsp pv_rsp;
- struct gpio_line_count_rsp gpio_lc_rsp;
- struct gpio_activate_req gpio_act_req;
- struct gpio_deactivate_req gpio_deact_req;
+ struct gpio_line_count_rsp gpio_lc_rsp;
+ struct gpio_activate_req gpio_act_req;
+ struct gpio_deactivate_req gpio_deact_req;
struct gpio_get_direction_req gpio_get_dir_req;
struct gpio_get_direction_rsp gpio_get_dir_rsp;
struct gpio_direction_input_req gpio_dir_input_req;
@@ -222,13 +253,15 @@ struct op_msg {
struct i2c_functionality_rsp i2c_fcn_rsp;
struct i2c_transfer_req i2c_xfer_req;
struct i2c_transfer_rsp i2c_xfer_rsp;
- struct pwm_count_rsp pwm_cnt_rsp;
- struct pwm_activate_req pwm_act_req;
- struct pwm_deactivate_req pwm_deact_req;
- struct pwm_config_req pwm_cfg_req;
- struct pwm_polarity_req pwm_pol_req;
- struct pwm_enable_req pwm_enb_req;
- struct pwm_disable_req pwm_dis_req;
+ struct pwm_count_rsp pwm_cnt_rsp;
+ struct pwm_activate_req pwm_act_req;
+ struct pwm_deactivate_req pwm_deact_req;
+ struct pwm_config_req pwm_cfg_req;
+ struct pwm_polarity_req pwm_pol_req;
+ struct pwm_enable_req pwm_enb_req;
+ struct pwm_disable_req pwm_dis_req;
+ struct gb_i2s_mgmt_get_supported_configurations_response i2s_mgmt_get_supported_conf_resp;
+ struct gb_i2s_mgmt_get_processing_delay_response i2s_mgmt_get_processing_delay_res;
};
};
@@ -28,6 +28,58 @@
#define GB_I2S_MGMT_TYPE_DEACTIVATE_CPORT 0x08
#define GB_I2S_MGMT_TYPE_REPORT_EVENT 0x09
+#ifndef BIT
+#define BIT(n) (1UL << (n))
+#endif
+#define GB_I2S_MGMT_BYTE_ORDER_NA BIT(0)
+#define GB_I2S_MGMT_BYTE_ORDER_BE BIT(1)
+#define GB_I2S_MGMT_BYTE_ORDER_LE BIT(2)
+
+#define GB_I2S_MGMT_SPATIAL_LOCATION_FL BIT(0)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_FR BIT(1)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_FC BIT(2)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_LFE BIT(3)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_BL BIT(4)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_BR BIT(5)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_FLC BIT(6)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_FRC BIT(7)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_C BIT(8) /* BC in USB */
+#define GB_I2S_MGMT_SPATIAL_LOCATION_SL BIT(9)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_SR BIT(10)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TC BIT(11)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TFL BIT(12)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TFC BIT(13)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TFR BIT(14)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TBL BIT(15)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TBC BIT(16)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TBR BIT(17)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TFLC BIT(18)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TFRC BIT(19)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_LLFE BIT(20)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_RLFE BIT(21)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TSL BIT(22)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_TSR BIT(23)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_BC BIT(24)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_BLC BIT(25)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_BRC BIT(26)
+#define GB_I2S_MGMT_SPATIAL_LOCATION_RD BIT(31)
+
+#define GB_I2S_MGMT_PROTOCOL_PCM BIT(0)
+#define GB_I2S_MGMT_PROTOCOL_I2S BIT(1)
+#define GB_I2S_MGMT_PROTOCOL_LR_STEREO BIT(2)
+
+#define GB_I2S_MGMT_ROLE_MASTER BIT(0)
+#define GB_I2S_MGMT_ROLE_SLAVE BIT(1)
+
+#define GB_I2S_MGMT_POLARITY_NORMAL BIT(0)
+#define GB_I2S_MGMT_POLARITY_REVERSED BIT(1)
+
+#define GB_I2S_MGMT_EDGE_RISING BIT(0)
+#define GB_I2S_MGMT_EDGE_FALLING BIT(1)
+
+#define CONFIG_COUNT_MAX 32
+
+
#define GB_I2S_DATA_TYPE_SEND_DATA 0x02
void i2s_mgmt_handler(__u8 *rbuf, size_t size)
@@ -36,6 +88,7 @@ void i2s_mgmt_handler(__u8 *rbuf, size_t size)
char *tbuf;
struct op_msg *op_req, *op_rsp;
struct cport_msg *cport_req, *cport_rsp;
+ struct gb_i2s_mgmt_configuration *conf;
size_t sz;
tbuf = malloc(4 * 1024);
@@ -51,6 +104,45 @@ void i2s_mgmt_handler(__u8 *rbuf, size_t size)
oph = (struct op_header *)&op_req->header;
switch (oph->type) {
+ case GB_I2S_MGMT_TYPE_GET_SUPPORTED_CONFIGURATIONS:
+ sz = sizeof(struct op_header) +
+ sizeof(struct gb_i2s_mgmt_get_supported_configurations_response) +
+ sizeof(struct gb_i2s_mgmt_configuration) * CONFIG_COUNT_MAX;
+
+ printf("JDB: sz=%i\n", sz);
+ op_rsp->header.size = htole16((__u16)sz);
+ op_rsp->header.id = oph->id;
+
+ op_rsp->header.type = OP_RESPONSE | GB_I2S_MGMT_TYPE_GET_SUPPORTED_CONFIGURATIONS;
+ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS;
+
+ op_rsp->i2s_mgmt_get_supported_conf_resp.config_count = 1;
+
+ conf = &op_rsp->i2s_mgmt_get_supported_conf_resp.config[0];
+ conf->sample_frequency = htole32(48000);
+ conf->num_channels = 2;
+ conf->bytes_per_channel = 2;
+ conf->byte_order = GB_I2S_MGMT_BYTE_ORDER_LE;
+ conf->spatial_locations = htole32(
+ GB_I2S_MGMT_SPATIAL_LOCATION_FL |
+ GB_I2S_MGMT_SPATIAL_LOCATION_FR);
+ conf->ll_protocol = htole32(GB_I2S_MGMT_PROTOCOL_I2S);
+ conf->ll_bclk_role = GB_I2S_MGMT_ROLE_MASTER;
+ conf->ll_wclk_role = GB_I2S_MGMT_ROLE_MASTER;
+ conf->ll_wclk_polarity = GB_I2S_MGMT_POLARITY_NORMAL;
+ conf->ll_wclk_change_edge = GB_I2S_MGMT_EDGE_FALLING;
+ conf->ll_wclk_tx_edge = GB_I2S_MGMT_EDGE_FALLING;
+ conf->ll_wclk_rx_edge = GB_I2S_MGMT_EDGE_RISING;
+ conf->ll_data_offset = 1;
+
+
+
+ gbsim_debug("Module %d -> AP CPort %d I2S GET_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_CONFIGURATION:
sz = sizeof(struct op_header);
op_rsp->header.size = htole16((__u16)sz);
Add I2S support for GB_I2S_MGMT_TYPE_GET_SUPPORTED_CONFIGURATIONS messages. (Also some nearby whitespace fixes) Cc: mark greer <mark.greer@animalcreek.com> Cc: Alex Elder <alex.elder@linaro.org> Cc: Greg Kroah-Hartman <gregkh@google.com> Signed-off-by: John Stultz <john.stultz@linaro.org> --- gbsim.h | 53 +++++++++++++++++++++++++++++------- i2s.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 10 deletions(-)