On Thu, Jan 26, 2017 at 01:31:29AM +0800, Cheah Kok Cheong wrote: > Currently this module needs to be manually configured by COMEDI > userspace tool before the test waveform can be read by a COMEDI > compatible application. > > This patch adds auto-configuration capability and makes it the default > loading option. This is achieved by creating a device during init > to stand in for a real hardware device. This allows comedi_auto_config > to perform auto-configuration. With this patch, the test waveform can > be read by a COMEDI compatible application without needing manual > configuration. > > Manual configuration [previous behaviour] is still selectable via > module loading parameter. Module loading without passing any > parameter will default to auto-configuration with the same default > waveform amplitude and period values. For auto-configuration, > different amplitude and period values can be set via module loading > parameters. > > Tested on Xubuntu 16.04 using Xoscope ver: 2.0 which is available > in the Ubuntu repository. Xoscope is a COMEDI compatible digital > oscilloscope application. For manual configuration, only module > loading/unloading is tested. > > Here are the truncated dmesg output. > [sudo modprobe comedi_test] > > comedi_test: 1000000 microvolt, 100000 microsecond waveform attached > driver 'comedi_test' has successfully auto-configured 'comedi_test'. > > [sudo modprobe comedi_test amplitude=2500000 period=150000] > > comedi_test: 2500000 microvolt, 150000 microsecond waveform attached > driver 'comedi_test' has successfully auto-configured 'comedi_test'. > > [sudo modprobe comedi_test manual=1] > > comedi_test: module is from the staging directory, the quality is unknown, > you have been warned. > > For those without an actual hardware, the comedi_test module > is as close as one can get to test the COMEDI system. > Having both auto and manual configuration capability will broaden > the test function of this module. > Hopefully this will make it easier for people to check out the > COMEDI system and contribute to its development. > > Signed-off-by: Cheah Kok Cheong <thrust73@xxxxxxxxx> > --- > drivers/staging/comedi/drivers/comedi_test.c | 140 ++++++++++++++++++++++++--- > 1 file changed, 128 insertions(+), 12 deletions(-) > > diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c > index ec5b9a2..92b3a4f1 100644 > --- a/drivers/staging/comedi/drivers/comedi_test.c > +++ b/drivers/staging/comedi/drivers/comedi_test.c > @@ -36,7 +36,15 @@ > * generate sample waveforms on systems that don't have data acquisition > * hardware. > * > - * Configuration options: > + * Auto configuration is the default mode if no parameter is supplied during > + * module loading. Manual configuration requires COMEDI userspace tool. > + * To select manual configuration mode, pass "manual=1" parameter for module > + * loading. Refer modinfo or MODULE_PARM_DESC description below for details. > + * > + * Auto configuration options: > + * Refer modinfo or MODULE_PARM_DESC description below for details. > + * > + * Manual configuration options: > * [0] - Amplitude in microvolts for fake waveforms (default 1 volt) > * [1] - Period in microseconds for fake waveforms (default 0.1 sec) > * > @@ -53,8 +61,27 @@ > #include <linux/timer.h> > #include <linux/ktime.h> > #include <linux/jiffies.h> > +#include <linux/device.h> > +#include <linux/kdev_t.h> > > #define N_CHANS 8 > +#define DEV_NAME "comedi_testd" > +#define CLASS_NAME "comedi_char" > + > +static bool config_mode; > +static unsigned int set_amplitude; > +static unsigned int set_period; > +static struct class *ctcls; > +static struct device *ctdev; > + > +module_param_named(manual, config_mode, bool, 0444); > +MODULE_PARM_DESC(manual, "Enable manual configuration: (1=enable [defaults to auto])"); > + > +module_param_named(amplitude, set_amplitude, uint, 0444); > +MODULE_PARM_DESC(amplitude, "Set auto mode wave amplitude in microvolts: (defaults to 1 volt)"); > + > +module_param_named(period, set_period, uint, 0444); > +MODULE_PARM_DESC(period, "Set auto mode wave period in microseconds: (defaults to 0.1 sec)"); > > /* Data unique to this driver */ > struct waveform_private { > @@ -607,13 +634,11 @@ static int waveform_ao_insn_write(struct comedi_device *dev, > return insn->n; > } > > -static int waveform_attach(struct comedi_device *dev, > - struct comedi_devconfig *it) > +static int waveform_common_attach(struct comedi_device *dev, > + int amplitude, int period) > { > struct waveform_private *devpriv; > struct comedi_subdevice *s; > - int amplitude = it->options[0]; > - int period = it->options[1]; > int i; > int ret; > > @@ -621,12 +646,6 @@ static int waveform_attach(struct comedi_device *dev, > if (!devpriv) > return -ENOMEM; > > - /* set default amplitude and period */ > - if (amplitude <= 0) > - amplitude = 1000000; /* 1 volt */ > - if (period <= 0) > - period = 100000; /* 0.1 sec */ > - > devpriv->wf_amplitude = amplitude; > devpriv->wf_period = period; > > @@ -678,6 +697,36 @@ static int waveform_attach(struct comedi_device *dev, > return 0; > } > > +static int waveform_attach(struct comedi_device *dev, > + struct comedi_devconfig *it) > +{ > + int amplitude = it->options[0]; > + int period = it->options[1]; > + > + /* set default amplitude and period */ > + if (amplitude <= 0) > + amplitude = 1000000; /* 1 volt */ > + if (period <= 0) > + period = 100000; /* 0.1 sec */ > + > + return waveform_common_attach(dev, amplitude, period); > +} > + > +static int waveform_auto_attach(struct comedi_device *dev, > + unsigned long context_unused) > +{ > + int amplitude = set_amplitude; > + int period = set_period; > + > + /* set default amplitude and period */ > + if (!amplitude) > + amplitude = 1000000; /* 1 volt */ > + if (!period) > + period = 100000; /* 0.1 sec */ > + > + return waveform_common_attach(dev, amplitude, period); > +} > + > static void waveform_detach(struct comedi_device *dev) > { > struct waveform_private *devpriv = dev->private; > @@ -692,9 +741,76 @@ static struct comedi_driver waveform_driver = { > .driver_name = "comedi_test", > .module = THIS_MODULE, > .attach = waveform_attach, > + .auto_attach = waveform_auto_attach, > .detach = waveform_detach, > }; > -module_comedi_driver(waveform_driver); > + > +/* > + * For auto configuration, a device is created to stand in for a > + * real hardware device. > + */ > +static int __init comedi_test_init(void) > +{ > + int ret; > + > + if (!config_mode) { > + ctcls = class_create(THIS_MODULE, CLASS_NAME); > + if (IS_ERR(ctcls)) { > + pr_err("comedi_test: unable to create class\n"); > + return PTR_ERR(ctcls); > + } > + > + ctdev = device_create(ctcls, NULL, MKDEV(0, 0), NULL, DEV_NAME); > + if (IS_ERR(ctdev)) { > + pr_err("comedi_test: unable to create device\n"); > + ret = PTR_ERR(ctdev); > + goto clean3; > + } > + } > + > + ret = comedi_driver_register(&waveform_driver); > + if (ret) { > + pr_err("comedi_test: unable to register driver\n"); > + if (!config_mode) > + goto clean2; > + else > + return ret; > + } > + > + if (!config_mode) { > + ret = comedi_auto_config(ctdev, &waveform_driver, 0); > + if (ret) { > + pr_err("comedi_test: unable to auto configure device\n"); > + goto clean; > + } > + } > + > + return 0; > + > +clean: > + comedi_driver_unregister(&waveform_driver); > +clean2: > + device_destroy(ctcls, MKDEV(0, 0)); > +clean3: > + class_destroy(ctcls); > + > + return ret; > +} > +module_init(comedi_test_init); > + > +static void __exit comedi_test_exit(void) > +{ > + if (!config_mode) > + comedi_auto_unconfig(ctdev); > + > + comedi_driver_unregister(&waveform_driver); > + > + if (!config_mode) { > + device_destroy(ctcls, MKDEV(0, 0)); > + class_destroy(ctcls); > + } > +} > +module_exit(comedi_test_exit); > > MODULE_AUTHOR("Comedi http://www.comedi.org"); > MODULE_DESCRIPTION("Comedi low-level driver"); > -- > 2.7.4 > Hi Ian and Hartley, I'm wondering whether you received this patch and a follow on one. If you did, sorry for the distraction. Thanks. Brgds, CheahKC _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel