brintos

brintos / linux-shallow public Read only

0
0
Text · 6.4 KiB · 614e65c Raw
272 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * mb1232.c - Support for MaxBotix I2CXL-MaxSonar-EZ series ultrasonic4 *   ranger with i2c interface5 * actually tested with mb1232 type6 *7 * Copyright (c) 2019 Andreas Klinger <ak@it-klinger.de>8 *9 * For details about the device see:10 * https://www.maxbotix.com/documents/I2CXL-MaxSonar-EZ_Datasheet.pdf11 */12 13#include <linux/bitops.h>14#include <linux/err.h>15#include <linux/i2c.h>16#include <linux/delay.h>17#include <linux/mod_devicetable.h>18#include <linux/module.h>19#include <linux/property.h>20 21#include <linux/iio/iio.h>22#include <linux/iio/sysfs.h>23#include <linux/iio/buffer.h>24#include <linux/iio/trigger_consumer.h>25#include <linux/iio/triggered_buffer.h>26 27/* registers of MaxSonar device */28#define MB1232_RANGE_COMMAND	0x51	/* Command for reading range */29#define MB1232_ADDR_UNLOCK_1	0xAA	/* Command 1 for changing address */30#define MB1232_ADDR_UNLOCK_2	0xA5	/* Command 2 for changing address */31 32struct mb1232_data {33	struct i2c_client	*client;34 35	struct mutex		lock;36 37	/*38	 * optionally a gpio can be used to announce when ranging has39	 * finished40	 * since we are just using the falling trigger of it we request41	 * only the interrupt for announcing when data is ready to be read42	 */43	struct completion	ranging;44	int			irqnr;45	/* Ensure correct alignment of data to push to IIO buffer */46	struct {47		s16 distance;48		s64 ts __aligned(8);49	} scan;50};51 52static irqreturn_t mb1232_handle_irq(int irq, void *dev_id)53{54	struct iio_dev *indio_dev = dev_id;55	struct mb1232_data *data = iio_priv(indio_dev);56 57	complete(&data->ranging);58 59	return IRQ_HANDLED;60}61 62static s16 mb1232_read_distance(struct mb1232_data *data)63{64	struct i2c_client *client = data->client;65	int ret;66	s16 distance;67	__be16 buf;68 69	mutex_lock(&data->lock);70 71	reinit_completion(&data->ranging);72 73	ret = i2c_smbus_write_byte(client, MB1232_RANGE_COMMAND);74	if (ret < 0) {75		dev_err(&client->dev, "write command - err: %d\n", ret);76		goto error_unlock;77	}78 79	if (data->irqnr > 0) {80		/* it cannot take more than 100 ms */81		ret = wait_for_completion_killable_timeout(&data->ranging,82									HZ/10);83		if (ret < 0)84			goto error_unlock;85		else if (ret == 0) {86			ret = -ETIMEDOUT;87			goto error_unlock;88		}89	} else {90		/* use simple sleep if announce irq is not connected */91		msleep(15);92	}93 94	ret = i2c_master_recv(client, (char *)&buf, sizeof(buf));95	if (ret < 0) {96		dev_err(&client->dev, "i2c_master_recv: ret=%d\n", ret);97		goto error_unlock;98	}99 100	distance = __be16_to_cpu(buf);101	/* check for not returning misleading error codes */102	if (distance < 0) {103		dev_err(&client->dev, "distance=%d\n", distance);104		ret = -EINVAL;105		goto error_unlock;106	}107 108	mutex_unlock(&data->lock);109 110	return distance;111 112error_unlock:113	mutex_unlock(&data->lock);114 115	return ret;116}117 118static irqreturn_t mb1232_trigger_handler(int irq, void *p)119{120	struct iio_poll_func *pf = p;121	struct iio_dev *indio_dev = pf->indio_dev;122	struct mb1232_data *data = iio_priv(indio_dev);123 124	data->scan.distance = mb1232_read_distance(data);125	if (data->scan.distance < 0)126		goto err;127 128	iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,129					   pf->timestamp);130 131err:132	iio_trigger_notify_done(indio_dev->trig);133	return IRQ_HANDLED;134}135 136static int mb1232_read_raw(struct iio_dev *indio_dev,137			    struct iio_chan_spec const *channel, int *val,138			    int *val2, long mask)139{140	struct mb1232_data *data = iio_priv(indio_dev);141	int ret;142 143	if (channel->type != IIO_DISTANCE)144		return -EINVAL;145 146	switch (mask) {147	case IIO_CHAN_INFO_RAW:148		ret = mb1232_read_distance(data);149		if (ret < 0)150			return ret;151		*val = ret;152		return IIO_VAL_INT;153	case IIO_CHAN_INFO_SCALE:154		/* 1 LSB is 1 cm */155		*val = 0;156		*val2 = 10000;157		return IIO_VAL_INT_PLUS_MICRO;158	default:159		return -EINVAL;160	}161}162 163static const struct iio_chan_spec mb1232_channels[] = {164	{165		.type = IIO_DISTANCE,166		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |167				      BIT(IIO_CHAN_INFO_SCALE),168		.scan_index = 0,169		.scan_type = {170			.sign = 's',171			.realbits = 16,172			.storagebits = 16,173			.endianness = IIO_CPU,174		},175	},176	IIO_CHAN_SOFT_TIMESTAMP(1),177};178 179static const struct iio_info mb1232_info = {180	.read_raw = mb1232_read_raw,181};182 183static int mb1232_probe(struct i2c_client *client)184{185	const struct i2c_device_id *id = i2c_client_get_device_id(client);186	struct iio_dev *indio_dev;187	struct mb1232_data *data;188	int ret;189	struct device *dev = &client->dev;190 191	if (!i2c_check_functionality(client->adapter,192					I2C_FUNC_SMBUS_READ_BYTE |193					I2C_FUNC_SMBUS_WRITE_BYTE))194		return -ENODEV;195 196	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));197	if (!indio_dev)198		return -ENOMEM;199 200	data = iio_priv(indio_dev);201	i2c_set_clientdata(client, indio_dev);202	data->client = client;203 204	indio_dev->info = &mb1232_info;205	indio_dev->name = id->name;206	indio_dev->modes = INDIO_DIRECT_MODE;207	indio_dev->channels = mb1232_channels;208	indio_dev->num_channels = ARRAY_SIZE(mb1232_channels);209 210	mutex_init(&data->lock);211 212	init_completion(&data->ranging);213 214	data->irqnr = fwnode_irq_get(dev_fwnode(&client->dev), 0);215	if (data->irqnr > 0) {216		ret = devm_request_irq(dev, data->irqnr, mb1232_handle_irq,217				IRQF_TRIGGER_FALLING, id->name, indio_dev);218		if (ret < 0) {219			dev_err(dev, "request_irq: %d\n", ret);220			return ret;221		}222	}223 224	ret = devm_iio_triggered_buffer_setup(dev, indio_dev,225			iio_pollfunc_store_time, mb1232_trigger_handler, NULL);226	if (ret < 0) {227		dev_err(dev, "setup of iio triggered buffer failed\n");228		return ret;229	}230 231	return devm_iio_device_register(dev, indio_dev);232}233 234static const struct of_device_id of_mb1232_match[] = {235	{ .compatible = "maxbotix,mb1202", },236	{ .compatible = "maxbotix,mb1212", },237	{ .compatible = "maxbotix,mb1222", },238	{ .compatible = "maxbotix,mb1232", },239	{ .compatible = "maxbotix,mb1242", },240	{ .compatible = "maxbotix,mb7040", },241	{ .compatible = "maxbotix,mb7137", },242	{},243};244 245MODULE_DEVICE_TABLE(of, of_mb1232_match);246 247static const struct i2c_device_id mb1232_id[] = {248	{ "maxbotix-mb1202", },249	{ "maxbotix-mb1212", },250	{ "maxbotix-mb1222", },251	{ "maxbotix-mb1232", },252	{ "maxbotix-mb1242", },253	{ "maxbotix-mb7040", },254	{ "maxbotix-mb7137", },255	{ }256};257MODULE_DEVICE_TABLE(i2c, mb1232_id);258 259static struct i2c_driver mb1232_driver = {260	.driver = {261		.name	= "maxbotix-mb1232",262		.of_match_table	= of_mb1232_match,263	},264	.probe = mb1232_probe,265	.id_table = mb1232_id,266};267module_i2c_driver(mb1232_driver);268 269MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");270MODULE_DESCRIPTION("Maxbotix I2CXL-MaxSonar i2c ultrasonic ranger driver");271MODULE_LICENSE("GPL");272