diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/ni_tio.c')
-rw-r--r-- | drivers/staging/comedi/drivers/ni_tio.c | 1687 |
1 files changed, 713 insertions, 974 deletions
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 92691b491c24..0525292c1d8b 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -49,363 +49,336 @@ TODO: #include "ni_tio_internal.h" -static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, - unsigned generic_clock_source); -static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter); +/* + * clock sources for ni e and m series boards, + * get bits with GI_SRC_SEL() + */ +#define NI_M_TIMEBASE_1_CLK 0x0 /* 20MHz */ +#define NI_M_PFI_CLK(x) (((x) < 10) ? (1 + (x)) : (0xb + (x))) +#define NI_M_RTSI_CLK(x) (((x) == 7) ? 0x1b : (0xb + (x))) +#define NI_M_TIMEBASE_2_CLK 0x12 /* 100KHz */ +#define NI_M_NEXT_TC_CLK 0x13 +#define NI_M_NEXT_GATE_CLK 0x14 /* Gi_Src_SubSelect=0 */ +#define NI_M_PXI_STAR_TRIGGER_CLK 0x14 /* Gi_Src_SubSelect=1 */ +#define NI_M_PXI10_CLK 0x1d +#define NI_M_TIMEBASE_3_CLK 0x1e /* 80MHz, Gi_Src_SubSelect=0 */ +#define NI_M_ANALOG_TRIGGER_OUT_CLK 0x1e /* Gi_Src_SubSelect=1 */ +#define NI_M_LOGIC_LOW_CLK 0x1f +#define NI_M_MAX_PFI_CHAN 15 +#define NI_M_MAX_RTSI_CHAN 7 -static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum - ni_gpct_variant - variant) +/* + * clock sources for ni_660x boards, + * get bits with GI_SRC_SEL() + */ +#define NI_660X_TIMEBASE_1_CLK 0x0 /* 20MHz */ +#define NI_660X_SRC_PIN_I_CLK 0x1 +#define NI_660X_SRC_PIN_CLK(x) (0x2 + (x)) +#define NI_660X_NEXT_GATE_CLK 0xa +#define NI_660X_RTSI_CLK(x) (0xb + (x)) +#define NI_660X_TIMEBASE_2_CLK 0x12 /* 100KHz */ +#define NI_660X_NEXT_TC_CLK 0x13 +#define NI_660X_TIMEBASE_3_CLK 0x1e /* 80MHz */ +#define NI_660X_LOGIC_LOW_CLK 0x1f +#define NI_660X_MAX_SRC_PIN 7 +#define NI_660X_MAX_RTSI_CHAN 6 + +/* ni m series gate_select */ +#define NI_M_TIMESTAMP_MUX_GATE_SEL 0x0 +#define NI_M_PFI_GATE_SEL(x) (((x) < 10) ? (1 + (x)) : (0xb + (x))) +#define NI_M_RTSI_GATE_SEL(x) (((x) == 7) ? 0x1b : (0xb + (x))) +#define NI_M_AI_START2_GATE_SEL 0x12 +#define NI_M_PXI_STAR_TRIGGER_GATE_SEL 0x13 +#define NI_M_NEXT_OUT_GATE_SEL 0x14 +#define NI_M_AI_START1_GATE_SEL 0x1c +#define NI_M_NEXT_SRC_GATE_SEL 0x1d +#define NI_M_ANALOG_TRIG_OUT_GATE_SEL 0x1e +#define NI_M_LOGIC_LOW_GATE_SEL 0x1f + +/* ni_660x gate select */ +#define NI_660X_SRC_PIN_I_GATE_SEL 0x0 +#define NI_660X_GATE_PIN_I_GATE_SEL 0x1 +#define NI_660X_PIN_GATE_SEL(x) (0x2 + (x)) +#define NI_660X_NEXT_SRC_GATE_SEL 0xa +#define NI_660X_RTSI_GATE_SEL(x) (0xb + (x)) +#define NI_660X_NEXT_OUT_GATE_SEL 0x14 +#define NI_660X_LOGIC_LOW_GATE_SEL 0x1f +#define NI_660X_MAX_GATE_PIN 7 + +/* ni_660x second gate select */ +#define NI_660X_SRC_PIN_I_GATE2_SEL 0x0 +#define NI_660X_UD_PIN_I_GATE2_SEL 0x1 +#define NI_660X_UD_PIN_GATE2_SEL(x) (0x2 + (x)) +#define NI_660X_NEXT_SRC_GATE2_SEL 0xa +#define NI_660X_RTSI_GATE2_SEL(x) (0xb + (x)) +#define NI_660X_NEXT_OUT_GATE2_SEL 0x14 +#define NI_660X_SELECTED_GATE2_SEL 0x1e +#define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f +#define NI_660X_MAX_UP_DOWN_PIN 7 + +static inline unsigned GI_ALT_SYNC(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: + default: return 0; - break; case ni_gpct_variant_m_series: - return Gi_M_Series_Alternate_Sync_Bit; - break; + return GI_M_ALT_SYNC; case ni_gpct_variant_660x: - return Gi_660x_Alternate_Sync_Bit; - break; - default: - BUG(); - break; + return GI_660X_ALT_SYNC; } - return 0; } -static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum - ni_gpct_variant - variant) +static inline unsigned GI_PRESCALE_X2(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: + default: return 0; - break; case ni_gpct_variant_m_series: - return Gi_M_Series_Prescale_X2_Bit; - break; + return GI_M_PRESCALE_X2; case ni_gpct_variant_660x: - return Gi_660x_Prescale_X2_Bit; - break; - default: - BUG(); - break; + return GI_660X_PRESCALE_X2; } - return 0; } -static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum - ni_gpct_variant - variant) +static inline unsigned GI_PRESCALE_X8(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: + default: return 0; - break; case ni_gpct_variant_m_series: - return Gi_M_Series_Prescale_X8_Bit; - break; + return GI_M_PRESCALE_X8; case ni_gpct_variant_660x: - return Gi_660x_Prescale_X8_Bit; - break; - default: - BUG(); - break; + return GI_660X_PRESCALE_X8; } - return 0; } -static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum - ni_gpct_variant - variant) +static inline unsigned GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant) { switch (variant) { case ni_gpct_variant_e_series: + default: return 0; - break; case ni_gpct_variant_m_series: - return Gi_M_Series_HW_Arm_Select_Mask; - break; + return GI_M_HW_ARM_SEL_MASK; case ni_gpct_variant_660x: - return Gi_660x_HW_Arm_Select_Mask; - break; - default: - BUG(); - break; + return GI_660X_HW_ARM_SEL_MASK; } - return 0; } -/* clock sources for ni_660x boards, get bits with Gi_Source_Select_Bits() */ -enum ni_660x_clock_source { - NI_660x_Timebase_1_Clock = 0x0, /* 20MHz */ - NI_660x_Source_Pin_i_Clock = 0x1, - NI_660x_Next_Gate_Clock = 0xa, - NI_660x_Timebase_2_Clock = 0x12, /* 100KHz */ - NI_660x_Next_TC_Clock = 0x13, - NI_660x_Timebase_3_Clock = 0x1e, /* 80MHz */ - NI_660x_Logic_Low_Clock = 0x1f, -}; -static const unsigned ni_660x_max_rtsi_channel = 6; -static inline unsigned NI_660x_RTSI_Clock(unsigned n) +static int ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev) { - BUG_ON(n > ni_660x_max_rtsi_channel); - return 0xb + n; -} - -static const unsigned ni_660x_max_source_pin = 7; -static inline unsigned NI_660x_Source_Pin_Clock(unsigned n) -{ - BUG_ON(n > ni_660x_max_source_pin); - return 0x2 + n; -} - -/* clock sources for ni e and m series boards, get bits with Gi_Source_Select_Bits() */ -enum ni_m_series_clock_source { - NI_M_Series_Timebase_1_Clock = 0x0, /* 20MHz */ - NI_M_Series_Timebase_2_Clock = 0x12, /* 100KHz */ - NI_M_Series_Next_TC_Clock = 0x13, - NI_M_Series_Next_Gate_Clock = 0x14, /* when Gi_Src_SubSelect = 0 */ - NI_M_Series_PXI_Star_Trigger_Clock = 0x14, /* when Gi_Src_SubSelect = 1 */ - NI_M_Series_PXI10_Clock = 0x1d, - NI_M_Series_Timebase_3_Clock = 0x1e, /* 80MHz, when Gi_Src_SubSelect = 0 */ - NI_M_Series_Analog_Trigger_Out_Clock = 0x1e, /* when Gi_Src_SubSelect = 1 */ - NI_M_Series_Logic_Low_Clock = 0x1f, -}; -static const unsigned ni_m_series_max_pfi_channel = 15; -static inline unsigned NI_M_Series_PFI_Clock(unsigned n) -{ - BUG_ON(n > ni_m_series_max_pfi_channel); - if (n < 10) - return 1 + n; - else - return 0xb + n; -} - -static const unsigned ni_m_series_max_rtsi_channel = 7; -static inline unsigned NI_M_Series_RTSI_Clock(unsigned n) -{ - BUG_ON(n > ni_m_series_max_rtsi_channel); - if (n == 7) - return 0x1b; - else - return 0xb + n; -} - -enum ni_660x_gate_select { - NI_660x_Source_Pin_i_Gate_Select = 0x0, - NI_660x_Gate_Pin_i_Gate_Select = 0x1, - NI_660x_Next_SRC_Gate_Select = 0xa, - NI_660x_Next_Out_Gate_Select = 0x14, - NI_660x_Logic_Low_Gate_Select = 0x1f, -}; -static const unsigned ni_660x_max_gate_pin = 7; -static inline unsigned NI_660x_Gate_Pin_Gate_Select(unsigned n) -{ - BUG_ON(n > ni_660x_max_gate_pin); - return 0x2 + n; -} - -static inline unsigned NI_660x_RTSI_Gate_Select(unsigned n) -{ - BUG_ON(n > ni_660x_max_rtsi_channel); - return 0xb + n; -} - -enum ni_m_series_gate_select { - NI_M_Series_Timestamp_Mux_Gate_Select = 0x0, - NI_M_Series_AI_START2_Gate_Select = 0x12, - NI_M_Series_PXI_Star_Trigger_Gate_Select = 0x13, - NI_M_Series_Next_Out_Gate_Select = 0x14, - NI_M_Series_AI_START1_Gate_Select = 0x1c, - NI_M_Series_Next_SRC_Gate_Select = 0x1d, - NI_M_Series_Analog_Trigger_Out_Gate_Select = 0x1e, - NI_M_Series_Logic_Low_Gate_Select = 0x1f, -}; -static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n) -{ - BUG_ON(n > ni_m_series_max_rtsi_channel); - if (n == 7) - return 0x1b; - return 0xb + n; -} - -static inline unsigned NI_M_Series_PFI_Gate_Select(unsigned n) -{ - BUG_ON(n > ni_m_series_max_pfi_channel); - if (n < 10) - return 1 + n; - return 0xb + n; -} - -static inline unsigned Gi_Source_Select_Bits(unsigned source) -{ - return (source << Gi_Source_Select_Shift) & Gi_Source_Select_Mask; -} - -static inline unsigned Gi_Gate_Select_Bits(unsigned gate_select) -{ - return (gate_select << Gi_Gate_Select_Shift) & Gi_Gate_Select_Mask; + switch (counter_dev->variant) { + case ni_gpct_variant_e_series: + default: + return 0; + case ni_gpct_variant_m_series: + case ni_gpct_variant_660x: + return 1; + } } -enum ni_660x_second_gate_select { - NI_660x_Source_Pin_i_Second_Gate_Select = 0x0, - NI_660x_Up_Down_Pin_i_Second_Gate_Select = 0x1, - NI_660x_Next_SRC_Second_Gate_Select = 0xa, - NI_660x_Next_Out_Second_Gate_Select = 0x14, - NI_660x_Selected_Gate_Second_Gate_Select = 0x1e, - NI_660x_Logic_Low_Second_Gate_Select = 0x1f, -}; -static const unsigned ni_660x_max_up_down_pin = 7; -static inline unsigned NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned n) +static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) { - BUG_ON(n > ni_660x_max_up_down_pin); - return 0x2 + n; -} + unsigned cidx = counter->counter_index; -static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n) -{ - BUG_ON(n > ni_660x_max_rtsi_channel); - return 0xb + n; + write_register(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); } -static const unsigned int counter_status_mask = - COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING; - -struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device *dev, - void (*write_register) (struct - ni_gpct - * - counter, - unsigned - bits, - enum - ni_gpct_register - reg), - unsigned (*read_register) - (struct ni_gpct *counter, - enum ni_gpct_register reg), - enum ni_gpct_variant variant, - unsigned num_counters) +static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, + unsigned generic_clock_source) { - unsigned i; + uint64_t clock_period_ps; - struct ni_gpct_device *counter_dev = - kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL); - if (counter_dev == NULL) - return NULL; - counter_dev->dev = dev; - counter_dev->write_register = write_register; - counter_dev->read_register = read_register; - counter_dev->variant = variant; - spin_lock_init(&counter_dev->regs_lock); - BUG_ON(num_counters == 0); - counter_dev->counters = - kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL); - if (counter_dev->counters == NULL) { - kfree(counter_dev); - return NULL; - } - for (i = 0; i < num_counters; ++i) { - counter_dev->counters[i].counter_dev = counter_dev; - spin_lock_init(&counter_dev->counters[i].lock); + switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { + case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: + clock_period_ps = 50000; + break; + case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: + clock_period_ps = 10000000; + break; + case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: + clock_period_ps = 12500; + break; + case NI_GPCT_PXI10_CLOCK_SRC_BITS: + clock_period_ps = 100000; + break; + default: + /* + * clock period is specified by user with prescaling + * already taken into account. + */ + return counter->clock_period_ps; } - counter_dev->num_counters = num_counters; - return counter_dev; -} -EXPORT_SYMBOL_GPL(ni_gpct_device_construct); - -void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) -{ - if (counter_dev->counters == NULL) - return; - kfree(counter_dev->counters); - kfree(counter_dev); -} -EXPORT_SYMBOL_GPL(ni_gpct_device_destroy); -static int ni_tio_second_gate_registers_present(const struct ni_gpct_device - *counter_dev) -{ - switch (counter_dev->variant) { - case ni_gpct_variant_e_series: - return 0; + switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { + case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: break; - case ni_gpct_variant_m_series: - case ni_gpct_variant_660x: - return 1; + case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: + clock_period_ps *= 2; + break; + case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: + clock_period_ps *= 8; break; default: BUG(); break; } - return 0; + return clock_period_ps; } -static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) +static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) { + struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; + const unsigned counting_mode_bits = + ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx)); + unsigned bits = 0; - write_register(counter, Gi_Reset_Bit(cidx), NITIO_RESET_REG(cidx)); + if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & + GI_SRC_POL_INVERT) + bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT; + if (counting_mode_bits & GI_PRESCALE_X2(counter_dev->variant)) + bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS; + if (counting_mode_bits & GI_PRESCALE_X8(counter_dev->variant)) + bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS; + return bits; } -void ni_tio_init_counter(struct ni_gpct *counter) +static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); + unsigned clock_source = 0; + unsigned src; + unsigned i; - ni_tio_reset_count_and_disarm(counter); - - /* initialize counter registers */ - counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0; - write_register(counter, counter_dev->regs[NITIO_AUTO_INC_REG(cidx)], - NITIO_AUTO_INC_REG(cidx)); - - ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), - ~0, Gi_Synchronize_Gate_Bit); - - ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); - - counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0; - write_register(counter, counter_dev->regs[NITIO_LOADA_REG(cidx)], - NITIO_LOADA_REG(cidx)); + src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter, + NITIO_INPUT_SEL_REG(cidx))); - counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0; - write_register(counter, counter_dev->regs[NITIO_LOADB_REG(cidx)], - NITIO_LOADB_REG(cidx)); + switch (src) { + case NI_M_TIMEBASE_1_CLK: + clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; + break; + case NI_M_TIMEBASE_2_CLK: + clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; + break; + case NI_M_TIMEBASE_3_CLK: + if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL) + clock_source = + NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; + else + clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; + break; + case NI_M_LOGIC_LOW_CLK: + clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; + break; + case NI_M_NEXT_GATE_CLK: + if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL) + clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; + else + clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; + break; + case NI_M_PXI10_CLK: + clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS; + break; + case NI_M_NEXT_TC_CLK: + clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; + break; + default: + for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { + if (src == NI_M_RTSI_CLK(i)) { + clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= NI_M_MAX_RTSI_CHAN) + break; + for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { + if (src == NI_M_PFI_CLK(i)) { + clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= NI_M_MAX_PFI_CHAN) + break; + BUG(); + break; + } + clock_source |= ni_tio_clock_src_modifiers(counter); + return clock_source; +} - ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); +static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter) +{ + unsigned clock_source = 0; + unsigned cidx = counter->counter_index; + unsigned src; + unsigned i; - if (ni_tio_counting_mode_registers_present(counter_dev)) - ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0); + src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter, + NITIO_INPUT_SEL_REG(cidx))); - if (ni_tio_second_gate_registers_present(counter_dev)) { - counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0; - write_register(counter, - counter_dev->regs[NITIO_GATE2_REG(cidx)], - NITIO_GATE2_REG(cidx)); + switch (src) { + case NI_660X_TIMEBASE_1_CLK: + clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; + break; + case NI_660X_TIMEBASE_2_CLK: + clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; + break; + case NI_660X_TIMEBASE_3_CLK: + clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; + break; + case NI_660X_LOGIC_LOW_CLK: + clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; + break; + case NI_660X_SRC_PIN_I_CLK: + clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS; + break; + case NI_660X_NEXT_GATE_CLK: + clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; + break; + case NI_660X_NEXT_TC_CLK: + clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; + break; + default: + for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { + if (src == NI_660X_RTSI_CLK(i)) { + clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= NI_660X_MAX_RTSI_CHAN) + break; + for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) { + if (src == NI_660X_SRC_PIN_CLK(i)) { + clock_source = + NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i); + break; + } + } + if (i <= NI_660X_MAX_SRC_PIN) + break; + BUG(); + break; } - - ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0); - - ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0); + clock_source |= ni_tio_clock_src_modifiers(counter); + return clock_source; } -EXPORT_SYMBOL_GPL(ni_tio_init_counter); -static unsigned int ni_tio_counter_status(struct ni_gpct *counter) +static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter) { - unsigned cidx = counter->counter_index; - const unsigned bits = read_register(counter, - NITIO_SHARED_STATUS_REG(cidx)); - unsigned int status = 0; - - if (bits & Gi_Armed_Bit(cidx)) { - status |= COMEDI_COUNTER_ARMED; - if (bits & Gi_Counting_Bit(cidx)) - status |= COMEDI_COUNTER_COUNTING; + switch (counter->counter_dev->variant) { + case ni_gpct_variant_e_series: + case ni_gpct_variant_m_series: + default: + return ni_m_series_clock_src_select(counter); + case ni_gpct_variant_660x: + return ni_660x_clock_src_select(counter); } - return status; } static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) @@ -414,34 +387,40 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) unsigned cidx = counter->counter_index; const unsigned counting_mode_reg = NITIO_CNT_MODE_REG(cidx); static const uint64_t min_normal_sync_period_ps = 25000; - const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter, - ni_tio_generic_clock_src_select - (counter)); + unsigned mode; + uint64_t clock_period_ps; if (ni_tio_counting_mode_registers_present(counter_dev) == 0) return; - switch (ni_tio_get_soft_copy(counter, counting_mode_reg) & Gi_Counting_Mode_Mask) { - case Gi_Counting_Mode_QuadratureX1_Bits: - case Gi_Counting_Mode_QuadratureX2_Bits: - case Gi_Counting_Mode_QuadratureX4_Bits: - case Gi_Counting_Mode_Sync_Source_Bits: + mode = ni_tio_get_soft_copy(counter, counting_mode_reg); + switch (mode & GI_CNT_MODE_MASK) { + case GI_CNT_MODE_QUADX1: + case GI_CNT_MODE_QUADX2: + case GI_CNT_MODE_QUADX4: + case GI_CNT_MODE_SYNC_SRC: force_alt_sync = 1; break; default: break; } - /* It's not clear what we should do if clock_period is unknown, so we are not - using the alt sync bit in that case, but allow the caller to decide by using the - force_alt_sync parameter. */ + + clock_period_ps = ni_tio_clock_period_ps(counter, + ni_tio_generic_clock_src_select(counter)); + + /* + * It's not clear what we should do if clock_period is unknown, so we + * are not using the alt sync bit in that case, but allow the caller + * to decide by using the force_alt_sync parameter. + */ if (force_alt_sync || (clock_period_ps && clock_period_ps < min_normal_sync_period_ps)) { ni_tio_set_bits(counter, counting_mode_reg, - Gi_Alternate_Sync_Bit(counter_dev->variant), - Gi_Alternate_Sync_Bit(counter_dev->variant)); + GI_ALT_SYNC(counter_dev->variant), + GI_ALT_SYNC(counter_dev->variant)); } else { ni_tio_set_bits(counter, counting_mode_reg, - Gi_Alternate_Sync_Bit(counter_dev->variant), + GI_ALT_SYNC(counter_dev->variant), 0x0); } } @@ -460,18 +439,18 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT | NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT; - mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit; + mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING; mode_reg_values = mode & mode_reg_direct_mask; switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) { case NI_GPCT_RELOAD_SOURCE_FIXED_BITS: break; case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS: - mode_reg_values |= Gi_Reload_Source_Switching_Bit; + mode_reg_values |= GI_RELOAD_SRC_SWITCHING; break; case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS: - input_select_bits |= Gi_Gate_Select_Load_Source_Bit; - mode_reg_mask |= Gi_Gating_Mode_Mask; - mode_reg_values |= Gi_Level_Gating_Bits; + input_select_bits |= GI_GATE_SEL_LOAD_SRC; + mode_reg_mask |= GI_GATING_MODE_MASK; + mode_reg_values |= GI_LEVEL_GATING; break; default: break; @@ -480,33 +459,28 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) mode_reg_mask, mode_reg_values); if (ni_tio_counting_mode_registers_present(counter_dev)) { - unsigned counting_mode_bits = 0; - counting_mode_bits |= - (mode >> NI_GPCT_COUNTING_MODE_SHIFT) & - Gi_Counting_Mode_Mask; - counting_mode_bits |= - ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) << - Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask; + unsigned bits = 0; + + bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT); + bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT)); if (mode & NI_GPCT_INDEX_ENABLE_BIT) - counting_mode_bits |= Gi_Index_Mode_Bit; + bits |= GI_INDEX_MODE; ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), - Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask | - Gi_Index_Mode_Bit, counting_mode_bits); + GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK | + GI_INDEX_MODE, bits); ni_tio_set_sync_mode(counter, 0); } - ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), - Gi_Up_Down_Mask, - (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << - Gi_Up_Down_Shift); + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK, + GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT)); if (mode & NI_GPCT_OR_GATE_BIT) - input_select_bits |= Gi_Or_Gate_Bit; + input_select_bits |= GI_OR_GATE; if (mode & NI_GPCT_INVERT_OUTPUT_BIT) - input_select_bits |= Gi_Output_Polarity_Bit; + input_select_bits |= GI_OUTPUT_POL_INVERT; ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), - Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit | - Gi_Output_Polarity_Bit, input_select_bits); + GI_GATE_SEL_LOAD_SRC | GI_OR_GATE | + GI_OUTPUT_POL_INVERT, input_select_bits); return 0; } @@ -520,16 +494,19 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) if (arm) { switch (start_trigger) { case NI_GPCT_ARM_IMMEDIATE: - command_transient_bits |= Gi_Arm_Bit; + command_transient_bits |= GI_ARM; break; case NI_GPCT_ARM_PAIRED_IMMEDIATE: - command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit; + command_transient_bits |= GI_ARM | GI_ARM_COPY; break; default: break; } if (ni_tio_counting_mode_registers_present(counter_dev)) { - unsigned counting_mode_bits = 0; + unsigned bits = 0; + unsigned sel_mask; + + sel_mask = GI_HW_ARM_SEL_MASK(counter_dev->variant); switch (start_trigger) { case NI_GPCT_ARM_IMMEDIATE: @@ -537,29 +514,24 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) break; default: if (start_trigger & NI_GPCT_ARM_UNKNOWN) { - /* pass-through the least significant bits so we can figure out what select later */ - unsigned hw_arm_select_bits = - (start_trigger << - Gi_HW_Arm_Select_Shift) & - Gi_HW_Arm_Select_Mask - (counter_dev->variant); - - counting_mode_bits |= - Gi_HW_Arm_Enable_Bit | - hw_arm_select_bits; + /* + * pass-through the least significant + * bits so we can figure out what + * select later + */ + bits |= GI_HW_ARM_ENA | + (GI_HW_ARM_SEL(start_trigger) & + sel_mask); } else { return -EINVAL; } break; } ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), - Gi_HW_Arm_Select_Mask - (counter_dev->variant) | - Gi_HW_Arm_Enable_Bit, - counting_mode_bits); + GI_HW_ARM_ENA | sel_mask, bits); } } else { - command_transient_bits |= Gi_Disarm_Bit; + command_transient_bits |= GI_DISARM; } ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), 0, 0, command_transient_bits); @@ -567,118 +539,116 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) } EXPORT_SYMBOL_GPL(ni_tio_arm); -static unsigned ni_660x_source_select_bits(unsigned int clock_source) +static unsigned ni_660x_clk_src(unsigned int clock_source) { + unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; unsigned ni_660x_clock; unsigned i; - const unsigned clock_select_bits = - clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; - switch (clock_select_bits) { + switch (clk_src) { case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Timebase_1_Clock; + ni_660x_clock = NI_660X_TIMEBASE_1_CLK; break; case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Timebase_2_Clock; + ni_660x_clock = NI_660X_TIMEBASE_2_CLK; break; case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Timebase_3_Clock; + ni_660x_clock = NI_660X_TIMEBASE_3_CLK; break; case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Logic_Low_Clock; + ni_660x_clock = NI_660X_LOGIC_LOW_CLK; break; case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Source_Pin_i_Clock; + ni_660x_clock = NI_660X_SRC_PIN_I_CLK; break; case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Next_Gate_Clock; + ni_660x_clock = NI_660X_NEXT_GATE_CLK; break; case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS: - ni_660x_clock = NI_660x_Next_TC_Clock; + ni_660x_clock = NI_660X_NEXT_TC_CLK; break; default: - for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { - if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { - ni_660x_clock = NI_660x_RTSI_Clock(i); + for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { + if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { + ni_660x_clock = NI_660X_RTSI_CLK(i); break; } } - if (i <= ni_660x_max_rtsi_channel) + if (i <= NI_660X_MAX_RTSI_CHAN) break; - for (i = 0; i <= ni_660x_max_source_pin; ++i) { - if (clock_select_bits == - NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) { - ni_660x_clock = NI_660x_Source_Pin_Clock(i); + for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) { + if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) { + ni_660x_clock = NI_660X_SRC_PIN_CLK(i); break; } } - if (i <= ni_660x_max_source_pin) + if (i <= NI_660X_MAX_SRC_PIN) break; ni_660x_clock = 0; BUG(); break; } - return Gi_Source_Select_Bits(ni_660x_clock); + return GI_SRC_SEL(ni_660x_clock); } -static unsigned ni_m_series_source_select_bits(unsigned int clock_source) +static unsigned ni_m_clk_src(unsigned int clock_source) { + unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; unsigned ni_m_series_clock; unsigned i; - const unsigned clock_select_bits = - clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; - switch (clock_select_bits) { + + switch (clk_src) { case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Timebase_1_Clock; + ni_m_series_clock = NI_M_TIMEBASE_1_CLK; break; case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Timebase_2_Clock; + ni_m_series_clock = NI_M_TIMEBASE_2_CLK; break; case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Timebase_3_Clock; + ni_m_series_clock = NI_M_TIMEBASE_3_CLK; break; case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Logic_Low_Clock; + ni_m_series_clock = NI_M_LOGIC_LOW_CLK; break; case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Next_Gate_Clock; + ni_m_series_clock = NI_M_NEXT_GATE_CLK; break; case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Next_TC_Clock; + ni_m_series_clock = NI_M_NEXT_TC_CLK; break; case NI_GPCT_PXI10_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_PXI10_Clock; + ni_m_series_clock = NI_M_PXI10_CLK; break; case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock; + ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK; break; case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: - ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock; + ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK; break; default: - for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { - if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { - ni_m_series_clock = NI_M_Series_RTSI_Clock(i); + for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { + if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { + ni_m_series_clock = NI_M_RTSI_CLK(i); break; } } - if (i <= ni_m_series_max_rtsi_channel) + if (i <= NI_M_MAX_RTSI_CHAN) break; - for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { - if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) { - ni_m_series_clock = NI_M_Series_PFI_Clock(i); + for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { + if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) { + ni_m_series_clock = NI_M_PFI_CLK(i); break; } } - if (i <= ni_m_series_max_pfi_channel) + if (i <= NI_M_MAX_PFI_CHAN) break; - printk(KERN_ERR "invalid clock source 0x%lx\n", + pr_err("invalid clock source 0x%lx\n", (unsigned long)clock_source); BUG(); ni_m_series_clock = 0; break; } - return Gi_Source_Select_Bits(ni_m_series_clock); + return GI_SRC_SEL(ni_m_series_clock); }; static void ni_tio_set_source_subselect(struct ni_gpct *counter, @@ -694,17 +664,16 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, /* Gi_Source_Subselect is zero */ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: - counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit; + counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL; break; /* Gi_Source_Subselect is one */ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: - counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit; + counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL; break; /* Gi_Source_Subselect doesn't matter */ default: return; - break; } write_register(counter, counter_dev->regs[second_gate_reg], second_gate_reg); @@ -716,344 +685,109 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; - unsigned input_select_bits = 0; - static const uint64_t pico_per_nano = 1000; + unsigned bits = 0; -/*FIXME: validate clock source */ + /* FIXME: validate clock source */ switch (counter_dev->variant) { case ni_gpct_variant_660x: - input_select_bits |= ni_660x_source_select_bits(clock_source); + bits |= ni_660x_clk_src(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(); + bits |= ni_m_clk_src(clock_source); break; } if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT) - input_select_bits |= Gi_Source_Polarity_Bit; + bits |= GI_SRC_POL_INVERT; ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), - Gi_Source_Select_Mask | Gi_Source_Polarity_Bit, - input_select_bits); + GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, 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) { + if (ni_tio_counting_mode_registers_present(counter_dev)) { + bits = 0; + switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { 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); + bits |= GI_PRESCALE_X2(counter_dev->variant); break; case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: - counting_mode_bits |= - Gi_Prescale_X8_Bit(counter_dev->variant); + bits |= GI_PRESCALE_X8(counter_dev->variant); break; default: return -EINVAL; - break; } ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), - Gi_Prescale_X2_Bit(counter_dev->variant) | - Gi_Prescale_X8_Bit(counter_dev->variant), - counting_mode_bits); + GI_PRESCALE_X2(counter_dev->variant) | + GI_PRESCALE_X8(counter_dev->variant), bits); } - counter->clock_period_ps = pico_per_nano * period_ns; + counter->clock_period_ps = period_ns * 1000; 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; - unsigned cidx = counter->counter_index; - const unsigned counting_mode_bits = - ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx)); - unsigned bits = 0; - - if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & - 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; -} - -static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) -{ - struct ni_gpct_device *counter_dev = counter->counter_dev; - unsigned cidx = counter->counter_index; - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); - unsigned clock_source = 0; - unsigned i; - const unsigned input_select = - (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & - Gi_Source_Select_Mask) >> Gi_Source_Select_Shift; - - switch (input_select) { - case NI_M_Series_Timebase_1_Clock: - clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; - break; - case NI_M_Series_Timebase_2_Clock: - clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; - break; - case NI_M_Series_Timebase_3_Clock: - if (counter_dev->regs[second_gate_reg] & - Gi_Source_Subselect_Bit) - clock_source = - NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; - else - clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; - break; - case NI_M_Series_Logic_Low_Clock: - clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; - break; - case NI_M_Series_Next_Gate_Clock: - if (counter_dev->regs[second_gate_reg] & - Gi_Source_Subselect_Bit) - clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; - else - clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; - break; - case NI_M_Series_PXI10_Clock: - clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS; - break; - case NI_M_Series_Next_TC_Clock: - clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; - break; - default: - for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { - if (input_select == NI_M_Series_RTSI_Clock(i)) { - clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); - break; - } - } - if (i <= ni_m_series_max_rtsi_channel) - break; - for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { - if (input_select == NI_M_Series_PFI_Clock(i)) { - clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i); - break; - } - } - if (i <= ni_m_series_max_pfi_channel) - break; - BUG(); - break; - } - clock_source |= ni_tio_clock_src_modifiers(counter); - return clock_source; -} - -static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter) -{ - unsigned clock_source = 0; - unsigned cidx = counter->counter_index; - const unsigned input_select = - (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & - Gi_Source_Select_Mask) >> Gi_Source_Select_Shift; - unsigned i; - - switch (input_select) { - case NI_660x_Timebase_1_Clock: - clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; - break; - case NI_660x_Timebase_2_Clock: - clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; - break; - case NI_660x_Timebase_3_Clock: - clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; - break; - case NI_660x_Logic_Low_Clock: - clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; - break; - case NI_660x_Source_Pin_i_Clock: - clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS; - break; - case NI_660x_Next_Gate_Clock: - clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; - break; - case NI_660x_Next_TC_Clock: - clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; - break; - default: - for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { - if (input_select == NI_660x_RTSI_Clock(i)) { - clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); - break; - } - } - if (i <= ni_660x_max_rtsi_channel) - break; - for (i = 0; i <= ni_660x_max_source_pin; ++i) { - if (input_select == NI_660x_Source_Pin_Clock(i)) { - clock_source = - NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i); - break; - } - } - if (i <= ni_660x_max_source_pin) - break; - BUG(); - break; - } - clock_source |= ni_tio_clock_src_modifiers(counter); - return clock_source; -} - -static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter) -{ - switch (counter->counter_dev->variant) { - case ni_gpct_variant_e_series: - case ni_gpct_variant_m_series: - return ni_m_series_clock_src_select(counter); - break; - case ni_gpct_variant_660x: - return ni_660x_clock_src_select(counter); - break; - default: - BUG(); - break; - } - return 0; -} - -static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, - unsigned generic_clock_source) -{ - uint64_t clock_period_ps; - - switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { - case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: - clock_period_ps = 50000; - break; - case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: - clock_period_ps = 10000000; - break; - case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: - clock_period_ps = 12500; - break; - case NI_GPCT_PXI10_CLOCK_SRC_BITS: - clock_period_ps = 100000; - break; - default: - /* clock period is specified by user with prescaling already taken into account. */ - return counter->clock_period_ps; - break; - } - - switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { - case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: - break; - case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: - clock_period_ps *= 2; - break; - case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: - clock_period_ps *= 8; - break; - default: - BUG(); - break; - } - return clock_period_ps; -} - static void ni_tio_get_clock_src(struct ni_gpct *counter, unsigned int *clock_source, unsigned int *period_ns) { - static const unsigned pico_per_nano = 1000; uint64_t temp64; + *clock_source = ni_tio_generic_clock_src_select(counter); temp64 = ni_tio_clock_period_ps(counter, *clock_source); - do_div(temp64, pico_per_nano); + do_div(temp64, 1000); /* ps to ns */ *period_ns = temp64; } -static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter, - unsigned int gate_source) +static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source) { - const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask; + unsigned int chan = CR_CHAN(gate_source); unsigned cidx = counter->counter_index; - unsigned mode_values = 0; - - if (gate_source & CR_INVERT) - mode_values |= Gi_Gate_Polarity_Bit; - if (gate_source & CR_EDGE) - mode_values |= Gi_Rising_Edge_Gating_Bits; - else - mode_values |= Gi_Level_Gating_Bits; - ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), - mode_mask, mode_values); -} - -static int ni_660x_set_first_gate(struct ni_gpct *counter, - unsigned int gate_source) -{ - const unsigned selected_gate = CR_CHAN(gate_source); - unsigned cidx = counter->counter_index; - /* bits of selected_gate that may be meaningful to input select register */ - const unsigned selected_gate_mask = 0x1f; - unsigned ni_660x_gate_select; + unsigned gate_sel; unsigned i; - switch (selected_gate) { + switch (chan) { case NI_GPCT_NEXT_SOURCE_GATE_SELECT: - ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select; + gate_sel = NI_660X_NEXT_SRC_GATE_SEL; break; case NI_GPCT_NEXT_OUT_GATE_SELECT: case NI_GPCT_LOGIC_LOW_GATE_SELECT: case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: case NI_GPCT_GATE_PIN_i_GATE_SELECT: - ni_660x_gate_select = selected_gate & selected_gate_mask; + gate_sel = chan & 0x1f; break; default: - for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { - if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { - ni_660x_gate_select = - selected_gate & selected_gate_mask; + for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { + if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) { + gate_sel = chan & 0x1f; break; } } - if (i <= ni_660x_max_rtsi_channel) + if (i <= NI_660X_MAX_RTSI_CHAN) break; - for (i = 0; i <= ni_660x_max_gate_pin; ++i) { - if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) { - ni_660x_gate_select = - selected_gate & selected_gate_mask; + for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) { + if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) { + gate_sel = chan & 0x1f; break; } } - if (i <= ni_660x_max_gate_pin) + if (i <= NI_660X_MAX_GATE_PIN) break; return -EINVAL; - break; } ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), - Gi_Gate_Select_Mask, - Gi_Gate_Select_Bits(ni_660x_gate_select)); + GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel)); return 0; } -static int ni_m_series_set_first_gate(struct ni_gpct *counter, - unsigned int gate_source) +static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source) { - const unsigned selected_gate = CR_CHAN(gate_source); + unsigned int chan = CR_CHAN(gate_source); unsigned cidx = counter->counter_index; - /* bits of selected_gate that may be meaningful to input select register */ - const unsigned selected_gate_mask = 0x1f; - unsigned ni_m_series_gate_select; + unsigned gate_sel; unsigned i; - switch (selected_gate) { + switch (chan) { case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT: case NI_GPCT_AI_START2_GATE_SELECT: case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT: @@ -1062,120 +796,99 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter, case NI_GPCT_NEXT_SOURCE_GATE_SELECT: case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT: case NI_GPCT_LOGIC_LOW_GATE_SELECT: - ni_m_series_gate_select = selected_gate & selected_gate_mask; + gate_sel = chan & 0x1f; break; default: - for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { - if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { - ni_m_series_gate_select = - selected_gate & selected_gate_mask; + for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { + if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) { + gate_sel = chan & 0x1f; break; } } - if (i <= ni_m_series_max_rtsi_channel) + if (i <= NI_M_MAX_RTSI_CHAN) break; - for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { - if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) { - ni_m_series_gate_select = - selected_gate & selected_gate_mask; + for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { + if (chan == NI_GPCT_PFI_GATE_SELECT(i)) { + gate_sel = chan & 0x1f; break; } } - if (i <= ni_m_series_max_pfi_channel) + if (i <= NI_M_MAX_PFI_CHAN) break; return -EINVAL; - break; } ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), - Gi_Gate_Select_Mask, - Gi_Gate_Select_Bits(ni_m_series_gate_select)); + GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel)); return 0; } -static int ni_660x_set_second_gate(struct ni_gpct *counter, - unsigned int gate_source) +static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); - const unsigned selected_second_gate = CR_CHAN(gate_source); - /* bits of second_gate that may be meaningful to second gate register */ - static const unsigned selected_second_gate_mask = 0x1f; - unsigned ni_660x_second_gate_select; + unsigned int chan = CR_CHAN(gate_source); + unsigned gate2_reg = NITIO_GATE2_REG(cidx); + unsigned gate2_sel; unsigned i; - switch (selected_second_gate) { + switch (chan) { case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT: case NI_GPCT_SELECTED_GATE_GATE_SELECT: case NI_GPCT_NEXT_OUT_GATE_SELECT: case NI_GPCT_LOGIC_LOW_GATE_SELECT: - ni_660x_second_gate_select = - selected_second_gate & selected_second_gate_mask; + gate2_sel = chan & 0x1f; break; case NI_GPCT_NEXT_SOURCE_GATE_SELECT: - ni_660x_second_gate_select = - NI_660x_Next_SRC_Second_Gate_Select; + gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL; break; default: - for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { - if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) { - ni_660x_second_gate_select = - selected_second_gate & - selected_second_gate_mask; + for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { + if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) { + gate2_sel = chan & 0x1f; break; } } - if (i <= ni_660x_max_rtsi_channel) + if (i <= NI_660X_MAX_RTSI_CHAN) break; - for (i = 0; i <= ni_660x_max_up_down_pin; ++i) { - if (selected_second_gate == - NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) { - ni_660x_second_gate_select = - selected_second_gate & - selected_second_gate_mask; + for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) { + if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) { + gate2_sel = chan & 0x1f; break; } } - if (i <= ni_660x_max_up_down_pin) + if (i <= NI_660X_MAX_UP_DOWN_PIN) break; return -EINVAL; - break; } - counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit; - counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask; - counter_dev->regs[second_gate_reg] |= - Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select); - write_register(counter, counter_dev->regs[second_gate_reg], - second_gate_reg); + counter_dev->regs[gate2_reg] |= GI_GATE2_MODE; + counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK; + counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel); + write_register(counter, counter_dev->regs[gate2_reg], gate2_reg); return 0; } -static int ni_m_series_set_second_gate(struct ni_gpct *counter, - unsigned int gate_source) +static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); - const unsigned selected_second_gate = CR_CHAN(gate_source); - /* bits of second_gate that may be meaningful to second gate register */ - static const unsigned selected_second_gate_mask = 0x1f; - unsigned ni_m_series_second_gate_select; - - /* FIXME: We don't know what the m-series second gate codes are, so we'll just pass - the bits through for now. */ - switch (selected_second_gate) { + unsigned int chan = CR_CHAN(gate_source); + unsigned gate2_reg = NITIO_GATE2_REG(cidx); + unsigned gate2_sel; + + /* + * FIXME: We don't know what the m-series second gate codes are, + * so we'll just pass the bits through for now. + */ + switch (chan) { default: - ni_m_series_second_gate_select = - selected_second_gate & selected_second_gate_mask; + gate2_sel = chan & 0x1f; break; } - counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit; - counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask; - counter_dev->regs[second_gate_reg] |= - Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select); - write_register(counter, counter_dev->regs[second_gate_reg], - second_gate_reg); + counter_dev->regs[gate2_reg] |= GI_GATE2_MODE; + counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK; + counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel); + write_register(counter, counter_dev->regs[gate2_reg], gate2_reg); return 0; } @@ -1184,56 +897,55 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); + unsigned int chan = CR_CHAN(gate_source); + unsigned gate2_reg = NITIO_GATE2_REG(cidx); + unsigned mode = 0; switch (gate_index) { case 0: - if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) { + if (chan == NI_GPCT_DISABLED_GATE_SELECT) { ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), - Gi_Gating_Mode_Mask, - Gi_Gating_Disabled_Bits); + GI_GATING_MODE_MASK, + GI_GATING_DISABLED); return 0; } - ni_tio_set_first_gate_modifiers(counter, gate_source); + if (gate_source & CR_INVERT) + mode |= GI_GATE_POL_INVERT; + if (gate_source & CR_EDGE) + mode |= GI_RISING_EDGE_GATING; + else + mode |= GI_LEVEL_GATING; + ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), + GI_GATE_POL_INVERT | GI_GATING_MODE_MASK, + mode); switch (counter_dev->variant) { case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: - return ni_m_series_set_first_gate(counter, gate_source); - break; - case ni_gpct_variant_660x: - return ni_660x_set_first_gate(counter, gate_source); - break; default: - BUG(); - break; + return ni_m_set_gate(counter, gate_source); + case ni_gpct_variant_660x: + return ni_660x_set_gate(counter, gate_source); } break; case 1: - if (ni_tio_second_gate_registers_present(counter_dev) == 0) + if (!ni_tio_has_gate2_registers(counter_dev)) return -EINVAL; - if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) { - counter_dev->regs[second_gate_reg] &= - ~Gi_Second_Gate_Mode_Bit; - write_register(counter, - counter_dev->regs[second_gate_reg], - second_gate_reg); + + if (chan == NI_GPCT_DISABLED_GATE_SELECT) { + counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE; + write_register(counter, counter_dev->regs[gate2_reg], + gate2_reg); return 0; } - if (gate_source & CR_INVERT) { - counter_dev->regs[second_gate_reg] |= - Gi_Second_Gate_Polarity_Bit; - } else { - counter_dev->regs[second_gate_reg] &= - ~Gi_Second_Gate_Polarity_Bit; - } + if (gate_source & CR_INVERT) + counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT; + else + counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT; switch (counter_dev->variant) { case ni_gpct_variant_m_series: - return ni_m_series_set_second_gate(counter, - gate_source); - break; + return ni_m_set_gate2(counter, gate_source); case ni_gpct_variant_660x: - return ni_660x_set_second_gate(counter, gate_source); - break; + return ni_660x_set_gate2(counter, gate_source); default: BUG(); break; @@ -1241,7 +953,6 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, break; default: return -EINVAL; - break; } return 0; } @@ -1252,196 +963,142 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; + unsigned int abz_reg, shift, mask; - if (counter_dev->variant == ni_gpct_variant_m_series) { - unsigned int abz_reg, shift, mask; + if (counter_dev->variant != ni_gpct_variant_m_series) + return -EINVAL; - abz_reg = NITIO_ABZ_REG(cidx); - switch (index) { - case NI_GPCT_SOURCE_ENCODER_A: - shift = 10; - break; - case NI_GPCT_SOURCE_ENCODER_B: - shift = 5; - break; - case NI_GPCT_SOURCE_ENCODER_Z: - shift = 0; - break; - default: - return -EINVAL; - break; - } - mask = 0x1f << shift; - if (source > 0x1f) { - /* Disable gate */ - source = 0x1f; - } - counter_dev->regs[abz_reg] &= ~mask; - counter_dev->regs[abz_reg] |= (source << shift) & mask; - write_register(counter, counter_dev->regs[abz_reg], abz_reg); - return 0; + abz_reg = NITIO_ABZ_REG(cidx); + switch (index) { + case NI_GPCT_SOURCE_ENCODER_A: + shift = 10; + break; + case NI_GPCT_SOURCE_ENCODER_B: + shift = 5; + break; + case NI_GPCT_SOURCE_ENCODER_Z: + shift = 0; + break; + default: + return -EINVAL; } - return -EINVAL; + mask = 0x1f << shift; + if (source > 0x1f) + source = 0x1f; /* Disable gate */ + + counter_dev->regs[abz_reg] &= ~mask; + counter_dev->regs[abz_reg] |= (source << shift) & mask; + write_register(counter, counter_dev->regs[abz_reg], abz_reg); + return 0; } -static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned - ni_660x_gate_select) +static unsigned ni_660x_gate_to_generic_gate(unsigned gate) { unsigned i; - switch (ni_660x_gate_select) { - case NI_660x_Source_Pin_i_Gate_Select: + switch (gate) { + case NI_660X_SRC_PIN_I_GATE_SEL: return NI_GPCT_SOURCE_PIN_i_GATE_SELECT; - break; - case NI_660x_Gate_Pin_i_Gate_Select: + case NI_660X_GATE_PIN_I_GATE_SEL: return NI_GPCT_GATE_PIN_i_GATE_SELECT; - break; - case NI_660x_Next_SRC_Gate_Select: + case NI_660X_NEXT_SRC_GATE_SEL: return NI_GPCT_NEXT_SOURCE_GATE_SELECT; - break; - case NI_660x_Next_Out_Gate_Select: + case NI_660X_NEXT_OUT_GATE_SEL: return NI_GPCT_NEXT_OUT_GATE_SELECT; - break; - case NI_660x_Logic_Low_Gate_Select: + case NI_660X_LOGIC_LOW_GATE_SEL: return NI_GPCT_LOGIC_LOW_GATE_SELECT; - break; default: - for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { - if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) { + for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { + if (gate == NI_660X_RTSI_GATE_SEL(i)) return NI_GPCT_RTSI_GATE_SELECT(i); - break; - } } - if (i <= ni_660x_max_rtsi_channel) - break; - for (i = 0; i <= ni_660x_max_gate_pin; ++i) { - if (ni_660x_gate_select == - NI_660x_Gate_Pin_Gate_Select(i)) { + for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) { + if (gate == NI_660X_PIN_GATE_SEL(i)) return NI_GPCT_GATE_PIN_GATE_SELECT(i); - break; - } } - if (i <= ni_660x_max_gate_pin) - break; BUG(); break; } return 0; }; -static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned - ni_m_series_gate_select) +static unsigned ni_m_gate_to_generic_gate(unsigned gate) { unsigned i; - switch (ni_m_series_gate_select) { - case NI_M_Series_Timestamp_Mux_Gate_Select: + switch (gate) { + case NI_M_TIMESTAMP_MUX_GATE_SEL: return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT; - break; - case NI_M_Series_AI_START2_Gate_Select: + case NI_M_AI_START2_GATE_SEL: return NI_GPCT_AI_START2_GATE_SELECT; - break; - case NI_M_Series_PXI_Star_Trigger_Gate_Select: + case NI_M_PXI_STAR_TRIGGER_GATE_SEL: return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT; - break; - case NI_M_Series_Next_Out_Gate_Select: + case NI_M_NEXT_OUT_GATE_SEL: return NI_GPCT_NEXT_OUT_GATE_SELECT; - break; - case NI_M_Series_AI_START1_Gate_Select: + case NI_M_AI_START1_GATE_SEL: return NI_GPCT_AI_START1_GATE_SELECT; - break; - case NI_M_Series_Next_SRC_Gate_Select: + case NI_M_NEXT_SRC_GATE_SEL: return NI_GPCT_NEXT_SOURCE_GATE_SELECT; - break; - case NI_M_Series_Analog_Trigger_Out_Gate_Select: + case NI_M_ANALOG_TRIG_OUT_GATE_SEL: return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT; - break; - case NI_M_Series_Logic_Low_Gate_Select: + case NI_M_LOGIC_LOW_GATE_SEL: return NI_GPCT_LOGIC_LOW_GATE_SELECT; - break; default: - for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) { - if (ni_m_series_gate_select == - NI_M_Series_RTSI_Gate_Select(i)) { + for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { + if (gate == NI_M_RTSI_GATE_SEL(i)) return NI_GPCT_RTSI_GATE_SELECT(i); - break; - } } - if (i <= ni_m_series_max_rtsi_channel) - break; - for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) { - if (ni_m_series_gate_select == - NI_M_Series_PFI_Gate_Select(i)) { + for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { + if (gate == NI_M_PFI_GATE_SEL(i)) return NI_GPCT_PFI_GATE_SELECT(i); - break; - } } - if (i <= ni_m_series_max_pfi_channel) - break; BUG(); break; } return 0; }; -static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned - ni_660x_gate_select) +static unsigned ni_660x_gate2_to_generic_gate(unsigned gate) { unsigned i; - switch (ni_660x_gate_select) { - case NI_660x_Source_Pin_i_Second_Gate_Select: + switch (gate) { + case NI_660X_SRC_PIN_I_GATE2_SEL: return NI_GPCT_SOURCE_PIN_i_GATE_SELECT; - break; - case NI_660x_Up_Down_Pin_i_Second_Gate_Select: + case NI_660X_UD_PIN_I_GATE2_SEL: return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT; - break; - case NI_660x_Next_SRC_Second_Gate_Select: + case NI_660X_NEXT_SRC_GATE2_SEL: return NI_GPCT_NEXT_SOURCE_GATE_SELECT; - break; - case NI_660x_Next_Out_Second_Gate_Select: + case NI_660X_NEXT_OUT_GATE2_SEL: return NI_GPCT_NEXT_OUT_GATE_SELECT; - break; - case NI_660x_Selected_Gate_Second_Gate_Select: + case NI_660X_SELECTED_GATE2_SEL: return NI_GPCT_SELECTED_GATE_GATE_SELECT; - break; - case NI_660x_Logic_Low_Second_Gate_Select: + case NI_660X_LOGIC_LOW_GATE2_SEL: return NI_GPCT_LOGIC_LOW_GATE_SELECT; - break; default: - for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) { - if (ni_660x_gate_select == - NI_660x_RTSI_Second_Gate_Select(i)) { + for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { + if (gate == NI_660X_RTSI_GATE2_SEL(i)) return NI_GPCT_RTSI_GATE_SELECT(i); - break; - } } - if (i <= ni_660x_max_rtsi_channel) - break; - for (i = 0; i <= ni_660x_max_up_down_pin; ++i) { - if (ni_660x_gate_select == - NI_660x_Up_Down_Pin_Second_Gate_Select(i)) { + for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) { + if (gate == NI_660X_UD_PIN_GATE2_SEL(i)) return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i); - break; - } } - if (i <= ni_660x_max_up_down_pin) - break; BUG(); break; } return 0; }; -static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned - ni_m_series_gate_select) +static unsigned ni_m_gate2_to_generic_gate(unsigned gate) { - /*FIXME: the second gate sources for the m series are undocumented, so we just return - * the raw bits for now. */ - switch (ni_m_series_gate_select) { + /* + * FIXME: the second gate sources for the m series are undocumented, + * so we just return the raw bits for now. + */ + switch (gate) { default: - return ni_m_series_gate_select; - break; + return gate; } return 0; }; @@ -1451,84 +1108,62 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index, { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; - const unsigned mode_bits = - ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); - const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); - unsigned gate_select_bits; + unsigned mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); + unsigned gate2_reg = NITIO_GATE2_REG(cidx); + unsigned gate; switch (gate_index) { case 0: - if ((mode_bits & Gi_Gating_Mode_Mask) == - Gi_Gating_Disabled_Bits) { + if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) { *gate_source = NI_GPCT_DISABLED_GATE_SELECT; return 0; - } else { - gate_select_bits = - (ni_tio_get_soft_copy(counter, - NITIO_INPUT_SEL_REG(cidx)) & - Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift; } + + gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter, + NITIO_INPUT_SEL_REG(cidx))); + switch (counter_dev->variant) { case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: - *gate_source = - ni_m_series_first_gate_to_generic_gate_source - (gate_select_bits); + default: + *gate_source = ni_m_gate_to_generic_gate(gate); break; case ni_gpct_variant_660x: - *gate_source = - ni_660x_first_gate_to_generic_gate_source - (gate_select_bits); - break; - default: - BUG(); + *gate_source = ni_660x_gate_to_generic_gate(gate); break; } - if (mode_bits & Gi_Gate_Polarity_Bit) + if (mode & GI_GATE_POL_INVERT) *gate_source |= CR_INVERT; - if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) + if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING) *gate_source |= CR_EDGE; break; case 1: - if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits - || (counter_dev->regs[second_gate_reg] & - Gi_Second_Gate_Mode_Bit) - == 0) { + if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED || + !(counter_dev->regs[gate2_reg] & GI_GATE2_MODE)) { *gate_source = NI_GPCT_DISABLED_GATE_SELECT; return 0; - } else { - gate_select_bits = - (counter_dev->regs[second_gate_reg] & - Gi_Second_Gate_Select_Mask) >> - Gi_Second_Gate_Select_Shift; } + + gate = GI_BITS_TO_GATE2(counter_dev->regs[gate2_reg]); + switch (counter_dev->variant) { case ni_gpct_variant_e_series: case ni_gpct_variant_m_series: - *gate_source = - ni_m_series_second_gate_to_generic_gate_source - (gate_select_bits); + default: + *gate_source = ni_m_gate2_to_generic_gate(gate); break; case ni_gpct_variant_660x: - *gate_source = - ni_660x_second_gate_to_generic_gate_source - (gate_select_bits); - break; - default: - BUG(); + *gate_source = ni_660x_gate2_to_generic_gate(gate); break; } - if (counter_dev->regs[second_gate_reg] & - Gi_Second_Gate_Polarity_Bit) { + if (counter_dev->regs[gate2_reg] & GI_GATE2_POL_INVERT) *gate_source |= CR_INVERT; - } /* second gate can't have edge/level mode set independently */ - if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) + if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING) *gate_source |= CR_EDGE; break; default: return -EINVAL; - break; } return 0; } @@ -1539,43 +1174,41 @@ int ni_tio_insn_config(struct comedi_device *dev, unsigned int *data) { struct ni_gpct *counter = s->private; + unsigned cidx = counter->counter_index; + unsigned status; switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: return ni_tio_set_counter_mode(counter, data[1]); - break; case INSN_CONFIG_ARM: return ni_tio_arm(counter, 1, data[1]); - break; case INSN_CONFIG_DISARM: ni_tio_arm(counter, 0, 0); return 0; - break; case INSN_CONFIG_GET_COUNTER_STATUS: - data[1] = ni_tio_counter_status(counter); - data[2] = counter_status_mask; + data[1] = 0; + status = read_register(counter, NITIO_SHARED_STATUS_REG(cidx)); + if (status & GI_ARMED(cidx)) { + data[1] |= COMEDI_COUNTER_ARMED; + if (status & GI_COUNTING(cidx)) + data[1] |= COMEDI_COUNTER_COUNTING; + } + data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING; return 0; - break; case INSN_CONFIG_SET_CLOCK_SRC: return ni_tio_set_clock_src(counter, data[1], data[2]); - break; case INSN_CONFIG_GET_CLOCK_SRC: ni_tio_get_clock_src(counter, &data[1], &data[2]); return 0; - break; case INSN_CONFIG_SET_GATE_SRC: return ni_tio_set_gate_src(counter, data[1], data[2]); - break; case INSN_CONFIG_GET_GATE_SRC: return ni_tio_get_gate_src(counter, data[1], &data[2]); - break; case INSN_CONFIG_SET_OTHER_SRC: return ni_tio_set_other_src(counter, data[1], data[2]); - break; case INSN_CONFIG_RESET: ni_tio_reset_count_and_disarm(counter); return 0; - break; default: break; } @@ -1583,6 +1216,33 @@ int ni_tio_insn_config(struct comedi_device *dev, } EXPORT_SYMBOL_GPL(ni_tio_insn_config); +static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct ni_gpct *counter = s->private; + unsigned cidx = counter->counter_index; + unsigned int val; + + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0); + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), + GI_SAVE_TRACE, GI_SAVE_TRACE); + + /* + * The count doesn't get latched until the next clock edge, so it is + * possible the count may change (once) while we are reading. Since + * the read of the SW_Save_Reg isn't atomic (apparently even when it's + * a 32 bit register according to 660x docs), we need to read twice + * and make sure the reading hasn't changed. If it has, a third read + * will be correct since the count value will definitely have latched + * by then. + */ + val = read_register(counter, NITIO_SW_SAVE_REG(cidx)); + if (val != read_register(counter, NITIO_SW_SAVE_REG(cidx))) + val = read_register(counter, NITIO_SW_SAVE_REG(cidx)); + + return val; +} + int ni_tio_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -1590,43 +1250,24 @@ int ni_tio_insn_read(struct comedi_device *dev, { struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned channel = CR_CHAN(insn->chanspec); + unsigned int channel = CR_CHAN(insn->chanspec); unsigned cidx = counter->counter_index; - unsigned first_read; - unsigned second_read; - unsigned correct_read; + int i; - if (insn->n < 1) - return 0; - switch (channel) { - case 0: - ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), - Gi_Save_Trace_Bit, 0); - ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), - Gi_Save_Trace_Bit, Gi_Save_Trace_Bit); - /* The count doesn't get latched until the next clock edge, so it is possible the count - may change (once) while we are reading. Since the read of the SW_Save_Reg isn't - atomic (apparently even when it's a 32 bit register according to 660x docs), - we need to read twice and make sure the reading hasn't changed. If it has, - a third read will be correct since the count value will definitely have latched by then. */ - first_read = read_register(counter, NITIO_SW_SAVE_REG(cidx)); - second_read = read_register(counter, NITIO_SW_SAVE_REG(cidx)); - if (first_read != second_read) - correct_read = - read_register(counter, NITIO_SW_SAVE_REG(cidx)); - else - correct_read = first_read; - data[0] = correct_read; - return 0; - break; - case 1: - data[0] = counter_dev->regs[NITIO_LOADA_REG(cidx)]; - break; - case 2: - data[0] = counter_dev->regs[NITIO_LOADB_REG(cidx)]; - break; + for (i = 0; i < insn->n; i++) { + switch (channel) { + case 0: + data[i] = ni_tio_read_sw_save_reg(dev, s); + break; + case 1: + data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)]; + break; + case 2: + data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)]; + break; + } } - return 0; + return insn->n; } EXPORT_SYMBOL_GPL(ni_tio_insn_read); @@ -1636,10 +1277,9 @@ static unsigned ni_tio_next_load_register(struct ni_gpct *counter) const unsigned bits = read_register(counter, NITIO_SHARED_STATUS_REG(cidx)); - if (bits & Gi_Next_Load_Source_Bit(cidx)) - return NITIO_LOADB_REG(cidx); - else - return NITIO_LOADA_REG(cidx); + return (bits & GI_NEXT_LOAD_SRC(cidx)) + ? NITIO_LOADB_REG(cidx) + : NITIO_LOADA_REG(cidx); } int ni_tio_insn_write(struct comedi_device *dev, @@ -1657,13 +1297,20 @@ int ni_tio_insn_write(struct comedi_device *dev, return 0; switch (channel) { case 0: - /* Unsafe if counter is armed. Should probably check status and return -EBUSY if armed. */ - /* Don't disturb load source select, just use whichever load register is already selected. */ + /* + * Unsafe if counter is armed. + * Should probably check status and return -EBUSY if armed. + */ + + /* + * Don't disturb load source select, just use whichever + * load register is already selected. + */ load_reg = ni_tio_next_load_register(counter); write_register(counter, data[0], load_reg); ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), - 0, 0, Gi_Load_Bit); - /* restore state of load reg to whatever the user set last set it to */ + 0, 0, GI_LOAD); + /* restore load reg */ write_register(counter, counter_dev->regs[load_reg], load_reg); break; case 1: @@ -1676,12 +1323,104 @@ int ni_tio_insn_write(struct comedi_device *dev, break; default: return -EINVAL; - break; } return 0; } EXPORT_SYMBOL_GPL(ni_tio_insn_write); +void ni_tio_init_counter(struct ni_gpct *counter) +{ + struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; + + ni_tio_reset_count_and_disarm(counter); + + /* initialize counter registers */ + counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0; + write_register(counter, 0x0, NITIO_AUTO_INC_REG(cidx)); + + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), + ~0, GI_SYNC_GATE); + + ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); + + counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0; + write_register(counter, 0x0, NITIO_LOADA_REG(cidx)); + + counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0; + write_register(counter, 0x0, NITIO_LOADB_REG(cidx)); + + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); + + if (ni_tio_counting_mode_registers_present(counter_dev)) + ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0); + + if (ni_tio_has_gate2_registers(counter_dev)) { + counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0; + write_register(counter, 0x0, NITIO_GATE2_REG(cidx)); + } + + ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0); + + ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0); +} +EXPORT_SYMBOL_GPL(ni_tio_init_counter); + +struct ni_gpct_device * +ni_gpct_device_construct(struct comedi_device *dev, + void (*write_register)(struct ni_gpct *counter, + unsigned bits, + enum ni_gpct_register reg), + unsigned (*read_register)(struct ni_gpct *counter, + enum ni_gpct_register reg), + enum ni_gpct_variant variant, + unsigned num_counters) +{ + struct ni_gpct_device *counter_dev; + struct ni_gpct *counter; + unsigned i; + + if (num_counters == 0) + return NULL; + + counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL); + if (!counter_dev) + return NULL; + + counter_dev->dev = dev; + counter_dev->write_register = write_register; + counter_dev->read_register = read_register; + counter_dev->variant = variant; + + spin_lock_init(&counter_dev->regs_lock); + + counter_dev->counters = kcalloc(num_counters, sizeof(*counter), + GFP_KERNEL); + if (!counter_dev->counters) { + kfree(counter_dev); + return NULL; + } + + for (i = 0; i < num_counters; ++i) { + counter = &counter_dev->counters[i]; + counter->counter_dev = counter_dev; + spin_lock_init(&counter->lock); + } + counter_dev->num_counters = num_counters; + + return counter_dev; +} +EXPORT_SYMBOL_GPL(ni_gpct_device_construct); + +void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) +{ + if (!counter_dev->counters) + return; + kfree(counter_dev->counters); + kfree(counter_dev); +} +EXPORT_SYMBOL_GPL(ni_gpct_device_destroy); + static int __init ni_tio_init_module(void) { return 0; |