static int dump_firmware(uint8_t *data) { int ret; if (!firmware_fd) { firmware_fd = open(firmware_file, O_WRONLY); if (firmware_fd < 0) { gbsim_debug("%s: Failed to open file %s\n", __func__, firmware_file); return firmware_fd; } } /* dump data */ ret = write(firmware_fd, data, firmware_fetch_size); gbsim_debug("%s: Dumped %d bytes of data\n", __func__, ret); firmware_read_size += firmware_fetch_size; if (firmware_read_size == firmware_size) { close(firmware_fd); firmware_fd = 0; firmware_size = 0; firmware_read_size = 0; firmware_fetch_size = 0; } return 0; }
/* Response from AP to Module, in response to a request Module has sent earlier */ static int firmware_handler_response(uint16_t cport_id, uint16_t hd_cport_id, void *rbuf, size_t rsize) { struct op_msg *op_rsp = rbuf; struct gb_operation_msg_hdr *oph = &op_rsp->header; struct gb_firmware_size_response *size_response; struct gb_firmware_get_firmware_response *get_fw_response; int ret = 0; int type = oph->type & ~OP_RESPONSE; /* Did the request fail? */ if (oph->result) { gbsim_error("%s: Operation type: %s FAILED (%d)\n", __func__, firmware_get_operation(type), oph->result); return oph->result; } switch (type) { case GB_FIRMWARE_TYPE_FIRMWARE_SIZE: size_response = &op_rsp->fw_size_resp; firmware_size = le32toh(size_response->size); gbsim_debug("%s: Firmware size returned is %d bytes\n", __func__, firmware_size); ret = fetch_firmware(hd_cport_id); break; case GB_FIRMWARE_TYPE_GET_FIRMWARE: get_fw_response = &op_rsp->fw_get_firmware_resp; ret = dump_firmware(get_fw_response->data); if (ret) break; if (firmware_read_size < firmware_size) { ret = fetch_firmware(hd_cport_id); break; } ret = firmware_request_send(GB_FIRMWARE_TYPE_READY_TO_BOOT, hd_cport_id); if (ret) gbsim_error("%s: Failed to send ready to boot message(%d)\n", __func__, ret); break; case GB_FIRMWARE_TYPE_READY_TO_BOOT: gbsim_debug("%s: AP granted permission to boot.\n", __func__); break; default: gbsim_error("%s: Response not supported (%d)\n", __func__, type); return -EINVAL; } return ret; }
/* Request from AP to Module */ static int firmware_handler_request(uint16_t cport_id, uint16_t hd_cport_id, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct op_msg *op_req = rbuf; struct op_msg *op_rsp = tbuf; struct gb_operation_msg_hdr *oph = &op_req->header; struct gb_protocol_version_response *version_request; uint16_t message_size = sizeof(*oph); size_t payload_size; int ret; switch (oph->type) { case GB_REQUEST_TYPE_PROTOCOL_VERSION: payload_size = sizeof(*version_request); version_request = &op_req->fw_version_request; gbsim_debug("AP Firmware version (%d %d)\n", version_request->major, version_request->minor); version_request = &op_rsp->fw_version_request; version_request->major = GB_FIRMWARE_VERSION_MAJOR; version_request->minor = GB_FIRMWARE_VERSION_MINOR; break; default: gbsim_error("%s: Request not supported (%d)\n", __func__, oph->type); return -EINVAL; } message_size += payload_size; ret = send_response(hd_cport_id, op_rsp, message_size, oph->operation_id, oph->type, PROTOCOL_STATUS_SUCCESS); if (ret) return ret; ret = firmware_request_send(GB_FIRMWARE_TYPE_FIRMWARE_SIZE, hd_cport_id); if (ret) gbsim_error("%s: Failed to get size (%d)\n", __func__, ret); return ret; }
void i2c_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; int i, op_count; __u8 *write_data; bool read_op; int read_count = 0; bool write_fail = false; size_t sz; tbuf = malloc(4 * 1024); if (!tbuf) { gbsim_error("failed to allocate i2c 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 = 0; /* FIXME hardcoded until we have connections */ op_rsp = (struct op_msg *)cport_rsp->data; oph = (struct op_header *)&op_req->header; switch (oph->type) { case OP_I2C_PROTOCOL_VERSION: sz = sizeof(struct op_header) + sizeof(struct protocol_version_rsp); op_rsp->header.size = htole16((__u16)sz); op_rsp->header.id = oph->id; op_rsp->header.type = OP_RESPONSE | OP_I2C_PROTOCOL_VERSION; op_rsp->header.result = PROTOCOL_STATUS_SUCCESS; op_rsp->pv_rsp.version_major = GREYBUS_VERSION_MAJOR; op_rsp->pv_rsp.version_minor = GREYBUS_VERSION_MINOR; gbsim_debug("Module %d -> AP CPort %d I2C protocol version response\n ", cport_to_module_id(cport_req->cport), cport_rsp->cport); if (verbose) gbsim_dump((__u8 *)op_rsp, sz); write(cport_in, cport_rsp, sz + 1); break; case OP_I2C_PROTOCOL_FUNCTIONALITY: sz = sizeof(struct op_header) + sizeof(struct i2c_functionality_rsp); op_rsp->header.size = htole16((__u16)sz); op_rsp->header.id = oph->id; op_rsp->header.type = OP_RESPONSE | OP_I2C_PROTOCOL_FUNCTIONALITY; op_rsp->header.result = PROTOCOL_STATUS_SUCCESS; op_rsp->i2c_fcn_rsp.functionality = htole32(I2C_FUNC_I2C); gbsim_debug("Module %d -> AP CPort %d I2C protocol functionality response\n ", cport_to_module_id(cport_req->cport), cport_rsp->cport); if (verbose) gbsim_dump((__u8 *)op_rsp, sz); write(cport_in, cport_rsp, sz + 1); break; case OP_I2C_PROTOCOL_TIMEOUT: sz = sizeof(struct op_header) + 0; op_rsp->header.size = htole16((__u16)sz); op_rsp->header.id = oph->id; op_rsp->header.type = OP_RESPONSE | OP_I2C_PROTOCOL_TIMEOUT; op_rsp->header.result = PROTOCOL_STATUS_SUCCESS; gbsim_debug("Module %d -> AP CPort %d I2C protocol timeout response\n ", cport_to_module_id(cport_req->cport), cport_rsp->cport); if (verbose) gbsim_dump((__u8 *)op_rsp, sz); write(cport_in, cport_rsp, sz + 1); break; case OP_I2C_PROTOCOL_RETRIES: sz = sizeof(struct op_header) + 0; op_rsp->header.size = htole16((__u16)sz); op_rsp->header.id = oph->id; op_rsp->header.type = OP_RESPONSE | OP_I2C_PROTOCOL_RETRIES; op_rsp->header.result = PROTOCOL_STATUS_SUCCESS; gbsim_debug("Module %d -> AP CPort %d I2C protocol retries response\n ", cport_to_module_id(cport_req->cport), cport_rsp->cport); if (verbose) gbsim_dump((__u8 *)op_rsp, sz); write(cport_in, cport_rsp, sz + 1); break; case OP_I2C_PROTOCOL_TRANSFER: op_count = le16toh(op_req->i2c_xfer_req.op_count); write_data = (__u8 *)&op_req->i2c_xfer_req.desc[op_count]; gbsim_debug("Number of transfer ops %d\n", op_count); for (i = 0; i < op_count; i++) { struct i2c_transfer_desc *desc; __u16 addr; __u16 flags; __u16 size; desc = &op_req->i2c_xfer_req.desc[i]; addr = le16toh(desc->addr); flags = le16toh(desc->flags); size = le16toh(desc->size); read_op = (flags & I2C_M_RD) ? true : false; gbsim_debug("op %d: %s address %04x size %04x\n", i, (read_op ? "read" : "write"), addr, size); /* FIXME: need some error handling */ if (bbb_backend) if (ioctl(ifd, I2C_SLAVE, addr) < 0) gbsim_error("failed setting i2c slave address\n"); if (read_op) { if (bbb_backend) { int count; ioctl(ifd, BLKFLSBUF); count = read(ifd, &op_rsp->i2c_xfer_rsp.data[read_count], size); if (count != size) gbsim_error("op %d: failed to read %04x bytes\n", i, size); } else { for (i = read_count; i < (read_count + size); i++) op_rsp->i2c_xfer_rsp.data[i] = data_byte++; } read_count += size; } else { if (bbb_backend) { int count; count = write(ifd, write_data, size); if (count != size) { gbsim_debug("op %d: failed to write %04x bytes\n", i, size); write_fail = true; } } write_data += size; } } op_rsp->header.id = oph->id; op_rsp->header.type = OP_RESPONSE | OP_I2C_PROTOCOL_TRANSFER; if (write_fail) op_rsp->header.result = PROTOCOL_STATUS_RETRY; else /* FIXME: handle read failure */ op_rsp->header.result = PROTOCOL_STATUS_SUCCESS; if (read_op) sz = sizeof(struct op_header) + 1 + read_count; else sz = sizeof(struct op_header) + 1; op_rsp->header.size = htole16((__u16)sz); gbsim_debug("Module %d -> AP CPort %d I2C transfer response\n ", cport_to_module_id(cport_req->cport), cport_rsp->cport); if (verbose) gbsim_dump((__u8 *)op_rsp, sz); write(cport_in, cport_rsp, sz + 1); break; default: gbsim_error("i2c operation type %02x not supported\n", oph->type); } free(tbuf); }
int gpio_handler(uint16_t cport_id, uint16_t hd_cport_id, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct gb_operation_msg_hdr *oph; struct op_msg *op_req = rbuf; struct op_msg *op_rsp; size_t payload_size; uint16_t message_size; ssize_t nbytes; op_rsp = (struct op_msg *)tbuf; oph = (struct gb_operation_msg_hdr *)&op_req->header; switch (oph->type) { case GB_REQUEST_TYPE_PROTOCOL_VERSION: payload_size = sizeof(struct gb_protocol_version_response); op_rsp->pv_rsp.major = GREYBUS_VERSION_MAJOR; op_rsp->pv_rsp.minor = GREYBUS_VERSION_MINOR; break; case GB_GPIO_TYPE_LINE_COUNT: payload_size = sizeof(struct gb_gpio_line_count_response); op_rsp->gpio_lc_rsp.count = 5; /* Something arbitrary, but useful */ break; case GB_GPIO_TYPE_ACTIVATE: payload_size = 0; gbsim_debug("GPIO %d activate request\n ", op_req->gpio_act_req.which); break; case GB_GPIO_TYPE_DEACTIVATE: payload_size = 0; gbsim_debug("GPIO %d deactivate request\n ", op_req->gpio_deact_req.which); break; case GB_GPIO_TYPE_GET_DIRECTION: payload_size = sizeof(struct gb_gpio_get_direction_response); if (bbb_backend) op_rsp->gpio_get_dir_rsp.direction = libsoc_gpio_get_direction(gpios[op_req->gpio_dir_output_req.which]); else op_rsp->gpio_get_dir_rsp.direction = gpio_dir[op_req->gpio_get_dir_req.which]; gbsim_debug("GPIO %d get direction (%d) response\n ", op_req->gpio_get_dir_req.which, op_rsp->gpio_get_dir_rsp.direction); break; case GB_GPIO_TYPE_DIRECTION_IN: payload_size = 0; gbsim_debug("GPIO %d direction input request\n ", op_req->gpio_dir_input_req.which); if (bbb_backend) libsoc_gpio_set_direction(gpios[op_req->gpio_dir_output_req.which], INPUT); else gpio_dir[op_req->gpio_dir_output_req.which] = 0; break; case GB_GPIO_TYPE_DIRECTION_OUT: payload_size = 0; gbsim_debug("GPIO %d direction output request\n ", op_req->gpio_dir_output_req.which); if (bbb_backend) libsoc_gpio_set_direction(gpios[op_req->gpio_dir_output_req.which], OUTPUT); else gpio_dir[op_req->gpio_dir_output_req.which] = 1; break; case GB_GPIO_TYPE_GET_VALUE: payload_size = sizeof(struct gb_gpio_get_value_response); if (bbb_backend) op_rsp->gpio_get_val_rsp.value = libsoc_gpio_get_level(gpios[op_req->gpio_dir_output_req.which]); else op_rsp->gpio_get_val_rsp.value = 1; gbsim_debug("GPIO %d get value (%d) response\n ", op_req->gpio_get_val_req.which, op_rsp->gpio_get_val_rsp.value); break; case GB_GPIO_TYPE_SET_VALUE: payload_size = 0; gbsim_debug("GPIO %d set value (%d) request\n ", op_req->gpio_set_val_req.which, op_req->gpio_set_val_req.value); if (bbb_backend) libsoc_gpio_set_level(gpios[op_req->gpio_set_val_req.which], op_req->gpio_set_val_req.value); break; case GB_GPIO_TYPE_SET_DEBOUNCE: payload_size = 0; gbsim_debug("GPIO %d set debounce (%d us) request\n ", op_req->gpio_set_db_req.which, op_req->gpio_set_db_req.usec); break; case GB_GPIO_TYPE_IRQ_TYPE: payload_size = 0; gbsim_debug("GPIO protocol IRQ type %d request\n ", op_req->gpio_irq_type_req.type); break; case GB_GPIO_TYPE_IRQ_MASK: payload_size = 0; break; case GB_GPIO_TYPE_IRQ_UNMASK: payload_size = 0; break; default: return -EINVAL; } message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; nbytes = send_response(op_rsp, hd_cport_id, message_size, oph, PROTOCOL_STATUS_SUCCESS); if (nbytes) return nbytes; #define TEST_HACK #ifdef TEST_HACK /* Test GPIO interrupts by sending one when they become unmasked */ if (oph->type == GB_GPIO_TYPE_IRQ_UNMASK) { payload_size = sizeof(struct gb_gpio_irq_event_request); op_req->gpio_irq_event_req.which = 1; /* XXX HACK */ message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; return send_request(op_req, hd_cport_id, message_size, 0, GB_GPIO_TYPE_IRQ_EVENT); } #endif return 0; }
int i2c_handler(uint16_t cport_id, uint16_t hd_cport_id, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct gb_operation_msg_hdr *oph; struct op_msg *op_req = rbuf; struct op_msg *op_rsp; int i, op_count; __u8 *write_data; bool read_op = false; int read_count = 0; bool write_fail = false; size_t payload_size; uint16_t message_size; uint8_t result = PROTOCOL_STATUS_SUCCESS; op_rsp = (struct op_msg *)tbuf; oph = (struct gb_operation_msg_hdr *)&op_req->header; switch (oph->type) { case GB_REQUEST_TYPE_PROTOCOL_VERSION: payload_size = sizeof(struct gb_protocol_version_response); op_rsp->pv_rsp.major = GREYBUS_VERSION_MAJOR; op_rsp->pv_rsp.minor = GREYBUS_VERSION_MINOR; break; case GB_I2C_TYPE_FUNCTIONALITY: payload_size = sizeof(struct gb_i2c_functionality_response); op_rsp->i2c_fcn_rsp.functionality = htole32(I2C_FUNC_I2C); break; case GB_I2C_TYPE_TIMEOUT: payload_size = 0; break; case GB_I2C_TYPE_RETRIES: payload_size = 0; break; case GB_I2C_TYPE_TRANSFER: op_count = le16toh(op_req->i2c_xfer_req.op_count); write_data = (__u8 *)&op_req->i2c_xfer_req.ops[op_count]; gbsim_debug("Number of transfer ops %d\n", op_count); for (i = 0; i < op_count; i++) { struct gb_i2c_transfer_op *op; __u16 addr; __u16 flags; __u16 size; op = &op_req->i2c_xfer_req.ops[i]; addr = le16toh(op->addr); flags = le16toh(op->flags); size = le16toh(op->size); read_op = (flags & I2C_M_RD) ? true : false; gbsim_debug("op %d: %s address %04x size %04x\n", i, (read_op ? "read" : "write"), addr, size); /* FIXME: need some error handling */ if (bbb_backend) if (ioctl(ifd, I2C_SLAVE, addr) < 0) gbsim_error("failed setting i2c slave address\n"); if (read_op) { if (bbb_backend) { int count; ioctl(ifd, BLKFLSBUF); count = read(ifd, &op_rsp->i2c_xfer_rsp.data[read_count], size); if (count != size) gbsim_error("op %d: failed to read %04x bytes\n", i, size); } else { for (i = read_count; i < (read_count + size); i++) op_rsp->i2c_xfer_rsp.data[i] = data_byte++; } read_count += size; } else { if (bbb_backend) { int count; count = write(ifd, write_data, size); if (count != size) { gbsim_debug("op %d: failed to write %04x bytes\n", i, size); write_fail = true; } } write_data += size; } } /* FIXME: handle read failure */ if (write_fail) result = PROTOCOL_STATUS_RETRY; payload_size = read_op ? read_count : 0; break; default: return -EINVAL; } message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; return send_response(op_rsp, hd_cport_id, message_size, oph, result); }
int gpio_handler(struct gbsim_connection *connection, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct gb_operation_msg_hdr *oph; struct op_msg *op_req = rbuf; struct op_msg *op_rsp; size_t payload_size; ssize_t nbytes; uint16_t message_size; uint16_t hd_cport_id = connection->hd_cport_id; uint8_t which = 0; int send_event = 0; op_rsp = (struct op_msg *)tbuf; oph = (struct gb_operation_msg_hdr *)&op_req->header; switch (oph->type) { case GB_GPIO_TYPE_LINE_COUNT: payload_size = sizeof(struct gb_gpio_line_count_response); op_rsp->gpio_lc_rsp.count = 5; /* Something arbitrary, but useful */ break; case GB_GPIO_TYPE_ACTIVATE: payload_size = 0; which = op_req->gpio_act_req.which; gbsim_debug("GPIO %d activate request\n", which); gb_gpios[which].activated = 1; break; case GB_GPIO_TYPE_DEACTIVATE: payload_size = 0; which = op_req->gpio_deact_req.which; gbsim_debug("GPIO %d deactivate request\n", which); gb_gpios[which].activated = 0; break; case GB_GPIO_TYPE_GET_DIRECTION: payload_size = sizeof(struct gb_gpio_get_direction_response); which = op_req->gpio_get_dir_req.which; if (bbb_backend) op_rsp->gpio_get_dir_rsp.direction = libsoc_gpio_get_direction(gpios[which]); else op_rsp->gpio_get_dir_rsp.direction = gb_gpios[which].direction; gbsim_debug("GPIO %d get direction (%d) response\n", which, op_rsp->gpio_get_dir_rsp.direction); break; case GB_GPIO_TYPE_DIRECTION_IN: payload_size = 0; which = op_req->gpio_dir_input_req.which; gbsim_debug("GPIO %d direction input request\n", which); if (bbb_backend) libsoc_gpio_set_direction(gpios[which], INPUT); else gb_gpios[which].direction = 1; break; case GB_GPIO_TYPE_DIRECTION_OUT: payload_size = 0; which = op_req->gpio_dir_output_req.which; gbsim_debug("GPIO %d direction output request\n", which); if (bbb_backend) libsoc_gpio_set_direction(gpios[which], OUTPUT); else gb_gpios[which].direction = 0; break; case GB_GPIO_TYPE_GET_VALUE: payload_size = sizeof(struct gb_gpio_get_value_response); which = op_req->gpio_get_val_req.which; if (bbb_backend) op_rsp->gpio_get_val_rsp.value = libsoc_gpio_get_level(gpios[which]); else op_rsp->gpio_get_val_rsp.value = gb_gpios[which].value; gbsim_debug("GPIO %d get value (%d) response\n ", which, op_rsp->gpio_get_val_rsp.value); break; case GB_GPIO_TYPE_SET_VALUE: payload_size = 0; which = op_req->gpio_set_val_req.which; gbsim_debug("GPIO %d set value (%d) request\n ", which, op_req->gpio_set_val_req.value); if (bbb_backend) libsoc_gpio_set_level(gpios[which], op_req->gpio_set_val_req.value); else send_event = gb_gpio_set_value(which, op_req->gpio_set_val_req.value); break; case GB_GPIO_TYPE_SET_DEBOUNCE: payload_size = 0; gbsim_debug("GPIO %d set debounce (%d us) request\n ", op_req->gpio_set_db_req.which, op_req->gpio_set_db_req.usec); break; case GB_GPIO_TYPE_IRQ_TYPE: payload_size = 0; which = op_req->gpio_irq_type_req.which; gbsim_debug("GPIO %d set IRQ type %d request\n ", which, op_req->gpio_irq_type_req.type); gb_gpios[which].irq_type = op_req->gpio_irq_type_req.type; break; case GB_GPIO_TYPE_IRQ_MASK: payload_size = 0; which = op_req->gpio_irq_mask_req.which; gb_gpios[which].irq_unmasked = 0; break; case GB_GPIO_TYPE_IRQ_UNMASK: payload_size = 0; which = op_req->gpio_irq_unmask_req.which; gb_gpios[which].irq_unmasked = 1; break; case GB_REQUEST_TYPE_CPORT_SHUTDOWN: payload_size = 0; break; default: return -EINVAL; } message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; nbytes = send_response(hd_cport_id, op_rsp, message_size, oph->operation_id, oph->type, PROTOCOL_STATUS_SUCCESS); if (nbytes) return nbytes; #define TEST_HACK #ifdef TEST_HACK /* * Test GPIO interrupts by sending one when they become unmasked, or * when set value trigger one */ if (send_event) { payload_size = sizeof(struct gb_gpio_irq_event_request); op_req->gpio_irq_event_req.which = which - 1; /* mask the irq to mimic fw action on event send */ gb_gpios[which - 1].irq_unmasked = 0; message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; return send_request(hd_cport_id, op_req, message_size, 0, GB_GPIO_TYPE_IRQ_EVENT); } #endif return 0; }
int pwm_handler(struct gbsim_cport *cport, void *rbuf, size_t rsize, void *tbuf, size_t tsize) { struct gb_operation_msg_hdr *oph; struct op_msg *op_req = rbuf; struct op_msg *op_rsp; __u32 duty; __u32 period; size_t payload_size; uint16_t message_size; uint16_t hd_cport_id = cport->hd_cport_id; uint8_t result = PROTOCOL_STATUS_SUCCESS; op_rsp = (struct op_msg *)tbuf; oph = (struct gb_operation_msg_hdr *)&op_req->header; switch (oph->type) { case GB_REQUEST_TYPE_PROTOCOL_VERSION: payload_size = sizeof(struct gb_protocol_version_response); op_rsp->pv_rsp.major = GREYBUS_VERSION_MAJOR; op_rsp->pv_rsp.minor = GREYBUS_VERSION_MINOR; break; case GB_PWM_TYPE_PWM_COUNT: payload_size = sizeof(struct gb_pwm_count_response); op_rsp->pwm_cnt_rsp.count = 1; /* Something arbitrary, but useful */ break; case GB_PWM_TYPE_ACTIVATE: payload_size = 0; gbsim_debug("PWM %d activate request\n ", op_req->pwm_act_req.which); break; case GB_PWM_TYPE_DEACTIVATE: payload_size = 0; gbsim_debug("PWM %d deactivate request\n ", op_req->pwm_deact_req.which); break; case GB_PWM_TYPE_CONFIG: payload_size = 0; duty = le32toh(op_req->pwm_cfg_req.duty); period = le32toh(op_req->pwm_cfg_req.period); if (bbb_backend) { libsoc_pwm_set_duty_cycle(pwms[op_req->pwm_cfg_req.which], duty); libsoc_pwm_set_period(pwms[op_req->pwm_cfg_req.which], period); } gbsim_debug("PWM %d config (%dns/%dns) request\n ", op_req->pwm_cfg_req.which, duty, period); break; case GB_PWM_TYPE_POLARITY: payload_size = 0; if (pwm_on[op_req->pwm_pol_req.which]) { result = PROTOCOL_STATUS_BUSY; } else if (bbb_backend) { libsoc_pwm_set_polarity(pwms[op_req->pwm_pol_req.which], op_req->pwm_pol_req.polarity); } gbsim_debug("PWM %d polarity (%s) request\n ", op_req->pwm_cfg_req.which, op_req->pwm_pol_req.polarity ? "inverse" : "normal"); break; case GB_PWM_TYPE_ENABLE: payload_size = 0; pwm_on[op_req->pwm_enb_req.which] = 1; if (bbb_backend) libsoc_pwm_set_enabled(pwms[op_req->pwm_enb_req.which], ENABLED); gbsim_debug("PWM %d enable request\n ", op_req->pwm_enb_req.which); break; case GB_PWM_TYPE_DISABLE: payload_size = 0; pwm_on[op_req->pwm_dis_req.which] = 0; if (bbb_backend) libsoc_pwm_set_enabled(pwms[op_req->pwm_dis_req.which], DISABLED); gbsim_debug("PWM %d disable request\n ", op_req->pwm_dis_req.which); break; default: gbsim_error("pwm operation type %02x not supported\n", oph->type); return -EINVAL; } message_size = sizeof(struct gb_operation_msg_hdr) + payload_size; return send_response(hd_cport_id, op_rsp, message_size, oph->operation_id, oph->type, result); }