me0900_di_subdevice_t *me0900_di_constructor(uint32_t reg_base, unsigned int di_idx) { me0900_di_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me0900_di_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me0900_di_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); /* Save the subdevice index. */ subdevice->di_idx = di_idx; /* Initialize registers */ if (di_idx == 0) { subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG; subdevice->port_reg = reg_base + ME0900_PORT_A_REG; } else { subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG; subdevice->port_reg = reg_base + ME0900_PORT_B_REG; } #ifdef MEDEBUG_DEBUG_REG subdevice->reg_base = reg_base; #endif /* Overload base class methods. */ subdevice->base.me_subdevice_io_reset_subdevice = me0900_di_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me0900_di_io_single_config; subdevice->base.me_subdevice_io_single_read = me0900_di_io_single_read; subdevice->base.me_subdevice_query_number_channels = me0900_di_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me0900_di_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me0900_di_query_subdevice_caps; return subdevice; }
metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base, unsigned int sub_idx, spinlock_t * ctrl_reg_lock) { metempl_sub_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(metempl_sub_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } memset(subdevice, 0, sizeof(metempl_sub_subdevice_t)); /* Check if subdevice index is out of range */ if (sub_idx >= 2) { PERROR("Template subdevice index is out of range.\n"); kfree(subdevice); return NULL; } /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->ctrl_reg_lock = ctrl_reg_lock; /* Save the subdevice index */ subdevice->sub_idx = sub_idx; /* Override base class methods. */ subdevice->base.me_subdevice_destructor = metempl_sub_destructor; subdevice->base.me_subdevice_query_number_channels = metempl_sub_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = metempl_sub_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = metempl_sub_query_subdevice_caps; return subdevice; }
me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base) { me0600_optoi_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } /* Initialize spin locks. */ spin_lock_init(&subdevice->subdevice_lock); /* Save the subdevice index */ subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG; /* Overload base class methods. */ subdevice->base.me_subdevice_io_reset_subdevice = me0600_optoi_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me0600_optoi_io_single_config; subdevice->base.me_subdevice_io_single_read = me0600_optoi_io_single_read; subdevice->base.me_subdevice_query_number_channels = me0600_optoi_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me0600_optoi_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me0600_optoi_query_subdevice_caps; return subdevice; }
me8200_dio_subdevice_t* me8200_dio_constr(void* reg_base, unsigned int idx, me_lock_t* ctrl_reg_lock) { me8200_dio_subdevice_t *subdevice; PDEBUG("executed idx=%d.\n", idx); // Allocate memory for subdevice instance. subdevice = kzalloc(sizeof(me8200_dio_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } // Initialize subdevice base class. if (me_subdevice_init(&subdevice->base)) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. subdevice->ctrl_reg_lock = ctrl_reg_lock; /* Save digital i/o index */ subdevice->base.idx = idx; /* Save the subdevice index */ subdevice->ctrl_reg = reg_base + ME8200_DIO_CTRL_REG; subdevice->port_reg = reg_base + ME8200_DIO_PORT_REG + idx; /* Overload base class methods. */ subdevice->base.me_subdevice_io_reset_subdevice = me8200_dio_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me8200_dio_io_single_config; subdevice->base.me_subdevice_io_single_read = me8200_dio_io_single_read; subdevice->base.me_subdevice_io_single_write = me8200_dio_io_single_write; subdevice->base.me_subdevice_query_number_channels = me8200_dio_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8200_dio_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8200_dio_query_subdevice_caps; return subdevice; }
me8200_do_subdevice_t* me8200_do_constr(me_general_dev_t* device, void* reg_base, unsigned int idx, me_lock_t* irq_mode_lock) { me8200_do_subdevice_t *subdevice; PDEBUG("executed.\n"); // Allocate memory for subdevice instance. subdevice = kzalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } // Initialize subdevice base class. if (me_subdevice_init(&subdevice->base)) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. subdevice->irq_mode_lock = irq_mode_lock; // Check firmware version. me8200_do_check_version(subdevice, device, reg_base + ME8200_FIRMWARE_VERSION_REG); // Initialize the wait queue. init_waitqueue_head(&subdevice->wait_queue); // Save the index of the digital output. subdevice->base.idx = idx; // Initialize the registers. if (idx == 0) { subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG; } else if (idx == 1) { subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG; } else { PERROR("Wrong subdevice idx=%d.\n", idx); kfree(subdevice); return NULL; } subdevice->irq_mode_reg = reg_base + ME8200_IRQ_MODE_REG; subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG; // Overload base class methods. subdevice->base.me_subdevice_io_reset_subdevice = me8200_do_io_reset_subdevice; subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start; subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait; subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop; subdevice->base.me_subdevice_io_irq_test = me8200_do_io_irq_test; subdevice->base.me_subdevice_io_single_config = me8200_do_io_single_config; subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read; subdevice->base.me_subdevice_io_single_write = me8200_do_io_single_write; subdevice->base.me_subdevice_query_number_channels = me8200_do_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8200_do_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8200_do_query_subdevice_caps; subdevice->base.me_subdevice_query_version_firmware = me8200_do_query_version_firmware; subdevice->base.me_subdevice_irq_handle = me8200_do_irq_handle; subdevice->rised = -1; subdevice->count = 0; return subdevice; }
me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id, uint32_t plx_reg_base, uint32_t me1400_reg_base, spinlock_t * clk_src_reg_lock, int irq) { me1400_ext_irq_subdevice_t *subdevice; int err; uint8_t tmp; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for 1400_ext_irq instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->clk_src_reg_lock = clk_src_reg_lock; /* Initialize wait queue */ init_waitqueue_head(&subdevice->wait_queue); subdevice->irq = irq; err = request_irq(irq, me1400_ext_irq_isr, #ifdef IRQF_DISABLED IRQF_DISABLED | IRQF_SHARED, #else SA_INTERRUPT | SA_SHIRQ, #endif ME1400_NAME, (void *)subdevice); if (err) { PERROR("Can't get irq.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } PINFO("Registered irq=%d.\n", subdevice->irq); /* Initialize registers */ subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG; subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG; #ifdef MEDEBUG_DEBUG_REG subdevice->reg_base = me1400_reg_base; #endif // Enable IRQ on PLX tmp = inb(subdevice-> plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN); outb(tmp, subdevice->plx_intcs_reg); PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg, tmp); /* Initialize the subdevice methods */ subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start; subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait; subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop; subdevice->base.me_subdevice_io_reset_subdevice = me1400_ext_irq_io_reset_subdevice; subdevice->base.me_subdevice_query_number_channels = me1400_ext_irq_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me1400_ext_irq_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me1400_ext_irq_query_subdevice_caps; subdevice->base.me_subdevice_query_subdevice_caps_args = me1400_ext_irq_query_subdevice_caps_args; subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor; subdevice->rised = 0; subdevice->n = 0; return subdevice; }
me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base, unsigned int dio_idx, spinlock_t * ctrl_reg_lock) { me6000_dio_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me6000_dio_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me6000_dio_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } /* Set the subdevice ports */ subdevice->ctrl_reg = reg_base + ME6000_DIO_CTRL_REG; switch (dio_idx) { case 0: subdevice->port_reg = reg_base + ME6000_DIO_PORT_0_REG; break; case 1: subdevice->port_reg = reg_base + ME6000_DIO_PORT_1_REG; break; default: err = ME_ERRNO_INVALID_SUBDEVICE; } if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->ctrl_reg_lock = ctrl_reg_lock; /* Save digital i/o index */ subdevice->dio_idx = dio_idx; #ifdef MEDEBUG_DEBUG_REG subdevice->reg_base = reg_base; #endif /* Overload base class methods. */ subdevice->base.me_subdevice_io_reset_subdevice = me6000_dio_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me6000_dio_io_single_config; subdevice->base.me_subdevice_io_single_read = me6000_dio_io_single_read; subdevice->base.me_subdevice_io_single_write = me6000_dio_io_single_write; subdevice->base.me_subdevice_query_number_channels = me6000_dio_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me6000_dio_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me6000_dio_query_subdevice_caps; return subdevice; }
me8254_subdevice_t* me8254_constr(uint16_t device_id, void* reg_base, unsigned int me8254_idx, unsigned int ctr_idx, me_lock_t* ctrl_reg_lock, me_lock_t* clk_src_reg_lock) { me8254_subdevice_t *subdevice; PDEBUG("executed.\n"); /** @todo Checkings should be removed. We can safetly assume that data passed from upper level are correct. */ // Check if counter index is out of range if (ctr_idx > 2) { PERROR("Counter index is out of range.\n"); return NULL; } // Check device specific values. switch (device_id) { case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: 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_ME4560: case PCI_DEVICE_ID_MEILHAUS_ME4560I: case PCI_DEVICE_ID_MEILHAUS_ME4560S: case PCI_DEVICE_ID_MEILHAUS_ME4560IS: case PCI_DEVICE_ID_MEILHAUS_ME4570: case PCI_DEVICE_ID_MEILHAUS_ME4570I: case PCI_DEVICE_ID_MEILHAUS_ME4570S: case PCI_DEVICE_ID_MEILHAUS_ME4570IS: case PCI_DEVICE_ID_MEILHAUS_ME4760: case PCI_DEVICE_ID_MEILHAUS_ME4760I: case PCI_DEVICE_ID_MEILHAUS_ME4760S: case PCI_DEVICE_ID_MEILHAUS_ME4760IS: case PCI_DEVICE_ID_MEILHAUS_ME4770: case PCI_DEVICE_ID_MEILHAUS_ME4770I: case PCI_DEVICE_ID_MEILHAUS_ME4770S: case PCI_DEVICE_ID_MEILHAUS_ME4770IS: case PCI_DEVICE_ID_MEILHAUS_ME4780: case PCI_DEVICE_ID_MEILHAUS_ME4780I: case PCI_DEVICE_ID_MEILHAUS_ME4780S: case PCI_DEVICE_ID_MEILHAUS_ME4780IS: case PCI_DEVICE_ID_MEILHAUS_ME4860: case PCI_DEVICE_ID_MEILHAUS_ME4860I: case PCI_DEVICE_ID_MEILHAUS_ME4860S: case PCI_DEVICE_ID_MEILHAUS_ME4860IS: case PCI_DEVICE_ID_MEILHAUS_ME4870: case PCI_DEVICE_ID_MEILHAUS_ME4870I: case PCI_DEVICE_ID_MEILHAUS_ME4870S: case PCI_DEVICE_ID_MEILHAUS_ME4870IS: case PCI_DEVICE_ID_MEILHAUS_ME4880: case PCI_DEVICE_ID_MEILHAUS_ME4880I: case PCI_DEVICE_ID_MEILHAUS_ME4880S: case PCI_DEVICE_ID_MEILHAUS_ME4880IS: case PCI_DEVICE_ID_MEILHAUS_ME0752: case PCI_DEVICE_ID_MEILHAUS_ME0754: case PCI_DEVICE_ID_MEILHAUS_ME0762: case PCI_DEVICE_ID_MEILHAUS_ME0764: case PCI_DEVICE_ID_MEILHAUS_ME0772: case PCI_DEVICE_ID_MEILHAUS_ME0774: case PCI_DEVICE_ID_MEILHAUS_ME0782: case PCI_DEVICE_ID_MEILHAUS_ME0784: case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: if (me8254_idx > 0) { PERROR("8254 index is out of range. Must be 0.\n"); return NULL; } break; case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14EB: if (me8254_idx > 1) { PERROR("8254 index is out of range. Must be 0 or 1.\n"); return NULL; } break; case PCI_DEVICE_ID_MEILHAUS_ME140C: if (me8254_idx > 4) { PERROR("8254 index is out of range. Must be between 0 and 3.\n"); return NULL; } case PCI_DEVICE_ID_MEILHAUS_ME140D: if (me8254_idx > 9) { PERROR("8254 index is out of range. Must be between 0 and 8.\n"); return NULL; } break; default: PERROR_CRITICAL("8254 registred for %x!\n", device_id); return NULL; } // Allocate memory for subdevice instance subdevice = kzalloc(sizeof(me8254_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for 8254 instance.\n"); return NULL; } // Initialize subdevice base class if (me_subdevice_init(&subdevice->base)) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. subdevice->ctrl_reg_lock = ctrl_reg_lock; subdevice->clk_src_reg_lock = clk_src_reg_lock; // Save type of Meilhaus device subdevice->device_id = device_id; // Save the subdevice indexes. subdevice->me8254_idx = me8254_idx; subdevice->ctr_idx = ctr_idx; subdevice->base.idx = ctr_idx + (me8254_idx * 3); /** @todo Setting flags for particular implementations create portibility problem. Flags should be passed from upper level. Also registers should be some how provided by upper level call. */ // Do device specific initialization switch (device_id) { case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: case PCI_DEVICE_ID_MEILHAUS_ME140B: case PCI_DEVICE_ID_MEILHAUS_ME14EB: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; if (ctr_idx == 0) subdevice->caps |= ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ; else subdevice->caps |= ME_CAPS_CTR_CLK_PREVIOUS; // Get the counters registers subdevice->val_reg = me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); break; case PCI_DEVICE_ID_MEILHAUS_ME140C: case PCI_DEVICE_ID_MEILHAUS_ME140D: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL | ME_CAPS_CTR_CLK_PREVIOUS; if (ctr_idx == 0) { subdevice->caps |= ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ; if ((me8254_idx == 0) || (me8254_idx == 5)) {// No cascading for first counter on first chips. subdevice->caps &= ~ME_CAPS_CTR_CLK_PREVIOUS; } } // Get the counters registers subdevice->val_reg = me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); 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_ME4560: case PCI_DEVICE_ID_MEILHAUS_ME4560I: case PCI_DEVICE_ID_MEILHAUS_ME4560S: case PCI_DEVICE_ID_MEILHAUS_ME4560IS: case PCI_DEVICE_ID_MEILHAUS_ME4570: case PCI_DEVICE_ID_MEILHAUS_ME4570I: case PCI_DEVICE_ID_MEILHAUS_ME4570S: case PCI_DEVICE_ID_MEILHAUS_ME4570IS: case PCI_DEVICE_ID_MEILHAUS_ME4760: case PCI_DEVICE_ID_MEILHAUS_ME4760I: case PCI_DEVICE_ID_MEILHAUS_ME4760S: case PCI_DEVICE_ID_MEILHAUS_ME4760IS: case PCI_DEVICE_ID_MEILHAUS_ME4770: case PCI_DEVICE_ID_MEILHAUS_ME4770I: case PCI_DEVICE_ID_MEILHAUS_ME4770S: case PCI_DEVICE_ID_MEILHAUS_ME4770IS: case PCI_DEVICE_ID_MEILHAUS_ME4780: case PCI_DEVICE_ID_MEILHAUS_ME4780I: case PCI_DEVICE_ID_MEILHAUS_ME4780S: case PCI_DEVICE_ID_MEILHAUS_ME4780IS: case PCI_DEVICE_ID_MEILHAUS_ME4860: case PCI_DEVICE_ID_MEILHAUS_ME4860I: case PCI_DEVICE_ID_MEILHAUS_ME4860S: case PCI_DEVICE_ID_MEILHAUS_ME4860IS: case PCI_DEVICE_ID_MEILHAUS_ME4870: case PCI_DEVICE_ID_MEILHAUS_ME4870I: case PCI_DEVICE_ID_MEILHAUS_ME4870S: case PCI_DEVICE_ID_MEILHAUS_ME4870IS: case PCI_DEVICE_ID_MEILHAUS_ME4880: case PCI_DEVICE_ID_MEILHAUS_ME4880I: case PCI_DEVICE_ID_MEILHAUS_ME4880S: case PCI_DEVICE_ID_MEILHAUS_ME4880IS: case PCI_DEVICE_ID_MEILHAUS_ME0752: case PCI_DEVICE_ID_MEILHAUS_ME0754: case PCI_DEVICE_ID_MEILHAUS_ME0762: case PCI_DEVICE_ID_MEILHAUS_ME0764: case PCI_DEVICE_ID_MEILHAUS_ME0772: case PCI_DEVICE_ID_MEILHAUS_ME0774: case PCI_DEVICE_ID_MEILHAUS_ME0782: case PCI_DEVICE_ID_MEILHAUS_ME0784: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me4600_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = 0; // Not used break; case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me8100_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = 0; // Not used break; default: PERROR("Unknown device type.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Overload subdevice base class methods. subdevice->base.me_subdevice_io_reset_subdevice = me8254_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me8254_io_single_config; subdevice->base.me_subdevice_io_single_read = me8254_io_single_read; subdevice->base.me_subdevice_io_single_write = me8254_io_single_write; subdevice->base.me_subdevice_query_number_channels = me8254_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8254_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8254_query_subdevice_caps; subdevice->base.me_subdevice_query_subdevice_caps_args = me8254_query_subdevice_caps_args; return subdevice; }
me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase, unsigned int di_idx, int irq, spinlock_t * irq_ctrl_lock, spinlock_t * irq_mode_lock) { me8200_di_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me8200_di_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me8200_di_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Check firmware version. me8200_di_check_version(subdevice, me8200_regbase + ME8200_FIRMWARE_VERSION_REG); // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->irq_ctrl_lock = irq_ctrl_lock; subdevice->irq_mode_lock = irq_mode_lock; /* Save the subdevice index. */ subdevice->di_idx = di_idx; /* Initialize registers */ if (di_idx == 0) { subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_0_REG; subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_0_REG; subdevice->compare_reg = me8200_regbase + ME8200_DI_COMPARE_0_REG; subdevice->irq_status_reg = me8200_regbase + ME8200_DI_CHANGE_0_REG; subdevice->irq_status_low_reg = me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_LOW_REG; subdevice->irq_status_high_reg = me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_HIGH_REG; } else if (di_idx == 1) { subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_1_REG; subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_1_REG; subdevice->compare_reg = me8200_regbase + ME8200_DI_COMPARE_1_REG; subdevice->irq_status_reg = me8200_regbase + ME8200_DI_CHANGE_1_REG; subdevice->irq_status_low_reg = me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_LOW_REG; subdevice->irq_status_high_reg = me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_HIGH_REG; } else { PERROR("Wrong subdevice idx=%d.\n", di_idx); kfree(subdevice); return NULL; } subdevice->irq_ctrl_reg = me8200_regbase + ME8200_DI_IRQ_CTRL_REG; subdevice->irq_mode_reg = me8200_regbase + ME8200_IRQ_MODE_REG; #ifdef MEDEBUG_DEBUG_REG subdevice->reg_base = me8200_regbase; #endif /* Initialize wait queue */ init_waitqueue_head(&subdevice->wait_queue); /* Overload base class methods. */ subdevice->base.me_subdevice_io_irq_start = me8200_di_io_irq_start; subdevice->base.me_subdevice_io_irq_wait = me8200_di_io_irq_wait; subdevice->base.me_subdevice_io_irq_stop = me8200_di_io_irq_stop; subdevice->base.me_subdevice_io_reset_subdevice = me8200_di_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me8200_di_io_single_config; subdevice->base.me_subdevice_io_single_read = me8200_di_io_single_read; subdevice->base.me_subdevice_query_number_channels = me8200_di_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8200_di_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8200_di_query_subdevice_caps; subdevice->base.me_subdevice_destructor = me8200_di_destructor; subdevice->rised = 0; subdevice->count = 0; /* Register interrupt service routine. */ subdevice->irq = irq; if (subdevice->version > 0) { // NEW err = request_irq(subdevice->irq, me8200_isr_EX, #ifdef IRQF_DISABLED IRQF_DISABLED | IRQF_SHARED, #else SA_INTERRUPT | SA_SHIRQ, #endif ME8200_NAME, (void *)subdevice); } else { //OLD err = request_irq(subdevice->irq, me8200_isr, #ifdef IRQF_DISABLED IRQF_DISABLED | IRQF_SHARED, #else SA_INTERRUPT | SA_SHIRQ, #endif ME8200_NAME, (void *)subdevice); } if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } PDEBUG("Registred irq=%d.\n", subdevice->irq); return subdevice; }
me8254_subdevice_t *me8254_constructor(uint32_t device_id, uint32_t reg_base, unsigned int me8254_idx, unsigned int ctr_idx, spinlock_t * ctrl_reg_lock, spinlock_t * clk_src_reg_lock) { me8254_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); // Allocate memory for subdevice instance subdevice = kmalloc(sizeof(me8254_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for 8254 instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me8254_subdevice_t)); // Check if counter index is out of range if (ctr_idx > 2) { PERROR("Counter index is out of range.\n"); kfree(subdevice); return NULL; } // Initialize subdevice base class err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->ctrl_reg_lock = ctrl_reg_lock; subdevice->clk_src_reg_lock = clk_src_reg_lock; // Save type of Meilhaus device subdevice->device_id = device_id; // Save the indices subdevice->me8254_idx = me8254_idx; subdevice->ctr_idx = ctr_idx; // Do device specific initialization switch (device_id) { case PCI_DEVICE_ID_MEILHAUS_ME140A: case PCI_DEVICE_ID_MEILHAUS_ME14EA: // Check if 8254 index is out of range if (me8254_idx > 0) { PERROR("8254 index is out of range.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } case PCI_DEVICE_ID_MEILHAUS_ME140B: // Fall through case PCI_DEVICE_ID_MEILHAUS_ME14EB: // Check if 8254 index is out of range if (me8254_idx > 1) { PERROR("8254 index is out of range.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Initialize the counters capabilities if (ctr_idx == 0) subdevice->caps = ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ | ME_CAPS_CTR_CLK_EXTERNAL; else subdevice->caps = ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); break; case PCI_DEVICE_ID_MEILHAUS_ME140C: // Check if 8254 index is out of range if (me8254_idx > 4) { PERROR("8254 index is out of range.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } case PCI_DEVICE_ID_MEILHAUS_ME140D: // Check if 8254 index is out of range if (me8254_idx > 9) { PERROR("8254 index is out of range.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Initialize the counters capabilities if (ctr_idx == 0) { if (me8254_idx == 0) subdevice->caps = ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ | ME_CAPS_CTR_CLK_EXTERNAL; else subdevice->caps = ME_CAPS_CTR_CLK_INTERNAL_1MHZ | ME_CAPS_CTR_CLK_INTERNAL_10MHZ | ME_CAPS_CTR_CLK_EXTERNAL; } else subdevice->caps = ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx); 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: // Check if 8254 index is out of range if (me8254_idx > 0) { PERROR("8254 index is out of range.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me4600_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = 0; // Not used break; case PCI_DEVICE_ID_MEILHAUS_ME8100_A: case PCI_DEVICE_ID_MEILHAUS_ME8100_B: // Check if 8254 index is out of range if (me8254_idx > 0) { PERROR("8254 index is out of range.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Initialize the counters capabilities subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL; // Get the counters registers subdevice->val_reg = me8100_get_val_reg(reg_base, me8254_idx, ctr_idx); subdevice->ctrl_reg = me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx); subdevice->clk_src_reg = 0; // Not used break; case PCI_DEVICE_ID_MEILHAUS_ME4650: case PCI_DEVICE_ID_MEILHAUS_ME1400: case PCI_DEVICE_ID_MEILHAUS_ME14E0: PERROR("No 8254 subdevices available for subdevice device.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; default: PERROR("Unknown device type.\n"); me_subdevice_deinit(&subdevice->base); kfree(subdevice); return NULL; } // Overload subdevice base class methods. subdevice->base.me_subdevice_io_reset_subdevice = me8254_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me8254_io_single_config; subdevice->base.me_subdevice_io_single_read = me8254_io_single_read; subdevice->base.me_subdevice_io_single_write = me8254_io_single_write; subdevice->base.me_subdevice_query_number_channels = me8254_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8254_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8254_query_subdevice_caps; subdevice->base.me_subdevice_query_subdevice_caps_args = me8254_query_subdevice_caps_args; return subdevice; }
me4700_fi_subdevice_t* me4700_fi_constr(void* reg_base, unsigned int idx, me_lock_t* ctrl_reg_lock) { me4700_fi_subdevice_t* subdevice; uint32_t tmp; PDEBUG("executed idx=%d.\n", idx); // Allocate memory for subdevice instance. subdevice = kzalloc(sizeof(me4700_fi_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } // Initialize subdevice base class. if (me_subdevice_init(&subdevice->base)) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. subdevice->ctrl_reg_lock = ctrl_reg_lock; // Save digital i/o index. subdevice->base.idx = idx; // Initialize wait queue init_waitqueue_head(&subdevice->wait_queue); // Set the subdevice ports' registers. switch (idx) { case 0: subdevice->low_level_reg = reg_base + ME4700_FIO_PORT_A_LOW_REG; subdevice->high_level_reg = reg_base + ME4700_FIO_PORT_A_HIGH_REG; break; case 1: subdevice->low_level_reg = reg_base + ME4700_FIO_PORT_B_LOW_REG; subdevice->high_level_reg = reg_base + ME4700_FIO_PORT_B_HIGH_REG; break; case 2: subdevice->low_level_reg = reg_base + ME4700_FIO_PORT_C_LOW_REG; subdevice->high_level_reg = reg_base + ME4700_FIO_PORT_C_HIGH_REG; break; case 3: subdevice->low_level_reg = reg_base + ME4700_FIO_PORT_D_LOW_REG; subdevice->high_level_reg = reg_base + ME4700_FIO_PORT_D_HIGH_REG; break; } subdevice->status_reg = reg_base + ME4700_FI_STATUS; subdevice->ctrl_reg = reg_base + ME4700_FI_START_STOP_REG; // Override base class methods. subdevice->base.me_subdevice_io_single_config = me4700_fi_io_single_config; subdevice->base.me_subdevice_query_number_channels = me4700_fi_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me4700_fi_query_subdevice_type; subdevice->base.me_subdevice_io_reset_subdevice = me4700_fi_io_reset_subdevice; subdevice->base.me_subdevice_io_single_read = me4700_fi_io_single_read; subdevice->base.me_subdevice_query_timer = me4700_fi_query_timer; subdevice->base.me_subdevice_irq_handle = me4700_fi_irq_handle; // Set FIO feature active. ME_SPIN_LOCK(subdevice->ctrl_reg_lock); me_readl(subdevice->base.dev, &tmp, reg_base + ME4700_FIO_CTRL_REG); tmp &= ~(ME4700_FIO_CTRL_BIT_MODE_MASK << ME4700_FI_CTRL_BIT_SHIFT); tmp |= ME4700_FIO_CTRL_BIT_FRQUENCY_MODE << ME4700_FI_CTRL_BIT_SHIFT; me_writel(subdevice->base.dev, tmp, reg_base + ME4700_FIO_CTRL_REG); ME_SPIN_UNLOCK(subdevice->ctrl_reg_lock); return subdevice; }
me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base, unsigned int do_idx, int irq, spinlock_t * irq_mode_lock) { me8200_do_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for subdevice instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me8200_do_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->irq_mode_lock = irq_mode_lock; /* Save the index of the digital output */ subdevice->do_idx = do_idx; subdevice->irq = irq; /* Initialize the registers */ if (do_idx == 0) { subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG; } else if (do_idx == 1) { subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG; } else { PERROR("Wrong subdevice idx=%d.\n", do_idx); kfree(subdevice); return NULL; } subdevice->irq_ctrl_reg = reg_base + ME8200_IRQ_MODE_REG; subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG; #ifdef MEDEBUG_DEBUG_REG subdevice->reg_base = reg_base; #endif /* Initialize the wait queue */ init_waitqueue_head(&subdevice->wait_queue); /* Request the interrupt line */ err = request_irq(irq, me8200_do_isr, #ifdef IRQF_DISABLED IRQF_DISABLED | IRQF_SHARED, #else SA_INTERRUPT | SA_SHIRQ, #endif ME8200_NAME, (void *)subdevice); if (err) { PERROR("Cannot get interrupt line.\n"); kfree(subdevice); return NULL; } PINFO("Registered irq=%d.\n", irq); /* Overload base class methods. */ subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start; subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait; subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop; subdevice->base.me_subdevice_io_reset_subdevice = me8200_do_io_reset_subdevice; subdevice->base.me_subdevice_io_single_config = me8200_do_io_single_config; subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read; subdevice->base.me_subdevice_io_single_write = me8200_do_io_single_write; subdevice->base.me_subdevice_query_number_channels = me8200_do_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me8200_do_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me8200_do_query_subdevice_caps; subdevice->base.me_subdevice_destructor = me8200_do_destructor; subdevice->rised = 0; subdevice->count = 0; return subdevice; }
me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base, uint32_t me0600_reg_base, spinlock_t *intcsr_lock, unsigned ext_irq_idx, int irq) { me0600_ext_irq_subdevice_t *subdevice; int err; PDEBUG("executed.\n"); /* Allocate memory for subdevice instance */ subdevice = kmalloc(sizeof(me0600_ext_irq_subdevice_t), GFP_KERNEL); if (!subdevice) { PERROR("Cannot get memory for 630_ext_irq instance.\n"); return NULL; } memset(subdevice, 0, sizeof(me0600_ext_irq_subdevice_t)); /* Initialize subdevice base class */ err = me_subdevice_init(&subdevice->base); if (err) { PERROR("Cannot initialize subdevice base class instance.\n"); kfree(subdevice); return NULL; } // Initialize spin locks. spin_lock_init(&subdevice->subdevice_lock); subdevice->intcsr_lock = intcsr_lock; /* Initialize wait queue */ init_waitqueue_head(&subdevice->wait_queue); subdevice->lintno = ext_irq_idx; /* Request interrupt line */ subdevice->irq = irq; err = request_irq(subdevice->irq, me0600_isr, IRQF_DISABLED | IRQF_SHARED, ME0600_NAME, (void *)subdevice); if (err) { PERROR("Cannot get interrupt line.\n"); kfree(subdevice); return NULL; } PINFO("Registered irq=%d.\n", subdevice->irq); /* Initialize registers */ subdevice->intcsr = plx_reg_base + PLX_INTCSR; subdevice->reset_reg = me0600_reg_base + ME0600_INT_0_RESET_REG + ext_irq_idx; /* Initialize the subdevice methods */ subdevice->base.me_subdevice_io_irq_start = me0600_ext_irq_io_irq_start; subdevice->base.me_subdevice_io_irq_wait = me0600_ext_irq_io_irq_wait; subdevice->base.me_subdevice_io_irq_stop = me0600_ext_irq_io_irq_stop; subdevice->base.me_subdevice_io_reset_subdevice = me0600_ext_irq_io_reset_subdevice; subdevice->base.me_subdevice_query_number_channels = me0600_ext_irq_query_number_channels; subdevice->base.me_subdevice_query_subdevice_type = me0600_ext_irq_query_subdevice_type; subdevice->base.me_subdevice_query_subdevice_caps = me0600_ext_irq_query_subdevice_caps; subdevice->base.me_subdevice_destructor = me0600_ext_irq_destructor; subdevice->rised = 0; subdevice->n = 0; return subdevice; }