GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / iio / accel / dmard10.c
1 /**
2  * IIO driver for the 3-axis accelerometer Domintech ARD10.
3  *
4  * Copyright (c) 2016 Hans de Goede <hdegoede@redhat.com>
5  * Copyright (c) 2012 Domintech Technology Co., Ltd
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms and conditions of the GNU General Public License,
9  * version 2, as published by the Free Software Foundation.
10  */
11
12 #include <linux/module.h>
13 #include <linux/i2c.h>
14 #include <linux/iio/iio.h>
15 #include <linux/iio/sysfs.h>
16 #include <linux/byteorder/generic.h>
17
18 #define DMARD10_REG_ACTR                        0x00
19 #define DMARD10_REG_AFEM                        0x0c
20 #define DMARD10_REG_STADR                       0x12
21 #define DMARD10_REG_STAINT                      0x1c
22 #define DMARD10_REG_MISC2                       0x1f
23 #define DMARD10_REG_PD                          0x21
24
25 #define DMARD10_MODE_OFF                        0x00
26 #define DMARD10_MODE_STANDBY                    0x02
27 #define DMARD10_MODE_ACTIVE                     0x06
28 #define DMARD10_MODE_READ_OTP                   0x12
29 #define DMARD10_MODE_RESET_DATA_PATH            0x82
30
31 /* AFEN set 1, ATM[2:0]=b'000 (normal), EN_Z/Y/X/T=1 */
32 #define DMARD10_VALUE_AFEM_AFEN_NORMAL          0x8f
33 /* ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ) */
34 #define DMARD10_VALUE_CKSEL_ODR_100_204         0x74
35 /* INTC[6:5]=b'00 */
36 #define DMARD10_VALUE_INTC                      0x00
37 /* TAP1/TAP2 Average 2 */
38 #define DMARD10_VALUE_TAPNS_AVE_2               0x11
39
40 #define DMARD10_VALUE_STADR                     0x55
41 #define DMARD10_VALUE_STAINT                    0xaa
42 #define DMARD10_VALUE_MISC2_OSCA_EN             0x08
43 #define DMARD10_VALUE_PD_RST                    0x52
44
45 /* Offsets into the buffer read in dmard10_read_raw() */
46 #define DMARD10_X_OFFSET                        1
47 #define DMARD10_Y_OFFSET                        2
48 #define DMARD10_Z_OFFSET                        3
49
50 /*
51  * a value of + or -128 corresponds to + or - 1G
52  * scale = 9.81 / 128 = 0.076640625
53  */
54
55 static const int dmard10_nscale = 76640625;
56
57 #define DMARD10_CHANNEL(reg, axis) {    \
58         .type = IIO_ACCEL,      \
59         .address = reg, \
60         .modified = 1,  \
61         .channel2 = IIO_MOD_##axis,     \
62         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
63         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
64 }
65
66 static const struct iio_chan_spec dmard10_channels[] = {
67         DMARD10_CHANNEL(DMARD10_X_OFFSET, X),
68         DMARD10_CHANNEL(DMARD10_Y_OFFSET, Y),
69         DMARD10_CHANNEL(DMARD10_Z_OFFSET, Z),
70 };
71
72 struct dmard10_data {
73         struct i2c_client *client;
74 };
75
76 /* Init sequence taken from the android driver */
77 static int dmard10_reset(struct i2c_client *client)
78 {
79         unsigned char buffer[7];
80         int ret;
81
82         /* 1. Powerdown reset */
83         ret = i2c_smbus_write_byte_data(client, DMARD10_REG_PD,
84                                                 DMARD10_VALUE_PD_RST);
85         if (ret < 0)
86                 return ret;
87
88         /*
89          * 2. ACTR => Standby mode => Download OTP to parameter reg =>
90          *    Standby mode => Reset data path => Standby mode
91          */
92         buffer[0] = DMARD10_REG_ACTR;
93         buffer[1] = DMARD10_MODE_STANDBY;
94         buffer[2] = DMARD10_MODE_READ_OTP;
95         buffer[3] = DMARD10_MODE_STANDBY;
96         buffer[4] = DMARD10_MODE_RESET_DATA_PATH;
97         buffer[5] = DMARD10_MODE_STANDBY;
98         ret = i2c_master_send(client, buffer, 6);
99         if (ret < 0)
100                 return ret;
101
102         /* 3. OSCA_EN = 1, TSTO = b'000 (INT1 = normal, TEST0 = normal) */
103         ret = i2c_smbus_write_byte_data(client, DMARD10_REG_MISC2,
104                                                 DMARD10_VALUE_MISC2_OSCA_EN);
105         if (ret < 0)
106                 return ret;
107
108         /* 4. AFEN = 1 (AFE will powerdown after ADC) */
109         buffer[0] = DMARD10_REG_AFEM;
110         buffer[1] = DMARD10_VALUE_AFEM_AFEN_NORMAL;
111         buffer[2] = DMARD10_VALUE_CKSEL_ODR_100_204;
112         buffer[3] = DMARD10_VALUE_INTC;
113         buffer[4] = DMARD10_VALUE_TAPNS_AVE_2;
114         buffer[5] = 0x00; /* DLYC, no delay timing */
115         buffer[6] = 0x07; /* INTD=1 push-pull, INTA=1 active high, AUTOT=1 */
116         ret = i2c_master_send(client, buffer, 7);
117         if (ret < 0)
118                 return ret;
119
120         /* 5. Activation mode */
121         ret = i2c_smbus_write_byte_data(client, DMARD10_REG_ACTR,
122                                                 DMARD10_MODE_ACTIVE);
123         if (ret < 0)
124                 return ret;
125
126         return 0;
127 }
128
129 /* Shutdown sequence taken from the android driver */
130 static int dmard10_shutdown(struct i2c_client *client)
131 {
132         unsigned char buffer[3];
133
134         buffer[0] = DMARD10_REG_ACTR;
135         buffer[1] = DMARD10_MODE_STANDBY;
136         buffer[2] = DMARD10_MODE_OFF;
137
138         return i2c_master_send(client, buffer, 3);
139 }
140
141 static int dmard10_read_raw(struct iio_dev *indio_dev,
142                                 struct iio_chan_spec const *chan,
143                                 int *val, int *val2, long mask)
144 {
145         struct dmard10_data *data = iio_priv(indio_dev);
146         __le16 buf[4];
147         int ret;
148
149         switch (mask) {
150         case IIO_CHAN_INFO_RAW:
151                 /*
152                  * Read 8 bytes starting at the REG_STADR register, trying to
153                  * read the individual X, Y, Z registers will always read 0.
154                  */
155                 ret = i2c_smbus_read_i2c_block_data(data->client,
156                                                     DMARD10_REG_STADR,
157                                                     sizeof(buf), (u8 *)buf);
158                 if (ret < 0)
159                         return ret;
160                 ret = le16_to_cpu(buf[chan->address]);
161                 *val = sign_extend32(ret, 12);
162                 return IIO_VAL_INT;
163         case IIO_CHAN_INFO_SCALE:
164                 *val = 0;
165                 *val2 = dmard10_nscale;
166                 return IIO_VAL_INT_PLUS_NANO;
167         default:
168                 return -EINVAL;
169         }
170 }
171
172 static const struct iio_info dmard10_info = {
173         .read_raw       = dmard10_read_raw,
174 };
175
176 static int dmard10_probe(struct i2c_client *client,
177                         const struct i2c_device_id *id)
178 {
179         int ret;
180         struct iio_dev *indio_dev;
181         struct dmard10_data *data;
182
183         /* These 2 registers have special POR reset values used for id */
184         ret = i2c_smbus_read_byte_data(client, DMARD10_REG_STADR);
185         if (ret != DMARD10_VALUE_STADR)
186                 return (ret < 0) ? ret : -ENODEV;
187
188         ret = i2c_smbus_read_byte_data(client, DMARD10_REG_STAINT);
189         if (ret != DMARD10_VALUE_STAINT)
190                 return (ret < 0) ? ret : -ENODEV;
191
192         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
193         if (!indio_dev) {
194                 dev_err(&client->dev, "iio allocation failed!\n");
195                 return -ENOMEM;
196         }
197
198         data = iio_priv(indio_dev);
199         data->client = client;
200         i2c_set_clientdata(client, indio_dev);
201
202         indio_dev->dev.parent = &client->dev;
203         indio_dev->info = &dmard10_info;
204         indio_dev->name = "dmard10";
205         indio_dev->modes = INDIO_DIRECT_MODE;
206         indio_dev->channels = dmard10_channels;
207         indio_dev->num_channels = ARRAY_SIZE(dmard10_channels);
208
209         ret = dmard10_reset(client);
210         if (ret < 0)
211                 return ret;
212
213         ret = iio_device_register(indio_dev);
214         if (ret < 0) {
215                 dev_err(&client->dev, "device_register failed\n");
216                 dmard10_shutdown(client);
217         }
218
219         return ret;
220 }
221
222 static int dmard10_remove(struct i2c_client *client)
223 {
224         struct iio_dev *indio_dev = i2c_get_clientdata(client);
225
226         iio_device_unregister(indio_dev);
227
228         return dmard10_shutdown(client);
229 }
230
231 #ifdef CONFIG_PM_SLEEP
232 static int dmard10_suspend(struct device *dev)
233 {
234         return dmard10_shutdown(to_i2c_client(dev));
235 }
236
237 static int dmard10_resume(struct device *dev)
238 {
239         return dmard10_reset(to_i2c_client(dev));
240 }
241 #endif
242
243 static SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend, dmard10_resume);
244
245 static const struct i2c_device_id dmard10_i2c_id[] = {
246         {"dmard10", 0},
247         {}
248 };
249 MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id);
250
251 static struct i2c_driver dmard10_driver = {
252         .driver = {
253                 .name = "dmard10",
254                 .pm = &dmard10_pm_ops,
255         },
256         .probe          = dmard10_probe,
257         .remove         = dmard10_remove,
258         .id_table       = dmard10_i2c_id,
259 };
260
261 module_i2c_driver(dmard10_driver);
262
263 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
264 MODULE_DESCRIPTION("Domintech ARD10 3-Axis Accelerometer driver");
265 MODULE_LICENSE("GPL v2");