brintos

brintos / linux-shallow public Read only

0
0
Text · 7.3 KiB · c28a7a6 Raw
305 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * maxim_thermocouple.c  - Support for Maxim thermocouple chips4 *5 * Copyright (C) 2016-2018 Matt Ranostay6 * Author: <matt.ranostay@konsulko.com>7 */8 9#include <linux/init.h>10#include <linux/mod_devicetable.h>11#include <linux/module.h>12#include <linux/mutex.h>13#include <linux/err.h>14#include <linux/spi/spi.h>15#include <linux/iio/iio.h>16#include <linux/iio/sysfs.h>17#include <linux/iio/trigger.h>18#include <linux/iio/buffer.h>19#include <linux/iio/triggered_buffer.h>20#include <linux/iio/trigger_consumer.h>21 22#define MAXIM_THERMOCOUPLE_DRV_NAME	"maxim_thermocouple"23 24enum {25	MAX6675,26	MAX31855,27	MAX31855K,28	MAX31855J,29	MAX31855N,30	MAX31855S,31	MAX31855T,32	MAX31855E,33	MAX31855R,34};35 36static const char maxim_tc_types[] = {37	'K', '?', 'K', 'J', 'N', 'S', 'T', 'E', 'R'38};39 40static const struct iio_chan_spec max6675_channels[] = {41	{	/* thermocouple temperature */42		.type = IIO_TEMP,43		.info_mask_separate =44			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |45			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),46		.scan_index = 0,47		.scan_type = {48			.sign = 's',49			.realbits = 13,50			.storagebits = 16,51			.shift = 3,52			.endianness = IIO_BE,53		},54	},55	IIO_CHAN_SOFT_TIMESTAMP(1),56};57 58static const struct iio_chan_spec max31855_channels[] = {59	{	/* thermocouple temperature */60		.type = IIO_TEMP,61		.address = 2,62		.info_mask_separate =63			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |64			BIT(IIO_CHAN_INFO_THERMOCOUPLE_TYPE),65		.scan_index = 0,66		.scan_type = {67			.sign = 's',68			.realbits = 14,69			.storagebits = 16,70			.shift = 2,71			.endianness = IIO_BE,72		},73	},74	{	/* cold junction temperature */75		.type = IIO_TEMP,76		.address = 0,77		.channel2 = IIO_MOD_TEMP_AMBIENT,78		.modified = 1,79		.info_mask_separate =80			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),81		.scan_index = 1,82		.scan_type = {83			.sign = 's',84			.realbits = 12,85			.storagebits = 16,86			.shift = 4,87			.endianness = IIO_BE,88		},89	},90	IIO_CHAN_SOFT_TIMESTAMP(2),91};92 93static const unsigned long max31855_scan_masks[] = {0x3, 0};94 95struct maxim_thermocouple_chip {96	const struct iio_chan_spec *channels;97	const unsigned long *scan_masks;98	u8 num_channels;99	u8 read_size;100 101	/* bit-check for valid input */102	u32 status_bit;103};104 105static const struct maxim_thermocouple_chip maxim_thermocouple_chips[] = {106	[MAX6675] = {107			.channels = max6675_channels,108			.num_channels = ARRAY_SIZE(max6675_channels),109			.read_size = 2,110			.status_bit = BIT(2),111		},112	[MAX31855] = {113			.channels = max31855_channels,114			.num_channels = ARRAY_SIZE(max31855_channels),115			.read_size = 4,116			.scan_masks = max31855_scan_masks,117			.status_bit = BIT(16),118		},119};120 121struct maxim_thermocouple_data {122	struct spi_device *spi;123	const struct maxim_thermocouple_chip *chip;124 125	u8 buffer[16] __aligned(IIO_DMA_MINALIGN);126	char tc_type;127};128 129static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,130				   struct iio_chan_spec const *chan, int *val)131{132	unsigned int storage_bytes = data->chip->read_size;133	unsigned int shift = chan->scan_type.shift + (chan->address * 8);134	__be16 buf16;135	__be32 buf32;136	int ret;137 138	switch (storage_bytes) {139	case 2:140		ret = spi_read(data->spi, (void *)&buf16, storage_bytes);141		*val = be16_to_cpu(buf16);142		break;143	case 4:144		ret = spi_read(data->spi, (void *)&buf32, storage_bytes);145		*val = be32_to_cpu(buf32);146		break;147	default:148		ret = -EINVAL;149	}150 151	if (ret)152		return ret;153 154	/* check to be sure this is a valid reading */155	if (*val & data->chip->status_bit)156		return -EINVAL;157 158	*val = sign_extend32(*val >> shift, chan->scan_type.realbits - 1);159 160	return 0;161}162 163static irqreturn_t maxim_thermocouple_trigger_handler(int irq, void *private)164{165	struct iio_poll_func *pf = private;166	struct iio_dev *indio_dev = pf->indio_dev;167	struct maxim_thermocouple_data *data = iio_priv(indio_dev);168	int ret;169 170	ret = spi_read(data->spi, data->buffer, data->chip->read_size);171	if (!ret) {172		iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,173						   iio_get_time_ns(indio_dev));174	}175 176	iio_trigger_notify_done(indio_dev->trig);177 178	return IRQ_HANDLED;179}180 181static int maxim_thermocouple_read_raw(struct iio_dev *indio_dev,182				       struct iio_chan_spec const *chan,183				       int *val, int *val2, long mask)184{185	struct maxim_thermocouple_data *data = iio_priv(indio_dev);186	int ret = -EINVAL;187 188	switch (mask) {189	case IIO_CHAN_INFO_RAW:190		ret = iio_device_claim_direct_mode(indio_dev);191		if (ret)192			return ret;193 194		ret = maxim_thermocouple_read(data, chan, val);195		iio_device_release_direct_mode(indio_dev);196 197		if (!ret)198			return IIO_VAL_INT;199 200		break;201	case IIO_CHAN_INFO_SCALE:202		switch (chan->channel2) {203		case IIO_MOD_TEMP_AMBIENT:204			*val = 62;205			*val2 = 500000; /* 1000 * 0.0625 */206			ret = IIO_VAL_INT_PLUS_MICRO;207			break;208		default:209			*val = 250; /* 1000 * 0.25 */210			ret = IIO_VAL_INT;211		}212		break;213	case IIO_CHAN_INFO_THERMOCOUPLE_TYPE:214		*val = data->tc_type;215		ret = IIO_VAL_CHAR;216		break;217	}218 219	return ret;220}221 222static const struct iio_info maxim_thermocouple_info = {223	.read_raw = maxim_thermocouple_read_raw,224};225 226static int maxim_thermocouple_probe(struct spi_device *spi)227{228	const struct spi_device_id *id = spi_get_device_id(spi);229	struct iio_dev *indio_dev;230	struct maxim_thermocouple_data *data;231	const int chip_type = (id->driver_data == MAX6675) ? MAX6675 : MAX31855;232	const struct maxim_thermocouple_chip *chip =233		&maxim_thermocouple_chips[chip_type];234	int ret;235 236	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));237	if (!indio_dev)238		return -ENOMEM;239 240	indio_dev->info = &maxim_thermocouple_info;241	indio_dev->name = MAXIM_THERMOCOUPLE_DRV_NAME;242	indio_dev->channels = chip->channels;243	indio_dev->available_scan_masks = chip->scan_masks;244	indio_dev->num_channels = chip->num_channels;245	indio_dev->modes = INDIO_DIRECT_MODE;246 247	data = iio_priv(indio_dev);248	data->spi = spi;249	data->chip = chip;250	data->tc_type = maxim_tc_types[id->driver_data];251 252	ret = devm_iio_triggered_buffer_setup(&spi->dev,253				indio_dev, NULL,254				maxim_thermocouple_trigger_handler, NULL);255	if (ret)256		return ret;257 258	if (id->driver_data == MAX31855)259		dev_warn(&spi->dev, "generic max31855 ID is deprecated\nplease use more specific part type");260 261	return devm_iio_device_register(&spi->dev, indio_dev);262}263 264static const struct spi_device_id maxim_thermocouple_id[] = {265	{"max6675", MAX6675},266	{"max31855", MAX31855},267	{"max31855k", MAX31855K},268	{"max31855j", MAX31855J},269	{"max31855n", MAX31855N},270	{"max31855s", MAX31855S},271	{"max31855t", MAX31855T},272	{"max31855e", MAX31855E},273	{"max31855r", MAX31855R},274	{},275};276MODULE_DEVICE_TABLE(spi, maxim_thermocouple_id);277 278static const struct of_device_id maxim_thermocouple_of_match[] = {279        { .compatible = "maxim,max6675" },280        { .compatible = "maxim,max31855" },281	{ .compatible = "maxim,max31855k" },282	{ .compatible = "maxim,max31855j" },283	{ .compatible = "maxim,max31855n" },284	{ .compatible = "maxim,max31855s" },285	{ .compatible = "maxim,max31855t" },286	{ .compatible = "maxim,max31855e" },287	{ .compatible = "maxim,max31855r" },288        { },289};290MODULE_DEVICE_TABLE(of, maxim_thermocouple_of_match);291 292static struct spi_driver maxim_thermocouple_driver = {293	.driver = {294		.name	= MAXIM_THERMOCOUPLE_DRV_NAME,295		.of_match_table = maxim_thermocouple_of_match,296	},297	.probe		= maxim_thermocouple_probe,298	.id_table	= maxim_thermocouple_id,299};300module_spi_driver(maxim_thermocouple_driver);301 302MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");303MODULE_DESCRIPTION("Maxim thermocouple sensors");304MODULE_LICENSE("GPL");305