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 <media/dvb_math.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 
27 struct 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 
45 static 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 
114 static 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 
196 static 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 
256 static 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 
364 static 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 
420 static 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 
475 static 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 
487 static 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 
539 static 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 
560 static 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 
603 static 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 
642 static 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 
676 static int cxd2880_read_ber(struct dvb_frontend *fe, u32 *ber)
677 {
678 	*ber = 0;
679 
680 	return 0;
681 }
682 
683 static 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 
794 static 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 
942 error_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 
951 error_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 
959 static 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 
994 static 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 
1034 static 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 
1120 static 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 
1264 static 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 
1302 static 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 
1381 static 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 
1407 static 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 
1608 static 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 
1802 static 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 
1828 static enum dvbfe_algo cxd2880_get_frontend_algo(struct dvb_frontend *fe)
1829 {
1830 	return DVBFE_ALGO_HW;
1831 }
1832 
1833 static 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 
1876 struct 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 }
1953 EXPORT_SYMBOL(cxd2880_attach);
1954 
1955 MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver");
1956 MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
1957 MODULE_LICENSE("GPL v2");
1958