static void ti_adc_disable(struct ti_adc_softc *sc) { int count; uint32_t data; TI_ADC_LOCK_ASSERT(sc); if (sc->sc_last_state == 0) return; /* Disable all the enabled steps. */ ADC_WRITE4(sc, ADC_STEPENABLE, 0); /* Disable the ADC. */ ADC_WRITE4(sc, ADC_CTRL, ADC_READ4(sc, ADC_CTRL) & ~ADC_CTRL_ENABLE); /* Disable the FIFO0 threshold and the end of sequence interrupt. */ ADC_WRITE4(sc, ADC_IRQENABLE_CLR, ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ); /* ACK any pending interrupt. */ ADC_WRITE4(sc, ADC_IRQSTATUS, ADC_READ4(sc, ADC_IRQSTATUS)); /* Drain the FIFO data. */ count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK; while (count > 0) { data = ADC_READ4(sc, ADC_FIFO0DATA); count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK; } sc->sc_last_state = 0; }
static int ti_adc_setup(struct ti_adc_softc *sc) { int ain; uint32_t enabled; TI_ADC_LOCK_ASSERT(sc); /* Check for enabled inputs. */ enabled = 0; for (ain = 0; ain < TI_ADC_NPINS; ain++) { if (ti_adc_inputs[ain].enable) enabled |= (1U << (ain + 1)); } /* Set the ADC global status. */ if (enabled != 0) { ti_adc_enable(sc); /* Update the enabled steps. */ if (enabled != ADC_READ4(sc, ADC_STEPENABLE)) ADC_WRITE4(sc, ADC_STEPENABLE, enabled); } else ti_adc_disable(sc); return (0); }
static void ti_adc_input_setup(struct ti_adc_softc *sc, int32_t ain) { struct ti_adc_input *input; uint32_t reg, val; TI_ADC_LOCK_ASSERT(sc); input = &ti_adc_inputs[ain]; reg = input->stepconfig; val = ADC_READ4(sc, reg); /* Set single ended operation. */ val &= ~ADC_STEP_DIFF_CNTRL; /* Set the negative voltage reference. */ val &= ~ADC_STEP_RFM_MSK; /* Set the positive voltage reference. */ val &= ~ADC_STEP_RFP_MSK; /* Set the samples average. */ val &= ~ADC_STEP_AVG_MSK; val |= input->samples << ADC_STEP_AVG_SHIFT; /* Select the desired input. */ val &= ~ADC_STEP_INP_MSK; val |= ain << ADC_STEP_INP_SHIFT; /* Set the ADC to one-shot mode. */ val &= ~ADC_STEP_MODE_MSK; ADC_WRITE4(sc, reg, val); }
static void ti_adc_reset(struct ti_adc_softc *sc) { int ain; TI_ADC_LOCK_ASSERT(sc); /* Disable all the inputs. */ for (ain = 0; ain < TI_ADC_NPINS; ain++) ti_adc_inputs[ain].enable = 0; }
static void ti_adc_enable(struct ti_adc_softc *sc) { TI_ADC_LOCK_ASSERT(sc); if (sc->sc_last_state == 1) return; /* Enable the FIFO0 threshold and the end of sequence interrupt. */ ADC_WRITE4(sc, ADC_IRQENABLE_SET, ADC_IRQ_FIFO0_THRES | ADC_IRQ_END_OF_SEQ); /* Enable the ADC. Run thru enabled steps, start the conversions. */ ADC_WRITE4(sc, ADC_CTRL, ADC_READ4(sc, ADC_CTRL) | ADC_CTRL_ENABLE); sc->sc_last_state = 1; }
static void ti_adc_read_data(struct ti_adc_softc *sc) { int count, ain; struct ti_adc_input *input; uint32_t data; TI_ADC_LOCK_ASSERT(sc); /* Read the available data. */ count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK; while (count > 0) { data = ADC_READ4(sc, ADC_FIFO0DATA); ain = (data & ADC_FIFO_STEP_ID_MSK) >> ADC_FIFO_STEP_ID_SHIFT; input = &ti_adc_inputs[ain]; if (input->enable == 0) input->value = 0; else input->value = (int32_t)(data & ADC_FIFO_DATA_MSK); count = ADC_READ4(sc, ADC_FIFO0COUNT) & ADC_FIFO_COUNT_MSK; } }