aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2015-01-27 02:57:00 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-01-27 02:58:56 -0500
commit43c0e2234021d7f838a24821e622589ee730e020 (patch)
treea9b58f2d85b9e31755c0fa88e5593c5e03c50672
parente443631d20f595e342dd00a315e5263b393b4735 (diff)
Input: sun4i-ts - add support for touchpanel controller on A31
The Allwinner A31 SoC (sun6i) has the same resistive touchpanel controller as on other sunxi platforms. The only difference between the variants is the control bits for enabling operations are left-shifted by 1 on the A31. Also update the comment for the original temperature sensor with information from Allwinner. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/sun4i.txt2
-rw-r--r--drivers/input/touchscreen/sun4i-ts.c46
2 files changed, 34 insertions, 14 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
index a8405bab6c00..433332d3b2ba 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt
@@ -2,7 +2,7 @@ sun4i resistive touchscreen controller
2-------------------------------------- 2--------------------------------------
3 3
4Required properties: 4Required properties:
5 - compatible: "allwinner,sun4i-a10-ts" 5 - compatible: "allwinner,sun4i-a10-ts" or "allwinner,sun6i-a31-ts"
6 - reg: mmio address range of the chip 6 - reg: mmio address range of the chip
7 - interrupts: interrupt to which the chip is connected 7 - interrupts: interrupt to which the chip is connected
8 - #thermal-sensor-cells: shall be 0 8 - #thermal-sensor-cells: shall be 0
diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c
index 9ae53d4289fb..b93a28b955fd 100644
--- a/drivers/input/touchscreen/sun4i-ts.c
+++ b/drivers/input/touchscreen/sun4i-ts.c
@@ -72,6 +72,9 @@
72#define TP_ADC_SELECT(x) ((x) << 3) 72#define TP_ADC_SELECT(x) ((x) << 3)
73#define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ 73#define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */
74 74
75/* on sun6i, bits 3~6 are left shifted by 1 to 4~7 */
76#define SUN6I_TP_MODE_EN(x) ((x) << 5)
77
75/* TP_CTRL2 bits */ 78/* TP_CTRL2 bits */
76#define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ 79#define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */
77#define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ 80#define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */
@@ -113,6 +116,8 @@ struct sun4i_ts_data {
113 unsigned int irq; 116 unsigned int irq;
114 bool ignore_fifo_data; 117 bool ignore_fifo_data;
115 int temp_data; 118 int temp_data;
119 int temp_offset;
120 int temp_step;
116}; 121};
117 122
118static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val) 123static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val)
@@ -188,17 +193,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data *ts, long *temp)
188 if (ts->temp_data == -1) 193 if (ts->temp_data == -1)
189 return -EAGAIN; 194 return -EAGAIN;
190 195
191 /* 196 *temp = (ts->temp_data - ts->temp_offset) * ts->temp_step;
192 * The user manuals do not contain the formula for calculating
193 * the temperature. The formula used here is from the AXP209,
194 * which is designed by X-Powers, an affiliate of Allwinner:
195 *
196 * temperature = -144.7 + (value * 0.1)
197 *
198 * This should be replaced with the correct one if such information
199 * becomes available.
200 */
201 *temp = (ts->temp_data - 1447) * 100;
202 197
203 return 0; 198 return 0;
204} 199}
@@ -249,6 +244,7 @@ static int sun4i_ts_probe(struct platform_device *pdev)
249 struct device_node *np = dev->of_node; 244 struct device_node *np = dev->of_node;
250 struct device *hwmon; 245 struct device *hwmon;
251 int error; 246 int error;
247 u32 reg;
252 bool ts_attached; 248 bool ts_attached;
253 249
254 ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); 250 ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL);
@@ -258,6 +254,25 @@ static int sun4i_ts_probe(struct platform_device *pdev)
258 ts->dev = dev; 254 ts->dev = dev;
259 ts->ignore_fifo_data = true; 255 ts->ignore_fifo_data = true;
260 ts->temp_data = -1; 256 ts->temp_data = -1;
257 if (of_device_is_compatible(np, "allwinner,sun6i-a31-ts")) {
258 /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
259 ts->temp_offset = 1626;
260 ts->temp_step = 167;
261 } else {
262 /*
263 * The user manuals do not contain the formula for calculating
264 * the temperature. The formula used here is from the AXP209,
265 * which is designed by X-Powers, an affiliate of Allwinner:
266 *
267 * temperature = -144.7 + (value * 0.1)
268 *
269 * Allwinner does not have any documentation whatsoever for
270 * this hardware. Moreover, it is claimed that the sensor
271 * is inaccurate and cannot work properly.
272 */
273 ts->temp_offset = 1447;
274 ts->temp_step = 100;
275 }
261 276
262 ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); 277 ts_attached = of_property_read_bool(np, "allwinner,ts-attached");
263 if (ts_attached) { 278 if (ts_attached) {
@@ -314,8 +329,12 @@ static int sun4i_ts_probe(struct platform_device *pdev)
314 * Set stylus up debounce to aprox 10 ms, enable debounce, and 329 * Set stylus up debounce to aprox 10 ms, enable debounce, and
315 * finally enable tp mode. 330 * finally enable tp mode.
316 */ 331 */
317 writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), 332 reg = STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1);
318 ts->base + TP_CTRL1); 333 if (of_device_is_compatible(np, "allwinner,sun4i-a10-ts"))
334 reg |= TP_MODE_EN(1);
335 else
336 reg |= SUN6I_TP_MODE_EN(1);
337 writel(reg, ts->base + TP_CTRL1);
319 338
320 /* 339 /*
321 * The thermal core does not register hwmon devices for DT-based 340 * The thermal core does not register hwmon devices for DT-based
@@ -364,6 +383,7 @@ static int sun4i_ts_remove(struct platform_device *pdev)
364 383
365static const struct of_device_id sun4i_ts_of_match[] = { 384static const struct of_device_id sun4i_ts_of_match[] = {
366 { .compatible = "allwinner,sun4i-a10-ts", }, 385 { .compatible = "allwinner,sun4i-a10-ts", },
386 { .compatible = "allwinner,sun6i-a31-ts", },
367 { /* sentinel */ } 387 { /* sentinel */ }
368}; 388};
369MODULE_DEVICE_TABLE(of, sun4i_ts_of_match); 389MODULE_DEVICE_TABLE(of, sun4i_ts_of_match);