File Index
Files and directories
Sign in
FILE

cxd2880_top.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * cxd2880_top.c
   4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
   5 *
   6 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
   7 */
   8
   9#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
  10
  11#include <linux/spi/spi.h>
  12
  13#include <media/dvb_frontend.h>
  14#include <linux/int_log.h>
  15
  16#include "cxd2880.h"
  17#include "cxd2880_tnrdmd_mon.h"
  18#include "cxd2880_tnrdmd_dvbt2_mon.h"
  19#include "cxd2880_tnrdmd_dvbt_mon.h"
  20#include "cxd2880_integ.h"
  21#include "cxd2880_tnrdmd_dvbt2.h"
  22#include "cxd2880_tnrdmd_dvbt.h"
  23#include "cxd2880_devio_spi.h"
  24#include "cxd2880_spi_device.h"
  25#include "cxd2880_tnrdmd_driver_version.h"
  26
  27struct cxd2880_priv {
  28	struct cxd2880_tnrdmd tnrdmd;
  29	struct spi_device *spi;
  30	struct cxd2880_io regio;
  31	struct cxd2880_spi_device spi_device;
  32	struct cxd2880_spi cxd2880_spi;
  33	struct cxd2880_dvbt_tune_param dvbt_tune_param;
  34	struct cxd2880_dvbt2_tune_param dvbt2_tune_param;
  35	struct mutex *spi_mutex; /* For SPI access exclusive control */
  36	unsigned long pre_ber_update;
  37	unsigned long pre_ber_interval;
  38	unsigned long post_ber_update;
  39	unsigned long post_ber_interval;
  40	unsigned long ucblock_update;
  41	unsigned long ucblock_interval;
  42	enum fe_status s;
  43};
  44
  45static int cxd2880_pre_bit_err_t(struct cxd2880_tnrdmd *tnrdmd,
  46				 u32 *pre_bit_err, u32 *pre_bit_count)
  47{
  48	u8 rdata[2];
  49	int ret;
  50
  51	if (!tnrdmd || !pre_bit_err || !pre_bit_count)
  52		return -EINVAL;
  53
  54	if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
  55		return -EINVAL;
  56
  57	if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
  58		return -EINVAL;
  59
  60	if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT)
  61		return -EINVAL;
  62
  63	ret = slvt_freeze_reg(tnrdmd);
  64	if (ret)
  65		return ret;
  66
  67	ret = tnrdmd->io->write_reg(tnrdmd->io,
  68				    CXD2880_IO_TGT_DMD,
  69				    0x00, 0x10);
  70	if (ret) {
  71		slvt_unfreeze_reg(tnrdmd);
  72		return ret;
  73	}
  74
  75	ret = tnrdmd->io->read_regs(tnrdmd->io,
  76				    CXD2880_IO_TGT_DMD,
  77				    0x39, rdata, 1);
  78	if (ret) {
  79		slvt_unfreeze_reg(tnrdmd);
  80		return ret;
  81	}
  82
  83	if ((rdata[0] & 0x01) == 0) {
  84		slvt_unfreeze_reg(tnrdmd);
  85		return -EAGAIN;
  86	}
  87
  88	ret = tnrdmd->io->read_regs(tnrdmd->io,
  89				    CXD2880_IO_TGT_DMD,
  90				    0x22, rdata, 2);
  91	if (ret) {
  92		slvt_unfreeze_reg(tnrdmd);
  93		return ret;
  94	}
  95
  96	*pre_bit_err = (rdata[0] << 8) | rdata[1];
  97
  98	ret = tnrdmd->io->read_regs(tnrdmd->io,
  99				    CXD2880_IO_TGT_DMD,
 100				    0x6f, rdata, 1);
 101	if (ret) {
 102		slvt_unfreeze_reg(tnrdmd);
 103		return ret;
 104	}
 105
 106	slvt_unfreeze_reg(tnrdmd);
 107
 108	*pre_bit_count = ((rdata[0] & 0x07) == 0) ?
 109			 256 : (0x1000 << (rdata[0] & 0x07));
 110
 111	return 0;
 112}
 113
 114static int cxd2880_pre_bit_err_t2(struct cxd2880_tnrdmd *tnrdmd,
 115				  u32 *pre_bit_err,
 116				  u32 *pre_bit_count)
 117{
 118	u32 period_exp = 0;
 119	u32 n_ldpc = 0;
 120	u8 data[5];
 121	int ret;
 122
 123	if (!tnrdmd || !pre_bit_err || !pre_bit_count)
 124		return -EINVAL;
 125
 126	if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 127		return -EINVAL;
 128
 129	if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 130		return -EINVAL;
 131
 132	if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT2)
 133		return -EINVAL;
 134
 135	ret = slvt_freeze_reg(tnrdmd);
 136	if (ret)
 137		return ret;
 138
 139	ret = tnrdmd->io->write_reg(tnrdmd->io,
 140				    CXD2880_IO_TGT_DMD,
 141				    0x00, 0x0b);
 142	if (ret) {
 143		slvt_unfreeze_reg(tnrdmd);
 144		return ret;
 145	}
 146
 147	ret = tnrdmd->io->read_regs(tnrdmd->io,
 148				    CXD2880_IO_TGT_DMD,
 149				    0x3c, data, sizeof(data));
 150	if (ret) {
 151		slvt_unfreeze_reg(tnrdmd);
 152		return ret;
 153	}
 154
 155	if (!(data[0] & 0x01)) {
 156		slvt_unfreeze_reg(tnrdmd);
 157		return -EAGAIN;
 158	}
 159	*pre_bit_err =
 160	((data[1] & 0x0f) << 24) | (data[2] << 16) | (data[3] << 8) | data[4];
 161
 162	ret = tnrdmd->io->read_regs(tnrdmd->io,
 163				    CXD2880_IO_TGT_DMD,
 164				    0xa0, data, 1);
 165	if (ret) {
 166		slvt_unfreeze_reg(tnrdmd);
 167		return ret;
 168	}
 169
 170	if (((enum cxd2880_dvbt2_plp_fec)(data[0] & 0x03)) ==
 171	    CXD2880_DVBT2_FEC_LDPC_16K)
 172		n_ldpc = 16200;
 173	else
 174		n_ldpc = 64800;
 175	slvt_unfreeze_reg(tnrdmd);
 176
 177	ret = tnrdmd->io->write_reg(tnrdmd->io,
 178				    CXD2880_IO_TGT_DMD,
 179				    0x00, 0x20);
 180	if (ret)
 181		return ret;
 182
 183	ret = tnrdmd->io->read_regs(tnrdmd->io,
 184				    CXD2880_IO_TGT_DMD,
 185				    0x6f, data, 1);
 186	if (ret)
 187		return ret;
 188
 189	period_exp = data[0] & 0x0f;
 190
 191	*pre_bit_count = (1U << period_exp) * n_ldpc;
 192
 193	return 0;
 194}
 195
 196static int cxd2880_post_bit_err_t(struct cxd2880_tnrdmd *tnrdmd,
 197				  u32 *post_bit_err,
 198				  u32 *post_bit_count)
 199{
 200	u8 rdata[3];
 201	u32 bit_error = 0;
 202	u32 period_exp = 0;
 203	int ret;
 204
 205	if (!tnrdmd || !post_bit_err || !post_bit_count)
 206		return -EINVAL;
 207
 208	if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 209		return -EINVAL;
 210
 211	if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 212		return -EINVAL;
 213
 214	if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT)
 215		return -EINVAL;
 216
 217	ret = tnrdmd->io->write_reg(tnrdmd->io,
 218				    CXD2880_IO_TGT_DMD,
 219				    0x00, 0x0d);
 220	if (ret)
 221		return ret;
 222
 223	ret = tnrdmd->io->read_regs(tnrdmd->io,
 224				    CXD2880_IO_TGT_DMD,
 225				    0x15, rdata, 3);
 226	if (ret)
 227		return ret;
 228
 229	if ((rdata[0] & 0x40) == 0)
 230		return -EAGAIN;
 231
 232	*post_bit_err = ((rdata[0] & 0x3f) << 16) | (rdata[1] << 8) | rdata[2];
 233
 234	ret = tnrdmd->io->write_reg(tnrdmd->io,
 235				    CXD2880_IO_TGT_DMD,
 236				    0x00, 0x10);
 237	if (ret)
 238		return ret;
 239
 240	ret = tnrdmd->io->read_regs(tnrdmd->io,
 241				    CXD2880_IO_TGT_DMD,
 242				    0x60, rdata, 1);
 243	if (ret)
 244		return ret;
 245
 246	period_exp = (rdata[0] & 0x1f);
 247
 248	if (period_exp <= 11 && (bit_error > (1U << period_exp) * 204 * 8))
 249		return -EAGAIN;
 250
 251	*post_bit_count = (1U << period_exp) * 204 * 8;
 252
 253	return 0;
 254}
 255
 256static int cxd2880_post_bit_err_t2(struct cxd2880_tnrdmd *tnrdmd,
 257				   u32 *post_bit_err,
 258				   u32 *post_bit_count)
 259{
 260	u32 period_exp = 0;
 261	u32 n_bch = 0;
 262	u8 data[3];
 263	enum cxd2880_dvbt2_plp_fec plp_fec_type =
 264		CXD2880_DVBT2_FEC_LDPC_16K;
 265	enum cxd2880_dvbt2_plp_code_rate plp_code_rate =
 266		CXD2880_DVBT2_R1_2;
 267	int ret;
 268	static const u16 n_bch_bits_lookup[2][8] = {
 269		{7200, 9720, 10800, 11880, 12600, 13320, 5400, 6480},
 270		{32400, 38880, 43200, 48600, 51840, 54000, 21600, 25920}
 271	};
 272
 273	if (!tnrdmd || !post_bit_err || !post_bit_count)
 274		return -EINVAL;
 275
 276	if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 277		return -EINVAL;
 278
 279	if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 280		return -EINVAL;
 281
 282	if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT2)
 283		return -EINVAL;
 284
 285	ret = slvt_freeze_reg(tnrdmd);
 286	if (ret)
 287		return ret;
 288
 289	ret = tnrdmd->io->write_reg(tnrdmd->io,
 290				    CXD2880_IO_TGT_DMD,
 291				    0x00, 0x0b);
 292	if (ret) {
 293		slvt_unfreeze_reg(tnrdmd);
 294		return ret;
 295	}
 296
 297	ret = tnrdmd->io->read_regs(tnrdmd->io,
 298				    CXD2880_IO_TGT_DMD,
 299				    0x15, data, 3);
 300	if (ret) {
 301		slvt_unfreeze_reg(tnrdmd);
 302		return ret;
 303	}
 304
 305	if (!(data[0] & 0x40)) {
 306		slvt_unfreeze_reg(tnrdmd);
 307		return -EAGAIN;
 308	}
 309
 310	*post_bit_err =
 311		((data[0] & 0x3f) << 16) | (data[1] << 8) | data[2];
 312
 313	ret = tnrdmd->io->read_regs(tnrdmd->io,
 314				    CXD2880_IO_TGT_DMD,
 315				    0x9d, data, 1);
 316	if (ret) {
 317		slvt_unfreeze_reg(tnrdmd);
 318		return ret;
 319	}
 320
 321	plp_code_rate =
 322	(enum cxd2880_dvbt2_plp_code_rate)(data[0] & 0x07);
 323
 324	ret = tnrdmd->io->read_regs(tnrdmd->io,
 325				    CXD2880_IO_TGT_DMD,
 326				    0xa0, data, 1);
 327	if (ret) {
 328		slvt_unfreeze_reg(tnrdmd);
 329		return ret;
 330	}
 331
 332	plp_fec_type = (enum cxd2880_dvbt2_plp_fec)(data[0] & 0x03);
 333
 334	slvt_unfreeze_reg(tnrdmd);
 335
 336	ret = tnrdmd->io->write_reg(tnrdmd->io,
 337				    CXD2880_IO_TGT_DMD,
 338				    0x00, 0x20);
 339	if (ret)
 340		return ret;
 341
 342	ret = tnrdmd->io->read_regs(tnrdmd->io,
 343				    CXD2880_IO_TGT_DMD,
 344				    0x72, data, 1);
 345	if (ret)
 346		return ret;
 347
 348	period_exp = data[0] & 0x0f;
 349
 350	if (plp_fec_type > CXD2880_DVBT2_FEC_LDPC_64K ||
 351	    plp_code_rate > CXD2880_DVBT2_R2_5)
 352		return -EAGAIN;
 353
 354	n_bch = n_bch_bits_lookup[plp_fec_type][plp_code_rate];
 355
 356	if (*post_bit_err > ((1U << period_exp) * n_bch))
 357		return -EAGAIN;
 358
 359	*post_bit_count = (1U << period_exp) * n_bch;
 360
 361	return 0;
 362}
 363
 364static int cxd2880_read_block_err_t(struct cxd2880_tnrdmd *tnrdmd,
 365				    u32 *block_err,
 366				    u32 *block_count)
 367{
 368	u8 rdata[3];
 369	int ret;
 370
 371	if (!tnrdmd || !block_err || !block_count)
 372		return -EINVAL;
 373
 374	if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 375		return -EINVAL;
 376
 377	if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 378		return -EINVAL;
 379
 380	if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT)
 381		return -EINVAL;
 382
 383	ret = tnrdmd->io->write_reg(tnrdmd->io,
 384				    CXD2880_IO_TGT_DMD,
 385				    0x00, 0x0d);
 386	if (ret)
 387		return ret;
 388
 389	ret = tnrdmd->io->read_regs(tnrdmd->io,
 390				    CXD2880_IO_TGT_DMD,
 391				    0x18, rdata, 3);
 392	if (ret)
 393		return ret;
 394
 395	if ((rdata[0] & 0x01) == 0)
 396		return -EAGAIN;
 397
 398	*block_err = (rdata[1] << 8) | rdata[2];
 399
 400	ret = tnrdmd->io->write_reg(tnrdmd->io,
 401				    CXD2880_IO_TGT_DMD,
 402				    0x00, 0x10);
 403	if (ret)
 404		return ret;
 405
 406	ret = tnrdmd->io->read_regs(tnrdmd->io,
 407				    CXD2880_IO_TGT_DMD,
 408				    0x5c, rdata, 1);
 409	if (ret)
 410		return ret;
 411
 412	*block_count = 1U << (rdata[0] & 0x0f);
 413
 414	if ((*block_count == 0) || (*block_err > *block_count))
 415		return -EAGAIN;
 416
 417	return 0;
 418}
 419
 420static int cxd2880_read_block_err_t2(struct cxd2880_tnrdmd *tnrdmd,
 421				     u32 *block_err,
 422				     u32 *block_count)
 423{
 424	u8 rdata[3];
 425	int ret;
 426
 427	if (!tnrdmd || !block_err || !block_count)
 428		return -EINVAL;
 429
 430	if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 431		return -EINVAL;
 432
 433	if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 434		return -EINVAL;
 435	if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT2)
 436		return -EINVAL;
 437
 438	ret = tnrdmd->io->write_reg(tnrdmd->io,
 439				    CXD2880_IO_TGT_DMD,
 440				    0x00, 0x0b);
 441	if (ret)
 442		return ret;
 443
 444	ret = tnrdmd->io->read_regs(tnrdmd->io,
 445				    CXD2880_IO_TGT_DMD,
 446				    0x18, rdata, 3);
 447	if (ret)
 448		return ret;
 449
 450	if ((rdata[0] & 0x01) == 0)
 451		return -EAGAIN;
 452
 453	*block_err = (rdata[1] << 8) | rdata[2];
 454
 455	ret = tnrdmd->io->write_reg(tnrdmd->io,
 456				    CXD2880_IO_TGT_DMD,
 457				    0x00, 0x24);
 458	if (ret)
 459		return ret;
 460
 461	ret = tnrdmd->io->read_regs(tnrdmd->io,
 462				    CXD2880_IO_TGT_DMD,
 463				    0xdc, rdata, 1);
 464	if (ret)
 465		return ret;
 466
 467	*block_count = 1U << (rdata[0] & 0x0f);
 468
 469	if ((*block_count == 0) || (*block_err > *block_count))
 470		return -EAGAIN;
 471
 472	return 0;
 473}
 474
 475static void cxd2880_release(struct dvb_frontend *fe)
 476{
 477	struct cxd2880_priv *priv = NULL;
 478
 479	if (!fe) {
 480		pr_err("invalid arg.\n");
 481		return;
 482	}
 483	priv = fe->demodulator_priv;
 484	kfree(priv);
 485}
 486
 487static int cxd2880_init(struct dvb_frontend *fe)
 488{
 489	int ret;
 490	struct cxd2880_priv *priv = NULL;
 491	struct cxd2880_tnrdmd_create_param create_param;
 492
 493	if (!fe) {
 494		pr_err("invalid arg.\n");
 495		return -EINVAL;
 496	}
 497
 498	priv = fe->demodulator_priv;
 499
 500	create_param.ts_output_if = CXD2880_TNRDMD_TSOUT_IF_SPI;
 501	create_param.xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_NONE;
 502	create_param.en_internal_ldo = 1;
 503	create_param.xosc_cap = 18;
 504	create_param.xosc_i = 8;
 505	create_param.stationary_use = 1;
 506
 507	mutex_lock(priv->spi_mutex);
 508	if (priv->tnrdmd.io != &priv->regio) {
 509		ret = cxd2880_tnrdmd_create(&priv->tnrdmd,
 510					    &priv->regio, &create_param);
 511		if (ret) {
 512			mutex_unlock(priv->spi_mutex);
 513			pr_info("cxd2880 tnrdmd create failed %d\n", ret);
 514			return ret;
 515		}
 516	}
 517	ret = cxd2880_integ_init(&priv->tnrdmd);
 518	if (ret) {
 519		mutex_unlock(priv->spi_mutex);
 520		pr_err("cxd2880 integ init failed %d\n", ret);
 521		return ret;
 522	}
 523
 524	ret = cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 525				     CXD2880_TNRDMD_CFG_TSPIN_CURRENT,
 526				     0x00);
 527	if (ret) {
 528		mutex_unlock(priv->spi_mutex);
 529		pr_err("cxd2880 set config failed %d\n", ret);
 530		return ret;
 531	}
 532	mutex_unlock(priv->spi_mutex);
 533
 534	pr_debug("OK.\n");
 535
 536	return ret;
 537}
 538
 539static int cxd2880_sleep(struct dvb_frontend *fe)
 540{
 541	int ret;
 542	struct cxd2880_priv *priv = NULL;
 543
 544	if (!fe) {
 545		pr_err("invalid arg\n");
 546		return -EINVAL;
 547	}
 548
 549	priv = fe->demodulator_priv;
 550
 551	mutex_lock(priv->spi_mutex);
 552	ret = cxd2880_tnrdmd_sleep(&priv->tnrdmd);
 553	mutex_unlock(priv->spi_mutex);
 554
 555	pr_debug("tnrdmd_sleep ret %d\n", ret);
 556
 557	return ret;
 558}
 559
 560static int cxd2880_read_signal_strength(struct dvb_frontend *fe,
 561					u16 *strength)
 562{
 563	int ret;
 564	struct cxd2880_priv *priv = NULL;
 565	struct dtv_frontend_properties *c = NULL;
 566	int level = 0;
 567
 568	if (!fe || !strength) {
 569		pr_err("invalid arg\n");
 570		return -EINVAL;
 571	}
 572
 573	priv = fe->demodulator_priv;
 574	c = &fe->dtv_property_cache;
 575
 576	mutex_lock(priv->spi_mutex);
 577	if (c->delivery_system == SYS_DVBT ||
 578	    c->delivery_system == SYS_DVBT2) {
 579		ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &level);
 580	} else {
 581		pr_debug("invalid system\n");
 582		mutex_unlock(priv->spi_mutex);
 583		return -EINVAL;
 584	}
 585	mutex_unlock(priv->spi_mutex);
 586
 587	level /= 125;
 588	/*
 589	 * level should be between -105dBm and -30dBm.
 590	 * E.g. they should be between:
 591	 * -105000/125 = -840 and -30000/125 = -240
 592	 */
 593	level = clamp(level, -840, -240);
 594	/* scale value to 0x0000-0xffff */
 595	*strength = ((level + 840) * 0xffff) / (-240 + 840);
 596
 597	if (ret)
 598		pr_debug("ret = %d\n", ret);
 599
 600	return ret;
 601}
 602
 603static int cxd2880_read_snr(struct dvb_frontend *fe, u16 *snr)
 604{
 605	int ret;
 606	int snrvalue = 0;
 607	struct cxd2880_priv *priv = NULL;
 608	struct dtv_frontend_properties *c = NULL;
 609
 610	if (!fe || !snr) {
 611		pr_err("invalid arg\n");
 612		return -EINVAL;
 613	}
 614
 615	priv = fe->demodulator_priv;
 616	c = &fe->dtv_property_cache;
 617
 618	mutex_lock(priv->spi_mutex);
 619	if (c->delivery_system == SYS_DVBT) {
 620		ret = cxd2880_tnrdmd_dvbt_mon_snr(&priv->tnrdmd,
 621						  &snrvalue);
 622	} else if (c->delivery_system == SYS_DVBT2) {
 623		ret = cxd2880_tnrdmd_dvbt2_mon_snr(&priv->tnrdmd,
 624						   &snrvalue);
 625	} else {
 626		pr_err("invalid system\n");
 627		mutex_unlock(priv->spi_mutex);
 628		return -EINVAL;
 629	}
 630	mutex_unlock(priv->spi_mutex);
 631
 632	if (snrvalue < 0)
 633		snrvalue = 0;
 634	*snr = snrvalue;
 635
 636	if (ret)
 637		pr_debug("ret = %d\n", ret);
 638
 639	return ret;
 640}
 641
 642static int cxd2880_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 643{
 644	int ret;
 645	struct cxd2880_priv *priv = NULL;
 646	struct dtv_frontend_properties *c = NULL;
 647
 648	if (!fe || !ucblocks) {
 649		pr_err("invalid arg\n");
 650		return -EINVAL;
 651	}
 652
 653	priv = fe->demodulator_priv;
 654	c = &fe->dtv_property_cache;
 655
 656	mutex_lock(priv->spi_mutex);
 657	if (c->delivery_system == SYS_DVBT) {
 658		ret = cxd2880_tnrdmd_dvbt_mon_packet_error_number(&priv->tnrdmd,
 659								  ucblocks);
 660	} else if (c->delivery_system == SYS_DVBT2) {
 661		ret = cxd2880_tnrdmd_dvbt2_mon_packet_error_number(&priv->tnrdmd,
 662								   ucblocks);
 663	} else {
 664		pr_err("invalid system\n");
 665		mutex_unlock(priv->spi_mutex);
 666		return -EINVAL;
 667	}
 668	mutex_unlock(priv->spi_mutex);
 669
 670	if (ret)
 671		pr_debug("ret = %d\n", ret);
 672
 673	return ret;
 674}
 675
 676static int cxd2880_read_ber(struct dvb_frontend *fe, u32 *ber)
 677{
 678	*ber = 0;
 679
 680	return 0;
 681}
 682
 683static int cxd2880_set_ber_per_period_t(struct dvb_frontend *fe)
 684{
 685	int ret;
 686	struct cxd2880_priv *priv;
 687	struct cxd2880_dvbt_tpsinfo info;
 688	enum cxd2880_dtv_bandwidth bw;
 689	u32 pre_ber_rate = 0;
 690	u32 post_ber_rate = 0;
 691	u32 ucblock_rate = 0;
 692	u32 mes_exp = 0;
 693	static const int cr_table[5] = {31500, 42000, 47250, 52500, 55125};
 694	static const int denominator_tbl[4] = {125664, 129472, 137088, 152320};
 695
 696	if (!fe) {
 697		pr_err("invalid arg\n");
 698		return -EINVAL;
 699	}
 700
 701	priv = fe->demodulator_priv;
 702	bw = priv->dvbt_tune_param.bandwidth;
 703
 704	ret = cxd2880_tnrdmd_dvbt_mon_tps_info(&priv->tnrdmd,
 705					       &info);
 706	if (ret) {
 707		pr_err("tps monitor error ret = %d\n", ret);
 708		info.hierarchy = CXD2880_DVBT_HIERARCHY_NON;
 709		info.constellation = CXD2880_DVBT_CONSTELLATION_QPSK;
 710		info.guard = CXD2880_DVBT_GUARD_1_4;
 711		info.rate_hp = CXD2880_DVBT_CODERATE_1_2;
 712		info.rate_lp = CXD2880_DVBT_CODERATE_1_2;
 713	}
 714
 715	if (info.hierarchy == CXD2880_DVBT_HIERARCHY_NON) {
 716		pre_ber_rate = 63000000 * bw * (info.constellation * 2 + 2) /
 717			       denominator_tbl[info.guard];
 718
 719		post_ber_rate =	1000 * cr_table[info.rate_hp] * bw *
 720				(info.constellation * 2 + 2) /
 721				denominator_tbl[info.guard];
 722
 723		ucblock_rate = 875 * cr_table[info.rate_hp] * bw *
 724			       (info.constellation * 2 + 2) /
 725			       denominator_tbl[info.guard];
 726	} else {
 727		u8 data = 0;
 728		struct cxd2880_tnrdmd *tnrdmd = &priv->tnrdmd;
 729
 730		ret = tnrdmd->io->write_reg(tnrdmd->io,
 731					    CXD2880_IO_TGT_DMD,
 732					    0x00, 0x10);
 733		if (!ret) {
 734			ret = tnrdmd->io->read_regs(tnrdmd->io,
 735						    CXD2880_IO_TGT_DMD,
 736						    0x67, &data, 1);
 737			if (ret)
 738				data = 0x00;
 739		} else {
 740			data = 0x00;
 741		}
 742
 743		if (data & 0x01) { /* Low priority */
 744			pre_ber_rate =
 745				63000000 * bw * (info.constellation * 2 + 2) /
 746				denominator_tbl[info.guard];
 747
 748			post_ber_rate = 1000 * cr_table[info.rate_lp] * bw *
 749					(info.constellation * 2 + 2) /
 750					denominator_tbl[info.guard];
 751
 752			ucblock_rate = (1000 * 7 / 8) *	cr_table[info.rate_lp] *
 753				       bw * (info.constellation * 2 + 2) /
 754				       denominator_tbl[info.guard];
 755		} else { /* High priority */
 756			pre_ber_rate =
 757				63000000 * bw * 2 / denominator_tbl[info.guard];
 758
 759			post_ber_rate = 1000 * cr_table[info.rate_hp] * bw * 2 /
 760					denominator_tbl[info.guard];
 761
 762			ucblock_rate = (1000 * 7 / 8) * cr_table[info.rate_hp] *
 763					bw * 2 / denominator_tbl[info.guard];
 764		}
 765	}
 766
 767	mes_exp = pre_ber_rate < 8192 ? 8 : intlog2(pre_ber_rate) >> 24;
 768	priv->pre_ber_interval =
 769		((1U << mes_exp) * 1000 + (pre_ber_rate / 2)) /
 770		pre_ber_rate;
 771	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 772			       CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD,
 773			       mes_exp == 8 ? 0 : mes_exp - 12);
 774
 775	mes_exp = intlog2(post_ber_rate) >> 24;
 776	priv->post_ber_interval =
 777		((1U << mes_exp) * 1000 + (post_ber_rate / 2)) /
 778		post_ber_rate;
 779	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 780			       CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD,
 781			       mes_exp);
 782
 783	mes_exp = intlog2(ucblock_rate) >> 24;
 784	priv->ucblock_interval =
 785		((1U << mes_exp) * 1000 + (ucblock_rate / 2)) /
 786		ucblock_rate;
 787	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 788			       CXD2880_TNRDMD_CFG_DVBT_PER_MES,
 789			       mes_exp);
 790
 791	return 0;
 792}
 793
 794static int cxd2880_set_ber_per_period_t2(struct dvb_frontend *fe)
 795{
 796	int ret;
 797	struct cxd2880_priv *priv;
 798	struct cxd2880_dvbt2_l1pre l1pre;
 799	struct cxd2880_dvbt2_l1post l1post;
 800	struct cxd2880_dvbt2_plp plp;
 801	struct cxd2880_dvbt2_bbheader bbheader;
 802	enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ;
 803	u32 pre_ber_rate = 0;
 804	u32 post_ber_rate = 0;
 805	u32 ucblock_rate = 0;
 806	u32 mes_exp = 0;
 807	u32 term_a = 0;
 808	u32 term_b = 0;
 809	u32 denominator = 0;
 810	static const u32 gi_tbl[7] = {32, 64, 128, 256, 8, 152, 76};
 811	static const u8 n_tbl[6] = {8, 2, 4, 16, 1, 1};
 812	static const u8 mode_tbl[6] = {2, 8, 4, 1, 16, 32};
 813	static const u32 kbch_tbl[2][8] = {
 814		{6952, 9472, 10552, 11632, 12352, 13072, 5152, 6232},
 815		{32128, 38608, 42960, 48328, 51568, 53760, 0, 0}
 816	};
 817
 818	if (!fe) {
 819		pr_err("invalid arg\n");
 820		return -EINVAL;
 821	}
 822
 823	priv = fe->demodulator_priv;
 824	bw = priv->dvbt2_tune_param.bandwidth;
 825
 826	ret = cxd2880_tnrdmd_dvbt2_mon_l1_pre(&priv->tnrdmd, &l1pre);
 827	if (ret) {
 828		pr_info("l1 pre error\n");
 829		goto error_ber_setting;
 830	}
 831
 832	ret = cxd2880_tnrdmd_dvbt2_mon_active_plp(&priv->tnrdmd,
 833						  CXD2880_DVBT2_PLP_DATA, &plp);
 834	if (ret) {
 835		pr_info("plp info error\n");
 836		goto error_ber_setting;
 837	}
 838
 839	ret = cxd2880_tnrdmd_dvbt2_mon_l1_post(&priv->tnrdmd, &l1post);
 840	if (ret) {
 841		pr_info("l1 post error\n");
 842		goto error_ber_setting;
 843	}
 844
 845	term_a =
 846		(mode_tbl[l1pre.fft_mode] * (1024 + gi_tbl[l1pre.gi])) *
 847		(l1pre.num_symbols + n_tbl[l1pre.fft_mode]) + 2048;
 848
 849	if (l1pre.mixed && l1post.fef_intvl) {
 850		term_b = (l1post.fef_length + (l1post.fef_intvl / 2)) /
 851			 l1post.fef_intvl;
 852	} else {
 853		term_b = 0;
 854	}
 855
 856	switch (bw) {
 857	case CXD2880_DTV_BW_1_7_MHZ:
 858		denominator = ((term_a + term_b) * 71 + (131 / 2)) / 131;
 859		break;
 860	case CXD2880_DTV_BW_5_MHZ:
 861		denominator = ((term_a + term_b) * 7 + 20) / 40;
 862		break;
 863	case CXD2880_DTV_BW_6_MHZ:
 864		denominator = ((term_a + term_b) * 7 + 24) / 48;
 865		break;
 866	case CXD2880_DTV_BW_7_MHZ:
 867		denominator = ((term_a + term_b) + 4) / 8;
 868		break;
 869	case CXD2880_DTV_BW_8_MHZ:
 870	default:
 871		denominator = ((term_a + term_b) * 7 + 32) / 64;
 872		break;
 873	}
 874
 875	if (plp.til_type && plp.til_len) {
 876		pre_ber_rate =
 877			(plp.num_blocks_max * 1000000 + (denominator / 2)) /
 878			denominator;
 879		pre_ber_rate = (pre_ber_rate + (plp.til_len / 2)) /
 880			       plp.til_len;
 881	} else {
 882		pre_ber_rate =
 883			(plp.num_blocks_max * 1000000 + (denominator / 2)) /
 884			denominator;
 885	}
 886
 887	post_ber_rate = pre_ber_rate;
 888
 889	mes_exp = intlog2(pre_ber_rate) >> 24;
 890	priv->pre_ber_interval =
 891		((1U << mes_exp) * 1000 + (pre_ber_rate / 2)) /
 892		pre_ber_rate;
 893	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 894			       CXD2880_TNRDMD_CFG_DVBT2_LBER_MES,
 895			       mes_exp);
 896
 897	mes_exp = intlog2(post_ber_rate) >> 24;
 898	priv->post_ber_interval =
 899		((1U << mes_exp) * 1000 + (post_ber_rate / 2)) /
 900		post_ber_rate;
 901	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 902			       CXD2880_TNRDMD_CFG_DVBT2_BBER_MES,
 903			       mes_exp);
 904
 905	ret = cxd2880_tnrdmd_dvbt2_mon_bbheader(&priv->tnrdmd,
 906						CXD2880_DVBT2_PLP_DATA,
 907						&bbheader);
 908	if (ret) {
 909		pr_info("bb header error\n");
 910		goto error_ucblock_setting;
 911	}
 912
 913	if (bbheader.plp_mode == CXD2880_DVBT2_PLP_MODE_NM) {
 914		if (!bbheader.issy_indicator) {
 915			ucblock_rate =
 916				(pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] +
 917				752) / 1504;
 918		} else {
 919			ucblock_rate =
 920				(pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] +
 921				764) / 1528;
 922		}
 923	} else if (bbheader.plp_mode == CXD2880_DVBT2_PLP_MODE_HEM) {
 924		ucblock_rate =
 925			(pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] + 748) /
 926			1496;
 927	} else {
 928		pr_info("plp mode is not Normal or HEM\n");
 929		goto error_ucblock_setting;
 930	}
 931
 932	mes_exp = intlog2(ucblock_rate) >> 24;
 933	priv->ucblock_interval =
 934		((1U << mes_exp) * 1000 + (ucblock_rate / 2)) /
 935		ucblock_rate;
 936	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 937			       CXD2880_TNRDMD_CFG_DVBT2_PER_MES,
 938			       mes_exp);
 939
 940	return 0;
 941
 942error_ber_setting:
 943	priv->pre_ber_interval = 1000;
 944	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 945				     CXD2880_TNRDMD_CFG_DVBT2_LBER_MES, 0);
 946
 947	priv->post_ber_interval = 1000;
 948	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 949			       CXD2880_TNRDMD_CFG_DVBT2_BBER_MES, 0);
 950
 951error_ucblock_setting:
 952	priv->ucblock_interval = 1000;
 953	cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
 954			       CXD2880_TNRDMD_CFG_DVBT2_PER_MES, 8);
 955
 956	return 0;
 957}
 958
 959static int cxd2880_dvbt_tune(struct cxd2880_tnrdmd *tnr_dmd,
 960			     struct cxd2880_dvbt_tune_param
 961			     *tune_param)
 962{
 963	int ret;
 964
 965	if (!tnr_dmd || !tune_param)
 966		return -EINVAL;
 967
 968	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 969		return -EINVAL;
 970
 971	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
 972	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 973		return -EINVAL;
 974
 975	atomic_set(&tnr_dmd->cancel, 0);
 976
 977	if (tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ &&
 978	    tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ &&
 979	    tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ &&
 980	    tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ) {
 981		return -ENOTTY;
 982	}
 983
 984	ret = cxd2880_tnrdmd_dvbt_tune1(tnr_dmd, tune_param);
 985	if (ret)
 986		return ret;
 987
 988	usleep_range(CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000,
 989		     CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000 + 1000);
 990
 991	return cxd2880_tnrdmd_dvbt_tune2(tnr_dmd, tune_param);
 992}
 993
 994static int cxd2880_dvbt2_tune(struct cxd2880_tnrdmd *tnr_dmd,
 995			      struct cxd2880_dvbt2_tune_param
 996			      *tune_param)
 997{
 998	int ret;
 999
1000	if (!tnr_dmd || !tune_param)
1001		return -EINVAL;
1002
1003	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
1004		return -EINVAL;
1005
1006	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
1007	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
1008		return -EINVAL;
1009
1010	atomic_set(&tnr_dmd->cancel, 0);
1011
1012	if (tune_param->bandwidth != CXD2880_DTV_BW_1_7_MHZ &&
1013	    tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ &&
1014	    tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ &&
1015	    tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ &&
1016	    tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ) {
1017		return -ENOTTY;
1018	}
1019
1020	if (tune_param->profile != CXD2880_DVBT2_PROFILE_BASE &&
1021	    tune_param->profile != CXD2880_DVBT2_PROFILE_LITE)
1022		return -EINVAL;
1023
1024	ret = cxd2880_tnrdmd_dvbt2_tune1(tnr_dmd, tune_param);
1025	if (ret)
1026		return ret;
1027
1028	usleep_range(CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000,
1029		     CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000 + 1000);
1030
1031	return cxd2880_tnrdmd_dvbt2_tune2(tnr_dmd, tune_param);
1032}
1033
1034static int cxd2880_set_frontend(struct dvb_frontend *fe)
1035{
1036	int ret;
1037	struct dtv_frontend_properties *c;
1038	struct cxd2880_priv *priv;
1039	enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ;
1040
1041	if (!fe) {
1042		pr_err("invalid arg\n");
1043		return -EINVAL;
1044	}
1045
1046	priv = fe->demodulator_priv;
1047	c = &fe->dtv_property_cache;
1048
1049	c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1050	c->pre_bit_error.stat[0].uvalue = 0;
1051	c->pre_bit_error.len = 1;
1052	c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1053	c->pre_bit_count.stat[0].uvalue = 0;
1054	c->pre_bit_count.len = 1;
1055	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1056	c->post_bit_error.stat[0].uvalue = 0;
1057	c->post_bit_error.len = 1;
1058	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1059	c->post_bit_count.stat[0].uvalue = 0;
1060	c->post_bit_count.len = 1;
1061	c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1062	c->block_error.stat[0].uvalue = 0;
1063	c->block_error.len = 1;
1064	c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1065	c->block_count.stat[0].uvalue = 0;
1066	c->block_count.len = 1;
1067
1068	switch (c->bandwidth_hz) {
1069	case 1712000:
1070		bw = CXD2880_DTV_BW_1_7_MHZ;
1071		break;
1072	case 5000000:
1073		bw = CXD2880_DTV_BW_5_MHZ;
1074		break;
1075	case 6000000:
1076		bw = CXD2880_DTV_BW_6_MHZ;
1077		break;
1078	case 7000000:
1079		bw = CXD2880_DTV_BW_7_MHZ;
1080		break;
1081	case 8000000:
1082		bw = CXD2880_DTV_BW_8_MHZ;
1083		break;
1084	default:
1085		return -EINVAL;
1086	}
1087
1088	priv->s = 0;
1089
1090	pr_info("sys:%d freq:%d bw:%d\n",
1091		c->delivery_system, c->frequency, bw);
1092	mutex_lock(priv->spi_mutex);
1093	if (c->delivery_system == SYS_DVBT) {
1094		priv->tnrdmd.sys = CXD2880_DTV_SYS_DVBT;
1095		priv->dvbt_tune_param.center_freq_khz = c->frequency / 1000;
1096		priv->dvbt_tune_param.bandwidth = bw;
1097		priv->dvbt_tune_param.profile = CXD2880_DVBT_PROFILE_HP;
1098		ret = cxd2880_dvbt_tune(&priv->tnrdmd,
1099					&priv->dvbt_tune_param);
1100	} else if (c->delivery_system == SYS_DVBT2) {
1101		priv->tnrdmd.sys = CXD2880_DTV_SYS_DVBT2;
1102		priv->dvbt2_tune_param.center_freq_khz = c->frequency / 1000;
1103		priv->dvbt2_tune_param.bandwidth = bw;
1104		priv->dvbt2_tune_param.data_plp_id = (u16)c->stream_id;
1105		priv->dvbt2_tune_param.profile = CXD2880_DVBT2_PROFILE_BASE;
1106		ret = cxd2880_dvbt2_tune(&priv->tnrdmd,
1107					 &priv->dvbt2_tune_param);
1108	} else {
1109		pr_err("invalid system\n");
1110		mutex_unlock(priv->spi_mutex);
1111		return -EINVAL;
1112	}
1113	mutex_unlock(priv->spi_mutex);
1114
1115	pr_info("tune result %d\n", ret);
1116
1117	return ret;
1118}
1119
1120static int cxd2880_get_stats(struct dvb_frontend *fe,
1121			     enum fe_status status)
1122{
1123	struct cxd2880_priv *priv = NULL;
1124	struct dtv_frontend_properties *c = NULL;
1125	u32 pre_bit_err = 0, pre_bit_count = 0;
1126	u32 post_bit_err = 0, post_bit_count = 0;
1127	u32 block_err = 0, block_count = 0;
1128	int ret;
1129
1130	if (!fe) {
1131		pr_err("invalid arg\n");
1132		return -EINVAL;
1133	}
1134
1135	priv = fe->demodulator_priv;
1136	c = &fe->dtv_property_cache;
1137
1138	if (!(status & FE_HAS_LOCK) || !(status & FE_HAS_CARRIER)) {
1139		c->pre_bit_error.len = 1;
1140		c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1141		c->pre_bit_count.len = 1;
1142		c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1143		c->post_bit_error.len = 1;
1144		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1145		c->post_bit_count.len = 1;
1146		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1147		c->block_error.len = 1;
1148		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1149		c->block_count.len = 1;
1150		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1151
1152		return 0;
1153	}
1154
1155	if (time_after(jiffies, priv->pre_ber_update)) {
1156		priv->pre_ber_update =
1157			 jiffies + msecs_to_jiffies(priv->pre_ber_interval);
1158		if (c->delivery_system == SYS_DVBT) {
1159			mutex_lock(priv->spi_mutex);
1160			ret = cxd2880_pre_bit_err_t(&priv->tnrdmd,
1161						    &pre_bit_err,
1162						    &pre_bit_count);
1163			mutex_unlock(priv->spi_mutex);
1164		} else if (c->delivery_system == SYS_DVBT2) {
1165			mutex_lock(priv->spi_mutex);
1166			ret = cxd2880_pre_bit_err_t2(&priv->tnrdmd,
1167						     &pre_bit_err,
1168						     &pre_bit_count);
1169			mutex_unlock(priv->spi_mutex);
1170		} else {
1171			return -EINVAL;
1172		}
1173
1174		if (!ret) {
1175			c->pre_bit_error.len = 1;
1176			c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1177			c->pre_bit_error.stat[0].uvalue += pre_bit_err;
1178			c->pre_bit_count.len = 1;
1179			c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1180			c->pre_bit_count.stat[0].uvalue += pre_bit_count;
1181		} else {
1182			c->pre_bit_error.len = 1;
1183			c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1184			c->pre_bit_count.len = 1;
1185			c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1186			pr_debug("pre_bit_error_t failed %d\n", ret);
1187		}
1188	}
1189
1190	if (time_after(jiffies, priv->post_ber_update)) {
1191		priv->post_ber_update =
1192			jiffies + msecs_to_jiffies(priv->post_ber_interval);
1193		if (c->delivery_system == SYS_DVBT) {
1194			mutex_lock(priv->spi_mutex);
1195			ret = cxd2880_post_bit_err_t(&priv->tnrdmd,
1196						     &post_bit_err,
1197						     &post_bit_count);
1198			mutex_unlock(priv->spi_mutex);
1199		} else if (c->delivery_system == SYS_DVBT2) {
1200			mutex_lock(priv->spi_mutex);
1201			ret = cxd2880_post_bit_err_t2(&priv->tnrdmd,
1202						      &post_bit_err,
1203						      &post_bit_count);
1204			mutex_unlock(priv->spi_mutex);
1205		} else {
1206			return -EINVAL;
1207		}
1208
1209		if (!ret) {
1210			c->post_bit_error.len = 1;
1211			c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1212			c->post_bit_error.stat[0].uvalue += post_bit_err;
1213			c->post_bit_count.len = 1;
1214			c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1215			c->post_bit_count.stat[0].uvalue += post_bit_count;
1216		} else {
1217			c->post_bit_error.len = 1;
1218			c->post_bit_error.stat[0].scale =
1219							FE_SCALE_NOT_AVAILABLE;
1220			c->post_bit_count.len = 1;
1221			c->post_bit_count.stat[0].scale =
1222							FE_SCALE_NOT_AVAILABLE;
1223			pr_debug("post_bit_err_t %d\n", ret);
1224		}
1225	}
1226
1227	if (time_after(jiffies, priv->ucblock_update)) {
1228		priv->ucblock_update =
1229			jiffies + msecs_to_jiffies(priv->ucblock_interval);
1230		if (c->delivery_system == SYS_DVBT) {
1231			mutex_lock(priv->spi_mutex);
1232			ret = cxd2880_read_block_err_t(&priv->tnrdmd,
1233						       &block_err,
1234						       &block_count);
1235			mutex_unlock(priv->spi_mutex);
1236		} else if (c->delivery_system == SYS_DVBT2) {
1237			mutex_lock(priv->spi_mutex);
1238			ret = cxd2880_read_block_err_t2(&priv->tnrdmd,
1239							&block_err,
1240							&block_count);
1241			mutex_unlock(priv->spi_mutex);
1242		} else {
1243			return -EINVAL;
1244		}
1245		if (!ret) {
1246			c->block_error.len = 1;
1247			c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1248			c->block_error.stat[0].uvalue += block_err;
1249			c->block_count.len = 1;
1250			c->block_count.stat[0].scale = FE_SCALE_COUNTER;
1251			c->block_count.stat[0].uvalue += block_count;
1252		} else {
1253			c->block_error.len = 1;
1254			c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1255			c->block_count.len = 1;
1256			c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1257			pr_debug("read_block_err_t  %d\n", ret);
1258		}
1259	}
1260
1261	return 0;
1262}
1263
1264static int cxd2880_check_l1post_plp(struct dvb_frontend *fe)
1265{
1266	u8 valid = 0;
1267	u8 plp_not_found;
1268	int ret;
1269	struct cxd2880_priv *priv = NULL;
1270
1271	if (!fe) {
1272		pr_err("invalid arg\n");
1273		return -EINVAL;
1274	}
1275
1276	priv = fe->demodulator_priv;
1277
1278	ret = cxd2880_tnrdmd_dvbt2_check_l1post_valid(&priv->tnrdmd,
1279						      &valid);
1280	if (ret)
1281		return ret;
1282
1283	if (!valid)
1284		return -EAGAIN;
1285
1286	ret = cxd2880_tnrdmd_dvbt2_mon_data_plp_error(&priv->tnrdmd,
1287						      &plp_not_found);
1288	if (ret)
1289		return ret;
1290
1291	if (plp_not_found) {
1292		priv->dvbt2_tune_param.tune_info =
1293			CXD2880_TNRDMD_DVBT2_TUNE_INFO_INVALID_PLP_ID;
1294	} else {
1295		priv->dvbt2_tune_param.tune_info =
1296			CXD2880_TNRDMD_DVBT2_TUNE_INFO_OK;
1297	}
1298
1299	return 0;
1300}
1301
1302static int cxd2880_read_status(struct dvb_frontend *fe,
1303			       enum fe_status *status)
1304{
1305	int ret;
1306	u8 sync = 0;
1307	u8 lock = 0;
1308	u8 unlock = 0;
1309	struct cxd2880_priv *priv = NULL;
1310	struct dtv_frontend_properties *c = NULL;
1311
1312	if (!fe || !status) {
1313		pr_err("invalid arg\n");
1314		return -EINVAL;
1315	}
1316
1317	priv = fe->demodulator_priv;
1318	c = &fe->dtv_property_cache;
1319	*status = 0;
1320
1321	if (priv->tnrdmd.state == CXD2880_TNRDMD_STATE_ACTIVE) {
1322		mutex_lock(priv->spi_mutex);
1323		if (c->delivery_system == SYS_DVBT) {
1324			ret = cxd2880_tnrdmd_dvbt_mon_sync_stat(&priv->tnrdmd,
1325								&sync,
1326								&lock,
1327								&unlock);
1328		} else if (c->delivery_system == SYS_DVBT2) {
1329			ret = cxd2880_tnrdmd_dvbt2_mon_sync_stat(&priv->tnrdmd,
1330								 &sync,
1331								 &lock,
1332								 &unlock);
1333		} else {
1334			pr_err("invalid system");
1335			mutex_unlock(priv->spi_mutex);
1336			return -EINVAL;
1337		}
1338
1339		mutex_unlock(priv->spi_mutex);
1340		if (ret) {
1341			pr_err("failed. sys = %d\n", priv->tnrdmd.sys);
1342			return  ret;
1343		}
1344
1345		if (sync == 6) {
1346			*status = FE_HAS_SIGNAL |
1347				  FE_HAS_CARRIER;
1348		}
1349		if (lock)
1350			*status |= FE_HAS_VITERBI |
1351				   FE_HAS_SYNC |
1352				   FE_HAS_LOCK;
1353	}
1354
1355	pr_debug("status %d\n", *status);
1356
1357	if (priv->s == 0 && (*status & FE_HAS_LOCK) &&
1358	    (*status & FE_HAS_CARRIER)) {
1359		mutex_lock(priv->spi_mutex);
1360		if (c->delivery_system == SYS_DVBT) {
1361			ret = cxd2880_set_ber_per_period_t(fe);
1362			priv->s = *status;
1363		} else if (c->delivery_system == SYS_DVBT2) {
1364			ret = cxd2880_check_l1post_plp(fe);
1365			if (!ret) {
1366				ret = cxd2880_set_ber_per_period_t2(fe);
1367				priv->s = *status;
1368			}
1369		} else {
1370			pr_err("invalid system\n");
1371			mutex_unlock(priv->spi_mutex);
1372			return -EINVAL;
1373		}
1374		mutex_unlock(priv->spi_mutex);
1375	}
1376
1377	cxd2880_get_stats(fe, *status);
1378	return  0;
1379}
1380
1381static int cxd2880_tune(struct dvb_frontend *fe,
1382			bool retune,
1383			unsigned int mode_flags,
1384			unsigned int *delay,
1385			enum fe_status *status)
1386{
1387	int ret;
1388
1389	if (!fe || !delay || !status) {
1390		pr_err("invalid arg.");
1391		return -EINVAL;
1392	}
1393
1394	if (retune) {
1395		ret = cxd2880_set_frontend(fe);
1396		if (ret) {
1397			pr_err("cxd2880_set_frontend failed %d\n", ret);
1398			return ret;
1399		}
1400	}
1401
1402	*delay = HZ / 5;
1403
1404	return cxd2880_read_status(fe, status);
1405}
1406
1407static int cxd2880_get_frontend_t(struct dvb_frontend *fe,
1408				  struct dtv_frontend_properties *c)
1409{
1410	int ret;
1411	struct cxd2880_priv *priv = NULL;
1412	enum cxd2880_dvbt_mode mode = CXD2880_DVBT_MODE_2K;
1413	enum cxd2880_dvbt_guard guard = CXD2880_DVBT_GUARD_1_32;
1414	struct cxd2880_dvbt_tpsinfo tps;
1415	enum cxd2880_tnrdmd_spectrum_sense sense;
1416	u16 snr = 0;
1417	int strength = 0;
1418
1419	if (!fe || !c) {
1420		pr_err("invalid arg\n");
1421		return -EINVAL;
1422	}
1423
1424	priv = fe->demodulator_priv;
1425
1426	mutex_lock(priv->spi_mutex);
1427	ret = cxd2880_tnrdmd_dvbt_mon_mode_guard(&priv->tnrdmd,
1428						 &mode, &guard);
1429	mutex_unlock(priv->spi_mutex);
1430	if (!ret) {
1431		switch (mode) {
1432		case CXD2880_DVBT_MODE_2K:
1433			c->transmission_mode = TRANSMISSION_MODE_2K;
1434			break;
1435		case CXD2880_DVBT_MODE_8K:
1436			c->transmission_mode = TRANSMISSION_MODE_8K;
1437			break;
1438		default:
1439			c->transmission_mode = TRANSMISSION_MODE_2K;
1440			pr_debug("transmission mode is invalid %d\n", mode);
1441			break;
1442		}
1443		switch (guard) {
1444		case CXD2880_DVBT_GUARD_1_32:
1445			c->guard_interval = GUARD_INTERVAL_1_32;
1446			break;
1447		case CXD2880_DVBT_GUARD_1_16:
1448			c->guard_interval = GUARD_INTERVAL_1_16;
1449			break;
1450		case CXD2880_DVBT_GUARD_1_8:
1451			c->guard_interval = GUARD_INTERVAL_1_8;
1452			break;
1453		case CXD2880_DVBT_GUARD_1_4:
1454			c->guard_interval = GUARD_INTERVAL_1_4;
1455			break;
1456		default:
1457			c->guard_interval = GUARD_INTERVAL_1_32;
1458			pr_debug("guard interval is invalid %d\n",
1459				 guard);
1460			break;
1461		}
1462	} else {
1463		c->transmission_mode = TRANSMISSION_MODE_2K;
1464		c->guard_interval = GUARD_INTERVAL_1_32;
1465		pr_debug("ModeGuard err %d\n", ret);
1466	}
1467
1468	mutex_lock(priv->spi_mutex);
1469	ret = cxd2880_tnrdmd_dvbt_mon_tps_info(&priv->tnrdmd, &tps);
1470	mutex_unlock(priv->spi_mutex);
1471	if (!ret) {
1472		switch (tps.hierarchy) {
1473		case CXD2880_DVBT_HIERARCHY_NON:
1474			c->hierarchy = HIERARCHY_NONE;
1475			break;
1476		case CXD2880_DVBT_HIERARCHY_1:
1477			c->hierarchy = HIERARCHY_1;
1478			break;
1479		case CXD2880_DVBT_HIERARCHY_2:
1480			c->hierarchy = HIERARCHY_2;
1481			break;
1482		case CXD2880_DVBT_HIERARCHY_4:
1483			c->hierarchy = HIERARCHY_4;
1484			break;
1485		default:
1486			c->hierarchy = HIERARCHY_NONE;
1487			pr_debug("TPSInfo hierarchy is invalid %d\n",
1488				 tps.hierarchy);
1489			break;
1490		}
1491
1492		switch (tps.rate_hp) {
1493		case CXD2880_DVBT_CODERATE_1_2:
1494			c->code_rate_HP = FEC_1_2;
1495			break;
1496		case CXD2880_DVBT_CODERATE_2_3:
1497			c->code_rate_HP = FEC_2_3;
1498			break;
1499		case CXD2880_DVBT_CODERATE_3_4:
1500			c->code_rate_HP = FEC_3_4;
1501			break;
1502		case CXD2880_DVBT_CODERATE_5_6:
1503			c->code_rate_HP = FEC_5_6;
1504			break;
1505		case CXD2880_DVBT_CODERATE_7_8:
1506			c->code_rate_HP = FEC_7_8;
1507			break;
1508		default:
1509			c->code_rate_HP = FEC_NONE;
1510			pr_debug("TPSInfo rateHP is invalid %d\n",
1511				 tps.rate_hp);
1512			break;
1513		}
1514		switch (tps.rate_lp) {
1515		case CXD2880_DVBT_CODERATE_1_2:
1516			c->code_rate_LP = FEC_1_2;
1517			break;
1518		case CXD2880_DVBT_CODERATE_2_3:
1519			c->code_rate_LP = FEC_2_3;
1520			break;
1521		case CXD2880_DVBT_CODERATE_3_4:
1522			c->code_rate_LP = FEC_3_4;
1523			break;
1524		case CXD2880_DVBT_CODERATE_5_6:
1525			c->code_rate_LP = FEC_5_6;
1526			break;
1527		case CXD2880_DVBT_CODERATE_7_8:
1528			c->code_rate_LP = FEC_7_8;
1529			break;
1530		default:
1531			c->code_rate_LP = FEC_NONE;
1532			pr_debug("TPSInfo rateLP is invalid %d\n",
1533				 tps.rate_lp);
1534			break;
1535		}
1536		switch (tps.constellation) {
1537		case CXD2880_DVBT_CONSTELLATION_QPSK:
1538			c->modulation = QPSK;
1539			break;
1540		case CXD2880_DVBT_CONSTELLATION_16QAM:
1541			c->modulation = QAM_16;
1542			break;
1543		case CXD2880_DVBT_CONSTELLATION_64QAM:
1544			c->modulation = QAM_64;
1545			break;
1546		default:
1547			c->modulation = QPSK;
1548			pr_debug("TPSInfo constellation is invalid %d\n",
1549				 tps.constellation);
1550			break;
1551		}
1552	} else {
1553		c->hierarchy = HIERARCHY_NONE;
1554		c->code_rate_HP = FEC_NONE;
1555		c->code_rate_LP = FEC_NONE;
1556		c->modulation = QPSK;
1557		pr_debug("TPS info err %d\n", ret);
1558	}
1559
1560	mutex_lock(priv->spi_mutex);
1561	ret = cxd2880_tnrdmd_dvbt_mon_spectrum_sense(&priv->tnrdmd, &sense);
1562	mutex_unlock(priv->spi_mutex);
1563	if (!ret) {
1564		switch (sense) {
1565		case CXD2880_TNRDMD_SPECTRUM_NORMAL:
1566			c->inversion = INVERSION_OFF;
1567			break;
1568		case CXD2880_TNRDMD_SPECTRUM_INV:
1569			c->inversion = INVERSION_ON;
1570			break;
1571		default:
1572			c->inversion = INVERSION_OFF;
1573			pr_debug("spectrum sense is invalid %d\n", sense);
1574			break;
1575		}
1576	} else {
1577		c->inversion = INVERSION_OFF;
1578		pr_debug("spectrum_sense %d\n", ret);
1579	}
1580
1581	mutex_lock(priv->spi_mutex);
1582	ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &strength);
1583	mutex_unlock(priv->spi_mutex);
1584	if (!ret) {
1585		c->strength.len = 1;
1586		c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1587		c->strength.stat[0].svalue = strength;
1588	} else {
1589		c->strength.len = 1;
1590		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1591		pr_debug("mon_rf_lvl %d\n", ret);
1592	}
1593
1594	ret = cxd2880_read_snr(fe, &snr);
1595	if (!ret) {
1596		c->cnr.len = 1;
1597		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1598		c->cnr.stat[0].svalue = snr;
1599	} else {
1600		c->cnr.len = 1;
1601		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1602		pr_debug("read_snr %d\n", ret);
1603	}
1604
1605	return 0;
1606}
1607
1608static int cxd2880_get_frontend_t2(struct dvb_frontend *fe,
1609				   struct dtv_frontend_properties *c)
1610{
1611	int ret;
1612	struct cxd2880_priv *priv = NULL;
1613	struct cxd2880_dvbt2_l1pre l1pre;
1614	enum cxd2880_dvbt2_plp_code_rate coderate;
1615	enum cxd2880_dvbt2_plp_constell qam;
1616	enum cxd2880_tnrdmd_spectrum_sense sense;
1617	u16 snr = 0;
1618	int strength = 0;
1619
1620	if (!fe || !c) {
1621		pr_err("invalid arg.\n");
1622		return -EINVAL;
1623	}
1624
1625	priv = fe->demodulator_priv;
1626
1627	mutex_lock(priv->spi_mutex);
1628	ret = cxd2880_tnrdmd_dvbt2_mon_l1_pre(&priv->tnrdmd, &l1pre);
1629	mutex_unlock(priv->spi_mutex);
1630	if (!ret) {
1631		switch (l1pre.fft_mode) {
1632		case CXD2880_DVBT2_M2K:
1633			c->transmission_mode = TRANSMISSION_MODE_2K;
1634			break;
1635		case CXD2880_DVBT2_M8K:
1636			c->transmission_mode = TRANSMISSION_MODE_8K;
1637			break;
1638		case CXD2880_DVBT2_M4K:
1639			c->transmission_mode = TRANSMISSION_MODE_4K;
1640			break;
1641		case CXD2880_DVBT2_M1K:
1642			c->transmission_mode = TRANSMISSION_MODE_1K;
1643			break;
1644		case CXD2880_DVBT2_M16K:
1645			c->transmission_mode = TRANSMISSION_MODE_16K;
1646			break;
1647		case CXD2880_DVBT2_M32K:
1648			c->transmission_mode = TRANSMISSION_MODE_32K;
1649			break;
1650		default:
1651			c->transmission_mode = TRANSMISSION_MODE_2K;
1652			pr_debug("L1Pre fft_mode is invalid %d\n",
1653				 l1pre.fft_mode);
1654			break;
1655		}
1656		switch (l1pre.gi) {
1657		case CXD2880_DVBT2_G1_32:
1658			c->guard_interval = GUARD_INTERVAL_1_32;
1659			break;
1660		case CXD2880_DVBT2_G1_16:
1661			c->guard_interval = GUARD_INTERVAL_1_16;
1662			break;
1663		case CXD2880_DVBT2_G1_8:
1664			c->guard_interval = GUARD_INTERVAL_1_8;
1665			break;
1666		case CXD2880_DVBT2_G1_4:
1667			c->guard_interval = GUARD_INTERVAL_1_4;
1668			break;
1669		case CXD2880_DVBT2_G1_128:
1670			c->guard_interval = GUARD_INTERVAL_1_128;
1671			break;
1672		case CXD2880_DVBT2_G19_128:
1673			c->guard_interval = GUARD_INTERVAL_19_128;
1674			break;
1675		case CXD2880_DVBT2_G19_256:
1676			c->guard_interval = GUARD_INTERVAL_19_256;
1677			break;
1678		default:
1679			c->guard_interval = GUARD_INTERVAL_1_32;
1680			pr_debug("L1Pre guard interval is invalid %d\n",
1681				 l1pre.gi);
1682			break;
1683		}
1684	} else {
1685		c->transmission_mode = TRANSMISSION_MODE_2K;
1686		c->guard_interval = GUARD_INTERVAL_1_32;
1687		pr_debug("L1Pre err %d\n", ret);
1688	}
1689
1690	mutex_lock(priv->spi_mutex);
1691	ret = cxd2880_tnrdmd_dvbt2_mon_code_rate(&priv->tnrdmd,
1692						 CXD2880_DVBT2_PLP_DATA,
1693						 &coderate);
1694	mutex_unlock(priv->spi_mutex);
1695	if (!ret) {
1696		switch (coderate) {
1697		case CXD2880_DVBT2_R1_2:
1698			c->fec_inner = FEC_1_2;
1699			break;
1700		case CXD2880_DVBT2_R3_5:
1701			c->fec_inner = FEC_3_5;
1702			break;
1703		case CXD2880_DVBT2_R2_3:
1704			c->fec_inner = FEC_2_3;
1705			break;
1706		case CXD2880_DVBT2_R3_4:
1707			c->fec_inner = FEC_3_4;
1708			break;
1709		case CXD2880_DVBT2_R4_5:
1710			c->fec_inner = FEC_4_5;
1711			break;
1712		case CXD2880_DVBT2_R5_6:
1713			c->fec_inner = FEC_5_6;
1714			break;
1715		default:
1716			c->fec_inner = FEC_NONE;
1717			pr_debug("CodeRate is invalid %d\n", coderate);
1718			break;
1719		}
1720	} else {
1721		c->fec_inner = FEC_NONE;
1722		pr_debug("CodeRate %d\n", ret);
1723	}
1724
1725	mutex_lock(priv->spi_mutex);
1726	ret = cxd2880_tnrdmd_dvbt2_mon_qam(&priv->tnrdmd,
1727					   CXD2880_DVBT2_PLP_DATA,
1728					   &qam);
1729	mutex_unlock(priv->spi_mutex);
1730	if (!ret) {
1731		switch (qam) {
1732		case CXD2880_DVBT2_QPSK:
1733			c->modulation = QPSK;
1734			break;
1735		case CXD2880_DVBT2_QAM16:
1736			c->modulation = QAM_16;
1737			break;
1738		case CXD2880_DVBT2_QAM64:
1739			c->modulation = QAM_64;
1740			break;
1741		case CXD2880_DVBT2_QAM256:
1742			c->modulation = QAM_256;
1743			break;
1744		default:
1745			c->modulation = QPSK;
1746			pr_debug("QAM is invalid %d\n", qam);
1747			break;
1748		}
1749	} else {
1750		c->modulation = QPSK;
1751		pr_debug("QAM %d\n", ret);
1752	}
1753
1754	mutex_lock(priv->spi_mutex);
1755	ret = cxd2880_tnrdmd_dvbt2_mon_spectrum_sense(&priv->tnrdmd, &sense);
1756	mutex_unlock(priv->spi_mutex);
1757	if (!ret) {
1758		switch (sense) {
1759		case CXD2880_TNRDMD_SPECTRUM_NORMAL:
1760			c->inversion = INVERSION_OFF;
1761			break;
1762		case CXD2880_TNRDMD_SPECTRUM_INV:
1763			c->inversion = INVERSION_ON;
1764			break;
1765		default:
1766			c->inversion = INVERSION_OFF;
1767			pr_debug("spectrum sense is invalid %d\n", sense);
1768			break;
1769		}
1770	} else {
1771		c->inversion = INVERSION_OFF;
1772		pr_debug("SpectrumSense %d\n", ret);
1773	}
1774
1775	mutex_lock(priv->spi_mutex);
1776	ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &strength);
1777	mutex_unlock(priv->spi_mutex);
1778	if (!ret) {
1779		c->strength.len = 1;
1780		c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1781		c->strength.stat[0].svalue = strength;
1782	} else {
1783		c->strength.len = 1;
1784		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1785		pr_debug("mon_rf_lvl %d\n", ret);
1786	}
1787
1788	ret = cxd2880_read_snr(fe, &snr);
1789	if (!ret) {
1790		c->cnr.len = 1;
1791		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1792		c->cnr.stat[0].svalue = snr;
1793	} else {
1794		c->cnr.len = 1;
1795		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1796		pr_debug("read_snr %d\n", ret);
1797	}
1798
1799	return 0;
1800}
1801
1802static int cxd2880_get_frontend(struct dvb_frontend *fe,
1803				struct dtv_frontend_properties *props)
1804{
1805	int ret;
1806
1807	if (!fe || !props) {
1808		pr_err("invalid arg.");
1809		return -EINVAL;
1810	}
1811
1812	pr_debug("system=%d\n", fe->dtv_property_cache.delivery_system);
1813	switch (fe->dtv_property_cache.delivery_system) {
1814	case SYS_DVBT:
1815		ret = cxd2880_get_frontend_t(fe, props);
1816		break;
1817	case SYS_DVBT2:
1818		ret = cxd2880_get_frontend_t2(fe, props);
1819		break;
1820	default:
1821		ret = -EINVAL;
1822		break;
1823	}
1824
1825	return ret;
1826}
1827
1828static enum dvbfe_algo cxd2880_get_frontend_algo(struct dvb_frontend *fe)
1829{
1830	return DVBFE_ALGO_HW;
1831}
1832
1833static struct dvb_frontend_ops cxd2880_dvbt_t2_ops = {
1834	.info = {
1835		.name = "Sony CXD2880",
1836		.frequency_min_hz = 174 * MHz,
1837		.frequency_max_hz = 862 * MHz,
1838		.frequency_stepsize_hz = 1 * kHz,
1839		.caps = FE_CAN_INVERSION_AUTO |
1840				FE_CAN_FEC_1_2 |
1841				FE_CAN_FEC_2_3 |
1842				FE_CAN_FEC_3_4 |
1843				FE_CAN_FEC_4_5 |
1844				FE_CAN_FEC_5_6	|
1845				FE_CAN_FEC_7_8	|
1846				FE_CAN_FEC_AUTO |
1847				FE_CAN_QPSK |
1848				FE_CAN_QAM_16 |
1849				FE_CAN_QAM_32 |
1850				FE_CAN_QAM_64 |
1851				FE_CAN_QAM_128 |
1852				FE_CAN_QAM_256 |
1853				FE_CAN_QAM_AUTO |
1854				FE_CAN_TRANSMISSION_MODE_AUTO |
1855				FE_CAN_GUARD_INTERVAL_AUTO |
1856				FE_CAN_2G_MODULATION |
1857				FE_CAN_RECOVER |
1858				FE_CAN_MUTE_TS,
1859	},
1860	.delsys = { SYS_DVBT, SYS_DVBT2 },
1861
1862	.release = cxd2880_release,
1863	.init = cxd2880_init,
1864	.sleep = cxd2880_sleep,
1865	.tune = cxd2880_tune,
1866	.set_frontend = cxd2880_set_frontend,
1867	.get_frontend = cxd2880_get_frontend,
1868	.read_status = cxd2880_read_status,
1869	.read_ber = cxd2880_read_ber,
1870	.read_signal_strength = cxd2880_read_signal_strength,
1871	.read_snr = cxd2880_read_snr,
1872	.read_ucblocks = cxd2880_read_ucblocks,
1873	.get_frontend_algo = cxd2880_get_frontend_algo,
1874};
1875
1876struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe,
1877				    struct cxd2880_config *cfg)
1878{
1879	int ret;
1880	enum cxd2880_tnrdmd_chip_id chipid =
1881					CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
1882	static struct cxd2880_priv *priv;
1883	u8 data = 0;
1884
1885	if (!fe) {
1886		pr_err("invalid arg.\n");
1887		return NULL;
1888	}
1889
1890	priv = kzalloc(sizeof(struct cxd2880_priv), GFP_KERNEL);
1891	if (!priv)
1892		return NULL;
1893
1894	priv->spi = cfg->spi;
1895	priv->spi_mutex = cfg->spi_mutex;
1896	priv->spi_device.spi = cfg->spi;
1897
1898	memcpy(&fe->ops, &cxd2880_dvbt_t2_ops,
1899	       sizeof(struct dvb_frontend_ops));
1900
1901	ret = cxd2880_spi_device_initialize(&priv->spi_device,
1902					    CXD2880_SPI_MODE_0,
1903					    55000000);
1904	if (ret) {
1905		pr_err("spi_device_initialize failed. %d\n", ret);
1906		kfree(priv);
1907		return NULL;
1908	}
1909
1910	ret = cxd2880_spi_device_create_spi(&priv->cxd2880_spi,
1911					    &priv->spi_device);
1912	if (ret) {
1913		pr_err("spi_device_create_spi failed. %d\n", ret);
1914		kfree(priv);
1915		return NULL;
1916	}
1917
1918	ret = cxd2880_io_spi_create(&priv->regio, &priv->cxd2880_spi, 0);
1919	if (ret) {
1920		pr_err("io_spi_create failed. %d\n", ret);
1921		kfree(priv);
1922		return NULL;
1923	}
1924	ret = priv->regio.write_reg(&priv->regio,
1925				    CXD2880_IO_TGT_SYS, 0x00, 0x00);
1926	if (ret) {
1927		pr_err("set bank to 0x00 failed.\n");
1928		kfree(priv);
1929		return NULL;
1930	}
1931	ret = priv->regio.read_regs(&priv->regio,
1932				    CXD2880_IO_TGT_SYS, 0xfd, &data, 1);
1933	if (ret) {
1934		pr_err("read chip id failed.\n");
1935		kfree(priv);
1936		return NULL;
1937	}
1938
1939	chipid = (enum cxd2880_tnrdmd_chip_id)data;
1940	if (chipid != CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X &&
1941	    chipid != CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11) {
1942		pr_err("chip id invalid.\n");
1943		kfree(priv);
1944		return NULL;
1945	}
1946
1947	fe->demodulator_priv = priv;
1948	pr_info("CXD2880 driver version: Ver %s\n",
1949		CXD2880_TNRDMD_DRIVER_VERSION);
1950
1951	return fe;
1952}
1953EXPORT_SYMBOL_GPL(cxd2880_attach);
1954
1955MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver");
1956MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
1957MODULE_LICENSE("GPL v2");
~/ Read-only file preview.