From d635711daa98be86d4c7fd01499c34f566b54ccb Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Fri, 10 Jun 2016 05:30:17 -0300 Subject: Linux-libre 4.6.2-gnu --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 458 ++++++++++++----------------- 1 file changed, 196 insertions(+), 262 deletions(-) (limited to 'drivers/iio/imu/inv_mpu6050/inv_mpu_core.c') diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index f0e06093b..d192953e9 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -39,6 +39,26 @@ static const int gyro_scale_6050[] = {133090, 266181, 532362, 1064724}; */ static const int accel_scale[] = {598, 1196, 2392, 4785}; +static const struct inv_mpu6050_reg_map reg_set_6500 = { + .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV, + .lpf = INV_MPU6050_REG_CONFIG, + .user_ctrl = INV_MPU6050_REG_USER_CTRL, + .fifo_en = INV_MPU6050_REG_FIFO_EN, + .gyro_config = INV_MPU6050_REG_GYRO_CONFIG, + .accl_config = INV_MPU6050_REG_ACCEL_CONFIG, + .fifo_count_h = INV_MPU6050_REG_FIFO_COUNT_H, + .fifo_r_w = INV_MPU6050_REG_FIFO_R_W, + .raw_gyro = INV_MPU6050_REG_RAW_GYRO, + .raw_accl = INV_MPU6050_REG_RAW_ACCEL, + .temperature = INV_MPU6050_REG_TEMPERATURE, + .int_enable = INV_MPU6050_REG_INT_ENABLE, + .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, + .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, + .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, + .accl_offset = INV_MPU6500_REG_ACCEL_OFFSET, + .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET, +}; + static const struct inv_mpu6050_reg_map reg_set_6050 = { .sample_rate_div = INV_MPU6050_REG_SAMPLE_RATE_DIV, .lpf = INV_MPU6050_REG_CONFIG, @@ -55,6 +75,8 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = { .pwr_mgmt_1 = INV_MPU6050_REG_PWR_MGMT_1, .pwr_mgmt_2 = INV_MPU6050_REG_PWR_MGMT_2, .int_pin_cfg = INV_MPU6050_REG_INT_PIN_CFG, + .accl_offset = INV_MPU6050_REG_ACCEL_OFFSET, + .gyro_offset = INV_MPU6050_REG_GYRO_OFFSET, }; static const struct inv_mpu6050_chip_config chip_config_6050 = { @@ -66,7 +88,13 @@ static const struct inv_mpu6050_chip_config chip_config_6050 = { .accl_fs = INV_MPU6050_FS_02G, }; -static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = { +static const struct inv_mpu6050_hw hw_info[] = { + { + .num_reg = 117, + .name = "MPU6500", + .reg = ®_set_6500, + .config = &chip_config_6050, + }, { .num_reg = 117, .name = "MPU6050", @@ -75,134 +103,53 @@ static const struct inv_mpu6050_hw hw_info[INV_NUM_PARTS] = { }, }; -int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d) -{ - return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d); -} - -/* - * The i2c read/write needs to happen in unlocked mode. As the parent - * adapter is common. If we use locked versions, it will fail as - * the mux adapter will lock the parent i2c adapter, while calling - * select/deselect functions. - */ -static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st, - u8 reg, u8 d) -{ - int ret; - u8 buf[2]; - struct i2c_msg msg[1] = { - { - .addr = st->client->addr, - .flags = 0, - .len = sizeof(buf), - .buf = buf, - } - }; - - buf[0] = reg; - buf[1] = d; - ret = __i2c_transfer(st->client->adapter, msg, 1); - if (ret != 1) - return ret; - - return 0; -} - -static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv, - u32 chan_id) -{ - struct iio_dev *indio_dev = mux_priv; - struct inv_mpu6050_state *st = iio_priv(indio_dev); - int ret = 0; - - /* Use the same mutex which was used everywhere to protect power-op */ - mutex_lock(&indio_dev->mlock); - if (!st->powerup_count) { - ret = inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1, - 0); - if (ret) - goto write_error; - - msleep(INV_MPU6050_REG_UP_TIME); - } - if (!ret) { - st->powerup_count++; - ret = inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg, - st->client->irq | - INV_MPU6050_BIT_BYPASS_EN); - } -write_error: - mutex_unlock(&indio_dev->mlock); - - return ret; -} - -static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap, - void *mux_priv, u32 chan_id) -{ - struct iio_dev *indio_dev = mux_priv; - struct inv_mpu6050_state *st = iio_priv(indio_dev); - - mutex_lock(&indio_dev->mlock); - /* It doesn't really mattter, if any of the calls fails */ - inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg, - st->client->irq); - st->powerup_count--; - if (!st->powerup_count) - inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1, - INV_MPU6050_BIT_SLEEP); - mutex_unlock(&indio_dev->mlock); - - return 0; -} - int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask) { - u8 d, mgmt_1; + unsigned int d, mgmt_1; int result; - - /* switch clock needs to be careful. Only when gyro is on, can - clock source be switched to gyro. Otherwise, it must be set to - internal clock */ - if (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) { - result = i2c_smbus_read_i2c_block_data(st->client, - st->reg->pwr_mgmt_1, 1, &mgmt_1); - if (result != 1) + /* + * switch clock needs to be careful. Only when gyro is on, can + * clock source be switched to gyro. Otherwise, it must be set to + * internal clock + */ + if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) { + result = regmap_read(st->map, st->reg->pwr_mgmt_1, &mgmt_1); + if (result) return result; mgmt_1 &= ~INV_MPU6050_BIT_CLK_MASK; } - if ((INV_MPU6050_BIT_PWR_GYRO_STBY == mask) && (!en)) { - /* turning off gyro requires switch to internal clock first. - Then turn off gyro engine */ + if ((mask == INV_MPU6050_BIT_PWR_GYRO_STBY) && (!en)) { + /* + * turning off gyro requires switch to internal clock first. + * Then turn off gyro engine + */ mgmt_1 |= INV_CLK_INTERNAL; - result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, mgmt_1); + result = regmap_write(st->map, st->reg->pwr_mgmt_1, mgmt_1); if (result) return result; } - result = i2c_smbus_read_i2c_block_data(st->client, - st->reg->pwr_mgmt_2, 1, &d); - if (result != 1) + result = regmap_read(st->map, st->reg->pwr_mgmt_2, &d); + if (result) return result; if (en) d &= ~mask; else d |= mask; - result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_2, d); + result = regmap_write(st->map, st->reg->pwr_mgmt_2, d); if (result) return result; if (en) { /* Wait for output stabilize */ msleep(INV_MPU6050_TEMP_UP_TIME); - if (INV_MPU6050_BIT_PWR_GYRO_STBY == mask) { + if (mask == INV_MPU6050_BIT_PWR_GYRO_STBY) { /* switch internal clock to PLL */ mgmt_1 |= INV_CLK_PLL; - result = inv_mpu6050_write_reg(st, - st->reg->pwr_mgmt_1, mgmt_1); + result = regmap_write(st->map, + st->reg->pwr_mgmt_1, mgmt_1); if (result) return result; } @@ -218,25 +165,26 @@ int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on) if (power_on) { /* Already under indio-dev->mlock mutex */ if (!st->powerup_count) - result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, - 0); + result = regmap_write(st->map, st->reg->pwr_mgmt_1, 0); if (!result) st->powerup_count++; } else { st->powerup_count--; if (!st->powerup_count) - result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, - INV_MPU6050_BIT_SLEEP); + result = regmap_write(st->map, st->reg->pwr_mgmt_1, + INV_MPU6050_BIT_SLEEP); } if (result) return result; if (power_on) - msleep(INV_MPU6050_REG_UP_TIME); + usleep_range(INV_MPU6050_REG_UP_TIME_MIN, + INV_MPU6050_REG_UP_TIME_MAX); return 0; } +EXPORT_SYMBOL_GPL(inv_mpu6050_set_power_itg); /** * inv_mpu6050_init_config() - Initialize hardware, disable FIFO. @@ -257,59 +205,73 @@ static int inv_mpu6050_init_config(struct iio_dev *indio_dev) if (result) return result; d = (INV_MPU6050_FSR_2000DPS << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT); - result = inv_mpu6050_write_reg(st, st->reg->gyro_config, d); + result = regmap_write(st->map, st->reg->gyro_config, d); if (result) return result; d = INV_MPU6050_FILTER_20HZ; - result = inv_mpu6050_write_reg(st, st->reg->lpf, d); + result = regmap_write(st->map, st->reg->lpf, d); if (result) return result; d = INV_MPU6050_ONE_K_HZ / INV_MPU6050_INIT_FIFO_RATE - 1; - result = inv_mpu6050_write_reg(st, st->reg->sample_rate_div, d); + result = regmap_write(st->map, st->reg->sample_rate_div, d); if (result) return result; d = (INV_MPU6050_FS_02G << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT); - result = inv_mpu6050_write_reg(st, st->reg->accl_config, d); + result = regmap_write(st->map, st->reg->accl_config, d); if (result) return result; memcpy(&st->chip_config, hw_info[st->chip_type].config, - sizeof(struct inv_mpu6050_chip_config)); + sizeof(struct inv_mpu6050_chip_config)); result = inv_mpu6050_set_power_itg(st, false); return result; } +static int inv_mpu6050_sensor_set(struct inv_mpu6050_state *st, int reg, + int axis, int val) +{ + int ind, result; + __be16 d = cpu_to_be16(val); + + ind = (axis - IIO_MOD_X) * 2; + result = regmap_bulk_write(st->map, reg + ind, (u8 *)&d, 2); + if (result) + return -EINVAL; + + return 0; +} + static int inv_mpu6050_sensor_show(struct inv_mpu6050_state *st, int reg, - int axis, int *val) + int axis, int *val) { int ind, result; __be16 d; ind = (axis - IIO_MOD_X) * 2; - result = i2c_smbus_read_i2c_block_data(st->client, reg + ind, 2, - (u8 *)&d); - if (result != 2) + result = regmap_bulk_read(st->map, reg + ind, (u8 *)&d, 2); + if (result) return -EINVAL; *val = (short)be16_to_cpup(&d); return IIO_VAL_INT; } -static int inv_mpu6050_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long mask) { +static int +inv_mpu6050_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ struct inv_mpu6050_state *st = iio_priv(indio_dev); + int ret = 0; switch (mask) { case IIO_CHAN_INFO_RAW: { - int ret, result; + int result; ret = IIO_VAL_INT; result = 0; @@ -323,16 +285,16 @@ static int inv_mpu6050_read_raw(struct iio_dev *indio_dev, switch (chan->type) { case IIO_ANGL_VEL: if (!st->chip_config.gyro_fifo_enable || - !st->chip_config.enable) { + !st->chip_config.enable) { result = inv_mpu6050_switch_engine(st, true, INV_MPU6050_BIT_PWR_GYRO_STBY); if (result) goto error_read_raw; } - ret = inv_mpu6050_sensor_show(st, st->reg->raw_gyro, - chan->channel2, val); + ret = inv_mpu6050_sensor_show(st, st->reg->raw_gyro, + chan->channel2, val); if (!st->chip_config.gyro_fifo_enable || - !st->chip_config.enable) { + !st->chip_config.enable) { result = inv_mpu6050_switch_engine(st, false, INV_MPU6050_BIT_PWR_GYRO_STBY); if (result) @@ -341,16 +303,16 @@ static int inv_mpu6050_read_raw(struct iio_dev *indio_dev, break; case IIO_ACCEL: if (!st->chip_config.accl_fifo_enable || - !st->chip_config.enable) { + !st->chip_config.enable) { result = inv_mpu6050_switch_engine(st, true, INV_MPU6050_BIT_PWR_ACCL_STBY); if (result) goto error_read_raw; } ret = inv_mpu6050_sensor_show(st, st->reg->raw_accl, - chan->channel2, val); + chan->channel2, val); if (!st->chip_config.accl_fifo_enable || - !st->chip_config.enable) { + !st->chip_config.enable) { result = inv_mpu6050_switch_engine(st, false, INV_MPU6050_BIT_PWR_ACCL_STBY); if (result) @@ -360,8 +322,8 @@ static int inv_mpu6050_read_raw(struct iio_dev *indio_dev, case IIO_TEMP: /* wait for stablization */ msleep(INV_MPU6050_SENSOR_UP_TIME); - inv_mpu6050_sensor_show(st, st->reg->temperature, - IIO_MOD_X, val); + ret = inv_mpu6050_sensor_show(st, st->reg->temperature, + IIO_MOD_X, val); break; default: ret = -EINVAL; @@ -405,6 +367,20 @@ error_read_raw: default: return -EINVAL; } + case IIO_CHAN_INFO_CALIBBIAS: + switch (chan->type) { + case IIO_ANGL_VEL: + ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset, + chan->channel2, val); + return IIO_VAL_INT; + case IIO_ACCEL: + ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset, + chan->channel2, val); + return IIO_VAL_INT; + + default: + return -EINVAL; + } default: return -EINVAL; } @@ -418,8 +394,7 @@ static int inv_mpu6050_write_gyro_scale(struct inv_mpu6050_state *st, int val) for (i = 0; i < ARRAY_SIZE(gyro_scale_6050); ++i) { if (gyro_scale_6050[i] == val) { d = (i << INV_MPU6050_GYRO_CONFIG_FSR_SHIFT); - result = inv_mpu6050_write_reg(st, - st->reg->gyro_config, d); + result = regmap_write(st->map, st->reg->gyro_config, d); if (result) return result; @@ -448,6 +423,7 @@ static int inv_write_raw_get_fmt(struct iio_dev *indio_dev, return -EINVAL; } + static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val) { int result, i; @@ -456,8 +432,7 @@ static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val) for (i = 0; i < ARRAY_SIZE(accel_scale); ++i) { if (accel_scale[i] == val) { d = (i << INV_MPU6050_ACCL_CONFIG_FSR_SHIFT); - result = inv_mpu6050_write_reg(st, - st->reg->accl_config, d); + result = regmap_write(st->map, st->reg->accl_config, d); if (result) return result; @@ -470,16 +445,17 @@ static int inv_mpu6050_write_accel_scale(struct inv_mpu6050_state *st, int val) } static int inv_mpu6050_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, - int val2, - long mask) { + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ struct inv_mpu6050_state *st = iio_priv(indio_dev); int result; mutex_lock(&indio_dev->mlock); - /* we should only update scale when the chip is disabled, i.e., - not running */ + /* + * we should only update scale when the chip is disabled, i.e. + * not running + */ if (st->chip_config.enable) { result = -EBUSY; goto error_write_raw; @@ -502,6 +478,21 @@ static int inv_mpu6050_write_raw(struct iio_dev *indio_dev, break; } break; + case IIO_CHAN_INFO_CALIBBIAS: + switch (chan->type) { + case IIO_ANGL_VEL: + result = inv_mpu6050_sensor_set(st, + st->reg->gyro_offset, + chan->channel2, val); + break; + case IIO_ACCEL: + result = inv_mpu6050_sensor_set(st, + st->reg->accl_offset, + chan->channel2, val); + break; + default: + result = -EINVAL; + } default: result = -EINVAL; break; @@ -537,7 +528,7 @@ static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate) while ((h < hz[i]) && (i < ARRAY_SIZE(d) - 1)) i++; data = d[i]; - result = inv_mpu6050_write_reg(st, st->reg->lpf, data); + result = regmap_write(st->map, st->reg->lpf, data); if (result) return result; st->chip_config.lpf = data; @@ -548,8 +539,9 @@ static int inv_mpu6050_set_lpf(struct inv_mpu6050_state *st, int rate) /** * inv_mpu6050_fifo_rate_store() - Set fifo rate. */ -static ssize_t inv_mpu6050_fifo_rate_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t +inv_mpu6050_fifo_rate_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { s32 fifo_rate; u8 d; @@ -560,7 +552,7 @@ static ssize_t inv_mpu6050_fifo_rate_store(struct device *dev, if (kstrtoint(buf, 10, &fifo_rate)) return -EINVAL; if (fifo_rate < INV_MPU6050_MIN_FIFO_RATE || - fifo_rate > INV_MPU6050_MAX_FIFO_RATE) + fifo_rate > INV_MPU6050_MAX_FIFO_RATE) return -EINVAL; if (fifo_rate == st->chip_config.fifo_rate) return count; @@ -575,7 +567,7 @@ static ssize_t inv_mpu6050_fifo_rate_store(struct device *dev, goto fifo_rate_fail; d = INV_MPU6050_ONE_K_HZ / fifo_rate - 1; - result = inv_mpu6050_write_reg(st, st->reg->sample_rate_div, d); + result = regmap_write(st->map, st->reg->sample_rate_div, d); if (result) goto fifo_rate_fail; st->chip_config.fifo_rate = fifo_rate; @@ -596,8 +588,9 @@ fifo_rate_fail: /** * inv_fifo_rate_show() - Get the current sampling rate. */ -static ssize_t inv_fifo_rate_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t +inv_fifo_rate_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev)); @@ -608,16 +601,18 @@ static ssize_t inv_fifo_rate_show(struct device *dev, * inv_attr_show() - calling this function will show current * parameters. */ -static ssize_t inv_attr_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev)); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); s8 *m; switch (this_attr->address) { - /* In MPU6050, the two matrix are the same because gyro and accel - are integrated in one chip */ + /* + * In MPU6050, the two matrix are the same because gyro and accel + * are integrated in one chip + */ case ATTR_GYRO_MATRIX: case ATTR_ACCL_MATRIX: m = st->plat_data.orientation; @@ -654,14 +649,15 @@ static int inv_mpu6050_validate_trigger(struct iio_dev *indio_dev, .type = _type, \ .modified = 1, \ .channel2 = _channel2, \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ .scan_index = _index, \ .scan_type = { \ .sign = 's', \ .realbits = 16, \ .storagebits = 16, \ - .shift = 0 , \ + .shift = 0, \ .endianness = IIO_BE, \ }, \ } @@ -674,7 +670,7 @@ static const struct iio_chan_spec inv_mpu_channels[] = { */ { .type = IIO_TEMP, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), .scan_index = -1, @@ -727,25 +723,25 @@ static const struct iio_info mpu_info = { /** * inv_check_and_setup_chip() - check and setup chip. */ -static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, - const struct i2c_device_id *id) +static int inv_check_and_setup_chip(struct inv_mpu6050_state *st) { int result; - st->chip_type = INV_MPU6050; st->hw = &hw_info[st->chip_type]; st->reg = hw_info[st->chip_type].reg; /* reset to make sure previous state are not there */ - result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, - INV_MPU6050_BIT_H_RESET); + result = regmap_write(st->map, st->reg->pwr_mgmt_1, + INV_MPU6050_BIT_H_RESET); if (result) return result; msleep(INV_MPU6050_POWER_UP_TIME); - /* toggle power state. After reset, the sleep bit could be on - or off depending on the OTP settings. Toggling power would - make it in a definite state as well as making the hardware - state align with the software state */ + /* + * toggle power state. After reset, the sleep bit could be on + * or off depending on the OTP settings. Toggling power would + * make it in a definite state as well as making the hardware + * state align with the software state + */ result = inv_mpu6050_set_power_itg(st, false); if (result) return result; @@ -754,65 +750,59 @@ static int inv_check_and_setup_chip(struct inv_mpu6050_state *st, return result; result = inv_mpu6050_switch_engine(st, false, - INV_MPU6050_BIT_PWR_ACCL_STBY); + INV_MPU6050_BIT_PWR_ACCL_STBY); if (result) return result; result = inv_mpu6050_switch_engine(st, false, - INV_MPU6050_BIT_PWR_GYRO_STBY); + INV_MPU6050_BIT_PWR_GYRO_STBY); if (result) return result; return 0; } -/** - * inv_mpu_probe() - probe function. - * @client: i2c client. - * @id: i2c device id. - * - * Returns 0 on success, a negative error code otherwise. - */ -static int inv_mpu_probe(struct i2c_client *client, - const struct i2c_device_id *id) +int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, + int (*inv_mpu_bus_setup)(struct iio_dev *), int chip_type) { struct inv_mpu6050_state *st; struct iio_dev *indio_dev; struct inv_mpu6050_platform_data *pdata; + struct device *dev = regmap_get_device(regmap); int result; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_I2C_BLOCK)) - return -ENOSYS; - - indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); - st->client = client; + st->chip_type = chip_type; st->powerup_count = 0; - pdata = dev_get_platdata(&client->dev); + st->irq = irq; + st->map = regmap; + pdata = dev_get_platdata(dev); if (pdata) st->plat_data = *pdata; /* power is turned on inside check chip type*/ - result = inv_check_and_setup_chip(st, id); + result = inv_check_and_setup_chip(st); if (result) return result; + if (inv_mpu_bus_setup) + inv_mpu_bus_setup(indio_dev); + result = inv_mpu6050_init_config(indio_dev); if (result) { - dev_err(&client->dev, - "Could not initialize device.\n"); + dev_err(dev, "Could not initialize device.\n"); return result; } - i2c_set_clientdata(client, indio_dev); - indio_dev->dev.parent = &client->dev; - /* id will be NULL when enumerated via ACPI */ - if (id) - indio_dev->name = (char *)id->name; + dev_set_drvdata(dev, indio_dev); + indio_dev->dev.parent = dev; + /* name will be NULL when enumerated via ACPI */ + if (name) + indio_dev->name = name; else - indio_dev->name = (char *)dev_name(&client->dev); + indio_dev->name = dev_name(dev); indio_dev->channels = inv_mpu_channels; indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); @@ -824,13 +814,12 @@ static int inv_mpu_probe(struct i2c_client *client, inv_mpu6050_read_fifo, NULL); if (result) { - dev_err(&st->client->dev, "configure buffer fail %d\n", - result); + dev_err(dev, "configure buffer fail %d\n", result); return result; } result = inv_mpu6050_probe_trigger(indio_dev); if (result) { - dev_err(&st->client->dev, "trigger probe fail %d\n", result); + dev_err(dev, "trigger probe fail %d\n", result); goto out_unreg_ring; } @@ -838,102 +827,47 @@ static int inv_mpu_probe(struct i2c_client *client, spin_lock_init(&st->time_stamp_lock); result = iio_device_register(indio_dev); if (result) { - dev_err(&st->client->dev, "IIO register fail %d\n", result); + dev_err(dev, "IIO register fail %d\n", result); goto out_remove_trigger; } - st->mux_adapter = i2c_add_mux_adapter(client->adapter, - &client->dev, - indio_dev, - 0, 0, 0, - inv_mpu6050_select_bypass, - inv_mpu6050_deselect_bypass); - if (!st->mux_adapter) { - result = -ENODEV; - goto out_unreg_device; - } - - result = inv_mpu_acpi_create_mux_client(st); - if (result) - goto out_del_mux; - return 0; -out_del_mux: - i2c_del_mux_adapter(st->mux_adapter); -out_unreg_device: - iio_device_unregister(indio_dev); out_remove_trigger: inv_mpu6050_remove_trigger(st); out_unreg_ring: iio_triggered_buffer_cleanup(indio_dev); return result; } +EXPORT_SYMBOL_GPL(inv_mpu_core_probe); -static int inv_mpu_remove(struct i2c_client *client) +int inv_mpu_core_remove(struct device *dev) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct inv_mpu6050_state *st = iio_priv(indio_dev); + struct iio_dev *indio_dev = dev_get_drvdata(dev); - inv_mpu_acpi_delete_mux_client(st); - i2c_del_mux_adapter(st->mux_adapter); iio_device_unregister(indio_dev); - inv_mpu6050_remove_trigger(st); + inv_mpu6050_remove_trigger(iio_priv(indio_dev)); iio_triggered_buffer_cleanup(indio_dev); return 0; } +EXPORT_SYMBOL_GPL(inv_mpu_core_remove); + #ifdef CONFIG_PM_SLEEP static int inv_mpu_resume(struct device *dev) { - return inv_mpu6050_set_power_itg( - iio_priv(i2c_get_clientdata(to_i2c_client(dev))), true); + return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), true); } static int inv_mpu_suspend(struct device *dev) { - return inv_mpu6050_set_power_itg( - iio_priv(i2c_get_clientdata(to_i2c_client(dev))), false); + return inv_mpu6050_set_power_itg(iio_priv(dev_get_drvdata(dev)), false); } -static SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume); - -#define INV_MPU6050_PMOPS (&inv_mpu_pmops) -#else -#define INV_MPU6050_PMOPS NULL #endif /* CONFIG_PM_SLEEP */ -/* - * device id table is used to identify what device can be - * supported by this driver - */ -static const struct i2c_device_id inv_mpu_id[] = { - {"mpu6050", INV_MPU6050}, - {"mpu6500", INV_MPU6500}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, inv_mpu_id); - -static const struct acpi_device_id inv_acpi_match[] = { - {"INVN6500", 0}, - { }, -}; - -MODULE_DEVICE_TABLE(acpi, inv_acpi_match); - -static struct i2c_driver inv_mpu_driver = { - .probe = inv_mpu_probe, - .remove = inv_mpu_remove, - .id_table = inv_mpu_id, - .driver = { - .name = "inv-mpu6050", - .pm = INV_MPU6050_PMOPS, - .acpi_match_table = ACPI_PTR(inv_acpi_match), - }, -}; - -module_i2c_driver(inv_mpu_driver); +SIMPLE_DEV_PM_OPS(inv_mpu_pmops, inv_mpu_suspend, inv_mpu_resume); +EXPORT_SYMBOL_GPL(inv_mpu_pmops); MODULE_AUTHOR("Invensense Corporation"); MODULE_DESCRIPTION("Invensense device MPU6050 driver"); -- cgit v1.2.3-54-g00ecf