Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Mar 24-27, 2025, special US time zones
Register
Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2011-2016 Synaptics Incorporated
  4 * Copyright (c) 2011 Unixphere
  5 */
  6
  7#include <linux/kernel.h>
  8#include <linux/device.h>
  9#include <linux/of.h>
 10#include <linux/input.h>
 11#include <linux/input/mt.h>
 12#include <linux/rmi.h>
 13#include "rmi_driver.h"
 14#include "rmi_2d_sensor.h"
 15
 16#define RMI_2D_REL_POS_MIN		-128
 17#define RMI_2D_REL_POS_MAX		127
 18
 19/* maximum ABS_MT_POSITION displacement (in mm) */
 20#define DMAX 10
 21
 22void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
 23				struct rmi_2d_sensor_abs_object *obj,
 24				int slot)
 25{
 26	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
 27
 28	/* we keep the previous values if the finger is released */
 29	if (obj->type == RMI_2D_OBJECT_NONE)
 30		return;
 31
 32	if (axis_align->flip_x)
 33		obj->x = sensor->max_x - obj->x;
 34
 35	if (axis_align->flip_y)
 36		obj->y = sensor->max_y - obj->y;
 37
 38	if (axis_align->swap_axes)
 39		swap(obj->x, obj->y);
 40
 41	/*
 42	 * Here checking if X offset or y offset are specified is
 43	 * redundant. We just add the offsets or clip the values.
 44	 *
 45	 * Note: offsets need to be applied before clipping occurs,
 46	 * or we could get funny values that are outside of
 47	 * clipping boundaries.
 48	 */
 49	obj->x += axis_align->offset_x;
 50	obj->y += axis_align->offset_y;
 51
 52	obj->x =  max(axis_align->clip_x_low, obj->x);
 53	obj->y =  max(axis_align->clip_y_low, obj->y);
 54
 55	if (axis_align->clip_x_high)
 56		obj->x = min(sensor->max_x, obj->x);
 57
 58	if (axis_align->clip_y_high)
 59		obj->y =  min(sensor->max_y, obj->y);
 60
 61	sensor->tracking_pos[slot].x = obj->x;
 62	sensor->tracking_pos[slot].y = obj->y;
 63}
 64EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_process);
 65
 66void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
 67				struct rmi_2d_sensor_abs_object *obj,
 68				int slot)
 69{
 70	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
 71	struct input_dev *input = sensor->input;
 72	int wide, major, minor;
 73
 74	if (sensor->kernel_tracking)
 75		input_mt_slot(input, sensor->tracking_slots[slot]);
 76	else
 77		input_mt_slot(input, slot);
 78
 79	input_mt_report_slot_state(input, obj->mt_tool,
 80				   obj->type != RMI_2D_OBJECT_NONE);
 81
 82	if (obj->type != RMI_2D_OBJECT_NONE) {
 83		obj->x = sensor->tracking_pos[slot].x;
 84		obj->y = sensor->tracking_pos[slot].y;
 85
 86		if (axis_align->swap_axes)
 87			swap(obj->wx, obj->wy);
 88
 89		wide = (obj->wx > obj->wy);
 90		major = max(obj->wx, obj->wy);
 91		minor = min(obj->wx, obj->wy);
 92
 93		if (obj->type == RMI_2D_OBJECT_STYLUS) {
 94			major = max(1, major);
 95			minor = max(1, minor);
 96		}
 97
 98		input_event(sensor->input, EV_ABS, ABS_MT_POSITION_X, obj->x);
 99		input_event(sensor->input, EV_ABS, ABS_MT_POSITION_Y, obj->y);
100		input_event(sensor->input, EV_ABS, ABS_MT_ORIENTATION, wide);
101		input_event(sensor->input, EV_ABS, ABS_MT_PRESSURE, obj->z);
102		input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
103		input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
104
105		rmi_dbg(RMI_DEBUG_2D_SENSOR, &sensor->input->dev,
106			"%s: obj[%d]: type: 0x%02x X: %d Y: %d Z: %d WX: %d WY: %d\n",
107			__func__, slot, obj->type, obj->x, obj->y, obj->z,
108			obj->wx, obj->wy);
109	}
110}
111EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_report);
112
113void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
114{
115	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
116
117	x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x));
118	y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y));
119
120	if (axis_align->flip_x)
121		x = min(RMI_2D_REL_POS_MAX, -x);
122
123	if (axis_align->flip_y)
124		y = min(RMI_2D_REL_POS_MAX, -y);
125
126	if (axis_align->swap_axes)
127		swap(x, y);
128
129	if (x || y) {
130		input_report_rel(sensor->input, REL_X, x);
131		input_report_rel(sensor->input, REL_Y, y);
132	}
133}
134EXPORT_SYMBOL_GPL(rmi_2d_sensor_rel_report);
135
136static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
137{
138	struct input_dev *input = sensor->input;
139	int res_x;
140	int res_y;
141	int max_x, max_y;
142	int input_flags = 0;
143
144	if (sensor->report_abs) {
145		sensor->min_x = sensor->axis_align.clip_x_low;
146		if (sensor->axis_align.clip_x_high)
147			sensor->max_x = min(sensor->max_x,
148				sensor->axis_align.clip_x_high);
149
150		sensor->min_y = sensor->axis_align.clip_y_low;
151		if (sensor->axis_align.clip_y_high)
152			sensor->max_y = min(sensor->max_y,
153				sensor->axis_align.clip_y_high);
154
155		set_bit(EV_ABS, input->evbit);
156
157		max_x = sensor->max_x;
158		max_y = sensor->max_y;
159		if (sensor->axis_align.swap_axes)
160			swap(max_x, max_y);
161		input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
162		input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
163
164		if (sensor->x_mm && sensor->y_mm) {
165			res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm;
166			res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm;
167			if (sensor->axis_align.swap_axes)
168				swap(res_x, res_y);
169
170			input_abs_set_res(input, ABS_X, res_x);
171			input_abs_set_res(input, ABS_Y, res_y);
172
173			input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
174			input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
175
176			if (!sensor->dmax)
177				sensor->dmax = DMAX * res_x;
178		}
179
180		input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
181		input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
182		input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
183		input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
184		input_set_abs_params(input, ABS_MT_TOOL_TYPE,
185				     0, MT_TOOL_MAX, 0, 0);
186
187		if (sensor->sensor_type == rmi_sensor_touchpad)
188			input_flags = INPUT_MT_POINTER;
189		else
190			input_flags = INPUT_MT_DIRECT;
191
192		if (sensor->kernel_tracking)
193			input_flags |= INPUT_MT_TRACK;
194
195		input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
196	}
197
198	if (sensor->report_rel) {
199		set_bit(EV_REL, input->evbit);
200		set_bit(REL_X, input->relbit);
201		set_bit(REL_Y, input->relbit);
202	}
203
204	if (sensor->topbuttonpad)
205		set_bit(INPUT_PROP_TOPBUTTONPAD, input->propbit);
206}
207
208int rmi_2d_sensor_configure_input(struct rmi_function *fn,
209					struct rmi_2d_sensor *sensor)
210{
211	struct rmi_device *rmi_dev = fn->rmi_dev;
212	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
213
214	if (!drv_data->input)
215		return -ENODEV;
216
217	sensor->input = drv_data->input;
218	rmi_2d_sensor_set_input_params(sensor);
219
220	return 0;
221}
222EXPORT_SYMBOL_GPL(rmi_2d_sensor_configure_input);
223
224#ifdef CONFIG_OF
225int rmi_2d_sensor_of_probe(struct device *dev,
226			struct rmi_2d_sensor_platform_data *pdata)
227{
228	int retval;
229	u32 val;
230
231	pdata->axis_align.swap_axes = of_property_read_bool(dev->of_node,
232						"touchscreen-swapped-x-y");
233
234	pdata->axis_align.flip_x = of_property_read_bool(dev->of_node,
235						"touchscreen-inverted-x");
236
237	pdata->axis_align.flip_y = of_property_read_bool(dev->of_node,
238						"touchscreen-inverted-y");
239
240	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-x-low", 1);
241	if (retval)
242		return retval;
243
244	pdata->axis_align.clip_x_low = val;
245
246	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-y-low",	1);
247	if (retval)
248		return retval;
249
250	pdata->axis_align.clip_y_low = val;
251
252	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-x-high", 1);
253	if (retval)
254		return retval;
255
256	pdata->axis_align.clip_x_high = val;
257
258	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-y-high", 1);
259	if (retval)
260		return retval;
261
262	pdata->axis_align.clip_y_high = val;
263
264	retval = rmi_of_property_read_u32(dev, &val, "syna,offset-x", 1);
265	if (retval)
266		return retval;
267
268	pdata->axis_align.offset_x = val;
269
270	retval = rmi_of_property_read_u32(dev, &val, "syna,offset-y", 1);
271	if (retval)
272		return retval;
273
274	pdata->axis_align.offset_y = val;
275
276	retval = rmi_of_property_read_u32(dev, &val, "syna,delta-x-threshold",
277						1);
278	if (retval)
279		return retval;
280
281	pdata->axis_align.delta_x_threshold = val;
282
283	retval = rmi_of_property_read_u32(dev, &val, "syna,delta-y-threshold",
284						1);
285	if (retval)
286		return retval;
287
288	pdata->axis_align.delta_y_threshold = val;
289
290	retval = rmi_of_property_read_u32(dev, (u32 *)&pdata->sensor_type,
291			"syna,sensor-type", 1);
292	if (retval)
293		return retval;
294
295	retval = rmi_of_property_read_u32(dev, &val, "touchscreen-x-mm", 1);
296	if (retval)
297		return retval;
298
299	pdata->x_mm = val;
300
301	retval = rmi_of_property_read_u32(dev, &val, "touchscreen-y-mm", 1);
302	if (retval)
303		return retval;
304
305	pdata->y_mm = val;
306
307	retval = rmi_of_property_read_u32(dev, &val,
308				"syna,disable-report-mask", 1);
309	if (retval)
310		return retval;
311
312	pdata->disable_report_mask = val;
313
314	retval = rmi_of_property_read_u32(dev, &val, "syna,rezero-wait-ms",
315						1);
316	if (retval)
317		return retval;
318
319	pdata->rezero_wait = val;
320
321	return 0;
322}
323#else
324inline int rmi_2d_sensor_of_probe(struct device *dev,
325			struct rmi_2d_sensor_platform_data *pdata)
326{
327	return -ENODEV;
328}
329#endif
330EXPORT_SYMBOL_GPL(rmi_2d_sensor_of_probe);
v5.4
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2011-2016 Synaptics Incorporated
  4 * Copyright (c) 2011 Unixphere
  5 */
  6
  7#include <linux/kernel.h>
  8#include <linux/device.h>
  9#include <linux/of.h>
 10#include <linux/input.h>
 11#include <linux/input/mt.h>
 12#include <linux/rmi.h>
 13#include "rmi_driver.h"
 14#include "rmi_2d_sensor.h"
 15
 16#define RMI_2D_REL_POS_MIN		-128
 17#define RMI_2D_REL_POS_MAX		127
 18
 19/* maximum ABS_MT_POSITION displacement (in mm) */
 20#define DMAX 10
 21
 22void rmi_2d_sensor_abs_process(struct rmi_2d_sensor *sensor,
 23				struct rmi_2d_sensor_abs_object *obj,
 24				int slot)
 25{
 26	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
 27
 28	/* we keep the previous values if the finger is released */
 29	if (obj->type == RMI_2D_OBJECT_NONE)
 30		return;
 31
 32	if (axis_align->flip_x)
 33		obj->x = sensor->max_x - obj->x;
 34
 35	if (axis_align->flip_y)
 36		obj->y = sensor->max_y - obj->y;
 37
 38	if (axis_align->swap_axes)
 39		swap(obj->x, obj->y);
 40
 41	/*
 42	 * Here checking if X offset or y offset are specified is
 43	 * redundant. We just add the offsets or clip the values.
 44	 *
 45	 * Note: offsets need to be applied before clipping occurs,
 46	 * or we could get funny values that are outside of
 47	 * clipping boundaries.
 48	 */
 49	obj->x += axis_align->offset_x;
 50	obj->y += axis_align->offset_y;
 51
 52	obj->x =  max(axis_align->clip_x_low, obj->x);
 53	obj->y =  max(axis_align->clip_y_low, obj->y);
 54
 55	if (axis_align->clip_x_high)
 56		obj->x = min(sensor->max_x, obj->x);
 57
 58	if (axis_align->clip_y_high)
 59		obj->y =  min(sensor->max_y, obj->y);
 60
 61	sensor->tracking_pos[slot].x = obj->x;
 62	sensor->tracking_pos[slot].y = obj->y;
 63}
 64EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_process);
 65
 66void rmi_2d_sensor_abs_report(struct rmi_2d_sensor *sensor,
 67				struct rmi_2d_sensor_abs_object *obj,
 68				int slot)
 69{
 70	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
 71	struct input_dev *input = sensor->input;
 72	int wide, major, minor;
 73
 74	if (sensor->kernel_tracking)
 75		input_mt_slot(input, sensor->tracking_slots[slot]);
 76	else
 77		input_mt_slot(input, slot);
 78
 79	input_mt_report_slot_state(input, obj->mt_tool,
 80				   obj->type != RMI_2D_OBJECT_NONE);
 81
 82	if (obj->type != RMI_2D_OBJECT_NONE) {
 83		obj->x = sensor->tracking_pos[slot].x;
 84		obj->y = sensor->tracking_pos[slot].y;
 85
 86		if (axis_align->swap_axes)
 87			swap(obj->wx, obj->wy);
 88
 89		wide = (obj->wx > obj->wy);
 90		major = max(obj->wx, obj->wy);
 91		minor = min(obj->wx, obj->wy);
 92
 93		if (obj->type == RMI_2D_OBJECT_STYLUS) {
 94			major = max(1, major);
 95			minor = max(1, minor);
 96		}
 97
 98		input_event(sensor->input, EV_ABS, ABS_MT_POSITION_X, obj->x);
 99		input_event(sensor->input, EV_ABS, ABS_MT_POSITION_Y, obj->y);
100		input_event(sensor->input, EV_ABS, ABS_MT_ORIENTATION, wide);
101		input_event(sensor->input, EV_ABS, ABS_MT_PRESSURE, obj->z);
102		input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
103		input_event(sensor->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
104
105		rmi_dbg(RMI_DEBUG_2D_SENSOR, &sensor->input->dev,
106			"%s: obj[%d]: type: 0x%02x X: %d Y: %d Z: %d WX: %d WY: %d\n",
107			__func__, slot, obj->type, obj->x, obj->y, obj->z,
108			obj->wx, obj->wy);
109	}
110}
111EXPORT_SYMBOL_GPL(rmi_2d_sensor_abs_report);
112
113void rmi_2d_sensor_rel_report(struct rmi_2d_sensor *sensor, int x, int y)
114{
115	struct rmi_2d_axis_alignment *axis_align = &sensor->axis_align;
116
117	x = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)x));
118	y = min(RMI_2D_REL_POS_MAX, max(RMI_2D_REL_POS_MIN, (int)y));
119
120	if (axis_align->flip_x)
121		x = min(RMI_2D_REL_POS_MAX, -x);
122
123	if (axis_align->flip_y)
124		y = min(RMI_2D_REL_POS_MAX, -y);
125
126	if (axis_align->swap_axes)
127		swap(x, y);
128
129	if (x || y) {
130		input_report_rel(sensor->input, REL_X, x);
131		input_report_rel(sensor->input, REL_Y, y);
132	}
133}
134EXPORT_SYMBOL_GPL(rmi_2d_sensor_rel_report);
135
136static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
137{
138	struct input_dev *input = sensor->input;
139	int res_x;
140	int res_y;
141	int max_x, max_y;
142	int input_flags = 0;
143
144	if (sensor->report_abs) {
145		sensor->min_x = sensor->axis_align.clip_x_low;
146		if (sensor->axis_align.clip_x_high)
147			sensor->max_x = min(sensor->max_x,
148				sensor->axis_align.clip_x_high);
149
150		sensor->min_y = sensor->axis_align.clip_y_low;
151		if (sensor->axis_align.clip_y_high)
152			sensor->max_y = min(sensor->max_y,
153				sensor->axis_align.clip_y_high);
154
155		set_bit(EV_ABS, input->evbit);
156
157		max_x = sensor->max_x;
158		max_y = sensor->max_y;
159		if (sensor->axis_align.swap_axes)
160			swap(max_x, max_y);
161		input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
162		input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
163
164		if (sensor->x_mm && sensor->y_mm) {
165			res_x = (sensor->max_x - sensor->min_x) / sensor->x_mm;
166			res_y = (sensor->max_y - sensor->min_y) / sensor->y_mm;
167			if (sensor->axis_align.swap_axes)
168				swap(res_x, res_y);
169
170			input_abs_set_res(input, ABS_X, res_x);
171			input_abs_set_res(input, ABS_Y, res_y);
172
173			input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
174			input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
175
176			if (!sensor->dmax)
177				sensor->dmax = DMAX * res_x;
178		}
179
180		input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0);
181		input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0);
182		input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0);
183		input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
184		input_set_abs_params(input, ABS_MT_TOOL_TYPE,
185				     0, MT_TOOL_MAX, 0, 0);
186
187		if (sensor->sensor_type == rmi_sensor_touchpad)
188			input_flags = INPUT_MT_POINTER;
189		else
190			input_flags = INPUT_MT_DIRECT;
191
192		if (sensor->kernel_tracking)
193			input_flags |= INPUT_MT_TRACK;
194
195		input_mt_init_slots(input, sensor->nbr_fingers, input_flags);
196	}
197
198	if (sensor->report_rel) {
199		set_bit(EV_REL, input->evbit);
200		set_bit(REL_X, input->relbit);
201		set_bit(REL_Y, input->relbit);
202	}
203
204	if (sensor->topbuttonpad)
205		set_bit(INPUT_PROP_TOPBUTTONPAD, input->propbit);
206}
207
208int rmi_2d_sensor_configure_input(struct rmi_function *fn,
209					struct rmi_2d_sensor *sensor)
210{
211	struct rmi_device *rmi_dev = fn->rmi_dev;
212	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
213
214	if (!drv_data->input)
215		return -ENODEV;
216
217	sensor->input = drv_data->input;
218	rmi_2d_sensor_set_input_params(sensor);
219
220	return 0;
221}
222EXPORT_SYMBOL_GPL(rmi_2d_sensor_configure_input);
223
224#ifdef CONFIG_OF
225int rmi_2d_sensor_of_probe(struct device *dev,
226			struct rmi_2d_sensor_platform_data *pdata)
227{
228	int retval;
229	u32 val;
230
231	pdata->axis_align.swap_axes = of_property_read_bool(dev->of_node,
232						"touchscreen-swapped-x-y");
233
234	pdata->axis_align.flip_x = of_property_read_bool(dev->of_node,
235						"touchscreen-inverted-x");
236
237	pdata->axis_align.flip_y = of_property_read_bool(dev->of_node,
238						"touchscreen-inverted-y");
239
240	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-x-low", 1);
241	if (retval)
242		return retval;
243
244	pdata->axis_align.clip_x_low = val;
245
246	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-y-low",	1);
247	if (retval)
248		return retval;
249
250	pdata->axis_align.clip_y_low = val;
251
252	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-x-high", 1);
253	if (retval)
254		return retval;
255
256	pdata->axis_align.clip_x_high = val;
257
258	retval = rmi_of_property_read_u32(dev, &val, "syna,clip-y-high", 1);
259	if (retval)
260		return retval;
261
262	pdata->axis_align.clip_y_high = val;
263
264	retval = rmi_of_property_read_u32(dev, &val, "syna,offset-x", 1);
265	if (retval)
266		return retval;
267
268	pdata->axis_align.offset_x = val;
269
270	retval = rmi_of_property_read_u32(dev, &val, "syna,offset-y", 1);
271	if (retval)
272		return retval;
273
274	pdata->axis_align.offset_y = val;
275
276	retval = rmi_of_property_read_u32(dev, &val, "syna,delta-x-threshold",
277						1);
278	if (retval)
279		return retval;
280
281	pdata->axis_align.delta_x_threshold = val;
282
283	retval = rmi_of_property_read_u32(dev, &val, "syna,delta-y-threshold",
284						1);
285	if (retval)
286		return retval;
287
288	pdata->axis_align.delta_y_threshold = val;
289
290	retval = rmi_of_property_read_u32(dev, (u32 *)&pdata->sensor_type,
291			"syna,sensor-type", 1);
292	if (retval)
293		return retval;
294
295	retval = rmi_of_property_read_u32(dev, &val, "touchscreen-x-mm", 1);
296	if (retval)
297		return retval;
298
299	pdata->x_mm = val;
300
301	retval = rmi_of_property_read_u32(dev, &val, "touchscreen-y-mm", 1);
302	if (retval)
303		return retval;
304
305	pdata->y_mm = val;
306
307	retval = rmi_of_property_read_u32(dev, &val,
308				"syna,disable-report-mask", 1);
309	if (retval)
310		return retval;
311
312	pdata->disable_report_mask = val;
313
314	retval = rmi_of_property_read_u32(dev, &val, "syna,rezero-wait-ms",
315						1);
316	if (retval)
317		return retval;
318
319	pdata->rezero_wait = val;
320
321	return 0;
322}
323#else
324inline int rmi_2d_sensor_of_probe(struct device *dev,
325			struct rmi_2d_sensor_platform_data *pdata)
326{
327	return -ENODEV;
328}
329#endif
330EXPORT_SYMBOL_GPL(rmi_2d_sensor_of_probe);