brintos

brintos / linux-shallow public Read only

0
0
Text · 7.0 KiB · e89e4c0 Raw
326 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Maxim Integrated4 * 7-bit, Multi-Channel Sink/Source Current DAC Driver5 * Copyright (C) 2017 Maxim Integrated6 */7 8#include <linux/kernel.h>9#include <linux/module.h>10#include <linux/i2c.h>11#include <linux/regulator/consumer.h>12#include <linux/err.h>13#include <linux/delay.h>14#include <linux/iio/iio.h>15#include <linux/iio/driver.h>16#include <linux/iio/machine.h>17#include <linux/iio/consumer.h>18 19#define DS4422_MAX_DAC_CHANNELS		220#define DS4424_MAX_DAC_CHANNELS		421 22#define DS4424_DAC_ADDR(chan)   ((chan) + 0xf8)23#define DS4424_SOURCE_I		124#define DS4424_SINK_I		025 26#define DS4424_CHANNEL(chan) { \27	.type = IIO_CURRENT, \28	.indexed = 1, \29	.output = 1, \30	.channel = chan, \31	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \32}33 34/*35 * DS4424 DAC control register 8 bits36 * [7]		0: to sink; 1: to source37 * [6:0]	steps to sink/source38 * bit[7] looks like a sign bit, but the value of the register is39 * not a two's complement code considering the bit[6:0] is a absolute40 * distance from the zero point.41 */42union ds4424_raw_data {43	struct {44		u8 dx:7;45		u8 source_bit:1;46	};47	u8 bits;48};49 50enum ds4424_device_ids {51	ID_DS4422,52	ID_DS4424,53};54 55struct ds4424_data {56	struct i2c_client *client;57	struct mutex lock;58	uint8_t save[DS4424_MAX_DAC_CHANNELS];59	struct regulator *vcc_reg;60	uint8_t raw[DS4424_MAX_DAC_CHANNELS];61};62 63static const struct iio_chan_spec ds4424_channels[] = {64	DS4424_CHANNEL(0),65	DS4424_CHANNEL(1),66	DS4424_CHANNEL(2),67	DS4424_CHANNEL(3),68};69 70static int ds4424_get_value(struct iio_dev *indio_dev,71			     int *val, int channel)72{73	struct ds4424_data *data = iio_priv(indio_dev);74	int ret;75 76	mutex_lock(&data->lock);77	ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel));78	if (ret < 0)79		goto fail;80 81	*val = ret;82 83fail:84	mutex_unlock(&data->lock);85	return ret;86}87 88static int ds4424_set_value(struct iio_dev *indio_dev,89			     int val, struct iio_chan_spec const *chan)90{91	struct ds4424_data *data = iio_priv(indio_dev);92	int ret;93 94	mutex_lock(&data->lock);95	ret = i2c_smbus_write_byte_data(data->client,96			DS4424_DAC_ADDR(chan->channel), val);97	if (ret < 0)98		goto fail;99 100	data->raw[chan->channel] = val;101 102fail:103	mutex_unlock(&data->lock);104	return ret;105}106 107static int ds4424_read_raw(struct iio_dev *indio_dev,108			   struct iio_chan_spec const *chan,109			   int *val, int *val2, long mask)110{111	union ds4424_raw_data raw;112	int ret;113 114	switch (mask) {115	case IIO_CHAN_INFO_RAW:116		ret = ds4424_get_value(indio_dev, val, chan->channel);117		if (ret < 0) {118			pr_err("%s : ds4424_get_value returned %d\n",119							__func__, ret);120			return ret;121		}122		raw.bits = *val;123		*val = raw.dx;124		if (raw.source_bit == DS4424_SINK_I)125			*val = -*val;126		return IIO_VAL_INT;127 128	default:129		return -EINVAL;130	}131}132 133static int ds4424_write_raw(struct iio_dev *indio_dev,134			     struct iio_chan_spec const *chan,135			     int val, int val2, long mask)136{137	union ds4424_raw_data raw;138 139	if (val2 != 0)140		return -EINVAL;141 142	switch (mask) {143	case IIO_CHAN_INFO_RAW:144		if (val < S8_MIN || val > S8_MAX)145			return -EINVAL;146 147		if (val > 0) {148			raw.source_bit = DS4424_SOURCE_I;149			raw.dx = val;150		} else {151			raw.source_bit = DS4424_SINK_I;152			raw.dx = -val;153		}154 155		return ds4424_set_value(indio_dev, raw.bits, chan);156 157	default:158		return -EINVAL;159	}160}161 162static int ds4424_verify_chip(struct iio_dev *indio_dev)163{164	int ret, val;165 166	ret = ds4424_get_value(indio_dev, &val, 0);167	if (ret < 0)168		dev_err(&indio_dev->dev,169				"%s failed. ret: %d\n", __func__, ret);170 171	return ret;172}173 174static int ds4424_suspend(struct device *dev)175{176	struct i2c_client *client = to_i2c_client(dev);177	struct iio_dev *indio_dev = i2c_get_clientdata(client);178	struct ds4424_data *data = iio_priv(indio_dev);179	int ret = 0;180	int i;181 182	for (i = 0; i < indio_dev->num_channels; i++) {183		data->save[i] = data->raw[i];184		ret = ds4424_set_value(indio_dev, 0,185				&indio_dev->channels[i]);186		if (ret < 0)187			return ret;188	}189	return ret;190}191 192static int ds4424_resume(struct device *dev)193{194	struct i2c_client *client = to_i2c_client(dev);195	struct iio_dev *indio_dev = i2c_get_clientdata(client);196	struct ds4424_data *data = iio_priv(indio_dev);197	int ret = 0;198	int i;199 200	for (i = 0; i < indio_dev->num_channels; i++) {201		ret = ds4424_set_value(indio_dev, data->save[i],202				&indio_dev->channels[i]);203		if (ret < 0)204			return ret;205	}206	return ret;207}208 209static DEFINE_SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);210 211static const struct iio_info ds4424_info = {212	.read_raw = ds4424_read_raw,213	.write_raw = ds4424_write_raw,214};215 216static int ds4424_probe(struct i2c_client *client)217{218	const struct i2c_device_id *id = i2c_client_get_device_id(client);219	struct ds4424_data *data;220	struct iio_dev *indio_dev;221	int ret;222 223	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));224	if (!indio_dev) {225		dev_err(&client->dev, "iio dev alloc failed.\n");226		return -ENOMEM;227	}228 229	data = iio_priv(indio_dev);230	i2c_set_clientdata(client, indio_dev);231	data->client = client;232	indio_dev->name = id->name;233 234	data->vcc_reg = devm_regulator_get(&client->dev, "vcc");235	if (IS_ERR(data->vcc_reg))236		return dev_err_probe(&client->dev, PTR_ERR(data->vcc_reg),237				     "Failed to get vcc-supply regulator.\n");238 239	mutex_init(&data->lock);240	ret = regulator_enable(data->vcc_reg);241	if (ret < 0) {242		dev_err(&client->dev,243				"Unable to enable the regulator.\n");244		return ret;245	}246 247	usleep_range(1000, 1200);248	ret = ds4424_verify_chip(indio_dev);249	if (ret < 0)250		goto fail;251 252	switch (id->driver_data) {253	case ID_DS4422:254		indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;255		break;256	case ID_DS4424:257		indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;258		break;259	default:260		dev_err(&client->dev,261				"ds4424: Invalid chip id.\n");262		ret = -ENXIO;263		goto fail;264	}265 266	indio_dev->channels = ds4424_channels;267	indio_dev->modes = INDIO_DIRECT_MODE;268	indio_dev->info = &ds4424_info;269 270	ret = iio_device_register(indio_dev);271	if (ret < 0) {272		dev_err(&client->dev,273				"iio_device_register failed. ret: %d\n", ret);274		goto fail;275	}276 277	return ret;278 279fail:280	regulator_disable(data->vcc_reg);281	return ret;282}283 284static void ds4424_remove(struct i2c_client *client)285{286	struct iio_dev *indio_dev = i2c_get_clientdata(client);287	struct ds4424_data *data = iio_priv(indio_dev);288 289	iio_device_unregister(indio_dev);290	regulator_disable(data->vcc_reg);291}292 293static const struct i2c_device_id ds4424_id[] = {294	{ "ds4422", ID_DS4422 },295	{ "ds4424", ID_DS4424 },296	{ }297};298 299MODULE_DEVICE_TABLE(i2c, ds4424_id);300 301static const struct of_device_id ds4424_of_match[] = {302	{ .compatible = "maxim,ds4422" },303	{ .compatible = "maxim,ds4424" },304	{ },305};306 307MODULE_DEVICE_TABLE(of, ds4424_of_match);308 309static struct i2c_driver ds4424_driver = {310	.driver = {311		.name	= "ds4424",312		.of_match_table = ds4424_of_match,313		.pm     = pm_sleep_ptr(&ds4424_pm_ops),314	},315	.probe		= ds4424_probe,316	.remove		= ds4424_remove,317	.id_table	= ds4424_id,318};319module_i2c_driver(ds4424_driver);320 321MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");322MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");323MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");324MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");325MODULE_LICENSE("GPL v2");326