Message ID | 1596815903-11144-1-git-send-email-min.li.xe@renesas.com |
---|---|
State | New |
Headers | show |
Series | None | expand |
Hi David/Richard When you have time, can you take a look at this change? Thanks Min -----Original Message----- From: min.li.xe@renesas.com <min.li.xe@renesas.com> Sent: August 7, 2020 11:58 AM To: richardcochran@gmail.com Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Min Li <min.li.xe@renesas.com> Subject: [PATCH net 4/4] ptp: ptp_idt82p33: support individually configure output by index From: Min Li <min.li.xe@renesas.com> Enable/disable individual output by index instead of by output_mask Signed-off-by: Min Li <min.li.xe@renesas.com> --- drivers/ptp/ptp_idt82p33.c | 62 ++++++++++++++++++++++++++++++++++------------ drivers/ptp/ptp_idt82p33.h | 2 ++ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/drivers/ptp/ptp_idt82p33.c b/drivers/ptp/ptp_idt82p33.c index 2d62aed..b3c82d7 100644 --- a/drivers/ptp/ptp_idt82p33.c +++ b/drivers/ptp/ptp_idt82p33.c @@ -578,33 +578,46 @@ static long idt82p33_sync_tod_work_handler(struct ptp_clock_info *ptp) return ret; } -static int idt82p33_pps_enable(struct idt82p33_channel *channel, bool enable) +static int idt82p33_output_enable(struct idt82p33_channel *channel, + bool enable, unsigned int outn) { struct idt82p33 *idt82p33 = channel->idt82p33; - u8 mask, outn, val; int err; + u8 val; + + err = idt82p33_read(idt82p33, OUT_MUX_CNFG(outn), &val, sizeof(val)); + + if (err) + return err; + + if (enable) + val &= ~SQUELCH_ENABLE; + else + val |= SQUELCH_ENABLE; + + return idt82p33_write(idt82p33, OUT_MUX_CNFG(outn), &val, +sizeof(val)); } + +static int idt82p33_output_mask_enable(struct idt82p33_channel *channel, + bool enable) +{ + u16 mask; + int err; + u8 outn; mask = channel->output_mask; outn = 0; while (mask) { - if (mask & 0x1) { - err = idt82p33_read(idt82p33, OUT_MUX_CNFG(outn), - &val, sizeof(val)); - if (err) - return err; - if (enable) - val &= ~SQUELCH_ENABLE; - else - val |= SQUELCH_ENABLE; + if (mask & 0x1) { - err = idt82p33_write(idt82p33, OUT_MUX_CNFG(outn), - &val, sizeof(val)); + err = idt82p33_output_enable(channel, enable, outn); if (err) return err; } + mask >>= 0x1; outn++; } @@ -612,6 +625,20 @@ static int idt82p33_pps_enable(struct idt82p33_channel *channel, bool enable) return 0; } +static int idt82p33_perout_enable(struct idt82p33_channel *channel, + bool enable, + struct ptp_perout_request *perout) { + unsigned int flags = perout->flags; + + /* Enable/disable output based on output_mask */ + if (flags == PEROUT_ENABLE_OUTPUT_MASK) + return idt82p33_output_mask_enable(channel, enable); + + /* Enable/disable individual output instead */ + return idt82p33_output_enable(channel, enable, perout->index); } + static int idt82p33_enable_tod(struct idt82p33_channel *channel) { struct idt82p33 *idt82p33 = channel->idt82p33; @@ -625,7 +652,8 @@ static int idt82p33_enable_tod(struct idt82p33_channel *channel) if (err) return err; - err = idt82p33_pps_enable(channel, false); + if (0) + err = idt82p33_output_mask_enable(channel, false); if (err) { dev_err(&idt82p33->client->dev, @@ -681,14 +709,16 @@ static int idt82p33_enable(struct ptp_clock_info *ptp, if (rq->type == PTP_CLK_REQ_PEROUT) { if (!on) - err = idt82p33_pps_enable(channel, false); + err = idt82p33_perout_enable(channel, false, + &rq->perout); /* Only accept a 1-PPS aligned to the second. */ else if (rq->perout.start.nsec || rq->perout.period.sec != 1 || rq->perout.period.nsec) { err = -ERANGE; } else - err = idt82p33_pps_enable(channel, true); + err = idt82p33_perout_enable(channel, true, + &rq->perout); } mutex_unlock(&idt82p33->reg_lock); diff --git a/drivers/ptp/ptp_idt82p33.h b/drivers/ptp/ptp_idt82p33.h index 1dcd2c0..5008998 100644 --- a/drivers/ptp/ptp_idt82p33.h +++ b/drivers/ptp/ptp_idt82p33.h @@ -56,6 +56,8 @@ #define PLL_MODE_SHIFT (0) #define PLL_MODE_MASK (0x1F) +#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef) + enum pll_mode { PLL_MODE_MIN = 0, PLL_MODE_AUTOMATIC = PLL_MODE_MIN, -- 2.7.4
diff --git a/drivers/ptp/ptp_idt82p33.c b/drivers/ptp/ptp_idt82p33.c index 2d62aed..b3c82d7 100644 --- a/drivers/ptp/ptp_idt82p33.c +++ b/drivers/ptp/ptp_idt82p33.c @@ -578,33 +578,46 @@ static long idt82p33_sync_tod_work_handler(struct ptp_clock_info *ptp) return ret; } -static int idt82p33_pps_enable(struct idt82p33_channel *channel, bool enable) +static int idt82p33_output_enable(struct idt82p33_channel *channel, + bool enable, unsigned int outn) { struct idt82p33 *idt82p33 = channel->idt82p33; - u8 mask, outn, val; int err; + u8 val; + + err = idt82p33_read(idt82p33, OUT_MUX_CNFG(outn), &val, sizeof(val)); + + if (err) + return err; + + if (enable) + val &= ~SQUELCH_ENABLE; + else + val |= SQUELCH_ENABLE; + + return idt82p33_write(idt82p33, OUT_MUX_CNFG(outn), &val, sizeof(val)); +} + +static int idt82p33_output_mask_enable(struct idt82p33_channel *channel, + bool enable) +{ + u16 mask; + int err; + u8 outn; mask = channel->output_mask; outn = 0; while (mask) { - if (mask & 0x1) { - err = idt82p33_read(idt82p33, OUT_MUX_CNFG(outn), - &val, sizeof(val)); - if (err) - return err; - if (enable) - val &= ~SQUELCH_ENABLE; - else - val |= SQUELCH_ENABLE; + if (mask & 0x1) { - err = idt82p33_write(idt82p33, OUT_MUX_CNFG(outn), - &val, sizeof(val)); + err = idt82p33_output_enable(channel, enable, outn); if (err) return err; } + mask >>= 0x1; outn++; } @@ -612,6 +625,20 @@ static int idt82p33_pps_enable(struct idt82p33_channel *channel, bool enable) return 0; } +static int idt82p33_perout_enable(struct idt82p33_channel *channel, + bool enable, + struct ptp_perout_request *perout) +{ + unsigned int flags = perout->flags; + + /* Enable/disable output based on output_mask */ + if (flags == PEROUT_ENABLE_OUTPUT_MASK) + return idt82p33_output_mask_enable(channel, enable); + + /* Enable/disable individual output instead */ + return idt82p33_output_enable(channel, enable, perout->index); +} + static int idt82p33_enable_tod(struct idt82p33_channel *channel) { struct idt82p33 *idt82p33 = channel->idt82p33; @@ -625,7 +652,8 @@ static int idt82p33_enable_tod(struct idt82p33_channel *channel) if (err) return err; - err = idt82p33_pps_enable(channel, false); + if (0) + err = idt82p33_output_mask_enable(channel, false); if (err) { dev_err(&idt82p33->client->dev, @@ -681,14 +709,16 @@ static int idt82p33_enable(struct ptp_clock_info *ptp, if (rq->type == PTP_CLK_REQ_PEROUT) { if (!on) - err = idt82p33_pps_enable(channel, false); + err = idt82p33_perout_enable(channel, false, + &rq->perout); /* Only accept a 1-PPS aligned to the second. */ else if (rq->perout.start.nsec || rq->perout.period.sec != 1 || rq->perout.period.nsec) { err = -ERANGE; } else - err = idt82p33_pps_enable(channel, true); + err = idt82p33_perout_enable(channel, true, + &rq->perout); } mutex_unlock(&idt82p33->reg_lock); diff --git a/drivers/ptp/ptp_idt82p33.h b/drivers/ptp/ptp_idt82p33.h index 1dcd2c0..5008998 100644 --- a/drivers/ptp/ptp_idt82p33.h +++ b/drivers/ptp/ptp_idt82p33.h @@ -56,6 +56,8 @@ #define PLL_MODE_SHIFT (0) #define PLL_MODE_MASK (0x1F) +#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef) + enum pll_mode { PLL_MODE_MIN = 0, PLL_MODE_AUTOMATIC = PLL_MODE_MIN,