iio: Implement and utilize register structures for ISA drivers
Subsystems (2)
v2 cover iio: Implement and utilize register structures for ISA drivers
Changes in v2:
- Rename 'ad' member to 'ssr_ad' to indicate access to Software Strobe Register as well; relevant comments updated
- Dereference DAC channel address via array subscripts in the stx104_write_raw() function in order to match rest of code
- Replace struct cio_dac_reg with direct u16 pointer to the DAC address; this greatly simplifies the cio-dac patch
The STX104 and CIO-DAC drivers were updated to use I/O memory accessor calls such as ioread8()/iowrite8() in previous patch series [1]. This patch series is a continuation of the effort to improve the code readability and reduce magic numbers by implementing and utilizing named register data structures.
[1] https://lore.kernel.org/all/[email protected]/
William Breathitt Gray (2):
iio: adc: stx104: Implement and utilize register structures
iio: dac: cio-dac: Cleanup indexing for DAC writes
drivers/iio/adc/stx104.c | 74 ++++++++++++++++++++++++++------------- drivers/iio/dac/cio-dac.c | 10 +++--- 2 files changed, 55 insertions(+), 29 deletions(-)
base-commit: 338222d8e1121bcb78a86fb39982eddcc367a5bc
Signature · 1 line
2.36.1
PATCH v2 1/2 iio: adc: stx104: Implement and utilize register structures
Reduce magic numbers and improve code readability by implementing and utilizing named register data structures.
--- drivers/iio/adc/stx104.c | 74 +++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 24 deletions(-)
drivers/iio/adc/stx104.c +50 -24
@@ -16,6 +16,7 @@#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/spinlock.h> +#include <linux/types.h> #define STX104_OUT_CHAN (chan) { \ .type = IIO_VOLTAGE, \
@@ -44,14 +45,36 @@ static unsigned int num_stx104;module_param_hw_array (base, uint, ioport, &num_stx104,0 );MODULE_PARM_DESC (base,"Apex Embedded Systems STX104 base addresses" ); +/** +* struct stx104_reg - device register structure +* @ssr_ad: Software Strobe Register and ADC Data +* @achan: ADC Channel +* @dio: Digital I/O +* @dac: DAC Channels +* @cir_asr: Clear Interrupts and ADC Status +* @acr: ADC Control +* @pccr_fsh: Pacer Clock Control and FIFO Status MSB +* @acfg: ADC Configuration +*/ +struct stx104_reg { +u16 ssr_ad; +u8 achan; +u8 dio; +u16 dac[2 ]; +u8 cir_asr; +u8 acr; +u8 pccr_fsh; +u8 acfg; +}; +/** * struct stx104_iio - IIO device private data structure * @chan_out_states: channels' output states -* @base: base port address of the IIO device +* @reg: I/O address offset for the device registers */ struct stx104_iio {unsigned int chan_out_states[STX104_NUM_OUT_CHAN ]; -void __iomem *base; +struct stx104_reg __iomem *reg; };/**
@@ -64,7 +87,7 @@ struct stx104_iio {struct stx104_gpio {struct gpio_chip chip;spinlock_t lock; -void __iomem *base; +u8 __iomem *base;unsigned int out_state; };
@@ -72,6 +95,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct stx104_iio *const priv = iio_priv(indio_dev); +struct stx104_reg __iomem *const reg = priv->reg;unsigned int adc_config;int adbu;int gain;
@@ -79,7 +103,7 @@ static int stx104_read_raw(struct iio_dev *indio_dev,switch (mask) {case IIO_CHAN_INFO_HARDWAREGAIN :/* get gain configuration */ - adc_config =ioread8 (priv->base +11 ); + adc_config =ioread8 (®->acfg); gain = adc_config &0x3 ; *val =1 << gain;
@@ -91,24 +115,26 @@ static int stx104_read_raw(struct iio_dev *indio_dev, }/* select ADC channel */ -iowrite8 (chan->channel | (chan->channel <<4 ), priv->base +2 ); +iowrite8 (chan->channel | (chan->channel <<4 ), ®->achan); -/* trigger ADC sample capture and wait for completion */ -iowrite8 (0 , priv->base); -while (ioread8 (priv->base +8 ) &BIT (7 )); +/* trigger ADC sample capture by writing to the 8-bit +* Software Strobe Register and wait for completion +*/ +iowrite8 (0 , ®->ssr_ad); +while (ioread8 (®->cir_asr) &BIT (7 )); - *val =ioread16 (priv->base); + *val =ioread16 (®->ssr_ad);return IIO_VAL_INT ;case IIO_CHAN_INFO_OFFSET :/* get ADC bipolar/unipolar configuration */ - adc_config =ioread8 (priv->base +11 ); + adc_config =ioread8 (®->acfg); adbu = !(adc_config &BIT (2 )); *val =-32768 * adbu;return IIO_VAL_INT ;case IIO_CHAN_INFO_SCALE :/* get ADC bipolar/unipolar and gain configuration */ - adc_config =ioread8 (priv->base +11 ); + adc_config =ioread8 (®->acfg); adbu = !(adc_config &BIT (2 )); gain = adc_config &0x3 ;
@@ -130,16 +156,16 @@ static int stx104_write_raw(struct iio_dev *indio_dev,/* Only four gain states (x1, x2, x4, x8) */ switch (val) {case 1 : -iowrite8 (0 , priv->base +11 ); +iowrite8 (0 , &priv->reg->acfg);break ;case 2 : -iowrite8 (1 , priv->base +11 ); +iowrite8 (1 , &priv->reg->acfg);break ;case 4 : -iowrite8 (2 , priv->base +11 ); +iowrite8 (2 , &priv->reg->acfg);break ;case 8 : -iowrite8 (3 , priv->base +11 ); +iowrite8 (3 , &priv->reg->acfg);break ;default :return -EINVAL ;
@@ -153,7 +179,7 @@ static int stx104_write_raw(struct iio_dev *indio_dev,return -EINVAL ; priv->chan_out_states[chan->channel] = val; -iowrite16 (val, priv->base +4 +2 * chan->channel); +iowrite16 (val, &priv->reg->dac[chan->channel]);return 0 ; }
@@ -307,15 +333,15 @@ static int stx104_probe(struct device *dev, unsigned int id) } priv =iio_priv (indio_dev); - priv->base =devm_ioport_map (dev, base[id],STX104_EXTENT ); -if (!priv->base) + priv->reg =devm_ioport_map (dev, base[id],STX104_EXTENT ); +if (!priv->reg)return -ENOMEM ; indio_dev->info = &stx104_info; indio_dev->modes =INDIO_DIRECT_MODE ;/* determine if differential inputs */ -if (ioread8 (priv->base +8 ) &BIT (5 )) { +if (ioread8 (&priv->reg->cir_asr) &BIT (5 )) { indio_dev->num_channels =ARRAY_SIZE (stx104_channels_diff); indio_dev->channels = stx104_channels_diff; }else {
@@ -326,14 +352,14 @@ static int stx104_probe(struct device *dev, unsigned int id) indio_dev->name =dev_name (dev);/* configure device for software trigger operation */ -iowrite8 (0 , priv->base +9 ); +iowrite8 (0 , &priv->reg->acr);/* initialize gain setting to x1 */ -iowrite8 (0 , priv->base +11 ); +iowrite8 (0 , &priv->reg->acfg);/* initialize DAC output to 0V */ -iowrite16 (0 , priv->base +4 ); -iowrite16 (0 , priv->base +6 ); +iowrite16 (0 , &priv->reg->dac[0 ]); +iowrite16 (0 , &priv->reg->dac[1 ]); stx104gpio->chip.label =dev_name (dev); stx104gpio->chip.parent = dev;
@@ -348,7 +374,7 @@ static int stx104_probe(struct device *dev, unsigned int id) stx104gpio->chip.get_multiple = stx104_gpio_get_multiple; stx104gpio->chip.set = stx104_gpio_set; stx104gpio->chip.set_multiple = stx104_gpio_set_multiple; - stx104gpio->base = priv->base +3 ; + stx104gpio->base = &priv->reg->dio; stx104gpio->out_state =0x0 ;spin_lock_init (&stx104gpio->lock);
Signature · 1 line
2.36.1
PATCH v2 2/2 iio: dac: cio-dac: Cleanup indexing for DAC writes
In reply to William Breathitt GraySimplify DAC write code by defining base member as u16 __iomem *; DAC registers are 16-bit so this allows us to index each DAC channel directly in a loop rather than calculating the offsets by multipling by 2 each time.
--- drivers/iio/dac/cio-dac.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/iio/dac/cio-dac.c +5 -5
@@ -16,6 +16,7 @@#include <linux/isa.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/types.h> #define CIO_DAC_NUM_CHAN 16
@@ -37,11 +38,11 @@ MODULE_PARM_DESC(base, "Measurement Computing CIO-DAC base addresses");/** * struct cio_dac_iio - IIO device private data structure * @chan_out_states: channels' output states -* @base: base port address of the IIO device +* @base: base memory address of the DAC device */ struct cio_dac_iio {int chan_out_states[CIO_DAC_NUM_CHAN ]; -void __iomem *base; +u16 __iomem *base; }; static int cio_dac_read_raw(struct iio_dev *indio_dev,
@@ -61,7 +62,6 @@ static int cio_dac_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { struct cio_dac_iio *const priv = iio_priv(indio_dev); -const unsigned int chan_addr_offset =2 * chan->channel;if (mask !=IIO_CHAN_INFO_RAW )return -EINVAL ;
@@ -71,7 +71,7 @@ static int cio_dac_write_raw(struct iio_dev *indio_dev,return -EINVAL ; priv->chan_out_states[chan->channel] = val; -iowrite16 (val, priv->base + chan_addr_offset); +iowrite16 (val, priv->base + chan->channel);return 0 ; }
@@ -117,7 +117,7 @@ static int cio_dac_probe(struct device *dev, unsigned int id) indio_dev->name =dev_name (dev);/* initialize DAC outputs to 0V */ -for (i =0 ; i <32 ; i +=2 ) +for (i =0 ; i <CIO_DAC_NUM_CHAN ; i++)iowrite16 (0 , priv->base + i);return devm_iio_device_register (dev, indio_dev);
Signature · 1 line
2.36.1
Jonathan Cameron
maintainerQuoted 8 lines · On Thu, 7 Jul 2022 13:21:23 -0400 William Breathitt Gray…
Changes in v2:
- Rename 'ad' member to 'ssr_ad' to indicate access to Software Strobe Register as well; relevant comments updated
- Dereference DAC channel address via array subscripts in thestx104_write_raw()function in order to match rest of code
- Replace structcio_dac_regwith direct u16 pointer to the DAC address; this greatly simplifies the cio-dac patch
Quoted 5 lines
The STX104 and CIO-DAC drivers were updated to use I/O memory accessor calls such as ioread8()/iowrite8() in previous patch series [1]. This patch series is a continuation of the effort to improve the code readability and reduce magic numbers by implementing and utilizing named register data structures.
Series applied to the togreg branch of iio.git. Given timing in cycle, I'll only push that out as testing (for 0-day etc) and then rebase it after rc1.
Thanks,
Jonathan
Quoted 13 lines
[1] https://lore.kernel.org/all/[email protected]/
William Breathitt Gray (2):
iio: adc: stx104: Implement and utilize register structures
iio: dac: cio-dac: Cleanup indexing for DAC writesdrivers/iio/adc/stx104.c | 74 ++++++++++++++++++++++++++------------- drivers/iio/dac/cio-dac.c | 10 +++--- 2 files changed, 55 insertions(+), 29 deletions(-)base-commit:
338222d8e1121bcb78a86fb39982eddcc367a5bc