drivers/ptp/ptp_fc3.c

Source file repositories/reference/linux-study-clean/drivers/ptp/ptp_fc3.c

File Facts

System
Linux kernel
Corpus path
drivers/ptp/ptp_fc3.c
Extension
.c
Size
21557 bytes
Lines
1011
Domain
Driver Families
Bucket
drivers/ptp
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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)

Annotation

Implementation Notes