aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/sun4i-ts.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/sun4i-ts.c')
-rw-r--r--drivers/input/touchscreen/sun4i-ts.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c
index b93a28b955fd..c0116994067d 100644
--- a/drivers/input/touchscreen/sun4i-ts.c
+++ b/drivers/input/touchscreen/sun4i-ts.c
@@ -30,6 +30,10 @@
30 * These kinds of heuristics are just asking for trouble (and don't belong 30 * These kinds of heuristics are just asking for trouble (and don't belong
31 * in the kernel). So this driver offers straight forward, reliable single 31 * in the kernel). So this driver offers straight forward, reliable single
32 * touch functionality only. 32 * touch functionality only.
33 *
34 * s.a. A20 User Manual "1.15 TP" (Documentation/arm/sunxi/README)
35 * (looks like the description in the A20 User Manual v1.3 is better
36 * than the one in the A10 User Manual v.1.5)
33 */ 37 */
34 38
35#include <linux/err.h> 39#include <linux/err.h>
@@ -193,7 +197,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data *ts, long *temp)
193 if (ts->temp_data == -1) 197 if (ts->temp_data == -1)
194 return -EAGAIN; 198 return -EAGAIN;
195 199
196 *temp = (ts->temp_data - ts->temp_offset) * ts->temp_step; 200 *temp = ts->temp_data * ts->temp_step - ts->temp_offset;
197 201
198 return 0; 202 return 0;
199} 203}
@@ -246,6 +250,8 @@ static int sun4i_ts_probe(struct platform_device *pdev)
246 int error; 250 int error;
247 u32 reg; 251 u32 reg;
248 bool ts_attached; 252 bool ts_attached;
253 u32 tp_sensitive_adjust = 15;
254 u32 filter_type = 1;
249 255
250 ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); 256 ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL);
251 if (!ts) 257 if (!ts)
@@ -255,22 +261,31 @@ static int sun4i_ts_probe(struct platform_device *pdev)
255 ts->ignore_fifo_data = true; 261 ts->ignore_fifo_data = true;
256 ts->temp_data = -1; 262 ts->temp_data = -1;
257 if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) { 263 if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) {
258 /* Allwinner SDK has temperature = -271 + (value / 6) (C) */ 264 /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
259 ts->temp_offset = 1626; 265 ts->temp_offset = 271000;
260 ts->temp_step = 167; 266 ts->temp_step = 167;
267 } else if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) {
268 /*
269 * The A10 temperature sensor has quite a wide spread, these
270 * parameters are based on the averaging of the calibration
271 * results of 4 completely different boards, with a spread of
272 * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
273 */
274 ts->temp_offset = 257000;
275 ts->temp_step = 133;
261 } else { 276 } else {
262 /* 277 /*
263 * The user manuals do not contain the formula for calculating 278 * The user manuals do not contain the formula for calculating
264 * the temperature. The formula used here is from the AXP209, 279 * the temperature. The formula used here is from the AXP209,
265 * which is designed by X-Powers, an affiliate of Allwinner: 280 * which is designed by X-Powers, an affiliate of Allwinner:
266 * 281 *
267 * temperature = -144.7 + (value * 0.1) 282 * temperature (C) = (value * 0.1) - 144.7
268 * 283 *
269 * Allwinner does not have any documentation whatsoever for 284 * Allwinner does not have any documentation whatsoever for
270 * this hardware. Moreover, it is claimed that the sensor 285 * this hardware. Moreover, it is claimed that the sensor
271 * is inaccurate and cannot work properly. 286 * is inaccurate and cannot work properly.
272 */ 287 */
273 ts->temp_offset = 1447; 288 ts->temp_offset = 144700;
274 ts->temp_step = 100; 289 ts->temp_step = 100;
275 } 290 }
276 291
@@ -313,14 +328,20 @@ static int sun4i_ts_probe(struct platform_device *pdev)
313 ts->base + TP_CTRL0); 328 ts->base + TP_CTRL0);
314 329
315 /* 330 /*
316 * sensitive_adjust = 15 : max, which is not all that sensitive, 331 * tp_sensitive_adjust is an optional property
317 * tp_mode = 0 : only x and y coordinates, as we don't use dual touch 332 * tp_mode = 0 : only x and y coordinates, as we don't use dual touch
318 */ 333 */
319 writel(TP_SENSITIVE_ADJUST(15) | TP_MODE_SELECT(0), 334 of_property_read_u32(np, "allwinner,tp-sensitive-adjust",
335 &tp_sensitive_adjust);
336 writel(TP_SENSITIVE_ADJUST(tp_sensitive_adjust) | TP_MODE_SELECT(0),
320 ts->base + TP_CTRL2); 337 ts->base + TP_CTRL2);
321 338
322 /* Enable median filter, type 1 : 5/3 */ 339 /*
323 writel(FILTER_EN(1) | FILTER_TYPE(1), ts->base + TP_CTRL3); 340 * Enable median and averaging filter, optional property for
341 * filter type.
342 */
343 of_property_read_u32(np, "allwinner,filter-type", &filter_type);
344 writel(FILTER_EN(1) | FILTER_TYPE(filter_type), ts->base + TP_CTRL3);
324 345
325 /* Enable temperature measurement, period 1953 (2 seconds) */ 346 /* Enable temperature measurement, period 1953 (2 seconds) */
326 writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR); 347 writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR);
@@ -330,10 +351,10 @@ static int sun4i_ts_probe(struct platform_device *pdev)
330 * finally enable tp mode. 351 * finally enable tp mode.
331 */ 352 */
332 reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1); 353 reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1);
333 if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) 354 if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts"))
334 reg |= TP_MODE_EN(1);
335 else
336 reg |= SUN6I_TP_MODE_EN(1); 355 reg |= SUN6I_TP_MODE_EN(1);
356 else
357 reg |= TP_MODE_EN(1);
337 writel(reg, ts->base + TP_CTRL1); 358 writel(reg, ts->base + TP_CTRL1);
338 359
339 /* 360 /*
@@ -383,6 +404,7 @@ static int sun4i_ts_remove(struct platform_device *pdev)
383 404
384static const struct of_device_id sun4i_ts_of_match[] = { 405static const struct of_device_id sun4i_ts_of_match[] = {
385 { .compatible = "allwinner,sun4i-a10-ts", }, 406 { .compatible = "allwinner,sun4i-a10-ts", },
407 { .compatible = "allwinner,sun5i-a13-ts", },
386 { .compatible = "allwinner,sun6i-a31-ts", }, 408 { .compatible = "allwinner,sun6i-a31-ts", },
387 { /* sentinel */ } 409 { /* sentinel */ }
388}; 410};