// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2021 Rockchip Electronics Co., Ltd */ #include "icm40605.h" #include /** * icm40605_set_enable() - enable chip functions. * @indio_dev: Device driver instance. * @enable: enable/disable */ int icm40605_set_enable(struct iio_dev *indio_dev, bool enable) { int ret; struct icm40605_data *data = iio_priv(indio_dev); ret = regmap_write(data->regmap, MPUREG_REG_BANK_SEL, ICM40605_BANK0); if (ret) { dev_err(regmap_get_device(data->regmap), "sel_bank0 fail: %d\n", ret); goto error_off; } if (enable) { ret = icm40605_set_mode(data, ICM40605_ACCEL, true); if (ret) goto error_off; ret = icm40605_set_mode(data, ICM40605_GYRO, true); if (ret) goto error_accl_off; ret = icm40605_reset_fifo(indio_dev); if (ret) goto error_gyro_off; data->standard_period = data->period_divider > 0 ? div_s64(NSEC_PER_MSEC, data->period_divider) : NSEC_PER_MSEC * data->period_divider * (-1); data->interrupt_period = data->standard_period; data->period_min = div_s64((data->standard_period * (100 - INV_MPU6050_TS_PERIOD_JITTER)), 100); data->period_max = div_s64((data->standard_period * (100 + INV_MPU6050_TS_PERIOD_JITTER)), 100); } else { ret = regmap_write(data->regmap, MPUREG_FIFO_CONFIG_REG, BIT_FIFO_MODE_CTRL_BYPASS); if (ret) { dev_err(regmap_get_device(data->regmap), "set MPUREG_FIFO_CONFIG_REG fail: %d\n", ret); goto error_gyro_off; } ret = icm40605_set_mode(data, ICM40605_GYRO, false); if (ret) goto error_gyro_off; ret = icm40605_set_mode(data, ICM40605_ACCEL, false); if (ret) goto error_accl_off; } dev_info(regmap_get_device(data->regmap), "set fifo mode end\n"); return ret; error_gyro_off: icm40605_set_mode(data, ICM40605_GYRO, false); error_accl_off: icm40605_set_mode(data, ICM40605_ACCEL, false); error_off: return ret; } /** * inv_mpu_data_rdy_trigger_set_state() - set data ready interrupt state * @trig: Trigger instance * @state: Desired trigger state */ static int inv_mpu_data_rdy_trigger_set_state(struct iio_trigger *trig, bool state) { struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct icm40605_data *data = iio_priv(indio_dev); int result; mutex_lock(&data->lock); dev_info(regmap_get_device(data->regmap), "in data_rdy_trigger_set_state, %d\n", state); result = icm40605_set_enable(indio_dev, state); mutex_unlock(&data->lock); return result; } static const struct iio_trigger_ops inv_mpu_trigger_ops = { .set_trigger_state = &inv_mpu_data_rdy_trigger_set_state, }; int icm40605_probe_trigger(struct iio_dev *indio_dev, int irq_type) { int ret; struct icm40605_data *data = iio_priv(indio_dev); data->trig = devm_iio_trigger_alloc(&indio_dev->dev, "%s-dev%d", indio_dev->name, indio_dev->id); if (!data->trig) return -ENOMEM; ret = devm_request_irq(&indio_dev->dev, data->irq, &iio_trigger_generic_data_rdy_poll, irq_type, "inv_mpu", data->trig); if (ret) return ret; data->trig->dev.parent = regmap_get_device(data->regmap); data->trig->ops = &inv_mpu_trigger_ops; iio_trigger_set_drvdata(data->trig, indio_dev); ret = devm_iio_trigger_register(&indio_dev->dev, data->trig); if (ret) return ret; indio_dev->trig = iio_trigger_get(data->trig); return 0; }