|
@@ -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 @@
|
|
#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,
|
|
}
|
|
}
|
|
|
|
|
|
*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)
|
|
|
|
|
|
/* 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[] = {
|
|
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)
|
|
}
|
|
}
|
|
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)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * 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)
|
|
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->num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels);
|
|
|
|
|
|
+ indio_dev->channels = info->data->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)
|
|
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,
|