summaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/sun4i-ts.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 18:25:15 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 18:25:15 -0700
commit8691c130fae136bb2b7d0554422a2dff4c6ac169 (patch)
tree9c75c86ab04e66d756c55f37e594c3e27a2963d5 /drivers/input/touchscreen/sun4i-ts.c
parentc3a416a669eb83cfa9ccb52db030e72d654bd105 (diff)
parent85a3685852d9ac7d92be9d824533c915a4597fa4 (diff)
downloadlinux-8691c130fae136bb2b7d0554422a2dff4c6ac169.tar.bz2
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov: "You will get the following new drivers: - Qualcomm PM8941 power key drver - ChipOne icn8318 touchscreen controller driver - Broadcom iProc touchscreen and keypad drivers - Semtech SX8654 I2C touchscreen controller driver ALPS driver now supports newer SS4 devices; Elantech got a fix that should make it work on some ASUS laptops; and a slew of other enhancements and random fixes" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (51 commits) Input: alps - non interleaved V2 dualpoint has separate stick button bits Input: alps - fix touchpad buttons getting stuck when used with trackpoint Input: atkbd - document "no new force-release quirks" policy Input: ALPS - make alps_get_pkt_id_ss4_v2() and others static Input: ALPS - V7 devices can report 5-finger taps Input: ALPS - add support for SS4 touchpad devices Input: ALPS - refactor alps_set_abs_params_mt() Input: elantech - fix absolute mode setting on some ASUS laptops Input: atmel_mxt_ts - split out touchpad initialisation logic Input: atmel_mxt_ts - implement support for T100 touch object Input: cros_ec_keyb - fix clearing keyboard state on wakeup Input: gscps2 - drop pci_ids dependency Input: synaptics - allocate 3 slots to keep stability in image sensors Input: Revert "Revert "synaptics - use dmax in input_mt_assign_slots"" Input: MT - make slot assignment work for overcovered solutions mfd: tc3589x: enforce device-tree only mode Input: tc3589x - localize platform data Input: tsc2007 - Convert msecs to jiffies only once Input: edt-ft5x06 - remove EV_SYN event report Input: edt-ft5x06 - allow to setting the maximum axes value through the DT ...
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 @@
* These kinds of heuristics are just asking for trouble (and don't belong
* in the kernel). So this driver offers straight forward, reliable single
* touch functionality only.
+ *
+ * s.a. A20 User Manual "1.15 TP" (Documentation/arm/sunxi/README)
+ * (looks like the description in the A20 User Manual v1.3 is better
+ * than the one in the A10 User Manual v.1.5)
*/
#include <linux/err.h>
@@ -193,7 +197,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data *ts, long *temp)
if (ts->temp_data == -1)
return -EAGAIN;
- *temp = (ts->temp_data - ts->temp_offset) * ts->temp_step;
+ *temp = ts->temp_data * ts->temp_step - ts->temp_offset;
return 0;
}
@@ -246,6 +250,8 @@ static int sun4i_ts_probe(struct platform_device *pdev)
int error;
u32 reg;
bool ts_attached;
+ u32 tp_sensitive_adjust = 15;
+ u32 filter_type = 1;
ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL);
if (!ts)
@@ -255,22 +261,31 @@ static int sun4i_ts_probe(struct platform_device *pdev)
ts->ignore_fifo_data = true;
ts->temp_data = -1;
if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) {
- /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
- ts->temp_offset = 1626;
+ /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
+ ts->temp_offset = 271000;
ts->temp_step = 167;
+ } else if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts")) {
+ /*
+ * The A10 temperature sensor has quite a wide spread, these
+ * parameters are based on the averaging of the calibration
+ * results of 4 completely different boards, with a spread of
+ * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
+ */
+ ts->temp_offset = 257000;
+ ts->temp_step = 133;
} else {
/*
* The user manuals do not contain the formula for calculating
* the temperature. The formula used here is from the AXP209,
* which is designed by X-Powers, an affiliate of Allwinner:
*
- * temperature = -144.7 + (value * 0.1)
+ * temperature (C) = (value * 0.1) - 144.7
*
* Allwinner does not have any documentation whatsoever for
* this hardware. Moreover, it is claimed that the sensor
* is inaccurate and cannot work properly.
*/
- ts->temp_offset = 1447;
+ ts->temp_offset = 144700;
ts->temp_step = 100;
}
@@ -313,14 +328,20 @@ static int sun4i_ts_probe(struct platform_device *pdev)
ts->base + TP_CTRL0);
/*
- * sensitive_adjust = 15 : max, which is not all that sensitive,
+ * tp_sensitive_adjust is an optional property
* tp_mode = 0 : only x and y coordinates, as we don't use dual touch
*/
- writel(TP_SENSITIVE_ADJUST(15) | TP_MODE_SELECT(0),
+ of_property_read_u32(np, "allwinner,tp-sensitive-adjust",
+ &tp_sensitive_adjust);
+ writel(TP_SENSITIVE_ADJUST(tp_sensitive_adjust) | TP_MODE_SELECT(0),
ts->base + TP_CTRL2);
- /* Enable median filter, type 1 : 5/3 */
- writel(FILTER_EN(1) | FILTER_TYPE(1), ts->base + TP_CTRL3);
+ /*
+ * Enable median and averaging filter, optional property for
+ * filter type.
+ */
+ of_property_read_u32(np, "allwinner,filter-type", &filter_type);
+ writel(FILTER_EN(1) | FILTER_TYPE(filter_type), ts->base + TP_CTRL3);
/* Enable temperature measurement, period 1953 (2 seconds) */
writel(TEMP_ENABLE(1) | TEMP_PERIOD(1953), ts->base + TP_TPR);
@@ -330,10 +351,10 @@ static int sun4i_ts_probe(struct platform_device *pdev)
* finally enable tp mode.
*/
reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1);
- if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts"))
- reg |= TP_MODE_EN(1);
- else
+ if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts"))
reg |= SUN6I_TP_MODE_EN(1);
+ else
+ reg |= TP_MODE_EN(1);
writel(reg, ts->base + TP_CTRL1);
/*
@@ -383,6 +404,7 @@ static int sun4i_ts_remove(struct platform_device *pdev)
static const struct of_device_id sun4i_ts_of_match[] = {
{ .compatible = "allwinner,sun4i-a10-ts", },
+ { .compatible = "allwinner,sun5i-a13-ts", },
{ .compatible = "allwinner,sun6i-a31-ts", },
{ /* sentinel */ }
};