firedtv-avc.c 39.2 KB
Newer Older
S
Stefan Richter 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
/*
 * FireDTV driver (formerly known as FireSAT)
 *
 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
 * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License as
 *	published by the Free Software Foundation; either version 2 of
 *	the License, or (at your option) any later version.
 */

#include <linux/bug.h>
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/stringify.h>
#include <linux/wait.h>
#include <linux/workqueue.h>

#include "firedtv.h"

#define FCP_COMMAND_REGISTER		0xfffff0000b00ULL

#define AVC_CTYPE_CONTROL		0x0
#define AVC_CTYPE_STATUS		0x1
#define AVC_CTYPE_NOTIFY		0x3

#define AVC_RESPONSE_ACCEPTED		0x9
#define AVC_RESPONSE_STABLE		0xc
#define AVC_RESPONSE_CHANGED		0xd
#define AVC_RESPONSE_INTERIM		0xf

#define AVC_SUBUNIT_TYPE_TUNER		(0x05 << 3)
#define AVC_SUBUNIT_TYPE_UNIT		(0x1f << 3)

#define AVC_OPCODE_VENDOR		0x00
#define AVC_OPCODE_READ_DESCRIPTOR	0x09
#define AVC_OPCODE_DSIT			0xc8
#define AVC_OPCODE_DSD			0xcb

#define DESCRIPTOR_TUNER_STATUS 	0x80
#define DESCRIPTOR_SUBUNIT_IDENTIFIER	0x00

#define SFE_VENDOR_DE_COMPANYID_0	0x00 /* OUI of Digital Everywhere */
#define SFE_VENDOR_DE_COMPANYID_1	0x12
#define SFE_VENDOR_DE_COMPANYID_2	0x87

#define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
#define SFE_VENDOR_OPCODE_LNB_CONTROL		0x52
#define SFE_VENDOR_OPCODE_TUNE_QPSK		0x58 /* for DVB-S */

#define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION	0x00
#define SFE_VENDOR_OPCODE_HOST2CA		0x56
#define SFE_VENDOR_OPCODE_CA2HOST		0x57
#define SFE_VENDOR_OPCODE_CISTATUS		0x59
#define SFE_VENDOR_OPCODE_TUNE_QPSK2		0x60 /* for DVB-S2 */

#define SFE_VENDOR_TAG_CA_RESET			0x00
#define SFE_VENDOR_TAG_CA_APPLICATION_INFO	0x01
#define SFE_VENDOR_TAG_CA_PMT			0x02
#define SFE_VENDOR_TAG_CA_DATE_TIME		0x04
#define SFE_VENDOR_TAG_CA_MMI			0x05
#define SFE_VENDOR_TAG_CA_ENTER_MENU		0x07

#define EN50221_LIST_MANAGEMENT_ONLY	0x03
#define EN50221_TAG_APP_INFO		0x9f8021
#define EN50221_TAG_CA_INFO		0x9f8031

struct avc_command_frame {
	u8 ctype;
	u8 subunit;
	u8 opcode;
	u8 operand[509];
};

struct avc_response_frame {
	u8 response;
	u8 subunit;
	u8 opcode;
	u8 operand[509];
};

90 91 92 93 94 95 96 97 98 99 100
#define AVC_DEBUG_READ_DESCRIPTOR              0x0001
#define AVC_DEBUG_DSIT                         0x0002
#define AVC_DEBUG_DSD                          0x0004
#define AVC_DEBUG_REGISTER_REMOTE_CONTROL      0x0008
#define AVC_DEBUG_LNB_CONTROL                  0x0010
#define AVC_DEBUG_TUNE_QPSK                    0x0020
#define AVC_DEBUG_TUNE_QPSK2                   0x0040
#define AVC_DEBUG_HOST2CA                      0x0080
#define AVC_DEBUG_CA2HOST                      0x0100
#define AVC_DEBUG_APPLICATION_PMT              0x4000
#define AVC_DEBUG_FCP_PAYLOADS                 0x8000
S
Stefan Richter 已提交
101 102 103

static int avc_debug;
module_param_named(debug, avc_debug, int, 0644);
104 105 106 107 108 109 110 111 112 113 114 115 116
MODULE_PARM_DESC(debug, "Verbose logging (none = 0"
	", FCP subactions"
	": READ DESCRIPTOR = "		__stringify(AVC_DEBUG_READ_DESCRIPTOR)
	", DSIT = "			__stringify(AVC_DEBUG_DSIT)
	", REGISTER_REMOTE_CONTROL = "	__stringify(AVC_DEBUG_REGISTER_REMOTE_CONTROL)
	", LNB CONTROL = "		__stringify(AVC_DEBUG_LNB_CONTROL)
	", TUNE QPSK = "		__stringify(AVC_DEBUG_TUNE_QPSK)
	", TUNE QPSK2 = "		__stringify(AVC_DEBUG_TUNE_QPSK2)
	", HOST2CA = "			__stringify(AVC_DEBUG_HOST2CA)
	", CA2HOST = "			__stringify(AVC_DEBUG_CA2HOST)
	"; Application sent PMT = "	__stringify(AVC_DEBUG_APPLICATION_PMT)
	", FCP payloads = "		__stringify(AVC_DEBUG_FCP_PAYLOADS)
	", or a combination, or all = -1)");
S
Stefan Richter 已提交
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

static const char *debug_fcp_ctype(unsigned int ctype)
{
	static const char *ctypes[] = {
		[0x0] = "CONTROL",		[0x1] = "STATUS",
		[0x2] = "SPECIFIC INQUIRY",	[0x3] = "NOTIFY",
		[0x4] = "GENERAL INQUIRY",	[0x8] = "NOT IMPLEMENTED",
		[0x9] = "ACCEPTED",		[0xa] = "REJECTED",
		[0xb] = "IN TRANSITION",	[0xc] = "IMPLEMENTED/STABLE",
		[0xd] = "CHANGED",		[0xf] = "INTERIM",
	};
	const char *ret = ctype < ARRAY_SIZE(ctypes) ? ctypes[ctype] : NULL;

	return ret ? ret : "?";
}

static const char *debug_fcp_opcode(unsigned int opcode,
134
				    const u8 *data, int length)
S
Stefan Richter 已提交
135 136
{
	switch (opcode) {
137 138 139 140 141 142 143 144 145 146 147 148
	case AVC_OPCODE_VENDOR:
		break;
	case AVC_OPCODE_READ_DESCRIPTOR:
		return avc_debug & AVC_DEBUG_READ_DESCRIPTOR ?
				"ReadDescriptor" : NULL;
	case AVC_OPCODE_DSIT:
		return avc_debug & AVC_DEBUG_DSIT ?
				"DirectSelectInfo.Type" : NULL;
	case AVC_OPCODE_DSD:
		return avc_debug & AVC_DEBUG_DSD ? "DirectSelectData" : NULL;
	default:
		return "Unknown";
S
Stefan Richter 已提交
149 150 151 152 153 154
	}

	if (length < 7 ||
	    data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
	    data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
	    data[5] != SFE_VENDOR_DE_COMPANYID_2)
155
		return "Vendor/Unknown";
S
Stefan Richter 已提交
156 157

	switch (data[6]) {
158 159 160 161 162 163 164 165 166 167 168 169 170
	case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:
		return avc_debug & AVC_DEBUG_REGISTER_REMOTE_CONTROL ?
				"RegisterRC" : NULL;
	case SFE_VENDOR_OPCODE_LNB_CONTROL:
		return avc_debug & AVC_DEBUG_LNB_CONTROL ? "LNBControl" : NULL;
	case SFE_VENDOR_OPCODE_TUNE_QPSK:
		return avc_debug & AVC_DEBUG_TUNE_QPSK ? "TuneQPSK" : NULL;
	case SFE_VENDOR_OPCODE_TUNE_QPSK2:
		return avc_debug & AVC_DEBUG_TUNE_QPSK2 ? "TuneQPSK2" : NULL;
	case SFE_VENDOR_OPCODE_HOST2CA:
		return avc_debug & AVC_DEBUG_HOST2CA ? "Host2CA" : NULL;
	case SFE_VENDOR_OPCODE_CA2HOST:
		return avc_debug & AVC_DEBUG_CA2HOST ? "CA2Host" : NULL;
S
Stefan Richter 已提交
171
	}
172
	return "Vendor/Unknown";
173 174
}

175
static void debug_fcp(const u8 *data, int length)
S
Stefan Richter 已提交
176
{
177 178
	unsigned int subunit_type, subunit_id, opcode;
	const char *op, *prefix;
S
Stefan Richter 已提交
179

180
	prefix       = data[0] > 7 ? "FCP <- " : "FCP -> ";
181
	subunit_type = data[1] >> 3;
182 183 184 185 186
	subunit_id   = data[1] & 7;
	opcode       = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
	op           = debug_fcp_opcode(opcode, data, length);

	if (op) {
187
		printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
S
Stefan Richter 已提交
188
		       prefix, subunit_type, subunit_id, length,
189
		       debug_fcp_ctype(data[0]), op);
190 191 192
		if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
			print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE,
				       16, 1, data, length, false);
S
Stefan Richter 已提交
193
	}
194
}
S
Stefan Richter 已提交
195

196 197 198 199 200
static void debug_pmt(char *msg, int length)
{
	printk(KERN_INFO "APP PMT -> l=%d\n", length);
	print_hex_dump(KERN_INFO, "APP PMT -> ", DUMP_PREFIX_NONE,
		       16, 1, msg, length, false);
S
Stefan Richter 已提交
201 202
}

203
static int avc_write(struct firedtv *fdtv)
S
Stefan Richter 已提交
204 205 206
{
	int err, retry;

207
	fdtv->avc_reply_received = false;
S
Stefan Richter 已提交
208 209 210

	for (retry = 0; retry < 6; retry++) {
		if (unlikely(avc_debug))
211
			debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
S
Stefan Richter 已提交
212 213

		err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER,
214
				fdtv->avc_data, fdtv->avc_data_length);
S
Stefan Richter 已提交
215 216
		if (err) {
			dev_err(fdtv->device, "FCP command write failed\n");
217

S
Stefan Richter 已提交
218 219 220 221 222 223 224 225 226
			return err;
		}

		/*
		 * AV/C specs say that answers should be sent within 150 ms.
		 * Time out after 200 ms.
		 */
		if (wait_event_timeout(fdtv->avc_wait,
				       fdtv->avc_reply_received,
227
				       msecs_to_jiffies(200)) != 0)
S
Stefan Richter 已提交
228 229 230
			return 0;
	}
	dev_err(fdtv->device, "FCP response timed out\n");
231

S
Stefan Richter 已提交
232 233 234
	return -ETIMEDOUT;
}

235
static bool is_register_rc(struct avc_response_frame *r)
S
Stefan Richter 已提交
236
{
237 238 239 240 241
	return r->opcode     == AVC_OPCODE_VENDOR &&
	       r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
	       r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
	       r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
	       r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
S
Stefan Richter 已提交
242 243 244 245
}

int avc_recv(struct firedtv *fdtv, void *data, size_t length)
{
246
	struct avc_response_frame *r = data;
S
Stefan Richter 已提交
247 248 249 250

	if (unlikely(avc_debug))
		debug_fcp(data, length);

251 252 253 254
	if (length >= 8 && is_register_rc(r)) {
		switch (r->response) {
		case AVC_RESPONSE_CHANGED:
			fdtv_handle_rc(fdtv, r->operand[4] << 8 | r->operand[5]);
S
Stefan Richter 已提交
255
			schedule_work(&fdtv->remote_ctrl_work);
256 257 258 259 260 261
			break;
		case AVC_RESPONSE_INTERIM:
			if (is_register_rc((void *)fdtv->avc_data))
				goto wake;
			break;
		default:
S
Stefan Richter 已提交
262 263 264 265 266 267 268 269 270 271 272
			dev_info(fdtv->device,
				 "remote control result = %d\n", r->response);
		}
		return 0;
	}

	if (fdtv->avc_reply_received) {
		dev_err(fdtv->device, "out-of-order AVC response, ignored\n");
		return -EIO;
	}

273 274 275
	memcpy(fdtv->avc_data, data, length);
	fdtv->avc_data_length = length;
wake:
S
Stefan Richter 已提交
276 277 278 279 280 281
	fdtv->avc_reply_received = true;
	wake_up(&fdtv->avc_wait);

	return 0;
}

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
{
	int i, n, pos = 1;

	for (i = 0, n = 0; i < 16; i++) {
		if (test_bit(i, &fdtv->channel_active)) {
			operand[pos++] = 0x13; /* flowfunction relay */
			operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
			operand[pos++] = (fdtv->channel_pid[i] >> 8) & 0x1f;
			operand[pos++] = fdtv->channel_pid[i] & 0xff;
			operand[pos++] = 0x00; /* tableID */
			operand[pos++] = 0x00; /* filter_length */
			n++;
		}
	}
	operand[0] = n;

	return pos;
}

S
Stefan Richter 已提交
302 303 304 305 306
/*
 * tuning command for setting the relative LNB frequency
 * (not supported by the AVC standard)
 */
static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
307
			       struct dvb_frontend_parameters *params)
S
Stefan Richter 已提交
308
{
309 310
	struct avc_command_frame *c = (void *)fdtv->avc_data;

S
Stefan Richter 已提交
311 312 313 314 315
	c->opcode = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
316 317 318 319
	if (fdtv->type == FIREDTV_DVB_S2)
		c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2;
	else
		c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
S
Stefan Richter 已提交
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358

	c->operand[4] = (params->frequency >> 24) & 0xff;
	c->operand[5] = (params->frequency >> 16) & 0xff;
	c->operand[6] = (params->frequency >> 8) & 0xff;
	c->operand[7] = params->frequency & 0xff;

	c->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff;
	c->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff;

	switch (params->u.qpsk.fec_inner) {
	case FEC_1_2:	c->operand[10] = 0x1; break;
	case FEC_2_3:	c->operand[10] = 0x2; break;
	case FEC_3_4:	c->operand[10] = 0x3; break;
	case FEC_5_6:	c->operand[10] = 0x4; break;
	case FEC_7_8:	c->operand[10] = 0x5; break;
	case FEC_4_5:
	case FEC_8_9:
	case FEC_AUTO:
	default:	c->operand[10] = 0x0;
	}

	if (fdtv->voltage == 0xff)
		c->operand[11] = 0xff;
	else if (fdtv->voltage == SEC_VOLTAGE_18) /* polarisation */
		c->operand[11] = 0;
	else
		c->operand[11] = 1;

	if (fdtv->tone == 0xff)
		c->operand[12] = 0xff;
	else if (fdtv->tone == SEC_TONE_ON) /* band */
		c->operand[12] = 1;
	else
		c->operand[12] = 0;

	if (fdtv->type == FIREDTV_DVB_S2) {
		c->operand[13] = 0x1;
		c->operand[14] = 0xff;
		c->operand[15] = 0xff;
359
		fdtv->avc_data_length = 20;
S
Stefan Richter 已提交
360
	} else {
361
		fdtv->avc_data_length = 16;
S
Stefan Richter 已提交
362 363 364
	}
}

365
static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
366
				struct dvb_frontend_parameters *params)
S
Stefan Richter 已提交
367
{
368 369
	struct avc_command_frame *c = (void *)fdtv->avc_data;

S
Stefan Richter 已提交
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
	c->opcode = AVC_OPCODE_DSD;

	c->operand[0] = 0;    /* source plug */
	c->operand[1] = 0xd2; /* subfunction replace */
	c->operand[2] = 0x20; /* system id = DVB */
	c->operand[3] = 0x00; /* antenna number */
	c->operand[4] = 0x11; /* system_specific_multiplex selection_length */

	/* multiplex_valid_flags, high byte */
	c->operand[5] =   0 << 7 /* reserved */
			| 0 << 6 /* Polarisation */
			| 0 << 5 /* Orbital_Pos */
			| 1 << 4 /* Frequency */
			| 1 << 3 /* Symbol_Rate */
			| 0 << 2 /* FEC_outer */
			| (params->u.qam.fec_inner  != FEC_AUTO ? 1 << 1 : 0)
			| (params->u.qam.modulation != QAM_AUTO ? 1 << 0 : 0);

	/* multiplex_valid_flags, low byte */
	c->operand[6] =   0 << 7 /* NetworkID */
			| 0 << 0 /* reserved */ ;

	c->operand[7]  = 0x00;
	c->operand[8]  = 0x00;
	c->operand[9]  = 0x00;
	c->operand[10] = 0x00;

	c->operand[11] = (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6);
	c->operand[12] = ((params->frequency / 4000) >> 8) & 0xff;
	c->operand[13] = (params->frequency / 4000) & 0xff;
	c->operand[14] = ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff;
	c->operand[15] = ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff;
	c->operand[16] = ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0;
	c->operand[17] = 0x00;

	switch (params->u.qpsk.fec_inner) {
	case FEC_1_2:	c->operand[18] = 0x1; break;
	case FEC_2_3:	c->operand[18] = 0x2; break;
	case FEC_3_4:	c->operand[18] = 0x3; break;
	case FEC_5_6:	c->operand[18] = 0x4; break;
	case FEC_7_8:	c->operand[18] = 0x5; break;
	case FEC_8_9:	c->operand[18] = 0x6; break;
	case FEC_4_5:	c->operand[18] = 0x8; break;
	case FEC_AUTO:
	default:	c->operand[18] = 0x0;
	}

	switch (params->u.qam.modulation) {
	case QAM_16:	c->operand[19] = 0x08; break;
	case QAM_32:	c->operand[19] = 0x10; break;
	case QAM_64:	c->operand[19] = 0x18; break;
	case QAM_128:	c->operand[19] = 0x20; break;
	case QAM_256:	c->operand[19] = 0x28; break;
	case QAM_AUTO:
	default:	c->operand[19] = 0x00;
	}

	c->operand[20] = 0x00;
	c->operand[21] = 0x00;

430
	/* Add PIDs to filter */
431 432
	fdtv->avc_data_length =
		ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
S
Stefan Richter 已提交
433 434
}

435
static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
436
				struct dvb_frontend_parameters *params)
S
Stefan Richter 已提交
437 438
{
	struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
439
	struct avc_command_frame *c = (void *)fdtv->avc_data;
S
Stefan Richter 已提交
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533

	c->opcode = AVC_OPCODE_DSD;

	c->operand[0] = 0;    /* source plug */
	c->operand[1] = 0xd2; /* subfunction replace */
	c->operand[2] = 0x20; /* system id = DVB */
	c->operand[3] = 0x00; /* antenna number */
	c->operand[4] = 0x0c; /* system_specific_multiplex selection_length */

	/* multiplex_valid_flags, high byte */
	c->operand[5] =
	      0 << 7 /* reserved */
	    | 1 << 6 /* CenterFrequency */
	    | (ofdm->bandwidth      != BANDWIDTH_AUTO        ? 1 << 5 : 0)
	    | (ofdm->constellation  != QAM_AUTO              ? 1 << 4 : 0)
	    | (ofdm->hierarchy_information != HIERARCHY_AUTO ? 1 << 3 : 0)
	    | (ofdm->code_rate_HP   != FEC_AUTO              ? 1 << 2 : 0)
	    | (ofdm->code_rate_LP   != FEC_AUTO              ? 1 << 1 : 0)
	    | (ofdm->guard_interval != GUARD_INTERVAL_AUTO   ? 1 << 0 : 0);

	/* multiplex_valid_flags, low byte */
	c->operand[6] =
	      0 << 7 /* NetworkID */
	    | (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO ? 1 << 6 : 0)
	    | 0 << 5 /* OtherFrequencyFlag */
	    | 0 << 0 /* reserved */ ;

	c->operand[7]  = 0x0;
	c->operand[8]  = (params->frequency / 10) >> 24;
	c->operand[9]  = ((params->frequency / 10) >> 16) & 0xff;
	c->operand[10] = ((params->frequency / 10) >>  8) & 0xff;
	c->operand[11] = (params->frequency / 10) & 0xff;

	switch (ofdm->bandwidth) {
	case BANDWIDTH_7_MHZ:	c->operand[12] = 0x20; break;
	case BANDWIDTH_8_MHZ:
	case BANDWIDTH_6_MHZ:	/* not defined by AVC spec */
	case BANDWIDTH_AUTO:
	default:		c->operand[12] = 0x00;
	}

	switch (ofdm->constellation) {
	case QAM_16:	c->operand[13] = 1 << 6; break;
	case QAM_64:	c->operand[13] = 2 << 6; break;
	case QPSK:
	default:	c->operand[13] = 0x00;
	}

	switch (ofdm->hierarchy_information) {
	case HIERARCHY_1:	c->operand[13] |= 1 << 3; break;
	case HIERARCHY_2:	c->operand[13] |= 2 << 3; break;
	case HIERARCHY_4:	c->operand[13] |= 3 << 3; break;
	case HIERARCHY_AUTO:
	case HIERARCHY_NONE:
	default:		break;
	}

	switch (ofdm->code_rate_HP) {
	case FEC_2_3:	c->operand[13] |= 1; break;
	case FEC_3_4:	c->operand[13] |= 2; break;
	case FEC_5_6:	c->operand[13] |= 3; break;
	case FEC_7_8:	c->operand[13] |= 4; break;
	case FEC_1_2:
	default:	break;
	}

	switch (ofdm->code_rate_LP) {
	case FEC_2_3:	c->operand[14] = 1 << 5; break;
	case FEC_3_4:	c->operand[14] = 2 << 5; break;
	case FEC_5_6:	c->operand[14] = 3 << 5; break;
	case FEC_7_8:	c->operand[14] = 4 << 5; break;
	case FEC_1_2:
	default:	c->operand[14] = 0x00; break;
	}

	switch (ofdm->guard_interval) {
	case GUARD_INTERVAL_1_16:	c->operand[14] |= 1 << 3; break;
	case GUARD_INTERVAL_1_8:	c->operand[14] |= 2 << 3; break;
	case GUARD_INTERVAL_1_4:	c->operand[14] |= 3 << 3; break;
	case GUARD_INTERVAL_1_32:
	case GUARD_INTERVAL_AUTO:
	default:			break;
	}

	switch (ofdm->transmission_mode) {
	case TRANSMISSION_MODE_8K:	c->operand[14] |= 1 << 1; break;
	case TRANSMISSION_MODE_2K:
	case TRANSMISSION_MODE_AUTO:
	default:			break;
	}

	c->operand[15] = 0x00; /* network_ID[0] */
	c->operand[16] = 0x00; /* network_ID[1] */

534
	/* Add PIDs to filter */
535 536
	fdtv->avc_data_length =
		ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
S
Stefan Richter 已提交
537 538 539 540 541
}

int avc_tuner_dsd(struct firedtv *fdtv,
		  struct dvb_frontend_parameters *params)
{
542 543 544
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret;

545
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
546 547 548 549 550 551 552 553

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;

	switch (fdtv->type) {
	case FIREDTV_DVB_S:
554 555 556
	case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params); break;
	case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params); break;
	case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params); break;
S
Stefan Richter 已提交
557 558 559
	default:
		BUG();
	}
560
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
561
#if 0
562 563 564 565 566
	/*
	 * FIXME:
	 * u8 *status was an out-parameter of avc_tuner_dsd, unused by caller.
	 * Check for AVC_RESPONSE_ACCEPTED here instead?
	 */
S
Stefan Richter 已提交
567 568 569
	if (status)
		*status = r->operand[2];
#endif
570 571 572 573 574 575
	mutex_unlock(&fdtv->avc_mutex);

	if (ret == 0)
		msleep(500);

	return ret;
S
Stefan Richter 已提交
576 577 578 579
}

int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[])
{
580 581
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret, pos, k;
S
Stefan Richter 已提交
582 583 584 585

	if (pidc > 16 && pidc != 0xff)
		return -EINVAL;

586
	mutex_lock(&fdtv->avc_mutex);
587

S
Stefan Richter 已提交
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_DSD;

	c->operand[0] = 0;	/* source plug */
	c->operand[1] = 0xd2;	/* subfunction replace */
	c->operand[2] = 0x20;	/* system id = DVB */
	c->operand[3] = 0x00;	/* antenna number */
	c->operand[4] = 0x00;	/* system_specific_multiplex selection_length */
	c->operand[5] = pidc;	/* Nr_of_dsd_sel_specs */

	pos = 6;
	if (pidc != 0xff)
		for (k = 0; k < pidc; k++) {
			c->operand[pos++] = 0x13; /* flowfunction relay */
			c->operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
			c->operand[pos++] = (pid[k] >> 8) & 0x1f;
			c->operand[pos++] = pid[k] & 0xff;
			c->operand[pos++] = 0x00; /* tableID */
			c->operand[pos++] = 0x00; /* filter_length */
		}

612 613
	fdtv->avc_data_length = ALIGN(3 + pos, 4);
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
614

615
	/* FIXME: check response code? */
S
Stefan Richter 已提交
616

617 618 619 620 621 622
	mutex_unlock(&fdtv->avc_mutex);

	if (ret == 0)
		msleep(50);

	return ret;
S
Stefan Richter 已提交
623 624 625 626
}

int avc_tuner_get_ts(struct firedtv *fdtv)
{
627 628 629
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret, sl;

630
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_DSIT;

	sl = fdtv->type == FIREDTV_DVB_T ? 0x0c : 0x11;

	c->operand[0] = 0;	/* source plug */
	c->operand[1] = 0xd2;	/* subfunction replace */
	c->operand[2] = 0xff;	/* status */
	c->operand[3] = 0x20;	/* system id = DVB */
	c->operand[4] = 0x00;	/* antenna number */
	c->operand[5] = 0x0; 	/* system_specific_search_flags */
	c->operand[6] = sl;	/* system_specific_multiplex selection_length */
	c->operand[7] = 0x00;	/* valid_flags [0] */
	c->operand[8] = 0x00;	/* valid_flags [1] */
	c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */

651 652
	fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28;
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
653

654
	/* FIXME: check response code? */
S
Stefan Richter 已提交
655

656 657 658 659 660 661
	mutex_unlock(&fdtv->avc_mutex);

	if (ret == 0)
		msleep(250);

	return ret;
S
Stefan Richter 已提交
662 663 664 665
}

int avc_identify_subunit(struct firedtv *fdtv)
{
666 667 668 669
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int ret;

670
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_READ_DESCRIPTOR;

	c->operand[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER;
	c->operand[1] = 0xff;
	c->operand[2] = 0x00;
	c->operand[3] = 0x00; /* length highbyte */
	c->operand[4] = 0x08; /* length lowbyte  */
	c->operand[5] = 0x00; /* offset highbyte */
	c->operand[6] = 0x0d; /* offset lowbyte  */

686 687 688 689
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
690 691 692 693 694

	if ((r->response != AVC_RESPONSE_STABLE &&
	     r->response != AVC_RESPONSE_ACCEPTED) ||
	    (r->operand[3] << 8) + r->operand[4] != 8) {
		dev_err(fdtv->device, "cannot read subunit identifier\n");
695
		ret = -EINVAL;
S
Stefan Richter 已提交
696
	}
697 698 699 700
out:
	mutex_unlock(&fdtv->avc_mutex);

	return ret;
S
Stefan Richter 已提交
701 702 703 704 705 706
}

#define SIZEOF_ANTENNA_INPUT_INFO 22

int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat)
{
707 708 709 710
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int length, ret;

711
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_READ_DESCRIPTOR;

	c->operand[0] = DESCRIPTOR_TUNER_STATUS;
	c->operand[1] = 0xff;	/* read_result_status */
	c->operand[2] = 0x00;	/* reserved */
	c->operand[3] = 0;	/* SIZEOF_ANTENNA_INPUT_INFO >> 8; */
	c->operand[4] = 0;	/* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */
	c->operand[5] = 0x00;
	c->operand[6] = 0x00;

727 728 729 730
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
731 732 733 734

	if (r->response != AVC_RESPONSE_STABLE &&
	    r->response != AVC_RESPONSE_ACCEPTED) {
		dev_err(fdtv->device, "cannot read tuner status\n");
735 736
		ret = -EINVAL;
		goto out;
S
Stefan Richter 已提交
737 738 739 740 741
	}

	length = r->operand[9];
	if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) {
		dev_err(fdtv->device, "got invalid tuner status\n");
742 743
		ret = -EINVAL;
		goto out;
S
Stefan Richter 已提交
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
	}

	stat->active_system		= r->operand[10];
	stat->searching			= r->operand[11] >> 7 & 1;
	stat->moving			= r->operand[11] >> 6 & 1;
	stat->no_rf			= r->operand[11] >> 5 & 1;
	stat->input			= r->operand[12] >> 7 & 1;
	stat->selected_antenna		= r->operand[12] & 0x7f;
	stat->ber			= r->operand[13] << 24 |
					  r->operand[14] << 16 |
					  r->operand[15] << 8 |
					  r->operand[16];
	stat->signal_strength		= r->operand[17];
	stat->raster_frequency		= r->operand[18] >> 6 & 2;
	stat->rf_frequency		= (r->operand[18] & 0x3f) << 16 |
					  r->operand[19] << 8 |
					  r->operand[20];
	stat->man_dep_info_length	= r->operand[21];
	stat->front_end_error		= r->operand[22] >> 4 & 1;
	stat->antenna_error		= r->operand[22] >> 3 & 1;
	stat->front_end_power_status	= r->operand[22] >> 1 & 1;
	stat->power_supply		= r->operand[22] & 1;
	stat->carrier_noise_ratio	= r->operand[23] << 8 |
					  r->operand[24];
	stat->power_supply_voltage	= r->operand[27];
	stat->antenna_voltage		= r->operand[28];
	stat->firewire_bus_voltage	= r->operand[29];
	stat->ca_mmi			= r->operand[30] & 1;
	stat->ca_pmt_reply		= r->operand[31] >> 7 & 1;
	stat->ca_date_time_request	= r->operand[31] >> 6 & 1;
	stat->ca_application_info	= r->operand[31] >> 5 & 1;
	stat->ca_module_present_status	= r->operand[31] >> 4 & 1;
	stat->ca_dvb_flag		= r->operand[31] >> 3 & 1;
	stat->ca_error_flag		= r->operand[31] >> 2 & 1;
	stat->ca_initialization_status	= r->operand[31] >> 1 & 1;
779 780
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
781

782
	return ret;
S
Stefan Richter 已提交
783 784 785 786 787 788
}

int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst,
		    char conttone, char nrdiseq,
		    struct dvb_diseqc_master_cmd *diseqcmd)
{
789 790 791 792
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int i, j, k, ret;

793
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL;

	c->operand[4] = voltage;
	c->operand[5] = nrdiseq;

	i = 6;

	for (j = 0; j < nrdiseq; j++) {
		c->operand[i++] = diseqcmd[j].msg_len;

		for (k = 0; k < diseqcmd[j].msg_len; k++)
			c->operand[i++] = diseqcmd[j].msg[k];
	}

	c->operand[i++] = burst;
	c->operand[i++] = conttone;

821 822 823 824
	fdtv->avc_data_length = ALIGN(3 + i, 4);
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
825 826 827

	if (r->response != AVC_RESPONSE_ACCEPTED) {
		dev_err(fdtv->device, "LNB control failed\n");
828
		ret = -EINVAL;
S
Stefan Richter 已提交
829
	}
830 831
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
832

833
	return ret;
S
Stefan Richter 已提交
834 835 836 837
}

int avc_register_remote_control(struct firedtv *fdtv)
{
838 839 840
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret;

841
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
842 843 844 845 846 847 848 849 850 851 852 853

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_NOTIFY;
	c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;

854 855
	fdtv->avc_data_length = 8;
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
856

857 858 859 860 861
	/* FIXME: check response code? */

	mutex_unlock(&fdtv->avc_mutex);

	return ret;
S
Stefan Richter 已提交
862 863 864 865 866 867 868 869 870 871 872 873 874 875
}

void avc_remote_ctrl_work(struct work_struct *work)
{
	struct firedtv *fdtv =
			container_of(work, struct firedtv, remote_ctrl_work);

	/* Should it be rescheduled in failure cases? */
	avc_register_remote_control(fdtv);
}

#if 0 /* FIXME: unused */
int avc_tuner_host2ca(struct firedtv *fdtv)
{
876 877 878
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret;

879
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */
	c->operand[6] = 0; /* more/last */
	c->operand[7] = 0; /* length */

896 897
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
898

899
	/* FIXME: check response code? */
S
Stefan Richter 已提交
900

901 902 903
	mutex_unlock(&fdtv->avc_mutex);

	return ret;
S
Stefan Richter 已提交
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
}
#endif

static int get_ca_object_pos(struct avc_response_frame *r)
{
	int length = 1;

	/* Check length of length field */
	if (r->operand[7] & 0x80)
		length = (r->operand[7] & 0x7f) + 1;
	return length + 7;
}

static int get_ca_object_length(struct avc_response_frame *r)
{
#if 0 /* FIXME: unused */
	int size = 0;
	int i;

	if (r->operand[7] & 0x80)
		for (i = 0; i < (r->operand[7] & 0x7f); i++) {
			size <<= 8;
			size += r->operand[8 + i];
		}
#endif
	return r->operand[7];
}

int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
{
934 935 936 937
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int pos, ret;

938
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
939 940 941 942 943 944 945 946 947 948 949 950 951 952

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_STATUS;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */

953 954 955 956
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
957 958 959 960 961 962 963 964 965 966 967

	/* FIXME: check response code and validate response data */

	pos = get_ca_object_pos(r);
	app_info[0] = (EN50221_TAG_APP_INFO >> 16) & 0xff;
	app_info[1] = (EN50221_TAG_APP_INFO >>  8) & 0xff;
	app_info[2] = (EN50221_TAG_APP_INFO >>  0) & 0xff;
	app_info[3] = 6 + r->operand[pos + 4];
	app_info[4] = 0x01;
	memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]);
	*len = app_info[3] + 4;
968 969
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
970

971
	return ret;
S
Stefan Richter 已提交
972 973 974 975
}

int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len)
{
976 977 978 979
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int pos, ret;

980
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
981 982 983 984 985 986 987 988 989 990 991 992 993 994

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_STATUS;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */

995 996 997 998
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
999

1000
	/* FIXME: check response code and validate response data */
S
Stefan Richter 已提交
1001 1002 1003 1004 1005 1006 1007 1008 1009

	pos = get_ca_object_pos(r);
	app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff;
	app_info[1] = (EN50221_TAG_CA_INFO >>  8) & 0xff;
	app_info[2] = (EN50221_TAG_CA_INFO >>  0) & 0xff;
	app_info[3] = 2;
	app_info[4] = r->operand[pos + 0];
	app_info[5] = r->operand[pos + 1];
	*len = app_info[3] + 4;
1010 1011
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1012

1013
	return ret;
S
Stefan Richter 已提交
1014 1015 1016 1017
}

int avc_ca_reset(struct firedtv *fdtv)
{
1018 1019 1020
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret;

1021
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_RESET; /* ca tag */
	c->operand[6] = 0; /* more/last */
	c->operand[7] = 1; /* length */
	c->operand[8] = 0; /* force hardware reset */

1039 1040
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
1041

1042
	/* FIXME: check response code? */
S
Stefan Richter 已提交
1043

1044 1045 1046
	mutex_unlock(&fdtv->avc_mutex);

	return ret;
S
Stefan Richter 已提交
1047 1048 1049 1050
}

int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
{
1051 1052
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
S
Stefan Richter 已提交
1053 1054 1055 1056 1057 1058 1059
	int list_management;
	int program_info_length;
	int pmt_cmd_id;
	int read_pos;
	int write_pos;
	int es_info_length;
	int crc32_csum;
1060
	int ret;
S
Stefan Richter 已提交
1061

1062 1063 1064
	if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
		debug_pmt(msg, length);

1065
	mutex_lock(&fdtv->avc_mutex);
1066

S
Stefan Richter 已提交
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_CONTROL;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	if (msg[0] != EN50221_LIST_MANAGEMENT_ONLY) {
		dev_info(fdtv->device, "forcing list_management to ONLY\n");
		msg[0] = EN50221_LIST_MANAGEMENT_ONLY;
	}
	/* We take the cmd_id from the programme level only! */
	list_management = msg[0];
	program_info_length = ((msg[4] & 0x0f) << 8) + msg[5];
	if (program_info_length > 0)
		program_info_length--; /* Remove pmt_cmd_id */
	pmt_cmd_id = msg[6];

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_PMT; /* ca tag */
	c->operand[6] = 0; /* more/last */
1091 1092 1093
	/* Use three bytes for length field in case length > 127 */
	c->operand[10] = list_management;
	c->operand[11] = 0x01; /* pmt_cmd=OK_descramble */
S
Stefan Richter 已提交
1094 1095 1096

	/* TS program map table */

1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
	c->operand[12] = 0x02; /* Table id=2 */
	c->operand[13] = 0x80; /* Section syntax + length */
	/* c->operand[14] = XXXprogram_info_length + 12; */
	c->operand[15] = msg[1]; /* Program number */
	c->operand[16] = msg[2];
	c->operand[17] = 0x01; /* Version number=0 + current/next=1 */
	c->operand[18] = 0x00; /* Section number=0 */
	c->operand[19] = 0x00; /* Last section number=0 */
	c->operand[20] = 0x1f; /* PCR_PID=1FFF */
	c->operand[21] = 0xff;
	c->operand[22] = (program_info_length >> 8); /* Program info length */
	c->operand[23] = (program_info_length & 0xff);
S
Stefan Richter 已提交
1109 1110 1111

	/* CA descriptors at programme level */
	read_pos = 6;
1112
	write_pos = 24;
S
Stefan Richter 已提交
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
	if (program_info_length > 0) {
		pmt_cmd_id = msg[read_pos++];
		if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
			dev_err(fdtv->device,
				"invalid pmt_cmd_id %d\n", pmt_cmd_id);

		memcpy(&c->operand[write_pos], &msg[read_pos],
		       program_info_length);
		read_pos += program_info_length;
		write_pos += program_info_length;
	}
	while (read_pos < length) {
		c->operand[write_pos++] = msg[read_pos++];
		c->operand[write_pos++] = msg[read_pos++];
		c->operand[write_pos++] = msg[read_pos++];
		es_info_length =
			((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1];
		read_pos += 2;
		if (es_info_length > 0)
			es_info_length--; /* Remove pmt_cmd_id */
		c->operand[write_pos++] = es_info_length >> 8;
		c->operand[write_pos++] = es_info_length & 0xff;
		if (es_info_length > 0) {
			pmt_cmd_id = msg[read_pos++];
			if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
				dev_err(fdtv->device, "invalid pmt_cmd_id %d "
					"at stream level\n", pmt_cmd_id);

			memcpy(&c->operand[write_pos], &msg[read_pos],
			       es_info_length);
			read_pos += es_info_length;
			write_pos += es_info_length;
		}
	}

	/* CRC */
	c->operand[write_pos++] = 0x00;
	c->operand[write_pos++] = 0x00;
	c->operand[write_pos++] = 0x00;
	c->operand[write_pos++] = 0x00;

1154 1155 1156 1157
	c->operand[7] = 0x82;
	c->operand[8] = (write_pos - 10) >> 8;
	c->operand[9] = (write_pos - 10) & 0xff;
	c->operand[14] = write_pos - 15;
S
Stefan Richter 已提交
1158 1159 1160 1161 1162 1163 1164

	crc32_csum = crc32_be(0, &c->operand[10], c->operand[12] - 1);
	c->operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
	c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
	c->operand[write_pos - 2] = (crc32_csum >>  8) & 0xff;
	c->operand[write_pos - 1] = (crc32_csum >>  0) & 0xff;

1165 1166 1167 1168
	fdtv->avc_data_length = ALIGN(3 + write_pos, 4);
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
1169 1170 1171 1172

	if (r->response != AVC_RESPONSE_ACCEPTED) {
		dev_err(fdtv->device,
			"CA PMT failed with response 0x%x\n", r->response);
1173
		ret = -EFAULT;
S
Stefan Richter 已提交
1174
	}
1175 1176
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1177

1178
	return ret;
S
Stefan Richter 已提交
1179 1180 1181 1182
}

int avc_ca_get_time_date(struct firedtv *fdtv, int *interval)
{
1183 1184 1185 1186
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int ret;

1187
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_STATUS;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */
	c->operand[6] = 0; /* more/last */
	c->operand[7] = 0; /* length */

1204 1205 1206 1207
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
1208 1209 1210 1211

	/* FIXME: check response code and validate response data */

	*interval = r->operand[get_ca_object_pos(r)];
1212 1213
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1214

1215
	return ret;
S
Stefan Richter 已提交
1216 1217 1218 1219
}

int avc_ca_enter_menu(struct firedtv *fdtv)
{
1220 1221 1222
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	int ret;

1223
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_STATUS;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
	c->operand[6] = 0; /* more/last */
	c->operand[7] = 0; /* length */

1240 1241
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
S
Stefan Richter 已提交
1242

1243
	/* FIXME: check response code? */
S
Stefan Richter 已提交
1244

1245 1246 1247
	mutex_unlock(&fdtv->avc_mutex);

	return ret;
S
Stefan Richter 已提交
1248 1249 1250 1251
}

int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len)
{
1252 1253 1254 1255
	struct avc_command_frame *c = (void *)fdtv->avc_data;
	struct avc_response_frame *r = (void *)fdtv->avc_data;
	int ret;

1256
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272

	memset(c, 0, sizeof(*c));

	c->ctype   = AVC_CTYPE_STATUS;
	c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit;
	c->opcode  = AVC_OPCODE_VENDOR;

	c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
	c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
	c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
	c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST;
	c->operand[4] = 0; /* slot */
	c->operand[5] = SFE_VENDOR_TAG_CA_MMI;
	c->operand[6] = 0; /* more/last */
	c->operand[7] = 0; /* length */

1273 1274 1275 1276
	fdtv->avc_data_length = 12;
	ret = avc_write(fdtv);
	if (ret < 0)
		goto out;
S
Stefan Richter 已提交
1277 1278 1279 1280 1281

	/* FIXME: check response code and validate response data */

	*len = get_ca_object_length(r);
	memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len);
1282 1283
out:
	mutex_unlock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1284

1285
	return ret;
S
Stefan Richter 已提交
1286 1287 1288 1289
}

#define CMP_OUTPUT_PLUG_CONTROL_REG_0	0xfffff0000904ULL

1290
static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
S
Stefan Richter 已提交
1291 1292 1293
{
	int ret;

1294
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1295

1296
	ret = fdtv->backend->read(fdtv, addr, data);
S
Stefan Richter 已提交
1297 1298 1299 1300
	if (ret < 0)
		dev_err(fdtv->device, "CMP: read I/O error\n");

	mutex_unlock(&fdtv->avc_mutex);
1301

S
Stefan Richter 已提交
1302 1303 1304
	return ret;
}

1305
static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
S
Stefan Richter 已提交
1306 1307 1308
{
	int ret;

1309
	mutex_lock(&fdtv->avc_mutex);
S
Stefan Richter 已提交
1310

1311 1312 1313 1314
	/* data[] is stack-allocated and should not be DMA-mapped. */
	memcpy(fdtv->avc_data, data, 8);

	ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data);
S
Stefan Richter 已提交
1315 1316
	if (ret < 0)
		dev_err(fdtv->device, "CMP: lock I/O error\n");
1317 1318
	else
		memcpy(data, fdtv->avc_data, 8);
S
Stefan Richter 已提交
1319 1320

	mutex_unlock(&fdtv->avc_mutex);
1321

S
Stefan Richter 已提交
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
	return ret;
}

static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
{
	return (be32_to_cpu(opcr) >> shift) & mask;
}

static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
{
	*opcr &= ~cpu_to_be32(mask << shift);
	*opcr |= cpu_to_be32((value & mask) << shift);
}

#define get_opcr_online(v)		get_opcr((v), 0x1, 31)
#define get_opcr_p2p_connections(v)	get_opcr((v), 0x3f, 24)
#define get_opcr_channel(v)		get_opcr((v), 0x3f, 16)

#define set_opcr_p2p_connections(p, v)	set_opcr((p), (v), 0x3f, 24)
#define set_opcr_channel(p, v)		set_opcr((p), (v), 0x3f, 16)
#define set_opcr_data_rate(p, v)	set_opcr((p), (v), 0x3, 14)
#define set_opcr_overhead_id(p, v)	set_opcr((p), (v), 0xf, 10)

int cmp_establish_pp_connection(struct firedtv *fdtv, int plug, int channel)
{
1347
	__be32 old_opcr, opcr[2];
S
Stefan Richter 已提交
1348 1349 1350 1351
	u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
	int attempts = 0;
	int ret;

1352
	ret = cmp_read(fdtv, opcr_address, opcr);
S
Stefan Richter 已提交
1353 1354 1355 1356
	if (ret < 0)
		return ret;

repeat:
1357
	if (!get_opcr_online(*opcr)) {
S
Stefan Richter 已提交
1358 1359 1360 1361
		dev_err(fdtv->device, "CMP: output offline\n");
		return -EBUSY;
	}

1362
	old_opcr = *opcr;
S
Stefan Richter 已提交
1363

1364 1365
	if (get_opcr_p2p_connections(*opcr)) {
		if (get_opcr_channel(*opcr) != channel) {
S
Stefan Richter 已提交
1366 1367 1368 1369 1370 1371 1372
			dev_err(fdtv->device, "CMP: cannot change channel\n");
			return -EBUSY;
		}
		dev_info(fdtv->device, "CMP: overlaying connection\n");

		/* We don't allocate isochronous resources. */
	} else {
1373 1374
		set_opcr_channel(opcr, channel);
		set_opcr_data_rate(opcr, 2); /* S400 */
S
Stefan Richter 已提交
1375 1376

		/* FIXME: this is for the worst case - optimize */
1377
		set_opcr_overhead_id(opcr, 0);
S
Stefan Richter 已提交
1378 1379 1380 1381 1382 1383 1384

		/*
		 * FIXME: allocate isochronous channel and bandwidth at IRM
		 * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
		 */
	}

1385
	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
S
Stefan Richter 已提交
1386

1387 1388 1389 1390
	opcr[1] = *opcr;
	opcr[0] = old_opcr;

	ret = cmp_lock(fdtv, opcr_address, opcr);
S
Stefan Richter 已提交
1391 1392 1393
	if (ret < 0)
		return ret;

1394
	if (old_opcr != *opcr) {
S
Stefan Richter 已提交
1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411
		/*
		 * FIXME: if old_opcr.P2P_Connections > 0,
		 * deallocate isochronous channel and bandwidth at IRM
		 * if (...)
		 *	fdtv->backend->dealloc_resources(fdtv, channel, bw);
		 */

		if (++attempts < 6) /* arbitrary limit */
			goto repeat;
		return -EBUSY;
	}

	return 0;
}

void cmp_break_pp_connection(struct firedtv *fdtv, int plug, int channel)
{
1412
	__be32 old_opcr, opcr[2];
S
Stefan Richter 已提交
1413 1414 1415
	u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
	int attempts = 0;

1416
	if (cmp_read(fdtv, opcr_address, opcr) < 0)
S
Stefan Richter 已提交
1417 1418 1419
		return;

repeat:
1420 1421
	if (!get_opcr_online(*opcr) || !get_opcr_p2p_connections(*opcr) ||
	    get_opcr_channel(*opcr) != channel) {
S
Stefan Richter 已提交
1422 1423 1424 1425
		dev_err(fdtv->device, "CMP: no connection to break\n");
		return;
	}

1426 1427 1428 1429 1430
	old_opcr = *opcr;
	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) - 1);

	opcr[1] = *opcr;
	opcr[0] = old_opcr;
S
Stefan Richter 已提交
1431

1432
	if (cmp_lock(fdtv, opcr_address, opcr) < 0)
S
Stefan Richter 已提交
1433 1434
		return;

1435
	if (old_opcr != *opcr) {
S
Stefan Richter 已提交
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446
		/*
		 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
		 * owner, deallocate isochronous channel and bandwidth at IRM
		 * if (...)
		 *	fdtv->backend->dealloc_resources(fdtv, channel, bw);
		 */

		if (++attempts < 6) /* arbitrary limit */
			goto repeat;
	}
}