arch/arm/samv7: fix issue when AFEC1 driver failed to open second time

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko 2023-01-25 17:44:03 +02:00 committed by Xiang Xiao
parent 5f55290e41
commit be10056702

View File

@ -161,91 +161,91 @@ static int afec_interrupt(int irq, void *context, void *arg);
static const struct adc_ops_s g_adcops = static const struct adc_ops_s g_adcops =
{ {
.ao_bind = afec_bind, .ao_bind = afec_bind,
.ao_reset = afec_reset, .ao_reset = afec_reset,
.ao_setup = afec_setup, .ao_setup = afec_setup,
.ao_shutdown = afec_shutdown, .ao_shutdown = afec_shutdown,
.ao_rxint = afec_rxint, .ao_rxint = afec_rxint,
.ao_ioctl = afec_ioctl, .ao_ioctl = afec_ioctl,
}; };
#ifdef CONFIG_SAMV7_AFEC0 #ifdef CONFIG_SAMV7_AFEC0
static struct samv7_dev_s g_adcpriv0 = static struct samv7_dev_s g_adcpriv0 =
{ {
.irq = SAM_IRQ_AFEC0, .irq = SAM_IRQ_AFEC0,
.pid = SAM_PID_AFEC0, .pid = SAM_PID_AFEC0,
.intf = 0, .intf = 0,
.initialized = 0, .initialized = 0,
.resolution = CONFIG_SAMV7_AFEC0_RES, .resolution = CONFIG_SAMV7_AFEC0_RES,
#ifdef CONFIG_SAMV7_AFEC0_SWTRIG #ifdef CONFIG_SAMV7_AFEC0_SWTRIG
.trigger = 0, .trigger = 0,
#else #else
.trigger = 1, .trigger = 1,
.timer_channel = CONFIG_SAMV7_AFEC0_TIOACHAN, .timer_channel = CONFIG_SAMV7_AFEC0_TIOACHAN,
.frequency = CONFIG_SAMV7_AFEC0_TIOAFREQ, .frequency = CONFIG_SAMV7_AFEC0_TIOAFREQ,
#endif #endif
.base = SAM_AFEC0_BASE, .base = SAM_AFEC0_BASE,
}; };
static struct adc_dev_s g_adcdev0 = static struct adc_dev_s g_adcdev0 =
{ {
.ad_ops = &g_adcops, .ad_ops = &g_adcops,
.ad_priv = &g_adcpriv0, .ad_priv = &g_adcpriv0,
}; };
gpio_pinset_t g_adcpinlist0[ADC_MAX_CHANNELS] = gpio_pinset_t g_adcpinlist0[ADC_MAX_CHANNELS] =
{ {
GPIO_AFE0_AD0, GPIO_AFE0_AD0,
GPIO_AFE0_AD1, GPIO_AFE0_AD1,
GPIO_AFE0_AD2, GPIO_AFE0_AD2,
GPIO_AFE0_AD3, GPIO_AFE0_AD3,
GPIO_AFE0_AD4, GPIO_AFE0_AD4,
GPIO_AFE0_AD5, GPIO_AFE0_AD5,
GPIO_AFE0_AD6, GPIO_AFE0_AD6,
GPIO_AFE0_AD7, GPIO_AFE0_AD7,
GPIO_AFE0_AD8, GPIO_AFE0_AD8,
GPIO_AFE0_AD9, GPIO_AFE0_AD9,
GPIO_AFE0_AD10, GPIO_AFE0_AD10,
}; };
#endif #endif
#ifdef CONFIG_SAMV7_AFEC1 #ifdef CONFIG_SAMV7_AFEC1
static struct samv7_dev_s g_adcpriv1 = static struct samv7_dev_s g_adcpriv1 =
{ {
.irq = SAM_IRQ_AFEC1, .irq = SAM_IRQ_AFEC1,
.pid = SAM_PID_AFEC1, .pid = SAM_PID_AFEC1,
.intf = 1, .intf = 1,
.initialized = 0, .initialized = 0,
.resolution = CONFIG_SAMV7_AFEC1_RES, .resolution = CONFIG_SAMV7_AFEC1_RES,
#ifdef CONFIG_SAMV7_AFEC1_SWTRIG #ifdef CONFIG_SAMV7_AFEC1_SWTRIG
.trigger = 0, .trigger = 0,
#else #else
.trigger = 1, .trigger = 1,
.timer_channel = CONFIG_SAMV7_AFEC1_TIOACHAN, .timer_channel = CONFIG_SAMV7_AFEC1_TIOACHAN,
.frequency = CONFIG_SAMV7_AFEC1_TIOAFREQ, .frequency = CONFIG_SAMV7_AFEC1_TIOAFREQ,
#endif #endif
.base = SAM_AFEC1_BASE, .base = SAM_AFEC1_BASE,
}; };
static struct adc_dev_s g_adcdev1 = static struct adc_dev_s g_adcdev1 =
{ {
.ad_ops = &g_adcops, .ad_ops = &g_adcops,
.ad_priv = &g_adcpriv1, .ad_priv = &g_adcpriv1,
}; };
gpio_pinset_t g_adcpinlist1[ADC_MAX_CHANNELS] = gpio_pinset_t g_adcpinlist1[ADC_MAX_CHANNELS] =
{ {
GPIO_AFE1_AD0, GPIO_AFE1_AD0,
GPIO_AFE1_AD1, GPIO_AFE1_AD1,
GPIO_AFE1_AD2, GPIO_AFE1_AD2,
GPIO_AFE1_AD3, GPIO_AFE1_AD3,
GPIO_AFE1_AD4, GPIO_AFE1_AD4,
GPIO_AFE1_AD5, GPIO_AFE1_AD5,
GPIO_AFE1_AD6, GPIO_AFE1_AD6,
GPIO_AFE1_AD7, GPIO_AFE1_AD7,
GPIO_AFE1_AD8, GPIO_AFE1_AD8,
GPIO_AFE1_AD9, GPIO_AFE1_AD9,
GPIO_AFE1_AD10, GPIO_AFE1_AD10,
}; };
#endif #endif
@ -638,22 +638,19 @@ static int sam_afec_trigger(struct samv7_dev_s *priv)
return ret; return ret;
} }
/* AFEC_MR registr still needs to select corresponding channels with /* Set trigger for AFECn driver
* 1, 2, 3 values (see TRGSEL bitfield description) even if channels *
* 3, 4 and 5 are selected for AFEC1 * Note: AFEC_MR register still needs to select corresponding channels
* with 1, 2, 3 values (see TRGSEL bitfield description) even if
* channels 3, 4 and 5 are selected for AFEC1
*/ */
if (priv->intf == 1)
{
priv->timer_channel -= 3;
}
/* Set trigger for AFECn driver */ /* Set trigger for AFECn driver */
regval = afec_getreg(priv, SAM_AFEC_MR_OFFSET); regval = afec_getreg(priv, SAM_AFEC_MR_OFFSET);
regval &= ~AFEC_MR_TRGSEL_MASK; regval &= ~AFEC_MR_TRGSEL_MASK;
regval |= ((priv->timer_channel + 1) << AFEC_MR_TRGSEL_SHIFT) | \ regval |= (((priv->timer_channel % 3) + 1) << AFEC_MR_TRGSEL_SHIFT) |
AFEC_MR_TRGEN; AFEC_MR_TRGEN;
afec_putreg(priv, SAM_AFEC_MR_OFFSET, regval); afec_putreg(priv, SAM_AFEC_MR_OFFSET, regval);
@ -753,7 +750,7 @@ static void afec_reset(struct adc_dev_s *dev)
/* Configure Extended Mode register */ /* Configure Extended Mode register */
uint32_t afec_emr = AFEC_EMR_TAG | AFEC_EMR_STM | \ uint32_t afec_emr = AFEC_EMR_TAG | AFEC_EMR_STM |
AFEC_EMR_RES(priv->resolution); AFEC_EMR_RES(priv->resolution);
afec_putreg(priv, SAM_AFEC_EMR_OFFSET, afec_emr); afec_putreg(priv, SAM_AFEC_EMR_OFFSET, afec_emr);
@ -1022,7 +1019,7 @@ static int afec_interrupt(int irq, void *context, void *arg)
struct samv7_dev_s *priv = (struct samv7_dev_s *)dev->ad_priv; struct samv7_dev_s *priv = (struct samv7_dev_s *)dev->ad_priv;
int32_t data; int32_t data;
if ((afec_getreg(priv, SAM_AFEC_ISR_OFFSET) & \ if ((afec_getreg(priv, SAM_AFEC_ISR_OFFSET) &
AFEC_CH(priv->chanlist[priv->current])) != 0) AFEC_CH(priv->chanlist[priv->current])) != 0)
{ {
/* Read data */ /* Read data */
@ -1120,7 +1117,7 @@ struct adc_dev_s *sam_afec_initialize(int intf,
#ifdef CONFIG_SAMV7_AFEC_DMA #ifdef CONFIG_SAMV7_AFEC_DMA
priv->nsamples = priv->nchannels * CONFIG_SAMV7_AFEC_DMASAMPLES; priv->nsamples = priv->nchannels * CONFIG_SAMV7_AFEC_DMASAMPLES;
priv->dma = sam_dmachannel(0, DMA_FLAGS | \ priv->dma = sam_dmachannel(0, DMA_FLAGS |
DMACH_FLAG_PERIPHPID(priv->pid)); DMACH_FLAG_PERIPHPID(priv->pid));
#endif #endif