brintos

brintos / linux-shallow public Read only

0
0
Text · 9.3 KiB · d687625 Raw
401 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * AD7091RX Analog to Digital converter driver4 *5 * Copyright 2014-2019 Analog Devices Inc.6 */7 8#include <linux/bitops.h>9#include <linux/bitfield.h>10#include <linux/iio/events.h>11#include <linux/iio/iio.h>12#include <linux/interrupt.h>13#include <linux/module.h>14#include <linux/regmap.h>15#include <linux/regulator/consumer.h>16 17#include "ad7091r-base.h"18 19const struct iio_event_spec ad7091r_events[] = {20	{21		.type = IIO_EV_TYPE_THRESH,22		.dir = IIO_EV_DIR_RISING,23		.mask_separate = BIT(IIO_EV_INFO_VALUE) |24				 BIT(IIO_EV_INFO_ENABLE),25	},26	{27		.type = IIO_EV_TYPE_THRESH,28		.dir = IIO_EV_DIR_FALLING,29		.mask_separate = BIT(IIO_EV_INFO_VALUE) |30				 BIT(IIO_EV_INFO_ENABLE),31	},32	{33		.type = IIO_EV_TYPE_THRESH,34		.dir = IIO_EV_DIR_EITHER,35		.mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),36	},37};38EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R);39 40static int ad7091r_set_channel(struct ad7091r_state *st, unsigned int channel)41{42	unsigned int dummy;43	int ret;44 45	/* AD7091R_REG_CHANNEL specified which channels to be converted */46	ret = regmap_write(st->map, AD7091R_REG_CHANNEL,47			BIT(channel) | (BIT(channel) << 8));48	if (ret)49		return ret;50 51	/*52	 * There is a latency of one conversion before the channel conversion53	 * sequence is updated54	 */55	return regmap_read(st->map, AD7091R_REG_RESULT, &dummy);56}57 58static int ad7091r_read_one(struct iio_dev *iio_dev,59		unsigned int channel, unsigned int *read_val)60{61	struct ad7091r_state *st = iio_priv(iio_dev);62	unsigned int val;63	int ret;64 65	ret = ad7091r_set_channel(st, channel);66	if (ret)67		return ret;68 69	ret = regmap_read(st->map, AD7091R_REG_RESULT, &val);70	if (ret)71		return ret;72 73	if (st->chip_info->reg_result_chan_id(val) != channel)74		return -EIO;75 76	*read_val = AD7091R_REG_RESULT_CONV_RESULT(val);77 78	return 0;79}80 81static int ad7091r_read_raw(struct iio_dev *iio_dev,82			   struct iio_chan_spec const *chan,83			   int *val, int *val2, long m)84{85	struct ad7091r_state *st = iio_priv(iio_dev);86	unsigned int read_val;87	int ret;88 89	guard(mutex)(&st->lock);90 91	switch (m) {92	case IIO_CHAN_INFO_RAW:93		if (st->mode != AD7091R_MODE_COMMAND)94			return -EBUSY;95 96		ret = ad7091r_read_one(iio_dev, chan->channel, &read_val);97		if (ret)98			return ret;99 100		*val = read_val;101		return IIO_VAL_INT;102 103	case IIO_CHAN_INFO_SCALE:104		if (st->vref) {105			ret = regulator_get_voltage(st->vref);106			if (ret < 0)107				return ret;108 109			*val = ret / 1000;110		} else {111			*val = st->chip_info->vref_mV;112		}113 114		*val2 = chan->scan_type.realbits;115		return IIO_VAL_FRACTIONAL_LOG2;116 117	default:118		return -EINVAL;119	}120}121 122static int ad7091r_read_event_config(struct iio_dev *indio_dev,123				     const struct iio_chan_spec *chan,124				     enum iio_event_type type,125				     enum iio_event_direction dir)126{127	struct ad7091r_state *st = iio_priv(indio_dev);128	int val, ret;129 130	switch (dir) {131	case IIO_EV_DIR_RISING:132		ret = regmap_read(st->map,133				  AD7091R_REG_CH_HIGH_LIMIT(chan->channel),134				  &val);135		if (ret)136			return ret;137		return val != AD7091R_HIGH_LIMIT;138	case IIO_EV_DIR_FALLING:139		ret = regmap_read(st->map,140				  AD7091R_REG_CH_LOW_LIMIT(chan->channel),141				  &val);142		if (ret)143			return ret;144		return val != AD7091R_LOW_LIMIT;145	default:146		return -EINVAL;147	}148}149 150static int ad7091r_write_event_config(struct iio_dev *indio_dev,151				      const struct iio_chan_spec *chan,152				      enum iio_event_type type,153				      enum iio_event_direction dir, int state)154{155	struct ad7091r_state *st = iio_priv(indio_dev);156 157	if (state) {158		return regmap_set_bits(st->map, AD7091R_REG_CONF,159				       AD7091R_REG_CONF_ALERT_EN);160	} else {161		/*162		 * Set thresholds either to 0 or to 2^12 - 1 as appropriate to163		 * prevent alerts and thus disable event generation.164		 */165		switch (dir) {166		case IIO_EV_DIR_RISING:167			return regmap_write(st->map,168					    AD7091R_REG_CH_HIGH_LIMIT(chan->channel),169					    AD7091R_HIGH_LIMIT);170		case IIO_EV_DIR_FALLING:171			return regmap_write(st->map,172					    AD7091R_REG_CH_LOW_LIMIT(chan->channel),173					    AD7091R_LOW_LIMIT);174		default:175			return -EINVAL;176		}177	}178}179 180static int ad7091r_read_event_value(struct iio_dev *indio_dev,181				    const struct iio_chan_spec *chan,182				    enum iio_event_type type,183				    enum iio_event_direction dir,184				    enum iio_event_info info, int *val, int *val2)185{186	struct ad7091r_state *st = iio_priv(indio_dev);187	int ret;188 189	switch (info) {190	case IIO_EV_INFO_VALUE:191		switch (dir) {192		case IIO_EV_DIR_RISING:193			ret = regmap_read(st->map,194					  AD7091R_REG_CH_HIGH_LIMIT(chan->channel),195					  val);196			if (ret)197				return ret;198			return IIO_VAL_INT;199		case IIO_EV_DIR_FALLING:200			ret = regmap_read(st->map,201					  AD7091R_REG_CH_LOW_LIMIT(chan->channel),202					  val);203			if (ret)204				return ret;205			return IIO_VAL_INT;206		default:207			return -EINVAL;208		}209	case IIO_EV_INFO_HYSTERESIS:210		ret = regmap_read(st->map,211				  AD7091R_REG_CH_HYSTERESIS(chan->channel),212				  val);213		if (ret)214			return ret;215		return IIO_VAL_INT;216	default:217		return -EINVAL;218	}219}220 221static int ad7091r_write_event_value(struct iio_dev *indio_dev,222				     const struct iio_chan_spec *chan,223				     enum iio_event_type type,224				     enum iio_event_direction dir,225				     enum iio_event_info info, int val, int val2)226{227	struct ad7091r_state *st = iio_priv(indio_dev);228 229	switch (info) {230	case IIO_EV_INFO_VALUE:231		switch (dir) {232		case IIO_EV_DIR_RISING:233			return regmap_write(st->map,234					    AD7091R_REG_CH_HIGH_LIMIT(chan->channel),235					    val);236		case IIO_EV_DIR_FALLING:237			return regmap_write(st->map,238					    AD7091R_REG_CH_LOW_LIMIT(chan->channel),239					    val);240		default:241			return -EINVAL;242		}243	case IIO_EV_INFO_HYSTERESIS:244		return regmap_write(st->map,245				    AD7091R_REG_CH_HYSTERESIS(chan->channel),246				    val);247	default:248		return -EINVAL;249	}250}251 252static const struct iio_info ad7091r_info = {253	.read_raw = ad7091r_read_raw,254	.read_event_config = &ad7091r_read_event_config,255	.write_event_config = &ad7091r_write_event_config,256	.read_event_value = &ad7091r_read_event_value,257	.write_event_value = &ad7091r_write_event_value,258};259 260static irqreturn_t ad7091r_event_handler(int irq, void *private)261{262	struct iio_dev *iio_dev = private;263	struct ad7091r_state *st = iio_priv(iio_dev);264	unsigned int i, read_val;265	int ret;266	s64 timestamp = iio_get_time_ns(iio_dev);267 268	ret = regmap_read(st->map, AD7091R_REG_ALERT, &read_val);269	if (ret)270		return IRQ_HANDLED;271 272	for (i = 0; i < st->chip_info->num_channels; i++) {273		if (read_val & BIT(i * 2))274			iio_push_event(iio_dev,275					IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,276						IIO_EV_TYPE_THRESH,277						IIO_EV_DIR_RISING), timestamp);278		if (read_val & BIT(i * 2 + 1))279			iio_push_event(iio_dev,280					IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,281						IIO_EV_TYPE_THRESH,282						IIO_EV_DIR_FALLING), timestamp);283	}284 285	return IRQ_HANDLED;286}287 288static void ad7091r_remove(void *data)289{290	struct ad7091r_state *st = data;291 292	regulator_disable(st->vref);293}294 295int ad7091r_probe(struct device *dev, const struct ad7091r_init_info *init_info,296		  int irq)297{298	struct iio_dev *iio_dev;299	struct ad7091r_state *st;300	int ret;301 302	iio_dev = devm_iio_device_alloc(dev, sizeof(*st));303	if (!iio_dev)304		return -ENOMEM;305 306	st = iio_priv(iio_dev);307	st->dev = dev;308	init_info->init_adc_regmap(st, init_info->regmap_config);309	if (IS_ERR(st->map))310		return dev_err_probe(st->dev, PTR_ERR(st->map),311				     "Error initializing regmap\n");312 313	iio_dev->info = &ad7091r_info;314	iio_dev->modes = INDIO_DIRECT_MODE;315 316	if (init_info->setup) {317		ret = init_info->setup(st);318		if (ret < 0)319			return ret;320	}321 322	if (irq) {323		st->chip_info = init_info->info_irq;324		ret = regmap_update_bits(st->map, AD7091R_REG_CONF,325					 AD7091R_REG_CONF_ALERT_EN, BIT(4));326		if (ret)327			return ret;328 329		ret = devm_request_threaded_irq(dev, irq, NULL,330						ad7091r_event_handler,331						IRQF_TRIGGER_FALLING |332						IRQF_ONESHOT,333						st->chip_info->name, iio_dev);334		if (ret)335			return ret;336	} else {337		st->chip_info = init_info->info_no_irq;338	}339 340	iio_dev->name = st->chip_info->name;341	iio_dev->num_channels = st->chip_info->num_channels;342	iio_dev->channels = st->chip_info->channels;343 344	st->vref = devm_regulator_get_optional(dev, "vref");345	if (IS_ERR(st->vref)) {346		if (PTR_ERR(st->vref) == -EPROBE_DEFER)347			return -EPROBE_DEFER;348 349		st->vref = NULL;350		/* Enable internal vref */351		ret = regmap_set_bits(st->map, AD7091R_REG_CONF,352				      AD7091R_REG_CONF_INT_VREF);353		if (ret)354			return dev_err_probe(st->dev, ret,355					     "Error on enable internal reference\n");356	} else {357		ret = regulator_enable(st->vref);358		if (ret)359			return ret;360		ret = devm_add_action_or_reset(dev, ad7091r_remove, st);361		if (ret)362			return ret;363	}364 365	/* Use command mode by default to convert only desired channels*/366	ret = st->chip_info->set_mode(st, AD7091R_MODE_COMMAND);367	if (ret)368		return ret;369 370	return devm_iio_device_register(dev, iio_dev);371}372EXPORT_SYMBOL_NS_GPL(ad7091r_probe, IIO_AD7091R);373 374bool ad7091r_writeable_reg(struct device *dev, unsigned int reg)375{376	switch (reg) {377	case AD7091R_REG_RESULT:378	case AD7091R_REG_ALERT:379		return false;380	default:381		return true;382	}383}384EXPORT_SYMBOL_NS_GPL(ad7091r_writeable_reg, IIO_AD7091R);385 386bool ad7091r_volatile_reg(struct device *dev, unsigned int reg)387{388	switch (reg) {389	case AD7091R_REG_RESULT:390	case AD7091R_REG_ALERT:391		return true;392	default:393		return false;394	}395}396EXPORT_SYMBOL_NS_GPL(ad7091r_volatile_reg, IIO_AD7091R);397 398MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>");399MODULE_DESCRIPTION("Analog Devices AD7091Rx multi-channel converters");400MODULE_LICENSE("GPL v2");401