xref: /openbmc/linux/drivers/iio/imu/kmx61.c (revision 20ffac278ebd64ad031149628560f47990910dd7)
1*20ffac27SDaniel Baluta /*
2*20ffac27SDaniel Baluta  * KMX61 - Kionix 6-axis Accelerometer/Magnetometer
3*20ffac27SDaniel Baluta  *
4*20ffac27SDaniel Baluta  * Copyright (c) 2014, Intel Corporation.
5*20ffac27SDaniel Baluta  *
6*20ffac27SDaniel Baluta  * This file is subject to the terms and conditions of version 2 of
7*20ffac27SDaniel Baluta  * the GNU General Public License.  See the file COPYING in the main
8*20ffac27SDaniel Baluta  * directory of this archive for more details.
9*20ffac27SDaniel Baluta  *
10*20ffac27SDaniel Baluta  * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F).
11*20ffac27SDaniel Baluta  *
12*20ffac27SDaniel Baluta  */
13*20ffac27SDaniel Baluta 
14*20ffac27SDaniel Baluta #include <linux/module.h>
15*20ffac27SDaniel Baluta #include <linux/i2c.h>
16*20ffac27SDaniel Baluta #include <linux/iio/iio.h>
17*20ffac27SDaniel Baluta #include <linux/iio/sysfs.h>
18*20ffac27SDaniel Baluta 
19*20ffac27SDaniel Baluta #define KMX61_DRV_NAME "kmx61"
20*20ffac27SDaniel Baluta 
21*20ffac27SDaniel Baluta #define KMX61_REG_WHO_AM_I	0x00
22*20ffac27SDaniel Baluta 
23*20ffac27SDaniel Baluta /*
24*20ffac27SDaniel Baluta  * three 16-bit accelerometer output registers for X/Y/Z axis
25*20ffac27SDaniel Baluta  * we use only XOUT_L as a base register, all other addresses
26*20ffac27SDaniel Baluta  * can be obtained by applying an offset and are provided here
27*20ffac27SDaniel Baluta  * only for clarity.
28*20ffac27SDaniel Baluta  */
29*20ffac27SDaniel Baluta #define KMX61_ACC_XOUT_L	0x0A
30*20ffac27SDaniel Baluta #define KMX61_ACC_XOUT_H	0x0B
31*20ffac27SDaniel Baluta #define KMX61_ACC_YOUT_L	0x0C
32*20ffac27SDaniel Baluta #define KMX61_ACC_YOUT_H	0x0D
33*20ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_L	0x0E
34*20ffac27SDaniel Baluta #define KMX61_ACC_ZOUT_H	0x0F
35*20ffac27SDaniel Baluta 
36*20ffac27SDaniel Baluta /*
37*20ffac27SDaniel Baluta  * one 16-bit temperature output register
38*20ffac27SDaniel Baluta  */
39*20ffac27SDaniel Baluta #define KMX61_TEMP_L		0x10
40*20ffac27SDaniel Baluta #define KMX61_TEMP_H		0x11
41*20ffac27SDaniel Baluta 
42*20ffac27SDaniel Baluta /*
43*20ffac27SDaniel Baluta  * three 16-bit magnetometer output registers for X/Y/Z axis
44*20ffac27SDaniel Baluta  */
45*20ffac27SDaniel Baluta #define KMX61_MAG_XOUT_L	0x12
46*20ffac27SDaniel Baluta #define KMX61_MAG_XOUT_H	0x13
47*20ffac27SDaniel Baluta #define KMX61_MAG_YOUT_L	0x14
48*20ffac27SDaniel Baluta #define KMX61_MAG_YOUT_H	0x15
49*20ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_L	0x16
50*20ffac27SDaniel Baluta #define KMX61_MAG_ZOUT_H	0x17
51*20ffac27SDaniel Baluta 
52*20ffac27SDaniel Baluta #define KMX61_REG_STBY		0x29
53*20ffac27SDaniel Baluta #define KMX61_REG_CTRL1		0x2A
54*20ffac27SDaniel Baluta #define KMX61_REG_ODCNTL	0x2C
55*20ffac27SDaniel Baluta 
56*20ffac27SDaniel Baluta #define KMX61_ACC_STBY_BIT	BIT(0)
57*20ffac27SDaniel Baluta #define KMX61_MAG_STBY_BIT	BIT(1)
58*20ffac27SDaniel Baluta #define KMX61_ACT_STBY_BIT	BIT(7)
59*20ffac27SDaniel Baluta 
60*20ffac27SDaniel Baluta #define KMX61_ALL_STBY		(KMX61_ACC_STBY_BIT | KMX61_MAG_STBY_BIT)
61*20ffac27SDaniel Baluta 
62*20ffac27SDaniel Baluta #define KMX61_REG_CTRL1_GSEL_MASK	0x03
63*20ffac27SDaniel Baluta 
64*20ffac27SDaniel Baluta #define KMX61_ACC_ODR_SHIFT	0
65*20ffac27SDaniel Baluta #define KMX61_MAG_ODR_SHIFT	4
66*20ffac27SDaniel Baluta #define KMX61_ACC_ODR_MASK	0x0F
67*20ffac27SDaniel Baluta #define KMX61_MAG_ODR_MASK	0xF0
68*20ffac27SDaniel Baluta 
69*20ffac27SDaniel Baluta #define KMX61_CHIP_ID		0x12
70*20ffac27SDaniel Baluta 
71*20ffac27SDaniel Baluta /* KMX61 devices */
72*20ffac27SDaniel Baluta #define KMX61_ACC	0x01
73*20ffac27SDaniel Baluta #define KMX61_MAG	0x02
74*20ffac27SDaniel Baluta 
75*20ffac27SDaniel Baluta struct kmx61_data {
76*20ffac27SDaniel Baluta 	struct i2c_client *client;
77*20ffac27SDaniel Baluta 
78*20ffac27SDaniel Baluta 	/* serialize access to non-atomic ops, e.g set_mode */
79*20ffac27SDaniel Baluta 	struct mutex lock;
80*20ffac27SDaniel Baluta 
81*20ffac27SDaniel Baluta 	/* standby state */
82*20ffac27SDaniel Baluta 	bool acc_stby;
83*20ffac27SDaniel Baluta 	bool mag_stby;
84*20ffac27SDaniel Baluta 
85*20ffac27SDaniel Baluta 	/* config bits */
86*20ffac27SDaniel Baluta 	u8 range;
87*20ffac27SDaniel Baluta 	u8 odr_bits;
88*20ffac27SDaniel Baluta 
89*20ffac27SDaniel Baluta 	/* accelerometer specific data */
90*20ffac27SDaniel Baluta 	struct iio_dev *acc_indio_dev;
91*20ffac27SDaniel Baluta 
92*20ffac27SDaniel Baluta 	/* magnetometer specific data */
93*20ffac27SDaniel Baluta 	struct iio_dev *mag_indio_dev;
94*20ffac27SDaniel Baluta };
95*20ffac27SDaniel Baluta 
96*20ffac27SDaniel Baluta enum kmx61_range {
97*20ffac27SDaniel Baluta 	KMX61_RANGE_2G,
98*20ffac27SDaniel Baluta 	KMX61_RANGE_4G,
99*20ffac27SDaniel Baluta 	KMX61_RANGE_8G,
100*20ffac27SDaniel Baluta };
101*20ffac27SDaniel Baluta 
102*20ffac27SDaniel Baluta enum kmx61_axis {
103*20ffac27SDaniel Baluta 	KMX61_AXIS_X,
104*20ffac27SDaniel Baluta 	KMX61_AXIS_Y,
105*20ffac27SDaniel Baluta 	KMX61_AXIS_Z,
106*20ffac27SDaniel Baluta };
107*20ffac27SDaniel Baluta 
108*20ffac27SDaniel Baluta static const u16 kmx61_uscale_table[] = {9582, 19163, 38326};
109*20ffac27SDaniel Baluta 
110*20ffac27SDaniel Baluta static const struct {
111*20ffac27SDaniel Baluta 	int val;
112*20ffac27SDaniel Baluta 	int val2;
113*20ffac27SDaniel Baluta 	u8 odr_bits;
114*20ffac27SDaniel Baluta } kmx61_samp_freq_table[] = { {12, 500000, 0x00},
115*20ffac27SDaniel Baluta 			{25, 0, 0x01},
116*20ffac27SDaniel Baluta 			{50, 0, 0x02},
117*20ffac27SDaniel Baluta 			{100, 0, 0x03},
118*20ffac27SDaniel Baluta 			{200, 0, 0x04},
119*20ffac27SDaniel Baluta 			{400, 0, 0x05},
120*20ffac27SDaniel Baluta 			{800, 0, 0x06},
121*20ffac27SDaniel Baluta 			{1600, 0, 0x07},
122*20ffac27SDaniel Baluta 			{0, 781000, 0x08},
123*20ffac27SDaniel Baluta 			{1, 563000, 0x09},
124*20ffac27SDaniel Baluta 			{3, 125000, 0x0A},
125*20ffac27SDaniel Baluta 			{6, 250000, 0x0B} };
126*20ffac27SDaniel Baluta 
127*20ffac27SDaniel Baluta static IIO_CONST_ATTR(accel_scale_available, "0.009582 0.019163 0.038326");
128*20ffac27SDaniel Baluta static IIO_CONST_ATTR(magn_scale_available, "0.001465");
129*20ffac27SDaniel Baluta static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
130*20ffac27SDaniel Baluta 	"0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800");
131*20ffac27SDaniel Baluta 
132*20ffac27SDaniel Baluta static struct attribute *kmx61_acc_attributes[] = {
133*20ffac27SDaniel Baluta 	&iio_const_attr_accel_scale_available.dev_attr.attr,
134*20ffac27SDaniel Baluta 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
135*20ffac27SDaniel Baluta 	NULL,
136*20ffac27SDaniel Baluta };
137*20ffac27SDaniel Baluta 
138*20ffac27SDaniel Baluta static struct attribute *kmx61_mag_attributes[] = {
139*20ffac27SDaniel Baluta 	&iio_const_attr_magn_scale_available.dev_attr.attr,
140*20ffac27SDaniel Baluta 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
141*20ffac27SDaniel Baluta 	NULL,
142*20ffac27SDaniel Baluta };
143*20ffac27SDaniel Baluta 
144*20ffac27SDaniel Baluta static const struct attribute_group kmx61_acc_attribute_group = {
145*20ffac27SDaniel Baluta 	.attrs = kmx61_acc_attributes,
146*20ffac27SDaniel Baluta };
147*20ffac27SDaniel Baluta 
148*20ffac27SDaniel Baluta static const struct attribute_group kmx61_mag_attribute_group = {
149*20ffac27SDaniel Baluta 	.attrs = kmx61_mag_attributes,
150*20ffac27SDaniel Baluta };
151*20ffac27SDaniel Baluta 
152*20ffac27SDaniel Baluta #define KMX61_ACC_CHAN(_axis) { \
153*20ffac27SDaniel Baluta 	.type = IIO_ACCEL, \
154*20ffac27SDaniel Baluta 	.modified = 1, \
155*20ffac27SDaniel Baluta 	.channel2 = IIO_MOD_ ## _axis, \
156*20ffac27SDaniel Baluta 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
157*20ffac27SDaniel Baluta 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
158*20ffac27SDaniel Baluta 				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
159*20ffac27SDaniel Baluta 	.address = KMX61_ACC, \
160*20ffac27SDaniel Baluta 	.scan_index = KMX61_AXIS_ ## _axis, \
161*20ffac27SDaniel Baluta 	.scan_type = { \
162*20ffac27SDaniel Baluta 		.sign = 's', \
163*20ffac27SDaniel Baluta 		.realbits = 12, \
164*20ffac27SDaniel Baluta 		.storagebits = 16, \
165*20ffac27SDaniel Baluta 		.shift = 4, \
166*20ffac27SDaniel Baluta 		.endianness = IIO_LE, \
167*20ffac27SDaniel Baluta 	}, \
168*20ffac27SDaniel Baluta }
169*20ffac27SDaniel Baluta 
170*20ffac27SDaniel Baluta #define KMX61_MAG_CHAN(_axis) { \
171*20ffac27SDaniel Baluta 	.type = IIO_MAGN, \
172*20ffac27SDaniel Baluta 	.modified = 1, \
173*20ffac27SDaniel Baluta 	.channel2 = IIO_MOD_ ## _axis, \
174*20ffac27SDaniel Baluta 	.address = KMX61_MAG, \
175*20ffac27SDaniel Baluta 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
176*20ffac27SDaniel Baluta 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
177*20ffac27SDaniel Baluta 				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
178*20ffac27SDaniel Baluta 	.scan_index = KMX61_AXIS_ ## _axis, \
179*20ffac27SDaniel Baluta 	.scan_type = { \
180*20ffac27SDaniel Baluta 		.sign = 's', \
181*20ffac27SDaniel Baluta 		.realbits = 14, \
182*20ffac27SDaniel Baluta 		.storagebits = 16, \
183*20ffac27SDaniel Baluta 		.shift = 2, \
184*20ffac27SDaniel Baluta 		.endianness = IIO_LE, \
185*20ffac27SDaniel Baluta 	}, \
186*20ffac27SDaniel Baluta }
187*20ffac27SDaniel Baluta 
188*20ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_acc_channels[] = {
189*20ffac27SDaniel Baluta 	KMX61_ACC_CHAN(X),
190*20ffac27SDaniel Baluta 	KMX61_ACC_CHAN(Y),
191*20ffac27SDaniel Baluta 	KMX61_ACC_CHAN(Z),
192*20ffac27SDaniel Baluta };
193*20ffac27SDaniel Baluta 
194*20ffac27SDaniel Baluta static const struct iio_chan_spec kmx61_mag_channels[] = {
195*20ffac27SDaniel Baluta 	KMX61_MAG_CHAN(X),
196*20ffac27SDaniel Baluta 	KMX61_MAG_CHAN(Y),
197*20ffac27SDaniel Baluta 	KMX61_MAG_CHAN(Z),
198*20ffac27SDaniel Baluta };
199*20ffac27SDaniel Baluta 
200*20ffac27SDaniel Baluta static void kmx61_set_data(struct iio_dev *indio_dev, struct kmx61_data *data)
201*20ffac27SDaniel Baluta {
202*20ffac27SDaniel Baluta 	struct kmx61_data **priv = iio_priv(indio_dev);
203*20ffac27SDaniel Baluta 
204*20ffac27SDaniel Baluta 	*priv = data;
205*20ffac27SDaniel Baluta }
206*20ffac27SDaniel Baluta 
207*20ffac27SDaniel Baluta static struct kmx61_data *kmx61_get_data(struct iio_dev *indio_dev)
208*20ffac27SDaniel Baluta {
209*20ffac27SDaniel Baluta 	return *(struct kmx61_data **)iio_priv(indio_dev);
210*20ffac27SDaniel Baluta }
211*20ffac27SDaniel Baluta 
212*20ffac27SDaniel Baluta static int kmx61_convert_freq_to_bit(int val, int val2)
213*20ffac27SDaniel Baluta {
214*20ffac27SDaniel Baluta 	int i;
215*20ffac27SDaniel Baluta 
216*20ffac27SDaniel Baluta 	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
217*20ffac27SDaniel Baluta 		if (val == kmx61_samp_freq_table[i].val &&
218*20ffac27SDaniel Baluta 		    val2 == kmx61_samp_freq_table[i].val2)
219*20ffac27SDaniel Baluta 			return kmx61_samp_freq_table[i].odr_bits;
220*20ffac27SDaniel Baluta 	return -EINVAL;
221*20ffac27SDaniel Baluta }
222*20ffac27SDaniel Baluta 
223*20ffac27SDaniel Baluta /**
224*20ffac27SDaniel Baluta  * kmx61_set_mode() - set KMX61 device operating mode
225*20ffac27SDaniel Baluta  * @data - kmx61 device private data pointer
226*20ffac27SDaniel Baluta  * @mode - bitmask, indicating operating mode for @device
227*20ffac27SDaniel Baluta  * @device - bitmask, indicating device for which @mode needs to be set
228*20ffac27SDaniel Baluta  * @update - update stby bits stored in device's private  @data
229*20ffac27SDaniel Baluta  *
230*20ffac27SDaniel Baluta  * For each sensor (accelerometer/magnetometer) there are two operating modes
231*20ffac27SDaniel Baluta  * STANDBY and OPERATION. Neither accel nor magn can be disabled independently
232*20ffac27SDaniel Baluta  * if they are both enabled. Internal sensors state is saved in acc_stby and
233*20ffac27SDaniel Baluta  * mag_stby members of driver's private @data.
234*20ffac27SDaniel Baluta  */
235*20ffac27SDaniel Baluta static int kmx61_set_mode(struct kmx61_data *data, u8 mode, u8 device,
236*20ffac27SDaniel Baluta 			  bool update)
237*20ffac27SDaniel Baluta {
238*20ffac27SDaniel Baluta 	int ret;
239*20ffac27SDaniel Baluta 	int acc_stby = -1, mag_stby = -1;
240*20ffac27SDaniel Baluta 
241*20ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
242*20ffac27SDaniel Baluta 	if (ret < 0) {
243*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_stby\n");
244*20ffac27SDaniel Baluta 		return ret;
245*20ffac27SDaniel Baluta 	}
246*20ffac27SDaniel Baluta 	if (device & KMX61_ACC) {
247*20ffac27SDaniel Baluta 		if (mode & KMX61_ACC_STBY_BIT) {
248*20ffac27SDaniel Baluta 			ret |= KMX61_ACC_STBY_BIT;
249*20ffac27SDaniel Baluta 			acc_stby = 1;
250*20ffac27SDaniel Baluta 		} else {
251*20ffac27SDaniel Baluta 			ret &= ~KMX61_ACC_STBY_BIT;
252*20ffac27SDaniel Baluta 			acc_stby = 0;
253*20ffac27SDaniel Baluta 		}
254*20ffac27SDaniel Baluta 	}
255*20ffac27SDaniel Baluta 
256*20ffac27SDaniel Baluta 	if (device & KMX61_MAG) {
257*20ffac27SDaniel Baluta 		if (mode & KMX61_MAG_STBY_BIT) {
258*20ffac27SDaniel Baluta 			ret |= KMX61_MAG_STBY_BIT;
259*20ffac27SDaniel Baluta 			mag_stby = 1;
260*20ffac27SDaniel Baluta 		} else {
261*20ffac27SDaniel Baluta 			ret &= ~KMX61_MAG_STBY_BIT;
262*20ffac27SDaniel Baluta 			mag_stby = 0;
263*20ffac27SDaniel Baluta 		}
264*20ffac27SDaniel Baluta 	}
265*20ffac27SDaniel Baluta 
266*20ffac27SDaniel Baluta 	if (mode & KMX61_ACT_STBY_BIT)
267*20ffac27SDaniel Baluta 		ret |= KMX61_ACT_STBY_BIT;
268*20ffac27SDaniel Baluta 
269*20ffac27SDaniel Baluta 	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_STBY, ret);
270*20ffac27SDaniel Baluta 	if (ret < 0) {
271*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error writing reg_stby\n");
272*20ffac27SDaniel Baluta 		return ret;
273*20ffac27SDaniel Baluta 	}
274*20ffac27SDaniel Baluta 
275*20ffac27SDaniel Baluta 	if (acc_stby != -1 && update)
276*20ffac27SDaniel Baluta 		data->acc_stby = acc_stby;
277*20ffac27SDaniel Baluta 	if (mag_stby != -1 && update)
278*20ffac27SDaniel Baluta 		data->mag_stby = mag_stby;
279*20ffac27SDaniel Baluta 
280*20ffac27SDaniel Baluta 	return 0;
281*20ffac27SDaniel Baluta }
282*20ffac27SDaniel Baluta 
283*20ffac27SDaniel Baluta static int kmx61_get_mode(struct kmx61_data *data, u8 *mode, u8 device)
284*20ffac27SDaniel Baluta {
285*20ffac27SDaniel Baluta 	int ret;
286*20ffac27SDaniel Baluta 
287*20ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
288*20ffac27SDaniel Baluta 	if (ret < 0) {
289*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_stby\n");
290*20ffac27SDaniel Baluta 		return ret;
291*20ffac27SDaniel Baluta 	}
292*20ffac27SDaniel Baluta 	*mode = 0;
293*20ffac27SDaniel Baluta 
294*20ffac27SDaniel Baluta 	if (device & KMX61_ACC) {
295*20ffac27SDaniel Baluta 		if (ret & KMX61_ACC_STBY_BIT)
296*20ffac27SDaniel Baluta 			*mode |= KMX61_ACC_STBY_BIT;
297*20ffac27SDaniel Baluta 		else
298*20ffac27SDaniel Baluta 			*mode &= ~KMX61_ACC_STBY_BIT;
299*20ffac27SDaniel Baluta 	}
300*20ffac27SDaniel Baluta 
301*20ffac27SDaniel Baluta 	if (device & KMX61_MAG) {
302*20ffac27SDaniel Baluta 		if (ret & KMX61_MAG_STBY_BIT)
303*20ffac27SDaniel Baluta 			*mode |= KMX61_MAG_STBY_BIT;
304*20ffac27SDaniel Baluta 		else
305*20ffac27SDaniel Baluta 			*mode &= ~KMX61_MAG_STBY_BIT;
306*20ffac27SDaniel Baluta 	}
307*20ffac27SDaniel Baluta 
308*20ffac27SDaniel Baluta 	return 0;
309*20ffac27SDaniel Baluta }
310*20ffac27SDaniel Baluta 
311*20ffac27SDaniel Baluta static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device)
312*20ffac27SDaniel Baluta {
313*20ffac27SDaniel Baluta 	int ret;
314*20ffac27SDaniel Baluta 	u8 mode;
315*20ffac27SDaniel Baluta 	int lodr_bits, odr_bits;
316*20ffac27SDaniel Baluta 
317*20ffac27SDaniel Baluta 	ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
318*20ffac27SDaniel Baluta 	if (ret < 0)
319*20ffac27SDaniel Baluta 		return ret;
320*20ffac27SDaniel Baluta 
321*20ffac27SDaniel Baluta 	lodr_bits = kmx61_convert_freq_to_bit(val, val2);
322*20ffac27SDaniel Baluta 	if (lodr_bits < 0)
323*20ffac27SDaniel Baluta 		return lodr_bits;
324*20ffac27SDaniel Baluta 
325*20ffac27SDaniel Baluta 	/* To change ODR, accel and magn must be in STDBY */
326*20ffac27SDaniel Baluta 	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
327*20ffac27SDaniel Baluta 			     true);
328*20ffac27SDaniel Baluta 	if (ret < 0)
329*20ffac27SDaniel Baluta 		return ret;
330*20ffac27SDaniel Baluta 
331*20ffac27SDaniel Baluta 	odr_bits = 0;
332*20ffac27SDaniel Baluta 	if (device & KMX61_ACC)
333*20ffac27SDaniel Baluta 		odr_bits |= lodr_bits << KMX61_ACC_ODR_SHIFT;
334*20ffac27SDaniel Baluta 	if (device & KMX61_MAG)
335*20ffac27SDaniel Baluta 		odr_bits |= lodr_bits << KMX61_MAG_ODR_SHIFT;
336*20ffac27SDaniel Baluta 
337*20ffac27SDaniel Baluta 	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_ODCNTL,
338*20ffac27SDaniel Baluta 					odr_bits);
339*20ffac27SDaniel Baluta 	if (ret < 0)
340*20ffac27SDaniel Baluta 		return ret;
341*20ffac27SDaniel Baluta 
342*20ffac27SDaniel Baluta 	return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
343*20ffac27SDaniel Baluta }
344*20ffac27SDaniel Baluta 
345*20ffac27SDaniel Baluta static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2,
346*20ffac27SDaniel Baluta 			 u8 device)
347*20ffac27SDaniel Baluta {	int i;
348*20ffac27SDaniel Baluta 	u8 lodr_bits;
349*20ffac27SDaniel Baluta 
350*20ffac27SDaniel Baluta 	if (device & KMX61_ACC)
351*20ffac27SDaniel Baluta 		lodr_bits = (data->odr_bits >> KMX61_ACC_ODR_SHIFT) &
352*20ffac27SDaniel Baluta 			     KMX61_ACC_ODR_MASK;
353*20ffac27SDaniel Baluta 	else if (device & KMX61_MAG)
354*20ffac27SDaniel Baluta 		lodr_bits = (data->odr_bits >> KMX61_MAG_ODR_SHIFT) &
355*20ffac27SDaniel Baluta 			     KMX61_MAG_ODR_MASK;
356*20ffac27SDaniel Baluta 	else
357*20ffac27SDaniel Baluta 		return -EINVAL;
358*20ffac27SDaniel Baluta 
359*20ffac27SDaniel Baluta 	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
360*20ffac27SDaniel Baluta 		if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) {
361*20ffac27SDaniel Baluta 			*val = kmx61_samp_freq_table[i].val;
362*20ffac27SDaniel Baluta 			*val2 = kmx61_samp_freq_table[i].val2;
363*20ffac27SDaniel Baluta 			return 0;
364*20ffac27SDaniel Baluta 		}
365*20ffac27SDaniel Baluta 	return -EINVAL;
366*20ffac27SDaniel Baluta }
367*20ffac27SDaniel Baluta 
368*20ffac27SDaniel Baluta static int kmx61_set_range(struct kmx61_data *data, u8 range)
369*20ffac27SDaniel Baluta {
370*20ffac27SDaniel Baluta 	int ret;
371*20ffac27SDaniel Baluta 
372*20ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
373*20ffac27SDaniel Baluta 	if (ret < 0) {
374*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
375*20ffac27SDaniel Baluta 		return ret;
376*20ffac27SDaniel Baluta 	}
377*20ffac27SDaniel Baluta 
378*20ffac27SDaniel Baluta 	ret &= ~KMX61_REG_CTRL1_GSEL_MASK;
379*20ffac27SDaniel Baluta 	ret |= range & KMX61_REG_CTRL1_GSEL_MASK;
380*20ffac27SDaniel Baluta 
381*20ffac27SDaniel Baluta 	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
382*20ffac27SDaniel Baluta 	if (ret < 0) {
383*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
384*20ffac27SDaniel Baluta 		return ret;
385*20ffac27SDaniel Baluta 	}
386*20ffac27SDaniel Baluta 
387*20ffac27SDaniel Baluta 	data->range = range;
388*20ffac27SDaniel Baluta 
389*20ffac27SDaniel Baluta 	return 0;
390*20ffac27SDaniel Baluta }
391*20ffac27SDaniel Baluta 
392*20ffac27SDaniel Baluta static int kmx61_set_scale(struct kmx61_data *data, u16 uscale)
393*20ffac27SDaniel Baluta {
394*20ffac27SDaniel Baluta 	int ret, i;
395*20ffac27SDaniel Baluta 	u8  mode;
396*20ffac27SDaniel Baluta 
397*20ffac27SDaniel Baluta 	for (i = 0; i < ARRAY_SIZE(kmx61_uscale_table); i++) {
398*20ffac27SDaniel Baluta 		if (kmx61_uscale_table[i] == uscale) {
399*20ffac27SDaniel Baluta 			ret = kmx61_get_mode(data, &mode,
400*20ffac27SDaniel Baluta 					     KMX61_ACC | KMX61_MAG);
401*20ffac27SDaniel Baluta 			if (ret < 0)
402*20ffac27SDaniel Baluta 				return ret;
403*20ffac27SDaniel Baluta 
404*20ffac27SDaniel Baluta 			ret = kmx61_set_mode(data, KMX61_ALL_STBY,
405*20ffac27SDaniel Baluta 					     KMX61_ACC | KMX61_MAG, true);
406*20ffac27SDaniel Baluta 			if (ret < 0)
407*20ffac27SDaniel Baluta 				return ret;
408*20ffac27SDaniel Baluta 
409*20ffac27SDaniel Baluta 			ret = kmx61_set_range(data, i);
410*20ffac27SDaniel Baluta 			if (ret < 0)
411*20ffac27SDaniel Baluta 				return ret;
412*20ffac27SDaniel Baluta 
413*20ffac27SDaniel Baluta 			return  kmx61_set_mode(data, mode,
414*20ffac27SDaniel Baluta 					       KMX61_ACC | KMX61_MAG, true);
415*20ffac27SDaniel Baluta 		}
416*20ffac27SDaniel Baluta 	}
417*20ffac27SDaniel Baluta 	return -EINVAL;
418*20ffac27SDaniel Baluta }
419*20ffac27SDaniel Baluta 
420*20ffac27SDaniel Baluta static int kmx61_chip_init(struct kmx61_data *data)
421*20ffac27SDaniel Baluta {
422*20ffac27SDaniel Baluta 	int ret;
423*20ffac27SDaniel Baluta 
424*20ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_WHO_AM_I);
425*20ffac27SDaniel Baluta 	if (ret < 0) {
426*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading who_am_i\n");
427*20ffac27SDaniel Baluta 		return ret;
428*20ffac27SDaniel Baluta 	}
429*20ffac27SDaniel Baluta 
430*20ffac27SDaniel Baluta 	if (ret != KMX61_CHIP_ID) {
431*20ffac27SDaniel Baluta 		dev_err(&data->client->dev,
432*20ffac27SDaniel Baluta 			"Wrong chip id, got %x expected %x\n",
433*20ffac27SDaniel Baluta 			 ret, KMX61_CHIP_ID);
434*20ffac27SDaniel Baluta 		return -EINVAL;
435*20ffac27SDaniel Baluta 	}
436*20ffac27SDaniel Baluta 
437*20ffac27SDaniel Baluta 	/* set accel 12bit, 4g range */
438*20ffac27SDaniel Baluta 	ret = kmx61_set_range(data, KMX61_RANGE_4G);
439*20ffac27SDaniel Baluta 	if (ret < 0)
440*20ffac27SDaniel Baluta 		return ret;
441*20ffac27SDaniel Baluta 
442*20ffac27SDaniel Baluta 	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_ODCNTL);
443*20ffac27SDaniel Baluta 	if (ret < 0) {
444*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "Error reading reg_odcntl\n");
445*20ffac27SDaniel Baluta 		return ret;
446*20ffac27SDaniel Baluta 	}
447*20ffac27SDaniel Baluta 	data->odr_bits = ret;
448*20ffac27SDaniel Baluta 
449*20ffac27SDaniel Baluta 	/* set acc/magn to OPERATION mode */
450*20ffac27SDaniel Baluta 	ret = kmx61_set_mode(data, 0, KMX61_ACC | KMX61_MAG, true);
451*20ffac27SDaniel Baluta 	if (ret < 0)
452*20ffac27SDaniel Baluta 		return ret;
453*20ffac27SDaniel Baluta 
454*20ffac27SDaniel Baluta 	return 0;
455*20ffac27SDaniel Baluta }
456*20ffac27SDaniel Baluta 
457*20ffac27SDaniel Baluta static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset)
458*20ffac27SDaniel Baluta {
459*20ffac27SDaniel Baluta 	int ret;
460*20ffac27SDaniel Baluta 	u8 reg = base + offset * 2;
461*20ffac27SDaniel Baluta 
462*20ffac27SDaniel Baluta 	ret = i2c_smbus_read_word_data(data->client, reg);
463*20ffac27SDaniel Baluta 	if (ret < 0)
464*20ffac27SDaniel Baluta 		dev_err(&data->client->dev, "failed to read reg at %x\n", reg);
465*20ffac27SDaniel Baluta 
466*20ffac27SDaniel Baluta 	return ret;
467*20ffac27SDaniel Baluta }
468*20ffac27SDaniel Baluta 
469*20ffac27SDaniel Baluta static int kmx61_read_raw(struct iio_dev *indio_dev,
470*20ffac27SDaniel Baluta 			  struct iio_chan_spec const *chan, int *val,
471*20ffac27SDaniel Baluta 			  int *val2, long mask)
472*20ffac27SDaniel Baluta {
473*20ffac27SDaniel Baluta 	int ret;
474*20ffac27SDaniel Baluta 	u8 base_reg;
475*20ffac27SDaniel Baluta 	struct kmx61_data *data = kmx61_get_data(indio_dev);
476*20ffac27SDaniel Baluta 
477*20ffac27SDaniel Baluta 	switch (mask) {
478*20ffac27SDaniel Baluta 	case IIO_CHAN_INFO_RAW:
479*20ffac27SDaniel Baluta 		switch (chan->type) {
480*20ffac27SDaniel Baluta 		case IIO_ACCEL:
481*20ffac27SDaniel Baluta 			base_reg = KMX61_ACC_XOUT_L;
482*20ffac27SDaniel Baluta 			break;
483*20ffac27SDaniel Baluta 		case IIO_MAGN:
484*20ffac27SDaniel Baluta 			base_reg = KMX61_MAG_XOUT_L;
485*20ffac27SDaniel Baluta 			break;
486*20ffac27SDaniel Baluta 		default:
487*20ffac27SDaniel Baluta 			return -EINVAL;
488*20ffac27SDaniel Baluta 		}
489*20ffac27SDaniel Baluta 		mutex_lock(&data->lock);
490*20ffac27SDaniel Baluta 
491*20ffac27SDaniel Baluta 		ret = kmx61_read_measurement(data, base_reg, chan->scan_index);
492*20ffac27SDaniel Baluta 		if (ret < 0) {
493*20ffac27SDaniel Baluta 			mutex_unlock(&data->lock);
494*20ffac27SDaniel Baluta 			return ret;
495*20ffac27SDaniel Baluta 		}
496*20ffac27SDaniel Baluta 		*val = sign_extend32(ret >> chan->scan_type.shift,
497*20ffac27SDaniel Baluta 				     chan->scan_type.realbits - 1);
498*20ffac27SDaniel Baluta 
499*20ffac27SDaniel Baluta 		mutex_unlock(&data->lock);
500*20ffac27SDaniel Baluta 		return IIO_VAL_INT;
501*20ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SCALE:
502*20ffac27SDaniel Baluta 		switch (chan->type) {
503*20ffac27SDaniel Baluta 		case IIO_ACCEL:
504*20ffac27SDaniel Baluta 			*val = 0;
505*20ffac27SDaniel Baluta 			*val2 = kmx61_uscale_table[data->range];
506*20ffac27SDaniel Baluta 			return IIO_VAL_INT_PLUS_MICRO;
507*20ffac27SDaniel Baluta 		case IIO_MAGN:
508*20ffac27SDaniel Baluta 			/* 14 bits res, 1465 microGauss per magn count */
509*20ffac27SDaniel Baluta 			*val = 0;
510*20ffac27SDaniel Baluta 			*val2 = 1465;
511*20ffac27SDaniel Baluta 			return IIO_VAL_INT_PLUS_MICRO;
512*20ffac27SDaniel Baluta 		default:
513*20ffac27SDaniel Baluta 			return -EINVAL;
514*20ffac27SDaniel Baluta 		}
515*20ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SAMP_FREQ:
516*20ffac27SDaniel Baluta 		if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
517*20ffac27SDaniel Baluta 			return -EINVAL;
518*20ffac27SDaniel Baluta 
519*20ffac27SDaniel Baluta 		mutex_lock(&data->lock);
520*20ffac27SDaniel Baluta 		ret = kmx61_get_odr(data, val, val2, chan->address);
521*20ffac27SDaniel Baluta 		mutex_unlock(&data->lock);
522*20ffac27SDaniel Baluta 		if (ret)
523*20ffac27SDaniel Baluta 			return -EINVAL;
524*20ffac27SDaniel Baluta 		return IIO_VAL_INT_PLUS_MICRO;
525*20ffac27SDaniel Baluta 	}
526*20ffac27SDaniel Baluta 	return -EINVAL;
527*20ffac27SDaniel Baluta }
528*20ffac27SDaniel Baluta 
529*20ffac27SDaniel Baluta static int kmx61_write_raw(struct iio_dev *indio_dev,
530*20ffac27SDaniel Baluta 			   struct iio_chan_spec const *chan, int val,
531*20ffac27SDaniel Baluta 			   int val2, long mask)
532*20ffac27SDaniel Baluta {
533*20ffac27SDaniel Baluta 	int ret;
534*20ffac27SDaniel Baluta 	struct kmx61_data *data = kmx61_get_data(indio_dev);
535*20ffac27SDaniel Baluta 
536*20ffac27SDaniel Baluta 	switch (mask) {
537*20ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SAMP_FREQ:
538*20ffac27SDaniel Baluta 		if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
539*20ffac27SDaniel Baluta 			return -EINVAL;
540*20ffac27SDaniel Baluta 
541*20ffac27SDaniel Baluta 		mutex_lock(&data->lock);
542*20ffac27SDaniel Baluta 		ret = kmx61_set_odr(data, val, val2, chan->address);
543*20ffac27SDaniel Baluta 		mutex_unlock(&data->lock);
544*20ffac27SDaniel Baluta 		return ret;
545*20ffac27SDaniel Baluta 	case IIO_CHAN_INFO_SCALE:
546*20ffac27SDaniel Baluta 		switch (chan->type) {
547*20ffac27SDaniel Baluta 		case IIO_ACCEL:
548*20ffac27SDaniel Baluta 			if (val != 0)
549*20ffac27SDaniel Baluta 				return -EINVAL;
550*20ffac27SDaniel Baluta 			mutex_lock(&data->lock);
551*20ffac27SDaniel Baluta 			ret = kmx61_set_scale(data, val2);
552*20ffac27SDaniel Baluta 			mutex_unlock(&data->lock);
553*20ffac27SDaniel Baluta 			return ret;
554*20ffac27SDaniel Baluta 		default:
555*20ffac27SDaniel Baluta 			return -EINVAL;
556*20ffac27SDaniel Baluta 		}
557*20ffac27SDaniel Baluta 	default:
558*20ffac27SDaniel Baluta 		return -EINVAL;
559*20ffac27SDaniel Baluta 	}
560*20ffac27SDaniel Baluta }
561*20ffac27SDaniel Baluta 
562*20ffac27SDaniel Baluta static const struct iio_info kmx61_acc_info = {
563*20ffac27SDaniel Baluta 	.driver_module		= THIS_MODULE,
564*20ffac27SDaniel Baluta 	.read_raw		= kmx61_read_raw,
565*20ffac27SDaniel Baluta 	.write_raw		= kmx61_write_raw,
566*20ffac27SDaniel Baluta 	.attrs			= &kmx61_acc_attribute_group,
567*20ffac27SDaniel Baluta };
568*20ffac27SDaniel Baluta 
569*20ffac27SDaniel Baluta static const struct iio_info kmx61_mag_info = {
570*20ffac27SDaniel Baluta 	.driver_module		= THIS_MODULE,
571*20ffac27SDaniel Baluta 	.read_raw		= kmx61_read_raw,
572*20ffac27SDaniel Baluta 	.write_raw		= kmx61_write_raw,
573*20ffac27SDaniel Baluta 	.attrs			= &kmx61_mag_attribute_group,
574*20ffac27SDaniel Baluta };
575*20ffac27SDaniel Baluta 
576*20ffac27SDaniel Baluta static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data,
577*20ffac27SDaniel Baluta 					    const struct iio_info *info,
578*20ffac27SDaniel Baluta 					    const struct iio_chan_spec *chan,
579*20ffac27SDaniel Baluta 					    int num_channels,
580*20ffac27SDaniel Baluta 					    const char *name)
581*20ffac27SDaniel Baluta {
582*20ffac27SDaniel Baluta 	struct iio_dev *indio_dev;
583*20ffac27SDaniel Baluta 
584*20ffac27SDaniel Baluta 	indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data));
585*20ffac27SDaniel Baluta 	if (!indio_dev)
586*20ffac27SDaniel Baluta 		return ERR_PTR(-ENOMEM);
587*20ffac27SDaniel Baluta 
588*20ffac27SDaniel Baluta 	kmx61_set_data(indio_dev, data);
589*20ffac27SDaniel Baluta 
590*20ffac27SDaniel Baluta 	indio_dev->dev.parent = &data->client->dev;
591*20ffac27SDaniel Baluta 	indio_dev->channels = chan;
592*20ffac27SDaniel Baluta 	indio_dev->num_channels = num_channels;
593*20ffac27SDaniel Baluta 	indio_dev->name = name;
594*20ffac27SDaniel Baluta 	indio_dev->modes = INDIO_DIRECT_MODE;
595*20ffac27SDaniel Baluta 	indio_dev->info = info;
596*20ffac27SDaniel Baluta 
597*20ffac27SDaniel Baluta 	return indio_dev;
598*20ffac27SDaniel Baluta }
599*20ffac27SDaniel Baluta 
600*20ffac27SDaniel Baluta static int kmx61_probe(struct i2c_client *client,
601*20ffac27SDaniel Baluta 		       const struct i2c_device_id *id)
602*20ffac27SDaniel Baluta {
603*20ffac27SDaniel Baluta 	int ret;
604*20ffac27SDaniel Baluta 	struct kmx61_data *data;
605*20ffac27SDaniel Baluta 	const char *name = NULL;
606*20ffac27SDaniel Baluta 
607*20ffac27SDaniel Baluta 	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
608*20ffac27SDaniel Baluta 	if (!data)
609*20ffac27SDaniel Baluta 		return -ENOMEM;
610*20ffac27SDaniel Baluta 
611*20ffac27SDaniel Baluta 	i2c_set_clientdata(client, data);
612*20ffac27SDaniel Baluta 	data->client = client;
613*20ffac27SDaniel Baluta 
614*20ffac27SDaniel Baluta 	mutex_init(&data->lock);
615*20ffac27SDaniel Baluta 
616*20ffac27SDaniel Baluta 	data->acc_indio_dev =
617*20ffac27SDaniel Baluta 		kmx61_indiodev_setup(data, &kmx61_acc_info,
618*20ffac27SDaniel Baluta 				     kmx61_acc_channels,
619*20ffac27SDaniel Baluta 				     ARRAY_SIZE(kmx61_acc_channels),
620*20ffac27SDaniel Baluta 				     name);
621*20ffac27SDaniel Baluta 	if (IS_ERR(data->acc_indio_dev))
622*20ffac27SDaniel Baluta 		return PTR_ERR(data->acc_indio_dev);
623*20ffac27SDaniel Baluta 
624*20ffac27SDaniel Baluta 	data->mag_indio_dev =
625*20ffac27SDaniel Baluta 		kmx61_indiodev_setup(data, &kmx61_mag_info,
626*20ffac27SDaniel Baluta 				     kmx61_mag_channels,
627*20ffac27SDaniel Baluta 				     ARRAY_SIZE(kmx61_mag_channels),
628*20ffac27SDaniel Baluta 				     name);
629*20ffac27SDaniel Baluta 	if (IS_ERR(data->mag_indio_dev))
630*20ffac27SDaniel Baluta 		return PTR_ERR(data->mag_indio_dev);
631*20ffac27SDaniel Baluta 
632*20ffac27SDaniel Baluta 	ret = kmx61_chip_init(data);
633*20ffac27SDaniel Baluta 	if (ret < 0)
634*20ffac27SDaniel Baluta 		return ret;
635*20ffac27SDaniel Baluta 
636*20ffac27SDaniel Baluta 	ret = iio_device_register(data->acc_indio_dev);
637*20ffac27SDaniel Baluta 	if (ret < 0) {
638*20ffac27SDaniel Baluta 		dev_err(&client->dev, "Failed to register acc iio device\n");
639*20ffac27SDaniel Baluta 		goto err_chip_uninit;
640*20ffac27SDaniel Baluta 	}
641*20ffac27SDaniel Baluta 
642*20ffac27SDaniel Baluta 	ret = iio_device_register(data->mag_indio_dev);
643*20ffac27SDaniel Baluta 	if (ret < 0) {
644*20ffac27SDaniel Baluta 		dev_err(&client->dev, "Failed to register mag iio device\n");
645*20ffac27SDaniel Baluta 		goto err_iio_unregister;
646*20ffac27SDaniel Baluta 	}
647*20ffac27SDaniel Baluta 
648*20ffac27SDaniel Baluta 	return 0;
649*20ffac27SDaniel Baluta 
650*20ffac27SDaniel Baluta err_iio_unregister:
651*20ffac27SDaniel Baluta 	iio_device_unregister(data->acc_indio_dev);
652*20ffac27SDaniel Baluta err_chip_uninit:
653*20ffac27SDaniel Baluta 	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
654*20ffac27SDaniel Baluta 	return ret;
655*20ffac27SDaniel Baluta }
656*20ffac27SDaniel Baluta 
657*20ffac27SDaniel Baluta static int kmx61_remove(struct i2c_client *client)
658*20ffac27SDaniel Baluta {
659*20ffac27SDaniel Baluta 	struct kmx61_data *data = i2c_get_clientdata(client);
660*20ffac27SDaniel Baluta 
661*20ffac27SDaniel Baluta 	iio_device_unregister(data->acc_indio_dev);
662*20ffac27SDaniel Baluta 	iio_device_unregister(data->mag_indio_dev);
663*20ffac27SDaniel Baluta 
664*20ffac27SDaniel Baluta 	mutex_lock(&data->lock);
665*20ffac27SDaniel Baluta 	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
666*20ffac27SDaniel Baluta 	mutex_unlock(&data->lock);
667*20ffac27SDaniel Baluta 
668*20ffac27SDaniel Baluta 	return 0;
669*20ffac27SDaniel Baluta }
670*20ffac27SDaniel Baluta 
671*20ffac27SDaniel Baluta static const struct i2c_device_id kmx61_id[] = {
672*20ffac27SDaniel Baluta 	{"kmx611021", 0},
673*20ffac27SDaniel Baluta 	{}
674*20ffac27SDaniel Baluta };
675*20ffac27SDaniel Baluta 
676*20ffac27SDaniel Baluta MODULE_DEVICE_TABLE(i2c, kmx61_id);
677*20ffac27SDaniel Baluta 
678*20ffac27SDaniel Baluta static struct i2c_driver kmx61_driver = {
679*20ffac27SDaniel Baluta 	.driver = {
680*20ffac27SDaniel Baluta 		.name = KMX61_DRV_NAME,
681*20ffac27SDaniel Baluta 	},
682*20ffac27SDaniel Baluta 	.probe		= kmx61_probe,
683*20ffac27SDaniel Baluta 	.remove		= kmx61_remove,
684*20ffac27SDaniel Baluta 	.id_table	= kmx61_id,
685*20ffac27SDaniel Baluta };
686*20ffac27SDaniel Baluta 
687*20ffac27SDaniel Baluta module_i2c_driver(kmx61_driver);
688*20ffac27SDaniel Baluta 
689*20ffac27SDaniel Baluta MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
690*20ffac27SDaniel Baluta MODULE_DESCRIPTION("KMX61 accelerometer/magnetometer driver");
691*20ffac27SDaniel Baluta MODULE_LICENSE("GPL v2");
692