in microchip-tcb-capture.c [84:144]
static int mchp_tc_count_function_write(struct counter_device *counter,
struct counter_count *count,
enum counter_function function)
{
struct mchp_tc_data *const priv = counter_priv(counter);
u32 bmr, cmr;
regmap_read(priv->regmap, ATMEL_TC_BMR, &bmr);
regmap_read(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), &cmr);
/* Set capture mode */
cmr &= ~ATMEL_TC_WAVE;
switch (function) {
case COUNTER_FUNCTION_INCREASE:
priv->qdec_mode = 0;
/* Set highest rate based on whether soc has gclk or not */
bmr &= ~(ATMEL_TC_QDEN | ATMEL_TC_POSEN);
if (priv->tc_cfg->has_gclk)
cmr |= ATMEL_TC_TIMER_CLOCK2;
else
cmr |= ATMEL_TC_TIMER_CLOCK1;
/* Setup the period capture mode */
cmr |= ATMEL_TC_CMR_MASK;
cmr &= ~(ATMEL_TC_ABETRG | ATMEL_TC_XC0);
break;
case COUNTER_FUNCTION_QUADRATURE_X4:
if (!priv->tc_cfg->has_qdec)
return -EINVAL;
/* In QDEC mode settings both channels 0 and 1 are required */
if (priv->num_channels < 2 || priv->channel[0] != 0 ||
priv->channel[1] != 1) {
pr_err("Invalid channels number or id for quadrature mode\n");
return -EINVAL;
}
priv->qdec_mode = 1;
bmr |= ATMEL_TC_QDEN | ATMEL_TC_POSEN;
cmr |= ATMEL_TC_ETRGEDG_RISING | ATMEL_TC_ABETRG | ATMEL_TC_XC0;
break;
default:
/* should never reach this path */
return -EINVAL;
}
regmap_write(priv->regmap, ATMEL_TC_BMR, bmr);
regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], CMR), cmr);
/* Enable clock and trigger counter */
regmap_write(priv->regmap, ATMEL_TC_REG(priv->channel[0], CCR),
ATMEL_TC_CLKEN | ATMEL_TC_SWTRG);
if (priv->qdec_mode) {
regmap_write(priv->regmap,
ATMEL_TC_REG(priv->channel[1], CMR), cmr);
regmap_write(priv->regmap,
ATMEL_TC_REG(priv->channel[1], CCR),
ATMEL_TC_CLKEN | ATMEL_TC_SWTRG);
}
return 0;
}