brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · 060651d Raw
144 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * ltc2485.c - Driver for Linear Technology LTC2485 ADC4 *5 * Copyright (C) 2016 Alison Schofield <amsfield22@gmail.com>6 *7 * Datasheet: http://cds.linear.com/docs/en/datasheet/2485fd.pdf8 */9 10#include <linux/delay.h>11#include <linux/i2c.h>12#include <linux/module.h>13 14#include <linux/iio/iio.h>15#include <linux/iio/sysfs.h>16 17/* Power-on configuration: rejects both 50/60Hz, operates at 1x speed */18#define LTC2485_CONFIG_DEFAULT		019 20struct ltc2485_data {21	struct i2c_client	*client;22	ktime_t			time_prev;	/* last conversion */23};24 25static void ltc2485_wait_conv(struct ltc2485_data *data)26{27	const unsigned int conv_time = 147;	/* conversion time ms */28	unsigned int time_elapsed;29 30	/* delay if conversion time not passed since last read or write */31	time_elapsed = ktime_ms_delta(ktime_get(), data->time_prev);32 33	if (time_elapsed < conv_time)34		msleep(conv_time - time_elapsed);35}36 37static int ltc2485_read(struct ltc2485_data *data, int *val)38{39	struct i2c_client *client = data->client;40	__be32 buf = 0;41	int ret;42 43	ltc2485_wait_conv(data);44 45	ret = i2c_master_recv(client, (char *)&buf, 4);46	if (ret < 0)  {47		dev_err(&client->dev, "i2c_master_recv failed\n");48		return ret;49	}50	data->time_prev = ktime_get();51	*val = sign_extend32(be32_to_cpu(buf) >> 6, 24);52 53	return ret;54}55 56static int ltc2485_read_raw(struct iio_dev *indio_dev,57			    struct iio_chan_spec const *chan,58			    int *val, int *val2, long mask)59{60	struct ltc2485_data *data = iio_priv(indio_dev);61	int ret;62 63	if (mask == IIO_CHAN_INFO_RAW) {64		ret = ltc2485_read(data, val);65		if (ret < 0)66			return ret;67 68		return IIO_VAL_INT;69 70	} else if (mask == IIO_CHAN_INFO_SCALE) {71		*val = 5000;			/* on board vref millivolts */72		*val2 = 25;			/* 25 (24 + sign) data bits */73		return IIO_VAL_FRACTIONAL_LOG2;74 75	} else {76		return -EINVAL;77	}78}79 80static const struct iio_chan_spec ltc2485_channel[] = {81	{82		.type = IIO_VOLTAGE,83		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),84		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)85	},86};87 88static const struct iio_info ltc2485_info = {89	.read_raw = ltc2485_read_raw,90};91 92static int ltc2485_probe(struct i2c_client *client)93{94	const struct i2c_device_id *id = i2c_client_get_device_id(client);95	struct iio_dev *indio_dev;96	struct ltc2485_data *data;97	int ret;98 99	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |100				     I2C_FUNC_SMBUS_WRITE_BYTE))101		return -EOPNOTSUPP;102 103	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));104	if (!indio_dev)105		return -ENOMEM;106 107	data = iio_priv(indio_dev);108	i2c_set_clientdata(client, indio_dev);109	data->client = client;110 111	indio_dev->name = id->name;112	indio_dev->info = &ltc2485_info;113	indio_dev->modes = INDIO_DIRECT_MODE;114	indio_dev->channels = ltc2485_channel;115	indio_dev->num_channels = ARRAY_SIZE(ltc2485_channel);116 117	ret = i2c_smbus_write_byte(data->client, LTC2485_CONFIG_DEFAULT);118	if (ret < 0)119		return ret;120 121	data->time_prev = ktime_get();122 123	return devm_iio_device_register(&client->dev, indio_dev);124}125 126static const struct i2c_device_id ltc2485_id[] = {127	{ "ltc2485" },128	{ }129};130MODULE_DEVICE_TABLE(i2c, ltc2485_id);131 132static struct i2c_driver ltc2485_driver = {133	.driver = {134		.name = "ltc2485",135	},136	.probe = ltc2485_probe,137	.id_table = ltc2485_id,138};139module_i2c_driver(ltc2485_driver);140 141MODULE_AUTHOR("Alison Schofield <amsfield22@gmail.com>");142MODULE_DESCRIPTION("Linear Technology LTC2485 ADC driver");143MODULE_LICENSE("GPL v2");144