1 // SPDX-License-Identifier: GPL-2.0
3 * Serial line interface for Bosh BNO055 IMU (via serdev).
4 * This file implements serial communication up to the register read/write
7 * Copyright (C) 2021-2022 Istituto Italiano di Tecnologia
8 * Electronic Design Laboratory
9 * Written by Andrea Merello <andrea.merello@iit.it>
11 * This driver is based on
12 * Plantower PMS7003 particulate matter sensor driver
14 * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
17 #include <linux/completion.h>
18 #include <linux/device.h>
19 #include <linux/errno.h>
20 #include <linux/jiffies.h>
21 #include <linux/kernel.h>
22 #include <linux/mod_devicetable.h>
23 #include <linux/module.h>
24 #include <linux/mutex.h>
25 #include <linux/regmap.h>
26 #include <linux/serdev.h>
28 #include "bno055_ser_trace.h"
32 * Register writes cmd have the following format
33 * +------+------+-----+-----+----- ... ----+
34 * | 0xAA | 0xOO | REG | LEN | payload[LEN] |
35 * +------+------+-----+-----+----- ... ----+
37 * Register write responses have the following format
42 * .. except when writing the SYS_RST bit (i.e. triggering a system reset); in
43 * case the IMU accepts the command, then it resets without responding. We don't
44 * handle this (yet) here (so we inform the common bno055 code not to perform
45 * sw resets - bno055 on serial bus basically requires the hw reset pin).
47 * Register read have the following format
48 * +------+------+-----+-----+
49 * | 0xAA | 0xO1 | REG | LEN |
50 * +------+------+-----+-----+
52 * Successful register read response have the following format
53 * +------+-----+----- ... ----+
54 * | 0xBB | LEN | payload[LEN] |
55 * +------+-----+----- ... ----+
57 * Failed register read response have the following format
59 * | 0xEE | ERRCODE| (ERRCODE always > 1)
67 * 06: wrong start byte
71 * 10: bus RX byte timeout (timeout is 30mS)
74 * **WORKAROUND ALERT**
76 * Serial communication seems very fragile: the BNO055 buffer seems to overflow
77 * very easy; BNO055 seems able to sink few bytes, then it needs a brief pause.
78 * On the other hand, it is also picky on timeout: if there is a pause > 30mS in
79 * between two bytes then the transaction fails (IMU internal RX FSM resets).
81 * BNO055 has been seen also failing to process commands in case we send them
82 * too close each other (or if it is somehow busy?)
84 * In particular I saw these scenarios:
85 * 1) If we send 2 bytes per time, then the IMU never(?) overflows.
86 * 2) If we send 4 bytes per time (i.e. the full header), then the IMU could
87 * overflow, but it seem to sink all 4 bytes, then it returns error.
88 * 3) If we send more than 4 bytes, the IMU could overflow, and I saw it sending
89 * error after 4 bytes are sent; we have troubles in synchronizing again,
90 * because we are still sending data, and the IMU interprets it as the 1st
91 * byte of a new command.
93 * While we must avoid case 3, we could send 4 bytes per time and eventually
94 * retry in case of failure; this seemed convenient for reads (which requires
95 * TXing exactly 4 bytes), however it has been seen that, depending by the IMU
96 * settings (e.g. LPF), failures became less or more frequent; in certain IMU
97 * configurations they are very rare, but in certain others we keeps failing
98 * even after like 30 retries.
100 * So, we just split TXes in [2-bytes + delay] steps, and still keep an eye on
101 * the IMU response; in case it overflows (which is now unlikely), we retry.
105 * Read operation overhead:
106 * 4 bytes req + 2byte resp hdr.
107 * 6 bytes = 60 bit (considering 1start + 1stop bits).
108 * 60/115200 = ~520uS + about 2500mS delay -> ~3mS
109 * In 3mS we could read back about 34 bytes that means 17 samples, this means
110 * that in case of scattered reads in which the gap is 17 samples or less it is
111 * still convenient to go for a burst.
112 * We have to take into account also IMU response time - IMU seems to be often
113 * reasonably quick to respond, but sometimes it seems to be in some "critical
114 * section" in which it delays handling of serial protocol. Because of this we
115 * round-up to 22, which is the max number of samples, always bursting indeed.
117 #define BNO055_SER_XFER_BURST_BREAK_THRESHOLD 22
119 struct bno055_ser_priv
{
125 int expected_data_len
;
129 * enum cmd_status - represent the status of a command sent to the HW.
130 * @STATUS_CRIT: The command failed: the serial communication failed.
131 * @STATUS_OK: The command executed successfully.
132 * @STATUS_FAIL: The command failed: HW responded with an error.
141 * Protects all the above fields, which are accessed in behalf of both
142 * the serdev RX callback and the regmap side
146 /* Only accessed in serdev RX callback context*/
158 /* Never accessed in behalf of serdev RX callback context */
161 struct completion cmd_complete
;
162 struct serdev_device
*serdev
;
165 static int bno055_ser_send_chunk(struct bno055_ser_priv
*priv
, const u8
*data
, int len
)
169 trace_send_chunk(len
, data
);
170 ret
= serdev_device_write(priv
->serdev
, data
, len
, msecs_to_jiffies(25));
181 * Send a read or write command.
182 * 'data' can be NULL (used in read case). 'len' parameter is always valid; in
183 * case 'data' is non-NULL then it must match 'data' size.
185 static int bno055_ser_do_send_cmd(struct bno055_ser_priv
*priv
,
186 bool read
, int addr
, int len
, const u8
*data
)
188 u8 hdr
[] = {0xAA, read
, addr
, len
};
192 ret
= bno055_ser_send_chunk(priv
, hdr
, 2);
195 usleep_range(2000, 3000);
196 ret
= bno055_ser_send_chunk(priv
, hdr
+ 2, 2);
204 chunk_len
= min(len
, 2);
205 usleep_range(2000, 3000);
206 ret
= bno055_ser_send_chunk(priv
, data
, chunk_len
);
215 /* waiting more than 30mS should clear the BNO055 internal state */
216 usleep_range(40000, 50000);
220 static int bno055_ser_send_cmd(struct bno055_ser_priv
*priv
,
221 bool read
, int addr
, int len
, const u8
*data
)
223 const int retry_max
= 5;
224 int retry
= retry_max
;
228 * In case previous command was interrupted we still need to wait it to
229 * complete before we can issue new commands
231 if (priv
->cmd_stale
) {
232 ret
= wait_for_completion_interruptible_timeout(&priv
->cmd_complete
,
233 msecs_to_jiffies(100));
234 if (ret
== -ERESTARTSYS
)
237 priv
->cmd_stale
= false;
238 /* if serial protocol broke, bail out */
239 if (priv
->cmd_status
== STATUS_CRIT
)
244 * Try to convince the IMU to cooperate.. as explained in the comments
245 * at the top of this file, the IMU could also refuse the command (i.e.
246 * it is not ready yet); retry in this case.
249 mutex_lock(&priv
->lock
);
250 priv
->expect_response
= read
? CMD_READ
: CMD_WRITE
;
251 reinit_completion(&priv
->cmd_complete
);
252 mutex_unlock(&priv
->lock
);
254 if (retry
!= retry_max
)
255 trace_cmd_retry(read
, addr
, retry_max
- retry
);
256 ret
= bno055_ser_do_send_cmd(priv
, read
, addr
, len
, data
);
260 ret
= wait_for_completion_interruptible_timeout(&priv
->cmd_complete
,
261 msecs_to_jiffies(100));
262 if (ret
== -ERESTARTSYS
) {
263 priv
->cmd_stale
= true;
270 if (priv
->cmd_status
== STATUS_OK
)
272 if (priv
->cmd_status
== STATUS_CRIT
)
275 /* loop in case priv->cmd_status == STATUS_FAIL */
280 if (priv
->cmd_status
== STATUS_FAIL
)
285 static int bno055_ser_write_reg(void *context
, const void *_data
, size_t count
)
287 const u8
*data
= _data
;
288 struct bno055_ser_priv
*priv
= context
;
291 dev_err(&priv
->serdev
->dev
, "Invalid write count %zu", count
);
295 trace_write_reg(data
[0], data
[1]);
296 return bno055_ser_send_cmd(priv
, 0, data
[0], count
- 1, data
+ 1);
299 static int bno055_ser_read_reg(void *context
,
300 const void *_reg
, size_t reg_size
,
301 void *val
, size_t val_size
)
305 const u8
*reg
= _reg
;
306 struct bno055_ser_priv
*priv
= context
;
308 if (val_size
> 128) {
309 dev_err(&priv
->serdev
->dev
, "Invalid read valsize %zu", val_size
);
314 trace_read_reg(reg_addr
, val_size
);
315 mutex_lock(&priv
->lock
);
316 priv
->expected_data_len
= val_size
;
317 priv
->response_buf
= val
;
318 mutex_unlock(&priv
->lock
);
320 ret
= bno055_ser_send_cmd(priv
, 1, reg_addr
, val_size
, NULL
);
322 mutex_lock(&priv
->lock
);
323 priv
->response_buf
= NULL
;
324 mutex_unlock(&priv
->lock
);
330 * Handler for received data; this is called from the receiver callback whenever
331 * it got some packet from the serial bus. The status tells us whether the
332 * packet is valid (i.e. header ok && received payload len consistent wrt the
333 * header). It's now our responsibility to check whether this is what we
334 * expected, of whether we got some unexpected, yet valid, packet.
336 static void bno055_ser_handle_rx(struct bno055_ser_priv
*priv
, int status
)
338 mutex_lock(&priv
->lock
);
339 switch (priv
->expect_response
) {
341 dev_warn(&priv
->serdev
->dev
, "received unexpected, yet valid, data from sensor");
342 mutex_unlock(&priv
->lock
);
346 priv
->cmd_status
= status
;
347 if (status
== STATUS_OK
&&
348 priv
->rx
.databuf_count
!= priv
->expected_data_len
) {
350 * If we got here, then the lower layer serial protocol
351 * seems consistent with itself; if we got an unexpected
352 * amount of data then signal it as a non critical error
354 priv
->cmd_status
= STATUS_FAIL
;
355 dev_warn(&priv
->serdev
->dev
,
356 "received an unexpected amount of, yet valid, data from sensor");
361 priv
->cmd_status
= status
;
365 priv
->expect_response
= CMD_NONE
;
366 mutex_unlock(&priv
->lock
);
367 complete(&priv
->cmd_complete
);
371 * Serdev receiver FSM. This tracks the serial communication and parse the
372 * header. It pushes packets to bno055_ser_handle_rx(), eventually communicating
373 * failures (i.e. malformed packets).
374 * Ideally it doesn't know anything about upper layer (i.e. if this is the
375 * packet we were really expecting), but since we copies the payload into the
376 * receiver buffer (that is not valid when i.e. we don't expect data), we
377 * snoop a bit in the upper layer..
378 * Also, we assume to RX one pkt per time (i.e. the HW doesn't send anything
379 * unless we require to AND we don't queue more than one request per time).
381 static size_t bno055_ser_receive_buf(struct serdev_device
*serdev
,
382 const u8
*buf
, size_t size
)
385 struct bno055_ser_priv
*priv
= serdev_device_get_drvdata(serdev
);
386 size_t remaining
= size
;
391 trace_recv(size
, buf
);
392 switch (priv
->rx
.state
) {
396 * Check for its 1st byte that identifies the pkt type.
398 if (buf
[0] != 0xEE && buf
[0] != 0xBB) {
399 dev_err(&priv
->serdev
->dev
,
400 "Invalid packet start %x", buf
[0]);
401 bno055_ser_handle_rx(priv
, STATUS_CRIT
);
404 priv
->rx
.type
= buf
[0];
405 priv
->rx
.state
= RX_START
;
408 priv
->rx
.databuf_count
= 0;
413 * Packet RX in progress, we expect either 1-byte len or 1-byte
414 * status depending by the packet type.
419 if (priv
->rx
.type
== 0xEE) {
421 dev_err(&priv
->serdev
->dev
, "EE pkt. Extra data received");
422 status
= STATUS_CRIT
;
424 status
= (buf
[0] == 1) ? STATUS_OK
: STATUS_FAIL
;
426 bno055_ser_handle_rx(priv
, status
);
427 priv
->rx
.state
= RX_IDLE
;
431 /*priv->rx.type == 0xBB */
432 priv
->rx
.state
= RX_DATA
;
433 priv
->rx
.expected_len
= buf
[0];
440 /* Header parsed; now receiving packet data payload */
444 if (priv
->rx
.databuf_count
+ remaining
> priv
->rx
.expected_len
) {
446 * This is an inconsistency in serial protocol, we lost
447 * sync and we don't know how to handle further data
449 dev_err(&priv
->serdev
->dev
, "BB pkt. Extra data received");
450 bno055_ser_handle_rx(priv
, STATUS_CRIT
);
451 priv
->rx
.state
= RX_IDLE
;
455 mutex_lock(&priv
->lock
);
457 * NULL e.g. when read cmd is stale or when no read cmd is
460 if (priv
->response_buf
&&
462 * Snoop on the upper layer protocol stuff to make sure not
463 * to write to an invalid memory. Apart for this, let's the
464 * upper layer manage any inconsistency wrt expected data
465 * len (as long as the serial protocol is consistent wrt
466 * itself (i.e. response header is consistent with received
469 (priv
->rx
.databuf_count
+ remaining
<= priv
->expected_data_len
))
470 memcpy(priv
->response_buf
+ priv
->rx
.databuf_count
,
472 mutex_unlock(&priv
->lock
);
474 priv
->rx
.databuf_count
+= remaining
;
477 * Reached expected len advertised by the IMU for the current
478 * packet. Pass it to the upper layer (for us it is just valid).
480 if (priv
->rx
.databuf_count
== priv
->rx
.expected_len
) {
481 bno055_ser_handle_rx(priv
, STATUS_OK
);
482 priv
->rx
.state
= RX_IDLE
;
490 static const struct serdev_device_ops bno055_ser_serdev_ops
= {
491 .receive_buf
= bno055_ser_receive_buf
,
492 .write_wakeup
= serdev_device_write_wakeup
,
495 static const struct regmap_bus bno055_ser_regmap_bus
= {
496 .write
= bno055_ser_write_reg
,
497 .read
= bno055_ser_read_reg
,
500 static int bno055_ser_probe(struct serdev_device
*serdev
)
502 struct bno055_ser_priv
*priv
;
503 struct regmap
*regmap
;
506 priv
= devm_kzalloc(&serdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
510 serdev_device_set_drvdata(serdev
, priv
);
511 priv
->serdev
= serdev
;
512 mutex_init(&priv
->lock
);
513 init_completion(&priv
->cmd_complete
);
515 serdev_device_set_client_ops(serdev
, &bno055_ser_serdev_ops
);
516 ret
= devm_serdev_device_open(&serdev
->dev
, serdev
);
520 if (serdev_device_set_baudrate(serdev
, 115200) != 115200) {
521 dev_err(&serdev
->dev
, "Cannot set required baud rate");
525 ret
= serdev_device_set_parity(serdev
, SERDEV_PARITY_NONE
);
527 dev_err(&serdev
->dev
, "Cannot set required parity setting");
530 serdev_device_set_flow_control(serdev
, false);
532 regmap
= devm_regmap_init(&serdev
->dev
, &bno055_ser_regmap_bus
,
533 priv
, &bno055_regmap_config
);
535 return dev_err_probe(&serdev
->dev
, PTR_ERR(regmap
),
536 "Unable to init register map");
538 return bno055_probe(&serdev
->dev
, regmap
,
539 BNO055_SER_XFER_BURST_BREAK_THRESHOLD
, false);
542 static const struct of_device_id bno055_ser_of_match
[] = {
543 { .compatible
= "bosch,bno055" },
546 MODULE_DEVICE_TABLE(of
, bno055_ser_of_match
);
548 static struct serdev_device_driver bno055_ser_driver
= {
550 .name
= "bno055-ser",
551 .of_match_table
= bno055_ser_of_match
,
553 .probe
= bno055_ser_probe
,
555 module_serdev_device_driver(bno055_ser_driver
);
557 MODULE_AUTHOR("Andrea Merello <andrea.merello@iit.it>");
558 MODULE_DESCRIPTION("Bosch BNO055 serdev interface");
559 MODULE_IMPORT_NS("IIO_BNO055");
560 MODULE_LICENSE("GPL");