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

max31856.c (12323B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* max31856.c
      3 *
      4 * Maxim MAX31856 thermocouple sensor driver
      5 *
      6 * Copyright (C) 2018-2019 Rockwell Collins
      7 */
      8
      9#include <linux/ctype.h>
     10#include <linux/mod_devicetable.h>
     11#include <linux/module.h>
     12#include <linux/init.h>
     13#include <linux/err.h>
     14#include <linux/property.h>
     15#include <linux/spi/spi.h>
     16#include <linux/iio/iio.h>
     17#include <linux/iio/sysfs.h>
     18#include <linux/util_macros.h>
     19#include <asm/unaligned.h>
     20#include <dt-bindings/iio/temperature/thermocouple.h>
     21/*
     22 * The MSB of the register value determines whether the following byte will
     23 * be written or read. If it is 0, one or more byte reads will follow.
     24 */
     25#define MAX31856_RD_WR_BIT         BIT(7)
     26
     27#define MAX31856_CR0_AUTOCONVERT   BIT(7)
     28#define MAX31856_CR0_1SHOT         BIT(6)
     29#define MAX31856_CR0_OCFAULT       BIT(4)
     30#define MAX31856_CR0_OCFAULT_MASK  GENMASK(5, 4)
     31#define MAX31856_CR0_FILTER_50HZ   BIT(0)
     32#define MAX31856_AVERAGING_MASK    GENMASK(6, 4)
     33#define MAX31856_AVERAGING_SHIFT   4
     34#define MAX31856_TC_TYPE_MASK      GENMASK(3, 0)
     35#define MAX31856_FAULT_OVUV        BIT(1)
     36#define MAX31856_FAULT_OPEN        BIT(0)
     37
     38/* The MAX31856 registers */
     39#define MAX31856_CR0_REG           0x00
     40#define MAX31856_CR1_REG           0x01
     41#define MAX31856_MASK_REG          0x02
     42#define MAX31856_CJHF_REG          0x03
     43#define MAX31856_CJLF_REG          0x04
     44#define MAX31856_LTHFTH_REG        0x05
     45#define MAX31856_LTHFTL_REG        0x06
     46#define MAX31856_LTLFTH_REG        0x07
     47#define MAX31856_LTLFTL_REG        0x08
     48#define MAX31856_CJTO_REG          0x09
     49#define MAX31856_CJTH_REG          0x0A
     50#define MAX31856_CJTL_REG          0x0B
     51#define MAX31856_LTCBH_REG         0x0C
     52#define MAX31856_LTCBM_REG         0x0D
     53#define MAX31856_LTCBL_REG         0x0E
     54#define MAX31856_SR_REG            0x0F
     55
     56static const struct iio_chan_spec max31856_channels[] = {
     57	{	/* Thermocouple Temperature */
     58		.type = IIO_TEMP,
     59		.info_mask_separate =
     60			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
     61			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),
     62		.info_mask_shared_by_type =
     63			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
     64	},
     65	{	/* Cold Junction Temperature */
     66		.type = IIO_TEMP,
     67		.channel2 = IIO_MOD_TEMP_AMBIENT,
     68		.modified = 1,
     69		.info_mask_separate =
     70			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
     71		.info_mask_shared_by_type =
     72			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO)
     73	},
     74};
     75
     76struct max31856_data {
     77	struct spi_device *spi;
     78	u32 thermocouple_type;
     79	bool filter_50hz;
     80	int averaging;
     81};
     82
     83static const char max31856_tc_types[] = {
     84	'B', 'E', 'J', 'K', 'N', 'R', 'S', 'T'
     85};
     86
     87static int max31856_read(struct max31856_data *data, u8 reg,
     88			 u8 val[], unsigned int read_size)
     89{
     90	return spi_write_then_read(data->spi, &reg, 1, val, read_size);
     91}
     92
     93static int max31856_write(struct max31856_data *data, u8 reg,
     94			  unsigned int val)
     95{
     96	u8 buf[2];
     97
     98	buf[0] = reg | (MAX31856_RD_WR_BIT);
     99	buf[1] = val;
    100
    101	return spi_write(data->spi, buf, 2);
    102}
    103
    104static int max31856_init(struct max31856_data *data)
    105{
    106	int ret;
    107	u8 reg_cr0_val, reg_cr1_val;
    108
    109	/* Start by changing to Off mode before making changes as
    110	 * some settings are recommended to be set only when the device
    111	 * is off
    112	 */
    113	ret = max31856_read(data, MAX31856_CR0_REG, &reg_cr0_val, 1);
    114	if (ret)
    115		return ret;
    116
    117	reg_cr0_val &= ~MAX31856_CR0_AUTOCONVERT;
    118	ret = max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
    119	if (ret)
    120		return ret;
    121
    122	/* Set thermocouple type based on dts property */
    123	ret = max31856_read(data, MAX31856_CR1_REG, &reg_cr1_val, 1);
    124	if (ret)
    125		return ret;
    126
    127	reg_cr1_val &= ~MAX31856_TC_TYPE_MASK;
    128	reg_cr1_val |= data->thermocouple_type;
    129
    130	reg_cr1_val &= ~MAX31856_AVERAGING_MASK;
    131	reg_cr1_val |= data->averaging << MAX31856_AVERAGING_SHIFT;
    132
    133	ret = max31856_write(data, MAX31856_CR1_REG, reg_cr1_val);
    134	if (ret)
    135		return ret;
    136
    137	/*
    138	 * Enable Open circuit fault detection
    139	 * Read datasheet for more information: Table 4.
    140	 * Value 01 means : Enabled (Once every 16 conversions)
    141	 */
    142	reg_cr0_val &= ~MAX31856_CR0_OCFAULT_MASK;
    143	reg_cr0_val |= MAX31856_CR0_OCFAULT;
    144
    145	/* Set Auto Conversion Mode */
    146	reg_cr0_val &= ~MAX31856_CR0_1SHOT;
    147	reg_cr0_val |= MAX31856_CR0_AUTOCONVERT;
    148
    149	if (data->filter_50hz)
    150		reg_cr0_val |= MAX31856_CR0_FILTER_50HZ;
    151	else
    152		reg_cr0_val &= ~MAX31856_CR0_FILTER_50HZ;
    153
    154	return max31856_write(data, MAX31856_CR0_REG, reg_cr0_val);
    155}
    156
    157static int max31856_thermocouple_read(struct max31856_data *data,
    158				      struct iio_chan_spec const *chan,
    159				      int *val)
    160{
    161	int ret, offset_cjto;
    162	u8 reg_val[3];
    163
    164	switch (chan->channel2) {
    165	case IIO_NO_MOD:
    166		/*
    167		 * Multibyte Read
    168		 * MAX31856_LTCBH_REG, MAX31856_LTCBM_REG, MAX31856_LTCBL_REG
    169		 */
    170		ret = max31856_read(data, MAX31856_LTCBH_REG, reg_val, 3);
    171		if (ret)
    172			return ret;
    173		/* Skip last 5 dead bits of LTCBL */
    174		*val = get_unaligned_be24(&reg_val[0]) >> 5;
    175		/* Check 7th bit of LTCBH reg. value for sign*/
    176		if (reg_val[0] & 0x80)
    177			*val -= 0x80000;
    178		break;
    179
    180	case IIO_MOD_TEMP_AMBIENT:
    181		/*
    182		 * Multibyte Read
    183		 * MAX31856_CJTO_REG, MAX31856_CJTH_REG, MAX31856_CJTL_REG
    184		 */
    185		ret = max31856_read(data, MAX31856_CJTO_REG, reg_val, 3);
    186		if (ret)
    187			return ret;
    188		/* Get Cold Junction Temp. offset register value */
    189		offset_cjto = reg_val[0];
    190		/* Get CJTH and CJTL value and skip last 2 dead bits of CJTL */
    191		*val = get_unaligned_be16(&reg_val[1]) >> 2;
    192		/* As per datasheet add offset into CJTH and CJTL */
    193		*val += offset_cjto;
    194		/* Check 7th bit of CJTH reg. value for sign */
    195		if (reg_val[1] & 0x80)
    196			*val -= 0x4000;
    197		break;
    198
    199	default:
    200		return -EINVAL;
    201	}
    202
    203	ret = max31856_read(data, MAX31856_SR_REG, reg_val, 1);
    204	if (ret)
    205		return ret;
    206	/* Check for over/under voltage or open circuit fault */
    207	if (reg_val[0] & (MAX31856_FAULT_OVUV | MAX31856_FAULT_OPEN))
    208		return -EIO;
    209
    210	return ret;
    211}
    212
    213static int max31856_read_raw(struct iio_dev *indio_dev,
    214			     struct iio_chan_spec const *chan,
    215			     int *val, int *val2, long mask)
    216{
    217	struct max31856_data *data = iio_priv(indio_dev);
    218	int ret;
    219
    220	switch (mask) {
    221	case IIO_CHAN_INFO_RAW:
    222		ret = max31856_thermocouple_read(data, chan, val);
    223		if (ret)
    224			return ret;
    225		return IIO_VAL_INT;
    226	case IIO_CHAN_INFO_SCALE:
    227		switch (chan->channel2) {
    228		case IIO_MOD_TEMP_AMBIENT:
    229			/* Cold junction Temp. Data resolution is 0.015625 */
    230			*val = 15;
    231			*val2 = 625000; /* 1000 * 0.015625 */
    232			ret = IIO_VAL_INT_PLUS_MICRO;
    233			break;
    234		default:
    235			/* Thermocouple Temp. Data resolution is 0.0078125 */
    236			*val = 7;
    237			*val2 = 812500; /* 1000 * 0.0078125) */
    238			return IIO_VAL_INT_PLUS_MICRO;
    239		}
    240		break;
    241	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
    242		*val = 1 << data->averaging;
    243		return IIO_VAL_INT;
    244	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
    245		*val = max31856_tc_types[data->thermocouple_type];
    246		return IIO_VAL_CHAR;
    247	default:
    248		ret = -EINVAL;
    249		break;
    250	}
    251
    252	return ret;
    253}
    254
    255static int max31856_write_raw_get_fmt(struct iio_dev *indio_dev,
    256				      struct iio_chan_spec const *chan,
    257				      long mask)
    258{
    259	switch (mask) {
    260	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
    261		return IIO_VAL_CHAR;
    262	default:
    263		return IIO_VAL_INT;
    264	}
    265}
    266
    267static int max31856_write_raw(struct iio_dev *indio_dev,
    268			      struct iio_chan_spec const *chan,
    269			      int val, int val2, long mask)
    270{
    271	struct max31856_data *data = iio_priv(indio_dev);
    272	int msb;
    273
    274	switch (mask) {
    275	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
    276		if (val > 16 || val < 1)
    277			return -EINVAL;
    278		msb = fls(val) - 1;
    279		/* Round up to next 2pow if needed */
    280		if (BIT(msb) < val)
    281			msb++;
    282
    283		data->averaging = msb;
    284		max31856_init(data);
    285		break;
    286	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:
    287	{
    288		int tc_type = -1;
    289		int i;
    290
    291		for (i = 0; i < ARRAY_SIZE(max31856_tc_types); i++) {
    292			if (max31856_tc_types[i] == toupper(val)) {
    293				tc_type = i;
    294				break;
    295			}
    296		}
    297		if (tc_type < 0)
    298			return -EINVAL;
    299
    300		data->thermocouple_type = tc_type;
    301		max31856_init(data);
    302		break;
    303	}
    304	default:
    305		return -EINVAL;
    306	}
    307
    308	return 0;
    309}
    310
    311static ssize_t show_fault(struct device *dev, u8 faultbit, char *buf)
    312{
    313	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    314	struct max31856_data *data = iio_priv(indio_dev);
    315	u8 reg_val;
    316	int ret;
    317	bool fault;
    318
    319	ret = max31856_read(data, MAX31856_SR_REG, &reg_val, 1);
    320	if (ret)
    321		return ret;
    322
    323	fault = reg_val & faultbit;
    324
    325	return sysfs_emit(buf, "%d\n", fault);
    326}
    327
    328static ssize_t show_fault_ovuv(struct device *dev,
    329			       struct device_attribute *attr,
    330			       char *buf)
    331{
    332	return show_fault(dev, MAX31856_FAULT_OVUV, buf);
    333}
    334
    335static ssize_t show_fault_oc(struct device *dev,
    336			     struct device_attribute *attr,
    337			     char *buf)
    338{
    339	return show_fault(dev, MAX31856_FAULT_OPEN, buf);
    340}
    341
    342static ssize_t show_filter(struct device *dev,
    343			   struct device_attribute *attr,
    344			   char *buf)
    345{
    346	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    347	struct max31856_data *data = iio_priv(indio_dev);
    348
    349	return sysfs_emit(buf, "%d\n", data->filter_50hz ? 50 : 60);
    350}
    351
    352static ssize_t set_filter(struct device *dev,
    353			  struct device_attribute *attr,
    354			  const char *buf,
    355			  size_t len)
    356{
    357	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    358	struct max31856_data *data = iio_priv(indio_dev);
    359	unsigned int freq;
    360	int ret;
    361
    362	ret = kstrtouint(buf, 10, &freq);
    363	if (ret)
    364		return ret;
    365
    366	switch (freq) {
    367	case 50:
    368		data->filter_50hz = true;
    369		break;
    370	case 60:
    371		data->filter_50hz = false;
    372		break;
    373	default:
    374		return -EINVAL;
    375	}
    376
    377	max31856_init(data);
    378	return len;
    379}
    380
    381static IIO_DEVICE_ATTR(fault_ovuv, 0444, show_fault_ovuv, NULL, 0);
    382static IIO_DEVICE_ATTR(fault_oc, 0444, show_fault_oc, NULL, 0);
    383static IIO_DEVICE_ATTR(in_temp_filter_notch_center_frequency, 0644,
    384		       show_filter, set_filter, 0);
    385
    386static struct attribute *max31856_attributes[] = {
    387	&iio_dev_attr_fault_ovuv.dev_attr.attr,
    388	&iio_dev_attr_fault_oc.dev_attr.attr,
    389	&iio_dev_attr_in_temp_filter_notch_center_frequency.dev_attr.attr,
    390	NULL,
    391};
    392
    393static const struct attribute_group max31856_group = {
    394	.attrs = max31856_attributes,
    395};
    396
    397static const struct iio_info max31856_info = {
    398	.read_raw = max31856_read_raw,
    399	.write_raw = max31856_write_raw,
    400	.write_raw_get_fmt = max31856_write_raw_get_fmt,
    401	.attrs = &max31856_group,
    402};
    403
    404static int max31856_probe(struct spi_device *spi)
    405{
    406	const struct spi_device_id *id = spi_get_device_id(spi);
    407	struct iio_dev *indio_dev;
    408	struct max31856_data *data;
    409	int ret;
    410
    411	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
    412	if (!indio_dev)
    413		return -ENOMEM;
    414
    415	data = iio_priv(indio_dev);
    416	data->spi = spi;
    417	data->filter_50hz = false;
    418
    419	spi_set_drvdata(spi, indio_dev);
    420
    421	indio_dev->info = &max31856_info;
    422	indio_dev->name = id->name;
    423	indio_dev->modes = INDIO_DIRECT_MODE;
    424	indio_dev->channels = max31856_channels;
    425	indio_dev->num_channels = ARRAY_SIZE(max31856_channels);
    426
    427	ret = device_property_read_u32(&spi->dev, "thermocouple-type", &data->thermocouple_type);
    428	if (ret) {
    429		dev_info(&spi->dev,
    430			 "Could not read thermocouple type DT property, configuring as a K-Type\n");
    431		data->thermocouple_type = THERMOCOUPLE_TYPE_K;
    432	}
    433
    434	/*
    435	 * no need to translate values as the supported types
    436	 * have the same value as the #defines
    437	 */
    438	switch (data->thermocouple_type) {
    439	case THERMOCOUPLE_TYPE_B:
    440	case THERMOCOUPLE_TYPE_E:
    441	case THERMOCOUPLE_TYPE_J:
    442	case THERMOCOUPLE_TYPE_K:
    443	case THERMOCOUPLE_TYPE_N:
    444	case THERMOCOUPLE_TYPE_R:
    445	case THERMOCOUPLE_TYPE_S:
    446	case THERMOCOUPLE_TYPE_T:
    447		break;
    448	default:
    449		dev_err(&spi->dev,
    450			"error: thermocouple-type %u not supported by max31856\n"
    451			, data->thermocouple_type);
    452		return -EINVAL;
    453	}
    454
    455	ret = max31856_init(data);
    456	if (ret) {
    457		dev_err(&spi->dev, "error: Failed to configure max31856\n");
    458		return ret;
    459	}
    460
    461	return devm_iio_device_register(&spi->dev, indio_dev);
    462}
    463
    464static const struct spi_device_id max31856_id[] = {
    465	{ "max31856", 0 },
    466	{ }
    467};
    468MODULE_DEVICE_TABLE(spi, max31856_id);
    469
    470static const struct of_device_id max31856_of_match[] = {
    471	{ .compatible = "maxim,max31856" },
    472	{ }
    473};
    474MODULE_DEVICE_TABLE(of, max31856_of_match);
    475
    476static struct spi_driver max31856_driver = {
    477	.driver = {
    478		.name = "max31856",
    479		.of_match_table = max31856_of_match,
    480	},
    481	.probe = max31856_probe,
    482	.id_table = max31856_id,
    483};
    484module_spi_driver(max31856_driver);
    485
    486MODULE_AUTHOR("Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com>");
    487MODULE_AUTHOR("Patrick Havelange <patrick.havelange@essensium.com>");
    488MODULE_DESCRIPTION("Maxim MAX31856 thermocouple sensor driver");
    489MODULE_LICENSE("GPL");