File Index
Files and directories
Sign in
FILE

mma9551_core.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/accel/mma9551_core.c C
  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
 70struct 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
 86struct 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
100struct 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
108static 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 */
216int 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}
222EXPORT_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 */
241int 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}
247EXPORT_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 */
266int 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}
272EXPORT_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 */
291int 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}
306EXPORT_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 */
325int 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}
333EXPORT_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 */
352int 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}
367EXPORT_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 */
385int 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}
406EXPORT_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 */
424int 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}
445EXPORT_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 */
463int 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}
480EXPORT_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 */
498int 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}
516EXPORT_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 */
537int 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}
595EXPORT_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 */
609int 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}
625EXPORT_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 */
644int 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}
655EXPORT_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 */
667int 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		ret = pm_runtime_put_autosuspend(&client->dev);
676	if (ret < 0) {
677		dev_err(&client->dev,
678			"failed to change power state to %d\n", on);
679
680		return ret;
681	}
682#endif
683
684	return 0;
685}
686EXPORT_SYMBOL_NS(mma9551_set_power_state, "IIO_MMA9551");
687
688/**
689 * mma9551_sleep() - sleep
690 * @freq:	Application frequency
691 *
692 * Firmware applications run at a certain frequency on the
693 * device. Sleep for one application cycle to make sure the
694 * application had time to run once and initialize set values.
695 */
696void mma9551_sleep(int freq)
697{
698	int sleep_val = 1000 / freq;
699
700	if (sleep_val < 20)
701		usleep_range(sleep_val * 1000, 20000);
702	else
703		msleep_interruptible(sleep_val);
704}
705EXPORT_SYMBOL_NS(mma9551_sleep, "IIO_MMA9551");
706
707/**
708 * mma9551_read_accel_chan() - read accelerometer channel
709 * @client:	I2C client
710 * @chan:	IIO channel
711 * @val:	Pointer to the accelerometer value read
712 * @val2:	Unused
713 *
714 * Read accelerometer value for the specified channel.
715 *
716 * Locking note: This function must be called with the device lock held.
717 * Locking is not handled inside the function. Callers should ensure they
718 * serialize access to the HW.
719 *
720 * Returns: IIO_VAL_INT on success, negative value on failure.
721 */
722int mma9551_read_accel_chan(struct i2c_client *client,
723			    const struct iio_chan_spec *chan,
724			    int *val, int *val2)
725{
726	u16 reg_addr;
727	s16 raw_accel;
728	int ret;
729
730	switch (chan->channel2) {
731	case IIO_MOD_X:
732		reg_addr = MMA9551_AFE_X_ACCEL_REG;
733		break;
734	case IIO_MOD_Y:
735		reg_addr = MMA9551_AFE_Y_ACCEL_REG;
736		break;
737	case IIO_MOD_Z:
738		reg_addr = MMA9551_AFE_Z_ACCEL_REG;
739		break;
740	default:
741		return -EINVAL;
742	}
743
744	ret = mma9551_set_power_state(client, true);
745	if (ret < 0)
746		return ret;
747
748	ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
749				       reg_addr, &raw_accel);
750	if (ret < 0)
751		goto out_poweroff;
752
753	*val = raw_accel;
754
755	ret = IIO_VAL_INT;
756
757out_poweroff:
758	mma9551_set_power_state(client, false);
759	return ret;
760}
761EXPORT_SYMBOL_NS(mma9551_read_accel_chan, "IIO_MMA9551");
762
763/**
764 * mma9551_read_accel_scale() - read accelerometer scale
765 * @val:	Pointer to the accelerometer scale (int value)
766 * @val2:	Pointer to the accelerometer scale (micro value)
767 *
768 * Read accelerometer scale.
769 *
770 * Returns: IIO_VAL_INT_PLUS_MICRO.
771 */
772int mma9551_read_accel_scale(int *val, int *val2)
773{
774	*val = 0;
775	*val2 = 2440;
776
777	return IIO_VAL_INT_PLUS_MICRO;
778}
779EXPORT_SYMBOL_NS(mma9551_read_accel_scale, "IIO_MMA9551");
780
781/**
782 * mma9551_app_reset() - reset application
783 * @client:	I2C client
784 * @app_mask:	Application to reset
785 *
786 * Reset the given application (using the Reset/Suspend/Clear
787 * Control Application)
788 *
789 * Returns: 0 on success, negative value on failure.
790 */
791int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
792{
793	return mma9551_write_config_byte(client, MMA9551_APPID_RSC,
794					 MMA9551_RSC_RESET +
795					 MMA9551_RSC_OFFSET(app_mask),
796					 MMA9551_RSC_VAL(app_mask));
797}
798EXPORT_SYMBOL_NS(mma9551_app_reset, "IIO_MMA9551");
799
800MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
801MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
802MODULE_LICENSE("GPL v2");
803MODULE_DESCRIPTION("MMA955xL sensors core");
~/ Read-only file preview.