static int _trf7970a_tg_listen()

in trf7970a.c [1717:1790]


static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
			       nfc_digital_cmd_complete_t cb, void *arg,
			       bool mode_detect)
{
	struct trf7970a *trf = nfc_digital_get_drvdata(ddev);
	int ret;

	mutex_lock(&trf->lock);

	if ((trf->state != TRF7970A_ST_IDLE) &&
	    (trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
		dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
			trf->state);
		ret = -EIO;
		goto out_err;
	}

	if (trf->aborting) {
		dev_dbg(trf->dev, "Abort process complete\n");
		trf->aborting = false;
		ret = -ECANCELED;
		goto out_err;
	}

	trf->rx_skb = nfc_alloc_recv_skb(TRF7970A_RX_SKB_ALLOC_SIZE,
					 GFP_KERNEL);
	if (!trf->rx_skb) {
		dev_dbg(trf->dev, "Can't alloc rx_skb\n");
		ret = -ENOMEM;
		goto out_err;
	}

	ret = trf7970a_write(trf, TRF7970A_RX_SPECIAL_SETTINGS,
			     TRF7970A_RX_SPECIAL_SETTINGS_HBT |
			     TRF7970A_RX_SPECIAL_SETTINGS_M848 |
			     TRF7970A_RX_SPECIAL_SETTINGS_C424 |
			     TRF7970A_RX_SPECIAL_SETTINGS_C212);
	if (ret)
		goto out_err;

	ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
			     trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
	if (ret)
		goto out_err;

	ret = trf7970a_write(trf, TRF7970A_NFC_LOW_FIELD_LEVEL,
			     TRF7970A_NFC_LOW_FIELD_LEVEL_RFDET(0x3));
	if (ret)
		goto out_err;

	ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL,
			     TRF7970A_NFC_TARGET_LEVEL_RFDET(0x7));
	if (ret)
		goto out_err;

	trf->ddev = ddev;
	trf->cb = cb;
	trf->cb_arg = arg;
	trf->timeout = timeout;
	trf->ignore_timeout = false;

	ret = trf7970a_cmd(trf, TRF7970A_CMD_ENABLE_RX);
	if (ret)
		goto out_err;

	trf->state = mode_detect ? TRF7970A_ST_LISTENING_MD :
				   TRF7970A_ST_LISTENING;

	schedule_delayed_work(&trf->timeout_work, msecs_to_jiffies(timeout));

out_err:
	mutex_unlock(&trf->lock);
	return ret;
}