diff options
author | Zoltan Herpai <wigyori@uid0.hu> | 2014-08-27 12:09:46 +0000 |
---|---|---|
committer | Zoltan Herpai <wigyori@uid0.hu> | 2014-08-27 12:09:46 +0000 |
commit | f10f009609aac0941d750ae3a1106675e6d6656a (patch) | |
tree | 70f62106f833dc3b4882118e914ff183440e1e9d /target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch | |
parent | b3d10005c1ce3b9676580d09001e14458e410f89 (diff) | |
download | mtk-20170518-f10f009609aac0941d750ae3a1106675e6d6656a.zip mtk-20170518-f10f009609aac0941d750ae3a1106675e6d6656a.tar.gz mtk-20170518-f10f009609aac0941d750ae3a1106675e6d6656a.tar.bz2 |
sunxi: initial 3.14 patchset
Signed-off-by: Zoltan HERPAI <wigyori@uid0.hu>
SVN-Revision: 42313
Diffstat (limited to 'target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch')
-rw-r--r-- | target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch b/target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch new file mode 100644 index 0000000..3d0bdad --- /dev/null +++ b/target/linux/sunxi/patches-3.14/171-input-add-temp-sensor-support.patch @@ -0,0 +1,264 @@ +From d8b5553dbf60e519d565dbd83327b08865e960e2 Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 27 Dec 2013 15:25:28 +0100 +Subject: [PATCH] input: sun4i-ts: Add support for temperature sensor + +The sun4i resisitive touchscreen controller also comes with a built-in +temperature sensor. This commit adds support for it. + +This commit also introduces a new "ts-attached" device-tree property, +when this is not set, the input part of the driver won't register. This way +the internal temperature sensor can be used to measure the SoC temperature +independent of there actually being a touchscreen attached to the controller. + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + .../bindings/input/touchscreen/sun4i.txt | 5 + + drivers/input/touchscreen/sun4i-ts.c | 140 ++++++++++++++++----- + 2 files changed, 114 insertions(+), 31 deletions(-) + +diff --git a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt +index e45927e..6bac67b 100644 +--- a/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt ++++ b/Documentation/devicetree/bindings/input/touchscreen/sun4i.txt +@@ -6,10 +6,15 @@ Required properties: + - reg: mmio address range of the chip + - interrupts: interrupt to which the chip is connected + ++Optional properties: ++ - allwinner,ts-attached: boolean indicating that an actual touchscreen is ++ attached to the controller ++ + Example: + + rtp: rtp@01c25000 { + compatible = "allwinner,sun4i-ts"; + reg = <0x01c25000 0x100>; + interrupts = <29>; ++ allwinner,ts-attached; + }; +diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c +index 5945219..16cbb01 100644 +--- a/drivers/input/touchscreen/sun4i-ts.c ++++ b/drivers/input/touchscreen/sun4i-ts.c +@@ -3,6 +3,9 @@ + * + * Copyright (C) 2013 - 2014 Hans de Goede <hdegoede@redhat.com> + * ++ * The hwmon parts are based on work by Corentin LABBE which is: ++ * Copyright (C) 2013 Corentin LABBE <clabbe.montjoie@gmail.com> ++ * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or +@@ -30,6 +33,7 @@ + */ + + #include <linux/err.h> ++#include <linux/hwmon.h> + #include <linux/init.h> + #include <linux/input.h> + #include <linux/interrupt.h> +@@ -106,14 +110,12 @@ struct sun4i_ts_data { + void __iomem *base; + unsigned int irq; + bool ignore_fifo_data; ++ int temp_data; + }; + +-static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) ++static void sun4i_ts_irq_handle_input(struct sun4i_ts_data *ts, u32 reg_val) + { +- struct sun4i_ts_data *ts = dev_id; +- u32 reg_val, x, y; +- +- reg_val = readl(ts->base + TP_INT_FIFOS); ++ u32 x, y; + + if (reg_val & FIFO_DATA_PENDING) { + x = readl(ts->base + TP_DATA); +@@ -139,6 +141,20 @@ static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) + input_report_key(ts->input, BTN_TOUCH, 0); + input_sync(ts->input); + } ++} ++ ++static irqreturn_t sun4i_ts_irq(int irq, void *dev_id) ++{ ++ struct sun4i_ts_data *ts = dev_id; ++ u32 reg_val; ++ ++ reg_val = readl(ts->base + TP_INT_FIFOS); ++ ++ if (reg_val & TEMP_DATA_PENDING) ++ ts->temp_data = readl(ts->base + TEMP_DATA); ++ ++ if (ts->input) ++ sun4i_ts_irq_handle_input(ts, reg_val); + + writel(reg_val, ts->base + TP_INT_FIFOS); + +@@ -149,9 +165,9 @@ static int sun4i_ts_open(struct input_dev *dev) + { + struct sun4i_ts_data *ts = input_get_drvdata(dev); + +- /* Flush, set trig level to 1, enable data and up irqs */ +- writel(DATA_IRQ_EN(1) | FIFO_TRIG(1) | FIFO_FLUSH(1) | TP_UP_IRQ_EN(1), +- ts->base + TP_INT_FIFOC); ++ /* Flush, set trig level to 1, enable temp, data and up irqs */ ++ writel(TEMP_IRQ_EN(1) | DATA_IRQ_EN(1) | FIFO_TRIG(1) | FIFO_FLUSH(1) | ++ TP_UP_IRQ_EN(1), ts->base + TP_INT_FIFOC); + + return 0; + } +@@ -160,15 +176,48 @@ static void sun4i_ts_close(struct input_dev *dev) + { + struct sun4i_ts_data *ts = input_get_drvdata(dev); + +- /* Deactivate all IRQs */ +- writel(0, ts->base + TP_INT_FIFOC); ++ /* Deactivate all input IRQs */ ++ writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); ++} ++ ++static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, ++ char *buf) ++{ ++ struct sun4i_ts_data *ts = dev_get_drvdata(dev); ++ ++ /* No temp_data until the first irq */ ++ if (ts->temp_data == -1) ++ return -EAGAIN; ++ ++ return sprintf(buf, "%d\n", (ts->temp_data - 1447) * 100); ++} ++ ++static ssize_t show_temp_label(struct device *dev, ++ struct device_attribute *devattr, char *buf) ++{ ++ return sprintf(buf, "SoC temperature\n"); + } + ++static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); ++static DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL); ++ ++static struct attribute *sun4i_ts_attrs[] = { ++ &dev_attr_temp1_input.attr, ++ &dev_attr_temp1_label.attr, ++ NULL ++}; ++ATTRIBUTE_GROUPS(sun4i_ts); ++ + static int sun4i_ts_probe(struct platform_device *pdev) + { + struct sun4i_ts_data *ts; + struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct device *hwmon; + int ret; ++ bool ts_attached; ++ ++ ts_attached = of_property_read_bool(np, "allwinner,ts-attached"); + + ts = devm_kzalloc(dev, sizeof(struct sun4i_ts_data), GFP_KERNEL); + if (!ts) +@@ -176,24 +225,27 @@ static int sun4i_ts_probe(struct platform_device *pdev) + + ts->dev = dev; + ts->ignore_fifo_data = true; +- +- ts->input = devm_input_allocate_device(dev); +- if (!ts->input) +- return -ENOMEM; +- +- ts->input->name = pdev->name; +- ts->input->phys = "sun4i_ts/input0"; +- ts->input->open = sun4i_ts_open; +- ts->input->close = sun4i_ts_close; +- ts->input->id.bustype = BUS_HOST; +- ts->input->id.vendor = 0x0001; +- ts->input->id.product = 0x0001; +- ts->input->id.version = 0x0100; +- ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); +- set_bit(BTN_TOUCH, ts->input->keybit); +- input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); +- input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); +- input_set_drvdata(ts->input, ts); ++ ts->temp_data = -1; ++ ++ if (ts_attached) { ++ ts->input = devm_input_allocate_device(dev); ++ if (!ts->input) ++ return -ENOMEM; ++ ++ ts->input->name = pdev->name; ++ ts->input->phys = "sun4i_ts/input0"; ++ ts->input->open = sun4i_ts_open; ++ ts->input->close = sun4i_ts_close; ++ ts->input->id.bustype = BUS_HOST; ++ ts->input->id.vendor = 0x0001; ++ ts->input->id.product = 0x0001; ++ ts->input->id.version = 0x0100; ++ ts->input->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) | BIT(EV_ABS); ++ set_bit(BTN_TOUCH, ts->input->keybit); ++ input_set_abs_params(ts->input, ABS_X, 0, 4095, 0, 0); ++ input_set_abs_params(ts->input, ABS_Y, 0, 4095, 0, 0); ++ input_set_drvdata(ts->input, ts); ++ } + + ts->base = devm_ioremap_resource(dev, + platform_get_resource(pdev, IORESOURCE_MEM, 0)); +@@ -232,14 +284,39 @@ static int sun4i_ts_probe(struct platform_device *pdev) + writel(STYLUS_UP_DEBOUN(5) | STYLUS_UP_DEBOUN_EN(1) | TP_MODE_EN(1), + ts->base + TP_CTRL1); + +- ret = input_register_device(ts->input); +- if (ret) +- return ret; ++ hwmon = devm_hwmon_device_register_with_groups(ts->dev, "sun4i_ts", ++ ts, sun4i_ts_groups); ++ if (IS_ERR(hwmon)) ++ return PTR_ERR(hwmon); ++ ++ writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); ++ ++ if (ts_attached) { ++ ret = input_register_device(ts->input); ++ if (ret) { ++ writel(0, ts->base + TP_INT_FIFOC); ++ return ret; ++ } ++ } + + platform_set_drvdata(pdev, ts); + return 0; + } + ++static int sun4i_ts_remove(struct platform_device *pdev) ++{ ++ struct sun4i_ts_data *ts = platform_get_drvdata(pdev); ++ ++ /* Explicit unregister to avoid open/close changing the imask later */ ++ if (ts->input) ++ input_unregister_device(ts->input); ++ ++ /* Deactivate all IRQs */ ++ writel(0, ts->base + TP_INT_FIFOC); ++ ++ return 0; ++} ++ + static const struct of_device_id sun4i_ts_of_match[] = { + { .compatible = "allwinner,sun4i-ts", }, + { /* sentinel */ } +@@ -253,6 +330,7 @@ static struct platform_driver sun4i_ts_driver = { + .of_match_table = of_match_ptr(sun4i_ts_of_match), + }, + .probe = sun4i_ts_probe, ++ .remove = sun4i_ts_remove, + }; + + module_platform_driver(sun4i_ts_driver); +-- +2.0.3 + |