1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
4 *
5 * Author: Kay Guo <kay.guo@rock-chips.com>
6 */
7 #include <linux/atomic.h>
8 #include <linux/delay.h>
9 #ifdef CONFIG_HAS_EARLYSUSPEND
10 #include <linux/earlysuspend.h>
11 #endif
12 #include <linux/freezer.h>
13 #include <linux/gpio.h>
14 #include <linux/i2c.h>
15 #include <linux/input.h>
16 #include <linux/interrupt.h>
17 #include <linux/irq.h>
18 #include <linux/miscdevice.h>
19 #include <linux/of_gpio.h>
20 #include <linux/sensor-dev.h>
21 #include <linux/slab.h>
22 #include <linux/uaccess.h>
23 #include <linux/workqueue.h>
24
25 #define SYSM_CTRL 0x00
26 #define INT_CTRL 0x01
27 #define INT_FLAG 0x02
28 #define WAIT_TIME 0x03
29 #define ALS_GAIN 0x04
30 #define ALS_TIME 0x05
31 #define LED_CTRL 0x06
32 #define PS_GAIN 0x07
33 #define PS_PULSE 0x08
34 #define PS_TIME 0x09
35
36 #define PERSISTENCE 0x0B
37 #define ALS_THR_LL 0x0C
38 #define ALS_THR_LH 0x0D
39 #define ALS_THR_HL 0x0E
40 #define ALS_THR_HH 0x0F
41 #define PS_THR_LL 0x10
42 #define PS_THR_LH 0x11
43 #define PS_THR_HL 0x12
44 #define PS_THR_HH 0x13
45 #define PS_OFFSET_L 0x14
46 #define PS_OFFSET_H 0x15
47 #define INT_SOURCE 0x16
48 #define ERROR_FLAG 0x17
49 #define PS_DATA_L 0x18
50 #define PS_DATA_H 0x19
51 #define IR_DATA_L 0x1A
52 #define IR_DATA_H 0x1B
53 #define CH0_DATA_L 0x1C
54 #define CH0_DATA_H 0x1D
55 #define CH1_DATA_L 0x1E
56 #define CH1_DATA_H 0x1F
57
58 /* SYSM_CTRL 0x00 */
59 #define ALS_DISABLE (0 << 0)
60 #define ALS_ENABLE (1 << 0)
61 #define PS_DISABLE (0 << 1)
62 #define PS_ENABLE (1 << 1)
63 #define FRST_DISABLE (0 << 5)
64 #define FRST_ENABLE (1 << 5)
65 #define WAIT_DISABLE (0 << 6)
66 #define WAIT_ENABLE (1 << 6)
67 #define SWRST_START (1 << 7)
68
69 /* INT_CTRL 0x01 */
70 #define AINT_DISABLE (0 << 0)
71 #define AINT_ENABLE (1 << 0)
72 #define PINT_DISABLE (0 << 1)
73 #define PINT_ENABLE (1 << 1)
74 #define ALS_PEND_EN (1 << 4)
75 #define ALS_PEND_DIS (0 << 4)
76 #define PS_PEND_EN (1 << 5)
77 #define PS_PEND_DIS (0 << 5)
78 #define SPEED_UP_EN (1 << 6)
79 #define SPEED_UP_DIS (0 << 6)
80 #define PS_INT_HYS (0 << 7)
81 #define PS_INT_ZONE (1 << 7)
82
83 /* INT_FLAG 0x02 */
84 #define ALS_INT_FLAG (1 << 0)
85 #define PS_INT_FLAG (1 << 1)
86 #define OBJ_DET_FLAG (1 << 5)
87 #define DATA_INVALID (1 << 6)
88 #define POWER_ON_FLAG (1 << 7)
89
90 /* WAIT_TIME 0x03 */
91 #define WAIT_TIME_5MS(X) (X)
92 /* ALS_GAIN 0x04*/
93 #define ALS_GAIN_1 0x00
94 #define ALS_GAIN_4 0x01
95 #define ALS_GAIN_8 0x02
96 #define ALS_GAIN_32 0x03
97 #define ALS_GAIN_96 0x04
98 #define ALS_GAIN_192 0x05
99 #define ALS_GAIN_368 0x06
100
101 /* LED_CTRL */
102 #define IR_12_5MA (0 << 6)
103 #define IR_100MA (1 << 6)
104 #define IR_150MA (2 << 6)
105 #define IR_200MA (3 << 6)
106
107 /* PS_GAIN 0x07 */
108 #define PS_GAIN_1 (1 << 0)
109 #define PS_GAIN_2 (1 << 1)
110 #define PS_GAIN_4 (1 << 2)
111 #define PS_GAIN_8 (1 << 4)
112
113 #define PS_PULSE_NUM(X) (X)
114 #define LED_PULSE_WIDTH (0x0f)
115
116
117 static int ps_threshold_low;
118 static int ps_threshold_high;
119
sensor_active(struct i2c_client * client,int enable,int rate)120 static int sensor_active(struct i2c_client *client, int enable, int rate)
121 {
122 struct sensor_private_data *sensor =
123 (struct sensor_private_data *)i2c_get_clientdata(client);
124 int result = 0;
125 int status = 0;
126
127 sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
128 if (!enable) {
129 status = ~PS_ENABLE;
130 sensor->ops->ctrl_data &= status;
131 } else {
132 status = PS_ENABLE;
133 sensor->ops->ctrl_data |= status;
134 }
135
136 dev_dbg(&client->dev, "reg=0x%x, reg_ctrl=0x%x, enable=%d\n",
137 sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
138
139 result = sensor_write_reg(client, sensor->ops->ctrl_reg,
140 sensor->ops->ctrl_data);
141 if (result)
142 dev_err(&client->dev, "%s:fail to active sensor\n", __func__);
143
144 return result;
145 }
146
sensor_init(struct i2c_client * client)147 static int sensor_init(struct i2c_client *client)
148 {
149 struct sensor_private_data *sensor =
150 (struct sensor_private_data *)i2c_get_clientdata(client);
151 struct device_node *np = client->dev.of_node;
152 int ps_val = 0;
153 int result = 0;
154 int val = 0;
155
156 result = sensor->ops->active(client, 0, 0);
157 if (result) {
158 dev_err(&client->dev, "%s:sensor active fail\n", __func__);
159 return result;
160 }
161 sensor->status_cur = SENSOR_OFF;
162
163 result = of_property_read_u32(np, "ps_threshold_low", &ps_val);
164 if (result)
165 dev_err(&client->dev, "%s:Unable to read ps_threshold_low\n",
166 __func__);
167
168 ps_threshold_low = ps_val;
169 result = sensor_write_reg(client, PS_THR_LH,
170 (unsigned char)(ps_val >> 8));
171 if (result) {
172 dev_err(&client->dev, "%s:write PS_THR_LH fail\n", __func__);
173 return result;
174 }
175 result = sensor_write_reg(client, PS_THR_LL, (unsigned char)ps_val);
176 if (result) {
177 dev_err(&client->dev, "%s:write PS_THR_LL fail\n", __func__);
178 return result;
179 }
180
181 result = of_property_read_u32(np, "ps_threshold_high", &ps_val);
182 if (result)
183 dev_err(&client->dev, "%s:Unable to read ps_threshold_high\n",
184 __func__);
185
186 ps_threshold_high = ps_val;
187 result = sensor_write_reg(client, PS_THR_HH,
188 (unsigned char)(ps_val >> 8));
189 if (result) {
190 dev_err(&client->dev, "%s:write PS_THR_HH fail\n", __func__);
191 return result;
192 }
193
194 result = sensor_write_reg(client, PS_THR_HL, (unsigned char)ps_val);
195 if (result) {
196 dev_err(&client->dev, "%s:write PS_THR_HL fail\n", __func__);
197 return result;
198 }
199
200 result = of_property_read_u32(np, "ps_ctrl_gain", &ps_val);
201 if (result)
202 dev_err(&client->dev, "%s:Unable to read ps_ctrl_gain\n",
203 __func__);
204
205 result = sensor_write_reg(client, PS_GAIN, (unsigned char)ps_val);
206 if (result) {
207 dev_err(&client->dev, "%s:write PS_GAIN fail\n", __func__);
208 return result;
209 }
210
211 result = of_property_read_u32(np, "ps_led_current", &ps_val);
212 if (result)
213 dev_err(&client->dev, "%s:Unable to read ps_led_current\n",
214 __func__);
215
216 result |= sensor_write_reg(client, LED_CTRL,
217 (unsigned char)((ps_val << 6) | LED_PULSE_WIDTH));
218 if (result) {
219 dev_err(&client->dev, "%s:write LED_CTRL fail\n", __func__);
220 return result;
221 }
222
223 val = sensor_read_reg(client, INT_CTRL);
224 if (sensor->pdata->irq_enable) {
225 val |= PINT_ENABLE;
226 val |= PS_PEND_EN;
227 } else {
228 val &= PINT_DISABLE;
229 }
230 result = sensor_write_reg(client, INT_CTRL, val);
231 if (result) {
232 dev_err(&client->dev, "%s:write INT_CTRL fail\n", __func__);
233 return result;
234 }
235
236 return result;
237 }
238
ucs14620_get_ps_value(int ps)239 static int ucs14620_get_ps_value(int ps)
240 {
241 int index = 0;
242 static int value = 1;
243
244 if (ps > ps_threshold_high) {
245 index = 0;
246 value = 0;
247 } else if (ps < ps_threshold_low) {
248 index = 1;
249 value = 1;
250 } else {
251 index = value;
252 }
253
254 return index;
255 }
256
sensor_report_value(struct i2c_client * client)257 static int sensor_report_value(struct i2c_client *client)
258 {
259 struct sensor_private_data *sensor =
260 (struct sensor_private_data *)i2c_get_clientdata(client);
261 int result = 0;
262 int value = 0;
263 char buffer[2] = { 0 };
264 int index = 1;
265
266 if (sensor->ops->read_len < 2) {
267 dev_err(&client->dev, "%s:length is error, len=%d\n", __func__,
268 sensor->ops->read_len);
269 return -EINVAL;
270 }
271
272 buffer[0] = sensor->ops->read_reg;
273 result = sensor_rx_data(client, buffer, sensor->ops->read_len);
274 if (result) {
275 dev_err(&client->dev, "%s:sensor read data fail\n", __func__);
276 return result;
277 }
278 value = (buffer[1] << 8) | buffer[0];
279 if (sensor->pdata->irq_enable && sensor->ops->int_status_reg) {
280 value = sensor_read_reg(client, sensor->ops->int_status_reg);
281 if (value & PS_INT_FLAG)
282 index = 0;
283 else
284 index = 1;
285 input_report_abs(sensor->input_dev, ABS_DISTANCE, index);
286 input_sync(sensor->input_dev);
287 value &= ~PS_INT_FLAG;
288 result = sensor_write_reg(client,
289 sensor->ops->int_status_reg,
290 value);
291
292 dev_dbg(&client->dev, "%s object near = %d", sensor->ops->name, index);
293
294 if (result) {
295 dev_err(&client->dev, "write status reg error\n");
296 return result;
297 }
298 } else if (!sensor->pdata->irq_enable) {
299 index = ucs14620_get_ps_value(value);
300 input_report_abs(sensor->input_dev, ABS_DISTANCE, index);
301 input_sync(sensor->input_dev);
302 dev_dbg(&client->dev, "%s sensor closed=%d\n",
303 sensor->ops->name, index);
304 }
305
306 return result;
307 }
308
309 static struct sensor_operate psensor_ucs14620_ops = {
310 .name = "ps_ucs14620",
311 .type = SENSOR_TYPE_PROXIMITY,
312 .id_i2c = PROXIMITY_ID_UCS14620,
313 .read_reg = PS_DATA_L,
314 .read_len = 2,
315 .id_reg = SENSOR_UNKNOW_DATA,
316 .id_data = SENSOR_UNKNOW_DATA,
317 .precision = 16,
318 .ctrl_reg = SYSM_CTRL,
319 .int_status_reg = INT_FLAG,
320 .range = { 100, 65535 },
321 .brightness = { 10, 255 },
322 .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
323 .active = sensor_active,
324 .init = sensor_init,
325 .report = sensor_report_value,
326 };
327
proximity_ucs14620_probe(struct i2c_client * client,const struct i2c_device_id * devid)328 static int proximity_ucs14620_probe(struct i2c_client *client,
329 const struct i2c_device_id *devid)
330 {
331 return sensor_register_device(client, NULL, devid, &psensor_ucs14620_ops);
332 }
333
proximity_ucs14620_remove(struct i2c_client * client)334 static int proximity_ucs14620_remove(struct i2c_client *client)
335 {
336 return sensor_unregister_device(client, NULL, &psensor_ucs14620_ops);
337 }
338
339 static const struct i2c_device_id proximity_ucs14620_id[] = {
340 { "ps_ucs14620", PROXIMITY_ID_UCS14620 },
341 {}
342 };
343
344 static struct i2c_driver proximity_ucs14620_driver = {
345 .probe = proximity_ucs14620_probe,
346 .remove = proximity_ucs14620_remove,
347 .shutdown = sensor_shutdown,
348 .id_table = proximity_ucs14620_id,
349 .driver = {
350 .name = "ps_ucs14620",
351 #ifdef CONFIG_PM
352 .pm = &sensor_pm_ops,
353 #endif
354 },
355 };
356
357 module_i2c_driver(proximity_ucs14620_driver);
358
359 MODULE_AUTHOR("Kay Guo<yangbin@rock-chips.com>");
360 MODULE_DESCRIPTION("ucs14620 proximity driver");
361 MODULE_LICENSE("GPL");
362