diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2014-05-28 23:26:31 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-06-18 21:33:51 (GMT) |
commit | 24e7c352ba019653c9fbe006dc3fe4c0162fa3a7 (patch) | |
tree | 85ae534d642812866baad02ae003705938a2a0a6 /drivers/staging/comedi | |
parent | 4187a79a8416cbbb37354d6e64d013db0f131646 (diff) | |
download | linux-24e7c352ba019653c9fbe006dc3fe4c0162fa3a7.tar.xz |
staging: comedi: ni_mio_common: remove forward declaration 8
Move the cs5529 calibration subdevice functions and helpers to remove
the need for the forward declarations.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi')
-rw-r--r-- | drivers/staging/comedi/drivers/ni_mio_common.c | 280 |
1 files changed, 136 insertions, 144 deletions
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 55eadf4..ffb5a84 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -247,15 +247,6 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, static void handle_gpct_interrupt(struct comedi_device *dev, unsigned short counter_index); -static int init_cs5529(struct comedi_device *dev); -static int cs5529_do_conversion(struct comedi_device *dev, - unsigned short *data); -static int cs5529_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static void cs5529_config_write(struct comedi_device *dev, unsigned int value, - unsigned int reg_select_bits); - static int ni_set_master_clock(struct comedi_device *dev, unsigned source, unsigned period_ns); static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status); @@ -4680,6 +4671,142 @@ static int ni_pfi_insn_bits(struct comedi_device *dev, return insn->n; } +static int cs5529_wait_for_idle(struct comedi_device *dev) +{ + unsigned short status; + const int timeout = HZ; + int i; + + for (i = 0; i < timeout; i++) { + status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); + if ((status & CSS_ADC_BUSY) == 0) + break; + set_current_state(TASK_INTERRUPTIBLE); + if (schedule_timeout(1)) + return -EIO; + } +/* printk("looped %i times waiting for idle\n", i); */ + if (i == timeout) { + printk("%s: %s: timeout\n", __FILE__, __func__); + return -ETIME; + } + return 0; +} + +static void cs5529_command(struct comedi_device *dev, unsigned short value) +{ + static const int timeout = 100; + int i; + + ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx); + /* give time for command to start being serially clocked into cs5529. + * this insures that the CSS_ADC_BUSY bit will get properly + * set before we exit this function. + */ + for (i = 0; i < timeout; i++) { + if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY)) + break; + udelay(1); + } +/* printk("looped %i times writing command to cs5529\n", i); */ + if (i == timeout) + comedi_error(dev, "possible problem - never saw adc go busy?"); +} + +static int cs5529_do_conversion(struct comedi_device *dev, + unsigned short *data) +{ + int retval; + unsigned short status; + + cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION); + retval = cs5529_wait_for_idle(dev); + if (retval) { + comedi_error(dev, + "timeout or signal in cs5529_do_conversion()"); + return -ETIME; + } + status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); + if (status & CSS_OSC_DETECT) { + printk + ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n"); + return -EIO; + } + if (status & CSS_OVERRANGE) { + printk + ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n"); + } + if (data) { + *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx); + /* cs5529 returns 16 bit signed data in bipolar mode */ + *data ^= (1 << 15); + } + return 0; +} + +static int cs5529_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + int n, retval; + unsigned short sample; + unsigned int channel_select; + const unsigned int INTERNAL_REF = 0x1000; + + /* Set calibration adc source. Docs lie, reference select bits 8 to 11 + * do nothing. bit 12 seems to chooses internal reference voltage, bit + * 13 causes the adc input to go overrange (maybe reads external reference?) */ + if (insn->chanspec & CR_ALT_SOURCE) + channel_select = INTERNAL_REF; + else + channel_select = CR_CHAN(insn->chanspec); + ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx); + + for (n = 0; n < insn->n; n++) { + retval = cs5529_do_conversion(dev, &sample); + if (retval < 0) + return retval; + data[n] = sample; + } + return insn->n; +} + +static void cs5529_config_write(struct comedi_device *dev, unsigned int value, + unsigned int reg_select_bits) +{ + ni_ao_win_outw(dev, ((value >> 16) & 0xff), + CAL_ADC_Config_Data_High_Word_67xx); + ni_ao_win_outw(dev, (value & 0xffff), + CAL_ADC_Config_Data_Low_Word_67xx); + reg_select_bits &= CSCMD_REGISTER_SELECT_MASK; + cs5529_command(dev, CSCMD_COMMAND | reg_select_bits); + if (cs5529_wait_for_idle(dev)) + comedi_error(dev, "time or signal in cs5529_config_write()"); +} + +static int init_cs5529(struct comedi_device *dev) +{ + unsigned int config_bits = + CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES; + +#if 1 + /* do self-calibration */ + cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN, + CSCMD_CONFIG_REGISTER); + /* need to force a conversion for calibration to run */ + cs5529_do_conversion(dev, NULL); +#else + /* force gain calibration to 1 */ + cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER); + cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET, + CSCMD_CONFIG_REGISTER); + if (cs5529_wait_for_idle(dev)) + comedi_error(dev, "timeout or signal in init_cs5529()\n"); +#endif + return 0; +} + #ifdef PCIDMA static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -5542,138 +5669,3 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, } return 1; } - -static int cs5529_wait_for_idle(struct comedi_device *dev) -{ - unsigned short status; - const int timeout = HZ; - int i; - - for (i = 0; i < timeout; i++) { - status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); - if ((status & CSS_ADC_BUSY) == 0) - break; - set_current_state(TASK_INTERRUPTIBLE); - if (schedule_timeout(1)) - return -EIO; - } -/* printk("looped %i times waiting for idle\n", i); */ - if (i == timeout) { - printk("%s: %s: timeout\n", __FILE__, __func__); - return -ETIME; - } - return 0; -} - -static void cs5529_command(struct comedi_device *dev, unsigned short value) -{ - static const int timeout = 100; - int i; - - ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx); - /* give time for command to start being serially clocked into cs5529. - * this insures that the CSS_ADC_BUSY bit will get properly - * set before we exit this function. - */ - for (i = 0; i < timeout; i++) { - if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY)) - break; - udelay(1); - } -/* printk("looped %i times writing command to cs5529\n", i); */ - if (i == timeout) - comedi_error(dev, "possible problem - never saw adc go busy?"); -} - -/* write to cs5529 register */ -static void cs5529_config_write(struct comedi_device *dev, unsigned int value, - unsigned int reg_select_bits) -{ - ni_ao_win_outw(dev, ((value >> 16) & 0xff), - CAL_ADC_Config_Data_High_Word_67xx); - ni_ao_win_outw(dev, (value & 0xffff), - CAL_ADC_Config_Data_Low_Word_67xx); - reg_select_bits &= CSCMD_REGISTER_SELECT_MASK; - cs5529_command(dev, CSCMD_COMMAND | reg_select_bits); - if (cs5529_wait_for_idle(dev)) - comedi_error(dev, "time or signal in cs5529_config_write()"); -} - -static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data) -{ - int retval; - unsigned short status; - - cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION); - retval = cs5529_wait_for_idle(dev); - if (retval) { - comedi_error(dev, - "timeout or signal in cs5529_do_conversion()"); - return -ETIME; - } - status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); - if (status & CSS_OSC_DETECT) { - printk - ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n"); - return -EIO; - } - if (status & CSS_OVERRANGE) { - printk - ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n"); - } - if (data) { - *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx); - /* cs5529 returns 16 bit signed data in bipolar mode */ - *data ^= (1 << 15); - } - return 0; -} - -static int cs5529_ai_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int n, retval; - unsigned short sample; - unsigned int channel_select; - const unsigned int INTERNAL_REF = 0x1000; - - /* Set calibration adc source. Docs lie, reference select bits 8 to 11 - * do nothing. bit 12 seems to chooses internal reference voltage, bit - * 13 causes the adc input to go overrange (maybe reads external reference?) */ - if (insn->chanspec & CR_ALT_SOURCE) - channel_select = INTERNAL_REF; - else - channel_select = CR_CHAN(insn->chanspec); - ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx); - - for (n = 0; n < insn->n; n++) { - retval = cs5529_do_conversion(dev, &sample); - if (retval < 0) - return retval; - data[n] = sample; - } - return insn->n; -} - -static int init_cs5529(struct comedi_device *dev) -{ - unsigned int config_bits = - CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES; - -#if 1 - /* do self-calibration */ - cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN, - CSCMD_CONFIG_REGISTER); - /* need to force a conversion for calibration to run */ - cs5529_do_conversion(dev, NULL); -#else - /* force gain calibration to 1 */ - cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER); - cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET, - CSCMD_CONFIG_REGISTER); - if (cs5529_wait_for_idle(dev)) - comedi_error(dev, "timeout or signal in init_cs5529()\n"); -#endif - return 0; -} |