[RFC] A2x touchpad temperature readout

164 views
Skip to first unread message

Heiko Schröter

unread,
Jun 18, 2015, 9:32:09 AM6/18/15
to linux-sunxi, schr...@iup.physik.uni-bremen.de
Hello,

i'd like to place a RFC for a Kernel Module reading out the TP
temperature of the A2x SoC.

- output via sysfs
- all THS registers are user configurable including start/stop
- module is initially turned off after loading. THS has to be enabled or
module loaded with param.
- module honors /proc/ioports

This module is the (base) test layout for the A33 (which i dont have)
and the A80 (which i hopefully get within the next days).

Tested on cubietruck 3.4.103 as module or compiled into kernel.
Compiles under mainline kernel but not tested.

This module should work for the A33 out of the box BUT no guarantee for
correct temp reading.
On A33 the calibration value for the THS is placed in the SID register(s).

Is such temp monitoring stuff useful at all ?
What do you think ?

Regards
Heiko


From 615e5e0dda0715d4cb0f483b5a4cf39c68d61157 Mon Sep 17 00:00:00 2001
From: Heiko Schroeter <schr...@iup.physik.uni-bremen.de>
Date: Thu, 18 Jun 2015 15:18:30 +0200
Subject: [PATCH 1/1] arm: Added A2X SoC temperature readout

* Register values are user settable for platform depending
* power saving etc.
* THS registers: /sys/bus/platform/devices/a2x_thermal/
* Naming scheme identical to A23 datasheet.
* All settable register values in HEX.
* /sys/bus/platform/devices/a2x_ths/settings shows all THS
* register HEX values.
*
* THS registers are preset on module load, but NOT enabled
* by default.
* To start THS:
* echo "0x10000" > /sys/bus/platform/devices/a2x_thermal/ths_en
* or
* module_param: start_on_load=1 starts THS on module load.
*
* Temperature output in Celcius*100.

Signed-off-by: Heiko Schroeter <schr...@iup.physik.uni-bremen.de>
---
drivers/hwmon/Kconfig | 14 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/a2x_thermal.c | 667
++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 682 insertions(+)
create mode 100644 drivers/hwmon/a2x_thermal.c

diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 25d9e72..9b996db 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -39,6 +39,20 @@ config HWMON_DEBUG_CHIP

comment "Native drivers"

+
+config A2X_THERMAL
+ tristate "A2x SoC TP sensor controller"
+ depends on !TOUCHSCREEN_SUN4I_TS
+ help
+ If you say yes here you get support for the hardware temperature
+ monitoring sensor present in the touch screen controller on
A2x SoC.
+ Output via sysfs i.e.
/sys/bus/platform/devices/a2x_thermal/ths_data
+ Divied ths_data by 100 to get Celcius.
+ All other THS register settings are user settable by writing
to sysfs.
+
+ This driver can be build as a module. If so, the module will
called
+ a2x_thermal
+
config SENSORS_AB8500
tristate "AB8500 thermal monitoring"
depends on AB8500_GPADC && AB8500_BM
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b4a40f1..4e9d9cc 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -161,3 +161,4 @@ obj-$(CONFIG_PMBUS) += pmbus/

ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG

+obj-$(CONFIG_A2X_THERMAL) += a2x_thermal.o
diff --git a/drivers/hwmon/a2x_thermal.c b/drivers/hwmon/a2x_thermal.c
new file mode 100644
index 0000000..a15bba2
--- /dev/null
+++ b/drivers/hwmon/a2x_thermal.c
@@ -0,0 +1,667 @@
+/*
+ * a2x_thermal.c -- A2x touchpad temperature readout
+ *
+ * Copyright 2015 Heiko Schroeter
+ *
+ * Author: Heiko Schroeter
+ * schr...@physik.uni-bremen.de
+ *
+ * Ideas taken from various Authors using the hwmon_device interface.
+ *
+ * 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 (at
your
+ * option) any later version.
+ *
+ *
+ * ##################################
+ *
+ * Register values are user settable for platform depending
+ * power saving etc.
+ * THS registers: /sys/bus/platform/devices/a2x_thermal/
+ * Naming scheme identical to A23 datasheet.
+ * All settable register values in HEX.
+ * /sys/bus/platform/devices/a2x_ths/settings shows all THS
+ * register HEX values.
+ *
+ * THS registers are preset on module load, but NOT enabled
+ * by default.
+ * To start THS:
+ * echo "0x10000" > /sys/bus/platform/devices/a2x_thermal/ths_en
+ * or
+ * module_param: start_on_load=1 starts THS on module load.
+ *
+ * Temperature output in Celcius*100.
+ *
+ * ###################################
+ *
+ * From A23 User Manual (Revision 1.0):
+ *
+ * 3.19 Thermal Sensor Controller
+ * 3.19.1 Overview
+ *
+ * The A23 supports thermal sensor controller to monitor the chip
temperature.
+ *
+ * 3.19.2 Clock Tree and ADC Conversion Time
+ *
+ * A/D CONVERSION TIME
+ * When the clock source is 24MHz and the prescaler value M*N is 6,
+ * total 12-bit conversion time is as follows.
+ *
+ * CLK_IN = 24MHz/6 = 4MHz
+ *
+ * Conversion Time = 1/(4MHz/14Cycles) =3.50us
+ *
+ * If ADC acquire time divider is, then TACQ =1/(4MHz/6) = 1.50us
+ * FS_TIME (configured by the FS_DIV register) bases on the summation
+ * of Conversion Time and TACQ. The FS_TIME must be greater or equal
+ * than (TACQ + Conversion Time)
+ *
+ * FS_TIME >= TACQ + Conversion ITime=5.0us
+ *
+ * This A/D converter was designed to operate at maximum 24MHz clock,
+ * and the conversion rate can go up to 1 MSPS.
+ *
+ * Register naming convention as in A23 manual.
+ *
+ *
+ * 3.19.3 Thermal Measurement
+ * T = (V[AL] - 1669)/6.25 Celsius degree
+ * The V[AL] should read from thermal value register.
+ * FORMULA WRONG; offset of 0x10 = 100/6.25 is missing
+ * correct: T = (V[al] - 1669 + 100)*16 / 100
+ *
+ * 3.19.4 Thermal Sensor Controller Register List
+ * Module Name Base Address
+ * THS 0x01C25000
+ *
+ * Register Name Offset Description
+ * THS_CTRL0 0x00 THS Control Register0
+ * THS_CTRL1 0x04 THS Control Register1
+ * THS_INT 0x10 THS Int Control
+ * THS_DATA_PENDING 0x14 THS Data Status
+ * THS_TPR 0x18 THS Period Register
+ * THS_DATA 0x20 THS Data Register
+ *
+ * 3.19.5 Thermal Sensor Controller Register Description
+ * THS CONTROL REGISTER 0
+ *
+ * Offset: 0x00 Register Name: THS_CTRL0
+ * Bit Read/ Default/ Description
+ * Write Hex
+ * 31:24 R/W 0xF DATA_FIRST_DLY.
+ * DATA First Convert Delay
Time(T_FCDT)setting.
+ * Based on Data First Convert Delay Mode
+ * select (Bit 23).
+ * T_FCDT = DATA_FIRST_DLY *
DATA_FIRST_DLY_MODE
+ * 23 R/W 0x1 DATA_FIRST_DLY_MODE.
+ * TDATA First Convert Delay Mode Select.
+ * 0: CLK_IN/16
+ * 1: CLK_IN/16*256
+ * 22 / / /
+ * 21:20 R/W 0x0 DATA_CLK_DIVIDER.
+ * DATA Clock Divider(CLK_IN).
+ * 00: CLK/2
+ * 01: CLK/3
+ * 10: CLK/6
+ * 11: CLK/1
+ * 19:16 R/W 0x0 FS_DIV.
+ * DATA Sample Frequency Divider.
+ * 0000: CLK_IN/(2 power (20-n))
+ * 0001: CLK_IN/(2 power (20-n))
+ * ....
+ * 1111: CLK_IN/32
+ * 15:0 R/W 0x0 TACQ.
+ * DATA acquire time.
+ * CLK_IN/(16*(N+1))
+ *
+ * THS CONTROL REGISTER 1
+ * !! ATTENTION: ERROR in DATASHEET !!
+ * First HEX Value should be BITPOS 0-3 and not 0-4 !
+ * Offset: 0x04 Register Name: THS_CTRL1
+ * Bit Read/ Default/ Description
+ * Write Hex
+ * 31:8 / / /
+ * 7 R/W 0x1 CHOP_TEMP_EN.
+ * Chop temperature calibration enable.
+ * 0: Disable
+ * 1: Enable
+ * 6:5 / / /
+ * 4 R/W 0x0 DATA_EN.
+ * DATA Function Enable.
+ * 0: Disable
+ * 1: Enable
+ * 3:0 R/W 0x1 /
+ *
+ *
+ * From A20 Manual. Description of TP_INT not in A23 Manual
+ * THS (TP) INTERRUPT& FIFO CONTROL REGISTER
+ * Offset: 0x10 Register Name: THS_INT (TP_INT)
+ * Bit Read/ Default/ Description
+ * Write Hex
+ * 31:19 / / /
+ * 18 R/W 0x0 TEMP_IRQ_ENABLE.
+ * 17 R/W 0x0 TP_OVERRUN_IRQ_EN.
+ * 16 R/W 0x0 TP_DATA_IRQ_EN.
+ * 15:14 / / /
+ * 13 R/W 0x0 TP_DATA_XY_CHANGE.
+ * 12:8 R/W 0xF TP_FIFO_TRIG_LEVEL.
+ * 7 R/W 0x0 TP_DATA_DRQ_EN.
+ * 6:5 / / /
+ * 4 R/W 0x0 TP_FIFO_FLUSH.
+ * 3:2 / / /
+ * 1 R/W 0x0 TP_UP_IRQ_EN.
+ * 0 R/W 0x0 TP_DOWN_IRQ_EN.
+ *
+ *
+ * THS DATA STATUS REGISTER
+ * Offset: 0x14 Register Name: DATA_FIFOS
+ * Bit Read/ Default/ Description
+ * Write Hex
+ * 31:19 / / /
+ * 18 R/W 0x0 THS_DATA_PENDING.
+ * Thermal sensor data pending.
+ * 0: No Pending
+ * 1: Thermal sensor data Pending
+ * Write ‘1’ to clear this interrupt or
+ * automatic clear if data pending
+ * condition fails.
+ *
+ * THS PERIOD REGISTER
+ * Offset: 0x18 Register Name: THS_TPR
+ * Bit Read/ Default/ Description
+ * Write Hex
+ * 31:16 / / /
+ * 16 R/W 0x0 THS_EN.
+ * Thermal sensor enable.
+ * 15:0 R/W 0x0 THS_PER.
+ * Thermal sensor Period.
+ * 4096*(1/clk_in)
+ *
+ * THS DATA REGISTER
+ * Offset: 0x20 Register Name: THS_DATA
+ * Bit Read/ Default/ Description
+ * Write Hex Default: 0x0000_0000
+ * 31:12 / / /
+ * 11:0 R 0x0 THS_DATA.
+ * Thermal sensor data.
+ *
+ *
+ */
+
+#define A2X_LICENSE "GPL"
+#define A2X_VERSION "1.0"
+#define A2X_AUTHOR "Heiko Schroeter <schr...@iup.physik.uni-bremen.de>"
+#define A2X_DESC "A2x SoC THS reading and setting."
+
+/*
+ * Changelog:
+ *
+ * 2015-06-18 1.0 Initial release
+ *
+ *
+ *
+ */
+
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#define THS_MODULE_NAME "a2x_thermal"
+
+/* Access rights for sysfs */
+#define THS_S_UGO (S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH |
S_IXOTH)
+
+/* 1k IO MEM Space */
+#define THS_IO_MEM_SIZE 0x400
+
+/* A23 Thermal Registers */
+#define THS 0xF1C25000 /* Base */
+#define THS_CTRL0 ((void *) (THS + 0x00)) /* THS Control Register0 */
+#define THS_CTRL1 ((void *) (THS + 0x04)) /* THS Control Register1 */
+#define THS_INT ((void *) (THS + 0x10)) /* THS Int Enable */
+#define THS_FIFOS ((void *) (THS + 0x14)) /* THS Data Status */
+#define THS_TPR ((void *) (THS + 0x18)) /* THS Period Register */
+#define THS_DATA ((void *) (THS + 0x20)) /* THS Data Register */
+
+/* Bitpositions in Register */
+/* THS_CTRL0 */
+#define DATA_FIRST_DLY 24
+#define DATA_FIRST_DLY_MODE 23
+#define DATA_CLK_DIVIDER 20
+#define FS_DIV 16
+#define TACQ 0
+
+/* THS_CTRL1 */
+#define CHOP_TEMP_EN 7
+#define DATA_EN 4
+
+/* THS INT */
+#define TEMP_IRQ_ENABLE 18
+
+/* THS_FIFOS */
+#define DATA_PENDING 18
+
+/* THS_TPR */
+#define THS_EN 16
+#define THS_PER 0
+
+/* THS_DATA */
+#define THS_DATA_MASK 0xFFF
+
+#define THS_EAGAIN -1000
+
+/* Indicate no real value for the start */
+int32_t ths_data = THS_EAGAIN;
+
+/* preset ths register variables */
+/* 200000 50000 f8 80 10 10000 ff8 40000 */
+uint32_t data_first_dly = (0x0F << DATA_FIRST_DLY);
+uint32_t data_first_dly_mode = (0x01 << DATA_FIRST_DLY_MODE);
+uint32_t data_clk_divider = (0x02 << DATA_CLK_DIVIDER);
+uint32_t fs_div = (0x05 << FS_DIV);
+uint32_t tacq = (0xF8 << TACQ);
+uint32_t chop_temp_en = (1 << CHOP_TEMP_EN);
+uint32_t temp_irq_enable = (1 << TEMP_IRQ_ENABLE);
+uint32_t data_en = (1 << DATA_EN);
+/* Do not start by default */
+uint32_t ths_en = (0 << THS_EN);
+uint32_t ths_per = (0xFF8 << THS_PER);
+uint32_t data_pending = (1 << DATA_PENDING);
+
+/* module parameter */
+static bool start_on_load;
+module_param(start_on_load, bool, S_IRUGO);
+MODULE_PARM_DESC(start_on_load, "Start THS conversion on module load");
+
+/*
+ * Setup THS registers
+ */
+int ths_setup(void)
+{
+
+ /* Setup ADC speed for TP conversion */
+ writel(data_first_dly | data_first_dly_mode |
+ data_clk_divider | fs_div | tacq,
+ THS_CTRL0);
+
+ /* Enable TP */
+ writel(chop_temp_en | data_en, THS_CTRL1);
+
+ /* Enable the temperature */
+ writel(ths_en | ths_per, THS_TPR);
+
+ /* Enable the temperature IRQ */
+ writel(temp_irq_enable, THS_INT);
+
+ /* Make register setup atomic*/
+ wmb();
+
+ return 0;
+}
+
+/*
+ * Show THS values.
+ */
+static ssize_t
+show_values(struct device *dev, struct device_attribute *devattr, char
*buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+ /* Avoid race condition for first call */
+ if (ths_data <= THS_EAGAIN)
+ return -EAGAIN;
+
+ switch (attr->index) {
+ case 0:
+ sprintf(buf, "%d\n", ths_data);
+ break;
+ case 1:
+ sprintf(buf, "0x%x\n", data_clk_divider);
+ break;
+ case 2:
+ sprintf(buf, "0x%x\n", fs_div);
+ break;
+ case 3:
+ sprintf(buf, "0x%x\n", tacq);
+ break;
+ case 4:
+ sprintf(buf, "0x%x\n", chop_temp_en);
+ break;
+ case 5:
+ sprintf(buf, "0x%x\n", data_en);
+ break;
+ case 6:
+ sprintf(buf, "0x%x\n", ths_en);
+ break;
+ case 7:
+ sprintf(buf, "0x%x\n", ths_per);
+ break;
+ case 8:
+ sprintf(buf, "0x%x\n", data_pending);
+ break;
+ case 9:
+ sprintf(buf, "0x%x\n", data_first_dly);
+ break;
+ case 10:
+ sprintf(buf, "0x%x\n", data_first_dly_mode);
+ break;
+ case 11:
+ sprintf(buf, "%x %x %x %x %x %x %x %x\n",
+ data_clk_divider, fs_div, tacq, chop_temp_en,
+ temp_irq_enable, ths_en, ths_per, data_pending);
+ break;
+ default:
+ break;
+ }
+
+ return *buf;
+}
+
+/*
+ * Read THS values and Init THS with new values.
+ * User setable for power saving etc.
+ */
+static ssize_t
+read_values(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t n)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ long number;
+ int err = 0;
+
+ err = kstrtol(buf, 16, &number);
+ if (err)
+ return err;
+
+ switch (attr->index) {
+ case 1:
+ data_clk_divider = (uint32_t) number;
+ data_clk_divider &= (0xF << DATA_CLK_DIVIDER);
+ break;
+ case 2:
+ fs_div = (uint32_t) number;
+ fs_div &= (0xF << FS_DIV);
+ break;
+ case 3:
+ tacq = (uint32_t) number;
+ tacq &= (0xFF << TACQ);
+ break;
+ case 4:
+ chop_temp_en = (uint32_t) number;
+ chop_temp_en &= (1 << CHOP_TEMP_EN);
+ break;
+ case 5:
+ temp_irq_enable = (uint32_t) number;
+ temp_irq_enable &= (1 << TEMP_IRQ_ENABLE);
+ break;
+ case 6:
+ ths_en = (uint32_t) number;
+ ths_en &= (1 << THS_EN);
+ break;
+ case 7:
+ ths_per = (uint32_t) number;
+ ths_per &= (0xFFF << THS_PER);
+ break;
+ case 8:
+ data_pending = (uint32_t) number;
+ data_pending &= (1 << DATA_PENDING);
+ break;
+ case 9:
+ data_first_dly = (uint32_t) number;
+ data_first_dly &= (0xF << DATA_FIRST_DLY);
+ break;
+ case 10:
+ data_first_dly_mode = (uint32_t) number;
+ data_first_dly_mode &= (0xF << DATA_FIRST_DLY_MODE);
+ break;
+ default:
+ break;
+ }
+
+ /* init ADC again with new values */
+ ths_setup();
+
+ return n;
+}
+
+static SENSOR_DEVICE_ATTR(ths_data, S_IRUGO, show_values,
+ NULL, 0);
+static SENSOR_DEVICE_ATTR(data_clk_divider, THS_S_UGO, show_values,
+ read_values, 1);
+static SENSOR_DEVICE_ATTR(fs_div, THS_S_UGO, show_values,
+ read_values, 2);
+static SENSOR_DEVICE_ATTR(tacq, THS_S_UGO, show_values,
+ read_values, 3);
+static SENSOR_DEVICE_ATTR(chop_temp_en, THS_S_UGO, show_values,
+ read_values, 4);
+static SENSOR_DEVICE_ATTR(temp_irq_en, THS_S_UGO, show_values,
+ read_values, 5);
+static SENSOR_DEVICE_ATTR(ths_en, THS_S_UGO, show_values,
+ read_values, 6);
+static SENSOR_DEVICE_ATTR(ths_per, THS_S_UGO, show_values,
+ read_values, 7);
+static SENSOR_DEVICE_ATTR(data_pending, THS_S_UGO, show_values,
+ read_values, 8);
+static SENSOR_DEVICE_ATTR(data_first_dly, THS_S_UGO, show_values,
+ read_values, 9);
+static SENSOR_DEVICE_ATTR(data_first_dly_mode, THS_S_UGO, show_values,
+ read_values, 10);
+static SENSOR_DEVICE_ATTR(settings, THS_S_UGO, show_values,
+ NULL, 11);
+
+static struct attribute *ths_attributes[] = {
+ &sensor_dev_attr_ths_data.dev_attr.attr,
+ &sensor_dev_attr_data_clk_divider.dev_attr.attr,
+ &sensor_dev_attr_fs_div.dev_attr.attr,
+ &sensor_dev_attr_tacq.dev_attr.attr,
+ &sensor_dev_attr_chop_temp_en.dev_attr.attr,
+ &sensor_dev_attr_temp_irq_en.dev_attr.attr,
+ &sensor_dev_attr_ths_en.dev_attr.attr,
+ &sensor_dev_attr_ths_per.dev_attr.attr,
+ &sensor_dev_attr_data_pending.dev_attr.attr,
+ &sensor_dev_attr_data_first_dly.dev_attr.attr,
+ &sensor_dev_attr_data_first_dly_mode.dev_attr.attr,
+ &sensor_dev_attr_settings.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group ths_group = {
+ .attrs = ths_attributes
+};
+
+/*
+ * Interrupt routine for A2X Touchpad temperature
+ */
+static irqreturn_t ths_handle_irq(int irq, void *pdev)
+{
+ uint32_t reg_val;
+
+ reg_val = readl(THS_FIFOS);
+
+ /* Check if temperature interrupt triggered */
+ if (reg_val & (0x1 << DATA_PENDING)) {
+ /* Clear A2X TP Interrupt */
+ writel(reg_val | (0x1 << DATA_PENDING), THS_FIFOS);
+ /* Read and Calibrate Temperature Data */
+ reg_val = readl(THS_DATA);
+ /* Only 12 bits */
+ reg_val &= 0x00000FFF;
+ /* Calibrate temp value to Celcius*100 */
+ ths_data = ((reg_val - 1669 + 100) << 4);
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
+/*
+ * Device probing
+ */
+static int a2x_ths_hwmon_probe(struct platform_device *pdev)
+{
+ int irq = platform_get_irq(pdev, 0);
+ int err = 0;
+ struct device *hwmon_dev;
+
+ /* Modul Parameter check */
+ if (start_on_load)
+ ths_en = (1 << THS_EN);
+
+
+ /* Init THS register */
+ ths_setup();
+
+ /* create Int Handler */
+ err = request_irq(irq, ths_handle_irq,
+ IRQF_DISABLED, pdev->name, pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot request THS IRQ\n");
+ goto probe_err1;
+ }
+
+ /* create sysfs files */
+ err = sysfs_create_group(&pdev->dev.kobj, &ths_group);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot create sysfs group\n");
+ goto probe_err2;
+ }
+ /* register device in HWMON */
+ hwmon_dev = hwmon_device_register(&pdev->dev);
+
+ if (IS_ERR(hwmon_dev)) {
+ err = PTR_ERR(hwmon_dev);
+ goto probe_err3;
+ }
+
+ /* Signal load success */
+ dev_info(&pdev->dev, "TP initialization success\n");
+
+ return 0;
+
+probe_err3:
+ sysfs_remove_group(&pdev->dev.kobj, &ths_group);
+probe_err2:
+ free_irq(irq, pdev);
+probe_err1:
+ return err;
+}
+
+/*
+ * Device remove
+ */
+static int a2x_ths_hwmon_remove(struct platform_device *pdev)
+{
+ int irq = platform_get_irq(pdev, 0);
+
+ /* disable A2X THS INT */
+ writel((0 << THS_EN), THS_TPR);
+ /* release s/w interrupt routine */
+ free_irq(irq, pdev);
+
+ return 0;
+}
+
+
+static struct resource a2x_ths_hwmon_resource[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ .start = THS,
+ .end = THS + THS_IO_MEM_SIZE - 1
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ,
+ .start = SW_INT_IRQNO_TOUCH_PANEL,
+ .end = SW_INT_IRQNO_TOUCH_PANEL
+ }
+};
+
+static struct platform_device *a2x_ths_hwmon_device;
+
+static struct platform_driver a2x_ths_hwmon_driver = {
+ .probe = a2x_ths_hwmon_probe,
+ .remove = __devexit_p(a2x_ths_hwmon_remove),
+ .driver = {
+ .name = THS_MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+/*
+ * THS Init
+ */
+static int __init a2x_ths_init(void)
+{
+
+ int err = 0;
+
+ /* Get IO Address Range*/
+ if (!request_region(THS, THS_IO_MEM_SIZE, THS_MODULE_NAME)) {
+ pr_err("%s request region failed. Check /proc/ioports.\n",
+ THS_MODULE_NAME);
+ return -EBUSY;
+ }
+ err = platform_driver_register(&a2x_ths_hwmon_driver);
+ if (err) {
+ pr_err("%s driver register failed.\n", THS_MODULE_NAME);
+ goto init_err1;
+ }
+
+ a2x_ths_hwmon_device = platform_device_alloc(THS_MODULE_NAME, -1);
+ if (!a2x_ths_hwmon_device) {
+ pr_err("%s device_alloc failed.\n", THS_MODULE_NAME);
+ err = PTR_ERR(a2x_ths_hwmon_device);
+ goto init_err2;
+ }
+
+ err = platform_device_add_resources(a2x_ths_hwmon_device,
+ a2x_ths_hwmon_resource,
+ ARRAY_SIZE(a2x_ths_hwmon_resource));
+ if (err) {
+ pr_err("%s device_add_resources failed.\n", THS_MODULE_NAME);
+ goto init_err3;
+ }
+
+ err = platform_device_add(a2x_ths_hwmon_device);
+ if (err) {
+ pr_err("a2x_tp platform_device_add failed.\n");
+ goto init_err3;
+ }
+
+ return 0;
+
+init_err3:
+ platform_device_put(a2x_ths_hwmon_device);
+init_err2:
+ platform_driver_unregister(&a2x_ths_hwmon_driver);
+init_err1:
+ release_region(THS, THS_IO_MEM_SIZE);
+
+ return err;
+}
+
+/*
+ * Exit
+ */
+static void __exit a2x_ths_exit(void)
+{
+ platform_driver_unregister(&a2x_ths_hwmon_driver);
+ platform_device_unregister(a2x_ths_hwmon_device);
+ release_region(THS, THS_IO_MEM_SIZE);
+}
+
+module_init(a2x_ths_init);
+module_exit(a2x_ths_exit);
+
+MODULE_AUTHOR(A2X_AUTHOR);
+MODULE_DESCRIPTION(A2X_DESC);
+MODULE_LICENSE(A2X_LICENSE);
+MODULE_VERSION(A2X_VERSION);
--
2.1.0

Heiko Schröter

unread,
Jun 18, 2015, 12:02:44 PM6/18/15
to linux...@googlegroups.com, schr...@iup.physik.uni-bremen.de
Hello,

just seen that Hans did a temperature readout in sunxi-next in the
sun4i-ts module.
Sorry for the noise.

Regards
Heiko

Julian Calaby

unread,
Jun 18, 2015, 8:16:54 PM6/18/15
to schr...@iup.physik.uni-bremen.de, linux-sunxi
Hi Heiko,

On Fri, Jun 19, 2015 at 2:02 AM, Heiko Schröter
<schr...@iup.physik.uni-bremen.de> wrote:
> Hello,
>
> just seen that Hans did a temperature readout in sunxi-next in the sun4i-ts
> module.
> Sorry for the noise.

I was thinking of pointing out that any temperature sensor driver that
conflicts with the touch screen driver isn't going to fly and that you
should build your improvements (your driver is more configurable,
right?) into that driver instead of building a completely new one.

Thanks,

--
Julian Calaby

Email: julian...@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/

Thomas Kaiser

unread,
Jun 22, 2015, 8:31:00 AM6/22/15
to linux...@googlegroups.com
Hi,


schroete wrote on 18. Juni 2015 18:02:44 UTC+2:
just seen that Hans did a temperature readout in sunxi-next in the
sun4i-ts module.

If this is responsible for the value reported by /sys/devices/virtual/thermal/thermal_zone0/temp then the output seems to be wrong.

Steps to reproduce:

- ensure that the A20 board is idle and query /sys/devices/virtual/thermal/thermal_zone0/temp (will show you something below 37°C)
- press your thumb on the A20 while running and check again

Expected result: temperature exchange between thumb and SoC: If the SoC's temperature is below 37°C it should increase, if it's above it will decrease. What happens with kernel 4.0 or above: the temperature reported by thermal_zone0/temp will further decrease below 30° which seems to be impossible. Unfortunetaly I cannot provide patches but just report that there's something going wrong.

When I do a 'stress -t 900 -c 2 -m 2 -i 2' on an A20 board with kernel 4.0.4 then temperature doesn't exceed 42.5°C (very unrealistic) when doing the same with kernel 3.4.107 and the sunxi-dbgreg module approach ('echo 'f1c25004:90' > /sys/devices/virtual/misc/sunxi-dbgreg/rw/write;') temperatures reported rise above 50°.

m.sile...@gmail.com

unread,
Jun 22, 2015, 7:51:37 PM6/22/15
to linux...@googlegroups.com
I just noticed something even weirder on Linux 4.1.0:

Until 4.0.5 the temperature reading from /sys/devices/virtual/thermal/thermal_zone0/temp usually reported something around 40°C in my case.

Now when I use Linux 4.1.0 the temperature reads something between -15°C and -10°C which is obviously false.
Reply all
Reply to author
Forward
0 new messages