Commit 4c21bbb4 authored by Heiko Stübner's avatar Heiko Stübner Committed by Jonathan Cameron

iio: adc: rockchip_saradc: add support for rk3066-tsadc variant

Older Rockchip SoCs, at least the rk3066, used a slightly modified saradc
for temperature measurements. This so called tsadc does not contain any
active parts like temperature interrupts and only supports polling the
current temperature. The returned voltage can then be converted by a
suitable thermal driver to and actual temperature and used for thermal
handling.
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Acked-by: default avatarHartmut Knaack <knaack.h@gmx.de>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 774623ca
Rockchip Successive Approximation Register (SAR) A/D Converter bindings Rockchip Successive Approximation Register (SAR) A/D Converter bindings
Required properties: Required properties:
- compatible: Should be "rockchip,saradc" - compatible: Should be "rockchip,saradc" or "rockchip,rk3066-tsadc"
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
- interrupts: The interrupt number to the cpu. The interrupt specifier format - interrupts: The interrupt number to the cpu. The interrupt specifier format
......
...@@ -18,13 +18,13 @@ ...@@ -18,13 +18,13 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#define SARADC_DATA 0x00 #define SARADC_DATA 0x00
#define SARADC_DATA_MASK 0x3ff
#define SARADC_STAS 0x04 #define SARADC_STAS 0x04
#define SARADC_STAS_BUSY BIT(0) #define SARADC_STAS_BUSY BIT(0)
...@@ -38,15 +38,22 @@ ...@@ -38,15 +38,22 @@
#define SARADC_DLY_PU_SOC 0x0c #define SARADC_DLY_PU_SOC 0x0c
#define SARADC_DLY_PU_SOC_MASK 0x3f #define SARADC_DLY_PU_SOC_MASK 0x3f
#define SARADC_BITS 10
#define SARADC_TIMEOUT msecs_to_jiffies(100) #define SARADC_TIMEOUT msecs_to_jiffies(100)
struct rockchip_saradc_data {
int num_bits;
const struct iio_chan_spec *channels;
int num_channels;
unsigned long clk_rate;
};
struct rockchip_saradc { struct rockchip_saradc {
void __iomem *regs; void __iomem *regs;
struct clk *pclk; struct clk *pclk;
struct clk *clk; struct clk *clk;
struct completion completion; struct completion completion;
struct regulator *vref; struct regulator *vref;
const struct rockchip_saradc_data *data;
u16 last_val; u16 last_val;
}; };
...@@ -90,7 +97,7 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, ...@@ -90,7 +97,7 @@ static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
} }
*val = ret / 1000; *val = ret / 1000;
*val2 = SARADC_BITS; *val2 = info->data->num_bits;
return IIO_VAL_FRACTIONAL_LOG2; return IIO_VAL_FRACTIONAL_LOG2;
default: default:
return -EINVAL; return -EINVAL;
...@@ -103,7 +110,7 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) ...@@ -103,7 +110,7 @@ static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)
/* Read value */ /* Read value */
info->last_val = readl_relaxed(info->regs + SARADC_DATA); info->last_val = readl_relaxed(info->regs + SARADC_DATA);
info->last_val &= SARADC_DATA_MASK; info->last_val &= GENMASK(info->data->num_bits - 1, 0);
/* Clear irq & power down adc */ /* Clear irq & power down adc */
writel_relaxed(0, info->regs + SARADC_CTRL); writel_relaxed(0, info->regs + SARADC_CTRL);
...@@ -133,12 +140,44 @@ static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { ...@@ -133,12 +140,44 @@ static const struct iio_chan_spec rockchip_saradc_iio_channels[] = {
ADC_CHANNEL(2, "adc2"), ADC_CHANNEL(2, "adc2"),
}; };
static const struct rockchip_saradc_data saradc_data = {
.num_bits = 10,
.channels = rockchip_saradc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels),
.clk_rate = 1000000,
};
static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = {
ADC_CHANNEL(0, "adc0"),
ADC_CHANNEL(1, "adc1"),
};
static const struct rockchip_saradc_data rk3066_tsadc_data = {
.num_bits = 12,
.channels = rockchip_rk3066_tsadc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels),
.clk_rate = 50000,
};
static const struct of_device_id rockchip_saradc_match[] = {
{
.compatible = "rockchip,saradc",
.data = &saradc_data,
}, {
.compatible = "rockchip,rk3066-tsadc",
.data = &rk3066_tsadc_data,
},
{},
};
MODULE_DEVICE_TABLE(of, rockchip_saradc_match);
static int rockchip_saradc_probe(struct platform_device *pdev) static int rockchip_saradc_probe(struct platform_device *pdev)
{ {
struct rockchip_saradc *info = NULL; struct rockchip_saradc *info = NULL;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct iio_dev *indio_dev = NULL; struct iio_dev *indio_dev = NULL;
struct resource *mem; struct resource *mem;
const struct of_device_id *match;
int ret; int ret;
int irq; int irq;
...@@ -152,6 +191,9 @@ static int rockchip_saradc_probe(struct platform_device *pdev) ...@@ -152,6 +191,9 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
} }
info = iio_priv(indio_dev); info = iio_priv(indio_dev);
match = of_match_device(rockchip_saradc_match, &pdev->dev);
info->data = match->data;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
info->regs = devm_ioremap_resource(&pdev->dev, mem); info->regs = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(info->regs)) if (IS_ERR(info->regs))
...@@ -192,10 +234,10 @@ static int rockchip_saradc_probe(struct platform_device *pdev) ...@@ -192,10 +234,10 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
} }
/* /*
* Use a default of 1MHz for the converter clock. * Use a default value for the converter clock.
* This may become user-configurable in the future. * This may become user-configurable in the future.
*/ */
ret = clk_set_rate(info->clk, 1000000); ret = clk_set_rate(info->clk, info->data->clk_rate);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret);
return ret; return ret;
...@@ -227,8 +269,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) ...@@ -227,8 +269,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
indio_dev->info = &rockchip_saradc_iio_info; indio_dev->info = &rockchip_saradc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = rockchip_saradc_iio_channels; indio_dev->channels = info->data->channels;
indio_dev->num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels); indio_dev->num_channels = info->data->num_channels;
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret) if (ret)
...@@ -296,12 +338,6 @@ static int rockchip_saradc_resume(struct device *dev) ...@@ -296,12 +338,6 @@ static int rockchip_saradc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops, static SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops,
rockchip_saradc_suspend, rockchip_saradc_resume); rockchip_saradc_suspend, rockchip_saradc_resume);
static const struct of_device_id rockchip_saradc_match[] = {
{ .compatible = "rockchip,saradc" },
{},
};
MODULE_DEVICE_TABLE(of, rockchip_saradc_match);
static struct platform_driver rockchip_saradc_driver = { static struct platform_driver rockchip_saradc_driver = {
.probe = rockchip_saradc_probe, .probe = rockchip_saradc_probe,
.remove = rockchip_saradc_remove, .remove = rockchip_saradc_remove,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment