static int ni_tio_set_clock_src(struct ni_gpct *counter, unsigned int clock_source, unsigned int period_ns) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned input_select_bits = 0; static const uint64_t pico_per_nano = 1000; /*FIXME: validate clock source */ switch (counter_dev->variant) { case ni_gpct_variant_660x: input_select_bits |= ni_660x_source_select_bits(clock_source); break; case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: input_select_bits |= ni_m_series_source_select_bits(clock_source); break; default: BUG(); break; } if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT) input_select_bits |= Gi_Source_Polarity_Bit; ni_tio_set_bits(counter, NITIO_Gi_Input_Select_Reg(counter->counter_index), Gi_Source_Select_Mask | Gi_Source_Polarity_Bit, input_select_bits); ni_tio_set_source_subselect(counter, clock_source); if (ni_tio_counting_mode_registers_present(counter_dev)) { const unsigned prescaling_mode = clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK; unsigned counting_mode_bits = 0; switch (prescaling_mode) { case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: break; case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: counting_mode_bits |= Gi_Prescale_X2_Bit(counter_dev->variant); break; case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: counting_mode_bits |= Gi_Prescale_X8_Bit(counter_dev->variant); break; default: return -EINVAL; break; } ni_tio_set_bits(counter, NITIO_Gi_Counting_Mode_Reg(counter-> counter_index), Gi_Prescale_X2_Bit(counter_dev->variant) | Gi_Prescale_X8_Bit(counter_dev->variant), counting_mode_bits); } counter->clock_period_ps = pico_per_nano * period_ns; ni_tio_set_sync_mode(counter, 0); return 0; }
static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter, NITIO_Gi_Counting_Mode_Reg(counter->counter_index)); unsigned bits = 0; if (ni_tio_get_soft_copy(counter, NITIO_Gi_Input_Select_Reg(counter-> counter_index)) & Gi_Source_Polarity_Bit) bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT; if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant)) bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS; if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant)) bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS; return bits; }