* [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use @ 2016-03-22 16:08 Ludovic Desroches 2016-03-22 16:08 ` [PATCH 2/2] iio:adc:at91-sama5d2: add support for differential conversions Ludovic Desroches 2016-03-28 14:59 ` [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use Jonathan Cameron 0 siblings, 2 replies; 4+ messages in thread From: Ludovic Desroches @ 2016-03-22 16:08 UTC (permalink / raw) To: linux-arm-kernel Do not erase previous configuration of the mode register when setting the sampling frequency. Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> --- drivers/iio/adc/at91-sama5d2_adc.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 5bc038f..01ba106 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -66,8 +66,10 @@ #define AT91_SAMA5D2_MR_PRESCAL(v) ((v) << AT91_SAMA5D2_MR_PRESCAL_OFFSET) #define AT91_SAMA5D2_MR_PRESCAL_OFFSET 8 #define AT91_SAMA5D2_MR_PRESCAL_MAX 0xff +#define AT91_SAMA5D2_MR_PRESCAL_MASK GENMASK(15, 8) /* Startup Time */ #define AT91_SAMA5D2_MR_STARTUP(v) ((v) << 16) +#define AT91_SAMA5D2_MR_STARTUP_MASK GENMASK(19, 16) /* Analog Change */ #define AT91_SAMA5D2_MR_ANACH BIT(23) /* Tracking Time */ @@ -226,7 +228,7 @@ static unsigned at91_adc_startup_time(unsigned startup_time_min, static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) { struct iio_dev *indio_dev = iio_priv_to_dev(st); - unsigned f_per, prescal, startup; + unsigned f_per, prescal, startup, mr; f_per = clk_get_rate(st->per_clk); prescal = (f_per / (2 * freq)) - 1; @@ -234,10 +236,11 @@ static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) startup = at91_adc_startup_time(st->soc_info.startup_time, freq / 1000); - at91_adc_writel(st, AT91_SAMA5D2_MR, - AT91_SAMA5D2_MR_TRANSFER(2) - | AT91_SAMA5D2_MR_STARTUP(startup) - | AT91_SAMA5D2_MR_PRESCAL(prescal)); + mr = at91_adc_readl(st, AT91_SAMA5D2_MR); + mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK); + mr |= AT91_SAMA5D2_MR_STARTUP(startup); + mr |= AT91_SAMA5D2_MR_PRESCAL(prescal); + at91_adc_writel(st, AT91_SAMA5D2_MR, mr); dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n", freq, startup, prescal); @@ -444,6 +447,8 @@ static int at91_adc_probe(struct platform_device *pdev) at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); + /* Transfer field must be set to 2 according to the datasheet. */ + at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2)); at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); -- 2.5.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] iio:adc:at91-sama5d2: add support for differential conversions 2016-03-22 16:08 [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use Ludovic Desroches @ 2016-03-22 16:08 ` Ludovic Desroches 2016-03-28 14:58 ` Jonathan Cameron 2016-03-28 14:59 ` [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use Jonathan Cameron 1 sibling, 1 reply; 4+ messages in thread From: Ludovic Desroches @ 2016-03-22 16:08 UTC (permalink / raw) To: linux-arm-kernel Add signed differential channels and update the voltage scale for differential conversions. Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> --- This patch is based on: iio:adc:at91-sama5d2: fix identation iio:adc:at91-sama5d2: fix typo drivers/iio/adc/at91-sama5d2_adc.c | 71 ++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index 01ba106..07adb10 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -113,8 +113,11 @@ #define AT91_SAMA5D2_CWR 0x44 /* Channel Gain Register */ #define AT91_SAMA5D2_CGR 0x48 + /* Channel Offset Register */ #define AT91_SAMA5D2_COR 0x4c +#define AT91_SAMA5D2_COR_DIFF_OFFSET 16 + /* Channel Data Register 0 */ #define AT91_SAMA5D2_CDR0 0x50 /* Analog Control Register */ @@ -142,7 +145,7 @@ /* Version Register */ #define AT91_SAMA5D2_VERSION 0xfc -#define AT91_SAMA5D2_CHAN(num, addr) \ +#define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \ { \ .type = IIO_VOLTAGE, \ .channel = num, \ @@ -158,6 +161,24 @@ .indexed = 1, \ } +#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr) \ + { \ + .type = IIO_VOLTAGE, \ + .differential = 1, \ + .channel = num, \ + .channel2 = num2, \ + .address = addr, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ + .datasheet_name = "CH"#num"-CH"#num2, \ + .indexed = 1, \ + } + #define at91_adc_readl(st, reg) readl_relaxed(st->base + reg) #define at91_adc_writel(st, reg, val) writel_relaxed(val, st->base + reg) @@ -187,18 +208,24 @@ struct at91_adc_state { }; static const struct iio_chan_spec at91_adc_channels[] = { - AT91_SAMA5D2_CHAN(0, 0x50), - AT91_SAMA5D2_CHAN(1, 0x54), - AT91_SAMA5D2_CHAN(2, 0x58), - AT91_SAMA5D2_CHAN(3, 0x5c), - AT91_SAMA5D2_CHAN(4, 0x60), - AT91_SAMA5D2_CHAN(5, 0x64), - AT91_SAMA5D2_CHAN(6, 0x68), - AT91_SAMA5D2_CHAN(7, 0x6c), - AT91_SAMA5D2_CHAN(8, 0x70), - AT91_SAMA5D2_CHAN(9, 0x74), - AT91_SAMA5D2_CHAN(10, 0x78), - AT91_SAMA5D2_CHAN(11, 0x7c), + AT91_SAMA5D2_CHAN_SINGLE(0, 0x50), + AT91_SAMA5D2_CHAN_SINGLE(1, 0x54), + AT91_SAMA5D2_CHAN_SINGLE(2, 0x58), + AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c), + AT91_SAMA5D2_CHAN_SINGLE(4, 0x60), + AT91_SAMA5D2_CHAN_SINGLE(5, 0x64), + AT91_SAMA5D2_CHAN_SINGLE(6, 0x68), + AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c), + AT91_SAMA5D2_CHAN_SINGLE(8, 0x70), + AT91_SAMA5D2_CHAN_SINGLE(9, 0x74), + AT91_SAMA5D2_CHAN_SINGLE(10, 0x78), + AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c), + AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50), + AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58), + AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60), + AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68), + AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70), + AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78), }; static unsigned at91_adc_startup_time(unsigned startup_time_min, @@ -281,6 +308,7 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct at91_adc_state *st = iio_priv(indio_dev); + u32 cor = 0; int ret; switch (mask) { @@ -289,6 +317,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, st->chan = chan; + if (chan->differential) + cor = (BIT(chan->channel) | BIT(chan->channel2)) << + AT91_SAMA5D2_COR_DIFF_OFFSET; + + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel)); at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START); @@ -301,6 +334,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, if (ret > 0) { *val = st->conversion_value; + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, 11); ret = IIO_VAL_INT; st->conversion_done = false; } @@ -313,6 +348,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: *val = st->vref_uv / 1000; + if (chan->differential) + *val *= 2; *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; @@ -447,8 +484,12 @@ static int at91_adc_probe(struct platform_device *pdev) at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); - /* Transfer field must be set to 2 according to the datasheet. */ - at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2)); + /* + * Transfer field must be set to 2 according to the datasheet and + * allows different analog settings for each channel. + */ + at91_adc_writel(st, AT91_SAMA5D2_MR, + AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); -- 2.5.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] iio:adc:at91-sama5d2: add support for differential conversions 2016-03-22 16:08 ` [PATCH 2/2] iio:adc:at91-sama5d2: add support for differential conversions Ludovic Desroches @ 2016-03-28 14:58 ` Jonathan Cameron 0 siblings, 0 replies; 4+ messages in thread From: Jonathan Cameron @ 2016-03-28 14:58 UTC (permalink / raw) To: linux-arm-kernel On 22/03/16 16:08, Ludovic Desroches wrote: > Add signed differential channels and update the voltage scale for > differential conversions. > > Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> Looks good to me. Applied to the togreg branch of iio.git - initially pushed out as testing etc etc. Jonathan > --- > > This patch is based on: > iio:adc:at91-sama5d2: fix identation > iio:adc:at91-sama5d2: fix typo > > drivers/iio/adc/at91-sama5d2_adc.c | 71 ++++++++++++++++++++++++++++++-------- > 1 file changed, 56 insertions(+), 15 deletions(-) > > diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c > index 01ba106..07adb10 100644 > --- a/drivers/iio/adc/at91-sama5d2_adc.c > +++ b/drivers/iio/adc/at91-sama5d2_adc.c > @@ -113,8 +113,11 @@ > #define AT91_SAMA5D2_CWR 0x44 > /* Channel Gain Register */ > #define AT91_SAMA5D2_CGR 0x48 > + Ever so slight gripe here as this is unconnected to this patch so should have been in a trivial additional patch... > /* Channel Offset Register */ > #define AT91_SAMA5D2_COR 0x4c > +#define AT91_SAMA5D2_COR_DIFF_OFFSET 16 > + > /* Channel Data Register 0 */ > #define AT91_SAMA5D2_CDR0 0x50 > /* Analog Control Register */ > @@ -142,7 +145,7 @@ > /* Version Register */ > #define AT91_SAMA5D2_VERSION 0xfc > > -#define AT91_SAMA5D2_CHAN(num, addr) \ > +#define AT91_SAMA5D2_CHAN_SINGLE(num, addr) \ > { \ > .type = IIO_VOLTAGE, \ > .channel = num, \ > @@ -158,6 +161,24 @@ > .indexed = 1, \ > } > > +#define AT91_SAMA5D2_CHAN_DIFF(num, num2, addr) \ > + { \ > + .type = IIO_VOLTAGE, \ > + .differential = 1, \ > + .channel = num, \ > + .channel2 = num2, \ > + .address = addr, \ > + .scan_type = { \ > + .sign = 's', \ > + .realbits = 12, \ > + }, \ > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ > + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ > + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\ > + .datasheet_name = "CH"#num"-CH"#num2, \ > + .indexed = 1, \ > + } > + > #define at91_adc_readl(st, reg) readl_relaxed(st->base + reg) > #define at91_adc_writel(st, reg, val) writel_relaxed(val, st->base + reg) > > @@ -187,18 +208,24 @@ struct at91_adc_state { > }; > > static const struct iio_chan_spec at91_adc_channels[] = { > - AT91_SAMA5D2_CHAN(0, 0x50), > - AT91_SAMA5D2_CHAN(1, 0x54), > - AT91_SAMA5D2_CHAN(2, 0x58), > - AT91_SAMA5D2_CHAN(3, 0x5c), > - AT91_SAMA5D2_CHAN(4, 0x60), > - AT91_SAMA5D2_CHAN(5, 0x64), > - AT91_SAMA5D2_CHAN(6, 0x68), > - AT91_SAMA5D2_CHAN(7, 0x6c), > - AT91_SAMA5D2_CHAN(8, 0x70), > - AT91_SAMA5D2_CHAN(9, 0x74), > - AT91_SAMA5D2_CHAN(10, 0x78), > - AT91_SAMA5D2_CHAN(11, 0x7c), > + AT91_SAMA5D2_CHAN_SINGLE(0, 0x50), > + AT91_SAMA5D2_CHAN_SINGLE(1, 0x54), > + AT91_SAMA5D2_CHAN_SINGLE(2, 0x58), > + AT91_SAMA5D2_CHAN_SINGLE(3, 0x5c), > + AT91_SAMA5D2_CHAN_SINGLE(4, 0x60), > + AT91_SAMA5D2_CHAN_SINGLE(5, 0x64), > + AT91_SAMA5D2_CHAN_SINGLE(6, 0x68), > + AT91_SAMA5D2_CHAN_SINGLE(7, 0x6c), > + AT91_SAMA5D2_CHAN_SINGLE(8, 0x70), > + AT91_SAMA5D2_CHAN_SINGLE(9, 0x74), > + AT91_SAMA5D2_CHAN_SINGLE(10, 0x78), > + AT91_SAMA5D2_CHAN_SINGLE(11, 0x7c), > + AT91_SAMA5D2_CHAN_DIFF(0, 1, 0x50), > + AT91_SAMA5D2_CHAN_DIFF(2, 3, 0x58), > + AT91_SAMA5D2_CHAN_DIFF(4, 5, 0x60), > + AT91_SAMA5D2_CHAN_DIFF(6, 7, 0x68), > + AT91_SAMA5D2_CHAN_DIFF(8, 9, 0x70), > + AT91_SAMA5D2_CHAN_DIFF(10, 11, 0x78), > }; > > static unsigned at91_adc_startup_time(unsigned startup_time_min, > @@ -281,6 +308,7 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, > int *val, int *val2, long mask) > { > struct at91_adc_state *st = iio_priv(indio_dev); > + u32 cor = 0; > int ret; > > switch (mask) { > @@ -289,6 +317,11 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, > > st->chan = chan; > > + if (chan->differential) > + cor = (BIT(chan->channel) | BIT(chan->channel2)) << > + AT91_SAMA5D2_COR_DIFF_OFFSET; > + > + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); > at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); > at91_adc_writel(st, AT91_SAMA5D2_IER, BIT(chan->channel)); > at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_START); > @@ -301,6 +334,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, > > if (ret > 0) { > *val = st->conversion_value; > + if (chan->scan_type.sign == 's') > + *val = sign_extend32(*val, 11); > ret = IIO_VAL_INT; > st->conversion_done = false; > } > @@ -313,6 +348,8 @@ static int at91_adc_read_raw(struct iio_dev *indio_dev, > > case IIO_CHAN_INFO_SCALE: > *val = st->vref_uv / 1000; > + if (chan->differential) > + *val *= 2; > *val2 = chan->scan_type.realbits; > return IIO_VAL_FRACTIONAL_LOG2; > > @@ -447,8 +484,12 @@ static int at91_adc_probe(struct platform_device *pdev) > > at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); > at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); > - /* Transfer field must be set to 2 according to the datasheet. */ > - at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2)); > + /* > + * Transfer field must be set to 2 according to the datasheet and > + * allows different analog settings for each channel. > + */ > + at91_adc_writel(st, AT91_SAMA5D2_MR, > + AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); > > at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); > > ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use 2016-03-22 16:08 [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use Ludovic Desroches 2016-03-22 16:08 ` [PATCH 2/2] iio:adc:at91-sama5d2: add support for differential conversions Ludovic Desroches @ 2016-03-28 14:59 ` Jonathan Cameron 1 sibling, 0 replies; 4+ messages in thread From: Jonathan Cameron @ 2016-03-28 14:59 UTC (permalink / raw) To: linux-arm-kernel On 22/03/16 16:08, Ludovic Desroches wrote: > Do not erase previous configuration of the mode register when setting > the sampling frequency. > > Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com> Applied. > --- > drivers/iio/adc/at91-sama5d2_adc.c | 15 ++++++++++----- > 1 file changed, 10 insertions(+), 5 deletions(-) > > diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c > index 5bc038f..01ba106 100644 > --- a/drivers/iio/adc/at91-sama5d2_adc.c > +++ b/drivers/iio/adc/at91-sama5d2_adc.c > @@ -66,8 +66,10 @@ > #define AT91_SAMA5D2_MR_PRESCAL(v) ((v) << AT91_SAMA5D2_MR_PRESCAL_OFFSET) > #define AT91_SAMA5D2_MR_PRESCAL_OFFSET 8 > #define AT91_SAMA5D2_MR_PRESCAL_MAX 0xff > +#define AT91_SAMA5D2_MR_PRESCAL_MASK GENMASK(15, 8) > /* Startup Time */ > #define AT91_SAMA5D2_MR_STARTUP(v) ((v) << 16) > +#define AT91_SAMA5D2_MR_STARTUP_MASK GENMASK(19, 16) > /* Analog Change */ > #define AT91_SAMA5D2_MR_ANACH BIT(23) > /* Tracking Time */ > @@ -226,7 +228,7 @@ static unsigned at91_adc_startup_time(unsigned startup_time_min, > static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) > { > struct iio_dev *indio_dev = iio_priv_to_dev(st); > - unsigned f_per, prescal, startup; > + unsigned f_per, prescal, startup, mr; > > f_per = clk_get_rate(st->per_clk); > prescal = (f_per / (2 * freq)) - 1; > @@ -234,10 +236,11 @@ static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) > startup = at91_adc_startup_time(st->soc_info.startup_time, > freq / 1000); > > - at91_adc_writel(st, AT91_SAMA5D2_MR, > - AT91_SAMA5D2_MR_TRANSFER(2) > - | AT91_SAMA5D2_MR_STARTUP(startup) > - | AT91_SAMA5D2_MR_PRESCAL(prescal)); > + mr = at91_adc_readl(st, AT91_SAMA5D2_MR); > + mr &= ~(AT91_SAMA5D2_MR_STARTUP_MASK | AT91_SAMA5D2_MR_PRESCAL_MASK); > + mr |= AT91_SAMA5D2_MR_STARTUP(startup); > + mr |= AT91_SAMA5D2_MR_PRESCAL(prescal); > + at91_adc_writel(st, AT91_SAMA5D2_MR, mr); > > dev_dbg(&indio_dev->dev, "freq: %u, startup: %u, prescal: %u\n", > freq, startup, prescal); > @@ -444,6 +447,8 @@ static int at91_adc_probe(struct platform_device *pdev) > > at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); > at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); > + /* Transfer field must be set to 2 according to the datasheet. */ > + at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2)); > > at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); > > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-03-28 14:59 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-03-22 16:08 [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use Ludovic Desroches 2016-03-22 16:08 ` [PATCH 2/2] iio:adc:at91-sama5d2: add support for differential conversions Ludovic Desroches 2016-03-28 14:58 ` Jonathan Cameron 2016-03-28 14:59 ` [PATCH 1/2] iio:adc:at91-sama5d2: cleanup mode register use Jonathan Cameron
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).