0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0015
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/init.h>
0019 #include <linux/irqnr.h>
0020 #include <linux/time.h>
0021 #include <linux/slab.h>
0022 #include <linux/parport.h>
0023 #include <linux/pps_kernel.h>
0024
0025
0026
0027 #define CLEAR_WAIT_MAX 100
0028 #define CLEAR_WAIT_MAX_ERRORS 5
0029
0030 static unsigned int clear_wait = 100;
0031 MODULE_PARM_DESC(clear_wait,
0032 "Maximum number of port reads when polling for signal clear,"
0033 " zero turns clear edge capture off entirely");
0034 module_param(clear_wait, uint, 0);
0035
0036 static DEFINE_IDA(pps_client_index);
0037
0038
0039 struct pps_client_pp {
0040 struct pardevice *pardev;
0041 struct pps_device *pps;
0042 unsigned int cw;
0043 unsigned int cw_err;
0044 int index;
0045 };
0046
0047 static inline int signal_is_set(struct parport *port)
0048 {
0049 return (port->ops->read_status(port) & PARPORT_STATUS_ACK) != 0;
0050 }
0051
0052
0053 static void parport_irq(void *handle)
0054 {
0055 struct pps_event_time ts_assert, ts_clear;
0056 struct pps_client_pp *dev = handle;
0057 struct parport *port = dev->pardev->port;
0058 unsigned int i;
0059 unsigned long flags;
0060
0061
0062 pps_get_ts(&ts_assert);
0063
0064 if (dev->cw == 0)
0065
0066 goto out_assert;
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 local_irq_save(flags);
0081
0082 if (!signal_is_set(port)) {
0083 local_irq_restore(flags);
0084 dev_err(dev->pps->dev, "lost the signal\n");
0085 goto out_assert;
0086 }
0087
0088
0089 for (i = dev->cw; i; i--)
0090 if (!signal_is_set(port)) {
0091 pps_get_ts(&ts_clear);
0092 local_irq_restore(flags);
0093 dev->cw_err = 0;
0094 goto out_both;
0095 }
0096 local_irq_restore(flags);
0097
0098
0099 dev->cw_err++;
0100 if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) {
0101 dev_err(dev->pps->dev, "disabled clear edge capture after %d"
0102 " timeouts\n", dev->cw_err);
0103 dev->cw = 0;
0104 dev->cw_err = 0;
0105 }
0106
0107 out_assert:
0108
0109 pps_event(dev->pps, &ts_assert,
0110 PPS_CAPTUREASSERT, NULL);
0111 return;
0112
0113 out_both:
0114
0115 pps_event(dev->pps, &ts_assert,
0116 PPS_CAPTUREASSERT, NULL);
0117
0118 pps_event(dev->pps, &ts_clear,
0119 PPS_CAPTURECLEAR, NULL);
0120 return;
0121 }
0122
0123 static void parport_attach(struct parport *port)
0124 {
0125 struct pardev_cb pps_client_cb;
0126 int index;
0127 struct pps_client_pp *device;
0128 struct pps_source_info info = {
0129 .name = KBUILD_MODNAME,
0130 .path = "",
0131 .mode = PPS_CAPTUREBOTH | \
0132 PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \
0133 PPS_ECHOASSERT | PPS_ECHOCLEAR | \
0134 PPS_CANWAIT | PPS_TSFMT_TSPEC,
0135 .owner = THIS_MODULE,
0136 .dev = NULL
0137 };
0138
0139 if (clear_wait > CLEAR_WAIT_MAX) {
0140 pr_err("clear_wait value should be not greater then %d\n",
0141 CLEAR_WAIT_MAX);
0142 return;
0143 }
0144
0145 device = kzalloc(sizeof(struct pps_client_pp), GFP_KERNEL);
0146 if (!device) {
0147 pr_err("memory allocation failed, not attaching\n");
0148 return;
0149 }
0150
0151 index = ida_simple_get(&pps_client_index, 0, 0, GFP_KERNEL);
0152 memset(&pps_client_cb, 0, sizeof(pps_client_cb));
0153 pps_client_cb.private = device;
0154 pps_client_cb.irq_func = parport_irq;
0155 pps_client_cb.flags = PARPORT_FLAG_EXCL;
0156 device->pardev = parport_register_dev_model(port,
0157 KBUILD_MODNAME,
0158 &pps_client_cb,
0159 index);
0160 if (!device->pardev) {
0161 pr_err("couldn't register with %s\n", port->name);
0162 goto err_free;
0163 }
0164
0165 if (parport_claim_or_block(device->pardev) < 0) {
0166 pr_err("couldn't claim %s\n", port->name);
0167 goto err_unregister_dev;
0168 }
0169
0170 device->pps = pps_register_source(&info,
0171 PPS_CAPTUREBOTH | PPS_OFFSETASSERT | PPS_OFFSETCLEAR);
0172 if (IS_ERR(device->pps)) {
0173 pr_err("couldn't register PPS source\n");
0174 goto err_release_dev;
0175 }
0176
0177 device->cw = clear_wait;
0178
0179 port->ops->enable_irq(port);
0180 device->index = index;
0181
0182 pr_info("attached to %s\n", port->name);
0183
0184 return;
0185
0186 err_release_dev:
0187 parport_release(device->pardev);
0188 err_unregister_dev:
0189 parport_unregister_device(device->pardev);
0190 err_free:
0191 ida_simple_remove(&pps_client_index, index);
0192 kfree(device);
0193 }
0194
0195 static void parport_detach(struct parport *port)
0196 {
0197 struct pardevice *pardev = port->cad;
0198 struct pps_client_pp *device;
0199
0200
0201 if (!pardev || strcmp(pardev->name, KBUILD_MODNAME))
0202
0203 return;
0204
0205 device = pardev->private;
0206
0207 port->ops->disable_irq(port);
0208 pps_unregister_source(device->pps);
0209 parport_release(pardev);
0210 parport_unregister_device(pardev);
0211 ida_simple_remove(&pps_client_index, device->index);
0212 kfree(device);
0213 }
0214
0215 static struct parport_driver pps_parport_driver = {
0216 .name = KBUILD_MODNAME,
0217 .match_port = parport_attach,
0218 .detach = parport_detach,
0219 .devmodel = true,
0220 };
0221 module_parport_driver(pps_parport_driver);
0222
0223 MODULE_AUTHOR("Alexander Gordeev <lasaine@lvk.cs.msu.su>");
0224 MODULE_DESCRIPTION("parallel port PPS client");
0225 MODULE_LICENSE("GPL");