Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24f63b1c authored by Andrew Duggan's avatar Andrew Duggan Committed by Dmitry Torokhov
Browse files

Input: synaptics-rmi4 - add support for controlling dribble packets in F12



Implements reading and setting the dribble bit in F12's control registers.

Signed-off-by: default avatarAndrew Duggan <aduggan@synaptics.com>
Acked-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 2775e523
Loading
Loading
Loading
Loading
+69 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ enum rmi_f12_object_type {
struct f12_data {
	struct rmi_2d_sensor sensor;
	struct rmi_2d_sensor_platform_data sensor_pdata;
	bool has_dribble;

	u16 data_addr;

@@ -239,12 +240,76 @@ static int rmi_f12_attention(struct rmi_function *fn,
	return 0;
}

static int rmi_f12_write_control_regs(struct rmi_function *fn)
{
	int ret;
	const struct rmi_register_desc_item *item;
	struct rmi_device *rmi_dev = fn->rmi_dev;
	struct f12_data *f12 = dev_get_drvdata(&fn->dev);
	int control_size;
	char buf[3];
	u16 control_offset = 0;
	u8 subpacket_offset = 0;

	if (f12->has_dribble
	    && (f12->sensor.dribble != RMI_REG_STATE_DEFAULT)) {
		item = rmi_get_register_desc_item(&f12->control_reg_desc, 20);
		if (item) {
			control_offset = rmi_register_desc_calc_reg_offset(
						&f12->control_reg_desc, 20);

			/*
			 * The byte containing the EnableDribble bit will be
			 * in either byte 0 or byte 2 of control 20. Depending
			 * on the existence of subpacket 0. If control 20 is
			 * larger then 3 bytes, just read the first 3.
			 */
			control_size = min(item->reg_size, 3UL);

			ret = rmi_read_block(rmi_dev, fn->fd.control_base_addr
					+ control_offset, buf, control_size);
			if (ret)
				return ret;

			if (rmi_register_desc_has_subpacket(item, 0))
				subpacket_offset += 1;

			switch (f12->sensor.dribble) {
			case RMI_REG_STATE_OFF:
				buf[subpacket_offset] &= ~BIT(2);
				break;
			case RMI_REG_STATE_ON:
				buf[subpacket_offset] |= BIT(2);
				break;
			case RMI_REG_STATE_DEFAULT:
			default:
				break;
			}

			ret = rmi_write_block(rmi_dev,
				fn->fd.control_base_addr + control_offset,
				buf, control_size);
			if (ret)
				return ret;
		}
	}

	return 0;

}

static int rmi_f12_config(struct rmi_function *fn)
{
	struct rmi_driver *drv = fn->rmi_dev->driver;
	int ret;

	drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);

	ret = rmi_f12_write_control_regs(fn);
	if (ret)
		dev_warn(&fn->dev,
			"Failed to write F12 control registers: %d\n", ret);

	return 0;
}

@@ -271,7 +336,7 @@ static int rmi_f12_probe(struct rmi_function *fn)
	}
	++query_addr;

	if (!(buf & 0x1)) {
	if (!(buf & BIT(0))) {
		dev_err(&fn->dev,
			"Behavior of F12 without register descriptors is undefined.\n");
		return -ENODEV;
@@ -281,6 +346,8 @@ static int rmi_f12_probe(struct rmi_function *fn)
	if (!f12)
		return -ENOMEM;

	f12->has_dribble = !!(buf & BIT(3));

	if (fn->dev.of_node) {
		ret = rmi_2d_sensor_of_probe(&fn->dev, &f12->sensor_pdata);
		if (ret)
@@ -329,6 +396,7 @@ static int rmi_f12_probe(struct rmi_function *fn)

	sensor->x_mm = f12->sensor_pdata.x_mm;
	sensor->y_mm = f12->sensor_pdata.y_mm;
	sensor->dribble = f12->sensor_pdata.dribble;

	if (sensor->sensor_type == rmi_sensor_default)
		sensor->sensor_type =