aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/gyro/itg3200_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/gyro/itg3200_core.c')
-rw-r--r--drivers/iio/gyro/itg3200_core.c101
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, &regval);
112 } 113 if (ret)
113} 114 return ret;
114
115static 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 &regval);
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
137static ssize_t itg3200_write_frequency(struct device *dev, 132static 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;
165err_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 */
281static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, itg3200_read_frequency,
282 itg3200_write_frequency);
283
284static struct attribute *itg3200_attributes[] = {
285 &iio_dev_attr_sampling_frequency.dev_attr.attr,
286 NULL
287};
288
289static const struct attribute_group itg3200_attribute_group = {
290 .attrs = itg3200_attributes,
291};
292
293static const struct iio_info itg3200_info = { 278static 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