// SPDX-License-Identifier: GPL-2.0+
/*
 * PTP hardware clock driver for the IDT ClockMatrix(TM) family of timing and
 * synchronization devices.
 *
 * Copyright (C) 2019 Integrated Device Technology, Inc., a Renesas Company.
 */
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/timekeeping.h>
#include <linux/string.h>
#include <linux/of.h>
#include <linux/mfd/rsmu.h>
#include <linux/mfd/idt8a340_reg.h>
#include <asm/unaligned.h>

#include "ptp_private.h"
#include "ptp_clockmatrix.h"

MODULE_DESCRIPTION("Driver for IDT ClockMatrix(TM) family");
MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
MODULE_AUTHOR("IDT support-1588 <IDT-support-1588@lm.renesas.com>");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL");

/*
 * The name of the firmware file to be loaded
 * over-rides any automatic selection
 */
static char *firmware;
module_param(firmware, charp, 0);

#define SETTIME_CORRECTION (0)
#define EXTTS_PERIOD_MS (95)

static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm);

static inline int idtcm_read(struct idtcm *idtcm,
			     u16 module,
			     u16 regaddr,
			     u8 *buf,
			     u16 count)
{
	return regmap_bulk_read(idtcm->regmap, module + regaddr, buf, count);
}

static inline int idtcm_write(struct idtcm *idtcm,
			      u16 module,
			      u16 regaddr,
			      u8 *buf,
			      u16 count)
{
	return regmap_bulk_write(idtcm->regmap, module + regaddr, buf, count);
}

static int contains_full_configuration(struct idtcm *idtcm,
				       const struct firmware *fw)
{
	struct idtcm_fwrc *rec = (struct idtcm_fwrc *)fw->data;
	u16 scratch = IDTCM_FW_REG(idtcm->fw_ver, V520, SCRATCH);
	s32 full_count;
	s32 count = 0;
	u16 regaddr;
	u8 loaddr;
	s32 len;

	/* 4 bytes skipped every 0x80 */
	full_count = (scratch - GPIO_USER_CONTROL) -
		     ((scratch >> 7) - (GPIO_USER_CONTROL >> 7)) * 4;

	/* If the firmware contains 'full configuration' SM_RESET can be used
	 * to ensure proper configuration.
	 *
	 * Full configuration is defined as the number of programmable
	 * bytes within the configuration range minus page offset addr range.
	 */
	for (len = fw->size; len > 0; len -= sizeof(*rec)) {
		regaddr = rec->hiaddr << 8;
		regaddr |= rec->loaddr;

		loaddr = rec->loaddr;

		rec++;

		/* Top (status registers) and bottom are read-only */
		if (regaddr < GPIO_USER_CONTROL || regaddr >= scratch)
			continue;

		/* Page size 128, last 4 bytes of page skipped */
		if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)
			continue;

		count++;
	}

	return (count >= full_count);
}

static int char_array_to_timespec(u8 *buf,
				  u8 count,
				  struct timespec64 *ts)
{
	u8 i;
	u64 nsec;
	time64_t sec;

	if (count < TOD_BYTE_COUNT)
		return 1;

	/* Sub-nanoseconds are in buf[0]. */
	nsec = buf[4];
	for (i = 0; i < 3; i++) {
		nsec <<= 8;
		nsec |= buf[3 - i];
	}

	sec = buf[10];
	for (i = 0; i < 5; i++) {
		sec <<= 8;
		sec |= buf[9 - i];
	}

	ts->tv_sec = sec;
	ts->tv_nsec = nsec;

	return 0;
}

static int timespec_to_char_array(struct timespec64 const *ts,
				  u8 *buf,
				  u8 count)
{
	u8 i;
	s32 nsec;
	time64_t sec;

	if (count < TOD_BYTE_COUNT)
		return 1;

	nsec = ts->tv_nsec;
	sec = ts->tv_sec;

	/* Sub-nanoseconds are in buf[0]. */
	buf[0] = 0;
	for (i = 1; i < 5; i++) {
		buf[i] = nsec & 0xff;
		nsec >>= 8;
	}

	for (i = 5; i < TOD_BYTE_COUNT; i++) {

		buf[i] = sec & 0xff;
		sec >>= 8;
	}

	return 0;
}

static int idtcm_strverscmp(const char *version1, const char *version2)
{
	u8 ver1[3], ver2[3];
	int i;

	if (sscanf(version1, "%hhu.%hhu.%hhu",
		   &ver1[0], &ver1[1], &ver1[2]) != 3)
		return -1;
	if (sscanf(version2, "%hhu.%hhu.%hhu",
		   &ver2[0], &ver2[1], &ver2[2]) != 3)
		return -1;

	for (i = 0; i < 3; i++) {
		if (ver1[i] > ver2[i])
			return 1;
		if (ver1[i] < ver2[i])
			return -1;
	}

	return 0;
}

static enum fw_version idtcm_fw_version(const char *version)
{
	enum fw_version ver = V_DEFAULT;

	if (idtcm_strverscmp(version, "4.8.7") >= 0)
		ver = V487;

	if (idtcm_strverscmp(version, "5.2.0") >= 0)
		ver = V520;

	return ver;
}

static int clear_boot_status(struct idtcm *idtcm)
{
	u8 buf[4] = {0};

	return idtcm_write(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));
}

static int read_boot_status(struct idtcm *idtcm, u32 *status)
{
	int err;
	u8 buf[4] = {0};

	err = idtcm_read(idtcm, GENERAL_STATUS, BOOT_STATUS, buf, sizeof(buf));

	*status = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];

	return err;
}

static int wait_for_boot_status_ready(struct idtcm *idtcm)
{
	u32 status = 0;
	u8 i = 30;	/* 30 * 100ms = 3s */
	int err;

	do {
		err = read_boot_status(idtcm, &status);
		if (err)
			return err;

		if (status == 0xA0)
			return 0;

		msleep(100);
		i--;

	} while (i);

	dev_warn(idtcm->dev, "%s timed out", __func__);

	return -EBUSY;
}

static int _idtcm_set_scsr_read_trig(struct idtcm_channel *channel,
				     enum scsr_read_trig_sel trig, u8 ref)
{
	struct idtcm *idtcm = channel->idtcm;
	u16 tod_read_cmd = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_READ_PRIMARY_CMD);
	u8 val;
	int err;

	if (trig == SCSR_TOD_READ_TRIG_SEL_REFCLK) {
		err = idtcm_read(idtcm, channel->tod_read_primary,
				 TOD_READ_PRIMARY_SEL_CFG_0, &val, sizeof(val));
		if (err)
			return err;

		val &= ~(WR_REF_INDEX_MASK << WR_REF_INDEX_SHIFT);
		val |= (ref << WR_REF_INDEX_SHIFT);

		err = idtcm_write(idtcm, channel->tod_read_primary,
				  TOD_READ_PRIMARY_SEL_CFG_0, &val, sizeof(val));
		if (err)
			return err;
	}

	err = idtcm_read(idtcm, channel->tod_read_primary,
			 tod_read_cmd, &val, sizeof(val));
	if (err)
		return err;

	val &= ~(TOD_READ_TRIGGER_MASK << TOD_READ_TRIGGER_SHIFT);
	val |= (trig << TOD_READ_TRIGGER_SHIFT);
	val &= ~TOD_READ_TRIGGER_MODE; /* single shot */

	err = idtcm_write(idtcm, channel->tod_read_primary,
			  tod_read_cmd, &val, sizeof(val));
	return err;
}

static int idtcm_enable_extts(struct idtcm_channel *channel, u8 todn, u8 ref,
			      bool enable)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 old_mask = idtcm->extts_mask;
	u8 mask = 1 << todn;
	int err = 0;

	if (todn >= MAX_TOD)
		return -EINVAL;

	if (enable) {
		if (ref > 0xF) /* E_REF_CLK15 */
			return -EINVAL;
		if (idtcm->extts_mask & mask)
			return 0;
		err = _idtcm_set_scsr_read_trig(&idtcm->channel[todn],
						SCSR_TOD_READ_TRIG_SEL_REFCLK,
						ref);
		if (err == 0) {
			idtcm->extts_mask |= mask;
			idtcm->event_channel[todn] = channel;
			idtcm->channel[todn].refn = ref;
		}
	} else
		idtcm->extts_mask &= ~mask;

	if (old_mask == 0 && idtcm->extts_mask)
		schedule_delayed_work(&idtcm->extts_work,
				      msecs_to_jiffies(EXTTS_PERIOD_MS));

	return err;
}

static int read_sys_apll_status(struct idtcm *idtcm, u8 *status)
{
	return idtcm_read(idtcm, STATUS, DPLL_SYS_APLL_STATUS, status,
			  sizeof(u8));
}

static int read_sys_dpll_status(struct idtcm *idtcm, u8 *status)
{
	return idtcm_read(idtcm, STATUS, DPLL_SYS_STATUS, status, sizeof(u8));
}

static int wait_for_sys_apll_dpll_lock(struct idtcm *idtcm)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(LOCK_TIMEOUT_MS);
	u8 apll = 0;
	u8 dpll = 0;
	int err;

	do {
		err = read_sys_apll_status(idtcm, &apll);
		if (err)
			return err;

		err = read_sys_dpll_status(idtcm, &dpll);
		if (err)
			return err;

		apll &= SYS_APLL_LOSS_LOCK_LIVE_MASK;
		dpll &= DPLL_SYS_STATE_MASK;

		if (apll == SYS_APLL_LOSS_LOCK_LIVE_LOCKED &&
		    dpll == DPLL_STATE_LOCKED) {
			return 0;
		} else if (dpll == DPLL_STATE_FREERUN ||
			   dpll == DPLL_STATE_HOLDOVER ||
			   dpll == DPLL_STATE_OPEN_LOOP) {
			dev_warn(idtcm->dev,
				"No wait state: DPLL_SYS_STATE %d", dpll);
			return -EPERM;
		}

		msleep(LOCK_POLL_INTERVAL_MS);
	} while (time_is_after_jiffies(timeout));

	dev_warn(idtcm->dev,
		 "%d ms lock timeout: SYS APLL Loss Lock %d  SYS DPLL state %d",
		 LOCK_TIMEOUT_MS, apll, dpll);

	return -ETIME;
}

static void wait_for_chip_ready(struct idtcm *idtcm)
{
	if (wait_for_boot_status_ready(idtcm))
		dev_warn(idtcm->dev, "BOOT_STATUS != 0xA0");

	if (wait_for_sys_apll_dpll_lock(idtcm))
		dev_warn(idtcm->dev,
			 "Continuing while SYS APLL/DPLL is not locked");
}

static int _idtcm_gettime(struct idtcm_channel *channel,
			  struct timespec64 *ts, u8 timeout)
{
	struct idtcm *idtcm = channel->idtcm;
	u16 tod_read_cmd = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_READ_PRIMARY_CMD);
	u8 buf[TOD_BYTE_COUNT];
	u8 trigger;
	int err;

	/* wait trigger to be 0 */
	do {
		if (timeout-- == 0)
			return -EIO;

		if (idtcm->calculate_overhead_flag)
			idtcm->start_time = ktime_get_raw();

		err = idtcm_read(idtcm, channel->tod_read_primary,
				 tod_read_cmd, &trigger,
				 sizeof(trigger));
		if (err)
			return err;
	} while (trigger & TOD_READ_TRIGGER_MASK);

	err = idtcm_read(idtcm, channel->tod_read_primary,
			 TOD_READ_PRIMARY, buf, sizeof(buf));
	if (err)
		return err;

	err = char_array_to_timespec(buf, sizeof(buf), ts);

	return err;
}

static int idtcm_extts_check_channel(struct idtcm *idtcm, u8 todn)
{
	struct idtcm_channel *ptp_channel, *extts_channel;
	struct ptp_clock_event event;
	struct timespec64 ts;
	u32 dco_delay = 0;
	int err;

	extts_channel = &idtcm->channel[todn];
	ptp_channel = idtcm->event_channel[todn];
	if (extts_channel == ptp_channel)
		dco_delay = ptp_channel->dco_delay;

	err = _idtcm_gettime(extts_channel, &ts, 1);
	if (err == 0) {
		event.type = PTP_CLOCK_EXTTS;
		event.index = todn;
		event.timestamp = timespec64_to_ns(&ts) - dco_delay;
		ptp_clock_event(ptp_channel->ptp_clock, &event);
	}
	return err;
}

static u8 idtcm_enable_extts_mask(struct idtcm_channel *channel,
				    u8 extts_mask, bool enable)
{
	struct idtcm *idtcm = channel->idtcm;
	int i, err;

	for (i = 0; i < MAX_TOD; i++) {
		u8 mask = 1 << i;
		u8 refn = idtcm->channel[i].refn;

		if (extts_mask & mask) {
			/* check extts before disabling it */
			if (enable == false) {
				err = idtcm_extts_check_channel(idtcm, i);
				/* trigger happened so we won't re-enable it */
				if (err == 0)
					extts_mask &= ~mask;
			}
			(void)idtcm_enable_extts(channel, i, refn, enable);
		}
	}

	return extts_mask;
}

static int _idtcm_gettime_immediate(struct idtcm_channel *channel,
				    struct timespec64 *ts)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 extts_mask = 0;
	int err;

	/* Disable extts */
	if (idtcm->extts_mask) {
		extts_mask = idtcm_enable_extts_mask(channel, idtcm->extts_mask,
						     false);
	}

	err = _idtcm_set_scsr_read_trig(channel,
					SCSR_TOD_READ_TRIG_SEL_IMMEDIATE, 0);
	if (err == 0)
		err = _idtcm_gettime(channel, ts, 10);

	/* Re-enable extts */
	if (extts_mask)
		idtcm_enable_extts_mask(channel, extts_mask, true);

	return err;
}

static int _sync_pll_output(struct idtcm *idtcm,
			    u8 pll,
			    u8 sync_src,
			    u8 qn,
			    u8 qn_plus_1)
{
	int err;
	u8 val;
	u16 sync_ctrl0;
	u16 sync_ctrl1;
	u8 temp;

	if (qn == 0 && qn_plus_1 == 0)
		return 0;

	switch (pll) {
	case 0:
		sync_ctrl0 = HW_Q0_Q1_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q0_Q1_CH_SYNC_CTRL_1;
		break;
	case 1:
		sync_ctrl0 = HW_Q2_Q3_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q2_Q3_CH_SYNC_CTRL_1;
		break;
	case 2:
		sync_ctrl0 = HW_Q4_Q5_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q4_Q5_CH_SYNC_CTRL_1;
		break;
	case 3:
		sync_ctrl0 = HW_Q6_Q7_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q6_Q7_CH_SYNC_CTRL_1;
		break;
	case 4:
		sync_ctrl0 = HW_Q8_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q8_CH_SYNC_CTRL_1;
		break;
	case 5:
		sync_ctrl0 = HW_Q9_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q9_CH_SYNC_CTRL_1;
		break;
	case 6:
		sync_ctrl0 = HW_Q10_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q10_CH_SYNC_CTRL_1;
		break;
	case 7:
		sync_ctrl0 = HW_Q11_CH_SYNC_CTRL_0;
		sync_ctrl1 = HW_Q11_CH_SYNC_CTRL_1;
		break;
	default:
		return -EINVAL;
	}

	val = SYNCTRL1_MASTER_SYNC_RST;

	/* Place master sync in reset */
	err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));
	if (err)
		return err;

	err = idtcm_write(idtcm, 0, sync_ctrl0, &sync_src, sizeof(sync_src));
	if (err)
		return err;

	/* Set sync trigger mask */
	val |= SYNCTRL1_FBDIV_FRAME_SYNC_TRIG | SYNCTRL1_FBDIV_SYNC_TRIG;

	if (qn)
		val |= SYNCTRL1_Q0_DIV_SYNC_TRIG;

	if (qn_plus_1)
		val |= SYNCTRL1_Q1_DIV_SYNC_TRIG;

	err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));
	if (err)
		return err;

	/* PLL5 can have OUT8 as second additional output. */
	if (pll == 5 && qn_plus_1 != 0) {
		err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
				 &temp, sizeof(temp));
		if (err)
			return err;

		temp &= ~(Q9_TO_Q8_SYNC_TRIG);

		err = idtcm_write(idtcm, 0, HW_Q8_CTRL_SPARE,
				  &temp, sizeof(temp));
		if (err)
			return err;

		temp |= Q9_TO_Q8_SYNC_TRIG;

		err = idtcm_write(idtcm, 0, HW_Q8_CTRL_SPARE,
				  &temp, sizeof(temp));
		if (err)
			return err;
	}

	/* PLL6 can have OUT11 as second additional output. */
	if (pll == 6 && qn_plus_1 != 0) {
		err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
				 &temp, sizeof(temp));
		if (err)
			return err;

		temp &= ~(Q10_TO_Q11_SYNC_TRIG);

		err = idtcm_write(idtcm, 0, HW_Q11_CTRL_SPARE,
				  &temp, sizeof(temp));
		if (err)
			return err;

		temp |= Q10_TO_Q11_SYNC_TRIG;

		err = idtcm_write(idtcm, 0, HW_Q11_CTRL_SPARE,
				  &temp, sizeof(temp));
		if (err)
			return err;
	}

	/* Place master sync out of reset */
	val &= ~(SYNCTRL1_MASTER_SYNC_RST);
	err = idtcm_write(idtcm, 0, sync_ctrl1, &val, sizeof(val));

	return err;
}

static int idtcm_sync_pps_output(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 pll;
	u8 qn;
	u8 qn_plus_1;
	int err = 0;
	u8 out8_mux = 0;
	u8 out11_mux = 0;
	u8 temp;
	u16 output_mask = channel->output_mask;

	err = idtcm_read(idtcm, 0, HW_Q8_CTRL_SPARE,
			 &temp, sizeof(temp));
	if (err)
		return err;

	if ((temp & Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==
	    Q9_TO_Q8_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
		out8_mux = 1;

	err = idtcm_read(idtcm, 0, HW_Q11_CTRL_SPARE,
			 &temp, sizeof(temp));
	if (err)
		return err;

	if ((temp & Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK) ==
	    Q10_TO_Q11_FANOUT_AND_CLOCK_SYNC_ENABLE_MASK)
		out11_mux = 1;

	for (pll = 0; pll < 8; pll++) {
		qn = 0;
		qn_plus_1 = 0;

		if (pll < 4) {
			/* First 4 pll has 2 outputs */
			qn = output_mask & 0x1;
			output_mask = output_mask >> 1;
			qn_plus_1 = output_mask & 0x1;
			output_mask = output_mask >> 1;
		} else if (pll == 4) {
			if (out8_mux == 0) {
				qn = output_mask & 0x1;
				output_mask = output_mask >> 1;
			}
		} else if (pll == 5) {
			if (out8_mux) {
				qn_plus_1 = output_mask & 0x1;
				output_mask = output_mask >> 1;
			}
			qn = output_mask & 0x1;
			output_mask = output_mask >> 1;
		} else if (pll == 6) {
			qn = output_mask & 0x1;
			output_mask = output_mask >> 1;
			if (out11_mux) {
				qn_plus_1 = output_mask & 0x1;
				output_mask = output_mask >> 1;
			}
		} else if (pll == 7) {
			if (out11_mux == 0) {
				qn = output_mask & 0x1;
				output_mask = output_mask >> 1;
			}
		}

		if (qn != 0 || qn_plus_1 != 0)
			err = _sync_pll_output(idtcm, pll, channel->sync_src,
					       qn, qn_plus_1);

		if (err)
			return err;
	}

	return err;
}

static int _idtcm_set_dpll_hw_tod(struct idtcm_channel *channel,
				  struct timespec64 const *ts,
				  enum hw_tod_write_trig_sel wr_trig)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 buf[TOD_BYTE_COUNT];
	u8 cmd;
	int err;
	struct timespec64 local_ts = *ts;
	s64 total_overhead_ns;

	/* Configure HW TOD write trigger. */
	err = idtcm_read(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
			 &cmd, sizeof(cmd));
	if (err)
		return err;

	cmd &= ~(0x0f);
	cmd |= wr_trig | 0x08;

	err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
			  &cmd, sizeof(cmd));
	if (err)
		return err;

	if (wr_trig  != HW_TOD_WR_TRIG_SEL_MSB) {
		err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
		if (err)
			return err;

		err = idtcm_write(idtcm, channel->hw_dpll_n,
				  HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
		if (err)
			return err;
	}

	/* ARM HW TOD write trigger. */
	cmd &= ~(0x08);

	err = idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_CTRL_1,
			  &cmd, sizeof(cmd));

	if (wr_trig == HW_TOD_WR_TRIG_SEL_MSB) {
		if (idtcm->calculate_overhead_flag) {
			/* Assumption: I2C @ 400KHz */
			ktime_t diff = ktime_sub(ktime_get_raw(),
						 idtcm->start_time);
			total_overhead_ns =  ktime_to_ns(diff)
					     + idtcm->tod_write_overhead_ns
					     + SETTIME_CORRECTION;

			timespec64_add_ns(&local_ts, total_overhead_ns);

			idtcm->calculate_overhead_flag = 0;
		}

		err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
		if (err)
			return err;

		err = idtcm_write(idtcm, channel->hw_dpll_n,
				  HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
	}

	return err;
}

static int _idtcm_set_dpll_scsr_tod(struct idtcm_channel *channel,
				    struct timespec64 const *ts,
				    enum scsr_tod_write_trig_sel wr_trig,
				    enum scsr_tod_write_type_sel wr_type)
{
	struct idtcm *idtcm = channel->idtcm;
	unsigned char buf[TOD_BYTE_COUNT], cmd;
	struct timespec64 local_ts = *ts;
	int err, count = 0;

	timespec64_add_ns(&local_ts, SETTIME_CORRECTION);

	err = timespec_to_char_array(&local_ts, buf, sizeof(buf));
	if (err)
		return err;

	err = idtcm_write(idtcm, channel->tod_write, TOD_WRITE,
			  buf, sizeof(buf));
	if (err)
		return err;

	/* Trigger the write operation. */
	err = idtcm_read(idtcm, channel->tod_write, TOD_WRITE_CMD,
			 &cmd, sizeof(cmd));
	if (err)
		return err;

	cmd &= ~(TOD_WRITE_SELECTION_MASK << TOD_WRITE_SELECTION_SHIFT);
	cmd &= ~(TOD_WRITE_TYPE_MASK << TOD_WRITE_TYPE_SHIFT);
	cmd |= (wr_trig << TOD_WRITE_SELECTION_SHIFT);
	cmd |= (wr_type << TOD_WRITE_TYPE_SHIFT);

	err = idtcm_write(idtcm, channel->tod_write, TOD_WRITE_CMD,
			   &cmd, sizeof(cmd));
	if (err)
		return err;

	/* Wait for the operation to complete. */
	while (1) {
		/* pps trigger takes up to 1 sec to complete */
		if (wr_trig == SCSR_TOD_WR_TRIG_SEL_TODPPS)
			msleep(50);

		err = idtcm_read(idtcm, channel->tod_write, TOD_WRITE_CMD,
				 &cmd, sizeof(cmd));
		if (err)
			return err;

		if ((cmd & TOD_WRITE_SELECTION_MASK) == 0)
			break;

		if (++count > 20) {
			dev_err(idtcm->dev,
				"Timed out waiting for the write counter");
			return -EIO;
		}
	}

	return 0;
}

static int get_output_base_addr(enum fw_version ver, u8 outn)
{
	int base;

	switch (outn) {
	case 0:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_0);
		break;
	case 1:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_1);
		break;
	case 2:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_2);
		break;
	case 3:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_3);
		break;
	case 4:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_4);
		break;
	case 5:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_5);
		break;
	case 6:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_6);
		break;
	case 7:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_7);
		break;
	case 8:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_8);
		break;
	case 9:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_9);
		break;
	case 10:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_10);
		break;
	case 11:
		base = IDTCM_FW_REG(ver, V520, OUTPUT_11);
		break;
	default:
		base = -EINVAL;
	}

	return base;
}

static int _idtcm_settime_deprecated(struct idtcm_channel *channel,
				     struct timespec64 const *ts)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;

	err = _idtcm_set_dpll_hw_tod(channel, ts, HW_TOD_WR_TRIG_SEL_MSB);
	if (err) {
		dev_err(idtcm->dev,
			"%s: Set HW ToD failed", __func__);
		return err;
	}

	return idtcm_sync_pps_output(channel);
}

static int _idtcm_settime(struct idtcm_channel *channel,
			  struct timespec64 const *ts,
			  enum scsr_tod_write_type_sel wr_type)
{
	return _idtcm_set_dpll_scsr_tod(channel, ts,
					SCSR_TOD_WR_TRIG_SEL_IMMEDIATE,
					wr_type);
}

static int idtcm_set_phase_pull_in_offset(struct idtcm_channel *channel,
					  s32 offset_ns)
{
	int err;
	int i;
	struct idtcm *idtcm = channel->idtcm;
	u8 buf[4];

	for (i = 0; i < 4; i++) {
		buf[i] = 0xff & (offset_ns);
		offset_ns >>= 8;
	}

	err = idtcm_write(idtcm, channel->dpll_phase_pull_in, PULL_IN_OFFSET,
			  buf, sizeof(buf));

	return err;
}

static int idtcm_set_phase_pull_in_slope_limit(struct idtcm_channel *channel,
					       u32 max_ffo_ppb)
{
	int err;
	u8 i;
	struct idtcm *idtcm = channel->idtcm;
	u8 buf[3];

	if (max_ffo_ppb & 0xff000000)
		max_ffo_ppb = 0;

	for (i = 0; i < 3; i++) {
		buf[i] = 0xff & (max_ffo_ppb);
		max_ffo_ppb >>= 8;
	}

	err = idtcm_write(idtcm, channel->dpll_phase_pull_in,
			  PULL_IN_SLOPE_LIMIT, buf, sizeof(buf));

	return err;
}

static int idtcm_start_phase_pull_in(struct idtcm_channel *channel)
{
	int err;
	struct idtcm *idtcm = channel->idtcm;
	u8 buf;

	err = idtcm_read(idtcm, channel->dpll_phase_pull_in, PULL_IN_CTRL,
			 &buf, sizeof(buf));
	if (err)
		return err;

	if (buf == 0) {
		buf = 0x01;
		err = idtcm_write(idtcm, channel->dpll_phase_pull_in,
				  PULL_IN_CTRL, &buf, sizeof(buf));
	} else {
		err = -EBUSY;
	}

	return err;
}

static int do_phase_pull_in_fw(struct idtcm_channel *channel,
			       s32 offset_ns,
			       u32 max_ffo_ppb)
{
	int err;

	err = idtcm_set_phase_pull_in_offset(channel, -offset_ns);
	if (err)
		return err;

	err = idtcm_set_phase_pull_in_slope_limit(channel, max_ffo_ppb);
	if (err)
		return err;

	err = idtcm_start_phase_pull_in(channel);

	return err;
}

static int set_tod_write_overhead(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	s64 current_ns = 0;
	s64 lowest_ns = 0;
	int err;
	u8 i;
	ktime_t start;
	ktime_t stop;
	ktime_t diff;

	char buf[TOD_BYTE_COUNT] = {0};

	/* Set page offset */
	idtcm_write(idtcm, channel->hw_dpll_n, HW_DPLL_TOD_OVR__0,
		    buf, sizeof(buf));

	for (i = 0; i < TOD_WRITE_OVERHEAD_COUNT_MAX; i++) {
		start = ktime_get_raw();

		err = idtcm_write(idtcm, channel->hw_dpll_n,
				  HW_DPLL_TOD_OVR__0, buf, sizeof(buf));
		if (err)
			return err;

		stop = ktime_get_raw();

		diff = ktime_sub(stop, start);

		current_ns = ktime_to_ns(diff);

		if (i == 0) {
			lowest_ns = current_ns;
		} else {
			if (current_ns < lowest_ns)
				lowest_ns = current_ns;
		}
	}

	idtcm->tod_write_overhead_ns = lowest_ns;

	return err;
}

static int _idtcm_adjtime_deprecated(struct idtcm_channel *channel, s64 delta)
{
	int err;
	struct idtcm *idtcm = channel->idtcm;
	struct timespec64 ts;
	s64 now;

	if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS_DEPRECATED) {
		err = channel->do_phase_pull_in(channel, delta, 0);
	} else {
		idtcm->calculate_overhead_flag = 1;

		err = set_tod_write_overhead(channel);
		if (err)
			return err;

		err = _idtcm_gettime_immediate(channel, &ts);
		if (err)
			return err;

		now = timespec64_to_ns(&ts);
		now += delta;

		ts = ns_to_timespec64(now);

		err = _idtcm_settime_deprecated(channel, &ts);
	}

	return err;
}

static int idtcm_state_machine_reset(struct idtcm *idtcm)
{
	u8 byte = SM_RESET_CMD;
	u32 status = 0;
	int err;
	u8 i;

	clear_boot_status(idtcm);

	err = idtcm_write(idtcm, RESET_CTRL,
			  IDTCM_FW_REG(idtcm->fw_ver, V520, SM_RESET),
			  &byte, sizeof(byte));

	if (!err) {
		for (i = 0; i < 30; i++) {
			msleep_interruptible(100);
			read_boot_status(idtcm, &status);

			if (status == 0xA0) {
				dev_dbg(idtcm->dev,
					"SM_RESET completed in %d ms", i * 100);
				break;
			}
		}

		if (!status)
			dev_err(idtcm->dev,
				"Timed out waiting for CM_RESET to complete");
	}

	return err;
}

static int idtcm_read_hw_rev_id(struct idtcm *idtcm, u8 *hw_rev_id)
{
	return idtcm_read(idtcm, HW_REVISION, REV_ID, hw_rev_id, sizeof(u8));
}

static int idtcm_read_product_id(struct idtcm *idtcm, u16 *product_id)
{
	int err;
	u8 buf[2] = {0};

	err = idtcm_read(idtcm, GENERAL_STATUS, PRODUCT_ID, buf, sizeof(buf));

	*product_id = (buf[1] << 8) | buf[0];

	return err;
}

static int idtcm_read_major_release(struct idtcm *idtcm, u8 *major)
{
	int err;
	u8 buf = 0;

	err = idtcm_read(idtcm, GENERAL_STATUS, MAJ_REL, &buf, sizeof(buf));

	*major = buf >> 1;

	return err;
}

static int idtcm_read_minor_release(struct idtcm *idtcm, u8 *minor)
{
	return idtcm_read(idtcm, GENERAL_STATUS, MIN_REL, minor, sizeof(u8));
}

static int idtcm_read_hotfix_release(struct idtcm *idtcm, u8 *hotfix)
{
	return idtcm_read(idtcm,
			  GENERAL_STATUS,
			  HOTFIX_REL,
			  hotfix,
			  sizeof(u8));
}

static int idtcm_read_otp_scsr_config_select(struct idtcm *idtcm,
					     u8 *config_select)
{
	return idtcm_read(idtcm, GENERAL_STATUS, OTP_SCSR_CONFIG_SELECT,
			  config_select, sizeof(u8));
}

static int set_pll_output_mask(struct idtcm *idtcm, u16 addr, u8 val)
{
	int err = 0;

	switch (addr) {
	case TOD0_OUT_ALIGN_MASK_ADDR:
		SET_U16_LSB(idtcm->channel[0].output_mask, val);
		break;
	case TOD0_OUT_ALIGN_MASK_ADDR + 1:
		SET_U16_MSB(idtcm->channel[0].output_mask, val);
		break;
	case TOD1_OUT_ALIGN_MASK_ADDR:
		SET_U16_LSB(idtcm->channel[1].output_mask, val);
		break;
	case TOD1_OUT_ALIGN_MASK_ADDR + 1:
		SET_U16_MSB(idtcm->channel[1].output_mask, val);
		break;
	case TOD2_OUT_ALIGN_MASK_ADDR:
		SET_U16_LSB(idtcm->channel[2].output_mask, val);
		break;
	case TOD2_OUT_ALIGN_MASK_ADDR + 1:
		SET_U16_MSB(idtcm->channel[2].output_mask, val);
		break;
	case TOD3_OUT_ALIGN_MASK_ADDR:
		SET_U16_LSB(idtcm->channel[3].output_mask, val);
		break;
	case TOD3_OUT_ALIGN_MASK_ADDR + 1:
		SET_U16_MSB(idtcm->channel[3].output_mask, val);
		break;
	default:
		err = -EFAULT; /* Bad address */;
		break;
	}

	return err;
}

static int set_tod_ptp_pll(struct idtcm *idtcm, u8 index, u8 pll)
{
	if (index >= MAX_TOD) {
		dev_err(idtcm->dev, "ToD%d not supported", index);
		return -EINVAL;
	}

	if (pll >= MAX_PLL) {
		dev_err(idtcm->dev, "Pll%d not supported", pll);
		return -EINVAL;
	}

	idtcm->channel[index].pll = pll;

	return 0;
}

static int check_and_set_masks(struct idtcm *idtcm,
			       u16 regaddr,
			       u8 val)
{
	int err = 0;

	switch (regaddr) {
	case TOD_MASK_ADDR:
		if ((val & 0xf0) || !(val & 0x0f)) {
			dev_err(idtcm->dev, "Invalid TOD mask 0x%02x", val);
			err = -EINVAL;
		} else {
			idtcm->tod_mask = val;
		}
		break;
	case TOD0_PTP_PLL_ADDR:
		err = set_tod_ptp_pll(idtcm, 0, val);
		break;
	case TOD1_PTP_PLL_ADDR:
		err = set_tod_ptp_pll(idtcm, 1, val);
		break;
	case TOD2_PTP_PLL_ADDR:
		err = set_tod_ptp_pll(idtcm, 2, val);
		break;
	case TOD3_PTP_PLL_ADDR:
		err = set_tod_ptp_pll(idtcm, 3, val);
		break;
	default:
		err = set_pll_output_mask(idtcm, regaddr, val);
		break;
	}

	return err;
}

static void display_pll_and_masks(struct idtcm *idtcm)
{
	u8 i;
	u8 mask;

	dev_dbg(idtcm->dev, "tod_mask = 0x%02x", idtcm->tod_mask);

	for (i = 0; i < MAX_TOD; i++) {
		mask = 1 << i;

		if (mask & idtcm->tod_mask)
			dev_dbg(idtcm->dev,
				"TOD%d pll = %d    output_mask = 0x%04x",
				i, idtcm->channel[i].pll,
				idtcm->channel[i].output_mask);
	}
}

static int idtcm_load_firmware(struct idtcm *idtcm,
			       struct device *dev)
{
	u16 scratch = IDTCM_FW_REG(idtcm->fw_ver, V520, SCRATCH);
	char fname[128] = FW_FILENAME;
	const struct firmware *fw;
	struct idtcm_fwrc *rec;
	u32 regaddr;
	int err;
	s32 len;
	u8 val;
	u8 loaddr;

	if (firmware) /* module parameter */
		snprintf(fname, sizeof(fname), "%s", firmware);

	dev_info(idtcm->dev, "requesting firmware '%s'", fname);

	err = request_firmware(&fw, fname, dev);
	if (err) {
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);
		return err;
	}

	dev_dbg(idtcm->dev, "firmware size %zu bytes", fw->size);

	rec = (struct idtcm_fwrc *) fw->data;

	if (contains_full_configuration(idtcm, fw))
		idtcm_state_machine_reset(idtcm);

	for (len = fw->size; len > 0; len -= sizeof(*rec)) {
		if (rec->reserved) {
			dev_err(idtcm->dev,
				"bad firmware, reserved field non-zero");
			err = -EINVAL;
		} else {
			regaddr = rec->hiaddr << 8;
			regaddr |= rec->loaddr;

			val = rec->value;
			loaddr = rec->loaddr;

			rec++;

			err = check_and_set_masks(idtcm, regaddr, val);
		}

		if (err != -EINVAL) {
			err = 0;

			/* Top (status registers) and bottom are read-only */
			if (regaddr < GPIO_USER_CONTROL || regaddr >= scratch)
				continue;

			/* Page size 128, last 4 bytes of page skipped */
			if ((loaddr > 0x7b && loaddr <= 0x7f) || loaddr > 0xfb)
				continue;

			err = idtcm_write(idtcm, regaddr, 0, &val, sizeof(val));
		}

		if (err)
			goto out;
	}

	display_pll_and_masks(idtcm);

out:
	release_firmware(fw);
	return err;
}

static int idtcm_output_enable(struct idtcm_channel *channel,
			       bool enable, unsigned int outn)
{
	struct idtcm *idtcm = channel->idtcm;
	int base;
	int err;
	u8 val;

	base = get_output_base_addr(idtcm->fw_ver, outn);

	if (!(base > 0)) {
		dev_err(idtcm->dev,
			"%s - Unsupported out%d", __func__, outn);
		return base;
	}

	err = idtcm_read(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
	if (err)
		return err;

	if (enable)
		val |= SQUELCH_DISABLE;
	else
		val &= ~SQUELCH_DISABLE;

	return idtcm_write(idtcm, (u16)base, OUT_CTRL_1, &val, sizeof(val));
}

static int idtcm_output_mask_enable(struct idtcm_channel *channel,
				    bool enable)
{
	u16 mask;
	int err;
	u8 outn;

	mask = channel->output_mask;
	outn = 0;

	while (mask) {
		if (mask & 0x1) {
			err = idtcm_output_enable(channel, enable, outn);
			if (err)
				return err;
		}

		mask >>= 0x1;
		outn++;
	}

	return 0;
}

static int idtcm_perout_enable(struct idtcm_channel *channel,
			       struct ptp_perout_request *perout,
			       bool enable)
{
	struct idtcm *idtcm = channel->idtcm;
	unsigned int flags = perout->flags;
	struct timespec64 ts = {0, 0};
	int err;

	if (flags == PEROUT_ENABLE_OUTPUT_MASK)
		err = idtcm_output_mask_enable(channel, enable);
	else
		err = idtcm_output_enable(channel, enable, perout->index);

	if (err) {
		dev_err(idtcm->dev, "Unable to set output enable");
		return err;
	}

	/* Align output to internal 1 PPS */
	return _idtcm_settime(channel, &ts, SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS);
}

static int idtcm_get_pll_mode(struct idtcm_channel *channel,
			      enum pll_mode *mode)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;
	u8 dpll_mode;

	err = idtcm_read(idtcm, channel->dpll_n,
			 IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_MODE),
			 &dpll_mode, sizeof(dpll_mode));
	if (err)
		return err;

	*mode = (dpll_mode >> PLL_MODE_SHIFT) & PLL_MODE_MASK;

	return 0;
}

static int idtcm_set_pll_mode(struct idtcm_channel *channel,
			      enum pll_mode mode)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;
	u8 dpll_mode;

	err = idtcm_read(idtcm, channel->dpll_n,
			 IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_MODE),
			 &dpll_mode, sizeof(dpll_mode));
	if (err)
		return err;

	dpll_mode &= ~(PLL_MODE_MASK << PLL_MODE_SHIFT);

	dpll_mode |= (mode << PLL_MODE_SHIFT);

	err = idtcm_write(idtcm, channel->dpll_n,
			  IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_MODE),
			  &dpll_mode, sizeof(dpll_mode));
	return err;
}

static int idtcm_get_manual_reference(struct idtcm_channel *channel,
				      enum manual_reference *ref)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 dpll_manu_ref_cfg;
	int err;

	err = idtcm_read(idtcm, channel->dpll_ctrl_n,
			 DPLL_CTRL_DPLL_MANU_REF_CFG,
			 &dpll_manu_ref_cfg, sizeof(dpll_manu_ref_cfg));
	if (err)
		return err;

	dpll_manu_ref_cfg &= (MANUAL_REFERENCE_MASK << MANUAL_REFERENCE_SHIFT);

	*ref = dpll_manu_ref_cfg >> MANUAL_REFERENCE_SHIFT;

	return 0;
}

static int idtcm_set_manual_reference(struct idtcm_channel *channel,
				      enum manual_reference ref)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 dpll_manu_ref_cfg;
	int err;

	err = idtcm_read(idtcm, channel->dpll_ctrl_n,
			 DPLL_CTRL_DPLL_MANU_REF_CFG,
			 &dpll_manu_ref_cfg, sizeof(dpll_manu_ref_cfg));
	if (err)
		return err;

	dpll_manu_ref_cfg &= ~(MANUAL_REFERENCE_MASK << MANUAL_REFERENCE_SHIFT);

	dpll_manu_ref_cfg |= (ref << MANUAL_REFERENCE_SHIFT);

	err = idtcm_write(idtcm, channel->dpll_ctrl_n,
			  DPLL_CTRL_DPLL_MANU_REF_CFG,
			  &dpll_manu_ref_cfg, sizeof(dpll_manu_ref_cfg));

	return err;
}

static int configure_dpll_mode_write_frequency(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;

	err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_FREQUENCY);

	if (err)
		dev_err(idtcm->dev, "Failed to set pll mode to write frequency");
	else
		channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;

	return err;
}

static int configure_dpll_mode_write_phase(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;

	err = idtcm_set_pll_mode(channel, PLL_MODE_WRITE_PHASE);

	if (err)
		dev_err(idtcm->dev, "Failed to set pll mode to write phase");
	else
		channel->mode = PTP_PLL_MODE_WRITE_PHASE;

	return err;
}

static int configure_manual_reference_write_frequency(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;

	err = idtcm_set_manual_reference(channel, MANU_REF_WRITE_FREQUENCY);

	if (err)
		dev_err(idtcm->dev, "Failed to set manual reference to write frequency");
	else
		channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;

	return err;
}

static int configure_manual_reference_write_phase(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;

	err = idtcm_set_manual_reference(channel, MANU_REF_WRITE_PHASE);

	if (err)
		dev_err(idtcm->dev, "Failed to set manual reference to write phase");
	else
		channel->mode = PTP_PLL_MODE_WRITE_PHASE;

	return err;
}

static int idtcm_stop_phase_pull_in(struct idtcm_channel *channel)
{
	int err;

	err = _idtcm_adjfine(channel, channel->current_freq_scaled_ppm);
	if (err)
		return err;

	channel->phase_pull_in = false;

	return 0;
}

static long idtcm_work_handler(struct ptp_clock_info *ptp)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;

	mutex_lock(idtcm->lock);

	(void)idtcm_stop_phase_pull_in(channel);

	mutex_unlock(idtcm->lock);

	/* Return a negative value here to not reschedule */
	return -1;
}

static s32 phase_pull_in_scaled_ppm(s32 current_ppm, s32 phase_pull_in_ppb)
{
	/* ppb = scaled_ppm * 125 / 2^13 */
	/* scaled_ppm = ppb * 2^13 / 125 */

	s64 max_scaled_ppm = div_s64((s64)PHASE_PULL_IN_MAX_PPB << 13, 125);
	s64 scaled_ppm = div_s64((s64)phase_pull_in_ppb << 13, 125);

	current_ppm += scaled_ppm;

	if (current_ppm > max_scaled_ppm)
		current_ppm = max_scaled_ppm;
	else if (current_ppm < -max_scaled_ppm)
		current_ppm = -max_scaled_ppm;

	return current_ppm;
}

static int do_phase_pull_in_sw(struct idtcm_channel *channel,
			       s32 delta_ns,
			       u32 max_ffo_ppb)
{
	s32 current_ppm = channel->current_freq_scaled_ppm;
	u32 duration_ms = MSEC_PER_SEC;
	s32 delta_ppm;
	s32 ppb;
	int err;

	/* If the ToD correction is less than PHASE_PULL_IN_MIN_THRESHOLD_NS,
	 * skip. The error introduced by the ToD adjustment procedure would
	 * be bigger than the required ToD correction
	 */
	if (abs(delta_ns) < PHASE_PULL_IN_MIN_THRESHOLD_NS)
		return 0;

	if (max_ffo_ppb == 0)
		max_ffo_ppb = PHASE_PULL_IN_MAX_PPB;

	/* For most cases, keep phase pull-in duration 1 second */
	ppb = delta_ns;
	while (abs(ppb) > max_ffo_ppb) {
		duration_ms *= 2;
		ppb /= 2;
	}

	delta_ppm = phase_pull_in_scaled_ppm(current_ppm, ppb);

	err = _idtcm_adjfine(channel, delta_ppm);

	if (err)
		return err;

	/* schedule the worker to cancel phase pull-in */
	ptp_schedule_worker(channel->ptp_clock,
			    msecs_to_jiffies(duration_ms) - 1);

	channel->phase_pull_in = true;

	return 0;
}

static int initialize_operating_mode_with_manual_reference(struct idtcm_channel *channel,
							   enum manual_reference ref)
{
	struct idtcm *idtcm = channel->idtcm;

	channel->mode = PTP_PLL_MODE_UNSUPPORTED;
	channel->configure_write_frequency = configure_manual_reference_write_frequency;
	channel->configure_write_phase = configure_manual_reference_write_phase;
	channel->do_phase_pull_in = do_phase_pull_in_sw;

	switch (ref) {
	case MANU_REF_WRITE_PHASE:
		channel->mode = PTP_PLL_MODE_WRITE_PHASE;
		break;
	case MANU_REF_WRITE_FREQUENCY:
		channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;
		break;
	default:
		dev_warn(idtcm->dev,
			 "Unsupported MANUAL_REFERENCE: 0x%02x", ref);
	}

	return 0;
}

static int initialize_operating_mode_with_pll_mode(struct idtcm_channel *channel,
						   enum pll_mode mode)
{
	struct idtcm *idtcm = channel->idtcm;
	int err = 0;

	channel->mode = PTP_PLL_MODE_UNSUPPORTED;
	channel->configure_write_frequency = configure_dpll_mode_write_frequency;
	channel->configure_write_phase = configure_dpll_mode_write_phase;
	channel->do_phase_pull_in = do_phase_pull_in_fw;

	switch (mode) {
	case  PLL_MODE_WRITE_PHASE:
		channel->mode = PTP_PLL_MODE_WRITE_PHASE;
		break;
	case PLL_MODE_WRITE_FREQUENCY:
		channel->mode = PTP_PLL_MODE_WRITE_FREQUENCY;
		break;
	default:
		dev_err(idtcm->dev,
			"Unsupported PLL_MODE: 0x%02x", mode);
		err = -EINVAL;
	}

	return err;
}

static int initialize_dco_operating_mode(struct idtcm_channel *channel)
{
	enum manual_reference ref = MANU_REF_XO_DPLL;
	enum pll_mode mode = PLL_MODE_DISABLED;
	struct idtcm *idtcm = channel->idtcm;
	int err;

	channel->mode = PTP_PLL_MODE_UNSUPPORTED;

	err = idtcm_get_pll_mode(channel, &mode);
	if (err) {
		dev_err(idtcm->dev, "Unable to read pll mode!");
		return err;
	}

	if (mode == PLL_MODE_PLL) {
		err = idtcm_get_manual_reference(channel, &ref);
		if (err) {
			dev_err(idtcm->dev, "Unable to read manual reference!");
			return err;
		}
		err = initialize_operating_mode_with_manual_reference(channel, ref);
	} else {
		err = initialize_operating_mode_with_pll_mode(channel, mode);
	}

	if (channel->mode == PTP_PLL_MODE_WRITE_PHASE)
		channel->configure_write_frequency(channel);

	return err;
}

/* PTP Hardware Clock interface */

/*
 * Maximum absolute value for write phase offset in picoseconds
 *
 * Destination signed register is 32-bit register in resolution of 50ps
 *
 * 0x7fffffff * 50 =  2147483647 * 50 = 107374182350
 */
static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
{
	struct idtcm *idtcm = channel->idtcm;
	int err;
	u8 i;
	u8 buf[4] = {0};
	s32 phase_50ps;
	s64 offset_ps;

	if (channel->mode != PTP_PLL_MODE_WRITE_PHASE) {
		err = channel->configure_write_phase(channel);
		if (err)
			return err;
	}

	offset_ps = (s64)delta_ns * 1000;

	/*
	 * Check for 32-bit signed max * 50:
	 *
	 * 0x7fffffff * 50 =  2147483647 * 50 = 107374182350
	 */
	if (offset_ps > MAX_ABS_WRITE_PHASE_PICOSECONDS)
		offset_ps = MAX_ABS_WRITE_PHASE_PICOSECONDS;
	else if (offset_ps < -MAX_ABS_WRITE_PHASE_PICOSECONDS)
		offset_ps = -MAX_ABS_WRITE_PHASE_PICOSECONDS;

	phase_50ps = div_s64(offset_ps, 50);

	for (i = 0; i < 4; i++) {
		buf[i] = phase_50ps & 0xff;
		phase_50ps >>= 8;
	}

	err = idtcm_write(idtcm, channel->dpll_phase, DPLL_WR_PHASE,
			  buf, sizeof(buf));

	return err;
}

static int _idtcm_adjfine(struct idtcm_channel *channel, long scaled_ppm)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 i;
	int err;
	u8 buf[6] = {0};
	s64 fcw;

	if (channel->mode  != PTP_PLL_MODE_WRITE_FREQUENCY) {
		err = channel->configure_write_frequency(channel);
		if (err)
			return err;
	}

	/*
	 * Frequency Control Word unit is: 1.11 * 10^-10 ppm
	 *
	 * adjfreq:
	 *       ppb * 10^9
	 * FCW = ----------
	 *          111
	 *
	 * adjfine:
	 *       ppm_16 * 5^12
	 * FCW = -------------
	 *         111 * 2^4
	 */

	/* 2 ^ -53 = 1.1102230246251565404236316680908e-16 */
	fcw = scaled_ppm * 244140625ULL;

	fcw = div_s64(fcw, 1776);

	for (i = 0; i < 6; i++) {
		buf[i] = fcw & 0xff;
		fcw >>= 8;
	}

	err = idtcm_write(idtcm, channel->dpll_freq, DPLL_WR_FREQ,
			  buf, sizeof(buf));

	return err;
}

static int idtcm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err;

	mutex_lock(idtcm->lock);
	err = _idtcm_gettime_immediate(channel, ts);
	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev, "Failed at line %d in %s!",
			__LINE__, __func__);

	return err;
}

static int idtcm_settime_deprecated(struct ptp_clock_info *ptp,
				    const struct timespec64 *ts)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err;

	mutex_lock(idtcm->lock);
	err = _idtcm_settime_deprecated(channel, ts);
	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);

	return err;
}

static int idtcm_settime(struct ptp_clock_info *ptp,
			 const struct timespec64 *ts)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err;

	mutex_lock(idtcm->lock);
	err = _idtcm_settime(channel, ts, SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);

	return err;
}

static int idtcm_adjtime_deprecated(struct ptp_clock_info *ptp, s64 delta)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err;

	mutex_lock(idtcm->lock);
	err = _idtcm_adjtime_deprecated(channel, delta);
	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);

	return err;
}

static int idtcm_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	struct timespec64 ts;
	enum scsr_tod_write_type_sel type;
	int err;

	if (channel->phase_pull_in == true)
		return 0;

	mutex_lock(idtcm->lock);

	if (abs(delta) < PHASE_PULL_IN_THRESHOLD_NS) {
		err = channel->do_phase_pull_in(channel, delta, 0);
	} else {
		if (delta >= 0) {
			ts = ns_to_timespec64(delta);
			type = SCSR_TOD_WR_TYPE_SEL_DELTA_PLUS;
		} else {
			ts = ns_to_timespec64(-delta);
			type = SCSR_TOD_WR_TYPE_SEL_DELTA_MINUS;
		}
		err = _idtcm_settime(channel, &ts, type);
	}

	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);

	return err;
}

static int idtcm_adjphase(struct ptp_clock_info *ptp, s32 delta)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err;

	mutex_lock(idtcm->lock);
	err = _idtcm_adjphase(channel, delta);
	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);

	return err;
}

static int idtcm_adjfine(struct ptp_clock_info *ptp,  long scaled_ppm)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err;

	if (channel->phase_pull_in == true)
		return 0;

	if (scaled_ppm == channel->current_freq_scaled_ppm)
		return 0;

	mutex_lock(idtcm->lock);
	err = _idtcm_adjfine(channel, scaled_ppm);
	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);
	else
		channel->current_freq_scaled_ppm = scaled_ppm;

	return err;
}

static int idtcm_enable(struct ptp_clock_info *ptp,
			struct ptp_clock_request *rq, int on)
{
	struct idtcm_channel *channel = container_of(ptp, struct idtcm_channel, caps);
	struct idtcm *idtcm = channel->idtcm;
	int err = -EOPNOTSUPP;

	mutex_lock(idtcm->lock);

	switch (rq->type) {
	case PTP_CLK_REQ_PEROUT:
		if (!on)
			err = idtcm_perout_enable(channel, &rq->perout, false);
		/* 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 = idtcm_perout_enable(channel, &rq->perout, true);
		break;
	case PTP_CLK_REQ_EXTTS:
		err = idtcm_enable_extts(channel, rq->extts.index,
					 rq->extts.rsv[0], on);
		break;
	default:
		break;
	}

	mutex_unlock(idtcm->lock);

	if (err)
		dev_err(channel->idtcm->dev,
			"Failed in %s with err %d!", __func__, err);

	return err;
}

static int idtcm_enable_tod(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	struct timespec64 ts = {0, 0};
	u16 tod_cfg = IDTCM_FW_REG(idtcm->fw_ver, V520, TOD_CFG);
	u8 cfg;
	int err;

	/* STEELAI-366 - Temporary workaround for ts2phc compatibility */
	if (0) {
		err = idtcm_output_mask_enable(channel, false);
		if (err)
			return err;
	}

	/*
	 * Start the TOD clock ticking.
	 */
	err = idtcm_read(idtcm, channel->tod_n, tod_cfg, &cfg, sizeof(cfg));
	if (err)
		return err;

	cfg |= TOD_ENABLE;

	err = idtcm_write(idtcm, channel->tod_n, tod_cfg, &cfg, sizeof(cfg));
	if (err)
		return err;

	if (idtcm->fw_ver < V487)
		return _idtcm_settime_deprecated(channel, &ts);
	else
		return _idtcm_settime(channel, &ts,
				      SCSR_TOD_WR_TYPE_SEL_ABSOLUTE);
}

static void idtcm_set_version_info(struct idtcm *idtcm)
{
	u8 major;
	u8 minor;
	u8 hotfix;
	u16 product_id;
	u8 hw_rev_id;
	u8 config_select;

	idtcm_read_major_release(idtcm, &major);
	idtcm_read_minor_release(idtcm, &minor);
	idtcm_read_hotfix_release(idtcm, &hotfix);

	idtcm_read_product_id(idtcm, &product_id);
	idtcm_read_hw_rev_id(idtcm, &hw_rev_id);

	idtcm_read_otp_scsr_config_select(idtcm, &config_select);

	snprintf(idtcm->version, sizeof(idtcm->version), "%u.%u.%u",
		 major, minor, hotfix);

	idtcm->fw_ver = idtcm_fw_version(idtcm->version);

	dev_info(idtcm->dev,
		 "%d.%d.%d, Id: 0x%04x  HW Rev: %d  OTP Config Select: %d",
		 major, minor, hotfix,
		 product_id, hw_rev_id, config_select);
}

static const struct ptp_clock_info idtcm_caps = {
	.owner		= THIS_MODULE,
	.max_adj	= 244000,
	.n_per_out	= 12,
	.n_ext_ts	= MAX_TOD,
	.adjphase	= &idtcm_adjphase,
	.adjfine	= &idtcm_adjfine,
	.adjtime	= &idtcm_adjtime,
	.gettime64	= &idtcm_gettime,
	.settime64	= &idtcm_settime,
	.enable		= &idtcm_enable,
	.do_aux_work	= &idtcm_work_handler,
};

static const struct ptp_clock_info idtcm_caps_deprecated = {
	.owner		= THIS_MODULE,
	.max_adj	= 244000,
	.n_per_out	= 12,
	.n_ext_ts	= MAX_TOD,
	.adjphase	= &idtcm_adjphase,
	.adjfine	= &idtcm_adjfine,
	.adjtime	= &idtcm_adjtime_deprecated,
	.gettime64	= &idtcm_gettime,
	.settime64	= &idtcm_settime_deprecated,
	.enable		= &idtcm_enable,
	.do_aux_work	= &idtcm_work_handler,
};

static int configure_channel_pll(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	int err = 0;

	switch (channel->pll) {
	case 0:
		channel->dpll_freq = DPLL_FREQ_0;
		channel->dpll_n = DPLL_0;
		channel->hw_dpll_n = HW_DPLL_0;
		channel->dpll_phase = DPLL_PHASE_0;
		channel->dpll_ctrl_n = DPLL_CTRL_0;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_0;
		break;
	case 1:
		channel->dpll_freq = DPLL_FREQ_1;
		channel->dpll_n = DPLL_1;
		channel->hw_dpll_n = HW_DPLL_1;
		channel->dpll_phase = DPLL_PHASE_1;
		channel->dpll_ctrl_n = DPLL_CTRL_1;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_1;
		break;
	case 2:
		channel->dpll_freq = DPLL_FREQ_2;
		channel->dpll_n = IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_2);
		channel->hw_dpll_n = HW_DPLL_2;
		channel->dpll_phase = DPLL_PHASE_2;
		channel->dpll_ctrl_n = DPLL_CTRL_2;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_2;
		break;
	case 3:
		channel->dpll_freq = DPLL_FREQ_3;
		channel->dpll_n = DPLL_3;
		channel->hw_dpll_n = HW_DPLL_3;
		channel->dpll_phase = DPLL_PHASE_3;
		channel->dpll_ctrl_n = DPLL_CTRL_3;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_3;
		break;
	case 4:
		channel->dpll_freq = DPLL_FREQ_4;
		channel->dpll_n = IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_4);
		channel->hw_dpll_n = HW_DPLL_4;
		channel->dpll_phase = DPLL_PHASE_4;
		channel->dpll_ctrl_n = DPLL_CTRL_4;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_4;
		break;
	case 5:
		channel->dpll_freq = DPLL_FREQ_5;
		channel->dpll_n = DPLL_5;
		channel->hw_dpll_n = HW_DPLL_5;
		channel->dpll_phase = DPLL_PHASE_5;
		channel->dpll_ctrl_n = DPLL_CTRL_5;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_5;
		break;
	case 6:
		channel->dpll_freq = DPLL_FREQ_6;
		channel->dpll_n = IDTCM_FW_REG(idtcm->fw_ver, V520, DPLL_6);
		channel->hw_dpll_n = HW_DPLL_6;
		channel->dpll_phase = DPLL_PHASE_6;
		channel->dpll_ctrl_n = DPLL_CTRL_6;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_6;
		break;
	case 7:
		channel->dpll_freq = DPLL_FREQ_7;
		channel->dpll_n = DPLL_7;
		channel->hw_dpll_n = HW_DPLL_7;
		channel->dpll_phase = DPLL_PHASE_7;
		channel->dpll_ctrl_n = DPLL_CTRL_7;
		channel->dpll_phase_pull_in = DPLL_PHASE_PULL_IN_7;
		break;
	default:
		err = -EINVAL;
	}

	return err;
}

/*
 * Compensate for the PTP DCO input-to-output delay.
 * This delay is 18 FOD cycles.
 */
static u32 idtcm_get_dco_delay(struct idtcm_channel *channel)
{
	struct idtcm *idtcm = channel->idtcm;
	u8 mbuf[8] = {0};
	u8 nbuf[2] = {0};
	u32 fodFreq;
	int err;
	u64 m;
	u16 n;

	err = idtcm_read(idtcm, channel->dpll_ctrl_n,
			 DPLL_CTRL_DPLL_FOD_FREQ, mbuf, 6);
	if (err)
		return 0;

	err = idtcm_read(idtcm, channel->dpll_ctrl_n,
			 DPLL_CTRL_DPLL_FOD_FREQ + 6, nbuf, 2);
	if (err)
		return 0;

	m = get_unaligned_le64(mbuf);
	n = get_unaligned_le16(nbuf);

	if (n == 0)
		n = 1;

	fodFreq = (u32)div_u64(m, n);
	if (fodFreq >= 500000000)
		return 18 * (u32)div_u64(NSEC_PER_SEC, fodFreq);

	return 0;
}

static int configure_channel_tod(struct idtcm_channel *channel, u32 index)
{
	enum fw_version fw_ver = channel->idtcm->fw_ver;

	/* Set tod addresses */
	switch (index) {
	case 0:
		channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_0);
		channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_0);
		channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_0);
		channel->sync_src = SYNC_SOURCE_DPLL0_TOD_PPS;
		break;
	case 1:
		channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_1);
		channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_1);
		channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_1);
		channel->sync_src = SYNC_SOURCE_DPLL1_TOD_PPS;
		break;
	case 2:
		channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_2);
		channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_2);
		channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_2);
		channel->sync_src = SYNC_SOURCE_DPLL2_TOD_PPS;
		break;
	case 3:
		channel->tod_read_primary = IDTCM_FW_REG(fw_ver, V520, TOD_READ_PRIMARY_3);
		channel->tod_write = IDTCM_FW_REG(fw_ver, V520, TOD_WRITE_3);
		channel->tod_n = IDTCM_FW_REG(fw_ver, V520, TOD_3);
		channel->sync_src = SYNC_SOURCE_DPLL3_TOD_PPS;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int idtcm_enable_channel(struct idtcm *idtcm, u32 index)
{
	struct idtcm_channel *channel;
	int err;

	if (!(index < MAX_TOD))
		return -EINVAL;

	channel = &idtcm->channel[index];

	channel->idtcm = idtcm;
	channel->current_freq_scaled_ppm = 0;

	/* Set pll addresses */
	err = configure_channel_pll(channel);
	if (err)
		return err;

	/* Set tod addresses */
	err = configure_channel_tod(channel, index);
	if (err)
		return err;

	if (idtcm->fw_ver < V487)
		channel->caps = idtcm_caps_deprecated;
	else
		channel->caps = idtcm_caps;

	snprintf(channel->caps.name, sizeof(channel->caps.name),
		 "IDT CM TOD%u", index);

	err = initialize_dco_operating_mode(channel);
	if (err)
		return err;

	err = idtcm_enable_tod(channel);
	if (err) {
		dev_err(idtcm->dev,
			"Failed at line %d in %s!", __LINE__, __func__);
		return err;
	}

	channel->dco_delay = idtcm_get_dco_delay(channel);

	channel->ptp_clock = ptp_clock_register(&channel->caps, NULL);

	if (IS_ERR(channel->ptp_clock)) {
		err = PTR_ERR(channel->ptp_clock);
		channel->ptp_clock = NULL;
		return err;
	}

	if (!channel->ptp_clock)
		return -ENOTSUPP;

	dev_info(idtcm->dev, "PLL%d registered as ptp%d",
		 index, channel->ptp_clock->index);

	return 0;
}

static int idtcm_enable_extts_channel(struct idtcm *idtcm, u32 index)
{
	struct idtcm_channel *channel;
	int err;

	if (!(index < MAX_TOD))
		return -EINVAL;

	channel = &idtcm->channel[index];
	channel->idtcm = idtcm;

	/* Set tod addresses */
	err = configure_channel_tod(channel, index);
	if (err)
		return err;

	channel->idtcm = idtcm;

	return 0;
}

static void idtcm_extts_check(struct work_struct *work)
{
	struct idtcm *idtcm = container_of(work, struct idtcm, extts_work.work);
	int err, i;

	if (idtcm->extts_mask == 0)
		return;

	mutex_lock(idtcm->lock);
	for (i = 0; i < MAX_TOD; i++) {
		u8 mask = 1 << i;

		if (idtcm->extts_mask & mask) {
			err = idtcm_extts_check_channel(idtcm, i);
			/* trigger clears itself, so clear the mask */
			if (err == 0)
				idtcm->extts_mask &= ~mask;
		}
	}

	if (idtcm->extts_mask)
		schedule_delayed_work(&idtcm->extts_work,
				      msecs_to_jiffies(EXTTS_PERIOD_MS));
	mutex_unlock(idtcm->lock);
}

static void ptp_clock_unregister_all(struct idtcm *idtcm)
{
	u8 i;
	struct idtcm_channel *channel;

	for (i = 0; i < MAX_TOD; i++) {
		channel = &idtcm->channel[i];
		if (channel->ptp_clock)
			ptp_clock_unregister(channel->ptp_clock);
	}
}

static void set_default_masks(struct idtcm *idtcm)
{
	idtcm->tod_mask = DEFAULT_TOD_MASK;
	idtcm->extts_mask = 0;

	idtcm->channel[0].pll = DEFAULT_TOD0_PTP_PLL;
	idtcm->channel[1].pll = DEFAULT_TOD1_PTP_PLL;
	idtcm->channel[2].pll = DEFAULT_TOD2_PTP_PLL;
	idtcm->channel[3].pll = DEFAULT_TOD3_PTP_PLL;

	idtcm->channel[0].output_mask = DEFAULT_OUTPUT_MASK_PLL0;
	idtcm->channel[1].output_mask = DEFAULT_OUTPUT_MASK_PLL1;
	idtcm->channel[2].output_mask = DEFAULT_OUTPUT_MASK_PLL2;
	idtcm->channel[3].output_mask = DEFAULT_OUTPUT_MASK_PLL3;
}

static int idtcm_probe(struct platform_device *pdev)
{
	struct rsmu_ddata *ddata = dev_get_drvdata(pdev->dev.parent);
	struct idtcm *idtcm;
	int err;
	u8 i;

	idtcm = devm_kzalloc(&pdev->dev, sizeof(struct idtcm), GFP_KERNEL);

	if (!idtcm)
		return -ENOMEM;

	idtcm->dev = &pdev->dev;
	idtcm->mfd = pdev->dev.parent;
	idtcm->lock = &ddata->lock;
	idtcm->regmap = ddata->regmap;
	idtcm->calculate_overhead_flag = 0;

	INIT_DELAYED_WORK(&idtcm->extts_work, idtcm_extts_check);

	set_default_masks(idtcm);

	mutex_lock(idtcm->lock);

	idtcm_set_version_info(idtcm);

	err = idtcm_load_firmware(idtcm, &pdev->dev);

	if (err)
		dev_warn(idtcm->dev, "loading firmware failed with %d", err);

	wait_for_chip_ready(idtcm);

	if (idtcm->tod_mask) {
		for (i = 0; i < MAX_TOD; i++) {
			if (idtcm->tod_mask & (1 << i))
				err = idtcm_enable_channel(idtcm, i);
			else
				err = idtcm_enable_extts_channel(idtcm, i);
			if (err) {
				dev_err(idtcm->dev,
					"idtcm_enable_channel %d failed!", i);
				break;
			}
		}
	} else {
		dev_err(idtcm->dev,
			"no PLLs flagged as PHCs, nothing to do");
		err = -ENODEV;
	}

	mutex_unlock(idtcm->lock);

	if (err) {
		ptp_clock_unregister_all(idtcm);
		return err;
	}

	platform_set_drvdata(pdev, idtcm);

	return 0;
}

static int idtcm_remove(struct platform_device *pdev)
{
	struct idtcm *idtcm = platform_get_drvdata(pdev);

	ptp_clock_unregister_all(idtcm);

	cancel_delayed_work_sync(&idtcm->extts_work);

	return 0;
}

static struct platform_driver idtcm_driver = {
	.driver = {
		.name = "8a3400x-phc",
	},
	.probe = idtcm_probe,
	.remove	= idtcm_remove,
};

module_platform_driver(idtcm_driver);
