[go: nahoru, domu]

1/*  Copyright (C) 2010 Texas Instruments
2    Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>
3    Acknowledgement: Jonathan Cameron <jic23@kernel.org> for valuable inputs.
4
5    Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.
6
7    Split to multiple files by Josef Gajdusek <atx@atx.name> - 2014
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#include <linux/module.h>
25#include <linux/regmap.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/trigger_consumer.h>
29#include <linux/iio/buffer.h>
30#include <linux/iio/triggered_buffer.h>
31#include <linux/delay.h>
32
33#include "hmc5843.h"
34
35/*
36 * Range gain settings in (+-)Ga
37 * Beware: HMC5843 and HMC5883 have different recommended sensor field
38 * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively
39 */
40#define HMC5843_RANGE_GAIN_OFFSET		0x05
41#define HMC5843_RANGE_GAIN_DEFAULT		0x01
42#define HMC5843_RANGE_GAIN_MASK		0xe0
43
44/* Device status */
45#define HMC5843_DATA_READY			0x01
46#define HMC5843_DATA_OUTPUT_LOCK		0x02
47
48/* Mode register configuration */
49#define HMC5843_MODE_CONVERSION_CONTINUOUS	0x00
50#define HMC5843_MODE_CONVERSION_SINGLE		0x01
51#define HMC5843_MODE_IDLE			0x02
52#define HMC5843_MODE_SLEEP			0x03
53#define HMC5843_MODE_MASK			0x03
54
55/*
56 * HMC5843: Minimum data output rate
57 * HMC5883: Typical data output rate
58 */
59#define HMC5843_RATE_OFFSET			0x02
60#define HMC5843_RATE_DEFAULT			0x04
61#define HMC5843_RATE_MASK		0x1c
62
63/* Device measurement configuration */
64#define HMC5843_MEAS_CONF_NORMAL		0x00
65#define HMC5843_MEAS_CONF_POSITIVE_BIAS		0x01
66#define HMC5843_MEAS_CONF_NEGATIVE_BIAS		0x02
67#define HMC5843_MEAS_CONF_MASK			0x03
68
69/* Scaling factors: 10000000/Gain */
70static const int hmc5843_regval_to_nanoscale[] = {
71	6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
72};
73
74static const int hmc5883_regval_to_nanoscale[] = {
75	7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
76};
77
78static const int hmc5883l_regval_to_nanoscale[] = {
79	7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
80};
81
82/*
83 * From the datasheet:
84 * Value	| HMC5843		| HMC5883/HMC5883L
85 *		| Data output rate (Hz)	| Data output rate (Hz)
86 * 0		| 0.5			| 0.75
87 * 1		| 1			| 1.5
88 * 2		| 2			| 3
89 * 3		| 5			| 7.5
90 * 4		| 10 (default)		| 15
91 * 5		| 20			| 30
92 * 6		| 50			| 75
93 * 7		| Not used		| Not used
94 */
95static const int hmc5843_regval_to_samp_freq[][2] = {
96	{0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
97};
98
99static const int hmc5883_regval_to_samp_freq[][2] = {
100	{0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
101	{75, 0}
102};
103
104static const int hmc5983_regval_to_samp_freq[][2] = {
105	{0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
106	{75, 0}, {220, 0}
107};
108
109/* Describe chip variants */
110struct hmc5843_chip_info {
111	const struct iio_chan_spec *channels;
112	const int (*regval_to_samp_freq)[2];
113	const int n_regval_to_samp_freq;
114	const int *regval_to_nanoscale;
115	const int n_regval_to_nanoscale;
116};
117
118/* The lower two bits contain the current conversion mode */
119static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
120{
121	int ret;
122
123	mutex_lock(&data->lock);
124	ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,
125			HMC5843_MODE_MASK, operating_mode);
126	mutex_unlock(&data->lock);
127
128	return ret;
129}
130
131static int hmc5843_wait_measurement(struct hmc5843_data *data)
132{
133	int tries = 150;
134	unsigned int val;
135	int ret;
136
137	while (tries-- > 0) {
138		ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);
139		if (ret < 0)
140			return ret;
141		if (val & HMC5843_DATA_READY)
142			break;
143		msleep(20);
144	}
145
146	if (tries < 0) {
147		dev_err(data->dev, "data not ready\n");
148		return -EIO;
149	}
150
151	return 0;
152}
153
154/* Return the measurement value from the specified channel */
155static int hmc5843_read_measurement(struct hmc5843_data *data,
156				    int idx, int *val)
157{
158	__be16 values[3];
159	int ret;
160
161	mutex_lock(&data->lock);
162	ret = hmc5843_wait_measurement(data);
163	if (ret < 0) {
164		mutex_unlock(&data->lock);
165		return ret;
166	}
167	ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
168			values, sizeof(values));
169	mutex_unlock(&data->lock);
170	if (ret < 0)
171		return ret;
172
173	*val = sign_extend32(be16_to_cpu(values[idx]), 15);
174	return IIO_VAL_INT;
175}
176
177/*
178 * API for setting the measurement configuration to
179 * Normal, Positive bias and Negative bias
180 *
181 * From the datasheet:
182 * 0 - Normal measurement configuration (default): In normal measurement
183 *     configuration the device follows normal measurement flow. Pins BP
184 *     and BN are left floating and high impedance.
185 *
186 * 1 - Positive bias configuration: In positive bias configuration, a
187 *     positive current is forced across the resistive load on pins BP
188 *     and BN.
189 *
190 * 2 - Negative bias configuration. In negative bias configuration, a
191 *     negative current is forced across the resistive load on pins BP
192 *     and BN.
193 *
194 */
195static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
196{
197	int ret;
198
199	mutex_lock(&data->lock);
200	ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
201			HMC5843_MEAS_CONF_MASK, meas_conf);
202	mutex_unlock(&data->lock);
203
204	return ret;
205}
206
207static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
208						struct device_attribute *attr,
209						char *buf)
210{
211	struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
212	unsigned int val;
213	int ret;
214
215	ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);
216	if (ret)
217		return ret;
218	val &= HMC5843_MEAS_CONF_MASK;
219
220	return sprintf(buf, "%d\n", val);
221}
222
223static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
224						struct device_attribute *attr,
225						const char *buf,
226						size_t count)
227{
228	struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
229	unsigned long meas_conf = 0;
230	int ret;
231
232	ret = kstrtoul(buf, 10, &meas_conf);
233	if (ret)
234		return ret;
235	if (meas_conf >= HMC5843_MEAS_CONF_MASK)
236		return -EINVAL;
237
238	ret = hmc5843_set_meas_conf(data, meas_conf);
239
240	return (ret < 0) ? ret : count;
241}
242
243static IIO_DEVICE_ATTR(meas_conf,
244			S_IWUSR | S_IRUGO,
245			hmc5843_show_measurement_configuration,
246			hmc5843_set_measurement_configuration,
247			0);
248
249static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
250				struct device_attribute *attr, char *buf)
251{
252	struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
253	size_t len = 0;
254	int i;
255
256	for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
257		len += scnprintf(buf + len, PAGE_SIZE - len,
258			"%d.%d ", data->variant->regval_to_samp_freq[i][0],
259			data->variant->regval_to_samp_freq[i][1]);
260
261	/* replace trailing space by newline */
262	buf[len - 1] = '\n';
263
264	return len;
265}
266
267static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
268
269static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
270{
271	int ret;
272
273	mutex_lock(&data->lock);
274	ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,
275			HMC5843_RATE_MASK, rate << HMC5843_RATE_OFFSET);
276	mutex_unlock(&data->lock);
277
278	return ret;
279}
280
281static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
282				   int val, int val2)
283{
284	int i;
285
286	for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)
287		if (val == data->variant->regval_to_samp_freq[i][0] &&
288			val2 == data->variant->regval_to_samp_freq[i][1])
289			return i;
290
291	return -EINVAL;
292}
293
294static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
295{
296	int ret;
297
298	mutex_lock(&data->lock);
299	ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,
300			HMC5843_RANGE_GAIN_MASK,
301			range << HMC5843_RANGE_GAIN_OFFSET);
302	mutex_unlock(&data->lock);
303
304	return ret;
305}
306
307static ssize_t hmc5843_show_scale_avail(struct device *dev,
308				struct device_attribute *attr, char *buf)
309{
310	struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
311
312	size_t len = 0;
313	int i;
314
315	for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
316		len += scnprintf(buf + len, PAGE_SIZE - len,
317			"0.%09d ", data->variant->regval_to_nanoscale[i]);
318
319	/* replace trailing space by newline */
320	buf[len - 1] = '\n';
321
322	return len;
323}
324
325static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
326	hmc5843_show_scale_avail, NULL, 0);
327
328static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
329{
330	int i;
331
332	if (val != 0)
333		return -EINVAL;
334
335	for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)
336		if (val2 == data->variant->regval_to_nanoscale[i])
337			return i;
338
339	return -EINVAL;
340}
341
342static int hmc5843_read_raw(struct iio_dev *indio_dev,
343			    struct iio_chan_spec const *chan,
344			    int *val, int *val2, long mask)
345{
346	struct hmc5843_data *data = iio_priv(indio_dev);
347	unsigned int rval;
348	int ret;
349
350	switch (mask) {
351	case IIO_CHAN_INFO_RAW:
352		return hmc5843_read_measurement(data, chan->scan_index, val);
353	case IIO_CHAN_INFO_SCALE:
354		ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);
355		if (ret < 0)
356			return ret;
357		rval >>= HMC5843_RANGE_GAIN_OFFSET;
358		*val = 0;
359		*val2 = data->variant->regval_to_nanoscale[rval];
360		return IIO_VAL_INT_PLUS_NANO;
361	case IIO_CHAN_INFO_SAMP_FREQ:
362		ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);
363		if (ret < 0)
364			return ret;
365		rval >>= HMC5843_RATE_OFFSET;
366		*val = data->variant->regval_to_samp_freq[rval][0];
367		*val2 = data->variant->regval_to_samp_freq[rval][1];
368		return IIO_VAL_INT_PLUS_MICRO;
369	}
370	return -EINVAL;
371}
372
373static int hmc5843_write_raw(struct iio_dev *indio_dev,
374			     struct iio_chan_spec const *chan,
375			     int val, int val2, long mask)
376{
377	struct hmc5843_data *data = iio_priv(indio_dev);
378	int rate, range;
379
380	switch (mask) {
381	case IIO_CHAN_INFO_SAMP_FREQ:
382		rate = hmc5843_get_samp_freq_index(data, val, val2);
383		if (rate < 0)
384			return -EINVAL;
385
386		return hmc5843_set_samp_freq(data, rate);
387	case IIO_CHAN_INFO_SCALE:
388		range = hmc5843_get_scale_index(data, val, val2);
389		if (range < 0)
390			return -EINVAL;
391
392		return hmc5843_set_range_gain(data, range);
393	default:
394		return -EINVAL;
395	}
396}
397
398static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,
399			       struct iio_chan_spec const *chan, long mask)
400{
401	switch (mask) {
402	case IIO_CHAN_INFO_SAMP_FREQ:
403		return IIO_VAL_INT_PLUS_MICRO;
404	case IIO_CHAN_INFO_SCALE:
405		return IIO_VAL_INT_PLUS_NANO;
406	default:
407		return -EINVAL;
408	}
409}
410
411static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
412{
413	struct iio_poll_func *pf = p;
414	struct iio_dev *indio_dev = pf->indio_dev;
415	struct hmc5843_data *data = iio_priv(indio_dev);
416	int ret;
417
418	mutex_lock(&data->lock);
419	ret = hmc5843_wait_measurement(data);
420	if (ret < 0) {
421		mutex_unlock(&data->lock);
422		goto done;
423	}
424
425	ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,
426			data->buffer, 3 * sizeof(__be16));
427
428	mutex_unlock(&data->lock);
429	if (ret < 0)
430		goto done;
431
432	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
433		iio_get_time_ns());
434
435done:
436	iio_trigger_notify_done(indio_dev->trig);
437
438	return IRQ_HANDLED;
439}
440
441#define HMC5843_CHANNEL(axis, idx)					\
442	{								\
443		.type = IIO_MAGN,					\
444		.modified = 1,						\
445		.channel2 = IIO_MOD_##axis,				\
446		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
447		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
448			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\
449		.scan_index = idx,					\
450		.scan_type = {						\
451			.sign = 's',					\
452			.realbits = 16,					\
453			.storagebits = 16,				\
454			.endianness = IIO_BE,				\
455		},							\
456	}
457
458static const struct iio_chan_spec hmc5843_channels[] = {
459	HMC5843_CHANNEL(X, 0),
460	HMC5843_CHANNEL(Y, 1),
461	HMC5843_CHANNEL(Z, 2),
462	IIO_CHAN_SOFT_TIMESTAMP(3),
463};
464
465/* Beware: Y and Z are exchanged on HMC5883 and 5983 */
466static const struct iio_chan_spec hmc5883_channels[] = {
467	HMC5843_CHANNEL(X, 0),
468	HMC5843_CHANNEL(Z, 1),
469	HMC5843_CHANNEL(Y, 2),
470	IIO_CHAN_SOFT_TIMESTAMP(3),
471};
472
473static struct attribute *hmc5843_attributes[] = {
474	&iio_dev_attr_meas_conf.dev_attr.attr,
475	&iio_dev_attr_scale_available.dev_attr.attr,
476	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
477	NULL
478};
479
480static const struct attribute_group hmc5843_group = {
481	.attrs = hmc5843_attributes,
482};
483
484static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
485	[HMC5843_ID] = {
486		.channels = hmc5843_channels,
487		.regval_to_samp_freq = hmc5843_regval_to_samp_freq,
488		.n_regval_to_samp_freq =
489				ARRAY_SIZE(hmc5843_regval_to_samp_freq),
490		.regval_to_nanoscale = hmc5843_regval_to_nanoscale,
491		.n_regval_to_nanoscale =
492				ARRAY_SIZE(hmc5843_regval_to_nanoscale),
493	},
494	[HMC5883_ID] = {
495		.channels = hmc5883_channels,
496		.regval_to_samp_freq = hmc5883_regval_to_samp_freq,
497		.n_regval_to_samp_freq =
498				ARRAY_SIZE(hmc5883_regval_to_samp_freq),
499		.regval_to_nanoscale = hmc5883_regval_to_nanoscale,
500		.n_regval_to_nanoscale =
501				ARRAY_SIZE(hmc5883_regval_to_nanoscale),
502	},
503	[HMC5883L_ID] = {
504		.channels = hmc5883_channels,
505		.regval_to_samp_freq = hmc5883_regval_to_samp_freq,
506		.n_regval_to_samp_freq =
507				ARRAY_SIZE(hmc5883_regval_to_samp_freq),
508		.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
509		.n_regval_to_nanoscale =
510				ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
511	},
512	[HMC5983_ID] = {
513		.channels = hmc5883_channels,
514		.regval_to_samp_freq = hmc5983_regval_to_samp_freq,
515		.n_regval_to_samp_freq =
516				ARRAY_SIZE(hmc5983_regval_to_samp_freq),
517		.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
518		.n_regval_to_nanoscale =
519				ARRAY_SIZE(hmc5883l_regval_to_nanoscale),
520	}
521};
522
523static int hmc5843_init(struct hmc5843_data *data)
524{
525	int ret;
526	u8 id[3];
527
528	ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,
529			id, ARRAY_SIZE(id));
530	if (ret < 0)
531		return ret;
532	if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
533		dev_err(data->dev, "no HMC5843/5883/5883L/5983 sensor\n");
534		return -ENODEV;
535	}
536
537	ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
538	if (ret < 0)
539		return ret;
540	ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
541	if (ret < 0)
542		return ret;
543	ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
544	if (ret < 0)
545		return ret;
546	return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
547}
548
549static const struct iio_info hmc5843_info = {
550	.attrs = &hmc5843_group,
551	.read_raw = &hmc5843_read_raw,
552	.write_raw = &hmc5843_write_raw,
553	.write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
554	.driver_module = THIS_MODULE,
555};
556
557static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
558
559
560int hmc5843_common_suspend(struct device *dev)
561{
562	return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
563			HMC5843_MODE_CONVERSION_CONTINUOUS);
564}
565EXPORT_SYMBOL(hmc5843_common_suspend);
566
567int hmc5843_common_resume(struct device *dev)
568{
569	return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),
570			HMC5843_MODE_SLEEP);
571}
572EXPORT_SYMBOL(hmc5843_common_resume);
573
574int hmc5843_common_probe(struct device *dev, struct regmap *regmap,
575		enum hmc5843_ids id)
576{
577	struct hmc5843_data *data;
578	struct iio_dev *indio_dev;
579	int ret;
580
581	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
582	if (indio_dev == NULL)
583		return -ENOMEM;
584
585	dev_set_drvdata(dev, indio_dev);
586
587	/* default settings at probe */
588	data = iio_priv(indio_dev);
589	data->dev = dev;
590	data->regmap = regmap;
591	data->variant = &hmc5843_chip_info_tbl[id];
592	mutex_init(&data->lock);
593
594	indio_dev->dev.parent = dev;
595	indio_dev->info = &hmc5843_info;
596	indio_dev->modes = INDIO_DIRECT_MODE;
597	indio_dev->channels = data->variant->channels;
598	indio_dev->num_channels = 4;
599	indio_dev->available_scan_masks = hmc5843_scan_masks;
600
601	ret = hmc5843_init(data);
602	if (ret < 0)
603		return ret;
604
605	ret = iio_triggered_buffer_setup(indio_dev, NULL,
606		hmc5843_trigger_handler, NULL);
607	if (ret < 0)
608		return ret;
609
610	ret = iio_device_register(indio_dev);
611	if (ret < 0)
612		goto buffer_cleanup;
613
614	return 0;
615
616buffer_cleanup:
617	iio_triggered_buffer_cleanup(indio_dev);
618	return ret;
619}
620EXPORT_SYMBOL(hmc5843_common_probe);
621
622int hmc5843_common_remove(struct device *dev)
623{
624	struct iio_dev *indio_dev = dev_get_drvdata(dev);
625
626	iio_device_unregister(indio_dev);
627	iio_triggered_buffer_cleanup(indio_dev);
628
629	/*  sleep mode to save power */
630	hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
631
632	return 0;
633}
634EXPORT_SYMBOL(hmc5843_common_remove);
635
636MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
637MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver");
638MODULE_LICENSE("GPL");
639