static int brickpi_in_port_set_mode(void *context, u8 mode)
{
	struct brickpi_in_port_data *in_port = context;
	const char *name = NULL;
	int err;

	brickpi_in_port_unregister_sensor(in_port);
	switch (mode) {
	case BRICKPI_IN_PORT_MODE_NONE:
	case BRICKPI_IN_PORT_MODE_EV3_UART:
		/* We don't want to load the wrong UART sensor because it causes problems. */
		in_port->sensor_type = BRICKPI_SENSOR_TYPE_FW_VERSION;
		return brickpi_set_sensors(in_port->ch_data);
	case BRICKPI_IN_PORT_MODE_NXT_ANALOG:
		in_port->sensor_type = BRICKPI_SENSOR_TYPE_NXT_ANALOG;
		name = GENERIC_NXT_ANALOG_SENSOR_NAME;
		break;
	case BRICKPI_IN_PORT_MODE_EV3_ANALOG:
		in_port->sensor_type = BRICKPI_SENSOR_TYPE_EV3_TOUCH;
		name = LEGO_EV3_TOUCH_SENSOR_NAME;
		break;
	}

	/* TODO: This check shouldn't be needed when we have all of the modes implemented */
	if (!name)
		return -EOPNOTSUPP;

	err = brickpi_set_sensors(in_port->ch_data);
	if (err < 0)
		return err;

	return brickpi_in_port_register_sensor(in_port,
					       &brickpi_device_type[mode], name);
}
static int brickpi_in_port_set_device(void *context, const char *name)
{
	struct brickpi_in_port_data *in_port = context;
	int mode = in_port->port.mode;

	brickpi_in_port_unregister_sensor(in_port);

	if (mode == BRICKPI_IN_PORT_MODE_NONE)
		return -EOPNOTSUPP;

	return brickpi_in_port_register_sensor(in_port,
					       &brickpi_device_type[mode], name);
}
static int brickpi_in_port_set_device(void *context, const char *name)
{
	struct brickpi_in_port_data *in_port = context;
	int mode = in_port->port.mode;

	brickpi_in_port_unregister_sensor(in_port);

	if (mode == BRICKPI_IN_PORT_MODE_NONE)
		return -EOPNOTSUPP;
	else if (mode == BRICKPI_IN_PORT_MODE_NXT_I2C) {
		char i2c_name[I2C_NAME_SIZE] = { 0 };
		char *blank, end;
		int ret, hex;

		/* TODO: Modify to allow multiple sensors */

		/* credit: parameter parsing code copied from i2c_core.c */
		blank = strchr(name, ' ');
		if (!blank) {
			dev_err(&in_port->port.dev, "%s: Missing parameters -"
				"requires both driver name and I2C address\n",
				"set_device");
			return -EINVAL;
		}
		if (blank - name >= I2C_NAME_SIZE) {
			dev_err(&in_port->port.dev, "%s: Invalid device name\n",
				"set_device");
			return -EINVAL;
		}
		memcpy(i2c_name, name, blank - name);

		/* Parse remaining parameters, reject extra parameters */
		ret = sscanf(++blank, "%hhu%c%x", &in_port->i2c_msg[0].addr,
			     &end, &hex);
		if (ret < 1) {
			dev_err(&in_port->port.dev, "%s: Can't parse I2C address\n",
				"set_device");
			return -EINVAL;
		}
		if (in_port->i2c_msg[0].addr == 0 && end == 'x')
			in_port->i2c_msg[0].addr = hex;
		in_port->num_i2c_msg = 1;
		name = i2c_name;
	}

	return brickpi_in_port_register_sensor(in_port,
					       &brickpi_in_port_device_types[mode], name);
}