--- zzzz-none-000/linux-3.10.107/drivers/iio/gyro/itg3200_core.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/iio/gyro/itg3200_core.c 2021-02-04 17:41:59.000000000 +0000 @@ -90,6 +90,7 @@ { int ret = 0; u8 reg; + u8 regval; switch (info) { case IIO_CHAN_INFO_RAW: @@ -107,67 +108,60 @@ /* Only the temperature channel has an offset */ *val = 23000; return IIO_VAL_INT; - default: - return -EINVAL; - } - - return ret; -} - -static ssize_t itg3200_read_frequency(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - int ret, sps; - u8 val; - - ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val); - if (ret) - return ret; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, ®val); + if (ret) + return ret; - sps = (val & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000; + *val = (regval & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000; - ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, &val); - if (ret) - return ret; + ret = itg3200_read_reg_8(indio_dev, + ITG3200_REG_SAMPLE_RATE_DIV, + ®val); + if (ret) + return ret; - sps /= val + 1; + *val /= regval + 1; + return IIO_VAL_INT; - return sprintf(buf, "%d\n", sps); + default: + return -EINVAL; + } } -static ssize_t itg3200_write_frequency(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static int itg3200_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) { - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - unsigned val; int ret; u8 t; - ret = kstrtouint(buf, 10, &val); - if (ret) - return ret; - - mutex_lock(&indio_dev->mlock); + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (val == 0 || val2 != 0) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + + ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t); + if (ret) { + mutex_unlock(&indio_dev->mlock); + return ret; + } + t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1; + + ret = itg3200_write_reg_8(indio_dev, + ITG3200_REG_SAMPLE_RATE_DIV, + t); - ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t); - if (ret) - goto err_ret; + mutex_unlock(&indio_dev->mlock); + return ret; - if (val == 0) { - ret = -EINVAL; - goto err_ret; + default: + return -EINVAL; } - t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1; - - ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t); - -err_ret: - mutex_unlock(&indio_dev->mlock); - - return ret ? ret : len; } /* @@ -229,6 +223,10 @@ int ret; u8 val; + ret = itg3200_reset(indio_dev); + if (ret) + goto err_ret; + ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val); if (ret) goto err_ret; @@ -239,10 +237,6 @@ goto err_ret; } - ret = itg3200_reset(indio_dev); - if (ret) - goto err_ret; - ret = itg3200_enable_full_scale(indio_dev); err_ret: return ret; @@ -257,6 +251,7 @@ .channel2 = IIO_MOD_ ## _mod, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \ .scan_index = ITG3200_SCAN_GYRO_ ## _mod, \ .scan_type = ITG3200_ST, \ @@ -269,6 +264,7 @@ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), .address = ITG3200_REG_TEMP_OUT_H, .scan_index = ITG3200_SCAN_TEMP, .scan_type = ITG3200_ST, @@ -279,22 +275,9 @@ IIO_CHAN_SOFT_TIMESTAMP(ITG3200_SCAN_ELEMENTS), }; -/* IIO device attributes */ -static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, itg3200_read_frequency, - itg3200_write_frequency); - -static struct attribute *itg3200_attributes[] = { - &iio_dev_attr_sampling_frequency.dev_attr.attr, - NULL -}; - -static const struct attribute_group itg3200_attribute_group = { - .attrs = itg3200_attributes, -}; - static const struct iio_info itg3200_info = { - .attrs = &itg3200_attribute_group, .read_raw = &itg3200_read_raw, + .write_raw = &itg3200_write_raw, .driver_module = THIS_MODULE, }; @@ -309,11 +292,9 @@ dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq); - indio_dev = iio_device_alloc(sizeof(*st)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; st = iio_priv(indio_dev); @@ -330,7 +311,7 @@ ret = itg3200_buffer_configure(indio_dev); if (ret) - goto error_free_dev; + return ret; if (client->irq) { ret = itg3200_probe_trigger(indio_dev); @@ -353,9 +334,6 @@ itg3200_remove_trigger(indio_dev); error_unconfigure_buffer: itg3200_buffer_unconfigure(indio_dev); -error_free_dev: - iio_device_free(indio_dev); -error_ret: return ret; } @@ -370,11 +348,29 @@ itg3200_buffer_unconfigure(indio_dev); - iio_device_free(indio_dev); - return 0; } +static int __maybe_unused itg3200_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct itg3200 *st = iio_priv(indio_dev); + + dev_dbg(&st->i2c->dev, "suspend device"); + + return itg3200_write_reg_8(indio_dev, ITG3200_REG_POWER_MANAGEMENT, + ITG3200_SLEEP); +} + +static int __maybe_unused itg3200_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + + return itg3200_initial_setup(indio_dev); +} + +static SIMPLE_DEV_PM_OPS(itg3200_pm_ops, itg3200_suspend, itg3200_resume); + static const struct i2c_device_id itg3200_id[] = { { "itg3200", 0 }, { } @@ -383,8 +379,8 @@ static struct i2c_driver itg3200_driver = { .driver = { - .owner = THIS_MODULE, .name = "itg3200", + .pm = &itg3200_pm_ops, }, .id_table = itg3200_id, .probe = itg3200_probe,