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  
mma9551_transfer(struct i2c_client * client,u8 app_id,u8 command,u16 offset,u8 * inbytes,int num_inbytes,u8 * outbytes,int num_outbytes)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   */
mma9551_read_config_byte(struct i2c_client * client,u8 app_id,u16 reg,u8 * val)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_NS(mma9551_read_config_byte, IIO_MMA9551);
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   */
mma9551_write_config_byte(struct i2c_client * client,u8 app_id,u16 reg,u8 val)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_NS(mma9551_write_config_byte, IIO_MMA9551);
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   */
mma9551_read_status_byte(struct i2c_client * client,u8 app_id,u16 reg,u8 * val)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_NS(mma9551_read_status_byte, IIO_MMA9551);
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   */
mma9551_read_config_word(struct i2c_client * client,u8 app_id,u16 reg,u16 * val)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  	if (ret < 0)
300  		return ret;
301  
302  	*val = be16_to_cpu(v);
303  
304  	return 0;
305  }
306  EXPORT_SYMBOL_NS(mma9551_read_config_word, IIO_MMA9551);
307  
308  /**
309   * mma9551_write_config_word() - write 1 config word
310   * @client:	I2C client
311   * @app_id:	Application ID
312   * @reg:	Application register
313   * @val:	Value to write
314   *
315   * Write one configuration word from the device using MMA955xL command format.
316   * Commands to the MMA955xL platform consist of a write followed by one or
317   * more reads.
318   *
319   * Locking note: This function must be called with the device lock held.
320   * Locking is not handled inside the function. Callers should ensure they
321   * serialize access to the HW.
322   *
323   * Returns: 0 on success, negative value on failure.
324   */
mma9551_write_config_word(struct i2c_client * client,u8 app_id,u16 reg,u16 val)325  int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
326  			      u16 reg, u16 val)
327  {
328  	__be16 v = cpu_to_be16(val);
329  
330  	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
331  				(u8 *)&v, 2, NULL, 0);
332  }
333  EXPORT_SYMBOL_NS(mma9551_write_config_word, IIO_MMA9551);
334  
335  /**
336   * mma9551_read_status_word() - read 1 status word
337   * @client:	I2C client
338   * @app_id:	Application ID
339   * @reg:	Application register
340   * @val:	Pointer to store value read
341   *
342   * Read one status word from the device using MMA955xL command format.
343   * Commands to the MMA955xL platform consist of a write followed by one or
344   * more reads.
345   *
346   * Locking note: This function must be called with the device lock held.
347   * Locking is not handled inside the function. Callers should ensure they
348   * serialize access to the HW.
349   *
350   * Returns: 0 on success, negative value on failure.
351   */
mma9551_read_status_word(struct i2c_client * client,u8 app_id,u16 reg,u16 * val)352  int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
353  			     u16 reg, u16 *val)
354  {
355  	int ret;
356  	__be16 v;
357  
358  	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
359  			       reg, NULL, 0, (u8 *)&v, 2);
360  	if (ret < 0)
361  		return ret;
362  
363  	*val = be16_to_cpu(v);
364  
365  	return 0;
366  }
367  EXPORT_SYMBOL_NS(mma9551_read_status_word, IIO_MMA9551);
368  
369  /**
370   * mma9551_read_config_words() - read multiple config words
371   * @client:	I2C client
372   * @app_id:	Application ID
373   * @reg:	Application register
374   * @len:	Length of array to read (in words)
375   * @buf:	Array of words to read
376   *
377   * Read multiple configuration registers (word-sized registers).
378   *
379   * Locking note: This function must be called with the device lock held.
380   * Locking is not handled inside the function. Callers should ensure they
381   * serialize access to the HW.
382   *
383   * Returns: 0 on success, negative value on failure.
384   */
mma9551_read_config_words(struct i2c_client * client,u8 app_id,u16 reg,u8 len,u16 * buf)385  int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
386  			      u16 reg, u8 len, u16 *buf)
387  {
388  	int ret, i;
389  	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
390  
391  	if (len > ARRAY_SIZE(be_buf)) {
392  		dev_err(&client->dev, "Invalid buffer size %d\n", len);
393  		return -EINVAL;
394  	}
395  
396  	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
397  			       reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
398  	if (ret < 0)
399  		return ret;
400  
401  	for (i = 0; i < len; i++)
402  		buf[i] = be16_to_cpu(be_buf[i]);
403  
404  	return 0;
405  }
406  EXPORT_SYMBOL_NS(mma9551_read_config_words, IIO_MMA9551);
407  
408  /**
409   * mma9551_read_status_words() - read multiple status words
410   * @client:	I2C client
411   * @app_id:	Application ID
412   * @reg:	Application register
413   * @len:	Length of array to read (in words)
414   * @buf:	Array of words to read
415   *
416   * Read multiple status registers (word-sized registers).
417   *
418   * Locking note: This function must be called with the device lock held.
419   * Locking is not handled inside the function. Callers should ensure they
420   * serialize access to the HW.
421   *
422   * Returns: 0 on success, negative value on failure.
423   */
mma9551_read_status_words(struct i2c_client * client,u8 app_id,u16 reg,u8 len,u16 * buf)424  int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
425  			      u16 reg, u8 len, u16 *buf)
426  {
427  	int ret, i;
428  	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
429  
430  	if (len > ARRAY_SIZE(be_buf)) {
431  		dev_err(&client->dev, "Invalid buffer size %d\n", len);
432  		return -EINVAL;
433  	}
434  
435  	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
436  			       reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
437  	if (ret < 0)
438  		return ret;
439  
440  	for (i = 0; i < len; i++)
441  		buf[i] = be16_to_cpu(be_buf[i]);
442  
443  	return 0;
444  }
445  EXPORT_SYMBOL_NS(mma9551_read_status_words, IIO_MMA9551);
446  
447  /**
448   * mma9551_write_config_words() - write multiple config words
449   * @client:	I2C client
450   * @app_id:	Application ID
451   * @reg:	Application register
452   * @len:	Length of array to write (in words)
453   * @buf:	Array of words to write
454   *
455   * Write multiple configuration registers (word-sized registers).
456   *
457   * Locking note: This function must be called with the device lock held.
458   * Locking is not handled inside the function. Callers should ensure they
459   * serialize access to the HW.
460   *
461   * Returns: 0 on success, negative value on failure.
462   */
mma9551_write_config_words(struct i2c_client * client,u8 app_id,u16 reg,u8 len,u16 * buf)463  int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
464  			       u16 reg, u8 len, u16 *buf)
465  {
466  	int i;
467  	__be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
468  
469  	if (len > ARRAY_SIZE(be_buf)) {
470  		dev_err(&client->dev, "Invalid buffer size %d\n", len);
471  		return -EINVAL;
472  	}
473  
474  	for (i = 0; i < len; i++)
475  		be_buf[i] = cpu_to_be16(buf[i]);
476  
477  	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
478  				reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
479  }
480  EXPORT_SYMBOL_NS(mma9551_write_config_words, IIO_MMA9551);
481  
482  /**
483   * mma9551_update_config_bits() - update bits in register
484   * @client:	I2C client
485   * @app_id:	Application ID
486   * @reg:	Application register
487   * @mask:	Mask for the bits to update
488   * @val:	Value of the bits to update
489   *
490   * Update bits in the given register using a bit mask.
491   *
492   * Locking note: This function must be called with the device lock held.
493   * Locking is not handled inside the function. Callers should ensure they
494   * serialize access to the HW.
495   *
496   * Returns: 0 on success, negative value on failure.
497   */
mma9551_update_config_bits(struct i2c_client * client,u8 app_id,u16 reg,u8 mask,u8 val)498  int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
499  			       u16 reg, u8 mask, u8 val)
500  {
501  	int ret;
502  	u8 tmp, orig;
503  
504  	ret = mma9551_read_config_byte(client, app_id, reg, &orig);
505  	if (ret < 0)
506  		return ret;
507  
508  	tmp = orig & ~mask;
509  	tmp |= val & mask;
510  
511  	if (tmp == orig)
512  		return 0;
513  
514  	return mma9551_write_config_byte(client, app_id, reg, tmp);
515  }
516  EXPORT_SYMBOL_NS(mma9551_update_config_bits, IIO_MMA9551);
517  
518  /**
519   * mma9551_gpio_config() - configure gpio
520   * @client:	I2C client
521   * @pin:	GPIO pin to configure
522   * @app_id:	Application ID
523   * @bitnum:	Bit number of status register being assigned to the GPIO pin.
524   * @polarity:	The polarity parameter is described in section 6.2.2, page 66,
525   *		of the Software Reference Manual.  Basically, polarity=0 means
526   *		the interrupt line has the same value as the selected bit,
527   *		while polarity=1 means the line is inverted.
528   *
529   * Assign a bit from an application’s status register to a specific GPIO pin.
530   *
531   * Locking note: This function must be called with the device lock held.
532   * Locking is not handled inside the function. Callers should ensure they
533   * serialize access to the HW.
534   *
535   * Returns: 0 on success, negative value on failure.
536   */
mma9551_gpio_config(struct i2c_client * client,enum mma9551_gpio_pin pin,u8 app_id,u8 bitnum,int polarity)537  int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
538  			u8 app_id, u8 bitnum, int polarity)
539  {
540  	u8 reg, pol_mask, pol_val;
541  	int ret;
542  
543  	if (pin > mma9551_gpio_max) {
544  		dev_err(&client->dev, "bad GPIO pin\n");
545  		return -EINVAL;
546  	}
547  
548  	/*
549  	 * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and
550  	 * 0x03, and so on.
551  	 */
552  	reg = pin * 2;
553  
554  	ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
555  					reg, app_id);
556  	if (ret < 0) {
557  		dev_err(&client->dev, "error setting GPIO app_id\n");
558  		return ret;
559  	}
560  
561  	ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
562  					reg + 1, bitnum);
563  	if (ret < 0) {
564  		dev_err(&client->dev, "error setting GPIO bit number\n");
565  		return ret;
566  	}
567  
568  	switch (pin) {
569  	case mma9551_gpio6:
570  		reg = MMA9551_GPIO_POL_LSB;
571  		pol_mask = 1 << 6;
572  		break;
573  	case mma9551_gpio7:
574  		reg = MMA9551_GPIO_POL_LSB;
575  		pol_mask = 1 << 7;
576  		break;
577  	case mma9551_gpio8:
578  		reg = MMA9551_GPIO_POL_MSB;
579  		pol_mask = 1 << 0;
580  		break;
581  	case mma9551_gpio9:
582  		reg = MMA9551_GPIO_POL_MSB;
583  		pol_mask = 1 << 1;
584  		break;
585  	}
586  	pol_val = polarity ? pol_mask : 0;
587  
588  	ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,
589  					 pol_mask, pol_val);
590  	if (ret < 0)
591  		dev_err(&client->dev, "error setting GPIO polarity\n");
592  
593  	return ret;
594  }
595  EXPORT_SYMBOL_NS(mma9551_gpio_config, IIO_MMA9551);
596  
597  /**
598   * mma9551_read_version() - read device version information
599   * @client:	I2C client
600   *
601   * Read version information and print device id and firmware version.
602   *
603   * Locking note: This function must be called with the device lock held.
604   * Locking is not handled inside the function. Callers should ensure they
605   * serialize access to the HW.
606   *
607   * Returns: 0 on success, negative value on failure.
608   */
mma9551_read_version(struct i2c_client * client)609  int mma9551_read_version(struct i2c_client *client)
610  {
611  	struct mma9551_version_info info;
612  	int ret;
613  
614  	ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,
615  			       NULL, 0, (u8 *)&info, sizeof(info));
616  	if (ret < 0)
617  		return ret;
618  
619  	dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",
620  		 be32_to_cpu(info.device_id), info.fw_version[0],
621  		 info.fw_version[1]);
622  
623  	return 0;
624  }
625  EXPORT_SYMBOL_NS(mma9551_read_version, IIO_MMA9551);
626  
627  /**
628   * mma9551_set_device_state() - sets HW power mode
629   * @client:	I2C client
630   * @enable:	Use true to power on device, false to cause the device
631   *		to enter sleep.
632   *
633   * Set power on/off for device using the Sleep/Wake Application.
634   * When enable is true, power on chip and enable doze mode.
635   * When enable is false, enter sleep mode (device remains in the
636   * lowest-power mode).
637   *
638   * Locking note: This function must be called with the device lock held.
639   * Locking is not handled inside the function. Callers should ensure they
640   * serialize access to the HW.
641   *
642   * Returns: 0 on success, negative value on failure.
643   */
mma9551_set_device_state(struct i2c_client * client,bool enable)644  int mma9551_set_device_state(struct i2c_client *client, bool enable)
645  {
646  	return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,
647  					  MMA9551_SLEEP_CFG,
648  					  MMA9551_SLEEP_CFG_SNCEN |
649  					  MMA9551_SLEEP_CFG_FLEEN |
650  					  MMA9551_SLEEP_CFG_SCHEN,
651  					  enable ? MMA9551_SLEEP_CFG_SCHEN |
652  					  MMA9551_SLEEP_CFG_FLEEN :
653  					  MMA9551_SLEEP_CFG_SNCEN);
654  }
655  EXPORT_SYMBOL_NS(mma9551_set_device_state, IIO_MMA9551);
656  
657  /**
658   * mma9551_set_power_state() - sets runtime PM state
659   * @client:	I2C client
660   * @on:		Use true to power on device, false to power off
661   *
662   * Resume or suspend the device using Runtime PM.
663   * The device will suspend after the autosuspend delay.
664   *
665   * Returns: 0 on success, negative value on failure.
666   */
mma9551_set_power_state(struct i2c_client * client,bool on)667  int mma9551_set_power_state(struct i2c_client *client, bool on)
668  {
669  #ifdef CONFIG_PM
670  	int ret;
671  
672  	if (on)
673  		ret = pm_runtime_resume_and_get(&client->dev);
674  	else {
675  		pm_runtime_mark_last_busy(&client->dev);
676  		ret = pm_runtime_put_autosuspend(&client->dev);
677  	}
678  
679  	if (ret < 0) {
680  		dev_err(&client->dev,
681  			"failed to change power state to %d\n", on);
682  
683  		return ret;
684  	}
685  #endif
686  
687  	return 0;
688  }
689  EXPORT_SYMBOL_NS(mma9551_set_power_state, IIO_MMA9551);
690  
691  /**
692   * mma9551_sleep() - sleep
693   * @freq:	Application frequency
694   *
695   * Firmware applications run at a certain frequency on the
696   * device. Sleep for one application cycle to make sure the
697   * application had time to run once and initialize set values.
698   */
mma9551_sleep(int freq)699  void mma9551_sleep(int freq)
700  {
701  	int sleep_val = 1000 / freq;
702  
703  	if (sleep_val < 20)
704  		usleep_range(sleep_val * 1000, 20000);
705  	else
706  		msleep_interruptible(sleep_val);
707  }
708  EXPORT_SYMBOL_NS(mma9551_sleep, IIO_MMA9551);
709  
710  /**
711   * mma9551_read_accel_chan() - read accelerometer channel
712   * @client:	I2C client
713   * @chan:	IIO channel
714   * @val:	Pointer to the accelerometer value read
715   * @val2:	Unused
716   *
717   * Read accelerometer value for the specified channel.
718   *
719   * Locking note: This function must be called with the device lock held.
720   * Locking is not handled inside the function. Callers should ensure they
721   * serialize access to the HW.
722   *
723   * Returns: IIO_VAL_INT on success, negative value on failure.
724   */
mma9551_read_accel_chan(struct i2c_client * client,const struct iio_chan_spec * chan,int * val,int * val2)725  int mma9551_read_accel_chan(struct i2c_client *client,
726  			    const struct iio_chan_spec *chan,
727  			    int *val, int *val2)
728  {
729  	u16 reg_addr;
730  	s16 raw_accel;
731  	int ret;
732  
733  	switch (chan->channel2) {
734  	case IIO_MOD_X:
735  		reg_addr = MMA9551_AFE_X_ACCEL_REG;
736  		break;
737  	case IIO_MOD_Y:
738  		reg_addr = MMA9551_AFE_Y_ACCEL_REG;
739  		break;
740  	case IIO_MOD_Z:
741  		reg_addr = MMA9551_AFE_Z_ACCEL_REG;
742  		break;
743  	default:
744  		return -EINVAL;
745  	}
746  
747  	ret = mma9551_set_power_state(client, true);
748  	if (ret < 0)
749  		return ret;
750  
751  	ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
752  				       reg_addr, &raw_accel);
753  	if (ret < 0)
754  		goto out_poweroff;
755  
756  	*val = raw_accel;
757  
758  	ret = IIO_VAL_INT;
759  
760  out_poweroff:
761  	mma9551_set_power_state(client, false);
762  	return ret;
763  }
764  EXPORT_SYMBOL_NS(mma9551_read_accel_chan, IIO_MMA9551);
765  
766  /**
767   * mma9551_read_accel_scale() - read accelerometer scale
768   * @val:	Pointer to the accelerometer scale (int value)
769   * @val2:	Pointer to the accelerometer scale (micro value)
770   *
771   * Read accelerometer scale.
772   *
773   * Returns: IIO_VAL_INT_PLUS_MICRO.
774   */
mma9551_read_accel_scale(int * val,int * val2)775  int mma9551_read_accel_scale(int *val, int *val2)
776  {
777  	*val = 0;
778  	*val2 = 2440;
779  
780  	return IIO_VAL_INT_PLUS_MICRO;
781  }
782  EXPORT_SYMBOL_NS(mma9551_read_accel_scale, IIO_MMA9551);
783  
784  /**
785   * mma9551_app_reset() - reset application
786   * @client:	I2C client
787   * @app_mask:	Application to reset
788   *
789   * Reset the given application (using the Reset/Suspend/Clear
790   * Control Application)
791   *
792   * Returns: 0 on success, negative value on failure.
793   */
mma9551_app_reset(struct i2c_client * client,u32 app_mask)794  int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
795  {
796  	return mma9551_write_config_byte(client, MMA9551_APPID_RSC,
797  					 MMA9551_RSC_RESET +
798  					 MMA9551_RSC_OFFSET(app_mask),
799  					 MMA9551_RSC_VAL(app_mask));
800  }
801  EXPORT_SYMBOL_NS(mma9551_app_reset, IIO_MMA9551);
802  
803  MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
804  MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
805  MODULE_LICENSE("GPL v2");
806  MODULE_DESCRIPTION("MMA955xL sensors core");
807