brintos

brintos / linux-shallow public Read only

0
0
Text · 14.7 KiB · 71aa6dc Raw
571 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 2021 Google LLC.4 *5 * Common part of most Semtech SAR sensor.6 */7 8#include <linux/bitops.h>9#include <linux/byteorder/generic.h>10#include <linux/delay.h>11#include <linux/device.h>12#include <linux/err.h>13#include <linux/export.h>14#include <linux/interrupt.h>15#include <linux/irqreturn.h>16#include <linux/i2c.h>17#include <linux/kernel.h>18#include <linux/module.h>19#include <linux/regmap.h>20#include <linux/regulator/consumer.h>21#include <vdso/bits.h>22 23#include <linux/iio/buffer.h>24#include <linux/iio/events.h>25#include <linux/iio/iio.h>26#include <linux/iio/trigger.h>27#include <linux/iio/triggered_buffer.h>28#include <linux/iio/trigger_consumer.h>29 30#include "sx_common.h"31 32/* All Semtech SAR sensors have IRQ bit in the same order. */33#define   SX_COMMON_CONVDONE_IRQ			BIT(0)34#define   SX_COMMON_FAR_IRQ				BIT(2)35#define   SX_COMMON_CLOSE_IRQ				BIT(3)36 37const struct iio_event_spec sx_common_events[3] = {38	{39		.type = IIO_EV_TYPE_THRESH,40		.dir = IIO_EV_DIR_RISING,41		.mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),42	},43	{44		.type = IIO_EV_TYPE_THRESH,45		.dir = IIO_EV_DIR_FALLING,46		.mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),47	},48	{49		.type = IIO_EV_TYPE_THRESH,50		.dir = IIO_EV_DIR_EITHER,51		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |52				 BIT(IIO_EV_INFO_HYSTERESIS) |53				 BIT(IIO_EV_INFO_VALUE),54	},55};56EXPORT_SYMBOL_NS_GPL(sx_common_events, SEMTECH_PROX);57 58static irqreturn_t sx_common_irq_handler(int irq, void *private)59{60	struct iio_dev *indio_dev = private;61	struct sx_common_data *data = iio_priv(indio_dev);62 63	if (data->trigger_enabled)64		iio_trigger_poll(data->trig);65 66	/*67	 * Even if no event is enabled, we need to wake the thread to clear the68	 * interrupt state by reading SX_COMMON_REG_IRQ_SRC.69	 * It is not possible to do that here because regmap_read takes a mutex.70	 */71	return IRQ_WAKE_THREAD;72}73 74static void sx_common_push_events(struct iio_dev *indio_dev)75{76	int ret;77	unsigned int val, chan;78	struct sx_common_data *data = iio_priv(indio_dev);79	s64 timestamp = iio_get_time_ns(indio_dev);80	unsigned long prox_changed;81 82	/* Read proximity state on all channels */83	ret = regmap_read(data->regmap, data->chip_info->reg_stat, &val);84	if (ret) {85		dev_err(&data->client->dev, "i2c transfer error in irq\n");86		return;87	}88 89	val >>= data->chip_info->stat_offset;90 91	/*92	 * Only iterate over channels with changes on proximity status that have93	 * events enabled.94	 */95	prox_changed = (data->chan_prox_stat ^ val) & data->chan_event;96 97	for_each_set_bit(chan, &prox_changed, data->chip_info->num_channels) {98		int dir;99		u64 ev;100 101		dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING;102		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan,103					  IIO_EV_TYPE_THRESH, dir);104 105		iio_push_event(indio_dev, ev, timestamp);106	}107	data->chan_prox_stat = val;108}109 110static int sx_common_enable_irq(struct sx_common_data *data, unsigned int irq)111{112	if (!data->client->irq)113		return 0;114	return regmap_set_bits(data->regmap, data->chip_info->reg_irq_msk,115			       irq << data->chip_info->irq_msk_offset);116}117 118static int sx_common_disable_irq(struct sx_common_data *data, unsigned int irq)119{120	if (!data->client->irq)121		return 0;122	return regmap_clear_bits(data->regmap, data->chip_info->reg_irq_msk,123				 irq << data->chip_info->irq_msk_offset);124}125 126static int sx_common_update_chan_en(struct sx_common_data *data,127				    unsigned long chan_read,128				    unsigned long chan_event)129{130	int ret;131	unsigned long channels = chan_read | chan_event;132 133	if ((data->chan_read | data->chan_event) != channels) {134		ret = regmap_update_bits(data->regmap,135					 data->chip_info->reg_enable_chan,136					 data->chip_info->mask_enable_chan,137					 channels);138		if (ret)139			return ret;140	}141	data->chan_read = chan_read;142	data->chan_event = chan_event;143	return 0;144}145 146static int sx_common_get_read_channel(struct sx_common_data *data, int channel)147{148	return sx_common_update_chan_en(data, data->chan_read | BIT(channel),149				     data->chan_event);150}151 152static int sx_common_put_read_channel(struct sx_common_data *data, int channel)153{154	return sx_common_update_chan_en(data, data->chan_read & ~BIT(channel),155				     data->chan_event);156}157 158static int sx_common_get_event_channel(struct sx_common_data *data, int channel)159{160	return sx_common_update_chan_en(data, data->chan_read,161				     data->chan_event | BIT(channel));162}163 164static int sx_common_put_event_channel(struct sx_common_data *data, int channel)165{166	return sx_common_update_chan_en(data, data->chan_read,167				     data->chan_event & ~BIT(channel));168}169 170/**171 * sx_common_read_proximity() - Read raw proximity value.172 * @data:	Internal data173 * @chan:	Channel to read174 * @val:	pointer to return read value.175 *176 * Request a conversion, wait for the sensor to be ready and177 * return the raw proximity value.178 */179int sx_common_read_proximity(struct sx_common_data *data,180			     const struct iio_chan_spec *chan, int *val)181{182	int ret;183	__be16 rawval;184 185	mutex_lock(&data->mutex);186 187	ret = sx_common_get_read_channel(data, chan->channel);188	if (ret)189		goto out;190 191	ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ);192	if (ret)193		goto out_put_channel;194 195	mutex_unlock(&data->mutex);196 197	if (data->client->irq) {198		ret = wait_for_completion_interruptible(&data->completion);199		reinit_completion(&data->completion);200	} else {201		ret = data->chip_info->ops.wait_for_sample(data);202	}203 204	mutex_lock(&data->mutex);205 206	if (ret)207		goto out_disable_irq;208 209	ret = data->chip_info->ops.read_prox_data(data, chan, &rawval);210	if (ret)211		goto out_disable_irq;212 213	*val = sign_extend32(be16_to_cpu(rawval), chan->scan_type.realbits - 1);214 215	ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ);216	if (ret)217		goto out_put_channel;218 219	ret = sx_common_put_read_channel(data, chan->channel);220	if (ret)221		goto out;222 223	mutex_unlock(&data->mutex);224 225	return IIO_VAL_INT;226 227out_disable_irq:228	sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ);229out_put_channel:230	sx_common_put_read_channel(data, chan->channel);231out:232	mutex_unlock(&data->mutex);233 234	return ret;235}236EXPORT_SYMBOL_NS_GPL(sx_common_read_proximity, SEMTECH_PROX);237 238/**239 * sx_common_read_event_config() - Configure event setting.240 * @indio_dev:	iio device object241 * @chan:	Channel to read242 * @type:	Type of event (unused)243 * @dir:	Direction of event (unused)244 *245 * return if the given channel is used for event gathering.246 */247int sx_common_read_event_config(struct iio_dev *indio_dev,248				const struct iio_chan_spec *chan,249				enum iio_event_type type,250				enum iio_event_direction dir)251{252	struct sx_common_data *data = iio_priv(indio_dev);253 254	return !!(data->chan_event & BIT(chan->channel));255}256EXPORT_SYMBOL_NS_GPL(sx_common_read_event_config, SEMTECH_PROX);257 258/**259 * sx_common_write_event_config() - Configure event setting.260 * @indio_dev:	iio device object261 * @chan:	Channel to enable262 * @type:	Type of event (unused)263 * @dir:	Direction of event (unused)264 * @state:	State of the event.265 *266 * Enable/Disable event on a given channel.267 */268int sx_common_write_event_config(struct iio_dev *indio_dev,269				 const struct iio_chan_spec *chan,270				 enum iio_event_type type,271				 enum iio_event_direction dir, int state)272{273	struct sx_common_data *data = iio_priv(indio_dev);274	unsigned int eventirq = SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ;275	int ret;276 277	/* If the state hasn't changed, there's nothing to do. */278	if (!!(data->chan_event & BIT(chan->channel)) == state)279		return 0;280 281	mutex_lock(&data->mutex);282	if (state) {283		ret = sx_common_get_event_channel(data, chan->channel);284		if (ret)285			goto out_unlock;286		if (!(data->chan_event & ~BIT(chan->channel))) {287			ret = sx_common_enable_irq(data, eventirq);288			if (ret)289				sx_common_put_event_channel(data, chan->channel);290		}291	} else {292		ret = sx_common_put_event_channel(data, chan->channel);293		if (ret)294			goto out_unlock;295		if (!data->chan_event) {296			ret = sx_common_disable_irq(data, eventirq);297			if (ret)298				sx_common_get_event_channel(data, chan->channel);299		}300	}301 302out_unlock:303	mutex_unlock(&data->mutex);304	return ret;305}306EXPORT_SYMBOL_NS_GPL(sx_common_write_event_config, SEMTECH_PROX);307 308static int sx_common_set_trigger_state(struct iio_trigger *trig, bool state)309{310	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);311	struct sx_common_data *data = iio_priv(indio_dev);312	int ret = 0;313 314	mutex_lock(&data->mutex);315 316	if (state)317		ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ);318	else if (!data->chan_read)319		ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ);320	if (ret)321		goto out;322 323	data->trigger_enabled = state;324 325out:326	mutex_unlock(&data->mutex);327 328	return ret;329}330 331static const struct iio_trigger_ops sx_common_trigger_ops = {332	.set_trigger_state = sx_common_set_trigger_state,333};334 335static irqreturn_t sx_common_irq_thread_handler(int irq, void *private)336{337	struct iio_dev *indio_dev = private;338	struct sx_common_data *data = iio_priv(indio_dev);339	int ret;340	unsigned int val;341 342	mutex_lock(&data->mutex);343 344	ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val);345	if (ret) {346		dev_err(&data->client->dev, "i2c transfer error in irq\n");347		goto out;348	}349 350	if (val & ((SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ) << data->chip_info->irq_msk_offset))351		sx_common_push_events(indio_dev);352 353	if (val & (SX_COMMON_CONVDONE_IRQ << data->chip_info->irq_msk_offset))354		complete(&data->completion);355 356out:357	mutex_unlock(&data->mutex);358 359	return IRQ_HANDLED;360}361 362static irqreturn_t sx_common_trigger_handler(int irq, void *private)363{364	struct iio_poll_func *pf = private;365	struct iio_dev *indio_dev = pf->indio_dev;366	struct sx_common_data *data = iio_priv(indio_dev);367	__be16 val;368	int bit, ret, i = 0;369 370	mutex_lock(&data->mutex);371 372	iio_for_each_active_channel(indio_dev, bit) {373		ret = data->chip_info->ops.read_prox_data(data,374						     &indio_dev->channels[bit],375						     &val);376		if (ret)377			goto out;378 379		data->buffer.channels[i++] = val;380	}381 382	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,383					   pf->timestamp);384 385out:386	mutex_unlock(&data->mutex);387 388	iio_trigger_notify_done(indio_dev->trig);389 390	return IRQ_HANDLED;391}392 393static int sx_common_buffer_preenable(struct iio_dev *indio_dev)394{395	struct sx_common_data *data = iio_priv(indio_dev);396	unsigned long channels = 0;397	int bit, ret;398 399	mutex_lock(&data->mutex);400	iio_for_each_active_channel(indio_dev, bit)401		__set_bit(indio_dev->channels[bit].channel, &channels);402 403	ret = sx_common_update_chan_en(data, channels, data->chan_event);404	mutex_unlock(&data->mutex);405	return ret;406}407 408static int sx_common_buffer_postdisable(struct iio_dev *indio_dev)409{410	struct sx_common_data *data = iio_priv(indio_dev);411	int ret;412 413	mutex_lock(&data->mutex);414	ret = sx_common_update_chan_en(data, 0, data->chan_event);415	mutex_unlock(&data->mutex);416	return ret;417}418 419static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = {420	.preenable = sx_common_buffer_preenable,421	.postdisable = sx_common_buffer_postdisable,422};423 424void sx_common_get_raw_register_config(struct device *dev,425				       struct sx_common_reg_default *reg_def)426{427#ifdef CONFIG_ACPI428	struct acpi_device *adev = ACPI_COMPANION(dev);429	u32 raw = 0, ret;430	char prop[80];431 432	if (!reg_def->property || !adev)433		return;434 435	snprintf(prop, ARRAY_SIZE(prop), "%s,reg_%s", acpi_device_hid(adev), reg_def->property);436	ret = device_property_read_u32(dev, prop, &raw);437	if (ret)438		return;439 440	reg_def->def = raw;441#endif442}443EXPORT_SYMBOL_NS_GPL(sx_common_get_raw_register_config, SEMTECH_PROX);444 445#define SX_COMMON_SOFT_RESET				0xde446 447static int sx_common_init_device(struct device *dev, struct iio_dev *indio_dev)448{449	struct sx_common_data *data = iio_priv(indio_dev);450	struct sx_common_reg_default tmp;451	const struct sx_common_reg_default *initval;452	int ret;453	unsigned int i, val;454 455	ret = regmap_write(data->regmap, data->chip_info->reg_reset,456			   SX_COMMON_SOFT_RESET);457	if (ret)458		return ret;459 460	usleep_range(1000, 2000); /* power-up time is ~1ms. */461 462	/* Clear reset interrupt state by reading SX_COMMON_REG_IRQ_SRC. */463	ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val);464	if (ret)465		return ret;466 467	/* Program defaults from constant or BIOS. */468	for (i = 0; i < data->chip_info->num_default_regs; i++) {469		initval = data->chip_info->ops.get_default_reg(dev, i, &tmp);470		ret = regmap_write(data->regmap, initval->reg, initval->def);471		if (ret)472			return ret;473	}474 475	return data->chip_info->ops.init_compensation(indio_dev);476}477 478/**479 * sx_common_probe() - Common setup for Semtech SAR sensor480 * @client:		I2C client object481 * @chip_info:		Semtech sensor chip information.482 * @regmap_config:	Sensor registers map configuration.483 */484int sx_common_probe(struct i2c_client *client,485		    const struct sx_common_chip_info *chip_info,486		    const struct regmap_config *regmap_config)487{488	static const char * const regulator_names[] = { "vdd", "svdd" };489	struct device *dev = &client->dev;490	struct iio_dev *indio_dev;491	struct sx_common_data *data;492	int ret;493 494	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));495	if (!indio_dev)496		return -ENOMEM;497 498	data = iio_priv(indio_dev);499 500	data->chip_info = chip_info;501	data->client = client;502	mutex_init(&data->mutex);503	init_completion(&data->completion);504 505	data->regmap = devm_regmap_init_i2c(client, regmap_config);506	if (IS_ERR(data->regmap))507		return dev_err_probe(dev, PTR_ERR(data->regmap),508				     "Could init register map\n");509 510	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names),511					     regulator_names);512	if (ret)513		return dev_err_probe(dev, ret, "Unable to get regulators\n");514 515	/* Must wait for Tpor time after initial power up */516	usleep_range(1000, 1100);517 518	ret = data->chip_info->ops.check_whoami(dev, indio_dev);519	if (ret)520		return dev_err_probe(dev, ret, "error reading WHOAMI\n");521 522	indio_dev->modes = INDIO_DIRECT_MODE;523 524	indio_dev->channels =  data->chip_info->iio_channels;525	indio_dev->num_channels = data->chip_info->num_iio_channels;526	indio_dev->info = &data->chip_info->iio_info;527 528	i2c_set_clientdata(client, indio_dev);529 530	ret = sx_common_init_device(dev, indio_dev);531	if (ret)532		return dev_err_probe(dev, ret, "Unable to initialize sensor\n");533 534	if (client->irq) {535		ret = devm_request_threaded_irq(dev, client->irq,536						sx_common_irq_handler,537						sx_common_irq_thread_handler,538						IRQF_ONESHOT,539						"sx_event", indio_dev);540		if (ret)541			return dev_err_probe(dev, ret, "No IRQ\n");542 543		data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",544						    indio_dev->name,545						    iio_device_id(indio_dev));546		if (!data->trig)547			return -ENOMEM;548 549		data->trig->ops = &sx_common_trigger_ops;550		iio_trigger_set_drvdata(data->trig, indio_dev);551 552		ret = devm_iio_trigger_register(dev, data->trig);553		if (ret)554			return ret;555	}556 557	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,558					      iio_pollfunc_store_time,559					      sx_common_trigger_handler,560					      &sx_common_buffer_setup_ops);561	if (ret)562		return ret;563 564	return devm_iio_device_register(dev, indio_dev);565}566EXPORT_SYMBOL_NS_GPL(sx_common_probe, SEMTECH_PROX);567 568MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>");569MODULE_DESCRIPTION("Common functions and structures for Semtech sensor");570MODULE_LICENSE("GPL v2");571