예제 #1
0
static void hfc_upload_fsm_entry(
	struct hfc_card *card,
	struct hfc_fsm_entry *entry,
	struct hfc_fsm_entry *next_entry,
	int fsm_index)
{
	u8 subch_bits;

	hfc_debug_card(card, 3,
		"Seq #%d fifo [%d,%s] <=> chan [%d,%s] ",
		fsm_index,
		entry->fifo->hw_index,
		entry->fifo->direction == RX ? "RX" : "TX",
		entry->hfc_chan_hwindex,
		entry->fifo->direction == RX ? "RX" : "TX");

	hfc_fsm_select_entry(card, fsm_index);

	hfc_outb(card, hfc_A_CHANNEL,
		(entry->fifo->direction == RX ?
			hfc_A_CHANNEL_V_CH_FDIR_RX :
			hfc_A_CHANNEL_V_CH_FDIR_TX) |
		hfc_A_CHANNEL_V_CH_FNUM(
			entry->hfc_chan_hwindex));

	switch (entry->fifo->subchannel_bit_count) {
	case 1: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_1; break;
	case 2: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_2; break;
	case 3: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_3; break;
	case 4: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_4; break;
	case 5: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_5; break;
	case 6: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_6; break;
	case 7: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_7; break;
	case 8: subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_8; break;
	default:
		WARN_ON(1);
		subch_bits = hfc_A_SUBCH_CFG_V_BIT_CNT_8;
	}

	hfc_outb(card, hfc_A_SUBCH_CFG, subch_bits);

	if (next_entry) {
		hfc_outb(card, hfc_A_FIFO_SEQ,
			(next_entry->fifo->direction == RX ?
				hfc_A_FIFO_SEQ_V_NEXT_FIFO_DIR_RX :
				hfc_A_FIFO_SEQ_V_NEXT_FIFO_DIR_TX) |
			hfc_A_FIFO_SEQ_V_NEXT_FIFO_NUM(
				next_entry->fifo->hw_index));

		hfc_debug_cont(3, "=> fifo [%d,%s]\n",
			next_entry->fifo->hw_index,
			next_entry->fifo->direction == RX ? "RX" : "TX");

	} else {
		hfc_outb(card, hfc_A_FIFO_SEQ,
			hfc_A_FIFO_SEQ_V_SEQ_END);

		hfc_debug_cont(3, "END!\n");
	}
}
예제 #2
0
static void hfc_sys_port_upload_fsm(
	struct hfc_sys_port *port,
	struct hfc_fsm_entry *entries,
	int nentries)
{
	struct hfc_card *card = port->card;
	int i;

	// Nothing inserted, let's close the empty list :)
	if (!nentries) {
		hfc_fsm_select_entry(card, 0);

		hfc_outb(card, hfc_A_FIFO_SEQ,
			hfc_A_FIFO_SEQ_V_SEQ_END);

		return;
	}

	hfc_outb(card, hfc_R_FIRST_FIFO,
		(entries[0].fifo->direction == RX ?
			hfc_R_FIRST_FIFO_V_FIRST_FIFO_DIR_RX :
			hfc_R_FIRST_FIFO_V_FIRST_FIFO_DIR_TX) |
		hfc_R_FIRST_FIFO_V_FIRST_FIFO_NUM(entries[0].fifo->hw_index));

	for (i=0; i<nentries; i++) {

		if (i < nentries-1)
			hfc_upload_fsm_entry(card, &entries[i],
					&entries[i+1], i);
		else
			hfc_upload_fsm_entry(card, &entries[i],
					NULL, i);
	}

	hfc_pcm_port_select_slot(card,
		hfc_R_SLOT_V_SL_NUM(0) |
		hfc_R_SLOT_V_SL_DIR_TX);
	hfc_outb(card, hfc_A_SL_CFG,
		hfc_A_SL_CFG_V_CH_SDIR_TX |
		hfc_A_SL_CFG_V_CH_NUM(0) |
		hfc_A_SL_CFG_V_ROUT_OUT_STIO1);

	hfc_pcm_port_select_slot(card,
		hfc_R_SLOT_V_SL_NUM(10) |
		hfc_R_SLOT_V_SL_DIR_RX);
	hfc_outb(card, hfc_A_SL_CFG,
		hfc_A_SL_CFG_V_CH_SDIR_RX |
		hfc_A_SL_CFG_V_CH_NUM(0) |
		hfc_A_SL_CFG_V_ROUT_IN_STIO1);
}
예제 #3
0
static inline void hfc_fsm_select_entry(
	struct hfc_card *card,
	int index)
{
	mb();
	hfc_outb(card, hfc_R_FSM_IDX, index);
	hfc_wait_busy(card); // NOT DOCUMENTED BUT MANDATORY!!!!!!!
	mb();
}
예제 #4
0
static int hfc_bert_disable(
	struct hfc_st_chan *chan)
{
	struct hfc_card *card = chan->port->card;

	hfc_card_lock(card);

	if (chan->status == HFC_ST_CHAN_STATUS_OPEN_BERT) {
		chan->status = HFC_ST_CHAN_STATUS_FREE;

		hfc_st_port_select(chan->port);
		hfc_st_port_update_st_ctrl0(chan->port);
		hfc_st_port_update_st_ctrl2(chan->port);

		// RX
		hfc_fifo_select(chan->rx.fifo);
		hfc_fifo_reset(chan->rx.fifo);
		hfc_outb(card, hfc_A_CON_HDLC,
			hfc_A_CON_HDCL_V_IFF|
			hfc_A_CON_HDCL_V_HDLC_TRP_HDLC|
			hfc_A_CON_HDCL_V_TRP_IRQ_FIFO_DISABLED|
			hfc_A_CON_HDCL_V_DATA_FLOW_FIFO_from_ST);

		hfc_outb(card, hfc_A_IRQ_MSK, 0);

		// TX
		hfc_fifo_select(chan->tx.fifo);
		hfc_fifo_reset(chan->tx.fifo);
		hfc_outb(card, hfc_A_CON_HDLC,
			hfc_A_CON_HDCL_V_IFF|
			hfc_A_CON_HDCL_V_HDLC_TRP_HDLC|
			hfc_A_CON_HDCL_V_TRP_IRQ_FIFO_DISABLED|
			hfc_A_CON_HDCL_V_DATA_FLOW_FIFO_to_ST_FIFO_to_PCM);

		hfc_outb(card, hfc_A_IRQ_MSK, 0);

		hfc_msg_chan(chan, KERN_INFO, "BERT disabled\n");
	}

	hfc_card_unlock(card);

	return 0;
}
예제 #5
0
파일: fifo.c 프로젝트: GunioRobot/vstuff
void hfc_fifo_configure(
	struct hfc_fifo *fifo)
{
	struct hfc_card *card = fifo->card;
	u8 con_hdlc = 0;

	if (!fifo->enabled) {
		hfc_outb(card, hfc_A_CON_HDLC,
				hfc_A_CON_HDCL_V_HDLC_TRP_HDLC |
				hfc_A_CON_HDCL_V_TRP_IRQ_FIFO_DISABLED);
		hfc_outb(card, hfc_A_IRQ_MSK, 0);
		return;
	}

	if (fifo->framer_enabled) {
		con_hdlc |= hfc_A_CON_HDCL_V_HDLC_TRP_HDLC |
			    hfc_A_CON_HDCL_V_IFF |
			    hfc_A_CON_HDCL_V_TRP_IRQ_FIFO_ENABLED;
	} else {
		con_hdlc |= hfc_A_CON_HDCL_V_HDLC_TRP_TRP |
			    hfc_A_CON_HDCL_V_TRP_IRQ_DISABLED;
	}

	if (fifo->direction == RX) {
//		if (fifo->connect_to == HFC_FIFO_CONNECT_TO_ST)
			con_hdlc |= hfc_A_CON_HDCL_V_DATA_FLOW_FIFO_from_ST;
//			con_hdlc |= hfc_A_CON_HDCL_V_DATA_FLOW_FIFO_from_PCM;
//		else
//			con_hdlc |= hfc_A_CON_HDCL_V_DATA_FLOW_FIFO_from_ST_ST_from_PCM;
	} else {
//		if (fifo->connect_to == HFC_FIFO_CONNECT_TO_ST)
			con_hdlc |= hfc_A_CON_HDCL_V_DATA_FLOW_FIFO_to_ST_FIFO_to_PCM;
//		else
//			con_hdlc |= hfc_A_CON_HDCL_V_DATA_FLOW_ST_to_PCM;
	}

	hfc_outb(card, hfc_A_CON_HDLC, con_hdlc);
	hfc_outb(card, hfc_A_IRQ_MSK, hfc_A_IRQ_MSK_V_IRQ);
}
예제 #6
0
파일: led.c 프로젝트: nineinchnick/vstuff
void hfc_led_update(struct hfc_led *led)
{
	struct hfc_card *card = led->card;
	enum hfc_led_color color;
	u8 out_bit = 0;

	if (led->flashing_freq &&
	    (jiffies % led->flashing_freq) > (led->flashing_freq / 2) &&
	    led->flashes != 0)
		color = led->alt_color;
	else
		color = led->color;

	switch(led->id) {
	case 0:
		out_bit = hfc_R_GPIO_OUT1_V_GPIO_OUT8;
	break;
	case 1:
		out_bit = hfc_R_GPIO_OUT1_V_GPIO_OUT9;
	break;
	case 2:
		out_bit = hfc_R_GPIO_OUT1_V_GPIO_OUT10;
	break;
	case 3:
		out_bit = hfc_R_GPIO_OUT1_V_GPIO_OUT11;
	break;
	}

	if (color != HFC_LED_OFF)
		card->gpio_out &= ~out_bit;
	else
		card->gpio_out |= out_bit;

	hfc_outb(card, hfc_R_GPIO_OUT1, card->gpio_out);

	if (led->flashing_freq && led->flashes != 0) {
		led->timer.expires = jiffies + led->flashing_freq / 2;
		add_timer(&led->timer);
	}
}
예제 #7
0
static ssize_t hfc_store_sq_bits(
	struct visdn_chan *visdn_chan,
	struct visdn_chan_attribute *attr,
	const char *buf,
	size_t count)
{
	struct hfc_st_chan *chan = to_st_chan(visdn_chan);
	struct hfc_st_port *port = chan->port;
	struct hfc_card *card = port->card;

	unsigned int value;
	if (sscanf(buf, "%01x", &value) < 1)
		return -EINVAL;

	if (value > 0x0f)
		return -EINVAL;

	hfc_card_lock(card);
	hfc_st_port_select(port);
	hfc_outb(card, hfc_A_ST_SQ_WR, value);
	hfc_card_unlock(card);

	return count;
}
예제 #8
0
static int hfc_bert_enable(struct hfc_st_chan *chan)
{
	struct hfc_card *card = chan->port->card;

	int err;

	hfc_card_lock(card);

	if (chan->status != HFC_ST_CHAN_STATUS_FREE) {
		err = -EBUSY;
		goto err_busy;
	}

	struct hfc_fifo *fifo_rx;
	fifo_rx = hfc_allocate_fifo(card, RX);
	if (!fifo_rx) {
		err = -ENOMEM;
		goto err_allocate_fifo_rx;
	}

	struct hfc_fifo *fifo_tx;
	fifo_tx = hfc_allocate_fifo(card, TX);
	if (!fifo_tx) {
		err = -ENOMEM;
		goto err_allocate_fifo_tx;
	}

	chan->rx.fifo = fifo_rx;
	chan->rx.fifo->connected_chan = &chan->rx;
	chan->rx.fifo->bitrate = chan->visdn_chan.pars.bitrate;
	chan->rx.fifo->framing = VISDN_CHAN_FRAMING_TRANS;
	chan->rx.fifo->bit_reversed = FALSE;
	chan->rx.fifo->connect_to = HFC_FIFO_CONNECT_TO_ST;

	chan->tx.fifo = fifo_tx;
	chan->tx.fifo->connected_chan = &chan->tx;
	chan->tx.fifo->bitrate = chan->visdn_chan.pars.bitrate;
	chan->tx.fifo->framing = VISDN_CHAN_FRAMING_TRANS;
	chan->tx.fifo->bit_reversed = FALSE;
	chan->tx.fifo->connect_to = HFC_FIFO_CONNECT_TO_ST;

	hfc_upload_fsm(card);

	// RX
	hfc_fifo_select(chan->rx.fifo);
	hfc_fifo_configure(chan->rx.fifo);
	hfc_fifo_reset(chan->rx.fifo);

	hfc_outb(card, hfc_A_IRQ_MSK,
		hfc_A_IRQ_MSK_V_BERT_EN);

	// TX
	hfc_fifo_select(chan->tx.fifo);
	hfc_fifo_configure(chan->tx.fifo);
	hfc_fifo_reset(chan->tx.fifo);

	hfc_outb(card, hfc_A_IRQ_MSK,
		hfc_A_IRQ_MSK_V_BERT_EN);

	chan->status = HFC_ST_CHAN_STATUS_OPEN_BERT;

	// Enable the channel in the port
	hfc_st_port_select(chan->port);
	hfc_st_port_update_st_ctrl0(chan->port);
	hfc_st_port_update_st_ctrl1(chan->port);
	hfc_st_port_update_st_ctrl2(chan->port);

	hfc_card_unlock(card);

	hfc_msg_chan(chan, KERN_INFO, "BERT enabled\n");

	return 0;

	hfc_deallocate_fifo(fifo_tx);
err_allocate_fifo_tx:
	hfc_deallocate_fifo(fifo_rx);
err_allocate_fifo_rx:
err_busy:

	hfc_card_unlock(card);

	return err;
}