xref: /linux/drivers/iio/accel/mma9551.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Freescale MMA9551L Intelligent Motion-Sensing Platform driver
4  * Copyright (c) 2014, Intel Corporation.
5  */
6 
7 #include <linux/i2c.h>
8 #include <linux/interrupt.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/iio/iio.h>
14 #include <linux/iio/sysfs.h>
15 #include <linux/iio/events.h>
16 #include <linux/pm_runtime.h>
17 #include "mma9551_core.h"
18 
19 #define MMA9551_GPIO_COUNT		4
20 
21 /* Tilt application (inclination in IIO terms). */
22 #define MMA9551_TILT_XZ_ANG_REG		0x00
23 #define MMA9551_TILT_YZ_ANG_REG		0x01
24 #define MMA9551_TILT_XY_ANG_REG		0x02
25 #define MMA9551_TILT_ANGFLG		BIT(7)
26 #define MMA9551_TILT_QUAD_REG		0x03
27 #define MMA9551_TILT_XY_QUAD_SHIFT	0
28 #define MMA9551_TILT_YZ_QUAD_SHIFT	2
29 #define MMA9551_TILT_XZ_QUAD_SHIFT	4
30 #define MMA9551_TILT_CFG_REG		0x01
31 #define MMA9551_TILT_ANG_THRESH_MASK	GENMASK(3, 0)
32 
33 #define MMA9551_DEFAULT_SAMPLE_RATE	122	/* Hz */
34 
35 /* Tilt events are mapped to the first three GPIO pins. */
36 enum mma9551_tilt_axis {
37 	mma9551_x = 0,
38 	mma9551_y,
39 	mma9551_z,
40 };
41 
42 struct mma9551_data {
43 	struct i2c_client *client;
44 	struct mutex mutex;
45 	bool event_enabled[3];
46 	int irqs[MMA9551_GPIO_COUNT];
47 };
48 
49 static int mma9551_read_incli_chan(struct i2c_client *client,
50 				   const struct iio_chan_spec *chan,
51 				   int *val)
52 {
53 	u8 quad_shift, angle, quadrant;
54 	u16 reg_addr;
55 	int ret;
56 
57 	switch (chan->channel2) {
58 	case IIO_MOD_X:
59 		reg_addr = MMA9551_TILT_YZ_ANG_REG;
60 		quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT;
61 		break;
62 	case IIO_MOD_Y:
63 		reg_addr = MMA9551_TILT_XZ_ANG_REG;
64 		quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT;
65 		break;
66 	case IIO_MOD_Z:
67 		reg_addr = MMA9551_TILT_XY_ANG_REG;
68 		quad_shift = MMA9551_TILT_XY_QUAD_SHIFT;
69 		break;
70 	default:
71 		return -EINVAL;
72 	}
73 
74 	ret = mma9551_set_power_state(client, true);
75 	if (ret < 0)
76 		return ret;
77 
78 	ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
79 				       reg_addr, &angle);
80 	if (ret < 0)
81 		goto out_poweroff;
82 
83 	ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
84 				       MMA9551_TILT_QUAD_REG, &quadrant);
85 	if (ret < 0)
86 		goto out_poweroff;
87 
88 	angle &= ~MMA9551_TILT_ANGFLG;
89 	quadrant = (quadrant >> quad_shift) & 0x03;
90 
91 	if (quadrant == 1 || quadrant == 3)
92 		*val = 90 * (quadrant + 1) - angle;
93 	else
94 		*val = angle + 90 * quadrant;
95 
96 	ret = IIO_VAL_INT;
97 
98 out_poweroff:
99 	mma9551_set_power_state(client, false);
100 	return ret;
101 }
102 
103 static int mma9551_read_raw(struct iio_dev *indio_dev,
104 			    struct iio_chan_spec const *chan,
105 			    int *val, int *val2, long mask)
106 {
107 	struct mma9551_data *data = iio_priv(indio_dev);
108 	int ret;
109 
110 	switch (mask) {
111 	case IIO_CHAN_INFO_PROCESSED:
112 		switch (chan->type) {
113 		case IIO_INCLI:
114 			mutex_lock(&data->mutex);
115 			ret = mma9551_read_incli_chan(data->client, chan, val);
116 			mutex_unlock(&data->mutex);
117 			return ret;
118 		default:
119 			return -EINVAL;
120 		}
121 	case IIO_CHAN_INFO_RAW:
122 		switch (chan->type) {
123 		case IIO_ACCEL:
124 			mutex_lock(&data->mutex);
125 			ret = mma9551_read_accel_chan(data->client,
126 						      chan, val, val2);
127 			mutex_unlock(&data->mutex);
128 			return ret;
129 		default:
130 			return -EINVAL;
131 		}
132 	case IIO_CHAN_INFO_SCALE:
133 		switch (chan->type) {
134 		case IIO_ACCEL:
135 			return mma9551_read_accel_scale(val, val2);
136 		default:
137 			return -EINVAL;
138 		}
139 	default:
140 		return -EINVAL;
141 	}
142 }
143 
144 static int mma9551_read_event_config(struct iio_dev *indio_dev,
145 				     const struct iio_chan_spec *chan,
146 				     enum iio_event_type type,
147 				     enum iio_event_direction dir)
148 {
149 	struct mma9551_data *data = iio_priv(indio_dev);
150 
151 	switch (chan->type) {
152 	case IIO_INCLI:
153 		/* IIO counts axes from 1, because IIO_NO_MOD is 0. */
154 		return data->event_enabled[chan->channel2 - 1];
155 	default:
156 		return -EINVAL;
157 	}
158 }
159 
160 static int mma9551_config_incli_event(struct iio_dev *indio_dev,
161 				      enum iio_modifier axis,
162 				      bool state)
163 {
164 	struct mma9551_data *data = iio_priv(indio_dev);
165 	enum mma9551_tilt_axis mma_axis;
166 	int ret;
167 
168 	/* IIO counts axes from 1, because IIO_NO_MOD is 0. */
169 	mma_axis = axis - 1;
170 
171 	if (data->event_enabled[mma_axis] == state)
172 		return 0;
173 
174 	if (!state) {
175 		ret = mma9551_gpio_config(data->client,
176 					  (enum mma9551_gpio_pin)mma_axis,
177 					  MMA9551_APPID_NONE, 0, 0);
178 		if (ret < 0)
179 			return ret;
180 
181 		ret = mma9551_set_power_state(data->client, false);
182 		if (ret < 0)
183 			return ret;
184 	} else {
185 		int bitnum;
186 
187 		/* Bit 7 of each angle register holds the angle flag. */
188 		switch (axis) {
189 		case IIO_MOD_X:
190 			bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG;
191 			break;
192 		case IIO_MOD_Y:
193 			bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG;
194 			break;
195 		case IIO_MOD_Z:
196 			bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG;
197 			break;
198 		default:
199 			return -EINVAL;
200 		}
201 
202 
203 		ret = mma9551_set_power_state(data->client, true);
204 		if (ret < 0)
205 			return ret;
206 
207 		ret = mma9551_gpio_config(data->client,
208 					  (enum mma9551_gpio_pin)mma_axis,
209 					  MMA9551_APPID_TILT, bitnum, 0);
210 		if (ret < 0) {
211 			mma9551_set_power_state(data->client, false);
212 			return ret;
213 		}
214 	}
215 
216 	data->event_enabled[mma_axis] = state;
217 
218 	return ret;
219 }
220 
221 static int mma9551_write_event_config(struct iio_dev *indio_dev,
222 				      const struct iio_chan_spec *chan,
223 				      enum iio_event_type type,
224 				      enum iio_event_direction dir,
225 				      bool state)
226 {
227 	struct mma9551_data *data = iio_priv(indio_dev);
228 	int ret;
229 
230 	switch (chan->type) {
231 	case IIO_INCLI:
232 		mutex_lock(&data->mutex);
233 		ret = mma9551_config_incli_event(indio_dev,
234 						 chan->channel2, state);
235 		mutex_unlock(&data->mutex);
236 		return ret;
237 	default:
238 		return -EINVAL;
239 	}
240 }
241 
242 static int mma9551_write_event_value(struct iio_dev *indio_dev,
243 				     const struct iio_chan_spec *chan,
244 				     enum iio_event_type type,
245 				     enum iio_event_direction dir,
246 				     enum iio_event_info info,
247 				     int val, int val2)
248 {
249 	struct mma9551_data *data = iio_priv(indio_dev);
250 	int ret;
251 
252 	switch (chan->type) {
253 	case IIO_INCLI:
254 		if (val2 != 0 || val < 1 || val > 10)
255 			return -EINVAL;
256 		mutex_lock(&data->mutex);
257 		ret = mma9551_update_config_bits(data->client,
258 						 MMA9551_APPID_TILT,
259 						 MMA9551_TILT_CFG_REG,
260 						 MMA9551_TILT_ANG_THRESH_MASK,
261 						 val);
262 		mutex_unlock(&data->mutex);
263 		return ret;
264 	default:
265 		return -EINVAL;
266 	}
267 }
268 
269 static int mma9551_read_event_value(struct iio_dev *indio_dev,
270 				    const struct iio_chan_spec *chan,
271 				    enum iio_event_type type,
272 				    enum iio_event_direction dir,
273 				    enum iio_event_info info,
274 				    int *val, int *val2)
275 {
276 	struct mma9551_data *data = iio_priv(indio_dev);
277 	int ret;
278 	u8 tmp;
279 
280 	switch (chan->type) {
281 	case IIO_INCLI:
282 		mutex_lock(&data->mutex);
283 		ret = mma9551_read_config_byte(data->client,
284 					       MMA9551_APPID_TILT,
285 					       MMA9551_TILT_CFG_REG, &tmp);
286 		mutex_unlock(&data->mutex);
287 		if (ret < 0)
288 			return ret;
289 		*val = tmp & MMA9551_TILT_ANG_THRESH_MASK;
290 		*val2 = 0;
291 		return IIO_VAL_INT;
292 	default:
293 		return -EINVAL;
294 	}
295 }
296 
297 static const struct iio_event_spec mma9551_incli_event = {
298 	.type = IIO_EV_TYPE_ROC,
299 	.dir = IIO_EV_DIR_RISING,
300 	.mask_separate = BIT(IIO_EV_INFO_ENABLE),
301 	.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
302 };
303 
304 #define MMA9551_INCLI_CHANNEL(axis) {				\
305 	.type = IIO_INCLI,					\
306 	.modified = 1,						\
307 	.channel2 = axis,					\
308 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
309 	.event_spec = &mma9551_incli_event,			\
310 	.num_event_specs = 1,					\
311 }
312 
313 static const struct iio_chan_spec mma9551_channels[] = {
314 	MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
315 	MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
316 	MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
317 
318 	MMA9551_INCLI_CHANNEL(IIO_MOD_X),
319 	MMA9551_INCLI_CHANNEL(IIO_MOD_Y),
320 	MMA9551_INCLI_CHANNEL(IIO_MOD_Z),
321 };
322 
323 static const struct iio_info mma9551_info = {
324 	.read_raw = mma9551_read_raw,
325 	.read_event_config = mma9551_read_event_config,
326 	.write_event_config = mma9551_write_event_config,
327 	.read_event_value = mma9551_read_event_value,
328 	.write_event_value = mma9551_write_event_value,
329 };
330 
331 static irqreturn_t mma9551_event_handler(int irq, void *private)
332 {
333 	struct iio_dev *indio_dev = private;
334 	struct mma9551_data *data = iio_priv(indio_dev);
335 	int i, ret, mma_axis = -1;
336 	u16 reg;
337 	u8 val;
338 
339 	mutex_lock(&data->mutex);
340 
341 	for (i = 0; i < 3; i++)
342 		if (irq == data->irqs[i]) {
343 			mma_axis = i;
344 			break;
345 		}
346 
347 	if (mma_axis == -1) {
348 		/* IRQ was triggered on 4th line, which we don't use. */
349 		dev_warn(&data->client->dev,
350 			 "irq triggered on unused line %d\n", data->irqs[3]);
351 		goto out;
352 	}
353 
354 	switch (mma_axis) {
355 	case mma9551_x:
356 		reg = MMA9551_TILT_YZ_ANG_REG;
357 		break;
358 	case mma9551_y:
359 		reg = MMA9551_TILT_XZ_ANG_REG;
360 		break;
361 	case mma9551_z:
362 		reg = MMA9551_TILT_XY_ANG_REG;
363 		break;
364 	}
365 
366 	/*
367 	 * Read the angle even though we don't use it, otherwise we
368 	 * won't get any further interrupts.
369 	 */
370 	ret = mma9551_read_status_byte(data->client, MMA9551_APPID_TILT,
371 				       reg, &val);
372 	if (ret < 0) {
373 		dev_err(&data->client->dev,
374 			"error %d reading tilt register in IRQ\n", ret);
375 		goto out;
376 	}
377 
378 	iio_push_event(indio_dev,
379 		       IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1),
380 					  IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING),
381 		       iio_get_time_ns(indio_dev));
382 
383 out:
384 	mutex_unlock(&data->mutex);
385 
386 	return IRQ_HANDLED;
387 }
388 
389 static int mma9551_init(struct mma9551_data *data)
390 {
391 	int ret;
392 
393 	ret = mma9551_read_version(data->client);
394 	if (ret)
395 		return ret;
396 
397 	return mma9551_set_device_state(data->client, true);
398 }
399 
400 static int mma9551_gpio_probe(struct iio_dev *indio_dev)
401 {
402 	struct gpio_desc *gpio;
403 	int i, ret;
404 	struct mma9551_data *data = iio_priv(indio_dev);
405 	struct device *dev = &data->client->dev;
406 
407 	for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
408 		gpio = devm_gpiod_get_index(dev, NULL, i, GPIOD_IN);
409 		if (IS_ERR(gpio)) {
410 			dev_err(dev, "acpi gpio get index failed\n");
411 			return PTR_ERR(gpio);
412 		}
413 
414 		ret = gpiod_to_irq(gpio);
415 		if (ret < 0)
416 			return ret;
417 
418 		data->irqs[i] = ret;
419 		ret = devm_request_threaded_irq(dev, data->irqs[i],
420 				NULL, mma9551_event_handler,
421 				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
422 				"mma9551_event", indio_dev);
423 		if (ret)
424 			return ret;
425 
426 		dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
427 			desc_to_gpio(gpio), data->irqs[i]);
428 	}
429 
430 	return 0;
431 }
432 
433 static int mma9551_probe(struct i2c_client *client)
434 {
435 	const struct i2c_device_id *id = i2c_client_get_device_id(client);
436 	struct mma9551_data *data;
437 	struct iio_dev *indio_dev;
438 	const char *name = NULL;
439 	int ret;
440 
441 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
442 	if (!indio_dev)
443 		return -ENOMEM;
444 
445 	data = iio_priv(indio_dev);
446 	i2c_set_clientdata(client, indio_dev);
447 	data->client = client;
448 
449 	if (id)
450 		name = id->name;
451 	else
452 		name = iio_get_acpi_device_name(&client->dev);
453 
454 	ret = mma9551_init(data);
455 	if (ret < 0)
456 		return ret;
457 
458 	mutex_init(&data->mutex);
459 
460 	indio_dev->channels = mma9551_channels;
461 	indio_dev->num_channels = ARRAY_SIZE(mma9551_channels);
462 	indio_dev->name = name;
463 	indio_dev->modes = INDIO_DIRECT_MODE;
464 	indio_dev->info = &mma9551_info;
465 
466 	ret = mma9551_gpio_probe(indio_dev);
467 	if (ret < 0)
468 		goto out_poweroff;
469 
470 	ret = pm_runtime_set_active(&client->dev);
471 	if (ret < 0)
472 		goto out_poweroff;
473 
474 	pm_runtime_enable(&client->dev);
475 	pm_runtime_set_autosuspend_delay(&client->dev,
476 					 MMA9551_AUTO_SUSPEND_DELAY_MS);
477 	pm_runtime_use_autosuspend(&client->dev);
478 
479 	ret = iio_device_register(indio_dev);
480 	if (ret < 0) {
481 		dev_err(&client->dev, "unable to register iio device\n");
482 		goto err_pm_cleanup;
483 	}
484 
485 	return 0;
486 
487 err_pm_cleanup:
488 	pm_runtime_dont_use_autosuspend(&client->dev);
489 	pm_runtime_disable(&client->dev);
490 out_poweroff:
491 	mma9551_set_device_state(client, false);
492 
493 	return ret;
494 }
495 
496 static void mma9551_remove(struct i2c_client *client)
497 {
498 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
499 	struct mma9551_data *data = iio_priv(indio_dev);
500 
501 	iio_device_unregister(indio_dev);
502 
503 	pm_runtime_disable(&client->dev);
504 	pm_runtime_set_suspended(&client->dev);
505 
506 	mutex_lock(&data->mutex);
507 	mma9551_set_device_state(data->client, false);
508 	mutex_unlock(&data->mutex);
509 }
510 
511 static int mma9551_runtime_suspend(struct device *dev)
512 {
513 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
514 	struct mma9551_data *data = iio_priv(indio_dev);
515 	int ret;
516 
517 	mutex_lock(&data->mutex);
518 	ret = mma9551_set_device_state(data->client, false);
519 	mutex_unlock(&data->mutex);
520 	if (ret < 0) {
521 		dev_err(&data->client->dev, "powering off device failed\n");
522 		return -EAGAIN;
523 	}
524 
525 	return 0;
526 }
527 
528 static int mma9551_runtime_resume(struct device *dev)
529 {
530 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
531 	struct mma9551_data *data = iio_priv(indio_dev);
532 	int ret;
533 
534 	ret = mma9551_set_device_state(data->client, true);
535 	if (ret < 0)
536 		return ret;
537 
538 	mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE);
539 
540 	return 0;
541 }
542 
543 static int mma9551_suspend(struct device *dev)
544 {
545 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
546 	struct mma9551_data *data = iio_priv(indio_dev);
547 	int ret;
548 
549 	mutex_lock(&data->mutex);
550 	ret = mma9551_set_device_state(data->client, false);
551 	mutex_unlock(&data->mutex);
552 
553 	return ret;
554 }
555 
556 static int mma9551_resume(struct device *dev)
557 {
558 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
559 	struct mma9551_data *data = iio_priv(indio_dev);
560 	int ret;
561 
562 	mutex_lock(&data->mutex);
563 	ret = mma9551_set_device_state(data->client, true);
564 	mutex_unlock(&data->mutex);
565 
566 	return ret;
567 }
568 
569 static const struct dev_pm_ops mma9551_pm_ops = {
570 	SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
571 	RUNTIME_PM_OPS(mma9551_runtime_suspend, mma9551_runtime_resume, NULL)
572 };
573 
574 static const struct acpi_device_id mma9551_acpi_match[] = {
575 	{"MMA9551", 0},
576 	{ }
577 };
578 
579 MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
580 
581 static const struct i2c_device_id mma9551_id[] = {
582 	{ .name = "mma9551" },
583 	{ }
584 };
585 
586 MODULE_DEVICE_TABLE(i2c, mma9551_id);
587 
588 static struct i2c_driver mma9551_driver = {
589 	.driver = {
590 		   .name = "mma9551",
591 		   .acpi_match_table = mma9551_acpi_match,
592 		   .pm = pm_ptr(&mma9551_pm_ops),
593 	},
594 	.probe = mma9551_probe,
595 	.remove = mma9551_remove,
596 	.id_table = mma9551_id,
597 };
598 
599 module_i2c_driver(mma9551_driver);
600 
601 MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
602 MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
603 MODULE_LICENSE("GPL v2");
604 MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");
605 MODULE_IMPORT_NS("IIO_MMA9551");
606