int me8254_io_single_config(struct me_subdevice* subdevice, struct file* filep, int channel, int single_config, int ref, int trig_chain, int trig_type, int trig_edge, int flags) { me8254_subdevice_t* instance; uint8_t ctrl = ME8254_CTRL_LM | ME8254_CTRL_BIN; int err; instance = (me8254_subdevice_t *) subdevice; PDEBUG("executed.\n"); if (flags) { PERROR("Invalid flags. Should be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n"); return ME_ERRNO_INVALID_FLAGS; } if (trig_edge) { PERROR("Invalid trigger edge. Must be ME_TRIG_EDGE_NONE.\n"); return ME_ERRNO_INVALID_TRIG_EDGE; } switch (trig_type) { case ME_TRIG_TYPE_NONE: if (trig_chain != ME_TRIG_CHAN_NONE) { PERROR("Invalid trigger chain specified. Must be ME_TRIG_CHAN_NONE.\n"); return ME_ERRNO_INVALID_TRIG_CHAN; } break; case ME_TRIG_TYPE_SW: if (trig_chain != ME_TRIG_CHAN_DEFAULT) { PERROR("Invalid trigger chain specified. Must be ME_TRIG_CHAN_DEFAULT.\n"); return ME_ERRNO_INVALID_TRIG_CHAN; } break; default: PERROR("Invalid trigger type.\n"); return ME_ERRNO_INVALID_TRIG_TYPE; } switch (single_config) { case ME_SINGLE_CONFIG_CTR_8254_MODE_DISABLE: return me8254_io_reset_subdevice(subdevice, filep, flags); break; case ME_SINGLE_CONFIG_CTR_8254_MODE_INTERRUPT_ON_TERMINAL_COUNT: case ME_SINGLE_CONFIG_CTR_8254_MODE_ONE_SHOT: case ME_SINGLE_CONFIG_CTR_8254_MODE_RATE_GENERATOR: case ME_SINGLE_CONFIG_CTR_8254_MODE_SQUARE_WAVE: case ME_SINGLE_CONFIG_CTR_8254_MODE_SOFTWARE_TRIGGER: case ME_SINGLE_CONFIG_CTR_8254_MODE_HARDWARE_TRIGGER: break; default: PERROR("Invalid single configuration.\n"); return ME_ERRNO_INVALID_SINGLE_CONFIG; } if (channel) { PERROR("Invalid channel number. Must be 0.\n"); return ME_ERRNO_INVALID_CHANNEL; } ME_SUBDEVICE_ENTER; ME_SUBDEVICE_LOCK; // Configure the counter modes switch (instance->ctr_idx) { case 0: ctrl |= ME8254_CTRL_SC0; break; case 1: ctrl |= ME8254_CTRL_SC1; break; default: ctrl |= ME8254_CTRL_SC2; } switch (single_config) { case ME_SINGLE_CONFIG_CTR_8254_MODE_INTERRUPT_ON_TERMINAL_COUNT: ctrl |= ME8254_CTRL_M0; break; case ME_SINGLE_CONFIG_CTR_8254_MODE_ONE_SHOT: ctrl |= ME8254_CTRL_M1; break; case ME_SINGLE_CONFIG_CTR_8254_MODE_RATE_GENERATOR: ctrl |= ME8254_CTRL_M2; break; case ME_SINGLE_CONFIG_CTR_8254_MODE_SQUARE_WAVE: ctrl |= ME8254_CTRL_M3; break; case ME_SINGLE_CONFIG_CTR_8254_MODE_SOFTWARE_TRIGGER: ctrl |= ME8254_CTRL_M4; break; case ME_SINGLE_CONFIG_CTR_8254_MODE_HARDWARE_TRIGGER: ctrl |= ME8254_CTRL_M5; break; } me_writeb(instance->base.dev, ctrl, instance->ctrl_reg); /** @todo Instead of ID related calls features flags should be used. */ switch (instance->device_id) { case PCI_DEVICE_ID_MEILHAUS_ME1400: case PCI_DEVICE_ID_MEILHAUS_ME14E0: case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14EB: err = me1400_ab_ref_config(instance, ref); break; case PCI_DEVICE_ID_MEILHAUS_ME140C: case PCI_DEVICE_ID_MEILHAUS_ME140D: err = me1400_cd_ref_config(instance, ref); break; case PCI_DEVICE_ID_MEILHAUS_ME4610: case PCI_DEVICE_ID_MEILHAUS_ME4660: case PCI_DEVICE_ID_MEILHAUS_ME4660I: case PCI_DEVICE_ID_MEILHAUS_ME4660S: case PCI_DEVICE_ID_MEILHAUS_ME4660IS: case PCI_DEVICE_ID_MEILHAUS_ME4670: case PCI_DEVICE_ID_MEILHAUS_ME4670I: case PCI_DEVICE_ID_MEILHAUS_ME4670S: case PCI_DEVICE_ID_MEILHAUS_ME4670IS: case PCI_DEVICE_ID_MEILHAUS_ME4680: case PCI_DEVICE_ID_MEILHAUS_ME4680I: case PCI_DEVICE_ID_MEILHAUS_ME4680S: case PCI_DEVICE_ID_MEILHAUS_ME4680IS: case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: err = me_ref_config(instance, ref); break; default: PERROR_CRITICAL("Invalid device type. 8254 registred for %x.\n", instance->device_id); err = ME_ERRNO_INVALID_SINGLE_CONFIG; } ME_SUBDEVICE_UNLOCK; ME_SUBDEVICE_EXIT; return err; }
static int me8254_io_single_config(struct me_subdevice *subdevice, struct file *filep, int channel, int single_config, int ref, int trig_chan, int trig_type, int trig_edge, int flags) { me8254_subdevice_t *instance; int err; PDEBUG("executed.\n"); if (channel) { PERROR("Invalid channel.\n"); return ME_ERRNO_INVALID_CHANNEL; } instance = (me8254_subdevice_t *) subdevice; if (flags) { PERROR("Invalid flag specified.\n"); return ME_ERRNO_INVALID_FLAGS; } ME_SUBDEVICE_ENTER; spin_lock(&instance->subdevice_lock); // Configure the counter modes if (instance->ctr_idx == 0) { if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) { outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) { outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M1 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) { outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M2 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) { outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M3 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) { outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M4 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) { outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M5 | ME8254_CTRL_BIN, instance->ctrl_reg); } else { PERROR("Invalid single configuration.\n"); spin_unlock(&instance->subdevice_lock); return ME_ERRNO_INVALID_SINGLE_CONFIG; } } else if (instance->ctr_idx == 1) { if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) { outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) { outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M1 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) { outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M2 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) { outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M3 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) { outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M4 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) { outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M5 | ME8254_CTRL_BIN, instance->ctrl_reg); } else { PERROR("Invalid single configuration.\n"); spin_unlock(&instance->subdevice_lock); return ME_ERRNO_INVALID_SINGLE_CONFIG; } } else { if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) { outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) { outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M1 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) { outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M2 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) { outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M3 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) { outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M4 | ME8254_CTRL_BIN, instance->ctrl_reg); } else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) { outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M5 | ME8254_CTRL_BIN, instance->ctrl_reg); } else { PERROR("Invalid single configuration.\n"); spin_unlock(&instance->subdevice_lock); return ME_ERRNO_INVALID_SINGLE_CONFIG; } } switch (instance->device_id) { case PCI_DEVICE_ID_MEILHAUS_ME1400: case PCI_DEVICE_ID_MEILHAUS_ME14E0: case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14EB: err = me1400_ab_ref_config(instance, ref); if (err) { spin_unlock(&instance->subdevice_lock); return err; } break; case PCI_DEVICE_ID_MEILHAUS_ME140C: case PCI_DEVICE_ID_MEILHAUS_ME140D: err = me1400_cd_ref_config(instance, ref); if (err) { spin_unlock(&instance->subdevice_lock); return err; } break; case PCI_DEVICE_ID_MEILHAUS_ME4610: case PCI_DEVICE_ID_MEILHAUS_ME4660: case PCI_DEVICE_ID_MEILHAUS_ME4660I: case PCI_DEVICE_ID_MEILHAUS_ME4660S: case PCI_DEVICE_ID_MEILHAUS_ME4660IS: case PCI_DEVICE_ID_MEILHAUS_ME4670: case PCI_DEVICE_ID_MEILHAUS_ME4670I: case PCI_DEVICE_ID_MEILHAUS_ME4670S: case PCI_DEVICE_ID_MEILHAUS_ME4670IS: case PCI_DEVICE_ID_MEILHAUS_ME4680: case PCI_DEVICE_ID_MEILHAUS_ME4680I: case PCI_DEVICE_ID_MEILHAUS_ME4680S: case PCI_DEVICE_ID_MEILHAUS_ME4680IS: err = me4600_ref_config(instance, ref); if (err) { spin_unlock(&instance->subdevice_lock); return err; } break; case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: err = me8100_ref_config(instance, ref); if (err) { spin_unlock(&instance->subdevice_lock); return err; } break; default: PERROR("Invalid device type.\n"); spin_unlock(&instance->subdevice_lock); // spin_unlock(instance->clk_src_reg_lock); return ME_ERRNO_INVALID_SINGLE_CONFIG; } spin_unlock(&instance->subdevice_lock); ME_SUBDEVICE_EXIT; return ME_ERRNO_SUCCESS; }