// SPDX-License-Identifier: GPL-2.0-or-later
/*
* DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
*
* Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
*
* TODO:
* - add smart card reader support for Conditional Access (CA)
*
* Card reader in Anysee is nothing more than ISO 7816 card reader.
* There is no hardware CAM in any Anysee device sold.
* In my understanding it should be implemented by making own module
* for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
* module registers serial interface that can be used to communicate
* with any ISO 7816 smart card.
*
* Any help according to implement serial smart card reader support
* is highly welcome!
*/
#include "anysee.h"
#include "dvb-pll.h"
#include "tda1002x.h"
#include "mt352.h"
#include "mt352_priv.h"
#include "zl10353.h"
#include "tda18212.h"
#include "cx24116.h"
#include "stv0900.h"
#include "stv6110.h"
#include "isl6423.h"
#include "cxd2820r.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int anysee_ctrl_msg(struct dvb_usb_device *d,
u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen)
{
struct anysee_state *state = d_to_priv(d);
int act_len, ret, i;
mutex_lock(&d->usb_mutex);
memcpy(&state->buf[0], sbuf, slen);
state->buf[60] = state->seq++;
dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, slen, state->buf);
/* We need receive one message more after dvb_usb_generic_rw due
to weird transaction flow, which is 1 x send + 2 x receive. */
ret = dvb_usbv2_generic_rw_locked(d, state->buf, sizeof(state->buf),
state->buf, sizeof(state->buf));
if (ret)
goto error_unlock;
/* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
* (EPIPE, Broken pipe). Function supports currently msleep() as a
* parameter but I would not like to use it, since according to
* Documentation/timers/timers-howto.rst it should not be used such
* short, under < 20ms, sleeps. Repeating failed message would be
* better choice as not to add unwanted delays...
* Fixing that correctly is one of those or both;
* 1) use repeat if possible
* 2) add suitable delay
*/
/* get answer, retry few times if error returned */
for (i = 0; i < 3; i++) {
/* receive 2nd answer */
ret = usb_bulk_msg(d->udev