File Index
Files and directories
Sign in
FILE

af8133j.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/magnetometer/af8133j.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * af8133j.c - Voltafield AF8133J magnetometer driver
  4 *
  5 * Copyright 2021 Icenowy Zheng <icenowy@aosc.io>
  6 * Copyright 2024 Ondřej Jirman <megi@xff.cz>
  7 */
  8
  9#include <linux/delay.h>
 10#include <linux/gpio/consumer.h>
 11#include <linux/i2c.h>
 12#include <linux/module.h>
 13#include <linux/pm_runtime.h>
 14#include <linux/regmap.h>
 15#include <linux/regulator/consumer.h>
 16
 17#include <linux/iio/iio.h>
 18#include <linux/iio/trigger_consumer.h>
 19#include <linux/iio/triggered_buffer.h>
 20
 21#define AF8133J_REG_OUT		0x03
 22#define AF8133J_REG_PCODE	0x00
 23#define AF8133J_REG_PCODE_VAL	0x5e
 24#define AF8133J_REG_STATUS	0x02
 25#define AF8133J_REG_STATUS_ACQ	BIT(0)
 26#define AF8133J_REG_STATE	0x0a
 27#define AF8133J_REG_STATE_STBY	0x00
 28#define AF8133J_REG_STATE_WORK	0x01
 29#define AF8133J_REG_RANGE	0x0b
 30#define AF8133J_REG_RANGE_22G	0x12
 31#define AF8133J_REG_RANGE_12G	0x34
 32#define AF8133J_REG_SWR		0x11
 33#define AF8133J_REG_SWR_PERFORM	0x81
 34
 35static const char * const af8133j_supply_names[] = {
 36	"avdd",
 37	"dvdd",
 38};
 39
 40struct af8133j_data {
 41	struct i2c_client *client;
 42	struct regmap *regmap;
 43	/*
 44	 * Protect device internal state between starting a measurement
 45	 * and reading the result.
 46	 */
 47	struct mutex mutex;
 48	struct iio_mount_matrix orientation;
 49
 50	struct gpio_desc *reset_gpiod;
 51	struct regulator_bulk_data supplies[ARRAY_SIZE(af8133j_supply_names)];
 52
 53	u8 range;
 54};
 55
 56enum af8133j_axis {
 57	AXIS_X = 0,
 58	AXIS_Y,
 59	AXIS_Z,
 60};
 61
 62static struct iio_mount_matrix *
 63af8133j_get_mount_matrix(struct iio_dev *indio_dev,
 64			 const struct iio_chan_spec *chan)
 65{
 66	struct af8133j_data *data = iio_priv(indio_dev);
 67
 68	return &data->orientation;
 69}
 70
 71static const struct iio_chan_spec_ext_info af8133j_ext_info[] = {
 72	IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, af8133j_get_mount_matrix),
 73	{ }
 74};
 75
 76#define AF8133J_CHANNEL(_si, _axis) { \
 77	.type = IIO_MAGN, \
 78	.modified = 1, \
 79	.channel2 = IIO_MOD_ ## _axis, \
 80	.address = AXIS_ ## _axis, \
 81	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
 82	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 83	.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
 84	.ext_info = af8133j_ext_info, \
 85	.scan_index = _si, \
 86	.scan_type = { \
 87		.sign = 's', \
 88		.realbits = 16, \
 89		.storagebits = 16, \
 90		.endianness = IIO_LE, \
 91	}, \
 92}
 93
 94static const struct iio_chan_spec af8133j_channels[] = {
 95	AF8133J_CHANNEL(0, X),
 96	AF8133J_CHANNEL(1, Y),
 97	AF8133J_CHANNEL(2, Z),
 98	IIO_CHAN_SOFT_TIMESTAMP(3),
 99};
100
101static int af8133j_product_check(struct af8133j_data *data)
102{
103	struct device *dev = &data->client->dev;
104	unsigned int val;
105	int ret;
106
107	ret = regmap_read(data->regmap, AF8133J_REG_PCODE, &val);
108	if (ret) {
109		dev_err(dev, "Error reading product code (%d)\n", ret);
110		return ret;
111	}
112
113	if (val != AF8133J_REG_PCODE_VAL) {
114		dev_warn(dev, "Invalid product code (0x%02x)\n", val);
115		return 0; /* Allow unknown ID so fallback compatibles work */
116	}
117
118	return 0;
119}
120
121static int af8133j_reset(struct af8133j_data *data)
122{
123	struct device *dev = &data->client->dev;
124	int ret;
125
126	if (data->reset_gpiod) {
127		/* If we have GPIO reset line, use it */
128		gpiod_set_value_cansleep(data->reset_gpiod, 1);
129		udelay(10);
130		gpiod_set_value_cansleep(data->reset_gpiod, 0);
131	} else {
132		/* Otherwise use software reset */
133		ret = regmap_write(data->regmap, AF8133J_REG_SWR,
134				   AF8133J_REG_SWR_PERFORM);
135		if (ret) {
136			dev_err(dev, "Failed to reset the chip\n");
137			return ret;
138		}
139	}
140
141	/* Wait for reset to finish */
142	usleep_range(1000, 1100);
143
144	/* Restore range setting */
145	if (data->range == AF8133J_REG_RANGE_22G) {
146		ret = regmap_write(data->regmap, AF8133J_REG_RANGE, data->range);
147		if (ret)
148			return ret;
149	}
150
151	return 0;
152}
153
154static void af8133j_power_down(struct af8133j_data *data)
155{
156	gpiod_set_value_cansleep(data->reset_gpiod, 1);
157	regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies);
158}
159
160static int af8133j_power_up(struct af8133j_data *data)
161{
162	struct device *dev = &data->client->dev;
163	int ret;
164
165	ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies), data->supplies);
166	if (ret) {
167		dev_err(dev, "Could not enable regulators\n");
168		return ret;
169	}
170
171	gpiod_set_value_cansleep(data->reset_gpiod, 0);
172
173	/* Wait for power on reset */
174	usleep_range(15000, 16000);
175
176	ret = af8133j_reset(data);
177	if (ret) {
178		af8133j_power_down(data);
179		return ret;
180	}
181
182	return 0;
183}
184
185static int af8133j_take_measurement(struct af8133j_data *data)
186{
187	unsigned int val;
188	int ret;
189
190	ret = regmap_write(data->regmap,
191			   AF8133J_REG_STATE, AF8133J_REG_STATE_WORK);
192	if (ret)
193		return ret;
194
195	/* The datasheet says "Mesaure Time <1.5ms" */
196	ret = regmap_read_poll_timeout(data->regmap, AF8133J_REG_STATUS, val,
197				       val & AF8133J_REG_STATUS_ACQ,
198				       500, 1500);
199	if (ret)
200		return ret;
201
202	ret = regmap_write(data->regmap,
203			   AF8133J_REG_STATE, AF8133J_REG_STATE_STBY);
204	if (ret)
205		return ret;
206
207	return 0;
208}
209
210static int af8133j_read_measurement(struct af8133j_data *data, __le16 buf[3])
211{
212	struct device *dev = &data->client->dev;
213	int ret;
214
215	ret = pm_runtime_resume_and_get(dev);
216	if (ret) {
217		/*
218		 * Ignore EACCES because that happens when RPM is disabled
219		 * during system sleep, while userspace leave eg. hrtimer
220		 * trigger attached and IIO core keeps trying to do measurements.
221		 */
222		if (ret != -EACCES)
223			dev_err(dev, "Failed to power on (%d)\n", ret);
224		return ret;
225	}
226
227	scoped_guard(mutex, &data->mutex) {
228		ret = af8133j_take_measurement(data);
229		if (ret)
230			goto out_rpm_put;
231
232		ret = regmap_bulk_read(data->regmap, AF8133J_REG_OUT,
233				       buf, sizeof(__le16) * 3);
234	}
235
236out_rpm_put:
237	pm_runtime_mark_last_busy(dev);
238	pm_runtime_put_autosuspend(dev);
239
240	return ret;
241}
242
243static const int af8133j_scales[][2] = {
244	[0] = { 0, 366210 }, /* 12 gauss */
245	[1] = { 0, 671386 }, /* 22 gauss */
246};
247
248static int af8133j_read_raw(struct iio_dev *indio_dev,
249			    struct iio_chan_spec const *chan, int *val,
250			    int *val2, long mask)
251{
252	struct af8133j_data *data = iio_priv(indio_dev);
253	__le16 buf[3];
254	int ret;
255
256	switch (mask) {
257	case IIO_CHAN_INFO_RAW:
258		ret = af8133j_read_measurement(data, buf);
259		if (ret)
260			return ret;
261
262		*val = sign_extend32(le16_to_cpu(buf[chan->address]),
263				     chan->scan_type.realbits - 1);
264		return IIO_VAL_INT;
265	case IIO_CHAN_INFO_SCALE:
266		*val = 0;
267
268		if (data->range == AF8133J_REG_RANGE_12G)
269			*val2 = af8133j_scales[0][1];
270		else
271			*val2 = af8133j_scales[1][1];
272
273		return IIO_VAL_INT_PLUS_NANO;
274	default:
275		return -EINVAL;
276	}
277}
278
279static int af8133j_read_avail(struct iio_dev *indio_dev,
280			      struct iio_chan_spec const *chan,
281			      const int **vals, int *type, int *length,
282			      long mask)
283{
284	switch (mask) {
285	case IIO_CHAN_INFO_SCALE:
286		*vals = (const int *)af8133j_scales;
287		*length = ARRAY_SIZE(af8133j_scales) * 2;
288		*type = IIO_VAL_INT_PLUS_NANO;
289		return IIO_AVAIL_LIST;
290	default:
291		return -EINVAL;
292	}
293}
294
295static int af8133j_set_scale(struct af8133j_data *data,
296			     unsigned int val, unsigned int val2)
297{
298	struct device *dev = &data->client->dev;
299	u8 range;
300	int ret = 0;
301
302	if (af8133j_scales[0][0] == val && af8133j_scales[0][1] == val2)
303		range = AF8133J_REG_RANGE_12G;
304	else if (af8133j_scales[1][0] == val && af8133j_scales[1][1] == val2)
305		range = AF8133J_REG_RANGE_22G;
306	else
307		return -EINVAL;
308
309	pm_runtime_disable(dev);
310
311	/*
312	 * When suspended, just store the new range to data->range to be
313	 * applied later during power up.
314	 */
315	if (!pm_runtime_status_suspended(dev)) {
316		scoped_guard(mutex, &data->mutex)
317			ret = regmap_write(data->regmap,
318					   AF8133J_REG_RANGE, range);
319	}
320
321	pm_runtime_enable(dev);
322
323	data->range = range;
324	return ret;
325}
326
327static int af8133j_write_raw(struct iio_dev *indio_dev,
328			     struct iio_chan_spec const *chan,
329			     int val, int val2, long mask)
330{
331	struct af8133j_data *data = iio_priv(indio_dev);
332
333	switch (mask) {
334	case IIO_CHAN_INFO_SCALE:
335		return af8133j_set_scale(data, val, val2);
336	default:
337		return -EINVAL;
338	}
339}
340
341static int af8133j_write_raw_get_fmt(struct iio_dev *indio_dev,
342				     struct iio_chan_spec const *chan,
343				     long mask)
344{
345	return IIO_VAL_INT_PLUS_NANO;
346}
347
348static const struct iio_info af8133j_info = {
349	.read_raw = af8133j_read_raw,
350	.read_avail = af8133j_read_avail,
351	.write_raw = af8133j_write_raw,
352	.write_raw_get_fmt = af8133j_write_raw_get_fmt,
353};
354
355static irqreturn_t af8133j_trigger_handler(int irq, void *p)
356{
357	struct iio_poll_func *pf = p;
358	struct iio_dev *indio_dev = pf->indio_dev;
359	struct af8133j_data *data = iio_priv(indio_dev);
360	s64 timestamp = iio_get_time_ns(indio_dev);
361	struct {
362		__le16 values[3];
363		aligned_s64 timestamp;
364	} sample = { };
365	int ret;
366
367	ret = af8133j_read_measurement(data, sample.values);
368	if (ret)
369		goto out_done;
370
371	iio_push_to_buffers_with_ts(indio_dev, &sample, sizeof(sample),
372				    timestamp);
373
374out_done:
375	iio_trigger_notify_done(indio_dev->trig);
376
377	return IRQ_HANDLED;
378}
379
380static const struct regmap_config af8133j_regmap_config = {
381	.name = "af8133j_regmap",
382	.reg_bits = 8,
383	.val_bits = 8,
384	.max_register = AF8133J_REG_SWR,
385};
386
387static void af8133j_power_down_action(void *ptr)
388{
389	struct af8133j_data *data = ptr;
390
391	if (!pm_runtime_status_suspended(&data->client->dev))
392		af8133j_power_down(data);
393}
394
395static int af8133j_probe(struct i2c_client *client)
396{
397	struct device *dev = &client->dev;
398	struct af8133j_data *data;
399	struct iio_dev *indio_dev;
400	struct regmap *regmap;
401	int ret, i;
402
403	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
404	if (!indio_dev)
405		return -ENOMEM;
406
407	regmap = devm_regmap_init_i2c(client, &af8133j_regmap_config);
408	if (IS_ERR(regmap))
409		return dev_err_probe(dev, PTR_ERR(regmap),
410				     "regmap initialization failed\n");
411
412	data = iio_priv(indio_dev);
413	i2c_set_clientdata(client, indio_dev);
414	data->client = client;
415	data->regmap = regmap;
416	data->range = AF8133J_REG_RANGE_12G;
417	mutex_init(&data->mutex);
418
419	data->reset_gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
420	if (IS_ERR(data->reset_gpiod))
421		return dev_err_probe(dev, PTR_ERR(data->reset_gpiod),
422				     "Failed to get reset gpio\n");
423
424	for (i = 0; i < ARRAY_SIZE(af8133j_supply_names); i++)
425		data->supplies[i].supply = af8133j_supply_names[i];
426	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
427				      data->supplies);
428	if (ret)
429		return ret;
430
431	ret = iio_read_mount_matrix(dev, &data->orientation);
432	if (ret)
433		return dev_err_probe(dev, ret, "Failed to read mount matrix\n");
434
435	ret = af8133j_power_up(data);
436	if (ret)
437		return ret;
438
439	pm_runtime_set_active(dev);
440
441	ret = devm_add_action_or_reset(dev, af8133j_power_down_action, data);
442	if (ret)
443		return ret;
444
445	ret = af8133j_product_check(data);
446	if (ret)
447		return ret;
448
449	pm_runtime_get_noresume(dev);
450	pm_runtime_use_autosuspend(dev);
451	pm_runtime_set_autosuspend_delay(dev, 500);
452	ret = devm_pm_runtime_enable(dev);
453	if (ret)
454		return ret;
455
456	pm_runtime_put_autosuspend(dev);
457
458	indio_dev->info = &af8133j_info;
459	indio_dev->name = "af8133j";
460	indio_dev->channels = af8133j_channels;
461	indio_dev->num_channels = ARRAY_SIZE(af8133j_channels);
462	indio_dev->modes = INDIO_DIRECT_MODE;
463
464	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
465					      &af8133j_trigger_handler, NULL);
466	if (ret)
467		return dev_err_probe(&client->dev, ret,
468				     "Failed to setup iio triggered buffer\n");
469
470	ret = devm_iio_device_register(dev, indio_dev);
471	if (ret)
472		return dev_err_probe(dev, ret, "Failed to register iio device");
473
474	return 0;
475}
476
477static int af8133j_runtime_suspend(struct device *dev)
478{
479	struct iio_dev *indio_dev = dev_get_drvdata(dev);
480	struct af8133j_data *data = iio_priv(indio_dev);
481
482	af8133j_power_down(data);
483
484	return 0;
485}
486
487static int af8133j_runtime_resume(struct device *dev)
488{
489	struct iio_dev *indio_dev = dev_get_drvdata(dev);
490	struct af8133j_data *data = iio_priv(indio_dev);
491
492	return af8133j_power_up(data);
493}
494
495static const struct dev_pm_ops af8133j_pm_ops = {
496	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
497	RUNTIME_PM_OPS(af8133j_runtime_suspend, af8133j_runtime_resume, NULL)
498};
499
500static const struct of_device_id af8133j_of_match[] = {
501	{ .compatible = "voltafield,af8133j", },
502	{ }
503};
504MODULE_DEVICE_TABLE(of, af8133j_of_match);
505
506static const struct i2c_device_id af8133j_id[] = {
507	{ "af8133j" },
508	{ }
509};
510MODULE_DEVICE_TABLE(i2c, af8133j_id);
511
512static struct i2c_driver af8133j_driver = {
513	.driver = {
514		.name = "af8133j",
515		.of_match_table = af8133j_of_match,
516		.pm = pm_ptr(&af8133j_pm_ops),
517	},
518	.probe = af8133j_probe,
519	.id_table = af8133j_id,
520};
521
522module_i2c_driver(af8133j_driver);
523
524MODULE_AUTHOR("Icenowy Zheng <icenowy@aosc.io>");
525MODULE_AUTHOR("Ondřej Jirman <megi@xff.cz>");
526MODULE_DESCRIPTION("Voltafield AF8133J magnetic sensor driver");
527MODULE_LICENSE("GPL");
~/ Read-only file preview.