Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}