static int ev3_uart_sensor_set_mode(void *context, u8 mode)
{
	struct ev3_uart_sensor_data *data = context;
	struct lego_sensor_mode_info *mode_info = &data->info.mode_info[mode];
#if defined(CONFIG_NXT_I2C_SENSORS) || defined(CONFIG_NXT_I2C_SENSORS_MODULE)
	if (data->ldev->port->dev.type == &ms_ev3_smux_port_type) {
		int ret;

		ret = ms_ev3_smux_set_uart_sensor_mode(data->ldev->port, mode);
		if (ret < 0)
			return ret;
	} else
#endif
#if defined(CONFIG_BRICKPI) || defined(CONFIG_BRICKPI_MODULE)
	if (data->ldev->port->dev.type == &brickpi_in_port_type) {
		int ret;

		ret = brickpi_set_uart_sensor_mode(data->ldev, mode);
		if (ret < 0)
			return ret;
	} else
#endif
		return -EINVAL;

	lego_port_set_raw_data_ptr_and_func(data->ldev->port, mode_info->raw_data,
		lego_sensor_get_raw_data_size(mode_info), NULL, NULL);

	return 0;
}
static int ev3_uart_sensor_remove(struct lego_device *ldev)
{
	struct ev3_uart_sensor_data *data = dev_get_drvdata(&ldev->dev);

	lego_port_set_raw_data_ptr_and_func(ldev->port, NULL, 0, NULL, NULL);
	unregister_lego_sensor(&data->sensor);
	dev_set_drvdata(&ldev->dev, NULL);
	kfree(data);
	return 0;
}
static int ev3_analog_sensor_set_mode(void *context, u8 mode)
{
	struct ev3_analog_sensor_data *data = context;
	struct lego_sensor_mode_info *mode_info = &data->info.mode_info[mode];

	lego_port_set_raw_data_ptr_and_func(data->ldev->port, mode_info->raw_data,
		lego_sensor_get_raw_data_size(mode_info), NULL, NULL);

	return -EINVAL;
}
static int ht_nxt_smux_i2c_sensor_remove(struct lego_device *ldev)
{
	struct ht_nxt_smux_i2c_sensor_data *data = dev_get_drvdata(&ldev->dev);

	lego_port_set_raw_data_ptr_and_func(ldev->port, NULL, 0, NULL, NULL);
	ldev->port->nxt_i2c_ops->set_pin1_gpio(ldev->port->context,
					       LEGO_PORT_GPIO_FLOAT);
	unregister_lego_sensor(&data->sensor);
	dev_set_drvdata(&ldev->dev, NULL);
	kfree(data);

	return 0;
}
static int ht_nxt_smux_i2c_sensor_set_mode(void *context, u8 mode)
{
	struct ht_nxt_smux_i2c_sensor_data *data = context;
	struct lego_port_device *port = data->ldev->port;
	struct lego_sensor_mode_info *mode_info = &data->sensor.mode_info[mode];
	const struct nxt_i2c_sensor_mode_info *i2c_mode_info = data->info->i2c_mode_info;
	int size = lego_sensor_get_raw_data_size(mode_info);

	ht_nxt_smux_port_set_i2c_data_reg(port, i2c_mode_info[mode].read_data_reg,
					  size);
	lego_port_set_raw_data_ptr_and_func(port, mode_info->raw_data, size,
					    NULL, NULL);

	return 0;
}
static int ev3_uart_sensor_set_mode(void *context, u8 mode)
{
	struct ev3_uart_sensor_data *data = context;
	struct lego_port_device *port = data->ldev->port;
	struct lego_sensor_mode_info *mode_info = &data->info.mode_info[mode];

	if (port->ev3_uart_ops && port->ev3_uart_ops->set_mode) {
		int ret;

		ret = port->ev3_uart_ops->set_mode(port->context, mode);
		if (ret < 0)
			return ret;
	} else
		return -EOPNOTSUPP;

	lego_port_set_raw_data_ptr_and_func(data->ldev->port, mode_info->raw_data,
		lego_sensor_get_raw_data_size(mode_info), NULL, NULL);

	return 0;
}
static int brickpi_i2c_sensor_set_mode(void *context, u8 mode)
{
	struct brickpi_i2c_sensor_data *data = context;
	struct lego_port_device *port = data->ldev->port;
	struct lego_sensor_mode_info *mode_info = &data->sensor.mode_info[mode];
	const struct nxt_i2c_sensor_mode_info *i2c_mode_info = data->info->i2c_mode_info;
	int size = lego_sensor_get_raw_data_size(mode_info);
	int err;

	err = brickpi_in_port_set_i2c_mode(data->ldev,
					   i2c_mode_info[mode].set_mode_reg,
					   i2c_mode_info[mode].set_mode_data,
					   i2c_mode_info[mode].read_data_reg,
					   size);
	if (err < 0)
		return err;

	lego_port_set_raw_data_ptr_and_func(port, mode_info->raw_data, size,
					    NULL, NULL);

	return 0;
}