xref: /linux/drivers/iio/accel/mma9551_core.c (revision e5a52fd2b8cdb700b3c07b030e050a49ef3156b9)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
4  * Copyright (c) 2014, Intel Corporation.
5  */
6 
7 #include <linux/module.h>
8 #include <linux/i2c.h>
9 #include <linux/delay.h>
10 #include <linux/iio/iio.h>
11 #include <linux/pm_runtime.h>
12 #include "mma9551_core.h"
13 
14 /* Command masks for mailbox write command */
15 #define MMA9551_CMD_READ_VERSION_INFO	0x00
16 #define MMA9551_CMD_READ_CONFIG		0x10
17 #define MMA9551_CMD_WRITE_CONFIG	0x20
18 #define MMA9551_CMD_READ_STATUS		0x30
19 
20 /* Mailbox read command */
21 #define MMA9551_RESPONSE_COCO		BIT(7)
22 
23 /* Error-Status codes returned in mailbox read command */
24 #define MMA9551_MCI_ERROR_NONE			0x00
25 #define MMA9551_MCI_ERROR_PARAM			0x04
26 #define MMA9551_MCI_INVALID_COUNT		0x19
27 #define MMA9551_MCI_ERROR_COMMAND		0x1C
28 #define MMA9551_MCI_ERROR_INVALID_LENGTH	0x21
29 #define MMA9551_MCI_ERROR_FIFO_BUSY		0x22
30 #define MMA9551_MCI_ERROR_FIFO_ALLOCATED	0x23
31 #define MMA9551_MCI_ERROR_FIFO_OVERSIZE		0x24
32 
33 /* GPIO Application */
34 #define MMA9551_GPIO_POL_MSB		0x08
35 #define MMA9551_GPIO_POL_LSB		0x09
36 
37 /* Sleep/Wake application */
38 #define MMA9551_SLEEP_CFG		0x06
39 #define MMA9551_SLEEP_CFG_SNCEN		BIT(0)
40 #define MMA9551_SLEEP_CFG_FLEEN		BIT(1)
41 #define MMA9551_SLEEP_CFG_SCHEN		BIT(2)
42 
43 /* AFE application */
44 #define MMA9551_AFE_X_ACCEL_REG		0x00
45 #define MMA9551_AFE_Y_ACCEL_REG		0x02
46 #define MMA9551_AFE_Z_ACCEL_REG		0x04
47 
48 /* Reset/Suspend/Clear application */
49 #define MMA9551_RSC_RESET		0x00
50 #define MMA9551_RSC_OFFSET(mask)	(3 - (ffs(mask) - 1) / 8)
51 #define MMA9551_RSC_VAL(mask)		(mask >> (((ffs(mask) - 1) / 8) * 8))
52 
53 /*
54  * A response is composed of:
55  * - control registers: MB0-3
56  * - data registers: MB4-31
57  *
58  * A request is composed of:
59  * - mbox to write to (always 0)
60  * - control registers: MB1-4
61  * - data registers: MB5-31
62  */
63 #define MMA9551_MAILBOX_CTRL_REGS	4
64 #define MMA9551_MAX_MAILBOX_DATA_REGS	28
65 #define MMA9551_MAILBOX_REGS		32
66 
67 #define MMA9551_I2C_READ_RETRIES	5
68 #define MMA9551_I2C_READ_DELAY	50	/* us */
69 
70 struct mma9551_mbox_request {
71 	u8 start_mbox;		/* Always 0. */
72 	u8 app_id;
73 	/*
74 	 * See Section 5.3.1 of the MMA955xL Software Reference Manual.
75 	 *
76 	 * Bit 7: reserved, always 0
77 	 * Bits 6-4: command
78 	 * Bits 3-0: upper bits of register offset
79 	 */
80 	u8 cmd_off;
81 	u8 lower_off;
82 	u8 nbytes;
83 	u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1];
84 } __packed;
85 
86 struct mma9551_mbox_response {
87 	u8 app_id;
88 	/*
89 	 * See Section 5.3.3 of the MMA955xL Software Reference Manual.
90 	 *
91 	 * Bit 7: COCO
92 	 * Bits 6-0: Error code.
93 	 */
94 	u8 coco_err;
95 	u8 nbytes;
96 	u8 req_bytes;
97 	u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS];
98 } __packed;
99 
100 struct mma9551_version_info {
101 	__be32 device_id;
102 	u8 rom_version[2];
103 	u8 fw_version[2];
104 	u8 hw_version[2];
105 	u8 fw_build[2];
106 };
107 
108 static int mma9551_transfer(struct i2c_client *client,
109 			    u8 app_id, u8 command, u16 offset,
110 			    u8 *inbytes, int num_inbytes,
111 			    u8 *outbytes, int num_outbytes)
112 {
113 	struct mma9551_mbox_request req;
114 	struct mma9551_mbox_response rsp;
115 	struct i2c_msg in, out;
116 	u8 req_len, err_code;
117 	int ret, retries;
118 
119 	if (offset >= 1 << 12) {
120 		dev_err(&client->dev, "register offset too large\n");
121 		return -EINVAL;
122 	}
123 
124 	req_len = 1 + MMA9551_MAILBOX_CTRL_REGS + num_inbytes;
125 	req.start_mbox = 0;
126 	req.app_id = app_id;
127 	req.cmd_off = command | (offset >> 8);
128 	req.lower_off = offset;
129 
130 	if (command == MMA9551_CMD_WRITE_CONFIG)
131 		req.nbytes = num_inbytes;
132 	else
133 		req.nbytes = num_outbytes;
134 	if (num_inbytes)
135 		memcpy(req.buf, inbytes, num_inbytes);
136 
137 	out.addr = client->addr;
138 	out.flags = 0;
139 	out.len = req_len;
140 	out.buf = (u8 *)&req;
141 
142 	ret = i2c_transfer(client->adapter, &out, 1);
143 	if (ret < 0) {
144 		dev_err(&client->dev, "i2c write failed\n");
145 		return ret;
146 	}
147 
148 	retries = MMA9551_I2C_READ_RETRIES;
149 	do {
150 		udelay(MMA9551_I2C_READ_DELAY);
151 
152 		in.addr = client->addr;
153 		in.flags = I2C_M_RD;
154 		in.len = sizeof(rsp);
155 		in.buf = (u8 *)&rsp;
156 
157 		ret = i2c_transfer(client->adapter, &in, 1);
158 		if (ret < 0) {
159 			dev_err(&client->dev, "i2c read failed\n");
160 			return ret;
161 		}
162 
163 		if (rsp.coco_err & MMA9551_RESPONSE_COCO)
164 			break;
165 	} while (--retries > 0);
166 
167 	if (retries == 0) {
168 		dev_err(&client->dev,
169 			"timed out while waiting for command response\n");
170 		return -ETIMEDOUT;
171 	}
172 
173 	if (rsp.app_id != app_id) {
174 		dev_err(&client->dev,
175 			"app_id mismatch in response got %02x expected %02x\n",
176 			rsp.app_id, app_id);
177 		return -EINVAL;
178 	}
179 
180 	err_code = rsp.coco_err & ~MMA9551_RESPONSE_COCO;
181 	if (err_code != MMA9551_MCI_ERROR_NONE) {
182 		dev_err(&client->dev, "read returned error %x\n", err_code);
183 		return -EINVAL;
184 	}
185 
186 	if (rsp.nbytes != rsp.req_bytes) {
187 		dev_err(&client->dev,
188 			"output length mismatch got %d expected %d\n",
189 			rsp.nbytes, rsp.req_bytes);
190 		return -EINVAL;
191 	}
192 
193 	if (num_outbytes)
194 		memcpy(outbytes, rsp.buf, num_outbytes);
195 
196 	return 0;
197 }
198 
199 /**
200  * mma9551_read_config_byte() - read 1 configuration byte
201  * @client:	I2C client
202  * @app_id:	Application ID
203  * @reg:	Application register
204  * @val:	Pointer to store value read
205  *
206  * Read one configuration byte from the device using MMA955xL command format.
207  * Commands to the MMA955xL platform consist of a write followed
208  * by one or more reads.
209  *
210  * Locking note: This function must be called with the device lock held.
211  * Locking is not handled inside the function. Callers should ensure they
212  * serialize access to the HW.
213  *
214  * Returns: 0 on success, negative value on failure.
215  */
216 int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
217 			     u16 reg, u8 *val)
218 {
219 	return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
220 				reg, NULL, 0, val, 1);
221 }
222 EXPORT_SYMBOL(mma9551_read_config_byte);
223 
224 /**
225  * mma9551_write_config_byte() - write 1 configuration byte
226  * @client:	I2C client
227  * @app_id:	Application ID
228  * @reg:	Application register
229  * @val:	Value to write
230  *
231  * Write one configuration byte from the device using MMA955xL command format.
232  * Commands to the MMA955xL platform consist of a write followed by one or
233  * more reads.
234  *
235  * Locking note: This function must be called with the device lock held.
236  * Locking is not handled inside the function. Callers should ensure they
237  * serialize access to the HW.
238  *
239  * Returns: 0 on success, negative value on failure.
240  */
241 int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
242 			      u16 reg, u8 val)
243 {
244 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
245 				&val, 1, NULL, 0);
246 }
247 EXPORT_SYMBOL(mma9551_write_config_byte);
248 
249 /**
250  * mma9551_read_status_byte() - read 1 status byte
251  * @client:	I2C client
252  * @app_id:	Application ID
253  * @reg:	Application register
254  * @val:	Pointer to store value read
255  *
256  * Read one status byte from the device using MMA955xL command format.
257  * Commands to the MMA955xL platform consist of a write followed by one or
258  * more reads.
259  *
260  * Locking note: This function must be called with the device lock held.
261  * Locking is not handled inside the function. Callers should ensure they
262  * serialize access to the HW.
263  *
264  * Returns: 0 on success, negative value on failure.
265  */
266 int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
267 			     u16 reg, u8 *val)
268 {
269 	return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
270 				reg, NULL, 0, val, 1);
271 }
272 EXPORT_SYMBOL(mma9551_read_status_byte);
273 
274 /**
275  * mma9551_read_config_word() - read 1 config word
276  * @client:	I2C client
277  * @app_id:	Application ID
278  * @reg:	Application register
279  * @val:	Pointer to store value read
280  *
281  * Read one configuration word from the device using MMA955xL command format.
282  * Commands to the MMA955xL platform consist of a write followed by one or
283  * more reads.
284  *
285  * Locking note: This function must be called with the device lock held.
286  * Locking is not handled inside the function. Callers should ensure they
287  * serialize access to the HW.
288  *
289  * Returns: 0 on success, negative value on failure.
290  */
291 int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
292 			     u16 reg, u16 *val)
293 {
294 	int ret;
295 	__be16 v;
296 
297 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
298 			       reg, NULL, 0, (u8 *)&v, 2);
299 	*val = be16_to_cpu(v);
300 
301 	return ret;
302 }
303 EXPORT_SYMBOL(mma9551_read_config_word);
304 
305 /**
306  * mma9551_write_config_word() - write 1 config word
307  * @client:	I2C client
308  * @app_id:	Application ID
309  * @reg:	Application register
310  * @val:	Value to write
311  *
312  * Write one configuration word from the device using MMA955xL command format.
313  * Commands to the MMA955xL platform consist of a write followed by one or
314  * more reads.
315  *
316  * Locking note: This function must be called with the device lock held.
317  * Locking is not handled inside the function. Callers should ensure they
318  * serialize access to the HW.
319  *
320  * Returns: 0 on success, negative value on failure.
321  */
322 int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
323 			      u16 reg, u16 val)
324 {
325 	__be16 v = cpu_to_be16(val);
326 
327 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
328 				(u8 *)&v, 2, NULL, 0);
329 }
330 EXPORT_SYMBOL(mma9551_write_config_word);
331 
332 /**
333  * mma9551_read_status_word() - read 1 status word
334  * @client:	I2C client
335  * @app_id:	Application ID
336  * @reg:	Application register
337  * @val:	Pointer to store value read
338  *
339  * Read one status word from the device using MMA955xL command format.
340  * Commands to the MMA955xL platform consist of a write followed by one or
341  * more reads.
342  *
343  * Locking note: This function must be called with the device lock held.
344  * Locking is not handled inside the function. Callers should ensure they
345  * serialize access to the HW.
346  *
347  * Returns: 0 on success, negative value on failure.
348  */
349 int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
350 			     u16 reg, u16 *val)
351 {
352 	int ret;
353 	__be16 v;
354 
355 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
356 			       reg, NULL, 0, (u8 *)&v, 2);
357 	*val = be16_to_cpu(v);
358 
359 	return ret;
360 }
361 EXPORT_SYMBOL(mma9551_read_status_word);
362 
363 /**
364  * mma9551_read_config_words() - read multiple config words
365  * @client:	I2C client
366  * @app_id:	Application ID
367  * @reg:	Application register
368  * @len:	Length of array to read (in words)
369  * @buf:	Array of words to read
370  *
371  * Read multiple configuration registers (word-sized registers).
372  *
373  * Locking note: This function must be called with the device lock held.
374  * Locking is not handled inside the function. Callers should ensure they
375  * serialize access to the HW.
376  *
377  * Returns: 0 on success, negative value on failure.
378  */
379 int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
380 			      u16 reg, u8 len, u16 *buf)
381 {
382 	int ret, i;
383 	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
384 
385 	if (len > ARRAY_SIZE(be_buf)) {
386 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
387 		return -EINVAL;
388 	}
389 
390 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
391 			       reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
392 	if (ret < 0)
393 		return ret;
394 
395 	for (i = 0; i < len; i++)
396 		buf[i] = be16_to_cpu(be_buf[i]);
397 
398 	return 0;
399 }
400 EXPORT_SYMBOL(mma9551_read_config_words);
401 
402 /**
403  * mma9551_read_status_words() - read multiple status words
404  * @client:	I2C client
405  * @app_id:	Application ID
406  * @reg:	Application register
407  * @len:	Length of array to read (in words)
408  * @buf:	Array of words to read
409  *
410  * Read multiple status registers (word-sized registers).
411  *
412  * Locking note: This function must be called with the device lock held.
413  * Locking is not handled inside the function. Callers should ensure they
414  * serialize access to the HW.
415  *
416  * Returns: 0 on success, negative value on failure.
417  */
418 int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
419 			      u16 reg, u8 len, u16 *buf)
420 {
421 	int ret, i;
422 	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
423 
424 	if (len > ARRAY_SIZE(be_buf)) {
425 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
426 		return -EINVAL;
427 	}
428 
429 	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
430 			       reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
431 	if (ret < 0)
432 		return ret;
433 
434 	for (i = 0; i < len; i++)
435 		buf[i] = be16_to_cpu(be_buf[i]);
436 
437 	return 0;
438 }
439 EXPORT_SYMBOL(mma9551_read_status_words);
440 
441 /**
442  * mma9551_write_config_words() - write multiple config words
443  * @client:	I2C client
444  * @app_id:	Application ID
445  * @reg:	Application register
446  * @len:	Length of array to write (in words)
447  * @buf:	Array of words to write
448  *
449  * Write multiple configuration registers (word-sized registers).
450  *
451  * Locking note: This function must be called with the device lock held.
452  * Locking is not handled inside the function. Callers should ensure they
453  * serialize access to the HW.
454  *
455  * Returns: 0 on success, negative value on failure.
456  */
457 int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
458 			       u16 reg, u8 len, u16 *buf)
459 {
460 	int i;
461 	__be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
462 
463 	if (len > ARRAY_SIZE(be_buf)) {
464 		dev_err(&client->dev, "Invalid buffer size %d\n", len);
465 		return -EINVAL;
466 	}
467 
468 	for (i = 0; i < len; i++)
469 		be_buf[i] = cpu_to_be16(buf[i]);
470 
471 	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
472 				reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
473 }
474 EXPORT_SYMBOL(mma9551_write_config_words);
475 
476 /**
477  * mma9551_update_config_bits() - update bits in register
478  * @client:	I2C client
479  * @app_id:	Application ID
480  * @reg:	Application register
481  * @mask:	Mask for the bits to update
482  * @val:	Value of the bits to update
483  *
484  * Update bits in the given register using a bit mask.
485  *
486  * Locking note: This function must be called with the device lock held.
487  * Locking is not handled inside the function. Callers should ensure they
488  * serialize access to the HW.
489  *
490  * Returns: 0 on success, negative value on failure.
491  */
492 int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
493 			       u16 reg, u8 mask, u8 val)
494 {
495 	int ret;
496 	u8 tmp, orig;
497 
498 	ret = mma9551_read_config_byte(client, app_id, reg, &orig);
499 	if (ret < 0)
500 		return ret;
501 
502 	tmp = orig & ~mask;
503 	tmp |= val & mask;
504 
505 	if (tmp == orig)
506 		return 0;
507 
508 	return mma9551_write_config_byte(client, app_id, reg, tmp);
509 }
510 EXPORT_SYMBOL(mma9551_update_config_bits);
511 
512 /**
513  * mma9551_gpio_config() - configure gpio
514  * @client:	I2C client
515  * @pin:	GPIO pin to configure
516  * @app_id:	Application ID
517  * @bitnum:	Bit number of status register being assigned to the GPIO pin.
518  * @polarity:	The polarity parameter is described in section 6.2.2, page 66,
519  *		of the Software Reference Manual.  Basically, polarity=0 means
520  *		the interrupt line has the same value as the selected bit,
521  *		while polarity=1 means the line is inverted.
522  *
523  * Assign a bit from an application’s status register to a specific GPIO pin.
524  *
525  * Locking note: This function must be called with the device lock held.
526  * Locking is not handled inside the function. Callers should ensure they
527  * serialize access to the HW.
528  *
529  * Returns: 0 on success, negative value on failure.
530  */
531 int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
532 			u8 app_id, u8 bitnum, int polarity)
533 {
534 	u8 reg, pol_mask, pol_val;
535 	int ret;
536 
537 	if (pin > mma9551_gpio_max) {
538 		dev_err(&client->dev, "bad GPIO pin\n");
539 		return -EINVAL;
540 	}
541 
542 	/*
543 	 * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and
544 	 * 0x03, and so on.
545 	 */
546 	reg = pin * 2;
547 
548 	ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
549 					reg, app_id);
550 	if (ret < 0) {
551 		dev_err(&client->dev, "error setting GPIO app_id\n");
552 		return ret;
553 	}
554 
555 	ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
556 					reg + 1, bitnum);
557 	if (ret < 0) {
558 		dev_err(&client->dev, "error setting GPIO bit number\n");
559 		return ret;
560 	}
561 
562 	switch (pin) {
563 	case mma9551_gpio6:
564 		reg = MMA9551_GPIO_POL_LSB;
565 		pol_mask = 1 << 6;
566 		break;
567 	case mma9551_gpio7:
568 		reg = MMA9551_GPIO_POL_LSB;
569 		pol_mask = 1 << 7;
570 		break;
571 	case mma9551_gpio8:
572 		reg = MMA9551_GPIO_POL_MSB;
573 		pol_mask = 1 << 0;
574 		break;
575 	case mma9551_gpio9:
576 		reg = MMA9551_GPIO_POL_MSB;
577 		pol_mask = 1 << 1;
578 		break;
579 	}
580 	pol_val = polarity ? pol_mask : 0;
581 
582 	ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,
583 					 pol_mask, pol_val);
584 	if (ret < 0)
585 		dev_err(&client->dev, "error setting GPIO polarity\n");
586 
587 	return ret;
588 }
589 EXPORT_SYMBOL(mma9551_gpio_config);
590 
591 /**
592  * mma9551_read_version() - read device version information
593  * @client:	I2C client
594  *
595  * Read version information and print device id and firmware version.
596  *
597  * Locking note: This function must be called with the device lock held.
598  * Locking is not handled inside the function. Callers should ensure they
599  * serialize access to the HW.
600  *
601  * Returns: 0 on success, negative value on failure.
602  */
603 int mma9551_read_version(struct i2c_client *client)
604 {
605 	struct mma9551_version_info info;
606 	int ret;
607 
608 	ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,
609 			       NULL, 0, (u8 *)&info, sizeof(info));
610 	if (ret < 0)
611 		return ret;
612 
613 	dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",
614 		 be32_to_cpu(info.device_id), info.fw_version[0],
615 		 info.fw_version[1]);
616 
617 	return 0;
618 }
619 EXPORT_SYMBOL(mma9551_read_version);
620 
621 /**
622  * mma9551_set_device_state() - sets HW power mode
623  * @client:	I2C client
624  * @enable:	Use true to power on device, false to cause the device
625  *		to enter sleep.
626  *
627  * Set power on/off for device using the Sleep/Wake Application.
628  * When enable is true, power on chip and enable doze mode.
629  * When enable is false, enter sleep mode (device remains in the
630  * lowest-power mode).
631  *
632  * Locking note: This function must be called with the device lock held.
633  * Locking is not handled inside the function. Callers should ensure they
634  * serialize access to the HW.
635  *
636  * Returns: 0 on success, negative value on failure.
637  */
638 int mma9551_set_device_state(struct i2c_client *client, bool enable)
639 {
640 	return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,
641 					  MMA9551_SLEEP_CFG,
642 					  MMA9551_SLEEP_CFG_SNCEN |
643 					  MMA9551_SLEEP_CFG_FLEEN |
644 					  MMA9551_SLEEP_CFG_SCHEN,
645 					  enable ? MMA9551_SLEEP_CFG_SCHEN |
646 					  MMA9551_SLEEP_CFG_FLEEN :
647 					  MMA9551_SLEEP_CFG_SNCEN);
648 }
649 EXPORT_SYMBOL(mma9551_set_device_state);
650 
651 /**
652  * mma9551_set_power_state() - sets runtime PM state
653  * @client:	I2C client
654  * @on:		Use true to power on device, false to power off
655  *
656  * Resume or suspend the device using Runtime PM.
657  * The device will suspend after the autosuspend delay.
658  *
659  * Returns: 0 on success, negative value on failure.
660  */
661 int mma9551_set_power_state(struct i2c_client *client, bool on)
662 {
663 #ifdef CONFIG_PM
664 	int ret;
665 
666 	if (on)
667 		ret = pm_runtime_get_sync(&client->dev);
668 	else {
669 		pm_runtime_mark_last_busy(&client->dev);
670 		ret = pm_runtime_put_autosuspend(&client->dev);
671 	}
672 
673 	if (ret < 0) {
674 		dev_err(&client->dev,
675 			"failed to change power state to %d\n", on);
676 		if (on)
677 			pm_runtime_put_noidle(&client->dev);
678 
679 		return ret;
680 	}
681 #endif
682 
683 	return 0;
684 }
685 EXPORT_SYMBOL(mma9551_set_power_state);
686 
687 /**
688  * mma9551_sleep() - sleep
689  * @freq:	Application frequency
690  *
691  * Firmware applications run at a certain frequency on the
692  * device. Sleep for one application cycle to make sure the
693  * application had time to run once and initialize set values.
694  */
695 void mma9551_sleep(int freq)
696 {
697 	int sleep_val = 1000 / freq;
698 
699 	if (sleep_val < 20)
700 		usleep_range(sleep_val * 1000, 20000);
701 	else
702 		msleep_interruptible(sleep_val);
703 }
704 EXPORT_SYMBOL(mma9551_sleep);
705 
706 /**
707  * mma9551_read_accel_chan() - read accelerometer channel
708  * @client:	I2C client
709  * @chan:	IIO channel
710  * @val:	Pointer to the accelerometer value read
711  * @val2:	Unused
712  *
713  * Read accelerometer value for the specified channel.
714  *
715  * Locking note: This function must be called with the device lock held.
716  * Locking is not handled inside the function. Callers should ensure they
717  * serialize access to the HW.
718  *
719  * Returns: IIO_VAL_INT on success, negative value on failure.
720  */
721 int mma9551_read_accel_chan(struct i2c_client *client,
722 			    const struct iio_chan_spec *chan,
723 			    int *val, int *val2)
724 {
725 	u16 reg_addr;
726 	s16 raw_accel;
727 	int ret;
728 
729 	switch (chan->channel2) {
730 	case IIO_MOD_X:
731 		reg_addr = MMA9551_AFE_X_ACCEL_REG;
732 		break;
733 	case IIO_MOD_Y:
734 		reg_addr = MMA9551_AFE_Y_ACCEL_REG;
735 		break;
736 	case IIO_MOD_Z:
737 		reg_addr = MMA9551_AFE_Z_ACCEL_REG;
738 		break;
739 	default:
740 		return -EINVAL;
741 	}
742 
743 	ret = mma9551_set_power_state(client, true);
744 	if (ret < 0)
745 		return ret;
746 
747 	ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
748 				       reg_addr, &raw_accel);
749 	if (ret < 0)
750 		goto out_poweroff;
751 
752 	*val = raw_accel;
753 
754 	ret = IIO_VAL_INT;
755 
756 out_poweroff:
757 	mma9551_set_power_state(client, false);
758 	return ret;
759 }
760 EXPORT_SYMBOL(mma9551_read_accel_chan);
761 
762 /**
763  * mma9551_read_accel_scale() - read accelerometer scale
764  * @val:	Pointer to the accelerometer scale (int value)
765  * @val2:	Pointer to the accelerometer scale (micro value)
766  *
767  * Read accelerometer scale.
768  *
769  * Returns: IIO_VAL_INT_PLUS_MICRO.
770  */
771 int mma9551_read_accel_scale(int *val, int *val2)
772 {
773 	*val = 0;
774 	*val2 = 2440;
775 
776 	return IIO_VAL_INT_PLUS_MICRO;
777 }
778 EXPORT_SYMBOL(mma9551_read_accel_scale);
779 
780 /**
781  * mma9551_app_reset() - reset application
782  * @client:	I2C client
783  * @app_mask:	Application to reset
784  *
785  * Reset the given application (using the Reset/Suspend/Clear
786  * Control Application)
787  *
788  * Returns: 0 on success, negative value on failure.
789  */
790 int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
791 {
792 	return mma9551_write_config_byte(client, MMA9551_APPID_RSC,
793 					 MMA9551_RSC_RESET +
794 					 MMA9551_RSC_OFFSET(app_mask),
795 					 MMA9551_RSC_VAL(app_mask));
796 }
797 EXPORT_SYMBOL(mma9551_app_reset);
798 
799 MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
800 MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
801 MODULE_LICENSE("GPL v2");
802 MODULE_DESCRIPTION("MMA955xL sensors core");
803