struct can_tdc::tdco represents the absolute offset from TDCV. Some controllers use instead an offset relative to the Sample Point (SP) such that: | SSP = TDCV + absolute TDCO | = TDCV + SP + relative TDCO Consequently: | relative TDCO = absolute TDCO - SP The function can_tdc_get_relative_tdco() allow to retrieve this relative TDCO value. CC: Stefan Mätje <Stefan.Maetje@xxxxxx> Signed-off-by: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> --- include/linux/can/dev.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 0be982fd22fb..c912d8e92a41 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -93,6 +93,34 @@ static inline bool can_tdc_is_enabled(const struct can_priv *priv) return !!(priv->ctrlmode & CAN_CTRLMODE_TDC_MASK); } +/* + * can_tdc_get_relative_tdco() - TDCO relative to the sample point + * + * struct can_tdc::tdco represents the absolute offset from TDCV. Some + * controllers use instead an offset relative to the Sample Point (SP) + * such that: + * + * SSP = TDCV + absolute TDCO + * = TDCV + SP + relative TDCO + * + * -+----------- one bit ----------+-- TX pin + * |<--- Sample Point --->| + * + * --+----------- one bit ----------+-- RX pin + * |<-------- TDCV -------->| + * |<------------------------>| absolute TDCO + * |<--- Sample Point --->| + * | |<->| relative TDCO + * |<------------- Secondary Sample Point ------------>| + */ +static inline s32 can_tdc_get_relative_tdco(const struct can_priv *priv) +{ + const struct can_bittiming *dbt = &priv->data_bittiming; + s32 sample_point_in_tq = can_bit_time(dbt) * dbt->sample_point / 1000; + + return (s32)priv->tdc.tdco - sample_point_in_tq; +} + /* helper to define static CAN controller features at device creation time */ static inline void can_set_static_ctrlmode(struct net_device *dev, u32 static_mode) -- 2.31.1