Hi David/Richard When you have time, can you take a look at this change? Thanks
Min -----Original Message----- From: min.li...@renesas.com <min.li...@renesas.com> Sent: August 7, 2020 11:56 AM To: richardcoch...@gmail.com Cc: netdev@vger.kernel.org; linux-ker...@vger.kernel.org; Min Li <min.li...@renesas.com> Subject: [PATCH net 1/4] ptp: ptp_idt82p33: update to support adjphase From: Min Li <min.li...@renesas.com> Add adjphase support for idt82p33xxx synchronization management unit. Also fix n_per_out to the actual number of outputs. Changes since v1: - Break into small changes Signed-off-by: Min Li <min.li...@renesas.com> --- drivers/ptp/ptp_idt82p33.c | 48 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/ptp/ptp_idt82p33.c b/drivers/ptp/ptp_idt82p33.c index 179f6c4..bd1fbcd 100644 --- a/drivers/ptp/ptp_idt82p33.c +++ b/drivers/ptp/ptp_idt82p33.c @@ -674,6 +674,51 @@ static int idt82p33_enable(struct ptp_clock_info *ptp, return err; } +static int idt82p33_adjwritephase(struct ptp_clock_info *ptp, s32 +offsetNs) { + struct idt82p33_channel *channel = + container_of(ptp, struct idt82p33_channel, caps); + struct idt82p33 *idt82p33 = channel->idt82p33; + s64 offsetInFs; + s64 offsetRegVal; + u8 val[4] = {0}; + int err; + + offsetInFs = (s64)(-offsetNs) * 1000000; + + if (offsetInFs > WRITE_PHASE_OFFSET_LIMIT) + offsetInFs = WRITE_PHASE_OFFSET_LIMIT; + else if (offsetInFs < -WRITE_PHASE_OFFSET_LIMIT) + offsetInFs = -WRITE_PHASE_OFFSET_LIMIT; + + /* Convert from phaseOffsetInFs to register value */ + offsetRegVal = ((offsetInFs * 1000) / IDT_T0DPLL_PHASE_RESOL); + + val[0] = offsetRegVal & 0xFF; + val[1] = (offsetRegVal >> 8) & 0xFF; + val[2] = (offsetRegVal >> 16) & 0xFF; + val[3] = (offsetRegVal >> 24) & 0x1F; + val[3] |= PH_OFFSET_EN; + + mutex_lock(&idt82p33->reg_lock); + + err = idt82p33_dpll_set_mode(channel, PLL_MODE_WPH); + if (err) { + dev_err(&idt82p33->client->dev, + "Failed at line %d in func %s!\n", + __LINE__, + __func__); + goto out; + } + + err = idt82p33_write(idt82p33, channel->dpll_phase_cnfg, val, + sizeof(val)); + +out: + mutex_unlock(&idt82p33->reg_lock); + return err; +} + static int idt82p33_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) { struct idt82p33_channel *channel = @@ -784,6 +829,8 @@ static void idt82p33_caps_init(struct ptp_clock_info *caps) { caps->owner = THIS_MODULE; caps->max_adj = 92000; + caps->n_per_out = 11; + caps->adjphase = idt82p33_adjwritephase; caps->adjfine = idt82p33_adjfine; caps->adjtime = idt82p33_adjtime; caps->gettime64 = idt82p33_gettime; @@ -810,7 +857,6 @@ static int idt82p33_enable_channel(struct idt82p33 *idt82p33, u32 index) idt82p33_caps_init(&channel->caps); snprintf(channel->caps.name, sizeof(channel->caps.name), "IDT 82P33 PLL%u", index); - channel->caps.n_per_out = hweight8(channel->output_mask); err = idt82p33_dpll_set_mode(channel, PLL_MODE_DCO); if (err) -- 2.7.4