// SPDX-License-Identifier: GPL-2.0+
/*
 * PTP hardware clock driver for the FemtoClock3 family of timing and
 * synchronization devices.
 *
 * Copyright (C) 2023 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/bitfield.h>
#include <linux/mfd/rsmu.h>
#include <linux/mfd/idtRC38xxx_reg.h>
#include <linux/unaligned.h>

#include "ptp_private.h"
#include "ptp_fc3.h"

MODULE_DESCRIPTION("Driver for IDT FemtoClock3(TM) family");
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);

static s64 ns2counters(struct idtfc3 *idtfc3, s64 nsec, u32 *sub_ns)
{
	s64 sync;
	s32 rem;

	if (likely(nsec >= 0)) {
		sync = div_u64_rem(nsec, idtfc3->ns_per_sync, &rem);
		*sub_ns = rem;
	} else {
		sync = -div_u64_rem(-nsec - 1, idtfc3->ns_per_sync, &rem) - 1;
		*sub_ns = idtfc3->ns_per_sync - rem - 1;
	}

	return sync * idtfc3->ns_per_sync;
}

static s64 tdc_meas2offset(struct idtfc3 *idtfc3, u64 meas_read)
{
	s64 coarse, fine;

	fine = FIELD_GET_SIGNED(FINE_MEAS_MASK, meas_read);
	coarse = FIELD_GET_SIGNED(COARSE_MEAS_MASK, meas_read);

	fine = div64_s64(fine * NSEC_PER_SEC, idtfc3->tdc_apll_freq * 62LL);
	coarse = div64_s64(coarse * NSEC_PER_SEC, idtfc3->time_ref_freq);

	return coarse + fine;
}

static s64 tdc_offset2phase(struct idtfc3 *idtfc3, s64 offset_ns)
{
	if (offset_ns > idtfc3->ns_per_sync / 2)
		offset_ns -= idtfc3->ns_per_sync;

	return offset_ns * idtfc3->tdc_offset_sign;
}

static int idtfc3_set_lpf_mode(struct idtfc3 *idtfc3, u8 mode)
{
	int err;

	if (mode >= LPF_INVALID)
		return -EINVAL;

	if (idtfc3->lpf_mode == mode)
		return 0;

	err = regmap_bulk_write(idtfc3->regmap, LPF_MODE_CNFG, &mode, sizeof(mode));
	if (err)
		return err;

	idtfc3->lpf_mode = mode;

	return 0;
}

static int idtfc3_enable_lpf(struct idtfc3 *idtfc3, bool enable)
{
	u8 val;
	int err;

	err = regmap_bulk_read(idtfc3->regmap, LPF_CTRL, &val, sizeof(val));
	if (err)
		return err;

	if (enable == true)
		val |= LPF_EN;
	else
		val &= ~LPF_EN;

	return regmap_bulk_write(idtfc3->regmap, LPF_CTRL, &val, sizeof(val));
}

static int idtfc3_get_time_ref_freq(struct idtfc3 *idtfc3)
{
	int err;
	u8 buf[4];
	u8 time_ref_div;
	u8 time_clk_div;

	err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_MEAS_DIV_CNFG, buf, sizeof(buf));
	if (err)
		return err;
	time_ref_div = FIELD_GET(TIME_REF_DIV_MASK, get_unaligned_le32(buf)) + 1;

	err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_COUNT, buf, 1);
	if (err)
		return err;
	time_clk_div = (buf[0] & TIME_CLOCK_COUNT_MASK) + 1;
	idtfc3->time_ref_freq = idtfc3->hw_param.time_clk_freq *
				time_clk_div / time_ref_div;

	return 0;
}

static int idtfc3_get_tdc_offset_sign(struct idtfc3 *idtfc3)
{
	int err;
	u8 buf[4];
	u32 val;
	u8 sig1, sig2;

	err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_TDC_FANOUT_CNFG, buf, sizeof(buf));
	if (err)
		return err;

	val = get_unaligned_le32(buf);
	if ((val & TIME_SYNC_TO_TDC_EN) != TIME_SYNC_TO_TDC_EN) {
		dev_err(idtfc3->dev, "TIME_SYNC_TO_TDC_EN is off !!!");
		return -EINVAL;
	}

	sig1 = FIELD_GET(SIG1_MUX_SEL_MASK, val);
	sig2 = FIELD_GET(SIG2_MUX_SEL_MASK, val);

	if ((sig1 == sig2) || ((sig1 != TIME_SYNC) && (sig2 != TIME_SYNC))) {
		dev_err(idtfc3->dev, "Invalid tdc_mux_sel sig1=%d sig2=%d", sig1, sig2);
		return -EINVAL;
	} else if (sig1 == TIME_SYNC) {
		idtfc3->tdc_offset_sign = 1;
	} else if (sig2 == TIME_SYNC) {
		idtfc3->tdc_offset_sign = -1;
	}

	return 0;
}

static int idtfc3_lpf_bw(struct idtfc3 *idtfc3, u8 shift, u8 mult)
{
	u8 val = FIELD_PREP(LPF_BW_SHIFT, shift) | FIELD_PREP(LPF_BW_MULT, mult);

	return regmap_bulk_write(idtfc3->regmap, LPF_BW_CNFG, &val, sizeof(val));
}

static int idtfc3_enable_tdc(struct idtfc3 *idtfc3, bool enable, u8 meas_mode)
{
	int err;
	u8 val = 0;

	/* Disable TDC first */
	err = regmap_bulk_write(idtfc3->regmap, TIME_CLOCK_MEAS_CTRL, &val, sizeof(val));
	if (err)
		return err;

	if (enable == false)
		return idtfc3_lpf_bw(idtfc3, LPF_BW_SHIFT_DEFAULT, LPF_BW_MULT_DEFAULT);

	if (meas_mode >= MEAS_MODE_INVALID)
		return -EINVAL;

	/* Change TDC meas mode */
	err = regmap_bulk_write(idtfc3->regmap, TIME_CLOCK_MEAS_CNFG,
				&meas_mode, sizeof(meas_mode));
	if (err)
		return err;

	/* Enable TDC */
	val = TDC_MEAS_EN;
	if (meas_mode == CONTINUOUS)
		val |= TDC_MEAS_START;
	err = regmap_bulk_write(idtfc3->regmap, TIME_CLOCK_MEAS_CTRL, &val, sizeof(val));
	if (err)
		return err;

	return idtfc3_lpf_bw(idtfc3, LPF_BW_SHIFT_1PPS, LPF_BW_MULT_DEFAULT);
}

static bool get_tdc_meas(struct idtfc3 *idtfc3, s64 *offset_ns)
{
	bool valid = false;
	u8 buf[9];
	u8 val;
	int err;

	while (true) {
		err = regmap_bulk_read(idtfc3->regmap, TDC_FIFO_STS,
				       &val, sizeof(val));
		if (err)
			return false;

		if (val & FIFO_EMPTY)
			break;

		err = regmap_bulk_read(idtfc3->regmap, TDC_FIFO_READ_REQ,
				       &buf, sizeof(buf));
		if (err)
			return false;

		valid = true;
	}

	if (valid)
		*offset_ns = tdc_meas2offset(idtfc3, get_unaligned_le64(&buf[1]));

	return valid;
}

static int check_tdc_fifo_overrun(struct idtfc3 *idtfc3)
{
	u8 val;
	int err;

	/* Check if FIFO is overrun */
	err = regmap_bulk_read(idtfc3->regmap, TDC_FIFO_STS, &val, sizeof(val));
	if (err)
		return err;

	if (!(val & FIFO_FULL))
		return 0;

	dev_warn(idtfc3->dev, "TDC FIFO overrun !!!");

	err = idtfc3_enable_tdc(idtfc3, true, CONTINUOUS);
	if (err)
		return err;

	return 0;
}

static int get_tdc_meas_continuous(struct idtfc3 *idtfc3)
{
	int err;
	s64 offset_ns;
	struct ptp_clock_event event;

	err = check_tdc_fifo_overrun(idtfc3);
	if (err)
		return err;

	if (get_tdc_meas(idtfc3, &offset_ns) && offset_ns >= 0) {
		event.index = 0;
		event.offset = tdc_offset2phase(idtfc3, offset_ns);
		event.type = PTP_CLOCK_EXTOFF;
		ptp_clock_event(idtfc3->ptp_clock, &event);
	}

	return 0;
}

static int idtfc3_read_subcounter(struct idtfc3 *idtfc3)
{
	u8 buf[5] = {0};
	int err;

	err = regmap_bulk_read(idtfc3->regmap, TOD_COUNTER_READ_REQ,
			       &buf, sizeof(buf));
	if (err)
		return err;

	/* sync_counter_value is [31:82] and sub_sync_counter_value is [0:30] */
	return get_unaligned_le32(&buf[1]) & SUB_SYNC_COUNTER_MASK;
}

static int idtfc3_tod_update_is_done(struct idtfc3 *idtfc3)
{
	int err;
	u8 req;

	err = read_poll_timeout_atomic(regmap_bulk_read, err, !req, USEC_PER_MSEC,
				       idtfc3->tc_write_timeout, true, idtfc3->regmap,
				       TOD_SYNC_LOAD_REQ_CTRL, &req, 1);
	if (err)
		dev_err(idtfc3->dev, "TOD counter write timeout !!!");

	return err;
}

static int idtfc3_write_subcounter(struct idtfc3 *idtfc3, u32 counter)
{
	u8 buf[18] = {0};
	int err;

	/* sync_counter_value is [31:82] and sub_sync_counter_value is [0:30] */
	put_unaligned_le32(counter & SUB_SYNC_COUNTER_MASK, &buf[0]);

	buf[16] = SUB_SYNC_LOAD_ENABLE | SYNC_LOAD_ENABLE;
	buf[17] = SYNC_LOAD_REQ;

	err = regmap_bulk_write(idtfc3->regmap, TOD_SYNC_LOAD_VAL_CTRL,
				&buf, sizeof(buf));
	if (err)
		return err;

	return idtfc3_tod_update_is_done(idtfc3);
}

static int idtfc3_timecounter_update(struct idtfc3 *idtfc3, u32 counter, s64 ns)
{
	int err;

	err = idtfc3_write_subcounter(idtfc3, counter);
	if (err)
		return err;

	/* Update time counter */
	idtfc3->ns = ns;
	idtfc3->last_counter = counter;

	return 0;
}

static int idtfc3_timecounter_read(struct idtfc3 *idtfc3)
{
	int now, delta;

	now = idtfc3_read_subcounter(idtfc3);
	if (now < 0)
		return now;

	/* calculate the delta since the last idtfc3_timecounter_read(): */
	if (now >= idtfc3->last_counter)
		delta = now - idtfc3->last_counter;
	else
		delta = idtfc3->sub_sync_count - idtfc3->last_counter + now;

	/* Update time counter */
	idtfc3->ns += delta * idtfc3->ns_per_counter;
	idtfc3->last_counter = now;

	return 0;
}

static int _idtfc3_gettime(struct idtfc3 *idtfc3, struct timespec64 *ts)
{
	int err;

	err = idtfc3_timecounter_read(idtfc3);
	if (err)
		return err;

	*ts = ns_to_timespec64(idtfc3->ns);

	return 0;
}

static int idtfc3_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	int err;

	mutex_lock(idtfc3->lock);
	err = _idtfc3_gettime(idtfc3, ts);
	mutex_unlock(idtfc3->lock);

	return err;
}

static int _idtfc3_settime(struct idtfc3 *idtfc3, const struct timespec64 *ts)
{
	s64 offset_ns, now_ns;
	u32 counter, sub_ns;
	int now;

	if (timespec64_valid(ts) == false) {
		dev_err(idtfc3->dev, "%s: invalid timespec", __func__);
		return -EINVAL;
	}

	now = idtfc3_read_subcounter(idtfc3);
	if (now < 0)
		return now;

	offset_ns = (idtfc3->sub_sync_count - now) * idtfc3->ns_per_counter;
	now_ns = timespec64_to_ns(ts);
	(void)ns2counters(idtfc3, offset_ns + now_ns, &sub_ns);

	counter = sub_ns / idtfc3->ns_per_counter;
	return idtfc3_timecounter_update(idtfc3, counter, now_ns);
}

static int idtfc3_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	int err;

	mutex_lock(idtfc3->lock);
	err = _idtfc3_settime(idtfc3, ts);
	mutex_unlock(idtfc3->lock);

	return err;
}

static int _idtfc3_adjtime(struct idtfc3 *idtfc3, s64 delta)
{
	/*
	 * The TOD counter can be synchronously loaded with any value,
	 * to be loaded on the next Time Sync pulse
	 */
	s64 sync_ns;
	u32 sub_ns;
	u32 counter;

	if (idtfc3->ns + delta < 0) {
		dev_err(idtfc3->dev, "%lld ns adj is too large", delta);
		return -EINVAL;
	}

	sync_ns = ns2counters(idtfc3, delta + idtfc3->ns_per_sync, &sub_ns);

	counter = sub_ns / idtfc3->ns_per_counter;
	return idtfc3_timecounter_update(idtfc3, counter, idtfc3->ns + sync_ns +
									counter * idtfc3->ns_per_counter);
}

static int idtfc3_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	int err;

	mutex_lock(idtfc3->lock);
	err = _idtfc3_adjtime(idtfc3, delta);
	mutex_unlock(idtfc3->lock);

	return err;
}

static int _idtfc3_adjphase(struct idtfc3 *idtfc3, s32 delta)
{
	u8 buf[8] = {0};
	int err;
	s64 pcw;

	err = idtfc3_set_lpf_mode(idtfc3, LPF_WP);
	if (err)
		return err;

	/*
	 * Phase Control Word unit is: 10^9 / (TDC_APLL_FREQ * 124)
	 *
	 *       delta * TDC_APLL_FREQ * 124
	 * PCW = ---------------------------
	 *                  10^9
	 *
	 */
	pcw = div_s64((s64)delta * idtfc3->tdc_apll_freq * 124, NSEC_PER_SEC);

	put_unaligned_le64(pcw, buf);

	return regmap_bulk_write(idtfc3->regmap, LPF_WR_PHASE_CTRL, buf, sizeof(buf));
}

static int idtfc3_adjphase(struct ptp_clock_info *ptp, s32 delta)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	int err;

	mutex_lock(idtfc3->lock);
	err = _idtfc3_adjphase(idtfc3, delta);
	mutex_unlock(idtfc3->lock);

	return err;
}

static int _idtfc3_adjfine(struct idtfc3 *idtfc3, long scaled_ppm)
{
	u8 buf[8] = {0};
	int err;
	s64 fcw;

	err = idtfc3_set_lpf_mode(idtfc3, LPF_WF);
	if (err)
		return err;

	/*
	 * Frequency Control Word unit is: 2^-44 * 10^6 ppm
	 *
	 * adjfreq:
	 *       ppb * 2^44
	 * FCW = ----------
	 *          10^9
	 *
	 * adjfine:
	 *       ppm_16 * 2^28
	 * FCW = -------------
	 *           10^6
	 */
	fcw = scaled_ppm * BIT(28);
	fcw = div_s64(fcw, 1000000);

	put_unaligned_le64(fcw, buf);

	return regmap_bulk_write(idtfc3->regmap, LPF_WR_FREQ_CTRL, buf, sizeof(buf));
}

static int idtfc3_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	int err;

	mutex_lock(idtfc3->lock);
	err = _idtfc3_adjfine(idtfc3, scaled_ppm);
	mutex_unlock(idtfc3->lock);

	return err;
}

static int idtfc3_enable(struct ptp_clock_info *ptp,
			 struct ptp_clock_request *rq, int on)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	int err = -EOPNOTSUPP;

	mutex_lock(idtfc3->lock);
	switch (rq->type) {
	case PTP_CLK_REQ_PEROUT:
		if (!on)
			err = 0;
		/* 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 = 0;
		break;
	case PTP_CLK_REQ_EXTTS:
		if (on) {
			/* Only accept requests for external phase offset */
			if ((rq->extts.flags & PTP_EXT_OFFSET) != (PTP_EXT_OFFSET))
				err = -EOPNOTSUPP;
			else
				err = idtfc3_enable_tdc(idtfc3, true, CONTINUOUS);
		} else {
			err = idtfc3_enable_tdc(idtfc3, false, MEAS_MODE_INVALID);
		}
		break;
	default:
		break;
	}
	mutex_unlock(idtfc3->lock);

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

	return err;
}

static long idtfc3_aux_work(struct ptp_clock_info *ptp)
{
	struct idtfc3 *idtfc3 = container_of(ptp, struct idtfc3, caps);
	static int tdc_get;

	mutex_lock(idtfc3->lock);
	tdc_get %= TDC_GET_PERIOD;
	if ((tdc_get == 0) || (tdc_get == TDC_GET_PERIOD / 2))
		idtfc3_timecounter_read(idtfc3);
	get_tdc_meas_continuous(idtfc3);
	tdc_get++;
	mutex_unlock(idtfc3->lock);

	return idtfc3->tc_update_period;
}

static const struct ptp_clock_info idtfc3_caps = {
	.owner		= THIS_MODULE,
	.max_adj	= MAX_FFO_PPB,
	.n_per_out	= 1,
	.n_ext_ts	= 1,
	.supported_extts_flags = PTP_STRICT_FLAGS | PTP_EXT_OFFSET,
	.adjphase	= &idtfc3_adjphase,
	.adjfine	= &idtfc3_adjfine,
	.adjtime	= &idtfc3_adjtime,
	.gettime64	= &idtfc3_gettime,
	.settime64	= &idtfc3_settime,
	.enable		= &idtfc3_enable,
	.do_aux_work	= &idtfc3_aux_work,
};

static int idtfc3_hw_calibrate(struct idtfc3 *idtfc3)
{
	int err = 0;
	u8 val;

	mdelay(10);
	/*
	 * Toggle TDC_DAC_RECAL_REQ:
	 * (1) set tdc_en to 1
	 * (2) set tdc_dac_recal_req to 0
	 * (3) set tdc_dac_recal_req to 1
	 */
	val = TDC_EN;
	err = regmap_bulk_write(idtfc3->regmap, TDC_CTRL,
				&val, sizeof(val));
	if (err)
		return err;
	val = TDC_EN | TDC_DAC_RECAL_REQ;
	err = regmap_bulk_write(idtfc3->regmap, TDC_CTRL,
				&val, sizeof(val));
	if (err)
		return err;
	mdelay(10);

	/*
	 * Toggle APLL_REINIT:
	 * (1) set apll_reinit to 0
	 * (2) set apll_reinit to 1
	 */
	val = 0;
	err = regmap_bulk_write(idtfc3->regmap, SOFT_RESET_CTRL,
				&val, sizeof(val));
	if (err)
		return err;
	val = APLL_REINIT;
	err = regmap_bulk_write(idtfc3->regmap, SOFT_RESET_CTRL,
				&val, sizeof(val));
	if (err)
		return err;
	mdelay(10);

	return err;
}

static int idtfc3_init_timecounter(struct idtfc3 *idtfc3)
{
	int err;
	u32 period_ms;

	period_ms = idtfc3->sub_sync_count * MSEC_PER_SEC /
			idtfc3->hw_param.time_clk_freq;

	idtfc3->tc_update_period = msecs_to_jiffies(period_ms / TDC_GET_PERIOD);
	idtfc3->tc_write_timeout = period_ms * USEC_PER_MSEC;

	err = idtfc3_timecounter_update(idtfc3, 0, 0);
	if (err)
		return err;

	err = idtfc3_timecounter_read(idtfc3);
	if (err)
		return err;

	return 0;
}

static int idtfc3_get_tdc_apll_freq(struct idtfc3 *idtfc3)
{
	int err;
	u8 tdc_fb_div_int;
	u8 tdc_ref_div;
	struct idtfc3_hw_param *param = &idtfc3->hw_param;

	err = regmap_bulk_read(idtfc3->regmap, TDC_REF_DIV_CNFG,
				&tdc_ref_div, sizeof(tdc_ref_div));
	if (err)
		return err;

	err = regmap_bulk_read(idtfc3->regmap, TDC_FB_DIV_INT_CNFG,
				&tdc_fb_div_int, sizeof(tdc_fb_div_int));
	if (err)
		return err;

	tdc_fb_div_int &= TDC_FB_DIV_INT_MASK;
	tdc_ref_div &= TDC_REF_DIV_CONFIG_MASK;

	idtfc3->tdc_apll_freq = div_u64(param->xtal_freq * (u64)tdc_fb_div_int,
					1 << tdc_ref_div);

	return 0;
}

static int idtfc3_get_fod(struct idtfc3 *idtfc3)
{
	int err;
	u8 fod;

	err = regmap_bulk_read(idtfc3->regmap, TIME_CLOCK_SRC, &fod, sizeof(fod));
	if (err)
		return err;

	switch (fod) {
	case 0:
		idtfc3->fod_n = FOD_0;
		break;
	case 1:
		idtfc3->fod_n = FOD_1;
		break;
	case 2:
		idtfc3->fod_n = FOD_2;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int idtfc3_get_sync_count(struct idtfc3 *idtfc3)
{
	int err;
	u8 buf[4];

	err = regmap_bulk_read(idtfc3->regmap, SUB_SYNC_GEN_CNFG, buf, sizeof(buf));
	if (err)
		return err;

	idtfc3->sub_sync_count = (get_unaligned_le32(buf) & SUB_SYNC_COUNTER_MASK) + 1;
	idtfc3->ns_per_counter = NSEC_PER_SEC / idtfc3->hw_param.time_clk_freq;
	idtfc3->ns_per_sync = idtfc3->sub_sync_count * idtfc3->ns_per_counter;

	return 0;
}

static int idtfc3_setup_hw_param(struct idtfc3 *idtfc3)
{
	int err;

	err = idtfc3_get_fod(idtfc3);
	if (err)
		return err;

	err = idtfc3_get_sync_count(idtfc3);
	if (err)
		return err;

	err = idtfc3_get_time_ref_freq(idtfc3);
	if (err)
		return err;

	return idtfc3_get_tdc_apll_freq(idtfc3);
}

static int idtfc3_configure_hw(struct idtfc3 *idtfc3)
{
	int err = 0;

	err = idtfc3_hw_calibrate(idtfc3);
	if (err)
		return err;

	err = idtfc3_enable_lpf(idtfc3, true);
	if (err)
		return err;

	err = idtfc3_enable_tdc(idtfc3, false, MEAS_MODE_INVALID);
	if (err)
		return err;

	err = idtfc3_get_tdc_offset_sign(idtfc3);
	if (err)
		return err;

	return idtfc3_setup_hw_param(idtfc3);
}

static int idtfc3_set_overhead(struct idtfc3 *idtfc3)
{
	s64 current_ns = 0;
	s64 lowest_ns = 0;
	int err;
	u8 i;
	ktime_t start;
	ktime_t stop;
	ktime_t diff;

	char buf[18] = {0};

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

		err = regmap_bulk_write(idtfc3->regmap, TOD_SYNC_LOAD_VAL_CTRL,
					&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;
		}
	}

	idtfc3->tod_write_overhead = lowest_ns;

	return err;
}

static int idtfc3_enable_ptp(struct idtfc3 *idtfc3)
{
	int err;

	idtfc3->caps = idtfc3_caps;
	snprintf(idtfc3->caps.name, sizeof(idtfc3->caps.name), "IDT FC3W");
	err = idtfc3_set_overhead(idtfc3);
	if (err)
		return err;

	err = idtfc3_init_timecounter(idtfc3);
	if (err)
		return err;

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

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

	ptp_schedule_worker(idtfc3->ptp_clock, idtfc3->tc_update_period);

	dev_info(idtfc3->dev, "TIME_SYNC_CHANNEL registered as ptp%d",
		 idtfc3->ptp_clock->index);

	return 0;
}

static int idtfc3_load_firmware(struct idtfc3 *idtfc3)
{
	char fname[128] = FW_FILENAME;
	const struct firmware *fw;
	struct idtfc3_fwrc *rec;
	u16 addr;
	u8 val;
	int err;
	s32 len;

	idtfc3_default_hw_param(&idtfc3->hw_param);

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

	dev_info(idtfc3->dev, "requesting firmware '%s'\n", fname);

	err = request_firmware(&fw, fname, idtfc3->dev);

	if (err) {
		dev_err(idtfc3->dev,
			"requesting firmware failed with err %d!\n", err);
		return err;
	}

	dev_dbg(idtfc3->dev, "firmware size %zu bytes\n", fw->size);

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

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

			rec++;

			err = idtfc3_set_hw_param(&idtfc3->hw_param, addr, val);
		}

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

			/* Max register */
			if (addr >= 0xE88)
				continue;

			err = regmap_bulk_write(idtfc3->regmap, addr,
						&val, sizeof(val));
		}

		if (err)
			goto out;
	}

	err = idtfc3_configure_hw(idtfc3);
out:
	release_firmware(fw);
	return err;
}

static int idtfc3_read_device_id(struct idtfc3 *idtfc3, u16 *device_id)
{
	int err;
	u8 buf[2] = {0};

	err = regmap_bulk_read(idtfc3->regmap, DEVICE_ID,
			       &buf, sizeof(buf));
	if (err) {
		dev_err(idtfc3->dev, "%s failed with %d", __func__, err);
		return err;
	}

	*device_id = get_unaligned_le16(buf);

	return 0;
}

static int idtfc3_check_device_compatibility(struct idtfc3 *idtfc3)
{
	int err;
	u16 device_id;

	err = idtfc3_read_device_id(idtfc3, &device_id);
	if (err)
		return err;

	if ((device_id & DEVICE_ID_MASK) == 0) {
		dev_err(idtfc3->dev, "invalid device");
		return -EINVAL;
	}

	return 0;
}

static int idtfc3_probe(struct platform_device *pdev)
{
	struct rsmu_ddata *ddata = dev_get_drvdata(pdev->dev.parent);
	struct idtfc3 *idtfc3;
	int err;

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

	if (!idtfc3)
		return -ENOMEM;

	idtfc3->dev = &pdev->dev;
	idtfc3->mfd = pdev->dev.parent;
	idtfc3->lock = &ddata->lock;
	idtfc3->regmap = ddata->regmap;

	mutex_lock(idtfc3->lock);

	err = idtfc3_check_device_compatibility(idtfc3);
	if (err) {
		mutex_unlock(idtfc3->lock);
		return err;
	}

	err = idtfc3_load_firmware(idtfc3);
	if (err) {
		if (err == -ENOENT) {
			mutex_unlock(idtfc3->lock);
			return -EPROBE_DEFER;
		}
		dev_warn(idtfc3->dev, "loading firmware failed with %d", err);
	}

	err = idtfc3_enable_ptp(idtfc3);
	if (err) {
		dev_err(idtfc3->dev, "idtfc3_enable_ptp failed with %d", err);
		mutex_unlock(idtfc3->lock);
		return err;
	}

	mutex_unlock(idtfc3->lock);

	platform_set_drvdata(pdev, idtfc3);

	return 0;
}

static void idtfc3_remove(struct platform_device *pdev)
{
	struct idtfc3 *idtfc3 = platform_get_drvdata(pdev);

	ptp_clock_unregister(idtfc3->ptp_clock);
}

static struct platform_driver idtfc3_driver = {
	.driver = {
		.name = "rc38xxx-phc",
	},
	.probe = idtfc3_probe,
	.remove = idtfc3_remove,
};

module_platform_driver(idtfc3_driver);
