xref: /linux/drivers/iio/magnetometer/mmc5983.c (revision 0000d9ccbcfa90411c88f70850501723389312b9)
1*243a738cSVladislav Kulikov // SPDX-License-Identifier: GPL-2.0-only
2*243a738cSVladislav Kulikov /*
3*243a738cSVladislav Kulikov  * MMC5983 - MEMSIC 3-axis Magnetic Sensor
4*243a738cSVladislav Kulikov  *
5*243a738cSVladislav Kulikov  * Copyright (c) 2026, Vlad Kulikov <vlad.kulikov.c@gmail.com>
6*243a738cSVladislav Kulikov  *
7*243a738cSVladislav Kulikov  * IIO driver for MMC5983
8*243a738cSVladislav Kulikov  */
9*243a738cSVladislav Kulikov 
10*243a738cSVladislav Kulikov #include <linux/array_size.h>
11*243a738cSVladislav Kulikov #include <linux/bits.h>
12*243a738cSVladislav Kulikov #include <linux/cleanup.h>
13*243a738cSVladislav Kulikov #include <linux/delay.h>
14*243a738cSVladislav Kulikov #include <linux/dev_printk.h>
15*243a738cSVladislav Kulikov #include <linux/err.h>
16*243a738cSVladislav Kulikov #include <linux/i2c.h>
17*243a738cSVladislav Kulikov #include <linux/iio/iio.h>
18*243a738cSVladislav Kulikov #include <linux/mod_devicetable.h>
19*243a738cSVladislav Kulikov #include <linux/module.h>
20*243a738cSVladislav Kulikov #include <linux/mutex.h>
21*243a738cSVladislav Kulikov #include <linux/regmap.h>
22*243a738cSVladislav Kulikov #include <linux/time.h>
23*243a738cSVladislav Kulikov #include <linux/types.h>
24*243a738cSVladislav Kulikov 
25*243a738cSVladislav Kulikov #define MMC5983_REG_XOUT0	0x00
26*243a738cSVladislav Kulikov #define MMC5983_REG_XOUT1	0x01
27*243a738cSVladislav Kulikov #define MMC5983_REG_YOUT0	0x02
28*243a738cSVladislav Kulikov #define MMC5983_REG_YOUT1	0x03
29*243a738cSVladislav Kulikov #define MMC5983_REG_ZOUT0	0x04
30*243a738cSVladislav Kulikov #define MMC5983_REG_ZOUT1	0x05
31*243a738cSVladislav Kulikov #define MMC5983_REG_XYZOUT2	0x06
32*243a738cSVladislav Kulikov 
33*243a738cSVladislav Kulikov #define MMC5983_REG_STATUS	0x08
34*243a738cSVladislav Kulikov 
35*243a738cSVladislav Kulikov #define MMC5983_REG_CTRL0	0x09
36*243a738cSVladislav Kulikov #define MMC5983_REG_CTRL1	0x0A
37*243a738cSVladislav Kulikov #define MMC5983_REG_CTRL2	0x0B
38*243a738cSVladislav Kulikov #define MMC5983_REG_CTRL3	0x0C
39*243a738cSVladislav Kulikov 
40*243a738cSVladislav Kulikov #define MMC5983_REG_ID		0x2F
41*243a738cSVladislav Kulikov 
42*243a738cSVladislav Kulikov #define MMC5983_PRODUCT_ID	0x30
43*243a738cSVladislav Kulikov 
44*243a738cSVladislav Kulikov #define MMC5983_STATUS_MEAS_M_DONE_BIT	BIT(0)
45*243a738cSVladislav Kulikov #define MMC5983_STATUS_OTP_RD_DONE_BIT	BIT(4)
46*243a738cSVladislav Kulikov 
47*243a738cSVladislav Kulikov #define MMC5983_CTRL0_TM_M_BIT		BIT(0)
48*243a738cSVladislav Kulikov #define MMC5983_CTRL0_SET_BIT		BIT(3)
49*243a738cSVladislav Kulikov #define MMC5983_CTRL0_RESET_BIT		BIT(4)
50*243a738cSVladislav Kulikov #define MMC5983_CTRL0_OTP_RD_BIT	BIT(6)
51*243a738cSVladislav Kulikov 
52*243a738cSVladislav Kulikov #define MMC5983_CTRL1_SW_RST_BIT	BIT(7)
53*243a738cSVladislav Kulikov 
54*243a738cSVladislav Kulikov enum mmc5983_axis {
55*243a738cSVladislav Kulikov 	MMC5983_AXIS_X,
56*243a738cSVladislav Kulikov 	MMC5983_AXIS_Y,
57*243a738cSVladislav Kulikov 	MMC5983_AXIS_Z,
58*243a738cSVladislav Kulikov };
59*243a738cSVladislav Kulikov 
60*243a738cSVladislav Kulikov struct mmc5983_data {
61*243a738cSVladislav Kulikov 	struct regmap *regmap;
62*243a738cSVladislav Kulikov 	/* Protects chip access during SET/RESET measurement sequence */
63*243a738cSVladislav Kulikov 	struct mutex mutex;
64*243a738cSVladislav Kulikov };
65*243a738cSVladislav Kulikov 
66*243a738cSVladislav Kulikov #define MMC5983_CHANNEL(_axis) { \
67*243a738cSVladislav Kulikov 	.type = IIO_MAGN, \
68*243a738cSVladislav Kulikov 	.modified = 1, \
69*243a738cSVladislav Kulikov 	.channel2 = IIO_MOD_##_axis, \
70*243a738cSVladislav Kulikov 	.address = MMC5983_AXIS_##_axis, \
71*243a738cSVladislav Kulikov 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
72*243a738cSVladislav Kulikov 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
73*243a738cSVladislav Kulikov }
74*243a738cSVladislav Kulikov 
75*243a738cSVladislav Kulikov static const struct iio_chan_spec mmc5983_channels[] = {
76*243a738cSVladislav Kulikov 	MMC5983_CHANNEL(X),
77*243a738cSVladislav Kulikov 	MMC5983_CHANNEL(Y),
78*243a738cSVladislav Kulikov 	MMC5983_CHANNEL(Z),
79*243a738cSVladislav Kulikov };
80*243a738cSVladislav Kulikov 
81*243a738cSVladislav Kulikov static int mmc5983_pulse_coil(struct mmc5983_data *data, unsigned int coil_bit)
82*243a738cSVladislav Kulikov {
83*243a738cSVladislav Kulikov 	int ret;
84*243a738cSVladislav Kulikov 
85*243a738cSVladislav Kulikov 	ret = regmap_write(data->regmap, MMC5983_REG_CTRL0, coil_bit);
86*243a738cSVladislav Kulikov 	if (ret)
87*243a738cSVladislav Kulikov 		return ret;
88*243a738cSVladislav Kulikov 
89*243a738cSVladislav Kulikov 	/*
90*243a738cSVladislav Kulikov 	 * Datasheet page 15: SET/RESET coil pulse is 500 ns.
91*243a738cSVladislav Kulikov 	 * Vendor sample code waits 500 us before the next operation.
92*243a738cSVladislav Kulikov 	 */
93*243a738cSVladislav Kulikov 	fsleep(500);
94*243a738cSVladislav Kulikov 
95*243a738cSVladislav Kulikov 	return 0;
96*243a738cSVladislav Kulikov }
97*243a738cSVladislav Kulikov 
98*243a738cSVladislav Kulikov static int mmc5983_take_measurement(struct mmc5983_data *data, int m[3])
99*243a738cSVladislav Kulikov {
100*243a738cSVladislav Kulikov 	unsigned int status;
101*243a738cSVladislav Kulikov 	u8 buf[7];
102*243a738cSVladislav Kulikov 	int ret;
103*243a738cSVladislav Kulikov 
104*243a738cSVladislav Kulikov 	ret = regmap_write(data->regmap, MMC5983_REG_CTRL0,
105*243a738cSVladislav Kulikov 			   MMC5983_CTRL0_TM_M_BIT);
106*243a738cSVladislav Kulikov 	if (ret)
107*243a738cSVladislav Kulikov 		return ret;
108*243a738cSVladislav Kulikov 
109*243a738cSVladislav Kulikov 	/*
110*243a738cSVladislav Kulikov 	 * Datasheet page 15: measurement time is 8 ms at BW=00 (default,
111*243a738cSVladislav Kulikov 	 * slowest setting). Use a 50 ms timeout for margin.
112*243a738cSVladislav Kulikov 	 */
113*243a738cSVladislav Kulikov 	ret = regmap_read_poll_timeout(data->regmap, MMC5983_REG_STATUS,
114*243a738cSVladislav Kulikov 				       status,
115*243a738cSVladislav Kulikov 				       status & MMC5983_STATUS_MEAS_M_DONE_BIT,
116*243a738cSVladislav Kulikov 				       10 * USEC_PER_MSEC,
117*243a738cSVladislav Kulikov 				       50 * USEC_PER_MSEC);
118*243a738cSVladislav Kulikov 	if (ret)
119*243a738cSVladislav Kulikov 		return ret;
120*243a738cSVladislav Kulikov 
121*243a738cSVladislav Kulikov 	ret = regmap_bulk_read(data->regmap, MMC5983_REG_XOUT0, buf,
122*243a738cSVladislav Kulikov 			       sizeof(buf));
123*243a738cSVladislav Kulikov 	if (ret)
124*243a738cSVladislav Kulikov 		return ret;
125*243a738cSVladislav Kulikov 
126*243a738cSVladislav Kulikov 	m[0] = (buf[0] << 10) | (buf[1] << 2) | ((buf[6] >> 6) & 0x3);
127*243a738cSVladislav Kulikov 	m[1] = (buf[2] << 10) | (buf[3] << 2) | ((buf[6] >> 4) & 0x3);
128*243a738cSVladislav Kulikov 	m[2] = (buf[4] << 10) | (buf[5] << 2) | ((buf[6] >> 2) & 0x3);
129*243a738cSVladislav Kulikov 
130*243a738cSVladislav Kulikov 	return 0;
131*243a738cSVladislav Kulikov }
132*243a738cSVladislav Kulikov 
133*243a738cSVladislav Kulikov static int mmc5983_read_raw(struct iio_dev *indio_dev,
134*243a738cSVladislav Kulikov 			     const struct iio_chan_spec *chan, int *val,
135*243a738cSVladislav Kulikov 			     int *val2, long mask)
136*243a738cSVladislav Kulikov {
137*243a738cSVladislav Kulikov 	struct mmc5983_data *data = iio_priv(indio_dev);
138*243a738cSVladislav Kulikov 	int m1[3], m2[3];
139*243a738cSVladislav Kulikov 	int ret;
140*243a738cSVladislav Kulikov 
141*243a738cSVladislav Kulikov 	switch (mask) {
142*243a738cSVladislav Kulikov 	case IIO_CHAN_INFO_RAW: {
143*243a738cSVladislav Kulikov 		guard(mutex)(&data->mutex);
144*243a738cSVladislav Kulikov 
145*243a738cSVladislav Kulikov 		/* SET: magnetize sensor elements in forward direction */
146*243a738cSVladislav Kulikov 		ret = mmc5983_pulse_coil(data, MMC5983_CTRL0_SET_BIT);
147*243a738cSVladislav Kulikov 		if (ret)
148*243a738cSVladislav Kulikov 			return ret;
149*243a738cSVladislav Kulikov 
150*243a738cSVladislav Kulikov 		ret = mmc5983_take_measurement(data, m1);
151*243a738cSVladislav Kulikov 		if (ret)
152*243a738cSVladislav Kulikov 			return ret;
153*243a738cSVladislav Kulikov 
154*243a738cSVladislav Kulikov 		/* RESET: magnetize sensor elements in reverse direction */
155*243a738cSVladislav Kulikov 		ret = mmc5983_pulse_coil(data, MMC5983_CTRL0_RESET_BIT);
156*243a738cSVladislav Kulikov 		if (ret)
157*243a738cSVladislav Kulikov 			return ret;
158*243a738cSVladislav Kulikov 
159*243a738cSVladislav Kulikov 		ret = mmc5983_take_measurement(data, m2);
160*243a738cSVladislav Kulikov 		if (ret)
161*243a738cSVladislav Kulikov 			return ret;
162*243a738cSVladislav Kulikov 
163*243a738cSVladislav Kulikov 		*val = (m1[chan->address] - m2[chan->address]) / 2;
164*243a738cSVladislav Kulikov 		return IIO_VAL_INT;
165*243a738cSVladislav Kulikov 	}
166*243a738cSVladislav Kulikov 	case IIO_CHAN_INFO_SCALE:
167*243a738cSVladislav Kulikov 		*val = 0;
168*243a738cSVladislav Kulikov 		*val2 = 61035;
169*243a738cSVladislav Kulikov 		return IIO_VAL_INT_PLUS_NANO;
170*243a738cSVladislav Kulikov 	default:
171*243a738cSVladislav Kulikov 		return -EINVAL;
172*243a738cSVladislav Kulikov 	}
173*243a738cSVladislav Kulikov }
174*243a738cSVladislav Kulikov 
175*243a738cSVladislav Kulikov static const struct iio_info mmc5983_info = {
176*243a738cSVladislav Kulikov 	.read_raw = mmc5983_read_raw,
177*243a738cSVladislav Kulikov };
178*243a738cSVladislav Kulikov 
179*243a738cSVladislav Kulikov static bool mmc5983_is_writeable_reg(struct device *dev, unsigned int reg)
180*243a738cSVladislav Kulikov {
181*243a738cSVladislav Kulikov 	switch (reg) {
182*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL0:
183*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL1:
184*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL2:
185*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL3:
186*243a738cSVladislav Kulikov 		return true;
187*243a738cSVladislav Kulikov 	default:
188*243a738cSVladislav Kulikov 		return false;
189*243a738cSVladislav Kulikov 	}
190*243a738cSVladislav Kulikov }
191*243a738cSVladislav Kulikov 
192*243a738cSVladislav Kulikov static bool mmc5983_is_readable_reg(struct device *dev, unsigned int reg)
193*243a738cSVladislav Kulikov {
194*243a738cSVladislav Kulikov 	switch (reg) {
195*243a738cSVladislav Kulikov 	case MMC5983_REG_XOUT0:
196*243a738cSVladislav Kulikov 	case MMC5983_REG_XOUT1:
197*243a738cSVladislav Kulikov 	case MMC5983_REG_YOUT0:
198*243a738cSVladislav Kulikov 	case MMC5983_REG_YOUT1:
199*243a738cSVladislav Kulikov 	case MMC5983_REG_ZOUT0:
200*243a738cSVladislav Kulikov 	case MMC5983_REG_ZOUT1:
201*243a738cSVladislav Kulikov 	case MMC5983_REG_XYZOUT2:
202*243a738cSVladislav Kulikov 	case MMC5983_REG_STATUS:
203*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL0:
204*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL1:
205*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL2:
206*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL3:
207*243a738cSVladislav Kulikov 	case MMC5983_REG_ID:
208*243a738cSVladislav Kulikov 		return true;
209*243a738cSVladislav Kulikov 	default:
210*243a738cSVladislav Kulikov 		return false;
211*243a738cSVladislav Kulikov 	}
212*243a738cSVladislav Kulikov }
213*243a738cSVladislav Kulikov 
214*243a738cSVladislav Kulikov static bool mmc5983_is_volatile_reg(struct device *dev, unsigned int reg)
215*243a738cSVladislav Kulikov {
216*243a738cSVladislav Kulikov 	switch (reg) {
217*243a738cSVladislav Kulikov 	case MMC5983_REG_XOUT0:
218*243a738cSVladislav Kulikov 	case MMC5983_REG_XOUT1:
219*243a738cSVladislav Kulikov 	case MMC5983_REG_YOUT0:
220*243a738cSVladislav Kulikov 	case MMC5983_REG_YOUT1:
221*243a738cSVladislav Kulikov 	case MMC5983_REG_ZOUT0:
222*243a738cSVladislav Kulikov 	case MMC5983_REG_ZOUT1:
223*243a738cSVladislav Kulikov 	case MMC5983_REG_XYZOUT2:
224*243a738cSVladislav Kulikov 	case MMC5983_REG_STATUS:
225*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL0:
226*243a738cSVladislav Kulikov 	case MMC5983_REG_CTRL1:
227*243a738cSVladislav Kulikov 		return true;
228*243a738cSVladislav Kulikov 	default:
229*243a738cSVladislav Kulikov 		return false;
230*243a738cSVladislav Kulikov 	}
231*243a738cSVladislav Kulikov }
232*243a738cSVladislav Kulikov 
233*243a738cSVladislav Kulikov static const struct regmap_config mmc5983_regmap_config = {
234*243a738cSVladislav Kulikov 	.name = "mmc5983_regmap",
235*243a738cSVladislav Kulikov 	.reg_bits = 8,
236*243a738cSVladislav Kulikov 	.val_bits = 8,
237*243a738cSVladislav Kulikov 	.max_register = MMC5983_REG_ID,
238*243a738cSVladislav Kulikov 	.writeable_reg = mmc5983_is_writeable_reg,
239*243a738cSVladislav Kulikov 	.readable_reg = mmc5983_is_readable_reg,
240*243a738cSVladislav Kulikov 	.volatile_reg = mmc5983_is_volatile_reg,
241*243a738cSVladislav Kulikov };
242*243a738cSVladislav Kulikov 
243*243a738cSVladislav Kulikov static int mmc5983_init(struct mmc5983_data *data)
244*243a738cSVladislav Kulikov {
245*243a738cSVladislav Kulikov 	struct regmap *regmap = data->regmap;
246*243a738cSVladislav Kulikov 	struct device *dev = regmap_get_device(regmap);
247*243a738cSVladislav Kulikov 	unsigned int reg_id, status;
248*243a738cSVladislav Kulikov 	int ret;
249*243a738cSVladislav Kulikov 
250*243a738cSVladislav Kulikov 	ret = regmap_read(regmap, MMC5983_REG_ID, &reg_id);
251*243a738cSVladislav Kulikov 	if (ret)
252*243a738cSVladislav Kulikov 		return dev_err_probe(dev, ret, "Error reading product id\n");
253*243a738cSVladislav Kulikov 
254*243a738cSVladislav Kulikov 	if (reg_id != MMC5983_PRODUCT_ID)
255*243a738cSVladislav Kulikov 		dev_info(dev, "unexpected product id 0x%02x\n", reg_id);
256*243a738cSVladislav Kulikov 
257*243a738cSVladislav Kulikov 	ret = regmap_write(regmap, MMC5983_REG_CTRL1, MMC5983_CTRL1_SW_RST_BIT);
258*243a738cSVladislav Kulikov 	if (ret)
259*243a738cSVladislav Kulikov 		return ret;
260*243a738cSVladislav Kulikov 
261*243a738cSVladislav Kulikov 	/* Datasheet page 15: power-on time after SW_RST is 10 ms */
262*243a738cSVladislav Kulikov 	fsleep(10 * USEC_PER_MSEC);
263*243a738cSVladislav Kulikov 
264*243a738cSVladislav Kulikov 	ret = regmap_write(regmap, MMC5983_REG_CTRL0, MMC5983_CTRL0_OTP_RD_BIT);
265*243a738cSVladislav Kulikov 	if (ret)
266*243a738cSVladislav Kulikov 		return ret;
267*243a738cSVladislav Kulikov 
268*243a738cSVladislav Kulikov 	/*
269*243a738cSVladislav Kulikov 	 * Datasheet page 15: OTP read completes and self-clears. No separate
270*243a738cSVladislav Kulikov 	 * OTP refresh timeout is specified, so use the 10 ms power-on time as
271*243a738cSVladislav Kulikov 	 * a conservative upper bound.
272*243a738cSVladislav Kulikov 	 */
273*243a738cSVladislav Kulikov 	ret = regmap_read_poll_timeout(regmap, MMC5983_REG_STATUS, status,
274*243a738cSVladislav Kulikov 				       status & MMC5983_STATUS_OTP_RD_DONE_BIT,
275*243a738cSVladislav Kulikov 				       USEC_PER_MSEC,
276*243a738cSVladislav Kulikov 				       10 * USEC_PER_MSEC);
277*243a738cSVladislav Kulikov 	if (ret)
278*243a738cSVladislav Kulikov 		return ret;
279*243a738cSVladislav Kulikov 
280*243a738cSVladislav Kulikov 	/* SET: magnetize sensor elements in forward direction */
281*243a738cSVladislav Kulikov 	ret = mmc5983_pulse_coil(data, MMC5983_CTRL0_SET_BIT);
282*243a738cSVladislav Kulikov 	if (ret)
283*243a738cSVladislav Kulikov 		return ret;
284*243a738cSVladislav Kulikov 
285*243a738cSVladislav Kulikov 	/* RESET: magnetize sensor elements in reverse direction */
286*243a738cSVladislav Kulikov 	return mmc5983_pulse_coil(data, MMC5983_CTRL0_RESET_BIT);
287*243a738cSVladislav Kulikov }
288*243a738cSVladislav Kulikov 
289*243a738cSVladislav Kulikov static int mmc5983_probe(struct i2c_client *i2c)
290*243a738cSVladislav Kulikov {
291*243a738cSVladislav Kulikov 	struct device *dev = &i2c->dev;
292*243a738cSVladislav Kulikov 	struct mmc5983_data *data;
293*243a738cSVladislav Kulikov 	struct iio_dev *indio_dev;
294*243a738cSVladislav Kulikov 	int ret;
295*243a738cSVladislav Kulikov 
296*243a738cSVladislav Kulikov 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
297*243a738cSVladislav Kulikov 	if (!indio_dev)
298*243a738cSVladislav Kulikov 		return -ENOMEM;
299*243a738cSVladislav Kulikov 
300*243a738cSVladislav Kulikov 	data = iio_priv(indio_dev);
301*243a738cSVladislav Kulikov 
302*243a738cSVladislav Kulikov 	ret = devm_mutex_init(dev, &data->mutex);
303*243a738cSVladislav Kulikov 	if (ret)
304*243a738cSVladislav Kulikov 		return ret;
305*243a738cSVladislav Kulikov 
306*243a738cSVladislav Kulikov 	data->regmap = devm_regmap_init_i2c(i2c, &mmc5983_regmap_config);
307*243a738cSVladislav Kulikov 	if (IS_ERR(data->regmap))
308*243a738cSVladislav Kulikov 		return dev_err_probe(dev, PTR_ERR(data->regmap),
309*243a738cSVladislav Kulikov 				     "failed to allocate register map\n");
310*243a738cSVladislav Kulikov 
311*243a738cSVladislav Kulikov 	indio_dev->info = &mmc5983_info;
312*243a738cSVladislav Kulikov 	indio_dev->modes = INDIO_DIRECT_MODE;
313*243a738cSVladislav Kulikov 	indio_dev->name = "mmc5983";
314*243a738cSVladislav Kulikov 	indio_dev->channels = mmc5983_channels;
315*243a738cSVladislav Kulikov 	indio_dev->num_channels = ARRAY_SIZE(mmc5983_channels);
316*243a738cSVladislav Kulikov 
317*243a738cSVladislav Kulikov 	ret = mmc5983_init(data);
318*243a738cSVladislav Kulikov 	if (ret)
319*243a738cSVladislav Kulikov 		return dev_err_probe(dev, ret, "mmc5983 chip init failed\n");
320*243a738cSVladislav Kulikov 
321*243a738cSVladislav Kulikov 	return devm_iio_device_register(dev, indio_dev);
322*243a738cSVladislav Kulikov }
323*243a738cSVladislav Kulikov 
324*243a738cSVladislav Kulikov static const struct of_device_id mmc5983_of_match[] = {
325*243a738cSVladislav Kulikov 	{ .compatible = "memsic,mmc5983" },
326*243a738cSVladislav Kulikov 	{ }
327*243a738cSVladislav Kulikov };
328*243a738cSVladislav Kulikov MODULE_DEVICE_TABLE(of, mmc5983_of_match);
329*243a738cSVladislav Kulikov 
330*243a738cSVladislav Kulikov static const struct i2c_device_id mmc5983_id[] = {
331*243a738cSVladislav Kulikov 	{ "mmc5983" },
332*243a738cSVladislav Kulikov 	{ }
333*243a738cSVladislav Kulikov };
334*243a738cSVladislav Kulikov MODULE_DEVICE_TABLE(i2c, mmc5983_id);
335*243a738cSVladislav Kulikov 
336*243a738cSVladislav Kulikov static struct i2c_driver mmc5983_driver = {
337*243a738cSVladislav Kulikov 	.driver = {
338*243a738cSVladislav Kulikov 		.name = "mmc5983",
339*243a738cSVladislav Kulikov 		.of_match_table = mmc5983_of_match,
340*243a738cSVladislav Kulikov 	},
341*243a738cSVladislav Kulikov 	.probe = mmc5983_probe,
342*243a738cSVladislav Kulikov 	.id_table = mmc5983_id,
343*243a738cSVladislav Kulikov };
344*243a738cSVladislav Kulikov module_i2c_driver(mmc5983_driver);
345*243a738cSVladislav Kulikov 
346*243a738cSVladislav Kulikov MODULE_AUTHOR("Vladislav Kulikov <vlad.kulikov.c@gmail.com>");
347*243a738cSVladislav Kulikov MODULE_DESCRIPTION("MEMSIC MMC5983 magnetic sensor driver");
348*243a738cSVladislav Kulikov MODULE_LICENSE("GPL");
349