1
1
/*
2
2
* Driver for memory based ft5406 touchscreen
3
3
*
4
- * Copyright (C) 2015 Raspberry Pi
4
+ * Copyright (C) 2015, 2017 Raspberry Pi
5
5
*
6
6
*
7
7
* This program is free software; you can redistribute it and/or modify
26
26
#include <soc/bcm2835/raspberrypi-firmware.h>
27
27
28
28
#define MAXIMUM_SUPPORTED_POINTS 10
29
+
29
30
struct ft5406_regs {
30
31
uint8_t device_mode ;
31
32
uint8_t gesture_id ;
@@ -40,15 +41,22 @@ struct ft5406_regs {
40
41
} point [MAXIMUM_SUPPORTED_POINTS ];
41
42
};
42
43
43
- #define SCREEN_WIDTH 800
44
- #define SCREEN_HEIGHT 480
44
+ // These are defaults if the DT entries are missing.
45
+ #define DEFAULT_SCREEN_WIDTH 800
46
+ #define DEFAULT_SCREEN_HEIGHT 480
45
47
46
48
struct ft5406 {
47
- struct platform_device * pdev ;
48
- struct input_dev * input_dev ;
49
- void __iomem * ts_base ;
50
- dma_addr_t bus_addr ;
51
- struct task_struct * thread ;
49
+ struct platform_device * pdev ;
50
+ struct input_dev * input_dev ;
51
+ void __iomem * ts_base ;
52
+ dma_addr_t bus_addr ;
53
+ struct task_struct * thread ;
54
+
55
+ uint16_t max_x ;
56
+ uint16_t max_y ;
57
+ uint8_t hflip ;
58
+ uint8_t vflip ;
59
+ uint8_t xyswap ;
52
60
};
53
61
54
62
/* Thread to poll for touchscreen events
@@ -81,12 +89,21 @@ static int ft5406_thread(void *arg)
81
89
int x = (((int ) regs .point [i ].xh & 0xf ) << 8 ) + regs .point [i ].xl ;
82
90
int y = (((int ) regs .point [i ].yh & 0xf ) << 8 ) + regs .point [i ].yl ;
83
91
int touchid = (regs .point [i ].yh >> 4 ) & 0xf ;
84
-
92
+
85
93
modified_ids |= 1 << touchid ;
86
94
95
+ if (ts -> hflip )
96
+ x = ts -> max_x - 1 - x ;
97
+
98
+ if (ts -> vflip )
99
+ y = ts -> max_y - 1 - y ;
100
+
101
+ if (ts -> xyswap )
102
+ swap (x ,y );
103
+
87
104
if (!((1 << touchid ) & known_ids ))
88
105
dev_dbg (& ts -> pdev -> dev , "x = %d, y = %d, touchid = %d\n" , x , y , touchid );
89
-
106
+
90
107
input_mt_slot (ts -> input_dev , touchid );
91
108
input_mt_report_slot_state (ts -> input_dev , MT_TOOL_FINGER , 1 );
92
109
@@ -126,6 +143,7 @@ static int ft5406_probe(struct platform_device *pdev)
126
143
struct device_node * fw_node ;
127
144
struct rpi_firmware * fw ;
128
145
u32 touchbuf ;
146
+ u32 val ;
129
147
130
148
dev_info (dev , "Probing device\n" );
131
149
@@ -136,8 +154,10 @@ static int ft5406_probe(struct platform_device *pdev)
136
154
}
137
155
138
156
fw = rpi_firmware_get (fw_node );
139
- if (!fw )
157
+ if (!fw ) {
158
+ dev_err (dev , "No firmware node - deferring\n" );
140
159
return - EPROBE_DEFER ;
160
+ }
141
161
142
162
ts = devm_kzalloc (dev , sizeof (struct ft5406 ), GFP_KERNEL );
143
163
if (!ts ) {
@@ -202,15 +222,36 @@ static int ft5406_probe(struct platform_device *pdev)
202
222
ts -> pdev = pdev ;
203
223
204
224
ts -> input_dev -> name = "FT5406 memory based driver" ;
205
-
225
+
226
+ if (of_property_read_u32 (np , "touchscreen-size-x" , & val ) >= 0 )
227
+ ts -> max_x = val ;
228
+ else
229
+ ts -> max_x = DEFAULT_SCREEN_WIDTH ;
230
+
231
+ if (of_property_read_u32 (np , "touchscreen-size-y" , & val ) >= 0 )
232
+ ts -> max_y = val ;
233
+ else
234
+ ts -> max_y = DEFAULT_SCREEN_HEIGHT ;
235
+
236
+ if (of_property_read_u32 (np , "touchscreen-inverted-x" , & val ) >= 0 )
237
+ ts -> hflip = val ;
238
+
239
+ if (of_property_read_u32 (np , "touchscreen-inverted-y" , & val ) >= 0 )
240
+ ts -> vflip = val ;
241
+
242
+ if (of_property_read_u32 (np , "touchscreen-swapped-x-y" , & val ) >= 0 )
243
+ ts -> xyswap = val ;
244
+
245
+ dev_dbg (dev , "Touchscreen parameters (%d,%d), hflip=%d, vflip=%d, xyswap=%d" , ts -> max_x , ts -> max_y , ts -> hflip , ts -> vflip , ts -> xyswap );
246
+
206
247
__set_bit (EV_KEY , ts -> input_dev -> evbit );
207
248
__set_bit (EV_SYN , ts -> input_dev -> evbit );
208
249
__set_bit (EV_ABS , ts -> input_dev -> evbit );
209
250
210
251
input_set_abs_params (ts -> input_dev , ABS_MT_POSITION_X , 0 ,
211
- SCREEN_WIDTH , 0 , 0 );
252
+ ts -> xyswap ? ts -> max_y : ts -> max_x , 0 , 0 );
212
253
input_set_abs_params (ts -> input_dev , ABS_MT_POSITION_Y , 0 ,
213
- SCREEN_HEIGHT , 0 , 0 );
254
+ ts -> xyswap ? ts -> max_x : ts -> max_y , 0 , 0 );
214
255
215
256
input_mt_init_slots (ts -> input_dev , MAXIMUM_SUPPORTED_POINTS , INPUT_MT_DIRECT );
216
257
0 commit comments