1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Driver for the Infineon TLV493D Low-Power 3D Magnetic Sensor
4 *
5 * Copyright (C) 2025 Dixit Parmar <dixitparmar19@gmail.com>
6 */
7
8 #include <linux/array_size.h>
9 #include <linux/bits.h>
10 #include <linux/bitfield.h>
11 #include <linux/cleanup.h>
12 #include <linux/delay.h>
13 #include <linux/dev_printk.h>
14 #include <linux/i2c.h>
15 #include <linux/iopoll.h>
16 #include <linux/module.h>
17 #include <linux/pm.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/types.h>
21 #include <linux/units.h>
22
23 #include <linux/iio/buffer.h>
24 #include <linux/iio/iio.h>
25 #include <linux/iio/trigger_consumer.h>
26 #include <linux/iio/triggered_buffer.h>
27
28 /*
29 * TLV493D sensor I2C communication note:
30 *
31 * The sensor supports only direct byte-stream write starting from the
32 * register address 0x0. So for any modification to be made to any write
33 * registers, it must be written starting from the register address 0x0.
34 * I2C write operation should not contain the register address in the I2C
35 * frame, it should contain only raw byte stream for the write registers.
36 * I2C Frame: |S|SlaveAddr Wr|Ack|Byte[0]|Ack|Byte[1]|Ack|.....|Sp|
37 *
38 * Same as the write operation, reading from the sensor registers is also
39 * performed starting from the register address 0x0 for as many bytes as
40 * need to be read.
41 * I2C read operation should not contain the register address in the I2C frame.
42 * I2C Frame: |S|SlaveAddr Rd|Ack|Byte[0]|Ack|Byte[1]|Ack|.....|Sp|
43 */
44
45 #define TLV493D_RD_REG_BX 0x00
46 #define TLV493D_RD_REG_BY 0x01
47 #define TLV493D_RD_REG_BZ 0x02
48 #define TLV493D_RD_REG_TEMP 0x03
49 #define TLV493D_RD_REG_BX2 0x04
50 #define TLV493D_RD_REG_BZ2 0x05
51 #define TLV493D_RD_REG_TEMP2 0x06
52 #define TLV493D_RD_REG_RES1 0x07
53 #define TLV493D_RD_REG_RES2 0x08
54 #define TLV493D_RD_REG_RES3 0x09
55 #define TLV493D_RD_REG_MAX 0x0a
56
57 #define TLV493D_WR_REG_MODE1 0x01
58 #define TLV493D_WR_REG_MODE2 0x03
59 #define TLV493D_WR_REG_MAX 0x04
60
61 #define TLV493D_BX_MAG_X_AXIS_MSB GENMASK(7, 0)
62 #define TLV493D_BX2_MAG_X_AXIS_LSB GENMASK(7, 4)
63 #define TLV493D_BY_MAG_Y_AXIS_MSB GENMASK(7, 0)
64 #define TLV493D_BX2_MAG_Y_AXIS_LSB GENMASK(3, 0)
65 #define TLV493D_BZ_MAG_Z_AXIS_MSB GENMASK(7, 0)
66 #define TLV493D_BZ2_MAG_Z_AXIS_LSB GENMASK(3, 0)
67 #define TLV493D_TEMP_TEMP_MSB GENMASK(7, 4)
68 #define TLV493D_TEMP2_TEMP_LSB GENMASK(7, 0)
69 #define TLV493D_TEMP_CHANNEL GENMASK(1, 0)
70 #define TLV493D_MODE1_MOD_LOWFAST GENMASK(1, 0)
71 #define TLV493D_MODE2_LP_PERIOD BIT(6)
72 #define TLV493D_RD_REG_RES1_WR_MASK GENMASK(4, 3)
73 #define TLV493D_RD_REG_RES2_WR_MASK GENMASK(7, 0)
74 #define TLV493D_RD_REG_RES3_WR_MASK GENMASK(4, 0)
75
76 enum tlv493d_channels {
77 TLV493D_AXIS_X,
78 TLV493D_AXIS_Y,
79 TLV493D_AXIS_Z,
80 TLV493D_TEMPERATURE,
81 };
82
83 enum tlv493d_op_mode {
84 TLV493D_OP_MODE_POWERDOWN,
85 TLV493D_OP_MODE_FAST,
86 TLV493D_OP_MODE_LOWPOWER,
87 TLV493D_OP_MODE_ULTRA_LOWPOWER,
88 TLV493D_OP_MODE_MASTERCONTROLLED,
89 };
90
91 struct tlv493d_data {
92 struct i2c_client *client;
93 /* protects from simultaneous sensor access and register readings */
94 struct mutex lock;
95 enum tlv493d_op_mode mode;
96 u8 wr_regs[TLV493D_WR_REG_MAX];
97 };
98
99 /*
100 * Different mode has different measurement sampling time, this time is
101 * used in deriving the sleep and timeout while reading the data from
102 * sensor in polling.
103 * Power-down mode: No measurement.
104 * Fast mode: Freq:3.3 KHz. Measurement time:305 usec.
105 * Low-power mode: Freq:100 Hz. Measurement time:10 msec.
106 * Ultra low-power mode: Freq:10 Hz. Measurement time:100 msec.
107 * Master controlled mode: Freq:3.3 Khz. Measurement time:305 usec.
108 */
109 static const u32 tlv493d_sample_rate_us[] = {
110 [TLV493D_OP_MODE_POWERDOWN] = 0,
111 [TLV493D_OP_MODE_FAST] = 305,
112 [TLV493D_OP_MODE_LOWPOWER] = 10 * USEC_PER_MSEC,
113 [TLV493D_OP_MODE_ULTRA_LOWPOWER] = 100 * USEC_PER_MSEC,
114 [TLV493D_OP_MODE_MASTERCONTROLLED] = 305,
115 };
116
tlv493d_write_all_regs(struct tlv493d_data * data)117 static int tlv493d_write_all_regs(struct tlv493d_data *data)
118 {
119 int ret;
120 struct device *dev = &data->client->dev;
121
122 ret = i2c_master_send(data->client, data->wr_regs, ARRAY_SIZE(data->wr_regs));
123 if (ret < 0) {
124 dev_err(dev, "i2c write registers failed, error: %d\n", ret);
125 return ret;
126 }
127
128 return 0;
129 }
130
tlv493d_set_operating_mode(struct tlv493d_data * data,enum tlv493d_op_mode mode)131 static int tlv493d_set_operating_mode(struct tlv493d_data *data, enum tlv493d_op_mode mode)
132 {
133 u8 *mode1_cfg = &data->wr_regs[TLV493D_WR_REG_MODE1];
134 u8 *mode2_cfg = &data->wr_regs[TLV493D_WR_REG_MODE2];
135
136 switch (mode) {
137 case TLV493D_OP_MODE_POWERDOWN:
138 FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 0);
139 FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
140 break;
141
142 case TLV493D_OP_MODE_FAST:
143 FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 1);
144 FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
145 break;
146
147 case TLV493D_OP_MODE_LOWPOWER:
148 FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 2);
149 FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 1);
150 break;
151
152 case TLV493D_OP_MODE_ULTRA_LOWPOWER:
153 FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 2);
154 FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
155 break;
156
157 case TLV493D_OP_MODE_MASTERCONTROLLED:
158 FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 3);
159 FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
160 break;
161 }
162
163 return tlv493d_write_all_regs(data);
164 }
165
tlv493d_get_channel_data(u8 * b,enum tlv493d_channels ch)166 static s16 tlv493d_get_channel_data(u8 *b, enum tlv493d_channels ch)
167 {
168 u16 val;
169
170 switch (ch) {
171 case TLV493D_AXIS_X:
172 val = FIELD_GET(TLV493D_BX_MAG_X_AXIS_MSB, b[TLV493D_RD_REG_BX]) << 4 |
173 FIELD_GET(TLV493D_BX2_MAG_X_AXIS_LSB, b[TLV493D_RD_REG_BX2]);
174 break;
175 case TLV493D_AXIS_Y:
176 val = FIELD_GET(TLV493D_BY_MAG_Y_AXIS_MSB, b[TLV493D_RD_REG_BY]) << 4 |
177 FIELD_GET(TLV493D_BX2_MAG_Y_AXIS_LSB, b[TLV493D_RD_REG_BX2]);
178 break;
179 case TLV493D_AXIS_Z:
180 val = FIELD_GET(TLV493D_BZ_MAG_Z_AXIS_MSB, b[TLV493D_RD_REG_BZ]) << 4 |
181 FIELD_GET(TLV493D_BZ2_MAG_Z_AXIS_LSB, b[TLV493D_RD_REG_BZ2]);
182 break;
183 case TLV493D_TEMPERATURE:
184 val = FIELD_GET(TLV493D_TEMP_TEMP_MSB, b[TLV493D_RD_REG_TEMP]) << 8 |
185 FIELD_GET(TLV493D_TEMP2_TEMP_LSB, b[TLV493D_RD_REG_TEMP2]);
186 break;
187 }
188
189 return sign_extend32(val, 11);
190 }
191
tlv493d_get_measurements(struct tlv493d_data * data,s16 * x,s16 * y,s16 * z,s16 * t)192 static int tlv493d_get_measurements(struct tlv493d_data *data, s16 *x, s16 *y,
193 s16 *z, s16 *t)
194 {
195 u8 buff[7] = {};
196 int err, ret;
197 struct device *dev = &data->client->dev;
198 u32 sleep_us = tlv493d_sample_rate_us[data->mode];
199
200 guard(mutex)(&data->lock);
201
202 ret = pm_runtime_resume_and_get(dev);
203 if (ret < 0)
204 return ret;
205
206 /*
207 * Poll until data is valid.
208 * For a valid data TLV493D_TEMP_CHANNEL bit of TLV493D_RD_REG_TEMP
209 * should be set to 0. The sampling time depends on the sensor mode.
210 * Poll 3x the time of the sampling time.
211 */
212 ret = read_poll_timeout(i2c_master_recv, err,
213 err || !FIELD_GET(TLV493D_TEMP_CHANNEL, buff[TLV493D_RD_REG_TEMP]),
214 sleep_us, 3 * sleep_us, false, data->client, buff,
215 ARRAY_SIZE(buff));
216 if (ret) {
217 dev_err(dev, "i2c read poll timeout, error:%d\n", ret);
218 goto out_put_autosuspend;
219 }
220 if (err < 0) {
221 dev_err(dev, "i2c read data failed, error:%d\n", err);
222 ret = err;
223 goto out_put_autosuspend;
224 }
225
226 *x = tlv493d_get_channel_data(buff, TLV493D_AXIS_X);
227 *y = tlv493d_get_channel_data(buff, TLV493D_AXIS_Y);
228 *z = tlv493d_get_channel_data(buff, TLV493D_AXIS_Z);
229 *t = tlv493d_get_channel_data(buff, TLV493D_TEMPERATURE);
230
231 out_put_autosuspend:
232 pm_runtime_put_autosuspend(dev);
233 return ret;
234 }
235
tlv493d_init(struct tlv493d_data * data)236 static int tlv493d_init(struct tlv493d_data *data)
237 {
238 int ret;
239 u8 buff[TLV493D_RD_REG_MAX];
240 struct device *dev = &data->client->dev;
241
242 /*
243 * The sensor initialization requires below steps to be followed,
244 * 1. Power-up sensor.
245 * 2. Read and store read-registers map (0x0-0x9).
246 * 3. Copy values from read reserved registers to write reserved fields
247 * (0x0-0x3).
248 * 4. Set operating mode.
249 * 5. Write to all registers.
250 */
251 ret = i2c_master_recv(data->client, buff, ARRAY_SIZE(buff));
252 if (ret < 0)
253 return dev_err_probe(dev, ret, "i2c read failed\n");
254
255 /* Write register 0x0 is reserved. Does not require to be updated.*/
256 data->wr_regs[0] = 0;
257 data->wr_regs[1] = buff[TLV493D_RD_REG_RES1] & TLV493D_RD_REG_RES1_WR_MASK;
258 data->wr_regs[2] = buff[TLV493D_RD_REG_RES2] & TLV493D_RD_REG_RES2_WR_MASK;
259 data->wr_regs[3] = buff[TLV493D_RD_REG_RES3] & TLV493D_RD_REG_RES3_WR_MASK;
260
261 ret = tlv493d_set_operating_mode(data, data->mode);
262 if (ret < 0)
263 return dev_err_probe(dev, ret, "failed to set operating mode\n");
264
265 return 0;
266 }
267
tlv493d_read_raw(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,int * val,int * val2,long mask)268 static int tlv493d_read_raw(struct iio_dev *indio_dev,
269 const struct iio_chan_spec *chan, int *val,
270 int *val2, long mask)
271 {
272 struct tlv493d_data *data = iio_priv(indio_dev);
273 s16 x, y, z, t;
274 int ret;
275
276 switch (mask) {
277 case IIO_CHAN_INFO_RAW:
278 ret = tlv493d_get_measurements(data, &x, &y, &z, &t);
279 if (ret)
280 return ret;
281
282 switch (chan->address) {
283 case TLV493D_AXIS_X:
284 *val = x;
285 return IIO_VAL_INT;
286 case TLV493D_AXIS_Y:
287 *val = y;
288 return IIO_VAL_INT;
289 case TLV493D_AXIS_Z:
290 *val = z;
291 return IIO_VAL_INT;
292 case TLV493D_TEMPERATURE:
293 *val = t;
294 return IIO_VAL_INT;
295 default:
296 return -EINVAL;
297 }
298 case IIO_CHAN_INFO_SCALE:
299 switch (chan->type) {
300 case IIO_MAGN:
301 /*
302 * Magnetic field scale: 0.0098 mTesla (i.e. 9.8 µT)
303 * Magnetic field in Gauss: mT * 10 = 0.098.
304 */
305 *val = 98;
306 *val2 = 1000;
307 return IIO_VAL_FRACTIONAL;
308 case IIO_TEMP:
309 /*
310 * Temperature scale: 1.1 °C per LSB, expressed as 1100 m°C
311 * Returned as integer for IIO core to apply:
312 * temp = (raw + offset) * scale
313 */
314 *val = 1100;
315 return IIO_VAL_INT;
316 default:
317 return -EINVAL;
318 }
319 case IIO_CHAN_INFO_OFFSET:
320 switch (chan->type) {
321 case IIO_TEMP:
322 /*
323 * Temperature offset includes sensor-specific raw offset
324 * plus compensation for +25°C bias in formula.
325 * offset = -raw_offset + (25000 / 1100)
326 * -340 + 22.72 = -317.28
327 */
328 *val = -31728;
329 *val2 = 100;
330 return IIO_VAL_FRACTIONAL;
331 default:
332 return -EINVAL;
333 }
334 default:
335 return -EINVAL;
336 }
337 }
338
tlv493d_trigger_handler(int irq,void * ptr)339 static irqreturn_t tlv493d_trigger_handler(int irq, void *ptr)
340 {
341 int ret;
342 s16 x, y, z, t;
343 struct iio_poll_func *pf = ptr;
344 struct iio_dev *indio_dev = pf->indio_dev;
345 struct tlv493d_data *data = iio_priv(indio_dev);
346 struct device *dev = &data->client->dev;
347 struct {
348 s16 channels[3];
349 s16 temperature;
350 aligned_s64 timestamp;
351 } scan;
352
353 ret = tlv493d_get_measurements(data, &x, &y, &z, &t);
354 if (ret) {
355 dev_err(dev, "failed to read sensor data\n");
356 goto out_trigger_notify;
357 }
358
359 scan.channels[0] = x;
360 scan.channels[1] = y;
361 scan.channels[2] = z;
362 scan.temperature = t;
363 iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), pf->timestamp);
364
365 out_trigger_notify:
366 iio_trigger_notify_done(indio_dev->trig);
367
368 return IRQ_HANDLED;
369 }
370
371 #define TLV493D_AXIS_CHANNEL(axis, index) \
372 { \
373 .type = IIO_MAGN, \
374 .modified = 1, \
375 .channel2 = IIO_MOD_##axis, \
376 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
377 BIT(IIO_CHAN_INFO_SCALE), \
378 .address = index, \
379 .scan_index = index, \
380 .scan_type = { \
381 .sign = 's', \
382 .realbits = 12, \
383 .storagebits = 16, \
384 .endianness = IIO_CPU, \
385 }, \
386 }
387
388 static const struct iio_chan_spec tlv493d_channels[] = {
389 TLV493D_AXIS_CHANNEL(X, TLV493D_AXIS_X),
390 TLV493D_AXIS_CHANNEL(Y, TLV493D_AXIS_Y),
391 TLV493D_AXIS_CHANNEL(Z, TLV493D_AXIS_Z),
392 {
393 .type = IIO_TEMP,
394 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
395 BIT(IIO_CHAN_INFO_SCALE) |
396 BIT(IIO_CHAN_INFO_OFFSET),
397 .address = TLV493D_TEMPERATURE,
398 .scan_index = TLV493D_TEMPERATURE,
399 .scan_type = {
400 .sign = 's',
401 .realbits = 12,
402 .storagebits = 16,
403 .endianness = IIO_CPU,
404 },
405 },
406 IIO_CHAN_SOFT_TIMESTAMP(4),
407 };
408
409 static const struct iio_info tlv493d_info = {
410 .read_raw = tlv493d_read_raw,
411 };
412
413 static const unsigned long tlv493d_scan_masks[] = { GENMASK(3, 0), 0 };
414
tlv493d_probe(struct i2c_client * client)415 static int tlv493d_probe(struct i2c_client *client)
416 {
417 struct device *dev = &client->dev;
418 struct iio_dev *indio_dev;
419 struct tlv493d_data *data;
420 int ret;
421
422 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
423 if (!indio_dev)
424 return -ENOMEM;
425
426 data = iio_priv(indio_dev);
427 data->client = client;
428 i2c_set_clientdata(client, indio_dev);
429
430 ret = devm_mutex_init(dev, &data->lock);
431 if (ret)
432 return ret;
433
434 ret = devm_regulator_get_enable(dev, "vdd");
435 if (ret)
436 return dev_err_probe(dev, ret, "failed to enable regulator\n");
437
438 /*
439 * Setting Sensor default operating mode to Master-Controlled mode since
440 * it performs measurement cycle only on-request and stays in Power-Down
441 * state until next cycle is initiated.
442 */
443 data->mode = TLV493D_OP_MODE_MASTERCONTROLLED;
444 ret = tlv493d_init(data);
445 if (ret)
446 return dev_err_probe(dev, ret, "failed to initialize\n");
447
448 indio_dev->info = &tlv493d_info;
449 indio_dev->modes = INDIO_DIRECT_MODE;
450 indio_dev->name = client->name;
451 indio_dev->channels = tlv493d_channels;
452 indio_dev->num_channels = ARRAY_SIZE(tlv493d_channels);
453 indio_dev->available_scan_masks = tlv493d_scan_masks;
454
455 ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
456 iio_pollfunc_store_time,
457 tlv493d_trigger_handler,
458 NULL);
459 if (ret)
460 return dev_err_probe(dev, ret, "iio triggered buffer setup failed\n");
461
462 ret = pm_runtime_set_active(dev);
463 if (ret)
464 return ret;
465
466 ret = devm_pm_runtime_enable(dev);
467 if (ret)
468 return ret;
469
470 pm_runtime_get_noresume(dev);
471 pm_runtime_set_autosuspend_delay(dev, 500);
472 pm_runtime_use_autosuspend(dev);
473
474 pm_runtime_put_autosuspend(dev);
475
476 ret = devm_iio_device_register(dev, indio_dev);
477 if (ret)
478 return dev_err_probe(dev, ret, "iio device register failed\n");
479
480 return 0;
481 }
482
tlv493d_runtime_suspend(struct device * dev)483 static int tlv493d_runtime_suspend(struct device *dev)
484 {
485 struct tlv493d_data *data = iio_priv(dev_get_drvdata(dev));
486
487 return tlv493d_set_operating_mode(data, TLV493D_OP_MODE_POWERDOWN);
488 }
489
tlv493d_runtime_resume(struct device * dev)490 static int tlv493d_runtime_resume(struct device *dev)
491 {
492 struct tlv493d_data *data = iio_priv(dev_get_drvdata(dev));
493
494 return tlv493d_set_operating_mode(data, data->mode);
495 }
496
497 static DEFINE_RUNTIME_DEV_PM_OPS(tlv493d_pm_ops, tlv493d_runtime_suspend,
498 tlv493d_runtime_resume, NULL);
499
500 static const struct i2c_device_id tlv493d_id[] = {
501 { .name = "tlv493d" },
502 { }
503 };
504 MODULE_DEVICE_TABLE(i2c, tlv493d_id);
505
506 static const struct of_device_id tlv493d_of_match[] = {
507 { .compatible = "infineon,tlv493d-a1b6" },
508 { }
509 };
510 MODULE_DEVICE_TABLE(of, tlv493d_of_match);
511
512 static struct i2c_driver tlv493d_driver = {
513 .driver = {
514 .name = "tlv493d",
515 .of_match_table = tlv493d_of_match,
516 .pm = pm_ptr(&tlv493d_pm_ops),
517 },
518 .probe = tlv493d_probe,
519 .id_table = tlv493d_id,
520 };
521 module_i2c_driver(tlv493d_driver);
522
523 MODULE_LICENSE("GPL");
524 MODULE_DESCRIPTION("Infineon TLV493D Low-Power 3D Magnetic Sensor");
525 MODULE_AUTHOR("Dixit Parmar <dixitparmar19@gmail.com>");
526