Loading drivers/input/misc/mpu6050.c +267 −58 Original line number Diff line number Diff line Loading @@ -47,11 +47,12 @@ #define MPU6050_GYRO_MIN_VALUE -32768 #define MPU6050_GYRO_MAX_VALUE 32767 #define MPU6050_ACCEL_MIN_POLL_INTERVAL_MS 1 /* Limit mininum delay to 10ms as we do not need higher rate so far */ #define MPU6050_ACCEL_MIN_POLL_INTERVAL_MS 10 #define MPU6050_ACCEL_MAX_POLL_INTERVAL_MS 5000 #define MPU6050_ACCEL_DEFAULT_POLL_INTERVAL_MS 200 #define MPU6050_GYRO_MIN_POLL_INTERVAL_MS 1 #define MPU6050_GYRO_MIN_POLL_INTERVAL_MS 10 #define MPU6050_GYRO_MAX_POLL_INTERVAL_MS 5000 #define MPU6050_GYRO_DEFAULT_POLL_INTERVAL_MS 200 Loading @@ -62,6 +63,8 @@ #define MPU6050_ACCEL_SCALE_SHIFT_2G 4 #define MPU6050_GYRO_SCALE_SHIFT_FS0 3 #define MPU6050_RESET_SLEEP_US 10 #define MPU6050_DEV_NAME_ACCEL "MPU6050-accel" #define MPU6050_DEV_NAME_GYRO "gyroscope" Loading Loading @@ -246,6 +249,8 @@ mpu6050_place_name2num[MPU6050_AXIS_REMAP_TAB_SZ] = { /* Function declarations */ static void mpu6050_pinctrl_state(struct mpu6050_sensor *sensor, bool active); static int mpu6050_set_drdy_int(struct mpu6050_sensor *sensor, bool on); static int mpu6050_power_ctl(struct mpu6050_sensor *sensor, bool on) { Loading Loading @@ -551,18 +556,30 @@ static irqreturn_t mpu6050_interrupt_thread(int irq, void *data) { struct mpu6050_sensor *sensor = data; if (sensor->cfg.accel_enable) { mpu6050_read_accel_data(sensor, &sensor->axis); mpu6050_read_gyro_data(sensor, &sensor->axis); input_report_abs(sensor->accel_dev, ABS_X, sensor->axis.x); input_report_abs(sensor->accel_dev, ABS_Y, sensor->axis.y); input_report_abs(sensor->accel_dev, ABS_Z, sensor->axis.z); mpu6050_remap_accel_data(&sensor->axis, sensor->pdata->place); input_report_abs(sensor->accel_dev, ABS_X, (sensor->axis.x >> MPU6050_ACCEL_SCALE_SHIFT_2G)); input_report_abs(sensor->accel_dev, ABS_Y, (sensor->axis.y >> MPU6050_ACCEL_SCALE_SHIFT_2G)); input_report_abs(sensor->accel_dev, ABS_Z, (sensor->axis.z >> MPU6050_ACCEL_SCALE_SHIFT_2G)); input_sync(sensor->accel_dev); } if (sensor->cfg.gyro_enable) { mpu6050_read_gyro_data(sensor, &sensor->axis); mpu6050_remap_gyro_data(&sensor->axis, sensor->pdata->place); input_report_abs(sensor->gyro_dev, ABS_RX, sensor->axis.rx); input_report_abs(sensor->gyro_dev, ABS_RY, sensor->axis.ry); input_report_abs(sensor->gyro_dev, ABS_RZ, sensor->axis.rz); input_report_abs(sensor->gyro_dev, ABS_RX, (sensor->axis.rx >> MPU6050_GYRO_SCALE_SHIFT_FS0)); input_report_abs(sensor->gyro_dev, ABS_RY, (sensor->axis.ry >> MPU6050_GYRO_SCALE_SHIFT_FS0)); input_report_abs(sensor->gyro_dev, ABS_RZ, (sensor->axis.rz >> MPU6050_GYRO_SCALE_SHIFT_FS0)); input_sync(sensor->gyro_dev); } return IRQ_HANDLED; } Loading Loading @@ -788,7 +805,7 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to get sensor power state ret=%d\n", ret); "Fail to get sensor power state, ret=%d\n", ret); return ret; } Loading @@ -805,11 +822,37 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", ret); "Fail to set sensor power state, ret=%d\n", ret); return ret; } if (!sensor->cfg.int_enabled) { ret = mpu6050_set_drdy_int(sensor, true); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to enable interrupt mode for gyro, ret=%d\n", ret); return ret; } enable_irq(sensor->client->irq); sensor->cfg.int_enabled = true; } sensor->cfg.enable = 1; } else { if (sensor->cfg.int_enabled && !sensor->cfg.accel_enable) { ret = mpu6050_set_drdy_int(sensor, false); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to disable interrupt mode for gyro, ret=%d\n", ret); return ret; } disable_irq(sensor->client->irq); sensor->cfg.int_enabled = false; } ret = mpu6050_switch_engine(sensor, false, BIT_PWR_GYRO_STBY_MASK); if (ret) Loading @@ -821,7 +864,7 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", "Fail to set sensor power state, ret=%d\n", ret); return ret; } Loading @@ -840,11 +883,25 @@ static int mpu6050_restore_context(struct mpu6050_sensor *sensor) struct mpu_reg_map *reg; struct i2c_client *client; int ret; u8 data; u8 data, pwr_ctrl; client = sensor->client; reg = &sensor->reg; /* Save power state and wakeup device from sleep */ ret = i2c_smbus_read_byte_data(client, reg->pwr_mgmt_1); if (ret < 0) { dev_err(&client->dev, "read power ctrl failed.\n"); goto exit; } pwr_ctrl = (u8)ret; ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, BIT_WAKEUP_AFTER_RESET); if (ret < 0) { dev_err(&client->dev, "wakeup sensor failed.\n"); goto exit; } ret = i2c_smbus_write_byte_data(client, reg->gyro_config, sensor->cfg.fsr << GYRO_CONFIG_FSR_SHIFT); if (ret < 0) { Loading Loading @@ -898,9 +955,23 @@ static int mpu6050_restore_context(struct mpu6050_sensor *sensor) } ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, ODR_DLPF_ENA / INIT_FIFO_RATE - 1); sensor->cfg.rate_div); if (ret < 0) { dev_err(&client->dev, "set lpa_freq failed.\n"); dev_err(&client->dev, "set sample_rate_div failed.\n"); goto exit; } ret = i2c_smbus_write_byte_data(client, reg->int_pin_cfg, sensor->cfg.int_pin_cfg); if (ret < 0) { dev_err(&client->dev, "set int_pin_cfg failed.\n"); goto exit; } ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, pwr_ctrl); if (ret < 0) { dev_err(&client->dev, "Write saved power state failed.\n"); goto exit; } Loading Loading @@ -941,7 +1012,7 @@ static void mpu6050_reset_chip(struct mpu6050_sensor *sensor) break; } msleep(MPU6050_RESET_WAIT_MS); usleep(MPU6050_RESET_SLEEP_US); } exit: Loading Loading @@ -980,8 +1051,6 @@ static int mpu6050_gyro_set_enable(struct mpu6050_sensor *sensor, bool enable) if (sensor->use_poll) schedule_delayed_work(&sensor->gyro_poll_work, msecs_to_jiffies(sensor->gyro_poll_ms)); else enable_irq(sensor->client->irq); } else { ret = mpu6050_gyro_enable(sensor, false); if (ret) { Loading @@ -992,8 +1061,6 @@ static int mpu6050_gyro_set_enable(struct mpu6050_sensor *sensor, bool enable) } if (sensor->use_poll) cancel_delayed_work_sync(&sensor->gyro_poll_work); else disable_irq(sensor->client->irq); } Loading @@ -1002,9 +1069,109 @@ exit: return ret; } /* * Configure the sensor interrupt register that allow sensor to * issue interrupt for each new sensor event. */ static int mpu6050_set_drdy_int(struct mpu6050_sensor *sensor, bool on) { int ret; u8 data; if (sensor->cfg.is_asleep) return -EINVAL; if (on) { ret = i2c_smbus_read_byte_data(sensor->client, sensor->reg.int_enable); if (ret < 0) { dev_err(&sensor->client->dev, "Fail read interrupt mode. ret=%d\n", ret); return ret; } data = (u8)ret; data |= BIT_DATA_RDY_EN; ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.int_enable, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set interrupt. ret=%d\n", ret); return ret; } } else { ret = i2c_smbus_read_byte_data(sensor->client, sensor->reg.int_enable); if (ret < 0) { dev_err(&sensor->client->dev, "Fail read interrupt mode. ret=%d\n", ret); return ret; } data = (u8)ret; data &= ~BIT_DATA_RDY_EN; ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.int_enable, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set interrupt. ret=%d\n", ret); return ret; } } return 0; } /* Update sensor sample rate divider upon accel and gyro polling rate. */ static int mpu6050_config_sample_rate(struct mpu6050_sensor *sensor) { int ret; u32 delay_ms; u8 div; if (sensor->cfg.is_asleep) return -EINVAL; if (sensor->accel_poll_ms <= sensor->gyro_poll_ms) delay_ms = sensor->accel_poll_ms; else delay_ms = sensor->gyro_poll_ms; /* Sample_rate = internal_ODR/(1+SMPLRT_DIV) */ if ((sensor->cfg.lpf != MPU_DLPF_256HZ_NOLPF2) && (sensor->cfg.lpf != MPU_DLPF_RESERVED)) { if (delay_ms > DELAY_MS_MAX_DLPF) delay_ms = DELAY_MS_MAX_DLPF; if (delay_ms < DELAY_MS_MIN_DLPF) delay_ms = DELAY_MS_MIN_DLPF; div = (u8)(((ODR_DLPF_ENA * delay_ms) / MSEC_PER_SEC) - 1); } else { if (delay_ms > DELAY_MS_MAX_NODLPF) delay_ms = DELAY_MS_MAX_NODLPF; if (delay_ms < DELAY_MS_MIN_NODLPF) delay_ms = DELAY_MS_MIN_NODLPF; div = (u8)(((ODR_DLPF_DIS * delay_ms) / MSEC_PER_SEC) - 1); } ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.sample_rate_div, div); if (ret < 0) { dev_err(&sensor->client->dev, "Update sample rate divdier fail, ret=%d\n", ret); return ret; } sensor->cfg.rate_div = div; return 0; } static int mpu6050_gyro_set_poll_delay(struct mpu6050_sensor *sensor, unsigned long delay) { int ret; mutex_lock(&sensor->op_lock); if (delay < MPU6050_GYRO_MIN_POLL_INTERVAL_MS) delay = MPU6050_GYRO_MIN_POLL_INTERVAL_MS; Loading @@ -1016,6 +1183,11 @@ static int mpu6050_gyro_set_poll_delay(struct mpu6050_sensor *sensor, cancel_delayed_work_sync(&sensor->gyro_poll_work); schedule_delayed_work(&sensor->gyro_poll_work, msecs_to_jiffies(sensor->gyro_poll_ms)); } else { ret = mpu6050_config_sample_rate(sensor); if (ret < 0) dev_err(&sensor->client->dev, "Unable to set polling delay for gyro!\n"); } mutex_unlock(&sensor->op_lock); return 0; Loading Loading @@ -1150,7 +1322,7 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to get sensor power state ret=%d\n", ret); "Fail to get sensor power state, ret=%d\n", ret); return ret; } Loading @@ -1167,11 +1339,37 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", ret); "Fail to set sensor power state, ret=%d\n", ret); return ret; } if (!sensor->cfg.int_enabled) { ret = mpu6050_set_drdy_int(sensor, true); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to enable interrupt mode for accel, ret=%d\n", ret); return ret; } enable_irq(sensor->client->irq); sensor->cfg.int_enabled = true; } sensor->cfg.enable = 1; } else { if (sensor->cfg.int_enabled && !sensor->cfg.gyro_enable) { ret = mpu6050_set_drdy_int(sensor, false); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to disable interrupt mode for accel, ret=%d\n", ret); return ret; } disable_irq(sensor->client->irq); sensor->cfg.int_enabled = false; } ret = mpu6050_switch_engine(sensor, false, BIT_PWR_ACCEL_STBY_MASK); if (ret) Loading @@ -1184,7 +1382,7 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", "Fail to set sensor power state for accel, ret=%d\n", ret); return ret; } Loading Loading @@ -1227,13 +1425,9 @@ static int mpu6050_accel_set_enable(struct mpu6050_sensor *sensor, bool enable) if (sensor->use_poll) schedule_delayed_work(&sensor->accel_poll_work, msecs_to_jiffies(sensor->accel_poll_ms)); else enable_irq(sensor->client->irq); } else { if (sensor->use_poll) cancel_delayed_work_sync(&sensor->accel_poll_work); else disable_irq(sensor->client->irq); ret = mpu6050_accel_enable(sensor, false); if (ret) { Loading @@ -1253,7 +1447,6 @@ exit: static int mpu6050_accel_set_poll_delay(struct mpu6050_sensor *sensor, unsigned long delay) { u8 divider; int ret; mutex_lock(&sensor->op_lock); Loading @@ -1262,18 +1455,17 @@ static int mpu6050_accel_set_poll_delay(struct mpu6050_sensor *sensor, if (delay > MPU6050_ACCEL_MAX_POLL_INTERVAL_MS) delay = MPU6050_ACCEL_MAX_POLL_INTERVAL_MS; if (sensor->accel_poll_ms != delay) { /* Output frequency divider. and set timer delay */ divider = ODR_DLPF_ENA / INIT_FIFO_RATE - 1; ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.sample_rate_div, divider); if (ret == 0) sensor->accel_poll_ms = delay; } if (sensor->use_poll) { cancel_delayed_work_sync(&sensor->accel_poll_work); schedule_delayed_work(&sensor->accel_poll_work, msecs_to_jiffies(sensor->accel_poll_ms)); } else { ret = mpu6050_config_sample_rate(sensor); if (ret < 0) dev_err(&sensor->client->dev, "Unable to set polling delay for accel!\n"); } mutex_unlock(&sensor->op_lock); return 0; Loading Loading @@ -1495,6 +1687,7 @@ static void setup_mpu6050_reg(struct mpu_reg_map *reg) reg->raw_gyro = REG_RAW_GYRO; reg->raw_accel = REG_RAW_ACCEL; reg->temperature = REG_TEMPERATURE; reg->int_pin_cfg = REG_INT_PIN_CFG; reg->int_enable = REG_INT_ENABLE; reg->int_status = REG_INT_STATUS; reg->pwr_mgmt_1 = REG_PWR_MGMT_1; Loading Loading @@ -1565,6 +1758,7 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) struct mpu_reg_map *reg; struct i2c_client *client; s32 ret; u8 data; if (sensor->cfg.is_asleep) return -EINVAL; Loading @@ -1572,24 +1766,15 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) reg = &sensor->reg; client = sensor->client; /* reset device*/ ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, BIT_H_RESET); mpu6050_reset_chip(sensor); memset(&sensor->cfg, 0, sizeof(struct mpu_chip_config)); /* Wake up from sleep */ ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, BIT_WAKEUP_AFTER_RESET); if (ret < 0) return ret; do { usleep(10); /* check reset complete */ ret = i2c_smbus_read_byte_data(client, reg->pwr_mgmt_1); if (ret < 0) { dev_err(&client->dev, "Failed to read reset status ret =%d\n", ret); return ret; } } while (ret & BIT_H_RESET); memset(&sensor->cfg, 0, sizeof(struct mpu_chip_config)); /* Gyro full scale range configure */ ret = i2c_smbus_write_byte_data(client, reg->gyro_config, Loading @@ -1603,11 +1788,11 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) return ret; sensor->cfg.lpf = MPU_DLPF_42HZ; ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, ODR_DLPF_ENA / INIT_FIFO_RATE - 1); data = (u8)(ODR_DLPF_ENA / INIT_FIFO_RATE - 1); ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, data); if (ret < 0) return ret; sensor->cfg.fifo_rate = INIT_FIFO_RATE; sensor->cfg.rate_div = data; ret = i2c_smbus_write_byte_data(client, reg->accel_config, (ACCEL_FS_02G << ACCL_CONFIG_FSR_SHIFT)); Loading @@ -1615,6 +1800,29 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) return ret; sensor->cfg.accel_fs = ACCEL_FS_02G; if ((sensor->pdata->int_flags & IRQF_TRIGGER_FALLING) || (sensor->pdata->int_flags & IRQF_TRIGGER_LOW)) data = BIT_INT_CFG_DEFAULT | BIT_INT_ACTIVE_LOW; else data = BIT_INT_CFG_DEFAULT; ret = i2c_smbus_write_byte_data(client, reg->int_pin_cfg, data); if (ret < 0) return ret; sensor->cfg.int_pin_cfg = data; /* Put sensor into sleep mode */ ret = i2c_smbus_read_byte_data(client, sensor->reg.pwr_mgmt_1); if (ret < 0) return ret; data = (u8)ret; data |= BIT_SLEEP; ret = i2c_smbus_write_byte_data(client, sensor->reg.pwr_mgmt_1, data); if (ret < 0) return ret; sensor->cfg.gyro_enable = 0; sensor->cfg.gyro_fifo_enable = 0; sensor->cfg.accel_enable = 0; Loading Loading @@ -1926,6 +2134,7 @@ static int mpu6050_probe(struct i2c_client *client, client->irq = 0; goto err_free_gpio; } /* Disable interrupt until event is enabled */ disable_irq(client->irq); } else { sensor->use_poll = 1; Loading drivers/input/misc/mpu6050.h +38 −11 Original line number Diff line number Diff line Loading @@ -32,6 +32,14 @@ #define BIT_ACCEL_OUT 0x08 #define BITS_GYRO_OUT 0x70 #define REG_INT_PIN_CFG 0x37 #define BIT_INT_ACTIVE_LOW 0x80 #define BIT_INT_OPEN_DRAIN 0x40 #define BIT_INT_LATCH_EN 0x20 #define BIT_INT_RD_CLR 0x10 #define BIT_I2C_BYPASS_EN 0x02 #define BIT_INT_CFG_DEFAULT (BIT_INT_LATCH_EN | BIT_INT_RD_CLR) #define REG_INT_ENABLE 0x38 #define BIT_DATA_RDY_EN 0x01 #define BIT_DMP_INT_EN 0x02 Loading @@ -40,10 +48,12 @@ #define BIT_6500_WOM_EN 0x40 #define REG_DMP_INT_STATUS 0x39 #define REG_INT_STATUS 0x3A #define BIT_MOT_INT 0x40 #define BIT_DATA_RDY_INT 0x01 #define BIT_DMP_INT_INT 0x02 #define BIT_ZMOT_INT 0x20 #define BIT_MOT_INT 0x40 #define BIT_6500_WOM_INT 0x40 #define REG_RAW_ACCEL 0x3B #define REG_TEMPERATURE 0x41 Loading @@ -62,8 +72,9 @@ #define BIT_H_RESET 0x80 #define BIT_SLEEP 0x40 #define BIT_CYCLE 0x20 #define BIT_CLK_MASK 0x7 #define BIT_CLK_MASK 0x07 #define BIT_RESET_ALL 0xCF #define BIT_WAKEUP_AFTER_RESET 0x00 #define REG_PWR_MGMT_2 0x6C #define BIT_PWR_ACCEL_STBY_MASK 0x38 Loading @@ -74,9 +85,20 @@ #define REG_FIFO_R_W 0x74 #define REG_WHOAMI 0x75 #define SAMPLE_DIV_MAX 0xFF #define ODR_DLPF_DIS 8000 #define ODR_DLPF_ENA 1000 /* Min delay = MSEC_PER_SEC/ODR_DLPF_ENA */ /* Max delay = MSEC_PER_SEC/(ODR_DLPF_ENA/SAMPLE_DIV_MAX+1) */ #define DELAY_MS_MIN_DLPF 1 #define DELAY_MS_MAX_DLPF 256 /* Min delay = MSEC_PER_SEC/ODR_DLPF_DIS and round up to 1*/ /* Max delay = MSEC_PER_SEC/(ODR_DLPF_DIS/SAMPLE_DIV_MAX+1) */ #define DELAY_MS_MIN_NODLPF 1 #define DELAY_MS_MAX_NODLPF 32 /* device bootup time in millisecond */ #define POWER_UP_TIME_MS 100 /* delay to wait gyro engine stable in millisecond */ Loading Loading @@ -149,9 +171,10 @@ enum inv_devices { * @accel_config: accel config register * @fifo_count_h: Upper byte of FIFO count. * @fifo_r_w: FIFO register. * @raw_gyro Address of first gyro register. * @raw_accl Address of first accel register. * @temperature temperature register * @raw_gyro: Address of first gyro register. * @raw_accl: Address of first accel register. * @temperature: temperature register. * @int_pin_cfg: Interrupt pin and I2C bypass configuration. * @int_enable: Interrupt enable register. * @int_status: Interrupt flags. * @pwr_mgmt_1: Controls chip's power state and clock source. Loading @@ -169,6 +192,7 @@ struct mpu_reg_map { u8 raw_gyro; u8 raw_accel; u8 temperature; u8 int_pin_cfg; u8 int_enable; u8 int_status; u8 pwr_mgmt_1; Loading @@ -189,8 +213,9 @@ struct mpu_reg_map { * @lpa_mod: low power mode. * @tap_on: tap on/off. * @flick_int_on: flick interrupt on/off. * @int_enabled: interrupt is enabled. * @lpa_freq: low power frequency * @fifo_rate: FIFO update rate. * @rate_div: Sampling rate divider. */ struct mpu_chip_config { u32 fsr:2; Loading @@ -205,8 +230,10 @@ struct mpu_chip_config { u32 lpa_mode:1; u32 tap_on:1; u32 flick_int_on:1; u32 int_enabled:1; u8 int_pin_cfg; u16 lpa_freq; u16 fifo_rate; u16 rate_div; }; Loading Loading
drivers/input/misc/mpu6050.c +267 −58 Original line number Diff line number Diff line Loading @@ -47,11 +47,12 @@ #define MPU6050_GYRO_MIN_VALUE -32768 #define MPU6050_GYRO_MAX_VALUE 32767 #define MPU6050_ACCEL_MIN_POLL_INTERVAL_MS 1 /* Limit mininum delay to 10ms as we do not need higher rate so far */ #define MPU6050_ACCEL_MIN_POLL_INTERVAL_MS 10 #define MPU6050_ACCEL_MAX_POLL_INTERVAL_MS 5000 #define MPU6050_ACCEL_DEFAULT_POLL_INTERVAL_MS 200 #define MPU6050_GYRO_MIN_POLL_INTERVAL_MS 1 #define MPU6050_GYRO_MIN_POLL_INTERVAL_MS 10 #define MPU6050_GYRO_MAX_POLL_INTERVAL_MS 5000 #define MPU6050_GYRO_DEFAULT_POLL_INTERVAL_MS 200 Loading @@ -62,6 +63,8 @@ #define MPU6050_ACCEL_SCALE_SHIFT_2G 4 #define MPU6050_GYRO_SCALE_SHIFT_FS0 3 #define MPU6050_RESET_SLEEP_US 10 #define MPU6050_DEV_NAME_ACCEL "MPU6050-accel" #define MPU6050_DEV_NAME_GYRO "gyroscope" Loading Loading @@ -246,6 +249,8 @@ mpu6050_place_name2num[MPU6050_AXIS_REMAP_TAB_SZ] = { /* Function declarations */ static void mpu6050_pinctrl_state(struct mpu6050_sensor *sensor, bool active); static int mpu6050_set_drdy_int(struct mpu6050_sensor *sensor, bool on); static int mpu6050_power_ctl(struct mpu6050_sensor *sensor, bool on) { Loading Loading @@ -551,18 +556,30 @@ static irqreturn_t mpu6050_interrupt_thread(int irq, void *data) { struct mpu6050_sensor *sensor = data; if (sensor->cfg.accel_enable) { mpu6050_read_accel_data(sensor, &sensor->axis); mpu6050_read_gyro_data(sensor, &sensor->axis); input_report_abs(sensor->accel_dev, ABS_X, sensor->axis.x); input_report_abs(sensor->accel_dev, ABS_Y, sensor->axis.y); input_report_abs(sensor->accel_dev, ABS_Z, sensor->axis.z); mpu6050_remap_accel_data(&sensor->axis, sensor->pdata->place); input_report_abs(sensor->accel_dev, ABS_X, (sensor->axis.x >> MPU6050_ACCEL_SCALE_SHIFT_2G)); input_report_abs(sensor->accel_dev, ABS_Y, (sensor->axis.y >> MPU6050_ACCEL_SCALE_SHIFT_2G)); input_report_abs(sensor->accel_dev, ABS_Z, (sensor->axis.z >> MPU6050_ACCEL_SCALE_SHIFT_2G)); input_sync(sensor->accel_dev); } if (sensor->cfg.gyro_enable) { mpu6050_read_gyro_data(sensor, &sensor->axis); mpu6050_remap_gyro_data(&sensor->axis, sensor->pdata->place); input_report_abs(sensor->gyro_dev, ABS_RX, sensor->axis.rx); input_report_abs(sensor->gyro_dev, ABS_RY, sensor->axis.ry); input_report_abs(sensor->gyro_dev, ABS_RZ, sensor->axis.rz); input_report_abs(sensor->gyro_dev, ABS_RX, (sensor->axis.rx >> MPU6050_GYRO_SCALE_SHIFT_FS0)); input_report_abs(sensor->gyro_dev, ABS_RY, (sensor->axis.ry >> MPU6050_GYRO_SCALE_SHIFT_FS0)); input_report_abs(sensor->gyro_dev, ABS_RZ, (sensor->axis.rz >> MPU6050_GYRO_SCALE_SHIFT_FS0)); input_sync(sensor->gyro_dev); } return IRQ_HANDLED; } Loading Loading @@ -788,7 +805,7 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to get sensor power state ret=%d\n", ret); "Fail to get sensor power state, ret=%d\n", ret); return ret; } Loading @@ -805,11 +822,37 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", ret); "Fail to set sensor power state, ret=%d\n", ret); return ret; } if (!sensor->cfg.int_enabled) { ret = mpu6050_set_drdy_int(sensor, true); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to enable interrupt mode for gyro, ret=%d\n", ret); return ret; } enable_irq(sensor->client->irq); sensor->cfg.int_enabled = true; } sensor->cfg.enable = 1; } else { if (sensor->cfg.int_enabled && !sensor->cfg.accel_enable) { ret = mpu6050_set_drdy_int(sensor, false); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to disable interrupt mode for gyro, ret=%d\n", ret); return ret; } disable_irq(sensor->client->irq); sensor->cfg.int_enabled = false; } ret = mpu6050_switch_engine(sensor, false, BIT_PWR_GYRO_STBY_MASK); if (ret) Loading @@ -821,7 +864,7 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", "Fail to set sensor power state, ret=%d\n", ret); return ret; } Loading @@ -840,11 +883,25 @@ static int mpu6050_restore_context(struct mpu6050_sensor *sensor) struct mpu_reg_map *reg; struct i2c_client *client; int ret; u8 data; u8 data, pwr_ctrl; client = sensor->client; reg = &sensor->reg; /* Save power state and wakeup device from sleep */ ret = i2c_smbus_read_byte_data(client, reg->pwr_mgmt_1); if (ret < 0) { dev_err(&client->dev, "read power ctrl failed.\n"); goto exit; } pwr_ctrl = (u8)ret; ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, BIT_WAKEUP_AFTER_RESET); if (ret < 0) { dev_err(&client->dev, "wakeup sensor failed.\n"); goto exit; } ret = i2c_smbus_write_byte_data(client, reg->gyro_config, sensor->cfg.fsr << GYRO_CONFIG_FSR_SHIFT); if (ret < 0) { Loading Loading @@ -898,9 +955,23 @@ static int mpu6050_restore_context(struct mpu6050_sensor *sensor) } ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, ODR_DLPF_ENA / INIT_FIFO_RATE - 1); sensor->cfg.rate_div); if (ret < 0) { dev_err(&client->dev, "set lpa_freq failed.\n"); dev_err(&client->dev, "set sample_rate_div failed.\n"); goto exit; } ret = i2c_smbus_write_byte_data(client, reg->int_pin_cfg, sensor->cfg.int_pin_cfg); if (ret < 0) { dev_err(&client->dev, "set int_pin_cfg failed.\n"); goto exit; } ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, pwr_ctrl); if (ret < 0) { dev_err(&client->dev, "Write saved power state failed.\n"); goto exit; } Loading Loading @@ -941,7 +1012,7 @@ static void mpu6050_reset_chip(struct mpu6050_sensor *sensor) break; } msleep(MPU6050_RESET_WAIT_MS); usleep(MPU6050_RESET_SLEEP_US); } exit: Loading Loading @@ -980,8 +1051,6 @@ static int mpu6050_gyro_set_enable(struct mpu6050_sensor *sensor, bool enable) if (sensor->use_poll) schedule_delayed_work(&sensor->gyro_poll_work, msecs_to_jiffies(sensor->gyro_poll_ms)); else enable_irq(sensor->client->irq); } else { ret = mpu6050_gyro_enable(sensor, false); if (ret) { Loading @@ -992,8 +1061,6 @@ static int mpu6050_gyro_set_enable(struct mpu6050_sensor *sensor, bool enable) } if (sensor->use_poll) cancel_delayed_work_sync(&sensor->gyro_poll_work); else disable_irq(sensor->client->irq); } Loading @@ -1002,9 +1069,109 @@ exit: return ret; } /* * Configure the sensor interrupt register that allow sensor to * issue interrupt for each new sensor event. */ static int mpu6050_set_drdy_int(struct mpu6050_sensor *sensor, bool on) { int ret; u8 data; if (sensor->cfg.is_asleep) return -EINVAL; if (on) { ret = i2c_smbus_read_byte_data(sensor->client, sensor->reg.int_enable); if (ret < 0) { dev_err(&sensor->client->dev, "Fail read interrupt mode. ret=%d\n", ret); return ret; } data = (u8)ret; data |= BIT_DATA_RDY_EN; ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.int_enable, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set interrupt. ret=%d\n", ret); return ret; } } else { ret = i2c_smbus_read_byte_data(sensor->client, sensor->reg.int_enable); if (ret < 0) { dev_err(&sensor->client->dev, "Fail read interrupt mode. ret=%d\n", ret); return ret; } data = (u8)ret; data &= ~BIT_DATA_RDY_EN; ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.int_enable, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set interrupt. ret=%d\n", ret); return ret; } } return 0; } /* Update sensor sample rate divider upon accel and gyro polling rate. */ static int mpu6050_config_sample_rate(struct mpu6050_sensor *sensor) { int ret; u32 delay_ms; u8 div; if (sensor->cfg.is_asleep) return -EINVAL; if (sensor->accel_poll_ms <= sensor->gyro_poll_ms) delay_ms = sensor->accel_poll_ms; else delay_ms = sensor->gyro_poll_ms; /* Sample_rate = internal_ODR/(1+SMPLRT_DIV) */ if ((sensor->cfg.lpf != MPU_DLPF_256HZ_NOLPF2) && (sensor->cfg.lpf != MPU_DLPF_RESERVED)) { if (delay_ms > DELAY_MS_MAX_DLPF) delay_ms = DELAY_MS_MAX_DLPF; if (delay_ms < DELAY_MS_MIN_DLPF) delay_ms = DELAY_MS_MIN_DLPF; div = (u8)(((ODR_DLPF_ENA * delay_ms) / MSEC_PER_SEC) - 1); } else { if (delay_ms > DELAY_MS_MAX_NODLPF) delay_ms = DELAY_MS_MAX_NODLPF; if (delay_ms < DELAY_MS_MIN_NODLPF) delay_ms = DELAY_MS_MIN_NODLPF; div = (u8)(((ODR_DLPF_DIS * delay_ms) / MSEC_PER_SEC) - 1); } ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.sample_rate_div, div); if (ret < 0) { dev_err(&sensor->client->dev, "Update sample rate divdier fail, ret=%d\n", ret); return ret; } sensor->cfg.rate_div = div; return 0; } static int mpu6050_gyro_set_poll_delay(struct mpu6050_sensor *sensor, unsigned long delay) { int ret; mutex_lock(&sensor->op_lock); if (delay < MPU6050_GYRO_MIN_POLL_INTERVAL_MS) delay = MPU6050_GYRO_MIN_POLL_INTERVAL_MS; Loading @@ -1016,6 +1183,11 @@ static int mpu6050_gyro_set_poll_delay(struct mpu6050_sensor *sensor, cancel_delayed_work_sync(&sensor->gyro_poll_work); schedule_delayed_work(&sensor->gyro_poll_work, msecs_to_jiffies(sensor->gyro_poll_ms)); } else { ret = mpu6050_config_sample_rate(sensor); if (ret < 0) dev_err(&sensor->client->dev, "Unable to set polling delay for gyro!\n"); } mutex_unlock(&sensor->op_lock); return 0; Loading Loading @@ -1150,7 +1322,7 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to get sensor power state ret=%d\n", ret); "Fail to get sensor power state, ret=%d\n", ret); return ret; } Loading @@ -1167,11 +1339,37 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", ret); "Fail to set sensor power state, ret=%d\n", ret); return ret; } if (!sensor->cfg.int_enabled) { ret = mpu6050_set_drdy_int(sensor, true); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to enable interrupt mode for accel, ret=%d\n", ret); return ret; } enable_irq(sensor->client->irq); sensor->cfg.int_enabled = true; } sensor->cfg.enable = 1; } else { if (sensor->cfg.int_enabled && !sensor->cfg.gyro_enable) { ret = mpu6050_set_drdy_int(sensor, false); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to disable interrupt mode for accel, ret=%d\n", ret); return ret; } disable_irq(sensor->client->irq); sensor->cfg.int_enabled = false; } ret = mpu6050_switch_engine(sensor, false, BIT_PWR_ACCEL_STBY_MASK); if (ret) Loading @@ -1184,7 +1382,7 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on) sensor->reg.pwr_mgmt_1, data); if (ret < 0) { dev_err(&sensor->client->dev, "Fail to set sensor power state ret=%d\n", "Fail to set sensor power state for accel, ret=%d\n", ret); return ret; } Loading Loading @@ -1227,13 +1425,9 @@ static int mpu6050_accel_set_enable(struct mpu6050_sensor *sensor, bool enable) if (sensor->use_poll) schedule_delayed_work(&sensor->accel_poll_work, msecs_to_jiffies(sensor->accel_poll_ms)); else enable_irq(sensor->client->irq); } else { if (sensor->use_poll) cancel_delayed_work_sync(&sensor->accel_poll_work); else disable_irq(sensor->client->irq); ret = mpu6050_accel_enable(sensor, false); if (ret) { Loading @@ -1253,7 +1447,6 @@ exit: static int mpu6050_accel_set_poll_delay(struct mpu6050_sensor *sensor, unsigned long delay) { u8 divider; int ret; mutex_lock(&sensor->op_lock); Loading @@ -1262,18 +1455,17 @@ static int mpu6050_accel_set_poll_delay(struct mpu6050_sensor *sensor, if (delay > MPU6050_ACCEL_MAX_POLL_INTERVAL_MS) delay = MPU6050_ACCEL_MAX_POLL_INTERVAL_MS; if (sensor->accel_poll_ms != delay) { /* Output frequency divider. and set timer delay */ divider = ODR_DLPF_ENA / INIT_FIFO_RATE - 1; ret = i2c_smbus_write_byte_data(sensor->client, sensor->reg.sample_rate_div, divider); if (ret == 0) sensor->accel_poll_ms = delay; } if (sensor->use_poll) { cancel_delayed_work_sync(&sensor->accel_poll_work); schedule_delayed_work(&sensor->accel_poll_work, msecs_to_jiffies(sensor->accel_poll_ms)); } else { ret = mpu6050_config_sample_rate(sensor); if (ret < 0) dev_err(&sensor->client->dev, "Unable to set polling delay for accel!\n"); } mutex_unlock(&sensor->op_lock); return 0; Loading Loading @@ -1495,6 +1687,7 @@ static void setup_mpu6050_reg(struct mpu_reg_map *reg) reg->raw_gyro = REG_RAW_GYRO; reg->raw_accel = REG_RAW_ACCEL; reg->temperature = REG_TEMPERATURE; reg->int_pin_cfg = REG_INT_PIN_CFG; reg->int_enable = REG_INT_ENABLE; reg->int_status = REG_INT_STATUS; reg->pwr_mgmt_1 = REG_PWR_MGMT_1; Loading Loading @@ -1565,6 +1758,7 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) struct mpu_reg_map *reg; struct i2c_client *client; s32 ret; u8 data; if (sensor->cfg.is_asleep) return -EINVAL; Loading @@ -1572,24 +1766,15 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) reg = &sensor->reg; client = sensor->client; /* reset device*/ ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, BIT_H_RESET); mpu6050_reset_chip(sensor); memset(&sensor->cfg, 0, sizeof(struct mpu_chip_config)); /* Wake up from sleep */ ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1, BIT_WAKEUP_AFTER_RESET); if (ret < 0) return ret; do { usleep(10); /* check reset complete */ ret = i2c_smbus_read_byte_data(client, reg->pwr_mgmt_1); if (ret < 0) { dev_err(&client->dev, "Failed to read reset status ret =%d\n", ret); return ret; } } while (ret & BIT_H_RESET); memset(&sensor->cfg, 0, sizeof(struct mpu_chip_config)); /* Gyro full scale range configure */ ret = i2c_smbus_write_byte_data(client, reg->gyro_config, Loading @@ -1603,11 +1788,11 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) return ret; sensor->cfg.lpf = MPU_DLPF_42HZ; ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, ODR_DLPF_ENA / INIT_FIFO_RATE - 1); data = (u8)(ODR_DLPF_ENA / INIT_FIFO_RATE - 1); ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, data); if (ret < 0) return ret; sensor->cfg.fifo_rate = INIT_FIFO_RATE; sensor->cfg.rate_div = data; ret = i2c_smbus_write_byte_data(client, reg->accel_config, (ACCEL_FS_02G << ACCL_CONFIG_FSR_SHIFT)); Loading @@ -1615,6 +1800,29 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor) return ret; sensor->cfg.accel_fs = ACCEL_FS_02G; if ((sensor->pdata->int_flags & IRQF_TRIGGER_FALLING) || (sensor->pdata->int_flags & IRQF_TRIGGER_LOW)) data = BIT_INT_CFG_DEFAULT | BIT_INT_ACTIVE_LOW; else data = BIT_INT_CFG_DEFAULT; ret = i2c_smbus_write_byte_data(client, reg->int_pin_cfg, data); if (ret < 0) return ret; sensor->cfg.int_pin_cfg = data; /* Put sensor into sleep mode */ ret = i2c_smbus_read_byte_data(client, sensor->reg.pwr_mgmt_1); if (ret < 0) return ret; data = (u8)ret; data |= BIT_SLEEP; ret = i2c_smbus_write_byte_data(client, sensor->reg.pwr_mgmt_1, data); if (ret < 0) return ret; sensor->cfg.gyro_enable = 0; sensor->cfg.gyro_fifo_enable = 0; sensor->cfg.accel_enable = 0; Loading Loading @@ -1926,6 +2134,7 @@ static int mpu6050_probe(struct i2c_client *client, client->irq = 0; goto err_free_gpio; } /* Disable interrupt until event is enabled */ disable_irq(client->irq); } else { sensor->use_poll = 1; Loading
drivers/input/misc/mpu6050.h +38 −11 Original line number Diff line number Diff line Loading @@ -32,6 +32,14 @@ #define BIT_ACCEL_OUT 0x08 #define BITS_GYRO_OUT 0x70 #define REG_INT_PIN_CFG 0x37 #define BIT_INT_ACTIVE_LOW 0x80 #define BIT_INT_OPEN_DRAIN 0x40 #define BIT_INT_LATCH_EN 0x20 #define BIT_INT_RD_CLR 0x10 #define BIT_I2C_BYPASS_EN 0x02 #define BIT_INT_CFG_DEFAULT (BIT_INT_LATCH_EN | BIT_INT_RD_CLR) #define REG_INT_ENABLE 0x38 #define BIT_DATA_RDY_EN 0x01 #define BIT_DMP_INT_EN 0x02 Loading @@ -40,10 +48,12 @@ #define BIT_6500_WOM_EN 0x40 #define REG_DMP_INT_STATUS 0x39 #define REG_INT_STATUS 0x3A #define BIT_MOT_INT 0x40 #define BIT_DATA_RDY_INT 0x01 #define BIT_DMP_INT_INT 0x02 #define BIT_ZMOT_INT 0x20 #define BIT_MOT_INT 0x40 #define BIT_6500_WOM_INT 0x40 #define REG_RAW_ACCEL 0x3B #define REG_TEMPERATURE 0x41 Loading @@ -62,8 +72,9 @@ #define BIT_H_RESET 0x80 #define BIT_SLEEP 0x40 #define BIT_CYCLE 0x20 #define BIT_CLK_MASK 0x7 #define BIT_CLK_MASK 0x07 #define BIT_RESET_ALL 0xCF #define BIT_WAKEUP_AFTER_RESET 0x00 #define REG_PWR_MGMT_2 0x6C #define BIT_PWR_ACCEL_STBY_MASK 0x38 Loading @@ -74,9 +85,20 @@ #define REG_FIFO_R_W 0x74 #define REG_WHOAMI 0x75 #define SAMPLE_DIV_MAX 0xFF #define ODR_DLPF_DIS 8000 #define ODR_DLPF_ENA 1000 /* Min delay = MSEC_PER_SEC/ODR_DLPF_ENA */ /* Max delay = MSEC_PER_SEC/(ODR_DLPF_ENA/SAMPLE_DIV_MAX+1) */ #define DELAY_MS_MIN_DLPF 1 #define DELAY_MS_MAX_DLPF 256 /* Min delay = MSEC_PER_SEC/ODR_DLPF_DIS and round up to 1*/ /* Max delay = MSEC_PER_SEC/(ODR_DLPF_DIS/SAMPLE_DIV_MAX+1) */ #define DELAY_MS_MIN_NODLPF 1 #define DELAY_MS_MAX_NODLPF 32 /* device bootup time in millisecond */ #define POWER_UP_TIME_MS 100 /* delay to wait gyro engine stable in millisecond */ Loading Loading @@ -149,9 +171,10 @@ enum inv_devices { * @accel_config: accel config register * @fifo_count_h: Upper byte of FIFO count. * @fifo_r_w: FIFO register. * @raw_gyro Address of first gyro register. * @raw_accl Address of first accel register. * @temperature temperature register * @raw_gyro: Address of first gyro register. * @raw_accl: Address of first accel register. * @temperature: temperature register. * @int_pin_cfg: Interrupt pin and I2C bypass configuration. * @int_enable: Interrupt enable register. * @int_status: Interrupt flags. * @pwr_mgmt_1: Controls chip's power state and clock source. Loading @@ -169,6 +192,7 @@ struct mpu_reg_map { u8 raw_gyro; u8 raw_accel; u8 temperature; u8 int_pin_cfg; u8 int_enable; u8 int_status; u8 pwr_mgmt_1; Loading @@ -189,8 +213,9 @@ struct mpu_reg_map { * @lpa_mod: low power mode. * @tap_on: tap on/off. * @flick_int_on: flick interrupt on/off. * @int_enabled: interrupt is enabled. * @lpa_freq: low power frequency * @fifo_rate: FIFO update rate. * @rate_div: Sampling rate divider. */ struct mpu_chip_config { u32 fsr:2; Loading @@ -205,8 +230,10 @@ struct mpu_chip_config { u32 lpa_mode:1; u32 tap_on:1; u32 flick_int_on:1; u32 int_enabled:1; u8 int_pin_cfg; u16 lpa_freq; u16 fifo_rate; u16 rate_div; }; Loading