Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}