diff options
Diffstat (limited to 'drivers/iio/gyro/itg3200_core.c')
-rw-r--r-- | drivers/iio/gyro/itg3200_core.c | 101 |
1 files changed, 43 insertions, 58 deletions
diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index 8295e318399f..6a8020d48140 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c | |||
@@ -90,6 +90,7 @@ static int itg3200_read_raw(struct iio_dev *indio_dev, | |||
90 | { | 90 | { |
91 | int ret = 0; | 91 | int ret = 0; |
92 | u8 reg; | 92 | u8 reg; |
93 | u8 regval; | ||
93 | 94 | ||
94 | switch (info) { | 95 | switch (info) { |
95 | case IIO_CHAN_INFO_RAW: | 96 | case IIO_CHAN_INFO_RAW: |
@@ -107,65 +108,60 @@ static int itg3200_read_raw(struct iio_dev *indio_dev, | |||
107 | /* Only the temperature channel has an offset */ | 108 | /* Only the temperature channel has an offset */ |
108 | *val = 23000; | 109 | *val = 23000; |
109 | return IIO_VAL_INT; | 110 | return IIO_VAL_INT; |
110 | default: | 111 | case IIO_CHAN_INFO_SAMP_FREQ: |
111 | return -EINVAL; | 112 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, ®val); |
112 | } | 113 | if (ret) |
113 | } | 114 | return ret; |
114 | |||
115 | static ssize_t itg3200_read_frequency(struct device *dev, | ||
116 | struct device_attribute *attr, char *buf) | ||
117 | { | ||
118 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
119 | int ret, sps; | ||
120 | u8 val; | ||
121 | |||
122 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &val); | ||
123 | if (ret) | ||
124 | return ret; | ||
125 | 115 | ||
126 | sps = (val & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000; | 116 | *val = (regval & ITG3200_DLPF_CFG_MASK) ? 1000 : 8000; |
127 | 117 | ||
128 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, &val); | 118 | ret = itg3200_read_reg_8(indio_dev, |
129 | if (ret) | 119 | ITG3200_REG_SAMPLE_RATE_DIV, |
130 | return ret; | 120 | ®val); |
121 | if (ret) | ||
122 | return ret; | ||
131 | 123 | ||
132 | sps /= val + 1; | 124 | *val /= regval + 1; |
125 | return IIO_VAL_INT; | ||
133 | 126 | ||
134 | return sprintf(buf, "%d\n", sps); | 127 | default: |
128 | return -EINVAL; | ||
129 | } | ||
135 | } | 130 | } |
136 | 131 | ||
137 | static ssize_t itg3200_write_frequency(struct device *dev, | 132 | static int itg3200_write_raw(struct iio_dev *indio_dev, |
138 | struct device_attribute *attr, | 133 | struct iio_chan_spec const *chan, |
139 | const char *buf, | 134 | int val, |
140 | size_t len) | 135 | int val2, |
136 | long mask) | ||
141 | { | 137 | { |
142 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
143 | unsigned val; | ||
144 | int ret; | 138 | int ret; |
145 | u8 t; | 139 | u8 t; |
146 | 140 | ||
147 | ret = kstrtouint(buf, 10, &val); | 141 | switch (mask) { |
148 | if (ret) | 142 | case IIO_CHAN_INFO_SAMP_FREQ: |
149 | return ret; | 143 | if (val == 0 || val2 != 0) |
144 | return -EINVAL; | ||
150 | 145 | ||
151 | mutex_lock(&indio_dev->mlock); | 146 | mutex_lock(&indio_dev->mlock); |
152 | 147 | ||
153 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t); | 148 | ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_DLPF, &t); |
154 | if (ret) | 149 | if (ret) { |
155 | goto err_ret; | 150 | mutex_unlock(&indio_dev->mlock); |
151 | return ret; | ||
152 | } | ||
153 | t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1; | ||
156 | 154 | ||
157 | if (val == 0) { | 155 | ret = itg3200_write_reg_8(indio_dev, |
158 | ret = -EINVAL; | 156 | ITG3200_REG_SAMPLE_RATE_DIV, |
159 | goto err_ret; | 157 | t); |
160 | } | ||
161 | t = ((t & ITG3200_DLPF_CFG_MASK) ? 1000u : 8000u) / val - 1; | ||
162 | 158 | ||
163 | ret = itg3200_write_reg_8(indio_dev, ITG3200_REG_SAMPLE_RATE_DIV, t); | 159 | mutex_unlock(&indio_dev->mlock); |
164 | 160 | return ret; | |
165 | err_ret: | ||
166 | mutex_unlock(&indio_dev->mlock); | ||
167 | 161 | ||
168 | return ret ? ret : len; | 162 | default: |
163 | return -EINVAL; | ||
164 | } | ||
169 | } | 165 | } |
170 | 166 | ||
171 | /* | 167 | /* |
@@ -255,6 +251,7 @@ err_ret: | |||
255 | .channel2 = IIO_MOD_ ## _mod, \ | 251 | .channel2 = IIO_MOD_ ## _mod, \ |
256 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ | 252 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
257 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | 253 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
254 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
258 | .address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \ | 255 | .address = ITG3200_REG_GYRO_ ## _mod ## OUT_H, \ |
259 | .scan_index = ITG3200_SCAN_GYRO_ ## _mod, \ | 256 | .scan_index = ITG3200_SCAN_GYRO_ ## _mod, \ |
260 | .scan_type = ITG3200_ST, \ | 257 | .scan_type = ITG3200_ST, \ |
@@ -267,6 +264,7 @@ static const struct iio_chan_spec itg3200_channels[] = { | |||
267 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), | 264 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), |
268 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | | 265 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | |
269 | BIT(IIO_CHAN_INFO_SCALE), | 266 | BIT(IIO_CHAN_INFO_SCALE), |
267 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), | ||
270 | .address = ITG3200_REG_TEMP_OUT_H, | 268 | .address = ITG3200_REG_TEMP_OUT_H, |
271 | .scan_index = ITG3200_SCAN_TEMP, | 269 | .scan_index = ITG3200_SCAN_TEMP, |
272 | .scan_type = ITG3200_ST, | 270 | .scan_type = ITG3200_ST, |
@@ -277,22 +275,9 @@ static const struct iio_chan_spec itg3200_channels[] = { | |||
277 | IIO_CHAN_SOFT_TIMESTAMP(ITG3200_SCAN_ELEMENTS), | 275 | IIO_CHAN_SOFT_TIMESTAMP(ITG3200_SCAN_ELEMENTS), |
278 | }; | 276 | }; |
279 | 277 | ||
280 | /* IIO device attributes */ | ||
281 | static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, itg3200_read_frequency, | ||
282 | itg3200_write_frequency); | ||
283 | |||
284 | static struct attribute *itg3200_attributes[] = { | ||
285 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | ||
286 | NULL | ||
287 | }; | ||
288 | |||
289 | static const struct attribute_group itg3200_attribute_group = { | ||
290 | .attrs = itg3200_attributes, | ||
291 | }; | ||
292 | |||
293 | static const struct iio_info itg3200_info = { | 278 | static const struct iio_info itg3200_info = { |
294 | .attrs = &itg3200_attribute_group, | ||
295 | .read_raw = &itg3200_read_raw, | 279 | .read_raw = &itg3200_read_raw, |
280 | .write_raw = &itg3200_write_raw, | ||
296 | .driver_module = THIS_MODULE, | 281 | .driver_module = THIS_MODULE, |
297 | }; | 282 | }; |
298 | 283 | ||