diff options
Diffstat (limited to 'drivers/input/touchscreen/sun4i-ts.c')
-rw-r--r-- | drivers/input/touchscreen/sun4i-ts.c | 46 |
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 | ||
384 | static const struct of_device_id sun4i_ts_of_match[] = { | 405 | static 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 | }; |