distribution/projects/Rockchip/packages/linux/patches/RK3399/005-adc-revert.patch
2024-01-09 22:53:16 +00:00

403 lines
12 KiB
Diff

diff -rupN linux.orig/drivers/iio/adc/rockchip_saradc.c linux/drivers/iio/adc/rockchip_saradc.c
--- linux.orig/drivers/iio/adc/rockchip_saradc.c 2024-01-09 14:07:12.430393829 +0000
+++ linux/drivers/iio/adc/rockchip_saradc.c 2024-01-09 16:30:43.561613614 +0000
@@ -4,13 +4,13 @@
* Copyright (C) 2014 ROCKCHIP, Inc.
*/
-#include <linux/bitfield.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
@@ -38,31 +38,10 @@
#define SARADC_TIMEOUT msecs_to_jiffies(100)
#define SARADC_MAX_CHANNELS 8
-/* v2 registers */
-#define SARADC2_CONV_CON 0x000
-#define SARADC_T_PD_SOC 0x004
-#define SARADC_T_DAS_SOC 0x00c
-#define SARADC2_END_INT_EN 0x104
-#define SARADC2_ST_CON 0x108
-#define SARADC2_STATUS 0x10c
-#define SARADC2_END_INT_ST 0x110
-#define SARADC2_DATA_BASE 0x120
-
-#define SARADC2_EN_END_INT BIT(0)
-#define SARADC2_START BIT(4)
-#define SARADC2_SINGLE_MODE BIT(5)
-
-#define SARADC2_CONV_CHANNELS GENMASK(15, 0)
-
-struct rockchip_saradc;
-
struct rockchip_saradc_data {
const struct iio_chan_spec *channels;
int num_channels;
unsigned long clk_rate;
- void (*start)(struct rockchip_saradc *info, int chn);
- int (*read)(struct rockchip_saradc *info);
- void (*power_down)(struct rockchip_saradc *info);
};
struct rockchip_saradc {
@@ -81,81 +60,27 @@ struct rockchip_saradc {
struct notifier_block nb;
};
-static void rockchip_saradc_reset_controller(struct reset_control *reset);
-
-static void rockchip_saradc_start_v1(struct rockchip_saradc *info, int chn)
-{
- /* 8 clock periods as delay between power up and start cmd */
- writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
- /* Select the channel to be used and trigger conversion */
- writel(SARADC_CTRL_POWER_CTRL | (chn & SARADC_CTRL_CHN_MASK) |
- SARADC_CTRL_IRQ_ENABLE, info->regs + SARADC_CTRL);
-}
-
-static void rockchip_saradc_start_v2(struct rockchip_saradc *info, int chn)
-{
- int val;
-
- if (info->reset)
- rockchip_saradc_reset_controller(info->reset);
-
- writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC);
- writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
- val = FIELD_PREP(SARADC2_EN_END_INT, 1);
- val |= val << 16;
- writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
- val = FIELD_PREP(SARADC2_START, 1) |
- FIELD_PREP(SARADC2_SINGLE_MODE, 1) |
- FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
- val |= val << 16;
- writel(val, info->regs + SARADC2_CONV_CON);
-}
-
-static void rockchip_saradc_start(struct rockchip_saradc *info, int chn)
-{
- info->data->start(info, chn);
-}
-
-static int rockchip_saradc_read_v1(struct rockchip_saradc *info)
-{
- return readl_relaxed(info->regs + SARADC_DATA);
-}
-
-static int rockchip_saradc_read_v2(struct rockchip_saradc *info)
-{
- int offset;
-
- /* Clear irq */
- writel_relaxed(0x1, info->regs + SARADC2_END_INT_ST);
-
- offset = SARADC2_DATA_BASE + info->last_chan->channel * 0x4;
-
- return readl_relaxed(info->regs + offset);
-}
-
-static int rockchip_saradc_read(struct rockchip_saradc *info)
-{
- return info->data->read(info);
-}
-
-static void rockchip_saradc_power_down_v1(struct rockchip_saradc *info)
-{
- writel_relaxed(0, info->regs + SARADC_CTRL);
-}
-
static void rockchip_saradc_power_down(struct rockchip_saradc *info)
{
- if (info->data->power_down)
- info->data->power_down(info);
+ /* Clear irq & power down adc */
+ writel_relaxed(0, info->regs + SARADC_CTRL);
}
static int rockchip_saradc_conversion(struct rockchip_saradc *info,
- struct iio_chan_spec const *chan)
+ struct iio_chan_spec const *chan)
{
reinit_completion(&info->completion);
+ /* 8 clock periods as delay between power up and start cmd */
+ writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
+
info->last_chan = chan;
- rockchip_saradc_start(info, chan->channel);
+
+ /* Select the channel to be used and trigger conversion */
+ writel(SARADC_CTRL_POWER_CTRL
+ | (chan->channel & SARADC_CTRL_CHN_MASK)
+ | SARADC_CTRL_IRQ_ENABLE,
+ info->regs + SARADC_CTRL);
if (!wait_for_completion_timeout(&info->completion, SARADC_TIMEOUT))
return -ETIMEDOUT;
@@ -198,7 +123,7 @@ static irqreturn_t rockchip_saradc_isr(i
struct rockchip_saradc *info = dev_id;
/* Read value */
- info->last_val = rockchip_saradc_read(info);
+ info->last_val = readl_relaxed(info->regs + SARADC_DATA);
info->last_val &= GENMASK(info->last_chan->scan_type.realbits - 1, 0);
rockchip_saradc_power_down(info);
@@ -238,9 +163,6 @@ static const struct rockchip_saradc_data
.channels = rockchip_saradc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels),
.clk_rate = 1000000,
- .start = rockchip_saradc_start_v1,
- .read = rockchip_saradc_read_v1,
- .power_down = rockchip_saradc_power_down_v1,
};
static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = {
@@ -252,9 +174,6 @@ static const struct rockchip_saradc_data
.channels = rockchip_rk3066_tsadc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels),
.clk_rate = 50000,
- .start = rockchip_saradc_start_v1,
- .read = rockchip_saradc_read_v1,
- .power_down = rockchip_saradc_power_down_v1,
};
static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = {
@@ -270,9 +189,6 @@ static const struct rockchip_saradc_data
.channels = rockchip_rk3399_saradc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels),
.clk_rate = 1000000,
- .start = rockchip_saradc_start_v1,
- .read = rockchip_saradc_read_v1,
- .power_down = rockchip_saradc_power_down_v1,
};
static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = {
@@ -290,28 +206,6 @@ static const struct rockchip_saradc_data
.channels = rockchip_rk3568_saradc_iio_channels,
.num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels),
.clk_rate = 1000000,
- .start = rockchip_saradc_start_v1,
- .read = rockchip_saradc_read_v1,
- .power_down = rockchip_saradc_power_down_v1,
-};
-
-static const struct iio_chan_spec rockchip_rk3588_saradc_iio_channels[] = {
- SARADC_CHANNEL(0, "adc0", 12),
- SARADC_CHANNEL(1, "adc1", 12),
- SARADC_CHANNEL(2, "adc2", 12),
- SARADC_CHANNEL(3, "adc3", 12),
- SARADC_CHANNEL(4, "adc4", 12),
- SARADC_CHANNEL(5, "adc5", 12),
- SARADC_CHANNEL(6, "adc6", 12),
- SARADC_CHANNEL(7, "adc7", 12),
-};
-
-static const struct rockchip_saradc_data rk3588_saradc_data = {
- .channels = rockchip_rk3588_saradc_iio_channels,
- .num_channels = ARRAY_SIZE(rockchip_rk3588_saradc_iio_channels),
- .clk_rate = 1000000,
- .start = rockchip_saradc_start_v2,
- .read = rockchip_saradc_read_v2,
};
static const struct of_device_id rockchip_saradc_match[] = {
@@ -327,9 +221,6 @@ static const struct of_device_id rockchi
}, {
.compatible = "rockchip,rk3568-saradc",
.data = &rk3568_saradc_data,
- }, {
- .compatible = "rockchip,rk3588-saradc",
- .data = &rk3588_saradc_data,
},
{},
};
@@ -345,6 +236,20 @@ static void rockchip_saradc_reset_contro
reset_control_deassert(reset);
}
+static void rockchip_saradc_clk_disable(void *data)
+{
+ struct rockchip_saradc *info = data;
+
+ clk_disable_unprepare(info->clk);
+}
+
+static void rockchip_saradc_pclk_disable(void *data)
+{
+ struct rockchip_saradc *info = data;
+
+ clk_disable_unprepare(info->pclk);
+}
+
static void rockchip_saradc_regulator_disable(void *data)
{
struct rockchip_saradc *info = data;
@@ -393,7 +298,8 @@ out:
}
static int rockchip_saradc_volt_notify(struct notifier_block *nb,
- unsigned long event, void *data)
+ unsigned long event,
+ void *data)
{
struct rockchip_saradc *info =
container_of(nb, struct rockchip_saradc, nb);
@@ -413,10 +319,10 @@ static void rockchip_saradc_regulator_un
static int rockchip_saradc_probe(struct platform_device *pdev)
{
- const struct rockchip_saradc_data *match_data;
struct rockchip_saradc *info = NULL;
struct device_node *np = pdev->dev.of_node;
struct iio_dev *indio_dev = NULL;
+ const struct of_device_id *match;
int ret;
int irq;
@@ -424,23 +330,25 @@ static int rockchip_saradc_probe(struct
return -ENODEV;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
- if (!indio_dev)
- return dev_err_probe(&pdev->dev, -ENOMEM,
- "failed allocating iio device\n");
-
+ if (!indio_dev) {
+ dev_err(&pdev->dev, "failed allocating iio device\n");
+ return -ENOMEM;
+ }
info = iio_priv(indio_dev);
- match_data = of_device_get_match_data(&pdev->dev);
- if (!match_data)
- return dev_err_probe(&pdev->dev, -ENODEV,
- "failed to match device\n");
+ match = of_match_device(rockchip_saradc_match, &pdev->dev);
+ if (!match) {
+ dev_err(&pdev->dev, "failed to match device\n");
+ return -ENODEV;
+ }
- info->data = match_data;
+ info->data = match->data;
/* Sanity check for possible later IP variants with more channels */
- if (info->data->num_channels > SARADC_MAX_CHANNELS)
- return dev_err_probe(&pdev->dev, -EINVAL,
- "max channels exceeded");
+ if (info->data->num_channels > SARADC_MAX_CHANNELS) {
+ dev_err(&pdev->dev, "max channels exceeded");
+ return -EINVAL;
+ }
info->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(info->regs))
@@ -466,7 +374,7 @@ static int rockchip_saradc_probe(struct
irq = platform_get_irq(pdev, 0);
if (irq < 0)
- return irq;
+ return dev_err_probe(&pdev->dev, irq, "failed to get irq\n");
ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr,
0, dev_name(&pdev->dev), info);
@@ -475,6 +383,16 @@ static int rockchip_saradc_probe(struct
return ret;
}
+ info->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
+ if (IS_ERR(info->pclk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk),
+ "failed to get pclk\n");
+
+ info->clk = devm_clk_get(&pdev->dev, "saradc");
+ if (IS_ERR(info->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
+ "failed to get adc clock\n");
+
info->vref = devm_regulator_get(&pdev->dev, "vref");
if (IS_ERR(info->vref))
return dev_err_probe(&pdev->dev, PTR_ERR(info->vref),
@@ -488,20 +406,23 @@ static int rockchip_saradc_probe(struct
* This may become user-configurable in the future.
*/
ret = clk_set_rate(info->clk, info->data->clk_rate);
- if (ret < 0)
- return dev_err_probe(&pdev->dev, ret,
- "failed to set adc clk rate\n");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret);
+ return ret;
+ }
ret = regulator_enable(info->vref);
- if (ret < 0)
- return dev_err_probe(&pdev->dev, ret,
- "failed to enable vref regulator\n");
-
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to enable vref regulator\n");
+ return ret;
+ }
ret = devm_add_action_or_reset(&pdev->dev,
rockchip_saradc_regulator_disable, info);
- if (ret)
- return dev_err_probe(&pdev->dev, ret,
- "failed to register devm action\n");
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register devm action, %d\n",
+ ret);
+ return ret;
+ }
ret = regulator_get_voltage(info->vref);
if (ret < 0)
@@ -509,15 +430,31 @@ static int rockchip_saradc_probe(struct
info->uv_vref = ret;
- info->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk");
- if (IS_ERR(info->pclk))
- return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk),
- "failed to get pclk\n");
+ ret = clk_prepare_enable(info->pclk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to enable pclk\n");
+ return ret;
+ }
+ ret = devm_add_action_or_reset(&pdev->dev,
+ rockchip_saradc_pclk_disable, info);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register devm action, %d\n",
+ ret);
+ return ret;
+ }
- info->clk = devm_clk_get_enabled(&pdev->dev, "saradc");
- if (IS_ERR(info->clk))
- return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
- "failed to get adc clock\n");
+ ret = clk_prepare_enable(info->clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to enable converter clock\n");
+ return ret;
+ }
+ ret = devm_add_action_or_reset(&pdev->dev,
+ rockchip_saradc_clk_disable, info);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register devm action, %d\n",
+ ret);
+ return ret;
+ }
platform_set_drvdata(pdev, indio_dev);