6
6
* Copyright (c) 2023 Hans de Goede <hdegoede@redhat.com>
7
7
*/
8
8
9
+ #include <drm/drm_panel.h>
9
10
#include <linux/delay.h>
10
11
#include <linux/gpio/consumer.h>
11
12
#include <linux/interrupt.h>
14
15
#include <linux/input/mt.h>
15
16
#include <linux/input/touchscreen.h>
16
17
#include <linux/module.h>
17
-
18
18
#include <linux/unaligned.h>
19
19
20
20
#define NVT_TS_TOUCH_START 0x00
@@ -61,6 +61,12 @@ struct nvt_ts_data {
61
61
struct touchscreen_properties prop ;
62
62
int max_touches ;
63
63
u8 buf [NVT_TS_TOUCH_SIZE * NVT_TS_MAX_TOUCHES ];
64
+ /*
65
+ * Sometimes Novatek touchscreen is paired together with Novatek panel,
66
+ * and they need to be powered together in sync.
67
+ */
68
+ struct drm_panel_follower panel_follower ;
69
+ bool is_panel_follower ;
64
70
};
65
71
66
72
static int nvt_ts_read_data (struct i2c_client * client , u8 reg , u8 * data , int count )
@@ -97,6 +103,9 @@ static irqreturn_t nvt_ts_irq(int irq, void *dev_id)
97
103
bool active ;
98
104
u8 * touch ;
99
105
106
+ if (!data -> input )
107
+ return IRQ_HANDLED ;
108
+
100
109
error = nvt_ts_read_data (data -> client , NVT_TS_TOUCH_START , data -> buf ,
101
110
data -> max_touches * NVT_TS_TOUCH_SIZE );
102
111
if (error )
@@ -155,6 +164,7 @@ static int nvt_ts_start(struct input_dev *dev)
155
164
156
165
enable_irq (data -> client -> irq );
157
166
gpiod_set_value_cansleep (data -> reset_gpio , 0 );
167
+ msleep (100 ); // TODO: is it really needed? probably
158
168
159
169
return 0 ;
160
170
}
@@ -172,6 +182,9 @@ static int nvt_ts_suspend(struct device *dev)
172
182
{
173
183
struct nvt_ts_data * data = i2c_get_clientdata (to_i2c_client (dev ));
174
184
185
+ if (data -> is_panel_follower )
186
+ return 0 ;
187
+
175
188
mutex_lock (& data -> input -> mutex );
176
189
if (input_device_enabled (data -> input ))
177
190
nvt_ts_stop (data -> input );
@@ -184,6 +197,9 @@ static int nvt_ts_resume(struct device *dev)
184
197
{
185
198
struct nvt_ts_data * data = i2c_get_clientdata (to_i2c_client (dev ));
186
199
200
+ if (data -> is_panel_follower )
201
+ return 0 ;
202
+
187
203
mutex_lock (& data -> input -> mutex );
188
204
if (input_device_enabled (data -> input ))
189
205
nvt_ts_start (data -> input );
@@ -192,32 +208,17 @@ static int nvt_ts_resume(struct device *dev)
192
208
return 0 ;
193
209
}
194
210
195
- static DEFINE_SIMPLE_DEV_PM_OPS (nvt_ts_pm_ops , nvt_ts_suspend , nvt_ts_resume ) ;
196
-
197
- static int nvt_ts_probe (struct i2c_client * client )
211
+ static int nvt_ts_initial_power_on_and_register_inputdev (struct nvt_ts_data * data )
198
212
{
199
- struct device * dev = & client -> dev ;
213
+ struct device * dev = & data -> client -> dev ;
200
214
int error , width , height , irq_type ;
201
- struct nvt_ts_data * data ;
202
215
const struct nvt_ts_i2c_chip_data * chip ;
203
216
struct input_dev * input ;
204
217
205
- if (!client -> irq ) {
206
- dev_err (dev , "Error no irq specified\n" );
207
- return - EINVAL ;
208
- }
209
-
210
- data = devm_kzalloc (dev , sizeof (* data ), GFP_KERNEL );
211
- if (!data )
212
- return - ENOMEM ;
213
-
214
- chip = device_get_match_data (& client -> dev );
218
+ chip = device_get_match_data (dev );
215
219
if (!chip )
216
220
return - EINVAL ;
217
221
218
- data -> client = client ;
219
- i2c_set_clientdata (client , data );
220
-
221
222
/*
222
223
* VCC is the analog voltage supply
223
224
* IOVCC is the digital voltage supply
@@ -278,7 +279,7 @@ static int nvt_ts_probe(struct i2c_client *client)
278
279
if (!input )
279
280
return - ENOMEM ;
280
281
281
- input -> name = client -> name ;
282
+ input -> name = data -> client -> name ;
282
283
input -> id .bustype = BUS_I2C ;
283
284
input -> open = nvt_ts_start ;
284
285
input -> close = nvt_ts_stop ;
@@ -295,10 +296,11 @@ static int nvt_ts_probe(struct i2c_client *client)
295
296
data -> input = input ;
296
297
input_set_drvdata (input , data );
297
298
298
- error = devm_request_threaded_irq (dev , client -> irq , NULL , nvt_ts_irq ,
299
+ error = devm_request_threaded_irq (dev , data -> client -> irq , NULL ,
300
+ nvt_ts_irq ,
299
301
IRQF_ONESHOT | IRQF_NO_AUTOEN |
300
302
nvt_ts_irq_type [irq_type ],
301
- client -> name , data );
303
+ data -> client -> name , data );
302
304
if (error ) {
303
305
dev_err (dev , "failed to request irq: %d\n" , error );
304
306
return error ;
@@ -313,6 +315,91 @@ static int nvt_ts_probe(struct i2c_client *client)
313
315
return 0 ;
314
316
}
315
317
318
+ static int on_novatek_panel_prepared (struct drm_panel_follower * follower )
319
+ {
320
+ struct nvt_ts_data * data = container_of (follower , struct nvt_ts_data , panel_follower );
321
+ int ret ;
322
+ dev_info (& data -> client -> dev , "%s\n" , __func__ ); // REMOVEME
323
+
324
+ /* Is this the first power on? */
325
+ if (!data -> input ) {
326
+ dev_info (& data -> client -> dev , "doing initial power on\n" ); // REMOVEME
327
+ ret = nvt_ts_initial_power_on_and_register_inputdev (data );
328
+ if (ret )
329
+ return ret ;
330
+ }
331
+
332
+ mutex_lock (& data -> input -> mutex );
333
+ if (input_device_enabled (data -> input ))
334
+ nvt_ts_start (data -> input );
335
+ mutex_unlock (& data -> input -> mutex );
336
+
337
+ return 0 ;
338
+ }
339
+
340
+ static int on_novatek_panel_unpreparing (struct drm_panel_follower * follower )
341
+ {
342
+ struct nvt_ts_data * data = container_of (follower , struct nvt_ts_data , panel_follower );
343
+ dev_info (& data -> client -> dev , "%s\n" , __func__ ); // REMOVEME
344
+
345
+ mutex_lock (& data -> input -> mutex );
346
+ if (input_device_enabled (data -> input ))
347
+ nvt_ts_stop (data -> input );
348
+ mutex_unlock (& data -> input -> mutex );
349
+
350
+ return 0 ;
351
+ }
352
+
353
+ static const struct drm_panel_follower_funcs nvt_ts_follower_funcs = {
354
+ .panel_prepared = on_novatek_panel_prepared ,
355
+ .panel_unpreparing = on_novatek_panel_unpreparing ,
356
+ };
357
+
358
+ static DEFINE_SIMPLE_DEV_PM_OPS (nvt_ts_pm_ops , nvt_ts_suspend , nvt_ts_resume ) ;
359
+
360
+ static int nvt_ts_probe (struct i2c_client * client )
361
+ {
362
+ struct device * dev = & client -> dev ;
363
+ struct nvt_ts_data * data ;
364
+
365
+ if (!client -> irq ) {
366
+ dev_err (dev , "Error no irq specified\n" );
367
+ return - EINVAL ;
368
+ }
369
+
370
+ data = devm_kzalloc (dev , sizeof (* data ), GFP_KERNEL );
371
+ if (!data )
372
+ return - ENOMEM ;
373
+
374
+ data -> client = client ;
375
+ i2c_set_clientdata (client , data );
376
+
377
+ /* check if "panel = <&...>" is set in DT */
378
+ if (drm_is_panel_follower (dev )) {
379
+ /* register self as follower */
380
+ dev_info (dev , "probing in follower mode\n" ); // REMOVEME
381
+ data -> is_panel_follower = true;
382
+ data -> panel_follower .funcs = & nvt_ts_follower_funcs ;
383
+ drm_panel_add_follower (dev , & data -> panel_follower );
384
+ /*
385
+ * In this mode, we can't do anything more at this moment.
386
+ * Need to wait for callbacks from panel.
387
+ */
388
+ return 0 ;
389
+ }
390
+
391
+ dev_info (dev , "probing in normal mode\n" ); // REMOVEME
392
+ return nvt_ts_initial_power_on_and_register_inputdev (data );
393
+ }
394
+
395
+ static void nvt_ts_remove (struct i2c_client * client )
396
+ {
397
+ struct nvt_ts_data * data = i2c_get_clientdata (client );
398
+
399
+ if (data -> is_panel_follower )
400
+ drm_panel_remove_follower (& data -> panel_follower );
401
+ }
402
+
316
403
static const struct nvt_ts_i2c_chip_data nvt_nt11205_ts_data = {
317
404
.wake_type = 0x05 ,
318
405
.chip_id = 0x05 ,
@@ -344,6 +431,7 @@ static struct i2c_driver nvt_ts_driver = {
344
431
.of_match_table = nvt_ts_of_match ,
345
432
},
346
433
.probe = nvt_ts_probe ,
434
+ .remove = nvt_ts_remove ,
347
435
.id_table = nvt_ts_i2c_id ,
348
436
};
349
437
0 commit comments