^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * itg3200_buffer.c -- support InvenSense ITG3200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Digital 3-Axis Gyroscope driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/gyro/itg3200.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static int itg3200_read_all_channels(struct i2c_client *i2c, __be16 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u8 tx = 0x80 | ITG3200_REG_TEMP_OUT_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct i2c_msg msg[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .addr = i2c->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) .flags = i2c->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .buf = &tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .addr = i2c->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .flags = i2c->flags | I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .len = ITG3200_SCAN_ELEMENTS * sizeof(s16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .buf = (char *)&buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return i2c_transfer(i2c->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static irqreturn_t itg3200_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct itg3200 *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Ensure correct alignment and padding including for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * timestamp that may be inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) __be16 buf[ITG3200_SCAN_ELEMENTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) s64 ts __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int ret = itg3200_read_all_channels(st->i2c, scan.buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int itg3200_buffer_configure(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) itg3200_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) void itg3200_buffer_unconfigure(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static int itg3200_data_rdy_trigger_set_state(struct iio_trigger *trig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u8 msc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_IRQ_CONFIG, &msc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) msc |= ITG3200_IRQ_DATA_RDY_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) msc &= ~ITG3200_IRQ_DATA_RDY_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_IRQ_CONFIG, msc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const struct iio_trigger_ops itg3200_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .set_trigger_state = &itg3200_data_rdy_trigger_set_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int itg3200_probe_trigger(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct itg3200 *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) st->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!st->trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ret = request_irq(st->i2c->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) &iio_trigger_generic_data_rdy_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) IRQF_TRIGGER_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "itg3200_data_rdy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) goto error_free_trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) st->trig->dev.parent = &st->i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) st->trig->ops = &itg3200_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) iio_trigger_set_drvdata(st->trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ret = iio_trigger_register(st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) goto error_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* select default trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) indio_dev->trig = iio_trigger_get(st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) error_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) free_irq(st->i2c->irq, st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) error_free_trig:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) iio_trigger_free(st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) void itg3200_remove_trigger(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct itg3200 *st = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) iio_trigger_unregister(st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) free_irq(st->i2c->irq, st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) iio_trigger_free(st->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }