cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rockchip_saradc.c (13452B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Rockchip Successive Approximation Register (SAR) A/D Converter
      4 * Copyright (C) 2014 ROCKCHIP, Inc.
      5 */
      6
      7#include <linux/module.h>
      8#include <linux/platform_device.h>
      9#include <linux/interrupt.h>
     10#include <linux/io.h>
     11#include <linux/of.h>
     12#include <linux/of_device.h>
     13#include <linux/clk.h>
     14#include <linux/completion.h>
     15#include <linux/delay.h>
     16#include <linux/reset.h>
     17#include <linux/regulator/consumer.h>
     18#include <linux/iio/buffer.h>
     19#include <linux/iio/iio.h>
     20#include <linux/iio/trigger_consumer.h>
     21#include <linux/iio/triggered_buffer.h>
     22
     23#define SARADC_DATA			0x00
     24
     25#define SARADC_STAS			0x04
     26#define SARADC_STAS_BUSY		BIT(0)
     27
     28#define SARADC_CTRL			0x08
     29#define SARADC_CTRL_IRQ_STATUS		BIT(6)
     30#define SARADC_CTRL_IRQ_ENABLE		BIT(5)
     31#define SARADC_CTRL_POWER_CTRL		BIT(3)
     32#define SARADC_CTRL_CHN_MASK		0x7
     33
     34#define SARADC_DLY_PU_SOC		0x0c
     35#define SARADC_DLY_PU_SOC_MASK		0x3f
     36
     37#define SARADC_TIMEOUT			msecs_to_jiffies(100)
     38#define SARADC_MAX_CHANNELS		8
     39
     40struct rockchip_saradc_data {
     41	const struct iio_chan_spec	*channels;
     42	int				num_channels;
     43	unsigned long			clk_rate;
     44};
     45
     46struct rockchip_saradc {
     47	void __iomem		*regs;
     48	struct clk		*pclk;
     49	struct clk		*clk;
     50	struct completion	completion;
     51	struct regulator	*vref;
     52	int			uv_vref;
     53	struct reset_control	*reset;
     54	const struct rockchip_saradc_data *data;
     55	u16			last_val;
     56	const struct iio_chan_spec *last_chan;
     57	struct notifier_block nb;
     58};
     59
     60static void rockchip_saradc_power_down(struct rockchip_saradc *info)
     61{
     62	/* Clear irq & power down adc */
     63	writel_relaxed(0, info->regs + SARADC_CTRL);
     64}
     65
     66static int rockchip_saradc_conversion(struct rockchip_saradc *info,
     67				   struct iio_chan_spec const *chan)
     68{
     69	reinit_completion(&info->completion);
     70
     71	/* 8 clock periods as delay between power up and start cmd */
     72	writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC);
     73
     74	info->last_chan = chan;
     75
     76	/* Select the channel to be used and trigger conversion */
     77	writel(SARADC_CTRL_POWER_CTRL
     78			| (chan->channel & SARADC_CTRL_CHN_MASK)
     79			| SARADC_CTRL_IRQ_ENABLE,
     80		   info->regs + SARADC_CTRL);
     81
     82	if (!wait_for_completion_timeout(&info->completion, SARADC_TIMEOUT))
     83		return -ETIMEDOUT;
     84
     85	return 0;
     86}
     87
     88static int rockchip_saradc_read_raw(struct iio_dev *indio_dev,
     89				    struct iio_chan_spec const *chan,
     90				    int *val, int *val2, long mask)
     91{
     92	struct rockchip_saradc *info = iio_priv(indio_dev);
     93	int ret;
     94
     95	switch (mask) {
     96	case IIO_CHAN_INFO_RAW:
     97		mutex_lock(&indio_dev->mlock);
     98
     99		ret = rockchip_saradc_conversion(info, chan);
    100		if (ret) {
    101			rockchip_saradc_power_down(info);
    102			mutex_unlock(&indio_dev->mlock);
    103			return ret;
    104		}
    105
    106		*val = info->last_val;
    107		mutex_unlock(&indio_dev->mlock);
    108		return IIO_VAL_INT;
    109	case IIO_CHAN_INFO_SCALE:
    110		*val = info->uv_vref / 1000;
    111		*val2 = chan->scan_type.realbits;
    112		return IIO_VAL_FRACTIONAL_LOG2;
    113	default:
    114		return -EINVAL;
    115	}
    116}
    117
    118static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id)
    119{
    120	struct rockchip_saradc *info = dev_id;
    121
    122	/* Read value */
    123	info->last_val = readl_relaxed(info->regs + SARADC_DATA);
    124	info->last_val &= GENMASK(info->last_chan->scan_type.realbits - 1, 0);
    125
    126	rockchip_saradc_power_down(info);
    127
    128	complete(&info->completion);
    129
    130	return IRQ_HANDLED;
    131}
    132
    133static const struct iio_info rockchip_saradc_iio_info = {
    134	.read_raw = rockchip_saradc_read_raw,
    135};
    136
    137#define SARADC_CHANNEL(_index, _id, _res) {			\
    138	.type = IIO_VOLTAGE,					\
    139	.indexed = 1,						\
    140	.channel = _index,					\
    141	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
    142	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
    143	.datasheet_name = _id,					\
    144	.scan_index = _index,					\
    145	.scan_type = {						\
    146		.sign = 'u',					\
    147		.realbits = _res,				\
    148		.storagebits = 16,				\
    149		.endianness = IIO_CPU,				\
    150	},							\
    151}
    152
    153static const struct iio_chan_spec rockchip_saradc_iio_channels[] = {
    154	SARADC_CHANNEL(0, "adc0", 10),
    155	SARADC_CHANNEL(1, "adc1", 10),
    156	SARADC_CHANNEL(2, "adc2", 10),
    157};
    158
    159static const struct rockchip_saradc_data saradc_data = {
    160	.channels = rockchip_saradc_iio_channels,
    161	.num_channels = ARRAY_SIZE(rockchip_saradc_iio_channels),
    162	.clk_rate = 1000000,
    163};
    164
    165static const struct iio_chan_spec rockchip_rk3066_tsadc_iio_channels[] = {
    166	SARADC_CHANNEL(0, "adc0", 12),
    167	SARADC_CHANNEL(1, "adc1", 12),
    168};
    169
    170static const struct rockchip_saradc_data rk3066_tsadc_data = {
    171	.channels = rockchip_rk3066_tsadc_iio_channels,
    172	.num_channels = ARRAY_SIZE(rockchip_rk3066_tsadc_iio_channels),
    173	.clk_rate = 50000,
    174};
    175
    176static const struct iio_chan_spec rockchip_rk3399_saradc_iio_channels[] = {
    177	SARADC_CHANNEL(0, "adc0", 10),
    178	SARADC_CHANNEL(1, "adc1", 10),
    179	SARADC_CHANNEL(2, "adc2", 10),
    180	SARADC_CHANNEL(3, "adc3", 10),
    181	SARADC_CHANNEL(4, "adc4", 10),
    182	SARADC_CHANNEL(5, "adc5", 10),
    183};
    184
    185static const struct rockchip_saradc_data rk3399_saradc_data = {
    186	.channels = rockchip_rk3399_saradc_iio_channels,
    187	.num_channels = ARRAY_SIZE(rockchip_rk3399_saradc_iio_channels),
    188	.clk_rate = 1000000,
    189};
    190
    191static const struct iio_chan_spec rockchip_rk3568_saradc_iio_channels[] = {
    192	SARADC_CHANNEL(0, "adc0", 10),
    193	SARADC_CHANNEL(1, "adc1", 10),
    194	SARADC_CHANNEL(2, "adc2", 10),
    195	SARADC_CHANNEL(3, "adc3", 10),
    196	SARADC_CHANNEL(4, "adc4", 10),
    197	SARADC_CHANNEL(5, "adc5", 10),
    198	SARADC_CHANNEL(6, "adc6", 10),
    199	SARADC_CHANNEL(7, "adc7", 10),
    200};
    201
    202static const struct rockchip_saradc_data rk3568_saradc_data = {
    203	.channels = rockchip_rk3568_saradc_iio_channels,
    204	.num_channels = ARRAY_SIZE(rockchip_rk3568_saradc_iio_channels),
    205	.clk_rate = 1000000,
    206};
    207
    208static const struct of_device_id rockchip_saradc_match[] = {
    209	{
    210		.compatible = "rockchip,saradc",
    211		.data = &saradc_data,
    212	}, {
    213		.compatible = "rockchip,rk3066-tsadc",
    214		.data = &rk3066_tsadc_data,
    215	}, {
    216		.compatible = "rockchip,rk3399-saradc",
    217		.data = &rk3399_saradc_data,
    218	}, {
    219		.compatible = "rockchip,rk3568-saradc",
    220		.data = &rk3568_saradc_data,
    221	},
    222	{},
    223};
    224MODULE_DEVICE_TABLE(of, rockchip_saradc_match);
    225
    226/*
    227 * Reset SARADC Controller.
    228 */
    229static void rockchip_saradc_reset_controller(struct reset_control *reset)
    230{
    231	reset_control_assert(reset);
    232	usleep_range(10, 20);
    233	reset_control_deassert(reset);
    234}
    235
    236static void rockchip_saradc_clk_disable(void *data)
    237{
    238	struct rockchip_saradc *info = data;
    239
    240	clk_disable_unprepare(info->clk);
    241}
    242
    243static void rockchip_saradc_pclk_disable(void *data)
    244{
    245	struct rockchip_saradc *info = data;
    246
    247	clk_disable_unprepare(info->pclk);
    248}
    249
    250static void rockchip_saradc_regulator_disable(void *data)
    251{
    252	struct rockchip_saradc *info = data;
    253
    254	regulator_disable(info->vref);
    255}
    256
    257static irqreturn_t rockchip_saradc_trigger_handler(int irq, void *p)
    258{
    259	struct iio_poll_func *pf = p;
    260	struct iio_dev *i_dev = pf->indio_dev;
    261	struct rockchip_saradc *info = iio_priv(i_dev);
    262	/*
    263	 * @values: each channel takes an u16 value
    264	 * @timestamp: will be 8-byte aligned automatically
    265	 */
    266	struct {
    267		u16 values[SARADC_MAX_CHANNELS];
    268		int64_t timestamp;
    269	} data;
    270	int ret;
    271	int i, j = 0;
    272
    273	mutex_lock(&i_dev->mlock);
    274
    275	for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) {
    276		const struct iio_chan_spec *chan = &i_dev->channels[i];
    277
    278		ret = rockchip_saradc_conversion(info, chan);
    279		if (ret) {
    280			rockchip_saradc_power_down(info);
    281			goto out;
    282		}
    283
    284		data.values[j] = info->last_val;
    285		j++;
    286	}
    287
    288	iio_push_to_buffers_with_timestamp(i_dev, &data, iio_get_time_ns(i_dev));
    289out:
    290	mutex_unlock(&i_dev->mlock);
    291
    292	iio_trigger_notify_done(i_dev->trig);
    293
    294	return IRQ_HANDLED;
    295}
    296
    297static int rockchip_saradc_volt_notify(struct notifier_block *nb,
    298						   unsigned long event,
    299						   void *data)
    300{
    301	struct rockchip_saradc *info =
    302			container_of(nb, struct rockchip_saradc, nb);
    303
    304	if (event & REGULATOR_EVENT_VOLTAGE_CHANGE)
    305		info->uv_vref = (unsigned long)data;
    306
    307	return NOTIFY_OK;
    308}
    309
    310static void rockchip_saradc_regulator_unreg_notifier(void *data)
    311{
    312	struct rockchip_saradc *info = data;
    313
    314	regulator_unregister_notifier(info->vref, &info->nb);
    315}
    316
    317static int rockchip_saradc_probe(struct platform_device *pdev)
    318{
    319	struct rockchip_saradc *info = NULL;
    320	struct device_node *np = pdev->dev.of_node;
    321	struct iio_dev *indio_dev = NULL;
    322	const struct of_device_id *match;
    323	int ret;
    324	int irq;
    325
    326	if (!np)
    327		return -ENODEV;
    328
    329	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
    330	if (!indio_dev) {
    331		dev_err(&pdev->dev, "failed allocating iio device\n");
    332		return -ENOMEM;
    333	}
    334	info = iio_priv(indio_dev);
    335
    336	match = of_match_device(rockchip_saradc_match, &pdev->dev);
    337	if (!match) {
    338		dev_err(&pdev->dev, "failed to match device\n");
    339		return -ENODEV;
    340	}
    341
    342	info->data = match->data;
    343
    344	/* Sanity check for possible later IP variants with more channels */
    345	if (info->data->num_channels > SARADC_MAX_CHANNELS) {
    346		dev_err(&pdev->dev, "max channels exceeded");
    347		return -EINVAL;
    348	}
    349
    350	info->regs = devm_platform_ioremap_resource(pdev, 0);
    351	if (IS_ERR(info->regs))
    352		return PTR_ERR(info->regs);
    353
    354	/*
    355	 * The reset should be an optional property, as it should work
    356	 * with old devicetrees as well
    357	 */
    358	info->reset = devm_reset_control_get_exclusive(&pdev->dev,
    359						       "saradc-apb");
    360	if (IS_ERR(info->reset)) {
    361		ret = PTR_ERR(info->reset);
    362		if (ret != -ENOENT)
    363			return dev_err_probe(&pdev->dev, ret,
    364					     "failed to get saradc-apb\n");
    365
    366		dev_dbg(&pdev->dev, "no reset control found\n");
    367		info->reset = NULL;
    368	}
    369
    370	init_completion(&info->completion);
    371
    372	irq = platform_get_irq(pdev, 0);
    373	if (irq < 0)
    374		return dev_err_probe(&pdev->dev, irq, "failed to get irq\n");
    375
    376	ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr,
    377			       0, dev_name(&pdev->dev), info);
    378	if (ret < 0) {
    379		dev_err(&pdev->dev, "failed requesting irq %d\n", irq);
    380		return ret;
    381	}
    382
    383	info->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
    384	if (IS_ERR(info->pclk))
    385		return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk),
    386				     "failed to get pclk\n");
    387
    388	info->clk = devm_clk_get(&pdev->dev, "saradc");
    389	if (IS_ERR(info->clk))
    390		return dev_err_probe(&pdev->dev, PTR_ERR(info->clk),
    391				     "failed to get adc clock\n");
    392
    393	info->vref = devm_regulator_get(&pdev->dev, "vref");
    394	if (IS_ERR(info->vref))
    395		return dev_err_probe(&pdev->dev, PTR_ERR(info->vref),
    396				     "failed to get regulator\n");
    397
    398	if (info->reset)
    399		rockchip_saradc_reset_controller(info->reset);
    400
    401	/*
    402	 * Use a default value for the converter clock.
    403	 * This may become user-configurable in the future.
    404	 */
    405	ret = clk_set_rate(info->clk, info->data->clk_rate);
    406	if (ret < 0) {
    407		dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret);
    408		return ret;
    409	}
    410
    411	ret = regulator_enable(info->vref);
    412	if (ret < 0) {
    413		dev_err(&pdev->dev, "failed to enable vref regulator\n");
    414		return ret;
    415	}
    416	ret = devm_add_action_or_reset(&pdev->dev,
    417				       rockchip_saradc_regulator_disable, info);
    418	if (ret) {
    419		dev_err(&pdev->dev, "failed to register devm action, %d\n",
    420			ret);
    421		return ret;
    422	}
    423
    424	ret = regulator_get_voltage(info->vref);
    425	if (ret < 0)
    426		return ret;
    427
    428	info->uv_vref = ret;
    429
    430	ret = clk_prepare_enable(info->pclk);
    431	if (ret < 0) {
    432		dev_err(&pdev->dev, "failed to enable pclk\n");
    433		return ret;
    434	}
    435	ret = devm_add_action_or_reset(&pdev->dev,
    436				       rockchip_saradc_pclk_disable, info);
    437	if (ret) {
    438		dev_err(&pdev->dev, "failed to register devm action, %d\n",
    439			ret);
    440		return ret;
    441	}
    442
    443	ret = clk_prepare_enable(info->clk);
    444	if (ret < 0) {
    445		dev_err(&pdev->dev, "failed to enable converter clock\n");
    446		return ret;
    447	}
    448	ret = devm_add_action_or_reset(&pdev->dev,
    449				       rockchip_saradc_clk_disable, info);
    450	if (ret) {
    451		dev_err(&pdev->dev, "failed to register devm action, %d\n",
    452			ret);
    453		return ret;
    454	}
    455
    456	platform_set_drvdata(pdev, indio_dev);
    457
    458	indio_dev->name = dev_name(&pdev->dev);
    459	indio_dev->info = &rockchip_saradc_iio_info;
    460	indio_dev->modes = INDIO_DIRECT_MODE;
    461
    462	indio_dev->channels = info->data->channels;
    463	indio_dev->num_channels = info->data->num_channels;
    464	ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL,
    465					      rockchip_saradc_trigger_handler,
    466					      NULL);
    467	if (ret)
    468		return ret;
    469
    470	info->nb.notifier_call = rockchip_saradc_volt_notify;
    471	ret = regulator_register_notifier(info->vref, &info->nb);
    472	if (ret)
    473		return ret;
    474
    475	ret = devm_add_action_or_reset(&pdev->dev,
    476				       rockchip_saradc_regulator_unreg_notifier,
    477				       info);
    478	if (ret)
    479		return ret;
    480
    481	return devm_iio_device_register(&pdev->dev, indio_dev);
    482}
    483
    484static int rockchip_saradc_suspend(struct device *dev)
    485{
    486	struct iio_dev *indio_dev = dev_get_drvdata(dev);
    487	struct rockchip_saradc *info = iio_priv(indio_dev);
    488
    489	clk_disable_unprepare(info->clk);
    490	clk_disable_unprepare(info->pclk);
    491	regulator_disable(info->vref);
    492
    493	return 0;
    494}
    495
    496static int rockchip_saradc_resume(struct device *dev)
    497{
    498	struct iio_dev *indio_dev = dev_get_drvdata(dev);
    499	struct rockchip_saradc *info = iio_priv(indio_dev);
    500	int ret;
    501
    502	ret = regulator_enable(info->vref);
    503	if (ret)
    504		return ret;
    505
    506	ret = clk_prepare_enable(info->pclk);
    507	if (ret)
    508		return ret;
    509
    510	ret = clk_prepare_enable(info->clk);
    511	if (ret)
    512		clk_disable_unprepare(info->pclk);
    513
    514	return ret;
    515}
    516
    517static DEFINE_SIMPLE_DEV_PM_OPS(rockchip_saradc_pm_ops,
    518				rockchip_saradc_suspend,
    519				rockchip_saradc_resume);
    520
    521static struct platform_driver rockchip_saradc_driver = {
    522	.probe		= rockchip_saradc_probe,
    523	.driver		= {
    524		.name	= "rockchip-saradc",
    525		.of_match_table = rockchip_saradc_match,
    526		.pm	= pm_sleep_ptr(&rockchip_saradc_pm_ops),
    527	},
    528};
    529
    530module_platform_driver(rockchip_saradc_driver);
    531
    532MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
    533MODULE_DESCRIPTION("Rockchip SARADC driver");
    534MODULE_LICENSE("GPL v2");