xref: /openbmc/linux/drivers/input/rmi4/rmi_f01.c (revision 2b6a321da9a2d8725a1d3dbb0b2e96a7618ebe56)
1*2b6a321dSAndrew Duggan /*
2*2b6a321dSAndrew Duggan  * Copyright (c) 2011-2016 Synaptics Incorporated
3*2b6a321dSAndrew Duggan  * Copyright (c) 2011 Unixphere
4*2b6a321dSAndrew Duggan  *
5*2b6a321dSAndrew Duggan  * This program is free software; you can redistribute it and/or modify it
6*2b6a321dSAndrew Duggan  * under the terms of the GNU General Public License version 2 as published by
7*2b6a321dSAndrew Duggan  * the Free Software Foundation.
8*2b6a321dSAndrew Duggan  */
9*2b6a321dSAndrew Duggan 
10*2b6a321dSAndrew Duggan #include <linux/kernel.h>
11*2b6a321dSAndrew Duggan #include <linux/kconfig.h>
12*2b6a321dSAndrew Duggan #include <linux/rmi.h>
13*2b6a321dSAndrew Duggan #include <linux/slab.h>
14*2b6a321dSAndrew Duggan #include <linux/uaccess.h>
15*2b6a321dSAndrew Duggan #include <linux/of.h>
16*2b6a321dSAndrew Duggan #include "rmi_driver.h"
17*2b6a321dSAndrew Duggan 
18*2b6a321dSAndrew Duggan #define RMI_PRODUCT_ID_LENGTH    10
19*2b6a321dSAndrew Duggan #define RMI_PRODUCT_INFO_LENGTH   2
20*2b6a321dSAndrew Duggan 
21*2b6a321dSAndrew Duggan #define RMI_DATE_CODE_LENGTH      3
22*2b6a321dSAndrew Duggan 
23*2b6a321dSAndrew Duggan #define PRODUCT_ID_OFFSET 0x10
24*2b6a321dSAndrew Duggan #define PRODUCT_INFO_OFFSET 0x1E
25*2b6a321dSAndrew Duggan 
26*2b6a321dSAndrew Duggan 
27*2b6a321dSAndrew Duggan /* Force a firmware reset of the sensor */
28*2b6a321dSAndrew Duggan #define RMI_F01_CMD_DEVICE_RESET	1
29*2b6a321dSAndrew Duggan 
30*2b6a321dSAndrew Duggan /* Various F01_RMI_QueryX bits */
31*2b6a321dSAndrew Duggan 
32*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_CUSTOM_MAP		BIT(0)
33*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_NON_COMPLIANT	BIT(1)
34*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_LTS		BIT(2)
35*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_SENSOR_ID	BIT(3)
36*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_CHARGER_INP	BIT(4)
37*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_ADJ_DOZE	BIT(5)
38*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_ADJ_DOZE_HOFF	BIT(6)
39*2b6a321dSAndrew Duggan #define RMI_F01_QRY1_HAS_QUERY42	BIT(7)
40*2b6a321dSAndrew Duggan 
41*2b6a321dSAndrew Duggan #define RMI_F01_QRY5_YEAR_MASK		0x1f
42*2b6a321dSAndrew Duggan #define RMI_F01_QRY6_MONTH_MASK		0x0f
43*2b6a321dSAndrew Duggan #define RMI_F01_QRY7_DAY_MASK		0x1f
44*2b6a321dSAndrew Duggan 
45*2b6a321dSAndrew Duggan #define RMI_F01_QRY2_PRODINFO_MASK	0x7f
46*2b6a321dSAndrew Duggan 
47*2b6a321dSAndrew Duggan #define RMI_F01_BASIC_QUERY_LEN		21 /* From Query 00 through 20 */
48*2b6a321dSAndrew Duggan 
49*2b6a321dSAndrew Duggan struct f01_basic_properties {
50*2b6a321dSAndrew Duggan 	u8 manufacturer_id;
51*2b6a321dSAndrew Duggan 	bool has_lts;
52*2b6a321dSAndrew Duggan 	bool has_adjustable_doze;
53*2b6a321dSAndrew Duggan 	bool has_adjustable_doze_holdoff;
54*2b6a321dSAndrew Duggan 	char dom[11]; /* YYYY/MM/DD + '\0' */
55*2b6a321dSAndrew Duggan 	u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
56*2b6a321dSAndrew Duggan 	u16 productinfo;
57*2b6a321dSAndrew Duggan 	u32 firmware_id;
58*2b6a321dSAndrew Duggan };
59*2b6a321dSAndrew Duggan 
60*2b6a321dSAndrew Duggan /* F01 device status bits */
61*2b6a321dSAndrew Duggan 
62*2b6a321dSAndrew Duggan /* Most recent device status event */
63*2b6a321dSAndrew Duggan #define RMI_F01_STATUS_CODE(status)		((status) & 0x0f)
64*2b6a321dSAndrew Duggan /* The device has lost its configuration for some reason. */
65*2b6a321dSAndrew Duggan #define RMI_F01_STATUS_UNCONFIGURED(status)	(!!((status) & 0x80))
66*2b6a321dSAndrew Duggan 
67*2b6a321dSAndrew Duggan /* Control register bits */
68*2b6a321dSAndrew Duggan 
69*2b6a321dSAndrew Duggan /*
70*2b6a321dSAndrew Duggan  * Sleep mode controls power management on the device and affects all
71*2b6a321dSAndrew Duggan  * functions of the device.
72*2b6a321dSAndrew Duggan  */
73*2b6a321dSAndrew Duggan #define RMI_F01_CTRL0_SLEEP_MODE_MASK	0x03
74*2b6a321dSAndrew Duggan 
75*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_NORMAL		0x00
76*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_SENSOR_SLEEP	0x01
77*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_RESERVED0	0x02
78*2b6a321dSAndrew Duggan #define RMI_SLEEP_MODE_RESERVED1	0x03
79*2b6a321dSAndrew Duggan 
80*2b6a321dSAndrew Duggan /*
81*2b6a321dSAndrew Duggan  * This bit disables whatever sleep mode may be selected by the sleep_mode
82*2b6a321dSAndrew Duggan  * field and forces the device to run at full power without sleeping.
83*2b6a321dSAndrew Duggan  */
84*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_NOSLEEP_BIT	BIT(2)
85*2b6a321dSAndrew Duggan 
86*2b6a321dSAndrew Duggan /*
87*2b6a321dSAndrew Duggan  * When this bit is set, the touch controller employs a noise-filtering
88*2b6a321dSAndrew Duggan  * algorithm designed for use with a connected battery charger.
89*2b6a321dSAndrew Duggan  */
90*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_CHARGER_BIT	BIT(5)
91*2b6a321dSAndrew Duggan 
92*2b6a321dSAndrew Duggan /*
93*2b6a321dSAndrew Duggan  * Sets the report rate for the device. The effect of this setting is
94*2b6a321dSAndrew Duggan  * highly product dependent. Check the spec sheet for your particular
95*2b6a321dSAndrew Duggan  * touch sensor.
96*2b6a321dSAndrew Duggan  */
97*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_REPORTRATE_BIT	BIT(6)
98*2b6a321dSAndrew Duggan 
99*2b6a321dSAndrew Duggan /*
100*2b6a321dSAndrew Duggan  * Written by the host as an indicator that the device has been
101*2b6a321dSAndrew Duggan  * successfully configured.
102*2b6a321dSAndrew Duggan  */
103*2b6a321dSAndrew Duggan #define RMI_F01_CRTL0_CONFIGURED_BIT	BIT(7)
104*2b6a321dSAndrew Duggan 
105*2b6a321dSAndrew Duggan /**
106*2b6a321dSAndrew Duggan  * @ctrl0 - see the bit definitions above.
107*2b6a321dSAndrew Duggan  * @doze_interval - controls the interval between checks for finger presence
108*2b6a321dSAndrew Duggan  * when the touch sensor is in doze mode, in units of 10ms.
109*2b6a321dSAndrew Duggan  * @wakeup_threshold - controls the capacitance threshold at which the touch
110*2b6a321dSAndrew Duggan  * sensor will decide to wake up from that low power state.
111*2b6a321dSAndrew Duggan  * @doze_holdoff - controls how long the touch sensor waits after the last
112*2b6a321dSAndrew Duggan  * finger lifts before entering the doze state, in units of 100ms.
113*2b6a321dSAndrew Duggan  */
114*2b6a321dSAndrew Duggan struct f01_device_control {
115*2b6a321dSAndrew Duggan 	u8 ctrl0;
116*2b6a321dSAndrew Duggan 	u8 doze_interval;
117*2b6a321dSAndrew Duggan 	u8 wakeup_threshold;
118*2b6a321dSAndrew Duggan 	u8 doze_holdoff;
119*2b6a321dSAndrew Duggan };
120*2b6a321dSAndrew Duggan 
121*2b6a321dSAndrew Duggan struct f01_data {
122*2b6a321dSAndrew Duggan 	struct f01_basic_properties properties;
123*2b6a321dSAndrew Duggan 	struct f01_device_control device_control;
124*2b6a321dSAndrew Duggan 
125*2b6a321dSAndrew Duggan 	u16 doze_interval_addr;
126*2b6a321dSAndrew Duggan 	u16 wakeup_threshold_addr;
127*2b6a321dSAndrew Duggan 	u16 doze_holdoff_addr;
128*2b6a321dSAndrew Duggan 
129*2b6a321dSAndrew Duggan 	bool suspended;
130*2b6a321dSAndrew Duggan 	bool old_nosleep;
131*2b6a321dSAndrew Duggan 
132*2b6a321dSAndrew Duggan 	unsigned int num_of_irq_regs;
133*2b6a321dSAndrew Duggan };
134*2b6a321dSAndrew Duggan 
135*2b6a321dSAndrew Duggan static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
136*2b6a321dSAndrew Duggan 				   u16 query_base_addr,
137*2b6a321dSAndrew Duggan 				   struct f01_basic_properties *props)
138*2b6a321dSAndrew Duggan {
139*2b6a321dSAndrew Duggan 	u8 queries[RMI_F01_BASIC_QUERY_LEN];
140*2b6a321dSAndrew Duggan 	int ret;
141*2b6a321dSAndrew Duggan 	int query_offset = query_base_addr;
142*2b6a321dSAndrew Duggan 	bool has_ds4_queries = false;
143*2b6a321dSAndrew Duggan 	bool has_query42 = false;
144*2b6a321dSAndrew Duggan 	bool has_sensor_id = false;
145*2b6a321dSAndrew Duggan 	bool has_package_id_query = false;
146*2b6a321dSAndrew Duggan 	bool has_build_id_query = false;
147*2b6a321dSAndrew Duggan 	u16 prod_info_addr;
148*2b6a321dSAndrew Duggan 	u8 ds4_query_len;
149*2b6a321dSAndrew Duggan 
150*2b6a321dSAndrew Duggan 	ret = rmi_read_block(rmi_dev, query_offset,
151*2b6a321dSAndrew Duggan 			       queries, RMI_F01_BASIC_QUERY_LEN);
152*2b6a321dSAndrew Duggan 	if (ret) {
153*2b6a321dSAndrew Duggan 		dev_err(&rmi_dev->dev,
154*2b6a321dSAndrew Duggan 			"Failed to read device query registers: %d\n", ret);
155*2b6a321dSAndrew Duggan 		return ret;
156*2b6a321dSAndrew Duggan 	}
157*2b6a321dSAndrew Duggan 
158*2b6a321dSAndrew Duggan 	prod_info_addr = query_offset + 17;
159*2b6a321dSAndrew Duggan 	query_offset += RMI_F01_BASIC_QUERY_LEN;
160*2b6a321dSAndrew Duggan 
161*2b6a321dSAndrew Duggan 	/* Now parse what we got */
162*2b6a321dSAndrew Duggan 	props->manufacturer_id = queries[0];
163*2b6a321dSAndrew Duggan 
164*2b6a321dSAndrew Duggan 	props->has_lts = queries[1] & RMI_F01_QRY1_HAS_LTS;
165*2b6a321dSAndrew Duggan 	props->has_adjustable_doze =
166*2b6a321dSAndrew Duggan 			queries[1] & RMI_F01_QRY1_HAS_ADJ_DOZE;
167*2b6a321dSAndrew Duggan 	props->has_adjustable_doze_holdoff =
168*2b6a321dSAndrew Duggan 			queries[1] & RMI_F01_QRY1_HAS_ADJ_DOZE_HOFF;
169*2b6a321dSAndrew Duggan 	has_query42 = queries[1] & RMI_F01_QRY1_HAS_QUERY42;
170*2b6a321dSAndrew Duggan 	has_sensor_id = queries[1] & RMI_F01_QRY1_HAS_SENSOR_ID;
171*2b6a321dSAndrew Duggan 
172*2b6a321dSAndrew Duggan 	snprintf(props->dom, sizeof(props->dom), "20%02d/%02d/%02d",
173*2b6a321dSAndrew Duggan 		 queries[5] & RMI_F01_QRY5_YEAR_MASK,
174*2b6a321dSAndrew Duggan 		 queries[6] & RMI_F01_QRY6_MONTH_MASK,
175*2b6a321dSAndrew Duggan 		 queries[7] & RMI_F01_QRY7_DAY_MASK);
176*2b6a321dSAndrew Duggan 
177*2b6a321dSAndrew Duggan 	memcpy(props->product_id, &queries[11],
178*2b6a321dSAndrew Duggan 		RMI_PRODUCT_ID_LENGTH);
179*2b6a321dSAndrew Duggan 	props->product_id[RMI_PRODUCT_ID_LENGTH] = '\0';
180*2b6a321dSAndrew Duggan 
181*2b6a321dSAndrew Duggan 	props->productinfo =
182*2b6a321dSAndrew Duggan 			((queries[2] & RMI_F01_QRY2_PRODINFO_MASK) << 7) |
183*2b6a321dSAndrew Duggan 			(queries[3] & RMI_F01_QRY2_PRODINFO_MASK);
184*2b6a321dSAndrew Duggan 
185*2b6a321dSAndrew Duggan 	if (has_sensor_id)
186*2b6a321dSAndrew Duggan 		query_offset++;
187*2b6a321dSAndrew Duggan 
188*2b6a321dSAndrew Duggan 	if (has_query42) {
189*2b6a321dSAndrew Duggan 		ret = rmi_read(rmi_dev, query_offset, queries);
190*2b6a321dSAndrew Duggan 		if (ret) {
191*2b6a321dSAndrew Duggan 			dev_err(&rmi_dev->dev,
192*2b6a321dSAndrew Duggan 				"Failed to read query 42 register: %d\n", ret);
193*2b6a321dSAndrew Duggan 			return ret;
194*2b6a321dSAndrew Duggan 		}
195*2b6a321dSAndrew Duggan 
196*2b6a321dSAndrew Duggan 		has_ds4_queries = !!(queries[0] & BIT(0));
197*2b6a321dSAndrew Duggan 		query_offset++;
198*2b6a321dSAndrew Duggan 	}
199*2b6a321dSAndrew Duggan 
200*2b6a321dSAndrew Duggan 	if (has_ds4_queries) {
201*2b6a321dSAndrew Duggan 		ret = rmi_read(rmi_dev, query_offset, &ds4_query_len);
202*2b6a321dSAndrew Duggan 		if (ret) {
203*2b6a321dSAndrew Duggan 			dev_err(&rmi_dev->dev,
204*2b6a321dSAndrew Duggan 				"Failed to read DS4 queries length: %d\n", ret);
205*2b6a321dSAndrew Duggan 			return ret;
206*2b6a321dSAndrew Duggan 		}
207*2b6a321dSAndrew Duggan 		query_offset++;
208*2b6a321dSAndrew Duggan 
209*2b6a321dSAndrew Duggan 		if (ds4_query_len > 0) {
210*2b6a321dSAndrew Duggan 			ret = rmi_read(rmi_dev, query_offset, queries);
211*2b6a321dSAndrew Duggan 			if (ret) {
212*2b6a321dSAndrew Duggan 				dev_err(&rmi_dev->dev,
213*2b6a321dSAndrew Duggan 					"Failed to read DS4 queries: %d\n",
214*2b6a321dSAndrew Duggan 					ret);
215*2b6a321dSAndrew Duggan 				return ret;
216*2b6a321dSAndrew Duggan 			}
217*2b6a321dSAndrew Duggan 
218*2b6a321dSAndrew Duggan 			has_package_id_query = !!(queries[0] & BIT(0));
219*2b6a321dSAndrew Duggan 			has_build_id_query = !!(queries[0] & BIT(1));
220*2b6a321dSAndrew Duggan 		}
221*2b6a321dSAndrew Duggan 
222*2b6a321dSAndrew Duggan 		if (has_package_id_query)
223*2b6a321dSAndrew Duggan 			prod_info_addr++;
224*2b6a321dSAndrew Duggan 
225*2b6a321dSAndrew Duggan 		if (has_build_id_query) {
226*2b6a321dSAndrew Duggan 			ret = rmi_read_block(rmi_dev, prod_info_addr, queries,
227*2b6a321dSAndrew Duggan 					    3);
228*2b6a321dSAndrew Duggan 			if (ret) {
229*2b6a321dSAndrew Duggan 				dev_err(&rmi_dev->dev,
230*2b6a321dSAndrew Duggan 					"Failed to read product info: %d\n",
231*2b6a321dSAndrew Duggan 					ret);
232*2b6a321dSAndrew Duggan 				return ret;
233*2b6a321dSAndrew Duggan 			}
234*2b6a321dSAndrew Duggan 
235*2b6a321dSAndrew Duggan 			props->firmware_id = queries[1] << 8 | queries[0];
236*2b6a321dSAndrew Duggan 			props->firmware_id += queries[2] * 65536;
237*2b6a321dSAndrew Duggan 		}
238*2b6a321dSAndrew Duggan 	}
239*2b6a321dSAndrew Duggan 
240*2b6a321dSAndrew Duggan 	return 0;
241*2b6a321dSAndrew Duggan }
242*2b6a321dSAndrew Duggan 
243*2b6a321dSAndrew Duggan char *rmi_f01_get_product_ID(struct rmi_function *fn)
244*2b6a321dSAndrew Duggan {
245*2b6a321dSAndrew Duggan 	struct f01_data *f01 = dev_get_drvdata(&fn->dev);
246*2b6a321dSAndrew Duggan 
247*2b6a321dSAndrew Duggan 	return f01->properties.product_id;
248*2b6a321dSAndrew Duggan }
249*2b6a321dSAndrew Duggan 
250*2b6a321dSAndrew Duggan static int rmi_f01_probe(struct rmi_function *fn)
251*2b6a321dSAndrew Duggan {
252*2b6a321dSAndrew Duggan 	struct rmi_device *rmi_dev = fn->rmi_dev;
253*2b6a321dSAndrew Duggan 	struct rmi_driver_data *driver_data = dev_get_drvdata(&rmi_dev->dev);
254*2b6a321dSAndrew Duggan 	struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
255*2b6a321dSAndrew Duggan 	struct f01_data *f01;
256*2b6a321dSAndrew Duggan 	int error;
257*2b6a321dSAndrew Duggan 	u16 ctrl_base_addr = fn->fd.control_base_addr;
258*2b6a321dSAndrew Duggan 	u8 device_status;
259*2b6a321dSAndrew Duggan 	u8 temp;
260*2b6a321dSAndrew Duggan 
261*2b6a321dSAndrew Duggan 	f01 = devm_kzalloc(&fn->dev, sizeof(struct f01_data), GFP_KERNEL);
262*2b6a321dSAndrew Duggan 	if (!f01)
263*2b6a321dSAndrew Duggan 		return -ENOMEM;
264*2b6a321dSAndrew Duggan 
265*2b6a321dSAndrew Duggan 	f01->num_of_irq_regs = driver_data->num_of_irq_regs;
266*2b6a321dSAndrew Duggan 
267*2b6a321dSAndrew Duggan 	/*
268*2b6a321dSAndrew Duggan 	 * Set the configured bit and (optionally) other important stuff
269*2b6a321dSAndrew Duggan 	 * in the device control register.
270*2b6a321dSAndrew Duggan 	 */
271*2b6a321dSAndrew Duggan 
272*2b6a321dSAndrew Duggan 	error = rmi_read(rmi_dev, fn->fd.control_base_addr,
273*2b6a321dSAndrew Duggan 			 &f01->device_control.ctrl0);
274*2b6a321dSAndrew Duggan 	if (error) {
275*2b6a321dSAndrew Duggan 		dev_err(&fn->dev, "Failed to read F01 control: %d\n", error);
276*2b6a321dSAndrew Duggan 		return error;
277*2b6a321dSAndrew Duggan 	}
278*2b6a321dSAndrew Duggan 
279*2b6a321dSAndrew Duggan 	switch (pdata->power_management.nosleep) {
280*2b6a321dSAndrew Duggan 	case RMI_F01_NOSLEEP_DEFAULT:
281*2b6a321dSAndrew Duggan 		break;
282*2b6a321dSAndrew Duggan 	case RMI_F01_NOSLEEP_OFF:
283*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 &= ~RMI_F01_CRTL0_NOSLEEP_BIT;
284*2b6a321dSAndrew Duggan 		break;
285*2b6a321dSAndrew Duggan 	case RMI_F01_NOSLEEP_ON:
286*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
287*2b6a321dSAndrew Duggan 		break;
288*2b6a321dSAndrew Duggan 	}
289*2b6a321dSAndrew Duggan 
290*2b6a321dSAndrew Duggan 	/*
291*2b6a321dSAndrew Duggan 	 * Sleep mode might be set as a hangover from a system crash or
292*2b6a321dSAndrew Duggan 	 * reboot without power cycle.  If so, clear it so the sensor
293*2b6a321dSAndrew Duggan 	 * is certain to function.
294*2b6a321dSAndrew Duggan 	 */
295*2b6a321dSAndrew Duggan 	if ((f01->device_control.ctrl0 & RMI_F01_CTRL0_SLEEP_MODE_MASK) !=
296*2b6a321dSAndrew Duggan 			RMI_SLEEP_MODE_NORMAL) {
297*2b6a321dSAndrew Duggan 		dev_warn(&fn->dev,
298*2b6a321dSAndrew Duggan 			 "WARNING: Non-zero sleep mode found. Clearing...\n");
299*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
300*2b6a321dSAndrew Duggan 	}
301*2b6a321dSAndrew Duggan 
302*2b6a321dSAndrew Duggan 	f01->device_control.ctrl0 |= RMI_F01_CRTL0_CONFIGURED_BIT;
303*2b6a321dSAndrew Duggan 
304*2b6a321dSAndrew Duggan 	error = rmi_write(rmi_dev, fn->fd.control_base_addr,
305*2b6a321dSAndrew Duggan 			  f01->device_control.ctrl0);
306*2b6a321dSAndrew Duggan 	if (error) {
307*2b6a321dSAndrew Duggan 		dev_err(&fn->dev, "Failed to write F01 control: %d\n", error);
308*2b6a321dSAndrew Duggan 		return error;
309*2b6a321dSAndrew Duggan 	}
310*2b6a321dSAndrew Duggan 
311*2b6a321dSAndrew Duggan 	/* Dummy read in order to clear irqs */
312*2b6a321dSAndrew Duggan 	error = rmi_read(rmi_dev, fn->fd.data_base_addr + 1, &temp);
313*2b6a321dSAndrew Duggan 	if (error < 0) {
314*2b6a321dSAndrew Duggan 		dev_err(&fn->dev, "Failed to read Interrupt Status.\n");
315*2b6a321dSAndrew Duggan 		return error;
316*2b6a321dSAndrew Duggan 	}
317*2b6a321dSAndrew Duggan 
318*2b6a321dSAndrew Duggan 	error = rmi_f01_read_properties(rmi_dev, fn->fd.query_base_addr,
319*2b6a321dSAndrew Duggan 					&f01->properties);
320*2b6a321dSAndrew Duggan 	if (error < 0) {
321*2b6a321dSAndrew Duggan 		dev_err(&fn->dev, "Failed to read F01 properties.\n");
322*2b6a321dSAndrew Duggan 		return error;
323*2b6a321dSAndrew Duggan 	}
324*2b6a321dSAndrew Duggan 
325*2b6a321dSAndrew Duggan 	dev_info(&fn->dev, "found RMI device, manufacturer: %s, product: %s, fw id: %d\n",
326*2b6a321dSAndrew Duggan 		 f01->properties.manufacturer_id == 1 ? "Synaptics" : "unknown",
327*2b6a321dSAndrew Duggan 		 f01->properties.product_id, f01->properties.firmware_id);
328*2b6a321dSAndrew Duggan 
329*2b6a321dSAndrew Duggan 	/* Advance to interrupt control registers, then skip over them. */
330*2b6a321dSAndrew Duggan 	ctrl_base_addr++;
331*2b6a321dSAndrew Duggan 	ctrl_base_addr += f01->num_of_irq_regs;
332*2b6a321dSAndrew Duggan 
333*2b6a321dSAndrew Duggan 	/* read control register */
334*2b6a321dSAndrew Duggan 	if (f01->properties.has_adjustable_doze) {
335*2b6a321dSAndrew Duggan 		f01->doze_interval_addr = ctrl_base_addr;
336*2b6a321dSAndrew Duggan 		ctrl_base_addr++;
337*2b6a321dSAndrew Duggan 
338*2b6a321dSAndrew Duggan 		if (pdata->power_management.doze_interval) {
339*2b6a321dSAndrew Duggan 			f01->device_control.doze_interval =
340*2b6a321dSAndrew Duggan 				pdata->power_management.doze_interval;
341*2b6a321dSAndrew Duggan 			error = rmi_write(rmi_dev, f01->doze_interval_addr,
342*2b6a321dSAndrew Duggan 					  f01->device_control.doze_interval);
343*2b6a321dSAndrew Duggan 			if (error) {
344*2b6a321dSAndrew Duggan 				dev_err(&fn->dev,
345*2b6a321dSAndrew Duggan 					"Failed to configure F01 doze interval register: %d\n",
346*2b6a321dSAndrew Duggan 					error);
347*2b6a321dSAndrew Duggan 				return error;
348*2b6a321dSAndrew Duggan 			}
349*2b6a321dSAndrew Duggan 		} else {
350*2b6a321dSAndrew Duggan 			error = rmi_read(rmi_dev, f01->doze_interval_addr,
351*2b6a321dSAndrew Duggan 					 &f01->device_control.doze_interval);
352*2b6a321dSAndrew Duggan 			if (error) {
353*2b6a321dSAndrew Duggan 				dev_err(&fn->dev,
354*2b6a321dSAndrew Duggan 					"Failed to read F01 doze interval register: %d\n",
355*2b6a321dSAndrew Duggan 					error);
356*2b6a321dSAndrew Duggan 				return error;
357*2b6a321dSAndrew Duggan 			}
358*2b6a321dSAndrew Duggan 		}
359*2b6a321dSAndrew Duggan 
360*2b6a321dSAndrew Duggan 		f01->wakeup_threshold_addr = ctrl_base_addr;
361*2b6a321dSAndrew Duggan 		ctrl_base_addr++;
362*2b6a321dSAndrew Duggan 
363*2b6a321dSAndrew Duggan 		if (pdata->power_management.wakeup_threshold) {
364*2b6a321dSAndrew Duggan 			f01->device_control.wakeup_threshold =
365*2b6a321dSAndrew Duggan 				pdata->power_management.wakeup_threshold;
366*2b6a321dSAndrew Duggan 			error = rmi_write(rmi_dev, f01->wakeup_threshold_addr,
367*2b6a321dSAndrew Duggan 					  f01->device_control.wakeup_threshold);
368*2b6a321dSAndrew Duggan 			if (error) {
369*2b6a321dSAndrew Duggan 				dev_err(&fn->dev,
370*2b6a321dSAndrew Duggan 					"Failed to configure F01 wakeup threshold register: %d\n",
371*2b6a321dSAndrew Duggan 					error);
372*2b6a321dSAndrew Duggan 				return error;
373*2b6a321dSAndrew Duggan 			}
374*2b6a321dSAndrew Duggan 		} else {
375*2b6a321dSAndrew Duggan 			error = rmi_read(rmi_dev, f01->wakeup_threshold_addr,
376*2b6a321dSAndrew Duggan 					 &f01->device_control.wakeup_threshold);
377*2b6a321dSAndrew Duggan 			if (error < 0) {
378*2b6a321dSAndrew Duggan 				dev_err(&fn->dev,
379*2b6a321dSAndrew Duggan 					"Failed to read F01 wakeup threshold register: %d\n",
380*2b6a321dSAndrew Duggan 					error);
381*2b6a321dSAndrew Duggan 				return error;
382*2b6a321dSAndrew Duggan 			}
383*2b6a321dSAndrew Duggan 		}
384*2b6a321dSAndrew Duggan 	}
385*2b6a321dSAndrew Duggan 
386*2b6a321dSAndrew Duggan 	if (f01->properties.has_lts)
387*2b6a321dSAndrew Duggan 		ctrl_base_addr++;
388*2b6a321dSAndrew Duggan 
389*2b6a321dSAndrew Duggan 	if (f01->properties.has_adjustable_doze_holdoff) {
390*2b6a321dSAndrew Duggan 		f01->doze_holdoff_addr = ctrl_base_addr;
391*2b6a321dSAndrew Duggan 		ctrl_base_addr++;
392*2b6a321dSAndrew Duggan 
393*2b6a321dSAndrew Duggan 		if (pdata->power_management.doze_holdoff) {
394*2b6a321dSAndrew Duggan 			f01->device_control.doze_holdoff =
395*2b6a321dSAndrew Duggan 				pdata->power_management.doze_holdoff;
396*2b6a321dSAndrew Duggan 			error = rmi_write(rmi_dev, f01->doze_holdoff_addr,
397*2b6a321dSAndrew Duggan 					  f01->device_control.doze_holdoff);
398*2b6a321dSAndrew Duggan 			if (error) {
399*2b6a321dSAndrew Duggan 				dev_err(&fn->dev,
400*2b6a321dSAndrew Duggan 					"Failed to configure F01 doze holdoff register: %d\n",
401*2b6a321dSAndrew Duggan 					error);
402*2b6a321dSAndrew Duggan 				return error;
403*2b6a321dSAndrew Duggan 			}
404*2b6a321dSAndrew Duggan 		} else {
405*2b6a321dSAndrew Duggan 			error = rmi_read(rmi_dev, f01->doze_holdoff_addr,
406*2b6a321dSAndrew Duggan 					 &f01->device_control.doze_holdoff);
407*2b6a321dSAndrew Duggan 			if (error) {
408*2b6a321dSAndrew Duggan 				dev_err(&fn->dev,
409*2b6a321dSAndrew Duggan 					"Failed to read F01 doze holdoff register: %d\n",
410*2b6a321dSAndrew Duggan 					error);
411*2b6a321dSAndrew Duggan 				return error;
412*2b6a321dSAndrew Duggan 			}
413*2b6a321dSAndrew Duggan 		}
414*2b6a321dSAndrew Duggan 	}
415*2b6a321dSAndrew Duggan 
416*2b6a321dSAndrew Duggan 	error = rmi_read(rmi_dev, fn->fd.data_base_addr, &device_status);
417*2b6a321dSAndrew Duggan 	if (error < 0) {
418*2b6a321dSAndrew Duggan 		dev_err(&fn->dev,
419*2b6a321dSAndrew Duggan 			"Failed to read device status: %d\n", error);
420*2b6a321dSAndrew Duggan 		return error;
421*2b6a321dSAndrew Duggan 	}
422*2b6a321dSAndrew Duggan 
423*2b6a321dSAndrew Duggan 	if (RMI_F01_STATUS_UNCONFIGURED(device_status)) {
424*2b6a321dSAndrew Duggan 		dev_err(&fn->dev,
425*2b6a321dSAndrew Duggan 			"Device was reset during configuration process, status: %#02x!\n",
426*2b6a321dSAndrew Duggan 			RMI_F01_STATUS_CODE(device_status));
427*2b6a321dSAndrew Duggan 		return -EINVAL;
428*2b6a321dSAndrew Duggan 	}
429*2b6a321dSAndrew Duggan 
430*2b6a321dSAndrew Duggan 	dev_set_drvdata(&fn->dev, f01);
431*2b6a321dSAndrew Duggan 
432*2b6a321dSAndrew Duggan 	return 0;
433*2b6a321dSAndrew Duggan }
434*2b6a321dSAndrew Duggan 
435*2b6a321dSAndrew Duggan static int rmi_f01_config(struct rmi_function *fn)
436*2b6a321dSAndrew Duggan {
437*2b6a321dSAndrew Duggan 	struct f01_data *f01 = dev_get_drvdata(&fn->dev);
438*2b6a321dSAndrew Duggan 	int error;
439*2b6a321dSAndrew Duggan 
440*2b6a321dSAndrew Duggan 	error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr,
441*2b6a321dSAndrew Duggan 			  f01->device_control.ctrl0);
442*2b6a321dSAndrew Duggan 	if (error) {
443*2b6a321dSAndrew Duggan 		dev_err(&fn->dev,
444*2b6a321dSAndrew Duggan 			"Failed to write device_control register: %d\n", error);
445*2b6a321dSAndrew Duggan 		return error;
446*2b6a321dSAndrew Duggan 	}
447*2b6a321dSAndrew Duggan 
448*2b6a321dSAndrew Duggan 	if (f01->properties.has_adjustable_doze) {
449*2b6a321dSAndrew Duggan 		error = rmi_write(fn->rmi_dev, f01->doze_interval_addr,
450*2b6a321dSAndrew Duggan 				  f01->device_control.doze_interval);
451*2b6a321dSAndrew Duggan 		if (error) {
452*2b6a321dSAndrew Duggan 			dev_err(&fn->dev,
453*2b6a321dSAndrew Duggan 				"Failed to write doze interval: %d\n", error);
454*2b6a321dSAndrew Duggan 			return error;
455*2b6a321dSAndrew Duggan 		}
456*2b6a321dSAndrew Duggan 
457*2b6a321dSAndrew Duggan 		error = rmi_write_block(fn->rmi_dev,
458*2b6a321dSAndrew Duggan 					 f01->wakeup_threshold_addr,
459*2b6a321dSAndrew Duggan 					 &f01->device_control.wakeup_threshold,
460*2b6a321dSAndrew Duggan 					 sizeof(u8));
461*2b6a321dSAndrew Duggan 		if (error) {
462*2b6a321dSAndrew Duggan 			dev_err(&fn->dev,
463*2b6a321dSAndrew Duggan 				"Failed to write wakeup threshold: %d\n",
464*2b6a321dSAndrew Duggan 				error);
465*2b6a321dSAndrew Duggan 			return error;
466*2b6a321dSAndrew Duggan 		}
467*2b6a321dSAndrew Duggan 	}
468*2b6a321dSAndrew Duggan 
469*2b6a321dSAndrew Duggan 	if (f01->properties.has_adjustable_doze_holdoff) {
470*2b6a321dSAndrew Duggan 		error = rmi_write(fn->rmi_dev, f01->doze_holdoff_addr,
471*2b6a321dSAndrew Duggan 				  f01->device_control.doze_holdoff);
472*2b6a321dSAndrew Duggan 		if (error) {
473*2b6a321dSAndrew Duggan 			dev_err(&fn->dev,
474*2b6a321dSAndrew Duggan 				"Failed to write doze holdoff: %d\n", error);
475*2b6a321dSAndrew Duggan 			return error;
476*2b6a321dSAndrew Duggan 		}
477*2b6a321dSAndrew Duggan 	}
478*2b6a321dSAndrew Duggan 
479*2b6a321dSAndrew Duggan 	return 0;
480*2b6a321dSAndrew Duggan }
481*2b6a321dSAndrew Duggan 
482*2b6a321dSAndrew Duggan static int rmi_f01_suspend(struct rmi_function *fn)
483*2b6a321dSAndrew Duggan {
484*2b6a321dSAndrew Duggan 	struct f01_data *f01 = dev_get_drvdata(&fn->dev);
485*2b6a321dSAndrew Duggan 	int error;
486*2b6a321dSAndrew Duggan 
487*2b6a321dSAndrew Duggan 	f01->old_nosleep =
488*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 & RMI_F01_CRTL0_NOSLEEP_BIT;
489*2b6a321dSAndrew Duggan 	f01->device_control.ctrl0 &= ~RMI_F01_CRTL0_NOSLEEP_BIT;
490*2b6a321dSAndrew Duggan 
491*2b6a321dSAndrew Duggan 	f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
492*2b6a321dSAndrew Duggan 	if (device_may_wakeup(fn->rmi_dev->xport->dev))
493*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 |= RMI_SLEEP_MODE_RESERVED1;
494*2b6a321dSAndrew Duggan 	else
495*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 |= RMI_SLEEP_MODE_SENSOR_SLEEP;
496*2b6a321dSAndrew Duggan 
497*2b6a321dSAndrew Duggan 	error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr,
498*2b6a321dSAndrew Duggan 			  f01->device_control.ctrl0);
499*2b6a321dSAndrew Duggan 	if (error) {
500*2b6a321dSAndrew Duggan 		dev_err(&fn->dev, "Failed to write sleep mode: %d.\n", error);
501*2b6a321dSAndrew Duggan 		if (f01->old_nosleep)
502*2b6a321dSAndrew Duggan 			f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
503*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
504*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL;
505*2b6a321dSAndrew Duggan 		return error;
506*2b6a321dSAndrew Duggan 	}
507*2b6a321dSAndrew Duggan 
508*2b6a321dSAndrew Duggan 	return 0;
509*2b6a321dSAndrew Duggan }
510*2b6a321dSAndrew Duggan 
511*2b6a321dSAndrew Duggan static int rmi_f01_resume(struct rmi_function *fn)
512*2b6a321dSAndrew Duggan {
513*2b6a321dSAndrew Duggan 	struct f01_data *f01 = dev_get_drvdata(&fn->dev);
514*2b6a321dSAndrew Duggan 	int error;
515*2b6a321dSAndrew Duggan 
516*2b6a321dSAndrew Duggan 	if (f01->old_nosleep)
517*2b6a321dSAndrew Duggan 		f01->device_control.ctrl0 |= RMI_F01_CRTL0_NOSLEEP_BIT;
518*2b6a321dSAndrew Duggan 
519*2b6a321dSAndrew Duggan 	f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK;
520*2b6a321dSAndrew Duggan 	f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL;
521*2b6a321dSAndrew Duggan 
522*2b6a321dSAndrew Duggan 	error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr,
523*2b6a321dSAndrew Duggan 			  f01->device_control.ctrl0);
524*2b6a321dSAndrew Duggan 	if (error) {
525*2b6a321dSAndrew Duggan 		dev_err(&fn->dev,
526*2b6a321dSAndrew Duggan 			"Failed to restore normal operation: %d.\n", error);
527*2b6a321dSAndrew Duggan 		return error;
528*2b6a321dSAndrew Duggan 	}
529*2b6a321dSAndrew Duggan 
530*2b6a321dSAndrew Duggan 	return 0;
531*2b6a321dSAndrew Duggan }
532*2b6a321dSAndrew Duggan 
533*2b6a321dSAndrew Duggan static int rmi_f01_attention(struct rmi_function *fn,
534*2b6a321dSAndrew Duggan 			     unsigned long *irq_bits)
535*2b6a321dSAndrew Duggan {
536*2b6a321dSAndrew Duggan 	struct rmi_device *rmi_dev = fn->rmi_dev;
537*2b6a321dSAndrew Duggan 	int error;
538*2b6a321dSAndrew Duggan 	u8 device_status;
539*2b6a321dSAndrew Duggan 
540*2b6a321dSAndrew Duggan 	error = rmi_read(rmi_dev, fn->fd.data_base_addr, &device_status);
541*2b6a321dSAndrew Duggan 	if (error) {
542*2b6a321dSAndrew Duggan 		dev_err(&fn->dev,
543*2b6a321dSAndrew Duggan 			"Failed to read device status: %d.\n", error);
544*2b6a321dSAndrew Duggan 		return error;
545*2b6a321dSAndrew Duggan 	}
546*2b6a321dSAndrew Duggan 
547*2b6a321dSAndrew Duggan 	if (RMI_F01_STATUS_UNCONFIGURED(device_status)) {
548*2b6a321dSAndrew Duggan 		dev_warn(&fn->dev, "Device reset detected.\n");
549*2b6a321dSAndrew Duggan 		error = rmi_dev->driver->reset_handler(rmi_dev);
550*2b6a321dSAndrew Duggan 		if (error) {
551*2b6a321dSAndrew Duggan 			dev_err(&fn->dev, "Device reset failed: %d\n", error);
552*2b6a321dSAndrew Duggan 			return error;
553*2b6a321dSAndrew Duggan 		}
554*2b6a321dSAndrew Duggan 	}
555*2b6a321dSAndrew Duggan 
556*2b6a321dSAndrew Duggan 	return 0;
557*2b6a321dSAndrew Duggan }
558*2b6a321dSAndrew Duggan 
559*2b6a321dSAndrew Duggan struct rmi_function_handler rmi_f01_handler = {
560*2b6a321dSAndrew Duggan 	.driver = {
561*2b6a321dSAndrew Duggan 		.name	= "rmi4_f01",
562*2b6a321dSAndrew Duggan 		/*
563*2b6a321dSAndrew Duggan 		 * Do not allow user unbinding F01 as it is critical
564*2b6a321dSAndrew Duggan 		 * function.
565*2b6a321dSAndrew Duggan 		 */
566*2b6a321dSAndrew Duggan 		.suppress_bind_attrs = true,
567*2b6a321dSAndrew Duggan 	},
568*2b6a321dSAndrew Duggan 	.func		= 0x01,
569*2b6a321dSAndrew Duggan 	.probe		= rmi_f01_probe,
570*2b6a321dSAndrew Duggan 	.config		= rmi_f01_config,
571*2b6a321dSAndrew Duggan 	.attention	= rmi_f01_attention,
572*2b6a321dSAndrew Duggan 	.suspend	= rmi_f01_suspend,
573*2b6a321dSAndrew Duggan 	.resume		= rmi_f01_resume,
574*2b6a321dSAndrew Duggan };
575