brintos

brintos / linux-shallow public Read only

0
0
Text · 17.8 KiB · c5521d6 Raw
689 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Device driver for the HMC5843 multi-chip module designed4 * for low field magnetic sensing.5 *6 * Copyright (C) 2010 Texas Instruments7 *8 * Author: Shubhrajyoti Datta <shubhrajyoti@ti.com>9 * Acknowledgment: Jonathan Cameron <jic23@kernel.org> for valuable inputs.10 * Support for HMC5883 and HMC5883L by Peter Meerwald <pmeerw@pmeerw.net>.11 * Split to multiple files by Josef Gajdusek <atx@atx.name> - 201412 */13 14#include <linux/module.h>15#include <linux/regmap.h>16#include <linux/iio/iio.h>17#include <linux/iio/sysfs.h>18#include <linux/iio/trigger_consumer.h>19#include <linux/iio/buffer.h>20#include <linux/iio/triggered_buffer.h>21#include <linux/delay.h>22 23#include "hmc5843.h"24 25/*26 * Range gain settings in (+-)Ga27 * Beware: HMC5843 and HMC5883 have different recommended sensor field28 * ranges; default corresponds to +-1.0 Ga and +-1.3 Ga, respectively29 */30#define HMC5843_RANGE_GAIN_OFFSET		0x0531#define HMC5843_RANGE_GAIN_DEFAULT		0x0132#define HMC5843_RANGE_GAIN_MASK		0xe033 34/* Device status */35#define HMC5843_DATA_READY			0x0136#define HMC5843_DATA_OUTPUT_LOCK		0x0237 38/* Mode register configuration */39#define HMC5843_MODE_CONVERSION_CONTINUOUS	0x0040#define HMC5843_MODE_CONVERSION_SINGLE		0x0141#define HMC5843_MODE_IDLE			0x0242#define HMC5843_MODE_SLEEP			0x0343#define HMC5843_MODE_MASK			0x0344 45/*46 * HMC5843: Minimum data output rate47 * HMC5883: Typical data output rate48 */49#define HMC5843_RATE_OFFSET			0x0250#define HMC5843_RATE_DEFAULT			0x0451#define HMC5843_RATE_MASK		0x1c52 53/* Device measurement configuration */54#define HMC5843_MEAS_CONF_NORMAL		0x0055#define HMC5843_MEAS_CONF_POSITIVE_BIAS		0x0156#define HMC5843_MEAS_CONF_NEGATIVE_BIAS		0x0257#define HMC5843_MEAS_CONF_MASK			0x0358 59/*60 * API for setting the measurement configuration to61 * Normal, Positive bias and Negative bias62 *63 * From the datasheet:64 * 0 - Normal measurement configuration (default): In normal measurement65 *     configuration the device follows normal measurement flow. Pins BP66 *     and BN are left floating and high impedance.67 *68 * 1 - Positive bias configuration: In positive bias configuration, a69 *     positive current is forced across the resistive load on pins BP70 *     and BN.71 *72 * 2 - Negative bias configuration. In negative bias configuration, a73 *     negative current is forced across the resistive load on pins BP74 *     and BN.75 *76 * 3 - Only available on HMC5983. Magnetic sensor is disabled.77 *     Temperature sensor is enabled.78 */79 80static const char *const hmc5843_meas_conf_modes[] = {"normal", "positivebias",81						      "negativebias"};82 83static const char *const hmc5983_meas_conf_modes[] = {"normal", "positivebias",84						      "negativebias",85						      "disabled"};86/* Scaling factors: 10000000/Gain */87static const int hmc5843_regval_to_nanoscale[] = {88	6173, 7692, 10309, 12821, 18868, 21739, 25641, 3571489};90 91static const int hmc5883_regval_to_nanoscale[] = {92	7812, 9766, 13021, 16287, 24096, 27701, 32573, 4566293};94 95static const int hmc5883l_regval_to_nanoscale[] = {96	7299, 9174, 12195, 15152, 22727, 25641, 30303, 4347897};98 99/*100 * From the datasheet:101 * Value	| HMC5843		| HMC5883/HMC5883L102 *		| Data output rate (Hz)	| Data output rate (Hz)103 * 0		| 0.5			| 0.75104 * 1		| 1			| 1.5105 * 2		| 2			| 3106 * 3		| 5			| 7.5107 * 4		| 10 (default)		| 15108 * 5		| 20			| 30109 * 6		| 50			| 75110 * 7		| Not used		| Not used111 */112static const int hmc5843_regval_to_samp_freq[][2] = {113	{0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}114};115 116static const int hmc5883_regval_to_samp_freq[][2] = {117	{0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},118	{75, 0}119};120 121static const int hmc5983_regval_to_samp_freq[][2] = {122	{0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},123	{75, 0}, {220, 0}124};125 126/* Describe chip variants */127struct hmc5843_chip_info {128	const struct iio_chan_spec *channels;129	const int (*regval_to_samp_freq)[2];130	const int n_regval_to_samp_freq;131	const int *regval_to_nanoscale;132	const int n_regval_to_nanoscale;133};134 135/* The lower two bits contain the current conversion mode */136static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)137{138	int ret;139 140	mutex_lock(&data->lock);141	ret = regmap_update_bits(data->regmap, HMC5843_MODE_REG,142				 HMC5843_MODE_MASK, operating_mode);143	mutex_unlock(&data->lock);144 145	return ret;146}147 148static int hmc5843_wait_measurement(struct hmc5843_data *data)149{150	int tries = 150;151	unsigned int val;152	int ret;153 154	while (tries-- > 0) {155		ret = regmap_read(data->regmap, HMC5843_STATUS_REG, &val);156		if (ret < 0)157			return ret;158		if (val & HMC5843_DATA_READY)159			break;160		msleep(20);161	}162 163	if (tries < 0) {164		dev_err(data->dev, "data not ready\n");165		return -EIO;166	}167 168	return 0;169}170 171/* Return the measurement value from the specified channel */172static int hmc5843_read_measurement(struct hmc5843_data *data,173				    int idx, int *val)174{175	__be16 values[3];176	int ret;177 178	mutex_lock(&data->lock);179	ret = hmc5843_wait_measurement(data);180	if (ret < 0) {181		mutex_unlock(&data->lock);182		return ret;183	}184	ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,185			       values, sizeof(values));186	mutex_unlock(&data->lock);187	if (ret < 0)188		return ret;189 190	*val = sign_extend32(be16_to_cpu(values[idx]), 15);191	return IIO_VAL_INT;192}193 194static int hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)195{196	int ret;197 198	mutex_lock(&data->lock);199	ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,200				 HMC5843_MEAS_CONF_MASK, meas_conf);201	mutex_unlock(&data->lock);202 203	return ret;204}205 206static207int hmc5843_show_measurement_configuration(struct iio_dev *indio_dev,208					   const struct iio_chan_spec *chan)209{210	struct hmc5843_data *data = iio_priv(indio_dev);211	unsigned int val;212	int ret;213 214	ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val);215	if (ret)216		return ret;217 218	return val & HMC5843_MEAS_CONF_MASK;219}220 221static222int hmc5843_set_measurement_configuration(struct iio_dev *indio_dev,223					  const struct iio_chan_spec *chan,224					  unsigned int meas_conf)225{226	struct hmc5843_data *data = iio_priv(indio_dev);227 228	return hmc5843_set_meas_conf(data, meas_conf);229}230 231static const struct iio_mount_matrix *232hmc5843_get_mount_matrix(const struct iio_dev *indio_dev,233			  const struct iio_chan_spec *chan)234{235	struct hmc5843_data *data = iio_priv(indio_dev);236 237	return &data->orientation;238}239 240static const struct iio_enum hmc5843_meas_conf_enum = {241	.items = hmc5843_meas_conf_modes,242	.num_items = ARRAY_SIZE(hmc5843_meas_conf_modes),243	.get = hmc5843_show_measurement_configuration,244	.set = hmc5843_set_measurement_configuration,245};246 247static const struct iio_chan_spec_ext_info hmc5843_ext_info[] = {248	IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5843_meas_conf_enum),249	IIO_ENUM_AVAILABLE("meas_conf", IIO_SHARED_BY_TYPE, &hmc5843_meas_conf_enum),250	IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix),251	{ }252};253 254static const struct iio_enum hmc5983_meas_conf_enum = {255	.items = hmc5983_meas_conf_modes,256	.num_items = ARRAY_SIZE(hmc5983_meas_conf_modes),257	.get = hmc5843_show_measurement_configuration,258	.set = hmc5843_set_measurement_configuration,259};260 261static const struct iio_chan_spec_ext_info hmc5983_ext_info[] = {262	IIO_ENUM("meas_conf", IIO_SHARED_BY_TYPE, &hmc5983_meas_conf_enum),263	IIO_ENUM_AVAILABLE("meas_conf", IIO_SHARED_BY_TYPE, &hmc5983_meas_conf_enum),264	IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, hmc5843_get_mount_matrix),265	{ }266};267 268static269ssize_t hmc5843_show_samp_freq_avail(struct device *dev,270				     struct device_attribute *attr, char *buf)271{272	struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));273	size_t len = 0;274	int i;275 276	for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)277		len += scnprintf(buf + len, PAGE_SIZE - len,278			"%d.%d ", data->variant->regval_to_samp_freq[i][0],279			data->variant->regval_to_samp_freq[i][1]);280 281	/* replace trailing space by newline */282	buf[len - 1] = '\n';283 284	return len;285}286 287static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);288 289static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)290{291	int ret;292 293	mutex_lock(&data->lock);294	ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_A,295				 HMC5843_RATE_MASK,296				 rate << HMC5843_RATE_OFFSET);297	mutex_unlock(&data->lock);298 299	return ret;300}301 302static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,303				       int val, int val2)304{305	int i;306 307	for (i = 0; i < data->variant->n_regval_to_samp_freq; i++)308		if (val == data->variant->regval_to_samp_freq[i][0] &&309		    val2 == data->variant->regval_to_samp_freq[i][1])310			return i;311 312	return -EINVAL;313}314 315static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)316{317	int ret;318 319	mutex_lock(&data->lock);320	ret = regmap_update_bits(data->regmap, HMC5843_CONFIG_REG_B,321				 HMC5843_RANGE_GAIN_MASK,322				 range << HMC5843_RANGE_GAIN_OFFSET);323	mutex_unlock(&data->lock);324 325	return ret;326}327 328static ssize_t hmc5843_show_scale_avail(struct device *dev,329					struct device_attribute *attr,330					char *buf)331{332	struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));333 334	size_t len = 0;335	int i;336 337	for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)338		len += scnprintf(buf + len, PAGE_SIZE - len,339			"0.%09d ", data->variant->regval_to_nanoscale[i]);340 341	/* replace trailing space by newline */342	buf[len - 1] = '\n';343 344	return len;345}346 347static IIO_DEVICE_ATTR(scale_available, S_IRUGO,348	hmc5843_show_scale_avail, NULL, 0);349 350static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)351{352	int i;353 354	if (val)355		return -EINVAL;356 357	for (i = 0; i < data->variant->n_regval_to_nanoscale; i++)358		if (val2 == data->variant->regval_to_nanoscale[i])359			return i;360 361	return -EINVAL;362}363 364static int hmc5843_read_raw(struct iio_dev *indio_dev,365			    struct iio_chan_spec const *chan,366			    int *val, int *val2, long mask)367{368	struct hmc5843_data *data = iio_priv(indio_dev);369	unsigned int rval;370	int ret;371 372	switch (mask) {373	case IIO_CHAN_INFO_RAW:374		return hmc5843_read_measurement(data, chan->scan_index, val);375	case IIO_CHAN_INFO_SCALE:376		ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_B, &rval);377		if (ret < 0)378			return ret;379		rval >>= HMC5843_RANGE_GAIN_OFFSET;380		*val = 0;381		*val2 = data->variant->regval_to_nanoscale[rval];382		return IIO_VAL_INT_PLUS_NANO;383	case IIO_CHAN_INFO_SAMP_FREQ:384		ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &rval);385		if (ret < 0)386			return ret;387		rval >>= HMC5843_RATE_OFFSET;388		*val = data->variant->regval_to_samp_freq[rval][0];389		*val2 = data->variant->regval_to_samp_freq[rval][1];390		return IIO_VAL_INT_PLUS_MICRO;391	}392	return -EINVAL;393}394 395static int hmc5843_write_raw(struct iio_dev *indio_dev,396			     struct iio_chan_spec const *chan,397			     int val, int val2, long mask)398{399	struct hmc5843_data *data = iio_priv(indio_dev);400	int rate, range;401 402	switch (mask) {403	case IIO_CHAN_INFO_SAMP_FREQ:404		rate = hmc5843_get_samp_freq_index(data, val, val2);405		if (rate < 0)406			return -EINVAL;407 408		return hmc5843_set_samp_freq(data, rate);409	case IIO_CHAN_INFO_SCALE:410		range = hmc5843_get_scale_index(data, val, val2);411		if (range < 0)412			return -EINVAL;413 414		return hmc5843_set_range_gain(data, range);415	default:416		return -EINVAL;417	}418}419 420static int hmc5843_write_raw_get_fmt(struct iio_dev *indio_dev,421				     struct iio_chan_spec const *chan,422				     long mask)423{424	switch (mask) {425	case IIO_CHAN_INFO_SAMP_FREQ:426		return IIO_VAL_INT_PLUS_MICRO;427	case IIO_CHAN_INFO_SCALE:428		return IIO_VAL_INT_PLUS_NANO;429	default:430		return -EINVAL;431	}432}433 434static irqreturn_t hmc5843_trigger_handler(int irq, void *p)435{436	struct iio_poll_func *pf = p;437	struct iio_dev *indio_dev = pf->indio_dev;438	struct hmc5843_data *data = iio_priv(indio_dev);439	int ret;440 441	mutex_lock(&data->lock);442	ret = hmc5843_wait_measurement(data);443	if (ret < 0) {444		mutex_unlock(&data->lock);445		goto done;446	}447 448	ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS,449			       data->scan.chans, sizeof(data->scan.chans));450 451	mutex_unlock(&data->lock);452	if (ret < 0)453		goto done;454 455	iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,456					   iio_get_time_ns(indio_dev));457 458done:459	iio_trigger_notify_done(indio_dev->trig);460 461	return IRQ_HANDLED;462}463 464#define HMC5843_CHANNEL(axis, idx)					\465	{								\466		.type = IIO_MAGN,					\467		.modified = 1,						\468		.channel2 = IIO_MOD_##axis,				\469		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\470		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\471			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\472		.scan_index = idx,					\473		.scan_type = {						\474			.sign = 's',					\475			.realbits = 16,					\476			.storagebits = 16,				\477			.endianness = IIO_BE,				\478		},							\479		.ext_info = hmc5843_ext_info,	\480	}481 482#define HMC5983_CHANNEL(axis, idx)					\483	{								\484		.type = IIO_MAGN,					\485		.modified = 1,						\486		.channel2 = IIO_MOD_##axis,				\487		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\488		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\489			BIT(IIO_CHAN_INFO_SAMP_FREQ),			\490		.scan_index = idx,					\491		.scan_type = {						\492			.sign = 's',					\493			.realbits = 16,					\494			.storagebits = 16,				\495			.endianness = IIO_BE,				\496		},							\497		.ext_info = hmc5983_ext_info,	\498	}499 500static const struct iio_chan_spec hmc5843_channels[] = {501	HMC5843_CHANNEL(X, 0),502	HMC5843_CHANNEL(Y, 1),503	HMC5843_CHANNEL(Z, 2),504	IIO_CHAN_SOFT_TIMESTAMP(3),505};506 507/* Beware: Y and Z are exchanged on HMC5883 and 5983 */508static const struct iio_chan_spec hmc5883_channels[] = {509	HMC5843_CHANNEL(X, 0),510	HMC5843_CHANNEL(Z, 1),511	HMC5843_CHANNEL(Y, 2),512	IIO_CHAN_SOFT_TIMESTAMP(3),513};514 515static const struct iio_chan_spec hmc5983_channels[] = {516	HMC5983_CHANNEL(X, 0),517	HMC5983_CHANNEL(Z, 1),518	HMC5983_CHANNEL(Y, 2),519	IIO_CHAN_SOFT_TIMESTAMP(3),520};521 522static struct attribute *hmc5843_attributes[] = {523	&iio_dev_attr_scale_available.dev_attr.attr,524	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,525	NULL526};527 528static const struct attribute_group hmc5843_group = {529	.attrs = hmc5843_attributes,530};531 532static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {533	[HMC5843_ID] = {534		.channels = hmc5843_channels,535		.regval_to_samp_freq = hmc5843_regval_to_samp_freq,536		.n_regval_to_samp_freq =537				ARRAY_SIZE(hmc5843_regval_to_samp_freq),538		.regval_to_nanoscale = hmc5843_regval_to_nanoscale,539		.n_regval_to_nanoscale =540				ARRAY_SIZE(hmc5843_regval_to_nanoscale),541	},542	[HMC5883_ID] = {543		.channels = hmc5883_channels,544		.regval_to_samp_freq = hmc5883_regval_to_samp_freq,545		.n_regval_to_samp_freq =546				ARRAY_SIZE(hmc5883_regval_to_samp_freq),547		.regval_to_nanoscale = hmc5883_regval_to_nanoscale,548		.n_regval_to_nanoscale =549				ARRAY_SIZE(hmc5883_regval_to_nanoscale),550	},551	[HMC5883L_ID] = {552		.channels = hmc5883_channels,553		.regval_to_samp_freq = hmc5883_regval_to_samp_freq,554		.n_regval_to_samp_freq =555				ARRAY_SIZE(hmc5883_regval_to_samp_freq),556		.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,557		.n_regval_to_nanoscale =558				ARRAY_SIZE(hmc5883l_regval_to_nanoscale),559	},560	[HMC5983_ID] = {561		.channels = hmc5983_channels,562		.regval_to_samp_freq = hmc5983_regval_to_samp_freq,563		.n_regval_to_samp_freq =564				ARRAY_SIZE(hmc5983_regval_to_samp_freq),565		.regval_to_nanoscale = hmc5883l_regval_to_nanoscale,566		.n_regval_to_nanoscale =567				ARRAY_SIZE(hmc5883l_regval_to_nanoscale),568	}569};570 571static int hmc5843_init(struct hmc5843_data *data)572{573	int ret;574	u8 id[3];575 576	ret = regmap_bulk_read(data->regmap, HMC5843_ID_REG,577			       id, ARRAY_SIZE(id));578	if (ret < 0)579		return ret;580	if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {581		dev_err(data->dev, "no HMC5843/5883/5883L/5983 sensor\n");582		return -ENODEV;583	}584 585	ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);586	if (ret < 0)587		return ret;588	ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);589	if (ret < 0)590		return ret;591	ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);592	if (ret < 0)593		return ret;594	return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);595}596 597static const struct iio_info hmc5843_info = {598	.attrs = &hmc5843_group,599	.read_raw = &hmc5843_read_raw,600	.write_raw = &hmc5843_write_raw,601	.write_raw_get_fmt = &hmc5843_write_raw_get_fmt,602};603 604static const unsigned long hmc5843_scan_masks[] = {0x7, 0};605 606static int hmc5843_common_suspend(struct device *dev)607{608	return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),609				HMC5843_MODE_SLEEP);610}611 612static int hmc5843_common_resume(struct device *dev)613{614	return hmc5843_set_mode(iio_priv(dev_get_drvdata(dev)),615		HMC5843_MODE_CONVERSION_CONTINUOUS);616}617EXPORT_NS_SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_common_suspend,618			    hmc5843_common_resume, IIO_HMC5843);619 620int hmc5843_common_probe(struct device *dev, struct regmap *regmap,621			 enum hmc5843_ids id, const char *name)622{623	struct hmc5843_data *data;624	struct iio_dev *indio_dev;625	int ret;626 627	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));628	if (!indio_dev)629		return -ENOMEM;630 631	dev_set_drvdata(dev, indio_dev);632 633	/* default settings at probe */634	data = iio_priv(indio_dev);635	data->dev = dev;636	data->regmap = regmap;637	data->variant = &hmc5843_chip_info_tbl[id];638	mutex_init(&data->lock);639 640	ret = iio_read_mount_matrix(dev, &data->orientation);641	if (ret)642		return ret;643 644	indio_dev->name = name;645	indio_dev->info = &hmc5843_info;646	indio_dev->modes = INDIO_DIRECT_MODE;647	indio_dev->channels = data->variant->channels;648	indio_dev->num_channels = 4;649	indio_dev->available_scan_masks = hmc5843_scan_masks;650 651	ret = hmc5843_init(data);652	if (ret < 0)653		return ret;654 655	ret = iio_triggered_buffer_setup(indio_dev, NULL,656					 hmc5843_trigger_handler, NULL);657	if (ret < 0)658		goto buffer_setup_err;659 660	ret = iio_device_register(indio_dev);661	if (ret < 0)662		goto buffer_cleanup;663 664	return 0;665 666buffer_cleanup:667	iio_triggered_buffer_cleanup(indio_dev);668buffer_setup_err:669	hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);670	return ret;671}672EXPORT_SYMBOL_NS(hmc5843_common_probe, IIO_HMC5843);673 674void hmc5843_common_remove(struct device *dev)675{676	struct iio_dev *indio_dev = dev_get_drvdata(dev);677 678	iio_device_unregister(indio_dev);679	iio_triggered_buffer_cleanup(indio_dev);680 681	/*  sleep mode to save power */682	hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);683}684EXPORT_SYMBOL_NS(hmc5843_common_remove, IIO_HMC5843);685 686MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");687MODULE_DESCRIPTION("HMC5843/5883/5883L/5983 core driver");688MODULE_LICENSE("GPL");689