Linux-libre 4.17.3-gnu
[librecmc/linux-libre.git] / drivers / media / dvb-frontends / cxd2880 / cxd2880_top.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 <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         mutex_unlock(priv->spi_mutex);
524
525         pr_debug("OK.\n");
526
527         return ret;
528 }
529
530 static int cxd2880_sleep(struct dvb_frontend *fe)
531 {
532         int ret;
533         struct cxd2880_priv *priv = NULL;
534
535         if (!fe) {
536                 pr_err("invalid arg\n");
537                 return -EINVAL;
538         }
539
540         priv = fe->demodulator_priv;
541
542         mutex_lock(priv->spi_mutex);
543         ret = cxd2880_tnrdmd_sleep(&priv->tnrdmd);
544         mutex_unlock(priv->spi_mutex);
545
546         pr_debug("tnrdmd_sleep ret %d\n", ret);
547
548         return ret;
549 }
550
551 static int cxd2880_read_signal_strength(struct dvb_frontend *fe,
552                                         u16 *strength)
553 {
554         int ret;
555         struct cxd2880_priv *priv = NULL;
556         struct dtv_frontend_properties *c = NULL;
557         int level = 0;
558
559         if (!fe || !strength) {
560                 pr_err("invalid arg\n");
561                 return -EINVAL;
562         }
563
564         priv = fe->demodulator_priv;
565         c = &fe->dtv_property_cache;
566
567         mutex_lock(priv->spi_mutex);
568         if (c->delivery_system == SYS_DVBT ||
569             c->delivery_system == SYS_DVBT2) {
570                 ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &level);
571         } else {
572                 pr_debug("invalid system\n");
573                 mutex_unlock(priv->spi_mutex);
574                 return -EINVAL;
575         }
576         mutex_unlock(priv->spi_mutex);
577
578         level /= 125;
579         /*
580          * level should be between -105dBm and -30dBm.
581          * E.g. they should be between:
582          * -105000/125 = -840 and -30000/125 = -240
583          */
584         level = clamp(level, -840, -240);
585         /* scale value to 0x0000-0xffff */
586         *strength = ((level + 840) * 0xffff) / (-240 + 840);
587
588         if (ret)
589                 pr_debug("ret = %d\n", ret);
590
591         return ret;
592 }
593
594 static int cxd2880_read_snr(struct dvb_frontend *fe, u16 *snr)
595 {
596         int ret;
597         int snrvalue = 0;
598         struct cxd2880_priv *priv = NULL;
599         struct dtv_frontend_properties *c = NULL;
600
601         if (!fe || !snr) {
602                 pr_err("invalid arg\n");
603                 return -EINVAL;
604         }
605
606         priv = fe->demodulator_priv;
607         c = &fe->dtv_property_cache;
608
609         mutex_lock(priv->spi_mutex);
610         if (c->delivery_system == SYS_DVBT) {
611                 ret = cxd2880_tnrdmd_dvbt_mon_snr(&priv->tnrdmd,
612                                                   &snrvalue);
613         } else if (c->delivery_system == SYS_DVBT2) {
614                 ret = cxd2880_tnrdmd_dvbt2_mon_snr(&priv->tnrdmd,
615                                                    &snrvalue);
616         } else {
617                 pr_err("invalid system\n");
618                 mutex_unlock(priv->spi_mutex);
619                 return -EINVAL;
620         }
621         mutex_unlock(priv->spi_mutex);
622
623         if (snrvalue < 0)
624                 snrvalue = 0;
625         *snr = snrvalue;
626
627         if (ret)
628                 pr_debug("ret = %d\n", ret);
629
630         return ret;
631 }
632
633 static int cxd2880_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
634 {
635         int ret;
636         struct cxd2880_priv *priv = NULL;
637         struct dtv_frontend_properties *c = NULL;
638
639         if (!fe || !ucblocks) {
640                 pr_err("invalid arg\n");
641                 return -EINVAL;
642         }
643
644         priv = fe->demodulator_priv;
645         c = &fe->dtv_property_cache;
646
647         mutex_lock(priv->spi_mutex);
648         if (c->delivery_system == SYS_DVBT) {
649                 ret = cxd2880_tnrdmd_dvbt_mon_packet_error_number(&priv->tnrdmd,
650                                                                   ucblocks);
651         } else if (c->delivery_system == SYS_DVBT2) {
652                 ret = cxd2880_tnrdmd_dvbt2_mon_packet_error_number(&priv->tnrdmd,
653                                                                    ucblocks);
654         } else {
655                 pr_err("invalid system\n");
656                 mutex_unlock(priv->spi_mutex);
657                 return -EINVAL;
658         }
659         mutex_unlock(priv->spi_mutex);
660
661         if (ret)
662                 pr_debug("ret = %d\n", ret);
663
664         return ret;
665 }
666
667 static int cxd2880_read_ber(struct dvb_frontend *fe, u32 *ber)
668 {
669         *ber = 0;
670
671         return 0;
672 }
673
674 static int cxd2880_set_ber_per_period_t(struct dvb_frontend *fe)
675 {
676         int ret;
677         struct cxd2880_priv *priv;
678         struct cxd2880_dvbt_tpsinfo info;
679         enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ;
680         u32 pre_ber_rate = 0;
681         u32 post_ber_rate = 0;
682         u32 ucblock_rate = 0;
683         u32 mes_exp = 0;
684         static const int cr_table[5] = {31500, 42000, 47250, 52500, 55125};
685         static const int denominator_tbl[4] = {125664, 129472, 137088, 152320};
686
687         if (!fe) {
688                 pr_err("invalid arg\n");
689                 return -EINVAL;
690         }
691
692         priv = fe->demodulator_priv;
693         bw = priv->dvbt_tune_param.bandwidth;
694
695         ret = cxd2880_tnrdmd_dvbt_mon_tps_info(&priv->tnrdmd,
696                                                &info);
697         if (ret) {
698                 pr_err("tps monitor error ret = %d\n", ret);
699                 info.hierarchy = CXD2880_DVBT_HIERARCHY_NON;
700                 info.constellation = CXD2880_DVBT_CONSTELLATION_QPSK;
701                 info.guard = CXD2880_DVBT_GUARD_1_4;
702                 info.rate_hp = CXD2880_DVBT_CODERATE_1_2;
703                 info.rate_lp = CXD2880_DVBT_CODERATE_1_2;
704         }
705
706         if (info.hierarchy == CXD2880_DVBT_HIERARCHY_NON) {
707                 pre_ber_rate = 63000000 * bw * (info.constellation * 2 + 2) /
708                                denominator_tbl[info.guard];
709
710                 post_ber_rate = 1000 * cr_table[info.rate_hp] * bw *
711                                 (info.constellation * 2 + 2) /
712                                 denominator_tbl[info.guard];
713
714                 ucblock_rate = 875 * cr_table[info.rate_hp] * bw *
715                                (info.constellation * 2 + 2) /
716                                denominator_tbl[info.guard];
717         } else {
718                 u8 data = 0;
719                 struct cxd2880_tnrdmd *tnrdmd = &priv->tnrdmd;
720
721                 ret = tnrdmd->io->write_reg(tnrdmd->io,
722                                             CXD2880_IO_TGT_DMD,
723                                             0x00, 0x10);
724                 if (!ret) {
725                         ret = tnrdmd->io->read_regs(tnrdmd->io,
726                                                     CXD2880_IO_TGT_DMD,
727                                                     0x67, &data, 1);
728                         if (ret)
729                                 data = 0x00;
730                 } else {
731                         data = 0x00;
732                 }
733
734                 if (data & 0x01) { /* Low priority */
735                         pre_ber_rate =
736                                 63000000 * bw * (info.constellation * 2 + 2) /
737                                 denominator_tbl[info.guard];
738
739                         post_ber_rate = 1000 * cr_table[info.rate_lp] * bw *
740                                         (info.constellation * 2 + 2) /
741                                         denominator_tbl[info.guard];
742
743                         ucblock_rate = (1000 * 7 / 8) * cr_table[info.rate_lp] *
744                                        bw * (info.constellation * 2 + 2) /
745                                        denominator_tbl[info.guard];
746                 } else { /* High priority */
747                         pre_ber_rate =
748                                 63000000 * bw * 2 / denominator_tbl[info.guard];
749
750                         post_ber_rate = 1000 * cr_table[info.rate_hp] * bw * 2 /
751                                         denominator_tbl[info.guard];
752
753                         ucblock_rate = (1000 * 7 / 8) * cr_table[info.rate_hp] *
754                                         bw * 2 / denominator_tbl[info.guard];
755                 }
756         }
757
758         mes_exp = pre_ber_rate < 8192 ? 8 : intlog2(pre_ber_rate) >> 24;
759         priv->pre_ber_interval =
760                 ((1U << mes_exp) * 1000 + (pre_ber_rate / 2)) /
761                 pre_ber_rate;
762         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
763                                CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD,
764                                mes_exp == 8 ? 0 : mes_exp - 12);
765
766         mes_exp = intlog2(post_ber_rate) >> 24;
767         priv->post_ber_interval =
768                 ((1U << mes_exp) * 1000 + (post_ber_rate / 2)) /
769                 post_ber_rate;
770         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
771                                CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD,
772                                mes_exp);
773
774         mes_exp = intlog2(ucblock_rate) >> 24;
775         priv->ucblock_interval =
776                 ((1U << mes_exp) * 1000 + (ucblock_rate / 2)) /
777                 ucblock_rate;
778         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
779                                CXD2880_TNRDMD_CFG_DVBT_PER_MES,
780                                mes_exp);
781
782         return 0;
783 }
784
785 static int cxd2880_set_ber_per_period_t2(struct dvb_frontend *fe)
786 {
787         int ret;
788         struct cxd2880_priv *priv;
789         struct cxd2880_dvbt2_l1pre l1pre;
790         struct cxd2880_dvbt2_l1post l1post;
791         struct cxd2880_dvbt2_plp plp;
792         struct cxd2880_dvbt2_bbheader bbheader;
793         enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ;
794         u32 pre_ber_rate = 0;
795         u32 post_ber_rate = 0;
796         u32 ucblock_rate = 0;
797         u32 mes_exp = 0;
798         u32 term_a = 0;
799         u32 term_b = 0;
800         u32 denominator = 0;
801         static const u32 gi_tbl[7] = {32, 64, 128, 256, 8, 152, 76};
802         static const u8 n_tbl[6] = {8, 2, 4, 16, 1, 1};
803         static const u8 mode_tbl[6] = {2, 8, 4, 1, 16, 32};
804         static const u32 kbch_tbl[2][8] = {
805                 {6952, 9472, 10552, 11632, 12352, 13072, 5152, 6232},
806                 {32128, 38608, 42960, 48328, 51568, 53760, 0, 0}
807         };
808
809         if (!fe) {
810                 pr_err("invalid arg\n");
811                 return -EINVAL;
812         }
813
814         priv = fe->demodulator_priv;
815         bw = priv->dvbt2_tune_param.bandwidth;
816
817         ret = cxd2880_tnrdmd_dvbt2_mon_l1_pre(&priv->tnrdmd, &l1pre);
818         if (ret) {
819                 pr_info("l1 pre error\n");
820                 goto error_ber_setting;
821         }
822
823         ret = cxd2880_tnrdmd_dvbt2_mon_active_plp(&priv->tnrdmd,
824                                                   CXD2880_DVBT2_PLP_DATA, &plp);
825         if (ret) {
826                 pr_info("plp info error\n");
827                 goto error_ber_setting;
828         }
829
830         ret = cxd2880_tnrdmd_dvbt2_mon_l1_post(&priv->tnrdmd, &l1post);
831         if (ret) {
832                 pr_info("l1 post error\n");
833                 goto error_ber_setting;
834         }
835
836         term_a =
837                 (mode_tbl[l1pre.fft_mode] * (1024 + gi_tbl[l1pre.gi])) *
838                 (l1pre.num_symbols + n_tbl[l1pre.fft_mode]) + 2048;
839
840         if (l1pre.mixed && l1post.fef_intvl) {
841                 term_b = (l1post.fef_length + (l1post.fef_intvl / 2)) /
842                          l1post.fef_intvl;
843         } else {
844                 term_b = 0;
845         }
846
847         switch (bw) {
848         case CXD2880_DTV_BW_1_7_MHZ:
849                 denominator = ((term_a + term_b) * 71 + (131 / 2)) / 131;
850                 break;
851         case CXD2880_DTV_BW_5_MHZ:
852                 denominator = ((term_a + term_b) * 7 + 20) / 40;
853                 break;
854         case CXD2880_DTV_BW_6_MHZ:
855                 denominator = ((term_a + term_b) * 7 + 24) / 48;
856                 break;
857         case CXD2880_DTV_BW_7_MHZ:
858                 denominator = ((term_a + term_b) + 4) / 8;
859                 break;
860         case CXD2880_DTV_BW_8_MHZ:
861         default:
862                 denominator = ((term_a + term_b) * 7 + 32) / 64;
863                 break;
864         }
865
866         if (plp.til_type && plp.til_len) {
867                 pre_ber_rate =
868                         (plp.num_blocks_max * 1000000 + (denominator / 2)) /
869                         denominator;
870                 pre_ber_rate = (pre_ber_rate + (plp.til_len / 2)) /
871                                plp.til_len;
872         } else {
873                 pre_ber_rate =
874                         (plp.num_blocks_max * 1000000 + (denominator / 2)) /
875                         denominator;
876         }
877
878         post_ber_rate = pre_ber_rate;
879
880         mes_exp = intlog2(pre_ber_rate) >> 24;
881         priv->pre_ber_interval =
882                 ((1U << mes_exp) * 1000 + (pre_ber_rate / 2)) /
883                 pre_ber_rate;
884         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
885                                CXD2880_TNRDMD_CFG_DVBT2_LBER_MES,
886                                mes_exp);
887
888         mes_exp = intlog2(post_ber_rate) >> 24;
889         priv->post_ber_interval =
890                 ((1U << mes_exp) * 1000 + (post_ber_rate / 2)) /
891                 post_ber_rate;
892         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
893                                CXD2880_TNRDMD_CFG_DVBT2_BBER_MES,
894                                mes_exp);
895
896         ret = cxd2880_tnrdmd_dvbt2_mon_bbheader(&priv->tnrdmd,
897                                                 CXD2880_DVBT2_PLP_DATA,
898                                                 &bbheader);
899         if (ret) {
900                 pr_info("bb header error\n");
901                 goto error_ucblock_setting;
902         }
903
904         if (bbheader.plp_mode == CXD2880_DVBT2_PLP_MODE_NM) {
905                 if (!bbheader.issy_indicator) {
906                         ucblock_rate =
907                                 (pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] +
908                                 752) / 1504;
909                 } else {
910                         ucblock_rate =
911                                 (pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] +
912                                 764) / 1528;
913                 }
914         } else if (bbheader.plp_mode == CXD2880_DVBT2_PLP_MODE_HEM) {
915                 ucblock_rate =
916                         (pre_ber_rate * kbch_tbl[plp.fec][plp.plp_cr] + 748) /
917                         1496;
918         } else {
919                 pr_info("plp mode is not Normal or HEM\n");
920                 goto error_ucblock_setting;
921         }
922
923         mes_exp = intlog2(ucblock_rate) >> 24;
924         priv->ucblock_interval =
925                 ((1U << mes_exp) * 1000 + (ucblock_rate / 2)) /
926                 ucblock_rate;
927         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
928                                CXD2880_TNRDMD_CFG_DVBT2_PER_MES,
929                                mes_exp);
930
931         return 0;
932
933 error_ber_setting:
934         priv->pre_ber_interval = 1000;
935         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
936                                      CXD2880_TNRDMD_CFG_DVBT2_LBER_MES, 0);
937
938         priv->post_ber_interval = 1000;
939         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
940                                CXD2880_TNRDMD_CFG_DVBT2_BBER_MES, 0);
941
942 error_ucblock_setting:
943         priv->ucblock_interval = 1000;
944         cxd2880_tnrdmd_set_cfg(&priv->tnrdmd,
945                                CXD2880_TNRDMD_CFG_DVBT2_PER_MES, 8);
946
947         return 0;
948 }
949
950 static int cxd2880_dvbt_tune(struct cxd2880_tnrdmd *tnr_dmd,
951                              struct cxd2880_dvbt_tune_param
952                              *tune_param)
953 {
954         int ret;
955
956         if (!tnr_dmd || !tune_param)
957                 return -EINVAL;
958
959         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
960                 return -EINVAL;
961
962         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
963             tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
964                 return -EINVAL;
965
966         atomic_set(&tnr_dmd->cancel, 0);
967
968         if (tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ &&
969             tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ &&
970             tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ &&
971             tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ) {
972                 return -ENOTTY;
973         }
974
975         ret = cxd2880_tnrdmd_dvbt_tune1(tnr_dmd, tune_param);
976         if (ret)
977                 return ret;
978
979         usleep_range(CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000,
980                      CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000 + 1000);
981
982         return cxd2880_tnrdmd_dvbt_tune2(tnr_dmd, tune_param);
983 }
984
985 static int cxd2880_dvbt2_tune(struct cxd2880_tnrdmd *tnr_dmd,
986                               struct cxd2880_dvbt2_tune_param
987                               *tune_param)
988 {
989         int ret;
990
991         if (!tnr_dmd || !tune_param)
992                 return -EINVAL;
993
994         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
995                 return -EINVAL;
996
997         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
998             tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
999                 return -EINVAL;
1000
1001         atomic_set(&tnr_dmd->cancel, 0);
1002
1003         if (tune_param->bandwidth != CXD2880_DTV_BW_1_7_MHZ &&
1004             tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ &&
1005             tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ &&
1006             tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ &&
1007             tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ) {
1008                 return -ENOTTY;
1009         }
1010
1011         if (tune_param->profile != CXD2880_DVBT2_PROFILE_BASE &&
1012             tune_param->profile != CXD2880_DVBT2_PROFILE_LITE)
1013                 return -EINVAL;
1014
1015         ret = cxd2880_tnrdmd_dvbt2_tune1(tnr_dmd, tune_param);
1016         if (ret)
1017                 return ret;
1018
1019         usleep_range(CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000,
1020                      CXD2880_TNRDMD_WAIT_AGC_STABLE * 10000 + 1000);
1021
1022         return cxd2880_tnrdmd_dvbt2_tune2(tnr_dmd, tune_param);
1023 }
1024
1025 static int cxd2880_set_frontend(struct dvb_frontend *fe)
1026 {
1027         int ret;
1028         struct dtv_frontend_properties *c;
1029         struct cxd2880_priv *priv;
1030         enum cxd2880_dtv_bandwidth bw = CXD2880_DTV_BW_1_7_MHZ;
1031
1032         if (!fe) {
1033                 pr_err("invalid arg\n");
1034                 return -EINVAL;
1035         }
1036
1037         priv = fe->demodulator_priv;
1038         c = &fe->dtv_property_cache;
1039
1040         c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1041         c->pre_bit_error.stat[0].uvalue = 0;
1042         c->pre_bit_error.len = 1;
1043         c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1044         c->pre_bit_count.stat[0].uvalue = 0;
1045         c->pre_bit_count.len = 1;
1046         c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1047         c->post_bit_error.stat[0].uvalue = 0;
1048         c->post_bit_error.len = 1;
1049         c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1050         c->post_bit_count.stat[0].uvalue = 0;
1051         c->post_bit_count.len = 1;
1052         c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1053         c->block_error.stat[0].uvalue = 0;
1054         c->block_error.len = 1;
1055         c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1056         c->block_count.stat[0].uvalue = 0;
1057         c->block_count.len = 1;
1058
1059         switch (c->bandwidth_hz) {
1060         case 1712000:
1061                 bw = CXD2880_DTV_BW_1_7_MHZ;
1062                 break;
1063         case 5000000:
1064                 bw = CXD2880_DTV_BW_5_MHZ;
1065                 break;
1066         case 6000000:
1067                 bw = CXD2880_DTV_BW_6_MHZ;
1068                 break;
1069         case 7000000:
1070                 bw = CXD2880_DTV_BW_7_MHZ;
1071                 break;
1072         case 8000000:
1073                 bw = CXD2880_DTV_BW_8_MHZ;
1074                 break;
1075         default:
1076                 return -EINVAL;
1077         }
1078
1079         priv->s = 0;
1080
1081         pr_info("sys:%d freq:%d bw:%d\n",
1082                 c->delivery_system, c->frequency, bw);
1083         mutex_lock(priv->spi_mutex);
1084         if (c->delivery_system == SYS_DVBT) {
1085                 priv->tnrdmd.sys = CXD2880_DTV_SYS_DVBT;
1086                 priv->dvbt_tune_param.center_freq_khz = c->frequency / 1000;
1087                 priv->dvbt_tune_param.bandwidth = bw;
1088                 priv->dvbt_tune_param.profile = CXD2880_DVBT_PROFILE_HP;
1089                 ret = cxd2880_dvbt_tune(&priv->tnrdmd,
1090                                         &priv->dvbt_tune_param);
1091         } else if (c->delivery_system == SYS_DVBT2) {
1092                 priv->tnrdmd.sys = CXD2880_DTV_SYS_DVBT2;
1093                 priv->dvbt2_tune_param.center_freq_khz = c->frequency / 1000;
1094                 priv->dvbt2_tune_param.bandwidth = bw;
1095                 priv->dvbt2_tune_param.data_plp_id = (u16)c->stream_id;
1096                 priv->dvbt2_tune_param.profile = CXD2880_DVBT2_PROFILE_BASE;
1097                 ret = cxd2880_dvbt2_tune(&priv->tnrdmd,
1098                                          &priv->dvbt2_tune_param);
1099         } else {
1100                 pr_err("invalid system\n");
1101                 mutex_unlock(priv->spi_mutex);
1102                 return -EINVAL;
1103         }
1104         mutex_unlock(priv->spi_mutex);
1105
1106         pr_info("tune result %d\n", ret);
1107
1108         return ret;
1109 }
1110
1111 static int cxd2880_get_stats(struct dvb_frontend *fe,
1112                              enum fe_status status)
1113 {
1114         struct cxd2880_priv *priv = NULL;
1115         struct dtv_frontend_properties *c = NULL;
1116         u32 pre_bit_err = 0, pre_bit_count = 0;
1117         u32 post_bit_err = 0, post_bit_count = 0;
1118         u32 block_err = 0, block_count = 0;
1119         int ret;
1120
1121         if (!fe) {
1122                 pr_err("invalid arg\n");
1123                 return -EINVAL;
1124         }
1125
1126         priv = fe->demodulator_priv;
1127         c = &fe->dtv_property_cache;
1128
1129         if (!(status & FE_HAS_LOCK)) {
1130                 c->pre_bit_error.len = 1;
1131                 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1132                 c->pre_bit_count.len = 1;
1133                 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1134                 c->post_bit_error.len = 1;
1135                 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1136                 c->post_bit_count.len = 1;
1137                 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1138                 c->block_error.len = 1;
1139                 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1140                 c->block_count.len = 1;
1141                 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1142
1143                 return 0;
1144         }
1145
1146         if (time_after(jiffies, priv->pre_ber_update)) {
1147                 priv->pre_ber_update =
1148                          jiffies + msecs_to_jiffies(priv->pre_ber_interval);
1149                 if (c->delivery_system == SYS_DVBT) {
1150                         mutex_lock(priv->spi_mutex);
1151                         ret = cxd2880_pre_bit_err_t(&priv->tnrdmd,
1152                                                     &pre_bit_err,
1153                                                     &pre_bit_count);
1154                         mutex_unlock(priv->spi_mutex);
1155                 } else if (c->delivery_system == SYS_DVBT2) {
1156                         mutex_lock(priv->spi_mutex);
1157                         ret = cxd2880_pre_bit_err_t2(&priv->tnrdmd,
1158                                                      &pre_bit_err,
1159                                                      &pre_bit_count);
1160                         mutex_unlock(priv->spi_mutex);
1161                 } else {
1162                         return -EINVAL;
1163                 }
1164
1165                 if (!ret) {
1166                         c->pre_bit_error.len = 1;
1167                         c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1168                         c->pre_bit_error.stat[0].uvalue += pre_bit_err;
1169                         c->pre_bit_count.len = 1;
1170                         c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1171                         c->pre_bit_count.stat[0].uvalue += pre_bit_count;
1172                 } else {
1173                         c->pre_bit_error.len = 1;
1174                         c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1175                         c->pre_bit_count.len = 1;
1176                         c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1177                         pr_debug("pre_bit_error_t failed %d\n", ret);
1178                 }
1179         }
1180
1181         if (time_after(jiffies, priv->post_ber_update)) {
1182                 priv->post_ber_update =
1183                         jiffies + msecs_to_jiffies(priv->post_ber_interval);
1184                 if (c->delivery_system == SYS_DVBT) {
1185                         mutex_lock(priv->spi_mutex);
1186                         ret = cxd2880_post_bit_err_t(&priv->tnrdmd,
1187                                                      &post_bit_err,
1188                                                      &post_bit_count);
1189                         mutex_unlock(priv->spi_mutex);
1190                 } else if (c->delivery_system == SYS_DVBT2) {
1191                         mutex_lock(priv->spi_mutex);
1192                         ret = cxd2880_post_bit_err_t2(&priv->tnrdmd,
1193                                                       &post_bit_err,
1194                                                       &post_bit_count);
1195                         mutex_unlock(priv->spi_mutex);
1196                 } else {
1197                         return -EINVAL;
1198                 }
1199
1200                 if (!ret) {
1201                         c->post_bit_error.len = 1;
1202                         c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1203                         c->post_bit_error.stat[0].uvalue += post_bit_err;
1204                         c->post_bit_count.len = 1;
1205                         c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1206                         c->post_bit_count.stat[0].uvalue += post_bit_count;
1207                 } else {
1208                         c->post_bit_error.len = 1;
1209                         c->post_bit_error.stat[0].scale =
1210                                                         FE_SCALE_NOT_AVAILABLE;
1211                         c->post_bit_count.len = 1;
1212                         c->post_bit_count.stat[0].scale =
1213                                                         FE_SCALE_NOT_AVAILABLE;
1214                         pr_debug("post_bit_err_t %d\n", ret);
1215                 }
1216         }
1217
1218         if (time_after(jiffies, priv->ucblock_update)) {
1219                 priv->ucblock_update =
1220                         jiffies + msecs_to_jiffies(priv->ucblock_interval);
1221                 if (c->delivery_system == SYS_DVBT) {
1222                         mutex_lock(priv->spi_mutex);
1223                         ret = cxd2880_read_block_err_t(&priv->tnrdmd,
1224                                                        &block_err,
1225                                                        &block_count);
1226                         mutex_unlock(priv->spi_mutex);
1227                 } else if (c->delivery_system == SYS_DVBT2) {
1228                         mutex_lock(priv->spi_mutex);
1229                         ret = cxd2880_read_block_err_t2(&priv->tnrdmd,
1230                                                         &block_err,
1231                                                         &block_count);
1232                         mutex_unlock(priv->spi_mutex);
1233                 } else {
1234                         return -EINVAL;
1235                 }
1236                 if (!ret) {
1237                         c->block_error.len = 1;
1238                         c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1239                         c->block_error.stat[0].uvalue += block_err;
1240                         c->block_count.len = 1;
1241                         c->block_count.stat[0].scale = FE_SCALE_COUNTER;
1242                         c->block_count.stat[0].uvalue += block_count;
1243                 } else {
1244                         c->block_error.len = 1;
1245                         c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1246                         c->block_count.len = 1;
1247                         c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1248                         pr_debug("read_block_err_t  %d\n", ret);
1249                 }
1250         }
1251
1252         return 0;
1253 }
1254
1255 static int cxd2880_check_l1post_plp(struct dvb_frontend *fe)
1256 {
1257         u8 valid = 0;
1258         u8 plp_not_found;
1259         int ret;
1260         struct cxd2880_priv *priv = NULL;
1261
1262         if (!fe) {
1263                 pr_err("invalid arg\n");
1264                 return -EINVAL;
1265         }
1266
1267         priv = fe->demodulator_priv;
1268
1269         ret = cxd2880_tnrdmd_dvbt2_check_l1post_valid(&priv->tnrdmd,
1270                                                       &valid);
1271         if (ret)
1272                 return ret;
1273
1274         if (!valid)
1275                 return -EAGAIN;
1276
1277         ret = cxd2880_tnrdmd_dvbt2_mon_data_plp_error(&priv->tnrdmd,
1278                                                       &plp_not_found);
1279         if (ret)
1280                 return ret;
1281
1282         if (plp_not_found) {
1283                 priv->dvbt2_tune_param.tune_info =
1284                         CXD2880_TNRDMD_DVBT2_TUNE_INFO_INVALID_PLP_ID;
1285         } else {
1286                 priv->dvbt2_tune_param.tune_info =
1287                         CXD2880_TNRDMD_DVBT2_TUNE_INFO_OK;
1288         }
1289
1290         return 0;
1291 }
1292
1293 static int cxd2880_read_status(struct dvb_frontend *fe,
1294                                enum fe_status *status)
1295 {
1296         int ret;
1297         u8 sync = 0;
1298         u8 lock = 0;
1299         u8 unlock = 0;
1300         struct cxd2880_priv *priv = NULL;
1301         struct dtv_frontend_properties *c = NULL;
1302
1303         if (!fe || !status) {
1304                 pr_err("invalid arg\n");
1305                 return -EINVAL;
1306         }
1307
1308         priv = fe->demodulator_priv;
1309         c = &fe->dtv_property_cache;
1310         *status = 0;
1311
1312         if (priv->tnrdmd.state == CXD2880_TNRDMD_STATE_ACTIVE) {
1313                 mutex_lock(priv->spi_mutex);
1314                 if (c->delivery_system == SYS_DVBT) {
1315                         ret = cxd2880_tnrdmd_dvbt_mon_sync_stat(&priv->tnrdmd,
1316                                                                 &sync,
1317                                                                 &lock,
1318                                                                 &unlock);
1319                 } else if (c->delivery_system == SYS_DVBT2) {
1320                         ret = cxd2880_tnrdmd_dvbt2_mon_sync_stat(&priv->tnrdmd,
1321                                                                  &sync,
1322                                                                  &lock,
1323                                                                  &unlock);
1324                 } else {
1325                         pr_err("invalid system");
1326                         mutex_unlock(priv->spi_mutex);
1327                         return -EINVAL;
1328                 }
1329
1330                 mutex_unlock(priv->spi_mutex);
1331                 if (ret) {
1332                         pr_err("failed. sys = %d\n", priv->tnrdmd.sys);
1333                         return  ret;
1334                 }
1335
1336                 if (sync == 6) {
1337                         *status = FE_HAS_SIGNAL |
1338                                   FE_HAS_CARRIER;
1339                 }
1340                 if (lock)
1341                         *status |= FE_HAS_VITERBI |
1342                                    FE_HAS_SYNC |
1343                                    FE_HAS_LOCK;
1344         }
1345
1346         pr_debug("status %d\n", *status);
1347
1348         if (priv->s == 0 && (*status & FE_HAS_LOCK)) {
1349                 mutex_lock(priv->spi_mutex);
1350                 if (c->delivery_system == SYS_DVBT) {
1351                         ret = cxd2880_set_ber_per_period_t(fe);
1352                         priv->s = *status;
1353                 } else if (c->delivery_system == SYS_DVBT2) {
1354                         ret = cxd2880_check_l1post_plp(fe);
1355                         if (!ret) {
1356                                 ret = cxd2880_set_ber_per_period_t2(fe);
1357                                 priv->s = *status;
1358                         }
1359                 } else {
1360                         pr_err("invalid system\n");
1361                         mutex_unlock(priv->spi_mutex);
1362                         return -EINVAL;
1363                 }
1364                 mutex_unlock(priv->spi_mutex);
1365         }
1366
1367         cxd2880_get_stats(fe, *status);
1368         return  0;
1369 }
1370
1371 static int cxd2880_tune(struct dvb_frontend *fe,
1372                         bool retune,
1373                         unsigned int mode_flags,
1374                         unsigned int *delay,
1375                         enum fe_status *status)
1376 {
1377         int ret;
1378
1379         if (!fe || !delay || !status) {
1380                 pr_err("invalid arg.");
1381                 return -EINVAL;
1382         }
1383
1384         if (retune) {
1385                 ret = cxd2880_set_frontend(fe);
1386                 if (ret) {
1387                         pr_err("cxd2880_set_frontend failed %d\n", ret);
1388                         return ret;
1389                 }
1390         }
1391
1392         *delay = HZ / 5;
1393
1394         return cxd2880_read_status(fe, status);
1395 }
1396
1397 static int cxd2880_get_frontend_t(struct dvb_frontend *fe,
1398                                   struct dtv_frontend_properties *c)
1399 {
1400         int ret;
1401         struct cxd2880_priv *priv = NULL;
1402         enum cxd2880_dvbt_mode mode = CXD2880_DVBT_MODE_2K;
1403         enum cxd2880_dvbt_guard guard = CXD2880_DVBT_GUARD_1_32;
1404         struct cxd2880_dvbt_tpsinfo tps;
1405         enum cxd2880_tnrdmd_spectrum_sense sense;
1406         u16 snr = 0;
1407         int strength = 0;
1408
1409         if (!fe || !c) {
1410                 pr_err("invalid arg\n");
1411                 return -EINVAL;
1412         }
1413
1414         priv = fe->demodulator_priv;
1415
1416         mutex_lock(priv->spi_mutex);
1417         ret = cxd2880_tnrdmd_dvbt_mon_mode_guard(&priv->tnrdmd,
1418                                                  &mode, &guard);
1419         mutex_unlock(priv->spi_mutex);
1420         if (!ret) {
1421                 switch (mode) {
1422                 case CXD2880_DVBT_MODE_2K:
1423                         c->transmission_mode = TRANSMISSION_MODE_2K;
1424                         break;
1425                 case CXD2880_DVBT_MODE_8K:
1426                         c->transmission_mode = TRANSMISSION_MODE_8K;
1427                         break;
1428                 default:
1429                         c->transmission_mode = TRANSMISSION_MODE_2K;
1430                         pr_debug("transmission mode is invalid %d\n", mode);
1431                         break;
1432                 }
1433                 switch (guard) {
1434                 case CXD2880_DVBT_GUARD_1_32:
1435                         c->guard_interval = GUARD_INTERVAL_1_32;
1436                         break;
1437                 case CXD2880_DVBT_GUARD_1_16:
1438                         c->guard_interval = GUARD_INTERVAL_1_16;
1439                         break;
1440                 case CXD2880_DVBT_GUARD_1_8:
1441                         c->guard_interval = GUARD_INTERVAL_1_8;
1442                         break;
1443                 case CXD2880_DVBT_GUARD_1_4:
1444                         c->guard_interval = GUARD_INTERVAL_1_4;
1445                         break;
1446                 default:
1447                         c->guard_interval = GUARD_INTERVAL_1_32;
1448                         pr_debug("guard interval is invalid %d\n",
1449                                  guard);
1450                         break;
1451                 }
1452         } else {
1453                 c->transmission_mode = TRANSMISSION_MODE_2K;
1454                 c->guard_interval = GUARD_INTERVAL_1_32;
1455                 pr_debug("ModeGuard err %d\n", ret);
1456         }
1457
1458         mutex_lock(priv->spi_mutex);
1459         ret = cxd2880_tnrdmd_dvbt_mon_tps_info(&priv->tnrdmd, &tps);
1460         mutex_unlock(priv->spi_mutex);
1461         if (!ret) {
1462                 switch (tps.hierarchy) {
1463                 case CXD2880_DVBT_HIERARCHY_NON:
1464                         c->hierarchy = HIERARCHY_NONE;
1465                         break;
1466                 case CXD2880_DVBT_HIERARCHY_1:
1467                         c->hierarchy = HIERARCHY_1;
1468                         break;
1469                 case CXD2880_DVBT_HIERARCHY_2:
1470                         c->hierarchy = HIERARCHY_2;
1471                         break;
1472                 case CXD2880_DVBT_HIERARCHY_4:
1473                         c->hierarchy = HIERARCHY_4;
1474                         break;
1475                 default:
1476                         c->hierarchy = HIERARCHY_NONE;
1477                         pr_debug("TPSInfo hierarchy is invalid %d\n",
1478                                  tps.hierarchy);
1479                         break;
1480                 }
1481
1482                 switch (tps.rate_hp) {
1483                 case CXD2880_DVBT_CODERATE_1_2:
1484                         c->code_rate_HP = FEC_1_2;
1485                         break;
1486                 case CXD2880_DVBT_CODERATE_2_3:
1487                         c->code_rate_HP = FEC_2_3;
1488                         break;
1489                 case CXD2880_DVBT_CODERATE_3_4:
1490                         c->code_rate_HP = FEC_3_4;
1491                         break;
1492                 case CXD2880_DVBT_CODERATE_5_6:
1493                         c->code_rate_HP = FEC_5_6;
1494                         break;
1495                 case CXD2880_DVBT_CODERATE_7_8:
1496                         c->code_rate_HP = FEC_7_8;
1497                         break;
1498                 default:
1499                         c->code_rate_HP = FEC_NONE;
1500                         pr_debug("TPSInfo rateHP is invalid %d\n",
1501                                  tps.rate_hp);
1502                         break;
1503                 }
1504                 switch (tps.rate_lp) {
1505                 case CXD2880_DVBT_CODERATE_1_2:
1506                         c->code_rate_LP = FEC_1_2;
1507                         break;
1508                 case CXD2880_DVBT_CODERATE_2_3:
1509                         c->code_rate_LP = FEC_2_3;
1510                         break;
1511                 case CXD2880_DVBT_CODERATE_3_4:
1512                         c->code_rate_LP = FEC_3_4;
1513                         break;
1514                 case CXD2880_DVBT_CODERATE_5_6:
1515                         c->code_rate_LP = FEC_5_6;
1516                         break;
1517                 case CXD2880_DVBT_CODERATE_7_8:
1518                         c->code_rate_LP = FEC_7_8;
1519                         break;
1520                 default:
1521                         c->code_rate_LP = FEC_NONE;
1522                         pr_debug("TPSInfo rateLP is invalid %d\n",
1523                                  tps.rate_lp);
1524                         break;
1525                 }
1526                 switch (tps.constellation) {
1527                 case CXD2880_DVBT_CONSTELLATION_QPSK:
1528                         c->modulation = QPSK;
1529                         break;
1530                 case CXD2880_DVBT_CONSTELLATION_16QAM:
1531                         c->modulation = QAM_16;
1532                         break;
1533                 case CXD2880_DVBT_CONSTELLATION_64QAM:
1534                         c->modulation = QAM_64;
1535                         break;
1536                 default:
1537                         c->modulation = QPSK;
1538                         pr_debug("TPSInfo constellation is invalid %d\n",
1539                                  tps.constellation);
1540                         break;
1541                 }
1542         } else {
1543                 c->hierarchy = HIERARCHY_NONE;
1544                 c->code_rate_HP = FEC_NONE;
1545                 c->code_rate_LP = FEC_NONE;
1546                 c->modulation = QPSK;
1547                 pr_debug("TPS info err %d\n", ret);
1548         }
1549
1550         mutex_lock(priv->spi_mutex);
1551         ret = cxd2880_tnrdmd_dvbt_mon_spectrum_sense(&priv->tnrdmd, &sense);
1552         mutex_unlock(priv->spi_mutex);
1553         if (!ret) {
1554                 switch (sense) {
1555                 case CXD2880_TNRDMD_SPECTRUM_NORMAL:
1556                         c->inversion = INVERSION_OFF;
1557                         break;
1558                 case CXD2880_TNRDMD_SPECTRUM_INV:
1559                         c->inversion = INVERSION_ON;
1560                         break;
1561                 default:
1562                         c->inversion = INVERSION_OFF;
1563                         pr_debug("spectrum sense is invalid %d\n", sense);
1564                         break;
1565                 }
1566         } else {
1567                 c->inversion = INVERSION_OFF;
1568                 pr_debug("spectrum_sense %d\n", ret);
1569         }
1570
1571         mutex_lock(priv->spi_mutex);
1572         ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &strength);
1573         mutex_unlock(priv->spi_mutex);
1574         if (!ret) {
1575                 c->strength.len = 1;
1576                 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1577                 c->strength.stat[0].svalue = strength;
1578         } else {
1579                 c->strength.len = 1;
1580                 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1581                 pr_debug("mon_rf_lvl %d\n", ret);
1582         }
1583
1584         ret = cxd2880_read_snr(fe, &snr);
1585         if (!ret) {
1586                 c->cnr.len = 1;
1587                 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1588                 c->cnr.stat[0].svalue = snr;
1589         } else {
1590                 c->cnr.len = 1;
1591                 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1592                 pr_debug("read_snr %d\n", ret);
1593         }
1594
1595         return 0;
1596 }
1597
1598 static int cxd2880_get_frontend_t2(struct dvb_frontend *fe,
1599                                    struct dtv_frontend_properties *c)
1600 {
1601         int ret;
1602         struct cxd2880_priv *priv = NULL;
1603         struct cxd2880_dvbt2_l1pre l1pre;
1604         enum cxd2880_dvbt2_plp_code_rate coderate;
1605         enum cxd2880_dvbt2_plp_constell qam;
1606         enum cxd2880_tnrdmd_spectrum_sense sense;
1607         u16 snr = 0;
1608         int strength = 0;
1609
1610         if (!fe || !c) {
1611                 pr_err("invalid arg.\n");
1612                 return -EINVAL;
1613         }
1614
1615         priv = fe->demodulator_priv;
1616
1617         mutex_lock(priv->spi_mutex);
1618         ret = cxd2880_tnrdmd_dvbt2_mon_l1_pre(&priv->tnrdmd, &l1pre);
1619         mutex_unlock(priv->spi_mutex);
1620         if (!ret) {
1621                 switch (l1pre.fft_mode) {
1622                 case CXD2880_DVBT2_M2K:
1623                         c->transmission_mode = TRANSMISSION_MODE_2K;
1624                         break;
1625                 case CXD2880_DVBT2_M8K:
1626                         c->transmission_mode = TRANSMISSION_MODE_8K;
1627                         break;
1628                 case CXD2880_DVBT2_M4K:
1629                         c->transmission_mode = TRANSMISSION_MODE_4K;
1630                         break;
1631                 case CXD2880_DVBT2_M1K:
1632                         c->transmission_mode = TRANSMISSION_MODE_1K;
1633                         break;
1634                 case CXD2880_DVBT2_M16K:
1635                         c->transmission_mode = TRANSMISSION_MODE_16K;
1636                         break;
1637                 case CXD2880_DVBT2_M32K:
1638                         c->transmission_mode = TRANSMISSION_MODE_32K;
1639                         break;
1640                 default:
1641                         c->transmission_mode = TRANSMISSION_MODE_2K;
1642                         pr_debug("L1Pre fft_mode is invalid %d\n",
1643                                  l1pre.fft_mode);
1644                         break;
1645                 }
1646                 switch (l1pre.gi) {
1647                 case CXD2880_DVBT2_G1_32:
1648                         c->guard_interval = GUARD_INTERVAL_1_32;
1649                         break;
1650                 case CXD2880_DVBT2_G1_16:
1651                         c->guard_interval = GUARD_INTERVAL_1_16;
1652                         break;
1653                 case CXD2880_DVBT2_G1_8:
1654                         c->guard_interval = GUARD_INTERVAL_1_8;
1655                         break;
1656                 case CXD2880_DVBT2_G1_4:
1657                         c->guard_interval = GUARD_INTERVAL_1_4;
1658                         break;
1659                 case CXD2880_DVBT2_G1_128:
1660                         c->guard_interval = GUARD_INTERVAL_1_128;
1661                         break;
1662                 case CXD2880_DVBT2_G19_128:
1663                         c->guard_interval = GUARD_INTERVAL_19_128;
1664                         break;
1665                 case CXD2880_DVBT2_G19_256:
1666                         c->guard_interval = GUARD_INTERVAL_19_256;
1667                         break;
1668                 default:
1669                         c->guard_interval = GUARD_INTERVAL_1_32;
1670                         pr_debug("L1Pre guard interval is invalid %d\n",
1671                                  l1pre.gi);
1672                         break;
1673                 }
1674         } else {
1675                 c->transmission_mode = TRANSMISSION_MODE_2K;
1676                 c->guard_interval = GUARD_INTERVAL_1_32;
1677                 pr_debug("L1Pre err %d\n", ret);
1678         }
1679
1680         mutex_lock(priv->spi_mutex);
1681         ret = cxd2880_tnrdmd_dvbt2_mon_code_rate(&priv->tnrdmd,
1682                                                  CXD2880_DVBT2_PLP_DATA,
1683                                                  &coderate);
1684         mutex_unlock(priv->spi_mutex);
1685         if (!ret) {
1686                 switch (coderate) {
1687                 case CXD2880_DVBT2_R1_2:
1688                         c->fec_inner = FEC_1_2;
1689                         break;
1690                 case CXD2880_DVBT2_R3_5:
1691                         c->fec_inner = FEC_3_5;
1692                         break;
1693                 case CXD2880_DVBT2_R2_3:
1694                         c->fec_inner = FEC_2_3;
1695                         break;
1696                 case CXD2880_DVBT2_R3_4:
1697                         c->fec_inner = FEC_3_4;
1698                         break;
1699                 case CXD2880_DVBT2_R4_5:
1700                         c->fec_inner = FEC_4_5;
1701                         break;
1702                 case CXD2880_DVBT2_R5_6:
1703                         c->fec_inner = FEC_5_6;
1704                         break;
1705                 default:
1706                         c->fec_inner = FEC_NONE;
1707                         pr_debug("CodeRate is invalid %d\n", coderate);
1708                         break;
1709                 }
1710         } else {
1711                 c->fec_inner = FEC_NONE;
1712                 pr_debug("CodeRate %d\n", ret);
1713         }
1714
1715         mutex_lock(priv->spi_mutex);
1716         ret = cxd2880_tnrdmd_dvbt2_mon_qam(&priv->tnrdmd,
1717                                            CXD2880_DVBT2_PLP_DATA,
1718                                            &qam);
1719         mutex_unlock(priv->spi_mutex);
1720         if (!ret) {
1721                 switch (qam) {
1722                 case CXD2880_DVBT2_QPSK:
1723                         c->modulation = QPSK;
1724                         break;
1725                 case CXD2880_DVBT2_QAM16:
1726                         c->modulation = QAM_16;
1727                         break;
1728                 case CXD2880_DVBT2_QAM64:
1729                         c->modulation = QAM_64;
1730                         break;
1731                 case CXD2880_DVBT2_QAM256:
1732                         c->modulation = QAM_256;
1733                         break;
1734                 default:
1735                         c->modulation = QPSK;
1736                         pr_debug("QAM is invalid %d\n", qam);
1737                         break;
1738                 }
1739         } else {
1740                 c->modulation = QPSK;
1741                 pr_debug("QAM %d\n", ret);
1742         }
1743
1744         mutex_lock(priv->spi_mutex);
1745         ret = cxd2880_tnrdmd_dvbt2_mon_spectrum_sense(&priv->tnrdmd, &sense);
1746         mutex_unlock(priv->spi_mutex);
1747         if (!ret) {
1748                 switch (sense) {
1749                 case CXD2880_TNRDMD_SPECTRUM_NORMAL:
1750                         c->inversion = INVERSION_OFF;
1751                         break;
1752                 case CXD2880_TNRDMD_SPECTRUM_INV:
1753                         c->inversion = INVERSION_ON;
1754                         break;
1755                 default:
1756                         c->inversion = INVERSION_OFF;
1757                         pr_debug("spectrum sense is invalid %d\n", sense);
1758                         break;
1759                 }
1760         } else {
1761                 c->inversion = INVERSION_OFF;
1762                 pr_debug("SpectrumSense %d\n", ret);
1763         }
1764
1765         mutex_lock(priv->spi_mutex);
1766         ret = cxd2880_tnrdmd_mon_rf_lvl(&priv->tnrdmd, &strength);
1767         mutex_unlock(priv->spi_mutex);
1768         if (!ret) {
1769                 c->strength.len = 1;
1770                 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1771                 c->strength.stat[0].svalue = strength;
1772         } else {
1773                 c->strength.len = 1;
1774                 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1775                 pr_debug("mon_rf_lvl %d\n", ret);
1776         }
1777
1778         ret = cxd2880_read_snr(fe, &snr);
1779         if (!ret) {
1780                 c->cnr.len = 1;
1781                 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1782                 c->cnr.stat[0].svalue = snr;
1783         } else {
1784                 c->cnr.len = 1;
1785                 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1786                 pr_debug("read_snr %d\n", ret);
1787         }
1788
1789         return 0;
1790 }
1791
1792 static int cxd2880_get_frontend(struct dvb_frontend *fe,
1793                                 struct dtv_frontend_properties *props)
1794 {
1795         int ret;
1796
1797         if (!fe || !props) {
1798                 pr_err("invalid arg.");
1799                 return -EINVAL;
1800         }
1801
1802         pr_debug("system=%d\n", fe->dtv_property_cache.delivery_system);
1803         switch (fe->dtv_property_cache.delivery_system) {
1804         case SYS_DVBT:
1805                 ret = cxd2880_get_frontend_t(fe, props);
1806                 break;
1807         case SYS_DVBT2:
1808                 ret = cxd2880_get_frontend_t2(fe, props);
1809                 break;
1810         default:
1811                 ret = -EINVAL;
1812                 break;
1813         }
1814
1815         return ret;
1816 }
1817
1818 static enum dvbfe_algo cxd2880_get_frontend_algo(struct dvb_frontend *fe)
1819 {
1820         return DVBFE_ALGO_HW;
1821 }
1822
1823 static struct dvb_frontend_ops cxd2880_dvbt_t2_ops = {
1824         .info = {
1825                 .name = "Sony CXD2880",
1826                 .frequency_min =  174000000,
1827                 .frequency_max = 862000000,
1828                 .frequency_stepsize = 1000,
1829                 .caps = FE_CAN_INVERSION_AUTO |
1830                                 FE_CAN_FEC_1_2 |
1831                                 FE_CAN_FEC_2_3 |
1832                                 FE_CAN_FEC_3_4 |
1833                                 FE_CAN_FEC_4_5 |
1834                                 FE_CAN_FEC_5_6  |
1835                                 FE_CAN_FEC_7_8  |
1836                                 FE_CAN_FEC_AUTO |
1837                                 FE_CAN_QPSK |
1838                                 FE_CAN_QAM_16 |
1839                                 FE_CAN_QAM_32 |
1840                                 FE_CAN_QAM_64 |
1841                                 FE_CAN_QAM_128 |
1842                                 FE_CAN_QAM_256 |
1843                                 FE_CAN_QAM_AUTO |
1844                                 FE_CAN_TRANSMISSION_MODE_AUTO |
1845                                 FE_CAN_GUARD_INTERVAL_AUTO |
1846                                 FE_CAN_2G_MODULATION |
1847                                 FE_CAN_RECOVER |
1848                                 FE_CAN_MUTE_TS,
1849         },
1850         .delsys = { SYS_DVBT, SYS_DVBT2 },
1851
1852         .release = cxd2880_release,
1853         .init = cxd2880_init,
1854         .sleep = cxd2880_sleep,
1855         .tune = cxd2880_tune,
1856         .set_frontend = cxd2880_set_frontend,
1857         .get_frontend = cxd2880_get_frontend,
1858         .read_status = cxd2880_read_status,
1859         .read_ber = cxd2880_read_ber,
1860         .read_signal_strength = cxd2880_read_signal_strength,
1861         .read_snr = cxd2880_read_snr,
1862         .read_ucblocks = cxd2880_read_ucblocks,
1863         .get_frontend_algo = cxd2880_get_frontend_algo,
1864 };
1865
1866 struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe,
1867                                     struct cxd2880_config *cfg)
1868 {
1869         int ret;
1870         enum cxd2880_tnrdmd_chip_id chipid =
1871                                         CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
1872         static struct cxd2880_priv *priv;
1873         u8 data = 0;
1874
1875         if (!fe) {
1876                 pr_err("invalid arg.\n");
1877                 return NULL;
1878         }
1879
1880         priv = kzalloc(sizeof(struct cxd2880_priv), GFP_KERNEL);
1881         if (!priv)
1882                 return NULL;
1883
1884         priv->spi = cfg->spi;
1885         priv->spi_mutex = cfg->spi_mutex;
1886         priv->spi_device.spi = cfg->spi;
1887
1888         memcpy(&fe->ops, &cxd2880_dvbt_t2_ops,
1889                sizeof(struct dvb_frontend_ops));
1890
1891         ret = cxd2880_spi_device_initialize(&priv->spi_device,
1892                                             CXD2880_SPI_MODE_0,
1893                                             55000000);
1894         if (ret) {
1895                 pr_err("spi_device_initialize failed. %d\n", ret);
1896                 kfree(priv);
1897                 return NULL;
1898         }
1899
1900         ret = cxd2880_spi_device_create_spi(&priv->cxd2880_spi,
1901                                             &priv->spi_device);
1902         if (ret) {
1903                 pr_err("spi_device_create_spi failed. %d\n", ret);
1904                 kfree(priv);
1905                 return NULL;
1906         }
1907
1908         ret = cxd2880_io_spi_create(&priv->regio, &priv->cxd2880_spi, 0);
1909         if (ret) {
1910                 pr_err("io_spi_create failed. %d\n", ret);
1911                 kfree(priv);
1912                 return NULL;
1913         }
1914         ret = priv->regio.write_reg(&priv->regio,
1915                                     CXD2880_IO_TGT_SYS, 0x00, 0x00);
1916         if (ret) {
1917                 pr_err("set bank to 0x00 failed.\n");
1918                 kfree(priv);
1919                 return NULL;
1920         }
1921         ret = priv->regio.read_regs(&priv->regio,
1922                                     CXD2880_IO_TGT_SYS, 0xfd, &data, 1);
1923         if (ret) {
1924                 pr_err("read chip id failed.\n");
1925                 kfree(priv);
1926                 return NULL;
1927         }
1928
1929         chipid = (enum cxd2880_tnrdmd_chip_id)data;
1930         if (chipid != CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X &&
1931             chipid != CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11) {
1932                 pr_err("chip id invalid.\n");
1933                 kfree(priv);
1934                 return NULL;
1935         }
1936
1937         fe->demodulator_priv = priv;
1938         pr_info("CXD2880 driver version: Ver %s\n",
1939                 CXD2880_TNRDMD_DRIVER_VERSION);
1940
1941         return fe;
1942 }
1943 EXPORT_SYMBOL(cxd2880_attach);
1944
1945 MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver");
1946 MODULE_AUTHOR("Sony Semiconductor Solutions Corporation");
1947 MODULE_LICENSE("GPL v2");