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

ltc2497.c (2720B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * ltc2497.c - Driver for Analog Devices/Linear Technology LTC2497 ADC
      4 *
      5 * Copyright (C) 2017 Analog Devices Inc.
      6 *
      7 * Datasheet: http://cds.linear.com/docs/en/datasheet/2497fd.pdf
      8 */
      9
     10#include <linux/i2c.h>
     11#include <linux/iio/iio.h>
     12#include <linux/iio/driver.h>
     13#include <linux/module.h>
     14#include <linux/mod_devicetable.h>
     15
     16#include "ltc2497.h"
     17
     18struct ltc2497_driverdata {
     19	/* this must be the first member */
     20	struct ltc2497core_driverdata common_ddata;
     21	struct i2c_client *client;
     22	/*
     23	 * DMA (thus cache coherency maintenance) requires the
     24	 * transfer buffers to live in their own cache lines.
     25	 */
     26	__be32 buf ____cacheline_aligned;
     27};
     28
     29static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
     30				      u8 address, int *val)
     31{
     32	struct ltc2497_driverdata *st =
     33		container_of(ddata, struct ltc2497_driverdata, common_ddata);
     34	int ret;
     35
     36	if (val) {
     37		ret = i2c_master_recv(st->client, (char *)&st->buf, 3);
     38		if (ret < 0) {
     39			dev_err(&st->client->dev, "i2c_master_recv failed\n");
     40			return ret;
     41		}
     42
     43		*val = (be32_to_cpu(st->buf) >> 14) - (1 << 17);
     44	}
     45
     46	ret = i2c_smbus_write_byte(st->client,
     47				   LTC2497_ENABLE | address);
     48	if (ret)
     49		dev_err(&st->client->dev, "i2c transfer failed: %pe\n",
     50			ERR_PTR(ret));
     51	return ret;
     52}
     53
     54static int ltc2497_probe(struct i2c_client *client,
     55			 const struct i2c_device_id *id)
     56{
     57	struct iio_dev *indio_dev;
     58	struct ltc2497_driverdata *st;
     59	struct device *dev = &client->dev;
     60
     61	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
     62				     I2C_FUNC_SMBUS_WRITE_BYTE))
     63		return -EOPNOTSUPP;
     64
     65	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
     66	if (!indio_dev)
     67		return -ENOMEM;
     68
     69	st = iio_priv(indio_dev);
     70	i2c_set_clientdata(client, indio_dev);
     71	st->client = client;
     72	st->common_ddata.result_and_measure = ltc2497_result_and_measure;
     73
     74	return ltc2497core_probe(dev, indio_dev);
     75}
     76
     77static int ltc2497_remove(struct i2c_client *client)
     78{
     79	struct iio_dev *indio_dev = i2c_get_clientdata(client);
     80
     81	ltc2497core_remove(indio_dev);
     82
     83	return 0;
     84}
     85
     86static const struct i2c_device_id ltc2497_id[] = {
     87	{ "ltc2497", 0 },
     88	{ }
     89};
     90MODULE_DEVICE_TABLE(i2c, ltc2497_id);
     91
     92static const struct of_device_id ltc2497_of_match[] = {
     93	{ .compatible = "lltc,ltc2497", },
     94	{},
     95};
     96MODULE_DEVICE_TABLE(of, ltc2497_of_match);
     97
     98static struct i2c_driver ltc2497_driver = {
     99	.driver = {
    100		.name = "ltc2497",
    101		.of_match_table = ltc2497_of_match,
    102	},
    103	.probe = ltc2497_probe,
    104	.remove = ltc2497_remove,
    105	.id_table = ltc2497_id,
    106};
    107module_i2c_driver(ltc2497_driver);
    108
    109MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
    110MODULE_DESCRIPTION("Linear Technology LTC2497 ADC driver");
    111MODULE_LICENSE("GPL v2");