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 -------------------------------------- Required properties: - - compatible: "allwinner,sun4i-a10-ts" + - compatible: "allwinner,sun4i-a10-ts" or "allwinner,sun6i-a31-ts" - reg: mmio address range of the chip - interrupts: interrupt to which the chip is connected - #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 @@ #define TP_ADC_SELECT(x) ((x) << 3) #define ADC_CHAN_SELECT(x) ((x) << 0) /* 3 bits */ +/* on sun6i, bits 3~6 are left shifted by 1 to 4~7 */ +#define SUN6I_TP_MODE_EN(x) ((x) << 5) + /* TP_CTRL2 bits */ #define TP_SENSITIVE_ADJUST(x) ((x) << 28) /* 4 bits */ #define TP_MODE_SELECT(x) ((x) << 26) /* 2 bits */ @@ -113,6 +116,8 @@ struct sun4i_ts_data { unsigned int irq; bool ignore_fifo_data; int temp_data; + int temp_offset; + int temp_step; }; static 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) if (ts->temp_data == -1) return -EAGAIN; - /* - * 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) - * - * This should be replaced with the correct one if such information - * becomes available. - */ - *temp = (ts->temp_data - 1447) * 100; + *temp = (ts->temp_data - ts->temp_offset) * ts->temp_step; return 0; } @@ -249,6 +244,7 @@ static int sun4i_ts_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct device *hwmon; int error; + u32 reg; bool ts_attached; ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); @@ -258,6 +254,25 @@ static int sun4i_ts_probe(struct platform_device *pdev) ts->dev = dev; 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; + ts->temp_step = 167; + } 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) + * + * 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_step = 100; + } ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); if (ts_attached) { @@ -314,8 +329,12 @@ static int sun4i_ts_probe(struct platform_device *pdev) * Set stylus up debounce to aprox 10 ms, enable debounce, and * finally enable tp mode. */ - writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), - ts->base + TP_CTRL1); + 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 + reg |= SUN6I_TP_MODE_EN(1); + writel(reg, ts->base + TP_CTRL1); /* * The thermal core does not register hwmon devices for DT-based @@ -364,6 +383,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,sun6i-a31-ts", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sun4i_ts_of_match);