arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / drivers / iio / accel / adxl345_core.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ADXL345 3-Axis Digital Accelerometer IIO core driver
4  *
5  * Copyright (c) 2017 Eva Rachel Retuya <eraretuya@gmail.com>
6  *
7  * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
8  */
9
10 #include <linux/module.h>
11 #include <linux/property.h>
12 #include <linux/regmap.h>
13 #include <linux/units.h>
14
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17
18 #include "adxl345.h"
19
20 #define ADXL345_REG_DEVID               0x00
21 #define ADXL345_REG_OFSX                0x1e
22 #define ADXL345_REG_OFSY                0x1f
23 #define ADXL345_REG_OFSZ                0x20
24 #define ADXL345_REG_OFS_AXIS(index)     (ADXL345_REG_OFSX + (index))
25 #define ADXL345_REG_BW_RATE             0x2C
26 #define ADXL345_REG_POWER_CTL           0x2D
27 #define ADXL345_REG_DATA_FORMAT         0x31
28 #define ADXL345_REG_DATAX0              0x32
29 #define ADXL345_REG_DATAY0              0x34
30 #define ADXL345_REG_DATAZ0              0x36
31 #define ADXL345_REG_DATA_AXIS(index)    \
32         (ADXL345_REG_DATAX0 + (index) * sizeof(__le16))
33
34 #define ADXL345_BW_RATE                 GENMASK(3, 0)
35 #define ADXL345_BASE_RATE_NANO_HZ       97656250LL
36
37 #define ADXL345_POWER_CTL_MEASURE       BIT(3)
38 #define ADXL345_POWER_CTL_STANDBY       0x00
39
40 #define ADXL345_DATA_FORMAT_FULL_RES    BIT(3) /* Up to 13-bits resolution */
41 #define ADXL345_DATA_FORMAT_2G          0
42 #define ADXL345_DATA_FORMAT_4G          1
43 #define ADXL345_DATA_FORMAT_8G          2
44 #define ADXL345_DATA_FORMAT_16G         3
45
46 #define ADXL345_DEVID                   0xE5
47
48 struct adxl345_data {
49         const struct adxl345_chip_info *info;
50         struct regmap *regmap;
51         u8 data_range;
52 };
53
54 #define ADXL345_CHANNEL(index, axis) {                                  \
55         .type = IIO_ACCEL,                                              \
56         .modified = 1,                                                  \
57         .channel2 = IIO_MOD_##axis,                                     \
58         .address = index,                                               \
59         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |                  \
60                 BIT(IIO_CHAN_INFO_CALIBBIAS),                           \
61         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
62                 BIT(IIO_CHAN_INFO_SAMP_FREQ),                           \
63 }
64
65 static const struct iio_chan_spec adxl345_channels[] = {
66         ADXL345_CHANNEL(0, X),
67         ADXL345_CHANNEL(1, Y),
68         ADXL345_CHANNEL(2, Z),
69 };
70
71 static int adxl345_read_raw(struct iio_dev *indio_dev,
72                             struct iio_chan_spec const *chan,
73                             int *val, int *val2, long mask)
74 {
75         struct adxl345_data *data = iio_priv(indio_dev);
76         __le16 accel;
77         long long samp_freq_nhz;
78         unsigned int regval;
79         int ret;
80
81         switch (mask) {
82         case IIO_CHAN_INFO_RAW:
83                 /*
84                  * Data is stored in adjacent registers:
85                  * ADXL345_REG_DATA(X0/Y0/Z0) contain the least significant byte
86                  * and ADXL345_REG_DATA(X0/Y0/Z0) + 1 the most significant byte
87                  */
88                 ret = regmap_bulk_read(data->regmap,
89                                        ADXL345_REG_DATA_AXIS(chan->address),
90                                        &accel, sizeof(accel));
91                 if (ret < 0)
92                         return ret;
93
94                 *val = sign_extend32(le16_to_cpu(accel), 12);
95                 return IIO_VAL_INT;
96         case IIO_CHAN_INFO_SCALE:
97                 *val = 0;
98                 *val2 = data->info->uscale;
99                 return IIO_VAL_INT_PLUS_MICRO;
100         case IIO_CHAN_INFO_CALIBBIAS:
101                 ret = regmap_read(data->regmap,
102                                   ADXL345_REG_OFS_AXIS(chan->address), &regval);
103                 if (ret < 0)
104                         return ret;
105                 /*
106                  * 8-bit resolution at +/- 2g, that is 4x accel data scale
107                  * factor
108                  */
109                 *val = sign_extend32(regval, 7) * 4;
110
111                 return IIO_VAL_INT;
112         case IIO_CHAN_INFO_SAMP_FREQ:
113                 ret = regmap_read(data->regmap, ADXL345_REG_BW_RATE, &regval);
114                 if (ret < 0)
115                         return ret;
116
117                 samp_freq_nhz = ADXL345_BASE_RATE_NANO_HZ <<
118                                 (regval & ADXL345_BW_RATE);
119                 *val = div_s64_rem(samp_freq_nhz, NANOHZ_PER_HZ, val2);
120
121                 return IIO_VAL_INT_PLUS_NANO;
122         }
123
124         return -EINVAL;
125 }
126
127 static int adxl345_write_raw(struct iio_dev *indio_dev,
128                              struct iio_chan_spec const *chan,
129                              int val, int val2, long mask)
130 {
131         struct adxl345_data *data = iio_priv(indio_dev);
132         s64 n;
133
134         switch (mask) {
135         case IIO_CHAN_INFO_CALIBBIAS:
136                 /*
137                  * 8-bit resolution at +/- 2g, that is 4x accel data scale
138                  * factor
139                  */
140                 return regmap_write(data->regmap,
141                                     ADXL345_REG_OFS_AXIS(chan->address),
142                                     val / 4);
143         case IIO_CHAN_INFO_SAMP_FREQ:
144                 n = div_s64(val * NANOHZ_PER_HZ + val2,
145                             ADXL345_BASE_RATE_NANO_HZ);
146
147                 return regmap_update_bits(data->regmap, ADXL345_REG_BW_RATE,
148                                           ADXL345_BW_RATE,
149                                           clamp_val(ilog2(n), 0,
150                                                     ADXL345_BW_RATE));
151         }
152
153         return -EINVAL;
154 }
155
156 static int adxl345_write_raw_get_fmt(struct iio_dev *indio_dev,
157                                      struct iio_chan_spec const *chan,
158                                      long mask)
159 {
160         switch (mask) {
161         case IIO_CHAN_INFO_CALIBBIAS:
162                 return IIO_VAL_INT;
163         case IIO_CHAN_INFO_SAMP_FREQ:
164                 return IIO_VAL_INT_PLUS_NANO;
165         default:
166                 return -EINVAL;
167         }
168 }
169
170 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
171 "0.09765625 0.1953125 0.390625 0.78125 1.5625 3.125 6.25 12.5 25 50 100 200 400 800 1600 3200"
172 );
173
174 static struct attribute *adxl345_attrs[] = {
175         &iio_const_attr_sampling_frequency_available.dev_attr.attr,
176         NULL
177 };
178
179 static const struct attribute_group adxl345_attrs_group = {
180         .attrs = adxl345_attrs,
181 };
182
183 static const struct iio_info adxl345_info = {
184         .attrs          = &adxl345_attrs_group,
185         .read_raw       = adxl345_read_raw,
186         .write_raw      = adxl345_write_raw,
187         .write_raw_get_fmt      = adxl345_write_raw_get_fmt,
188 };
189
190 static int adxl345_powerup(void *regmap)
191 {
192         return regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_MEASURE);
193 }
194
195 static void adxl345_powerdown(void *regmap)
196 {
197         regmap_write(regmap, ADXL345_REG_POWER_CTL, ADXL345_POWER_CTL_STANDBY);
198 }
199
200 int adxl345_core_probe(struct device *dev, struct regmap *regmap)
201 {
202         struct adxl345_data *data;
203         struct iio_dev *indio_dev;
204         u32 regval;
205         int ret;
206
207         ret = regmap_read(regmap, ADXL345_REG_DEVID, &regval);
208         if (ret < 0)
209                 return dev_err_probe(dev, ret, "Error reading device ID\n");
210
211         if (regval != ADXL345_DEVID)
212                 return dev_err_probe(dev, -ENODEV, "Invalid device ID: %x, expected %x\n",
213                                      regval, ADXL345_DEVID);
214
215         indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
216         if (!indio_dev)
217                 return -ENOMEM;
218
219         data = iio_priv(indio_dev);
220         data->regmap = regmap;
221         /* Enable full-resolution mode */
222         data->data_range = ADXL345_DATA_FORMAT_FULL_RES;
223         data->info = device_get_match_data(dev);
224         if (!data->info)
225                 return -ENODEV;
226
227         ret = regmap_write(data->regmap, ADXL345_REG_DATA_FORMAT,
228                            data->data_range);
229         if (ret < 0)
230                 return dev_err_probe(dev, ret, "Failed to set data range\n");
231
232         indio_dev->name = data->info->name;
233         indio_dev->info = &adxl345_info;
234         indio_dev->modes = INDIO_DIRECT_MODE;
235         indio_dev->channels = adxl345_channels;
236         indio_dev->num_channels = ARRAY_SIZE(adxl345_channels);
237
238         /* Enable measurement mode */
239         ret = adxl345_powerup(data->regmap);
240         if (ret < 0)
241                 return dev_err_probe(dev, ret, "Failed to enable measurement mode\n");
242
243         ret = devm_add_action_or_reset(dev, adxl345_powerdown, data->regmap);
244         if (ret < 0)
245                 return ret;
246
247         return devm_iio_device_register(dev, indio_dev);
248 }
249 EXPORT_SYMBOL_NS_GPL(adxl345_core_probe, IIO_ADXL345);
250
251 MODULE_AUTHOR("Eva Rachel Retuya <eraretuya@gmail.com>");
252 MODULE_DESCRIPTION("ADXL345 3-Axis Digital Accelerometer core driver");
253 MODULE_LICENSE("GPL v2");