xref: /OK3568_Linux_fs/kernel/drivers/input/sensors/psensor/ps_em3071x.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * kernel/drivers/input/sensors/psensor/ps_em3071x.c
4  *
5  * Copyright (C) 2020 Rockchip Co.,Ltd.
6  * Author: Wang Jie <dave.wang@rock-chips.com>
7  */
8 
9 #include <linux/interrupt.h>
10 #include <linux/i2c.h>
11 #include <linux/slab.h>
12 #include <linux/irq.h>
13 #include <linux/miscdevice.h>
14 #include <linux/gpio.h>
15 #include <linux/uaccess.h>
16 #include <linux/atomic.h>
17 #include <linux/delay.h>
18 #include <linux/input.h>
19 #include <linux/workqueue.h>
20 #include <linux/freezer.h>
21 #include <linux/of_gpio.h>
22 #ifdef CONFIG_HAS_EARLYSUSPEND
23 #include <linux/earlysuspend.h>
24 #endif
25 #include <linux/sensor-dev.h>
26 
27 #define EM3071X_CONFIG_REG		0x01
28 #define EM3071X_INT_REG			0x02
29 #define EM3071X_PS_L_REG		0x03
30 #define EM3071X_PS_H_REG		0x04
31 #define EM3071X_PS_REG			0x08
32 #define EM3071X_INT_PMASK		0x80
33 #define EM3071X_PS_OFFSET		0x0F
34 
35 #define EM3071X_PS_CONFIG		0xB0
36 /* #define ps_threshold_low		0x30 */
37 /* #define ps_threshold_high		0x40 */
38 #define EM3071X_INT_CLEAR		0x00
39 
40 static int ps_threshold_low;
41 static int ps_threshold_high;
42 
em3071x_get_object(struct i2c_client * client)43 static int em3071x_get_object(struct i2c_client *client)
44 {
45 	int index = 0;
46 	int val;
47 
48 	val = sensor_read_reg(client, EM3071X_PS_REG);
49 
50 	if (val >= ps_threshold_high) {
51 		index = 0;
52 		val = 0;
53 	} else if (val <= ps_threshold_low) {
54 		index = 1;
55 		val = 1;
56 	} else {
57 		index = val;
58 	}
59 
60 	dev_dbg(&client->dev,
61 		 "%s: val = 0x%x, index = %d\n", __func__, val, index);
62 
63 	return index;
64 }
65 
sensor_active(struct i2c_client * client,int enable,int rate)66 static int sensor_active(struct i2c_client *client, int enable, int rate)
67 {
68 	struct sensor_private_data *sensor =
69 		(struct sensor_private_data *) i2c_get_clientdata(client);
70 	int result = 0;
71 	int status = 0;
72 
73 	sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
74 	if (enable) {
75 		status = EM3071X_PS_CONFIG;
76 		sensor->ops->ctrl_data |= status;
77 	} else {
78 		status = ~EM3071X_PS_CONFIG;
79 		sensor->ops->ctrl_data &= status;
80 	}
81 
82 	result = sensor_write_reg(client, sensor->ops->ctrl_reg,
83 						sensor->ops->ctrl_data);
84 	if (result)
85 		dev_err(&client->dev, "%s: fail to active sensor\n", __func__);
86 
87 	return result;
88 
89 }
90 
em3071x_set_threshold(struct i2c_client * client,int threshold_high,int threshold_low)91 static int em3071x_set_threshold(struct i2c_client *client,
92 				 int threshold_high, int threshold_low)
93 {
94 	int result = 0;
95 
96 	result = sensor_write_reg(client, EM3071X_PS_L_REG, threshold_low);
97 	if (result) {
98 		dev_err(&client->dev,
99 			"%s: fail to write EM3071X_PS_L_REG(%d)\n",
100 			__func__, result);
101 		return result;
102 	}
103 
104 	result = sensor_write_reg(client, EM3071X_PS_H_REG, threshold_high);
105 	if (result) {
106 		dev_err(&client->dev,
107 			"%s: fail to write EM3071X_PS_H_REG(%d)\n",
108 			__func__, result);
109 		return result;
110 	}
111 
112 	dev_dbg(&client->dev,
113 		"%s: set threshold_high = %d, set threshold_low = %d\n",
114 		__func__, threshold_high, threshold_low);
115 	return result;
116 }
117 
sensor_init(struct i2c_client * client)118 static int sensor_init(struct i2c_client *client)
119 {
120 	struct sensor_private_data *sensor =
121 		(struct sensor_private_data *) i2c_get_clientdata(client);
122 	struct device_node *np = client->dev.of_node;
123 	int ps_val = 0;
124 	int ret = 0;
125 	int result = 0;
126 
127 	result = sensor->ops->active(client, 0, 0);
128 	if (result) {
129 		dev_err(&client->dev, "%s: line = %d, result = %d.\n",
130 			__func__, __LINE__, result);
131 		return result;
132 	}
133 	sensor->status_cur = SENSOR_OFF;
134 
135 	/* initialize the EM3071X chip */
136 	result = sensor_write_reg(client, EM3071X_CONFIG_REG, 0X00);
137 	if (result) {
138 		dev_err(&client->dev,
139 			"%s: write EM3071X_CONFIG_REG reg fail(%d)\n",
140 			__func__, result);
141 		return result;
142 	}
143 
144 	result = sensor_write_reg(client, EM3071X_INT_REG, EM3071X_INT_CLEAR);
145 	if (result) {
146 		dev_err(&client->dev,
147 			"%s: write EM3071X_INT_REG reg fail(%d)\n",
148 			__func__, result);
149 		return result;
150 	}
151 
152 	result = sensor_write_reg(client, EM3071X_PS_OFFSET, 0X00);
153 	if (result) {
154 		dev_err(&client->dev,
155 			"%s: write EM3071X_PS_OFFSET reg fail(%d)\n",
156 			__func__, result);
157 		return result;
158 	}
159 
160 	ret = of_property_read_u32(np, "ps_threshold_low", &ps_val);
161 	if (ret)
162 		dev_warn(&client->dev,
163 			"%s: Unable to get ps_threshold_low\n", __func__);
164 
165 	ps_threshold_low = ps_val;
166 
167 	ret = of_property_read_u32(np, "ps_threshold_high", &ps_val);
168 	if (ret)
169 		dev_warn(&client->dev,
170 			"%s: Unable to get ps_threshold_high\n", __func__);
171 
172 	ps_threshold_high = ps_val;
173 
174 	ret = em3071x_set_threshold(client,
175 				    ps_threshold_high, ps_threshold_low);
176 	if (ret)
177 		dev_err(&client->dev,
178 			"%s: em3071x set threshold failed\n", __func__);
179 
180 	return result;
181 }
182 
em3071x_get_status(struct i2c_client * client)183 static int em3071x_get_status(struct i2c_client *client)
184 {
185 	struct sensor_private_data *sensor =
186 		(struct sensor_private_data *) i2c_get_clientdata(client);
187 	int val;
188 
189 	val = sensor_read_reg(client, sensor->ops->int_status_reg);
190 	val &= 0x80;
191 
192 	return val;
193 }
194 
sensor_report_value(struct i2c_client * client)195 static int sensor_report_value(struct i2c_client *client)
196 {
197 	struct sensor_private_data *sensor =
198 	    (struct sensor_private_data *) i2c_get_clientdata(client);
199 	int result = 0;
200 	char value = 0;
201 	u8 status;
202 
203 	status = em3071x_get_status(client);
204 	dev_dbg(&client->dev, "em3071x_get_status: status = 0x%x\n", status);
205 
206 	if (sensor->pdata->irq_enable) {
207 		if (status & EM3071X_INT_PMASK) {
208 			result = sensor_write_reg(client, EM3071X_INT_REG, 0x00);
209 			if (result) {
210 				dev_err(&client->dev,
211 					"%s: write EM3071X_INT_REG reg fail(%d)\n", __func__, result);
212 				return result;
213 			}
214 
215 			value = em3071x_get_object(client);
216 			input_report_abs(sensor->input_dev, ABS_DISTANCE, value);
217 			input_sync(sensor->input_dev);
218 		}
219 	} else {
220 		value = em3071x_get_object(client);
221 		input_report_abs(sensor->input_dev, ABS_DISTANCE, value);
222 		input_sync(sensor->input_dev);
223 	}
224 
225 	return result;
226 }
227 
228 static struct sensor_operate psensor_em3071x_ops = {
229 	.name		= "ps_em3071x",
230 	.type		= SENSOR_TYPE_PROXIMITY,
231 	.id_i2c		= PROXIMITY_ID_EM3071X,
232 	.read_reg	= SENSOR_UNKNOW_DATA,
233 	.read_len	= 1,
234 	.id_reg		= 0,
235 	.id_data	= 0x31,
236 	.precision	= 8,
237 	.ctrl_reg	= 0x01,
238 	.int_status_reg = 0x02,
239 	.range		= {0, 10},
240 	.brightness	= {10, 255},
241 	.trig		= IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
242 	.active		= sensor_active,
243 	.init		= sensor_init,
244 	.report		= sensor_report_value,
245 };
246 
proximity_em3071x_probe(struct i2c_client * client,const struct i2c_device_id * devid)247 static int proximity_em3071x_probe(struct i2c_client *client,
248 				   const struct i2c_device_id *devid)
249 {
250 	return sensor_register_device(client, NULL, devid, &psensor_em3071x_ops);
251 }
252 
proximity_em3071x_remove(struct i2c_client * client)253 static int proximity_em3071x_remove(struct i2c_client *client)
254 {
255 	return sensor_unregister_device(client, NULL, &psensor_em3071x_ops);
256 }
257 
258 static const struct i2c_device_id proximity_em3071x_id[] = {
259 	{"ps_em3071x", PROXIMITY_ID_EM3071X},
260 	{}
261 };
262 
263 static struct i2c_driver proximity_em3071x_driver = {
264 	.probe = proximity_em3071x_probe,
265 	.remove = proximity_em3071x_remove,
266 	.shutdown = sensor_shutdown,
267 	.id_table = proximity_em3071x_id,
268 	.driver = {
269 		.name = "proximity_em3071x",
270 #ifdef CONFIG_PM
271 		.pm = &sensor_pm_ops,
272 #endif
273 	},
274 };
275 
276 module_i2c_driver(proximity_em3071x_driver);
277 
278 MODULE_AUTHOR("Wang Jie <dave.wang@rock-chips.com>");
279 MODULE_DESCRIPTION("em3071x proximity driver");
280 MODULE_LICENSE("GPL");
281