blob: 9836880cc2d12ec6c1506d285f426d37f48cbea2 [file] [log] [blame]
Tiberiu Breana884ca452015-05-18 14:49:50 +03001/**
2 * Sensortek STK8BA50 3-Axis Accelerometer
3 *
4 * Copyright (c) 2015, Intel Corporation.
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * STK8BA50 7-bit I2C address: 0x18.
11 */
12
13#include <linux/acpi.h>
14#include <linux/i2c.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
19
20#define STK8BA50_REG_XOUT 0x02
21#define STK8BA50_REG_YOUT 0x04
22#define STK8BA50_REG_ZOUT 0x06
23#define STK8BA50_REG_RANGE 0x0F
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +030024#define STK8BA50_REG_BWSEL 0x10
Tiberiu Breana884ca452015-05-18 14:49:50 +030025#define STK8BA50_REG_POWMODE 0x11
26#define STK8BA50_REG_SWRST 0x14
27
28#define STK8BA50_MODE_NORMAL 0
29#define STK8BA50_MODE_SUSPEND 1
30#define STK8BA50_MODE_POWERBIT BIT(7)
31#define STK8BA50_DATA_SHIFT 6
32#define STK8BA50_RESET_CMD 0xB6
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +030033#define STK8BA50_SR_1792HZ_IDX 7
Tiberiu Breana884ca452015-05-18 14:49:50 +030034
35#define STK8BA50_DRIVER_NAME "stk8ba50"
36
37#define STK8BA50_SCALE_AVAIL "0.0384 0.0767 0.1534 0.3069"
38
39/*
40 * The accelerometer has four measurement ranges:
41 * +/-2g; +/-4g; +/-8g; +/-16g
42 *
43 * Acceleration values are 10-bit, 2's complement.
44 * Scales are calculated as following:
45 *
46 * scale1 = (2 + 2) * 9.81 / (2^10 - 1) = 0.0384
47 * scale2 = (4 + 4) * 9.81 / (2^10 - 1) = 0.0767
48 * etc.
49 *
50 * Scales are stored in this format:
51 * { <register value>, <scale value> }
52 *
53 * Locally, the range is stored as a table index.
54 */
Tiberiu Breana003f4882015-06-10 18:07:29 +030055static const struct {
56 u8 reg_val;
57 u32 scale_val;
58} stk8ba50_scale_table[] = {
Tiberiu Breana884ca452015-05-18 14:49:50 +030059 {3, 38400}, {5, 76700}, {8, 153400}, {12, 306900}
60};
61
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +030062/* Sample rates are stored as { <register value>, <Hz value> } */
63static const struct {
64 u8 reg_val;
65 u16 samp_freq;
66} stk8ba50_samp_freq_table[] = {
67 {0x08, 14}, {0x09, 25}, {0x0A, 56}, {0x0B, 112},
68 {0x0C, 224}, {0x0D, 448}, {0x0E, 896}, {0x0F, 1792}
69};
70
Tiberiu Breana884ca452015-05-18 14:49:50 +030071struct stk8ba50_data {
72 struct i2c_client *client;
73 struct mutex lock;
74 int range;
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +030075 u8 sample_rate_idx;
Tiberiu Breana884ca452015-05-18 14:49:50 +030076};
77
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +030078#define STK8BA50_ACCEL_CHANNEL(reg, axis) { \
79 .type = IIO_ACCEL, \
80 .address = reg, \
81 .modified = 1, \
82 .channel2 = IIO_MOD_##axis, \
83 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
84 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
85 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
Tiberiu Breana884ca452015-05-18 14:49:50 +030086}
87
88static const struct iio_chan_spec stk8ba50_channels[] = {
89 STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_XOUT, X),
90 STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_YOUT, Y),
91 STK8BA50_ACCEL_CHANNEL(STK8BA50_REG_ZOUT, Z),
92};
93
94static IIO_CONST_ATTR(in_accel_scale_available, STK8BA50_SCALE_AVAIL);
95
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +030096static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("14 25 56 112 224 448 896 1792");
97
Tiberiu Breana884ca452015-05-18 14:49:50 +030098static struct attribute *stk8ba50_attributes[] = {
99 &iio_const_attr_in_accel_scale_available.dev_attr.attr,
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +0300100 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
Tiberiu Breana884ca452015-05-18 14:49:50 +0300101 NULL,
102};
103
104static const struct attribute_group stk8ba50_attribute_group = {
105 .attrs = stk8ba50_attributes
106};
107
108static int stk8ba50_read_accel(struct stk8ba50_data *data, u8 reg)
109{
110 int ret;
111 struct i2c_client *client = data->client;
112
113 ret = i2c_smbus_read_word_data(client, reg);
114 if (ret < 0) {
115 dev_err(&client->dev, "register read failed\n");
116 return ret;
117 }
118
119 return sign_extend32(ret >> STK8BA50_DATA_SHIFT, 9);
120}
121
122static int stk8ba50_read_raw(struct iio_dev *indio_dev,
123 struct iio_chan_spec const *chan,
124 int *val, int *val2, long mask)
125{
126 struct stk8ba50_data *data = iio_priv(indio_dev);
127
128 switch (mask) {
129 case IIO_CHAN_INFO_RAW:
130 mutex_lock(&data->lock);
131 *val = stk8ba50_read_accel(data, chan->address);
132 mutex_unlock(&data->lock);
133 return IIO_VAL_INT;
134 case IIO_CHAN_INFO_SCALE:
135 *val = 0;
Tiberiu Breana003f4882015-06-10 18:07:29 +0300136 *val2 = stk8ba50_scale_table[data->range].scale_val;
Tiberiu Breana884ca452015-05-18 14:49:50 +0300137 return IIO_VAL_INT_PLUS_MICRO;
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +0300138 case IIO_CHAN_INFO_SAMP_FREQ:
139 *val = stk8ba50_samp_freq_table
140 [data->sample_rate_idx].samp_freq;
141 *val2 = 0;
142 return IIO_VAL_INT;
Tiberiu Breana884ca452015-05-18 14:49:50 +0300143 }
144
145 return -EINVAL;
146}
147
148static int stk8ba50_write_raw(struct iio_dev *indio_dev,
149 struct iio_chan_spec const *chan,
150 int val, int val2, long mask)
151{
152 int ret;
153 int i;
154 int index = -1;
155 struct stk8ba50_data *data = iio_priv(indio_dev);
156
157 switch (mask) {
158 case IIO_CHAN_INFO_SCALE:
159 if (val != 0)
160 return -EINVAL;
161
162 for (i = 0; i < ARRAY_SIZE(stk8ba50_scale_table); i++)
Tiberiu Breana003f4882015-06-10 18:07:29 +0300163 if (val2 == stk8ba50_scale_table[i].scale_val) {
Tiberiu Breana884ca452015-05-18 14:49:50 +0300164 index = i;
165 break;
166 }
167 if (index < 0)
168 return -EINVAL;
169
170 ret = i2c_smbus_write_byte_data(data->client,
171 STK8BA50_REG_RANGE,
Tiberiu Breana003f4882015-06-10 18:07:29 +0300172 stk8ba50_scale_table[index].reg_val);
Tiberiu Breana884ca452015-05-18 14:49:50 +0300173 if (ret < 0)
174 dev_err(&data->client->dev,
175 "failed to set measurement range\n");
176 else
177 data->range = index;
178
179 return ret;
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +0300180 case IIO_CHAN_INFO_SAMP_FREQ:
181 for (i = 0; i < ARRAY_SIZE(stk8ba50_samp_freq_table); i++)
182 if (val == stk8ba50_samp_freq_table[i].samp_freq) {
183 index = i;
184 break;
185 }
186 if (index < 0)
187 return -EINVAL;
188
189 ret = i2c_smbus_write_byte_data(data->client,
190 STK8BA50_REG_BWSEL,
191 stk8ba50_samp_freq_table[index].reg_val);
192 if (ret < 0)
193 dev_err(&data->client->dev,
194 "failed to set sampling rate\n");
195 else
196 data->sample_rate_idx = index;
197
198 return ret;
Tiberiu Breana884ca452015-05-18 14:49:50 +0300199 }
200
201 return -EINVAL;
202}
203
204static const struct iio_info stk8ba50_info = {
205 .driver_module = THIS_MODULE,
206 .read_raw = stk8ba50_read_raw,
207 .write_raw = stk8ba50_write_raw,
208 .attrs = &stk8ba50_attribute_group,
209};
210
211static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode)
212{
213 int ret;
214 u8 masked_reg;
215 struct i2c_client *client = data->client;
216
217 ret = i2c_smbus_read_byte_data(client, STK8BA50_REG_POWMODE);
218 if (ret < 0)
219 goto exit_err;
220
221 if (mode)
222 masked_reg = ret | STK8BA50_MODE_POWERBIT;
223 else
224 masked_reg = ret & (~STK8BA50_MODE_POWERBIT);
225
226 ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE,
227 masked_reg);
228 if (ret < 0)
229 goto exit_err;
230
231 return ret;
232
233exit_err:
234 dev_err(&client->dev, "failed to change sensor mode\n");
235 return ret;
236}
237
238static int stk8ba50_probe(struct i2c_client *client,
239 const struct i2c_device_id *id)
240{
241 int ret;
242 struct iio_dev *indio_dev;
243 struct stk8ba50_data *data;
244
245 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
246 if (!indio_dev) {
247 dev_err(&client->dev, "iio allocation failed!\n");
248 return -ENOMEM;
249 }
250
251 data = iio_priv(indio_dev);
252 data->client = client;
253 i2c_set_clientdata(client, indio_dev);
254 mutex_init(&data->lock);
255
256 indio_dev->dev.parent = &client->dev;
257 indio_dev->info = &stk8ba50_info;
258 indio_dev->name = STK8BA50_DRIVER_NAME;
259 indio_dev->modes = INDIO_DIRECT_MODE;
260 indio_dev->channels = stk8ba50_channels;
261 indio_dev->num_channels = ARRAY_SIZE(stk8ba50_channels);
262
263 /* Reset all registers on startup */
264 ret = i2c_smbus_write_byte_data(client,
265 STK8BA50_REG_SWRST, STK8BA50_RESET_CMD);
266 if (ret < 0) {
267 dev_err(&client->dev, "failed to reset sensor\n");
Tiberiu Breanadb42a9b2015-06-19 17:56:37 +0300268 goto err_power_off;
Tiberiu Breana884ca452015-05-18 14:49:50 +0300269 }
270
271 /* The default range is +/-2g */
272 data->range = 0;
273
Tiberiu Breanaeb2c9ce2015-06-10 18:07:30 +0300274 /* The default sampling rate is 1792 Hz (maximum) */
275 data->sample_rate_idx = STK8BA50_SR_1792HZ_IDX;
276
Tiberiu Breana884ca452015-05-18 14:49:50 +0300277 ret = iio_device_register(indio_dev);
278 if (ret < 0) {
279 dev_err(&client->dev, "device_register failed\n");
Tiberiu Breanadb42a9b2015-06-19 17:56:37 +0300280 goto err_power_off;
Tiberiu Breana884ca452015-05-18 14:49:50 +0300281 }
282
283 return ret;
Tiberiu Breanadb42a9b2015-06-19 17:56:37 +0300284
285err_power_off:
286 stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
287 return ret;
Tiberiu Breana884ca452015-05-18 14:49:50 +0300288}
289
290static int stk8ba50_remove(struct i2c_client *client)
291{
292 struct iio_dev *indio_dev = i2c_get_clientdata(client);
293
294 iio_device_unregister(indio_dev);
295
296 return stk8ba50_set_power(iio_priv(indio_dev), STK8BA50_MODE_SUSPEND);
297}
298
299#ifdef CONFIG_PM_SLEEP
300static int stk8ba50_suspend(struct device *dev)
301{
302 struct stk8ba50_data *data;
303
304 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
305
306 return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
307}
308
309static int stk8ba50_resume(struct device *dev)
310{
311 struct stk8ba50_data *data;
312
313 data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
314
315 return stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
316}
317
318static SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend, stk8ba50_resume);
319
320#define STK8BA50_PM_OPS (&stk8ba50_pm_ops)
321#else
322#define STK8BA50_PM_OPS NULL
323#endif
324
325static const struct i2c_device_id stk8ba50_i2c_id[] = {
326 {"stk8ba50", 0},
327 {}
328};
329
330static const struct acpi_device_id stk8ba50_acpi_id[] = {
331 {"STK8BA50", 0},
332 {}
333};
334
335MODULE_DEVICE_TABLE(acpi, stk8ba50_acpi_id);
336
337static struct i2c_driver stk8ba50_driver = {
338 .driver = {
339 .name = "stk8ba50",
340 .pm = STK8BA50_PM_OPS,
341 .acpi_match_table = ACPI_PTR(stk8ba50_acpi_id),
342 },
343 .probe = stk8ba50_probe,
344 .remove = stk8ba50_remove,
345 .id_table = stk8ba50_i2c_id,
346};
347
348module_i2c_driver(stk8ba50_driver);
349
350MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
351MODULE_DESCRIPTION("STK8BA50 3-Axis Accelerometer driver");
352MODULE_LICENSE("GPL v2");