Advertisement
Guest User

PCTV_290e_new_for_2.6.38.patch

a guest
May 7th, 2011
457
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 96.33 KB | None | 0 0
  1. diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
  2. index 9ad4454..88a5b3e 100644
  3. --- a/drivers/media/common/tuners/tda18271-fe.c
  4. +++ b/drivers/media/common/tuners/tda18271-fe.c
  5. @@ -975,6 +975,10 @@ static int tda18271_set_params(struct dvb_frontend *fe,
  6.                         tda_warn("bandwidth not set!\n");
  7.                         return -EINVAL;
  8.                 }
  9. +       } else if (fe->ops.info.type == FE_QAM) {
  10. +               /* DVB-C */
  11. +               map = &std_map->qam_8;
  12. +               bw = 8000000;
  13.         } else {
  14.                 tda_warn("modulation type not supported!\n");
  15.                 return -EINVAL;
  16. diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
  17. index b8519ba..71ca237 100644
  18. --- a/drivers/media/dvb/frontends/Kconfig
  19. +++ b/drivers/media/dvb/frontends/Kconfig
  20. @@ -370,6 +370,13 @@ config DVB_EC100
  21.         help
  22.           Say Y when you want to support this frontend.
  23.  
  24. +config DVB_CXD2820R
  25. +       tristate "Sony CXD2820R"
  26. +       depends on DVB_CORE && I2C
  27. +       default m if DVB_FE_CUSTOMISE
  28. +       help
  29. +         Say Y when you want to support this frontend.
  30. +
  31.  comment "DVB-C (cable) frontends"
  32.         depends on DVB_CORE
  33.  
  34. diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
  35. index b1d9525..c9195d0 100644
  36. --- a/drivers/media/dvb/frontends/Makefile
  37. +++ b/drivers/media/dvb/frontends/Makefile
  38. @@ -8,6 +8,7 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
  39.  stb0899-objs = stb0899_drv.o stb0899_algo.o
  40.  stv0900-objs = stv0900_core.o stv0900_sw.o
  41.  au8522-objs = au8522_dig.o au8522_decoder.o
  42. +cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
  43.  
  44.  obj-$(CONFIG_DVB_PLL) += dvb-pll.o
  45.  obj-$(CONFIG_DVB_STV0299) += stv0299.o
  46. @@ -83,3 +84,4 @@ obj-$(CONFIG_DVB_DS3000) += ds3000.o
  47.  obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
  48.  obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
  49.  obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
  50. +obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
  51. diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h
  52. new file mode 100644
  53. index 0000000..ad17845
  54. --- /dev/null
  55. +++ b/drivers/media/dvb/frontends/cxd2820r.h
  56. @@ -0,0 +1,118 @@
  57. +/*
  58. + * Sony CXD2820R demodulator driver
  59. + *
  60. + * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
  61. + *
  62. + *    This program is free software; you can redistribute it and/or modify
  63. + *    it under the terms of the GNU General Public License as published by
  64. + *    the Free Software Foundation; either version 2 of the License, or
  65. + *    (at your option) any later version.
  66. + *
  67. + *    This program is distributed in the hope that it will be useful,
  68. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  69. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  70. + *    GNU General Public License for more details.
  71. + *
  72. + *    You should have received a copy of the GNU General Public License along
  73. + *    with this program; if not, write to the Free Software Foundation, Inc.,
  74. + *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  75. + */
  76. +
  77. +
  78. +#ifndef CXD2820R_H
  79. +#define CXD2820R_H
  80. +
  81. +#include <linux/dvb/frontend.h>
  82. +
  83. +#define CXD2820R_GPIO_D (0 << 0) /* disable */
  84. +#define CXD2820R_GPIO_E (1 << 0) /* enable */
  85. +#define CXD2820R_GPIO_O (0 << 1) /* output */
  86. +#define CXD2820R_GPIO_I (1 << 1) /* input */
  87. +#define CXD2820R_GPIO_L (0 << 2) /* output low */
  88. +#define CXD2820R_GPIO_H (1 << 2) /* output high */
  89. +
  90. +#define CXD2820R_TS_SERIAL        0x08
  91. +#define CXD2820R_TS_SERIAL_MSB    0x28
  92. +#define CXD2820R_TS_PARALLEL      0x30
  93. +#define CXD2820R_TS_PARALLEL_MSB  0x70
  94. +
  95. +struct cxd2820r_config {
  96. +       /* Demodulator I2C address.
  97. +        * Driver determines DVB-C slave I2C address automatically from master
  98. +        * address.
  99. +        * Default: none, must set
  100. +        * Values: 0x6c, 0x6d
  101. +        */
  102. +       u8 i2c_address;
  103. +
  104. +       /* TS output mode.
  105. +        * Default: none, must set.
  106. +        * Values:
  107. +        */
  108. +       u8 ts_mode;
  109. +
  110. +       /* IF AGC polarity.
  111. +        * Default: 0
  112. +        * Values: 0, 1
  113. +        */
  114. +       int if_agc_polarity:1;
  115. +
  116. +       /* Spectrum inversion.
  117. +        * Default: 0
  118. +        * Values: 0, 1
  119. +        */
  120. +       int spec_inv:1;
  121. +
  122. +       /* IFs for all used modes.
  123. +        * Default: none, must set
  124. +        * Values: <kHz>
  125. +        */
  126. +       u16 if_dvbt_6;
  127. +       u16 if_dvbt_7;
  128. +       u16 if_dvbt_8;
  129. +       u16 if_dvbt2_5;
  130. +       u16 if_dvbt2_6;
  131. +       u16 if_dvbt2_7;
  132. +       u16 if_dvbt2_8;
  133. +       u16 if_dvbc;
  134. +
  135. +       /* GPIOs for all used modes.
  136. +        * Default: none, disabled
  137. +        * Values: <see above>
  138. +        */
  139. +       u8 gpio_dvbt[3];
  140. +       u8 gpio_dvbt2[3];
  141. +       u8 gpio_dvbc[3];
  142. +};
  143. +
  144. +
  145. +#if defined(CONFIG_DVB_CXD2820R) || \
  146. +       (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
  147. +extern struct dvb_frontend *cxd2820r_attach(
  148. +       const struct cxd2820r_config *config,
  149. +       struct i2c_adapter *i2c,
  150. +       struct dvb_frontend *fe
  151. +);
  152. +extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
  153. +       struct dvb_frontend *fe
  154. +);
  155. +#else
  156. +static inline struct dvb_frontend *cxd2820r_attach(
  157. +       const struct cxd2820r_config *config,
  158. +       struct i2c_adapter *i2c,
  159. +       struct dvb_frontend *fe
  160. +)
  161. +{
  162. +       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
  163. +       return NULL;
  164. +}
  165. +static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
  166. +       struct dvb_frontend *fe
  167. +)
  168. +{
  169. +       return NULL;
  170. +}
  171. +
  172. +#endif
  173. +
  174. +#endif /* CXD2820R_H */
  175. diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
  176. new file mode 100644
  177. index 0000000..3c07d40
  178. --- /dev/null
  179. +++ b/drivers/media/dvb/frontends/cxd2820r_c.c
  180. @@ -0,0 +1,338 @@
  181. +/*
  182. + * Sony CXD2820R demodulator driver
  183. + *
  184. + * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
  185. + *
  186. + *    This program is free software; you can redistribute it and/or modify
  187. + *    it under the terms of the GNU General Public License as published by
  188. + *    the Free Software Foundation; either version 2 of the License, or
  189. + *    (at your option) any later version.
  190. + *
  191. + *    This program is distributed in the hope that it will be useful,
  192. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  193. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  194. + *    GNU General Public License for more details.
  195. + *
  196. + *    You should have received a copy of the GNU General Public License along
  197. + *    with this program; if not, write to the Free Software Foundation, Inc.,
  198. + *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  199. + */
  200. +
  201. +
  202. +#include "cxd2820r_priv.h"
  203. +
  204. +int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
  205. +       struct dvb_frontend_parameters *params)
  206. +{
  207. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  208. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  209. +       int ret, i;
  210. +       u8 buf[2];
  211. +       u16 if_ctl;
  212. +       u64 num;
  213. +       struct reg_val_mask tab[] = {
  214. +               { 0x00080, 0x01, 0xff },
  215. +               { 0x00081, 0x05, 0xff },
  216. +               { 0x00085, 0x07, 0xff },
  217. +               { 0x00088, 0x01, 0xff },
  218. +
  219. +               { 0x00082, 0x20, 0x60 },
  220. +               { 0x1016a, 0x48, 0xff },
  221. +               { 0x100a5, 0x00, 0x01 },
  222. +               { 0x10020, 0x06, 0x07 },
  223. +               { 0x10059, 0x50, 0xff },
  224. +               { 0x10087, 0x0c, 0x3c },
  225. +               { 0x1008b, 0x07, 0xff },
  226. +               { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
  227. +               { 0x10070, priv->cfg.ts_mode, 0xff },
  228. +       };
  229. +
  230. +       dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
  231. +
  232. +       /* update GPIOs */
  233. +       ret = cxd2820r_gpio(fe);
  234. +       if (ret)
  235. +               goto error;
  236. +
  237. +       /* program tuner */
  238. +       if (fe->ops.tuner_ops.set_params)
  239. +               fe->ops.tuner_ops.set_params(fe, params);
  240. +
  241. +       if (priv->delivery_system !=  SYS_DVBC_ANNEX_AC) {
  242. +               for (i = 0; i < ARRAY_SIZE(tab); i++) {
  243. +                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
  244. +                               tab[i].val, tab[i].mask);
  245. +                       if (ret)
  246. +                               goto error;
  247. +               }
  248. +       }
  249. +
  250. +       priv->delivery_system = SYS_DVBC_ANNEX_AC;
  251. +       priv->ber_running = 0; /* tune stops BER counter */
  252. +
  253. +       num = priv->cfg.if_dvbc;
  254. +       num *= 0x4000;
  255. +       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
  256. +       buf[0] = (if_ctl >> 8) & 0x3f;
  257. +       buf[1] = (if_ctl >> 0) & 0xff;
  258. +
  259. +       ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2);
  260. +       if (ret)
  261. +               goto error;
  262. +
  263. +       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
  264. +       if (ret)
  265. +               goto error;
  266. +
  267. +       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
  268. +       if (ret)
  269. +               goto error;
  270. +
  271. +       return ret;
  272. +error:
  273. +       dbg("%s: failed:%d", __func__, ret);
  274. +       return ret;
  275. +}
  276. +
  277. +int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
  278. +       struct dvb_frontend_parameters *p)
  279. +{
  280. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  281. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  282. +       int ret;
  283. +       u8 buf[2];
  284. +
  285. +       ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2);
  286. +       if (ret)
  287. +               goto error;
  288. +
  289. +       c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
  290. +
  291. +       ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]);
  292. +       if (ret)
  293. +               goto error;
  294. +
  295. +       switch ((buf[0] >> 0) & 0x03) {
  296. +       case 0:
  297. +               c->modulation = QAM_16;
  298. +               break;
  299. +       case 1:
  300. +               c->modulation = QAM_32;
  301. +               break;
  302. +       case 2:
  303. +               c->modulation = QAM_64;
  304. +               break;
  305. +       case 3:
  306. +               c->modulation = QAM_128;
  307. +               break;
  308. +       case 4:
  309. +               c->modulation = QAM_256;
  310. +               break;
  311. +       }
  312. +
  313. +       switch ((buf[0] >> 7) & 0x01) {
  314. +       case 0:
  315. +               c->inversion = INVERSION_OFF;
  316. +               break;
  317. +       case 1:
  318. +               c->inversion = INVERSION_ON;
  319. +               break;
  320. +       }
  321. +
  322. +       return ret;
  323. +error:
  324. +       dbg("%s: failed:%d", __func__, ret);
  325. +       return ret;
  326. +}
  327. +
  328. +int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
  329. +{
  330. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  331. +       int ret;
  332. +       u8 buf[3], start_ber = 0;
  333. +       *ber = 0;
  334. +
  335. +       if (priv->ber_running) {
  336. +               ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
  337. +               if (ret)
  338. +                       goto error;
  339. +
  340. +               if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
  341. +                       *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
  342. +                       start_ber = 1;
  343. +               }
  344. +       } else {
  345. +               priv->ber_running = 1;
  346. +               start_ber = 1;
  347. +       }
  348. +
  349. +       if (start_ber) {
  350. +               /* (re)start BER */
  351. +               ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
  352. +               if (ret)
  353. +                       goto error;
  354. +       }
  355. +
  356. +       return ret;
  357. +error:
  358. +       dbg("%s: failed:%d", __func__, ret);
  359. +       return ret;
  360. +}
  361. +
  362. +int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
  363. +       u16 *strength)
  364. +{
  365. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  366. +       int ret;
  367. +       u8 buf[2];
  368. +       u16 tmp;
  369. +
  370. +       ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
  371. +       if (ret)
  372. +               goto error;
  373. +
  374. +       tmp = (buf[0] & 0x03) << 8 | buf[1];
  375. +       tmp = (~tmp & 0x03ff);
  376. +
  377. +       if (tmp == 512)
  378. +               /* ~no signal */
  379. +               tmp = 0;
  380. +       else if (tmp > 350)
  381. +               tmp = 350;
  382. +
  383. +       /* scale value to 0x0000-0xffff */
  384. +       *strength = tmp * 0xffff / (350-0);
  385. +
  386. +       return ret;
  387. +error:
  388. +       dbg("%s: failed:%d", __func__, ret);
  389. +       return ret;
  390. +}
  391. +
  392. +int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
  393. +{
  394. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  395. +       int ret;
  396. +       u8 tmp;
  397. +       unsigned int A, B;
  398. +       /* report SNR in dB * 10 */
  399. +
  400. +       ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
  401. +       if (ret)
  402. +               goto error;
  403. +
  404. +       if (((tmp >> 0) & 0x03) % 2) {
  405. +               A = 875;
  406. +               B = 650;
  407. +       } else {
  408. +               A = 950;
  409. +               B = 760;
  410. +       }
  411. +
  412. +       ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
  413. +       if (ret)
  414. +               goto error;
  415. +
  416. +       #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
  417. +       if (tmp)
  418. +               *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
  419. +                       / 10;
  420. +       else
  421. +               *snr = 0;
  422. +
  423. +       return ret;
  424. +error:
  425. +       dbg("%s: failed:%d", __func__, ret);
  426. +       return ret;
  427. +}
  428. +
  429. +int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
  430. +{
  431. +       *ucblocks = 0;
  432. +       /* no way to read ? */
  433. +       return 0;
  434. +}
  435. +
  436. +int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
  437. +{
  438. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  439. +       int ret;
  440. +       u8 buf[2];
  441. +       *status = 0;
  442. +
  443. +       ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf));
  444. +       if (ret)
  445. +               goto error;
  446. +
  447. +       if (((buf[0] >> 0) & 0x01) == 1) {
  448. +               *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
  449. +                       FE_HAS_VITERBI | FE_HAS_SYNC;
  450. +
  451. +               if (((buf[1] >> 3) & 0x01) == 1) {
  452. +                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
  453. +                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
  454. +               }
  455. +       }
  456. +
  457. +       dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
  458. +
  459. +       return ret;
  460. +error:
  461. +       dbg("%s: failed:%d", __func__, ret);
  462. +       return ret;
  463. +}
  464. +
  465. +int cxd2820r_init_c(struct dvb_frontend *fe)
  466. +{
  467. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  468. +       int ret;
  469. +
  470. +       ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
  471. +       if (ret)
  472. +               goto error;
  473. +
  474. +       return ret;
  475. +error:
  476. +       dbg("%s: failed:%d", __func__, ret);
  477. +       return ret;
  478. +}
  479. +
  480. +int cxd2820r_sleep_c(struct dvb_frontend *fe)
  481. +{
  482. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  483. +       int ret, i;
  484. +       struct reg_val_mask tab[] = {
  485. +               { 0x000ff, 0x1f, 0xff },
  486. +               { 0x00085, 0x00, 0xff },
  487. +               { 0x00088, 0x01, 0xff },
  488. +               { 0x00081, 0x00, 0xff },
  489. +               { 0x00080, 0x00, 0xff },
  490. +       };
  491. +
  492. +       dbg("%s", __func__);
  493. +
  494. +       priv->delivery_system = SYS_UNDEFINED;
  495. +
  496. +       for (i = 0; i < ARRAY_SIZE(tab); i++) {
  497. +               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
  498. +                       tab[i].mask);
  499. +               if (ret)
  500. +                       goto error;
  501. +       }
  502. +
  503. +       return ret;
  504. +error:
  505. +       dbg("%s: failed:%d", __func__, ret);
  506. +       return ret;
  507. +}
  508. +
  509. +int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
  510. +       struct dvb_frontend_tune_settings *s)
  511. +{
  512. +       s->min_delay_ms = 500;
  513. +       s->step_size = 0; /* no zigzag */
  514. +       s->max_drift = 0;
  515. +
  516. +       return 0;
  517. +}
  518. +
  519. diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
  520. new file mode 100644
  521. index 0000000..e900c4c
  522. --- /dev/null
  523. +++ b/drivers/media/dvb/frontends/cxd2820r_core.c
  524. @@ -0,0 +1,914 @@
  525. +/*
  526. + * Sony CXD2820R demodulator driver
  527. + *
  528. + * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
  529. + *
  530. + *    This program is free software; you can redistribute it and/or modify
  531. + *    it under the terms of the GNU General Public License as published by
  532. + *    the Free Software Foundation; either version 2 of the License, or
  533. + *    (at your option) any later version.
  534. + *
  535. + *    This program is distributed in the hope that it will be useful,
  536. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  537. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  538. + *    GNU General Public License for more details.
  539. + *
  540. + *    You should have received a copy of the GNU General Public License along
  541. + *    with this program; if not, write to the Free Software Foundation, Inc.,
  542. + *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  543. + */
  544. +
  545. +
  546. +#include "cxd2820r_priv.h"
  547. +
  548. +int cxd2820r_debug;
  549. +module_param_named(debug, cxd2820r_debug, int, 0644);
  550. +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  551. +
  552. +/* write multiple registers */
  553. +static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
  554. +       u8 *val, int len)
  555. +{
  556. +       int ret;
  557. +       u8 buf[len+1];
  558. +       struct i2c_msg msg[1] = {
  559. +               {
  560. +                       .addr = i2c,
  561. +                       .flags = 0,
  562. +                       .len = sizeof(buf),
  563. +                       .buf = buf,
  564. +               }
  565. +       };
  566. +
  567. +       buf[0] = reg;
  568. +       memcpy(&buf[1], val, len);
  569. +
  570. +       ret = i2c_transfer(priv->i2c, msg, 1);
  571. +       if (ret == 1) {
  572. +               ret = 0;
  573. +       } else {
  574. +               warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
  575. +               ret = -EREMOTEIO;
  576. +       }
  577. +       return ret;
  578. +}
  579. +
  580. +/* read multiple registers */
  581. +static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
  582. +       u8 *val, int len)
  583. +{
  584. +       int ret;
  585. +       u8 buf[len];
  586. +       struct i2c_msg msg[2] = {
  587. +               {
  588. +                       .addr = i2c,
  589. +                       .flags = 0,
  590. +                       .len = 1,
  591. +                       .buf = &reg,
  592. +               }, {
  593. +                       .addr = i2c,
  594. +                       .flags = I2C_M_RD,
  595. +                       .len = sizeof(buf),
  596. +                       .buf = buf,
  597. +               }
  598. +       };
  599. +
  600. +       ret = i2c_transfer(priv->i2c, msg, 2);
  601. +       if (ret == 2) {
  602. +               memcpy(val, buf, len);
  603. +               ret = 0;
  604. +       } else {
  605. +               warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
  606. +               ret = -EREMOTEIO;
  607. +       }
  608. +
  609. +       return ret;
  610. +}
  611. +
  612. +/* write multiple registers */
  613. +int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
  614. +       int len)
  615. +{
  616. +       int ret;
  617. +       u8 i2c_addr;
  618. +       u8 reg = (reginfo >> 0) & 0xff;
  619. +       u8 bank = (reginfo >> 8) & 0xff;
  620. +       u8 i2c = (reginfo >> 16) & 0x01;
  621. +
  622. +       /* select I2C */
  623. +       if (i2c)
  624. +               i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
  625. +       else
  626. +               i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
  627. +
  628. +       /* switch bank if needed */
  629. +       if (bank != priv->bank[i2c]) {
  630. +               ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
  631. +               if (ret)
  632. +                       return ret;
  633. +               priv->bank[i2c] = bank;
  634. +       }
  635. +       return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
  636. +}
  637. +
  638. +/* read multiple registers */
  639. +int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
  640. +       int len)
  641. +{
  642. +       int ret;
  643. +       u8 i2c_addr;
  644. +       u8 reg = (reginfo >> 0) & 0xff;
  645. +       u8 bank = (reginfo >> 8) & 0xff;
  646. +       u8 i2c = (reginfo >> 16) & 0x01;
  647. +
  648. +       /* select I2C */
  649. +       if (i2c)
  650. +               i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
  651. +       else
  652. +               i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
  653. +
  654. +       /* switch bank if needed */
  655. +       if (bank != priv->bank[i2c]) {
  656. +               ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
  657. +               if (ret)
  658. +                       return ret;
  659. +               priv->bank[i2c] = bank;
  660. +       }
  661. +       return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
  662. +}
  663. +
  664. +/* write single register */
  665. +int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
  666. +{
  667. +       return cxd2820r_wr_regs(priv, reg, &val, 1);
  668. +}
  669. +
  670. +/* read single register */
  671. +int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
  672. +{
  673. +       return cxd2820r_rd_regs(priv, reg, val, 1);
  674. +}
  675. +
  676. +/* write single register with mask */
  677. +int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
  678. +       u8 mask)
  679. +{
  680. +       int ret;
  681. +       u8 tmp;
  682. +
  683. +       /* no need for read if whole reg is written */
  684. +       if (mask != 0xff) {
  685. +               ret = cxd2820r_rd_reg(priv, reg, &tmp);
  686. +               if (ret)
  687. +                       return ret;
  688. +
  689. +               val &= mask;
  690. +               tmp &= ~mask;
  691. +               val |= tmp;
  692. +       }
  693. +
  694. +       return cxd2820r_wr_reg(priv, reg, val);
  695. +}
  696. +
  697. +int cxd2820r_gpio(struct dvb_frontend *fe)
  698. +{
  699. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  700. +       int ret, i;
  701. +       u8 *gpio, tmp0, tmp1;
  702. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  703. +
  704. +       switch (fe->dtv_property_cache.delivery_system) {
  705. +       case SYS_DVBT:
  706. +               gpio = priv->cfg.gpio_dvbt;
  707. +               break;
  708. +       case SYS_DVBT2:
  709. +               gpio = priv->cfg.gpio_dvbt2;
  710. +               break;
  711. +       case SYS_DVBC_ANNEX_AC:
  712. +               gpio = priv->cfg.gpio_dvbc;
  713. +               break;
  714. +       default:
  715. +               ret = -EINVAL;
  716. +               goto error;
  717. +       }
  718. +
  719. +       /* update GPIOs only when needed */
  720. +       if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
  721. +               return 0;
  722. +
  723. +       tmp0 = 0x00;
  724. +       tmp1 = 0x00;
  725. +       for (i = 0; i < sizeof(priv->gpio); i++) {
  726. +               /* enable / disable */
  727. +               if (gpio[i] & CXD2820R_GPIO_E)
  728. +                       tmp0 |= (2 << 6) >> (2 * i);
  729. +               else
  730. +                       tmp0 |= (1 << 6) >> (2 * i);
  731. +
  732. +               /* input / output */
  733. +               if (gpio[i] & CXD2820R_GPIO_I)
  734. +                       tmp1 |= (1 << (3 + i));
  735. +               else
  736. +                       tmp1 |= (0 << (3 + i));
  737. +
  738. +               /* high / low */
  739. +               if (gpio[i] & CXD2820R_GPIO_H)
  740. +                       tmp1 |= (1 << (0 + i));
  741. +               else
  742. +                       tmp1 |= (0 << (0 + i));
  743. +
  744. +               dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
  745. +       }
  746. +
  747. +       dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
  748. +
  749. +       /* write bits [7:2] */
  750. +       ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
  751. +       if (ret)
  752. +               goto error;
  753. +
  754. +       /* write bits [5:0] */
  755. +       ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
  756. +       if (ret)
  757. +               goto error;
  758. +
  759. +       memcpy(priv->gpio, gpio, sizeof(priv->gpio));
  760. +
  761. +       return ret;
  762. +error:
  763. +       dbg("%s: failed:%d", __func__, ret);
  764. +       return ret;
  765. +}
  766. +
  767. +/* lock FE */
  768. +static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe)
  769. +{
  770. +       int ret = 0;
  771. +       dbg("%s: active_fe=%d", __func__, active_fe);
  772. +
  773. +       mutex_lock(&priv->fe_lock);
  774. +
  775. +       /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
  776. +       if (priv->active_fe == active_fe)
  777. +               ;
  778. +       else if (priv->active_fe == -1)
  779. +               priv->active_fe = active_fe;
  780. +       else
  781. +               ret = -EBUSY;
  782. +
  783. +       mutex_unlock(&priv->fe_lock);
  784. +
  785. +       return ret;
  786. +}
  787. +
  788. +/* unlock FE */
  789. +static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe)
  790. +{
  791. +       dbg("%s: active_fe=%d", __func__, active_fe);
  792. +
  793. +       mutex_lock(&priv->fe_lock);
  794. +
  795. +       /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
  796. +       if (priv->active_fe == active_fe)
  797. +               priv->active_fe = -1;
  798. +
  799. +       mutex_unlock(&priv->fe_lock);
  800. +
  801. +       return;
  802. +}
  803. +
  804. +/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
  805. +u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
  806. +{
  807. +       return div_u64(dividend + (divisor / 2), divisor);
  808. +}
  809. +
  810. +static int cxd2820r_set_frontend(struct dvb_frontend *fe,
  811. +       struct dvb_frontend_parameters *p)
  812. +{
  813. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  814. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  815. +       int ret;
  816. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  817. +
  818. +       if (fe->ops.info.type == FE_OFDM) {
  819. +               /* DVB-T/T2 */
  820. +               ret = cxd2820r_lock(priv, 0);
  821. +               if (ret)
  822. +                       return ret;
  823. +
  824. +               switch (priv->delivery_system) {
  825. +               case SYS_UNDEFINED:
  826. +                       if (c->delivery_system == SYS_DVBT) {
  827. +                               /* SLEEP => DVB-T */
  828. +                               ret = cxd2820r_set_frontend_t(fe, p);
  829. +                       } else {
  830. +                               /* SLEEP => DVB-T2 */
  831. +                               ret = cxd2820r_set_frontend_t2(fe, p);
  832. +                       }
  833. +                       break;
  834. +               case SYS_DVBT:
  835. +                       if (c->delivery_system == SYS_DVBT) {
  836. +                               /* DVB-T => DVB-T */
  837. +                               ret = cxd2820r_set_frontend_t(fe, p);
  838. +                       } else if (c->delivery_system == SYS_DVBT2) {
  839. +                               /* DVB-T => DVB-T2 */
  840. +                               ret = cxd2820r_sleep_t(fe);
  841. +                               ret = cxd2820r_set_frontend_t2(fe, p);
  842. +                       }
  843. +                       break;
  844. +               case SYS_DVBT2:
  845. +                       if (c->delivery_system == SYS_DVBT2) {
  846. +                               /* DVB-T2 => DVB-T2 */
  847. +                               ret = cxd2820r_set_frontend_t2(fe, p);
  848. +                       } else if (c->delivery_system == SYS_DVBT) {
  849. +                               /* DVB-T2 => DVB-T */
  850. +                               ret = cxd2820r_sleep_t2(fe);
  851. +                               ret = cxd2820r_set_frontend_t(fe, p);
  852. +                       }
  853. +                       break;
  854. +               default:
  855. +                       dbg("%s: error state=%d", __func__,
  856. +                               priv->delivery_system);
  857. +                       ret = -EINVAL;
  858. +               }
  859. +       } else {
  860. +               /* DVB-C */
  861. +               ret = cxd2820r_lock(priv, 1);
  862. +               if (ret)
  863. +                       return ret;
  864. +
  865. +               ret = cxd2820r_set_frontend_c(fe, p);
  866. +       }
  867. +
  868. +       return ret;
  869. +}
  870. +
  871. +static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
  872. +{
  873. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  874. +       int ret;
  875. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  876. +
  877. +       if (fe->ops.info.type == FE_OFDM) {
  878. +               /* DVB-T/T2 */
  879. +               ret = cxd2820r_lock(priv, 0);
  880. +               if (ret)
  881. +                       return ret;
  882. +
  883. +               switch (fe->dtv_property_cache.delivery_system) {
  884. +               case SYS_DVBT:
  885. +                       ret = cxd2820r_read_status_t(fe, status);
  886. +                       break;
  887. +               case SYS_DVBT2:
  888. +                       ret = cxd2820r_read_status_t2(fe, status);
  889. +                       break;
  890. +               default:
  891. +                       ret = -EINVAL;
  892. +               }
  893. +       } else {
  894. +               /* DVB-C */
  895. +               ret = cxd2820r_lock(priv, 1);
  896. +               if (ret)
  897. +                       return ret;
  898. +
  899. +               ret = cxd2820r_read_status_c(fe, status);
  900. +       }
  901. +
  902. +       return ret;
  903. +}
  904. +
  905. +static int cxd2820r_get_frontend(struct dvb_frontend *fe,
  906. +       struct dvb_frontend_parameters *p)
  907. +{
  908. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  909. +       int ret;
  910. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  911. +
  912. +       if (fe->ops.info.type == FE_OFDM) {
  913. +               /* DVB-T/T2 */
  914. +               ret = cxd2820r_lock(priv, 0);
  915. +               if (ret)
  916. +                       return ret;
  917. +
  918. +               switch (fe->dtv_property_cache.delivery_system) {
  919. +               case SYS_DVBT:
  920. +                       ret = cxd2820r_get_frontend_t(fe, p);
  921. +                       break;
  922. +               case SYS_DVBT2:
  923. +                       ret = cxd2820r_get_frontend_t2(fe, p);
  924. +                       break;
  925. +               default:
  926. +                       ret = -EINVAL;
  927. +               }
  928. +       } else {
  929. +               /* DVB-C */
  930. +               ret = cxd2820r_lock(priv, 1);
  931. +               if (ret)
  932. +                       return ret;
  933. +
  934. +               ret = cxd2820r_get_frontend_c(fe, p);
  935. +       }
  936. +
  937. +       return ret;
  938. +}
  939. +
  940. +static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
  941. +{
  942. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  943. +       int ret;
  944. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  945. +
  946. +       if (fe->ops.info.type == FE_OFDM) {
  947. +               /* DVB-T/T2 */
  948. +               ret = cxd2820r_lock(priv, 0);
  949. +               if (ret)
  950. +                       return ret;
  951. +
  952. +               switch (fe->dtv_property_cache.delivery_system) {
  953. +               case SYS_DVBT:
  954. +                       ret = cxd2820r_read_ber_t(fe, ber);
  955. +                       break;
  956. +               case SYS_DVBT2:
  957. +                       ret = cxd2820r_read_ber_t2(fe, ber);
  958. +                       break;
  959. +               default:
  960. +                       ret = -EINVAL;
  961. +               }
  962. +       } else {
  963. +               /* DVB-C */
  964. +               ret = cxd2820r_lock(priv, 1);
  965. +               if (ret)
  966. +                       return ret;
  967. +
  968. +               ret = cxd2820r_read_ber_c(fe, ber);
  969. +       }
  970. +
  971. +       return ret;
  972. +}
  973. +
  974. +static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
  975. +{
  976. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  977. +       int ret;
  978. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  979. +
  980. +       if (fe->ops.info.type == FE_OFDM) {
  981. +               /* DVB-T/T2 */
  982. +               ret = cxd2820r_lock(priv, 0);
  983. +               if (ret)
  984. +                       return ret;
  985. +
  986. +               switch (fe->dtv_property_cache.delivery_system) {
  987. +               case SYS_DVBT:
  988. +                       ret = cxd2820r_read_signal_strength_t(fe, strength);
  989. +                       break;
  990. +               case SYS_DVBT2:
  991. +                       ret = cxd2820r_read_signal_strength_t2(fe, strength);
  992. +                       break;
  993. +               default:
  994. +                       ret = -EINVAL;
  995. +               }
  996. +       } else {
  997. +               /* DVB-C */
  998. +               ret = cxd2820r_lock(priv, 1);
  999. +               if (ret)
  1000. +                       return ret;
  1001. +
  1002. +               ret = cxd2820r_read_signal_strength_c(fe, strength);
  1003. +       }
  1004. +
  1005. +       return ret;
  1006. +}
  1007. +
  1008. +static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
  1009. +{
  1010. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1011. +       int ret;
  1012. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  1013. +
  1014. +       if (fe->ops.info.type == FE_OFDM) {
  1015. +               /* DVB-T/T2 */
  1016. +               ret = cxd2820r_lock(priv, 0);
  1017. +               if (ret)
  1018. +                       return ret;
  1019. +
  1020. +               switch (fe->dtv_property_cache.delivery_system) {
  1021. +               case SYS_DVBT:
  1022. +                       ret = cxd2820r_read_snr_t(fe, snr);
  1023. +                       break;
  1024. +               case SYS_DVBT2:
  1025. +                       ret = cxd2820r_read_snr_t2(fe, snr);
  1026. +                       break;
  1027. +               default:
  1028. +                       ret = -EINVAL;
  1029. +               }
  1030. +       } else {
  1031. +               /* DVB-C */
  1032. +               ret = cxd2820r_lock(priv, 1);
  1033. +               if (ret)
  1034. +                       return ret;
  1035. +
  1036. +               ret = cxd2820r_read_snr_c(fe, snr);
  1037. +       }
  1038. +
  1039. +       return ret;
  1040. +}
  1041. +
  1042. +static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
  1043. +{
  1044. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1045. +       int ret;
  1046. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  1047. +
  1048. +       if (fe->ops.info.type == FE_OFDM) {
  1049. +               /* DVB-T/T2 */
  1050. +               ret = cxd2820r_lock(priv, 0);
  1051. +               if (ret)
  1052. +                       return ret;
  1053. +
  1054. +               switch (fe->dtv_property_cache.delivery_system) {
  1055. +               case SYS_DVBT:
  1056. +                       ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
  1057. +                       break;
  1058. +               case SYS_DVBT2:
  1059. +                       ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
  1060. +                       break;
  1061. +               default:
  1062. +                       ret = -EINVAL;
  1063. +               }
  1064. +       } else {
  1065. +               /* DVB-C */
  1066. +               ret = cxd2820r_lock(priv, 1);
  1067. +               if (ret)
  1068. +                       return ret;
  1069. +
  1070. +               ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
  1071. +       }
  1072. +
  1073. +       return ret;
  1074. +}
  1075. +
  1076. +static int cxd2820r_init(struct dvb_frontend *fe)
  1077. +{
  1078. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1079. +       int ret;
  1080. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  1081. +
  1082. +       priv->delivery_system = SYS_UNDEFINED;
  1083. +       /* delivery system is unknown at that (init) phase */
  1084. +
  1085. +       if (fe->ops.info.type == FE_OFDM) {
  1086. +               /* DVB-T/T2 */
  1087. +               ret = cxd2820r_lock(priv, 0);
  1088. +               if (ret)
  1089. +                       return ret;
  1090. +
  1091. +               ret = cxd2820r_init_t(fe);
  1092. +       } else {
  1093. +               /* DVB-C */
  1094. +               ret = cxd2820r_lock(priv, 1);
  1095. +               if (ret)
  1096. +                       return ret;
  1097. +
  1098. +               ret = cxd2820r_init_c(fe);
  1099. +       }
  1100. +
  1101. +       return ret;
  1102. +}
  1103. +
  1104. +static int cxd2820r_sleep(struct dvb_frontend *fe)
  1105. +{
  1106. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1107. +       int ret;
  1108. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  1109. +
  1110. +       if (fe->ops.info.type == FE_OFDM) {
  1111. +               /* DVB-T/T2 */
  1112. +               ret = cxd2820r_lock(priv, 0);
  1113. +               if (ret)
  1114. +                       return ret;
  1115. +
  1116. +               switch (fe->dtv_property_cache.delivery_system) {
  1117. +               case SYS_DVBT:
  1118. +                       ret = cxd2820r_sleep_t(fe);
  1119. +                       break;
  1120. +               case SYS_DVBT2:
  1121. +                       ret = cxd2820r_sleep_t2(fe);
  1122. +                       break;
  1123. +               default:
  1124. +                       ret = -EINVAL;
  1125. +               }
  1126. +
  1127. +               cxd2820r_unlock(priv, 0);
  1128. +       } else {
  1129. +               /* DVB-C */
  1130. +               ret = cxd2820r_lock(priv, 1);
  1131. +               if (ret)
  1132. +                       return ret;
  1133. +
  1134. +               ret = cxd2820r_sleep_c(fe);
  1135. +
  1136. +               cxd2820r_unlock(priv, 1);
  1137. +       }
  1138. +
  1139. +       return ret;
  1140. +}
  1141. +
  1142. +static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
  1143. +       struct dvb_frontend_tune_settings *s)
  1144. +{
  1145. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1146. +       int ret;
  1147. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  1148. +
  1149. +       if (fe->ops.info.type == FE_OFDM) {
  1150. +               /* DVB-T/T2 */
  1151. +               ret = cxd2820r_lock(priv, 0);
  1152. +               if (ret)
  1153. +                       return ret;
  1154. +
  1155. +               switch (fe->dtv_property_cache.delivery_system) {
  1156. +               case SYS_DVBT:
  1157. +                       ret = cxd2820r_get_tune_settings_t(fe, s);
  1158. +                       break;
  1159. +               case SYS_DVBT2:
  1160. +                       ret = cxd2820r_get_tune_settings_t2(fe, s);
  1161. +                       break;
  1162. +               default:
  1163. +                       ret = -EINVAL;
  1164. +               }
  1165. +       } else {
  1166. +               /* DVB-C */
  1167. +               ret = cxd2820r_lock(priv, 1);
  1168. +               if (ret)
  1169. +                       return ret;
  1170. +
  1171. +               ret = cxd2820r_get_tune_settings_c(fe, s);
  1172. +       }
  1173. +
  1174. +       return ret;
  1175. +}
  1176. +
  1177. +static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe,
  1178. +       struct dvb_frontend_parameters *p)
  1179. +{
  1180. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1181. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  1182. +       int ret, i;
  1183. +       fe_status_t status = 0;
  1184. +       dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
  1185. +
  1186. +       /* switch between DVB-T and DVB-T2 when tune fails */
  1187. +       if (priv->last_tune_failed) {
  1188. +               if (priv->delivery_system == SYS_DVBT)
  1189. +                       c->delivery_system = SYS_DVBT2;
  1190. +               else
  1191. +                       c->delivery_system = SYS_DVBT;
  1192. +       }
  1193. +
  1194. +       /* set frontend */
  1195. +       ret = cxd2820r_set_frontend(fe, p);
  1196. +       if (ret)
  1197. +               goto error;
  1198. +
  1199. +
  1200. +       /* frontend lock wait loop count */
  1201. +       switch (priv->delivery_system) {
  1202. +       case SYS_DVBT:
  1203. +               i = 20;
  1204. +               break;
  1205. +       case SYS_DVBT2:
  1206. +               i = 40;
  1207. +               break;
  1208. +       case SYS_UNDEFINED:
  1209. +       default:
  1210. +               i = 0;
  1211. +               break;
  1212. +       }
  1213. +
  1214. +       /* wait frontend lock */
  1215. +       for (; i > 0; i--) {
  1216. +               dbg("%s: LOOP=%d", __func__, i);
  1217. +               msleep(50);
  1218. +               ret = cxd2820r_read_status(fe, &status);
  1219. +               if (ret)
  1220. +                       goto error;
  1221. +
  1222. +               if (status & FE_HAS_SIGNAL)
  1223. +                       break;
  1224. +       }
  1225. +
  1226. +       /* check if we have a valid signal */
  1227. +       if (status) {
  1228. +               priv->last_tune_failed = 0;
  1229. +               return DVBFE_ALGO_SEARCH_SUCCESS;
  1230. +       } else {
  1231. +               priv->last_tune_failed = 1;
  1232. +               return DVBFE_ALGO_SEARCH_AGAIN;
  1233. +       }
  1234. +
  1235. +error:
  1236. +       dbg("%s: failed:%d", __func__, ret);
  1237. +       return DVBFE_ALGO_SEARCH_ERROR;
  1238. +}
  1239. +
  1240. +static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
  1241. +{
  1242. +       return DVBFE_ALGO_CUSTOM;
  1243. +}
  1244. +
  1245. +static void cxd2820r_release(struct dvb_frontend *fe)
  1246. +{
  1247. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1248. +       dbg("%s", __func__);
  1249. +
  1250. +       if (fe->ops.info.type == FE_OFDM) {
  1251. +               i2c_del_adapter(&priv->tuner_i2c_adapter);
  1252. +               kfree(priv);
  1253. +       }
  1254. +
  1255. +       return;
  1256. +}
  1257. +
  1258. +static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter)
  1259. +{
  1260. +       return I2C_FUNC_I2C;
  1261. +}
  1262. +
  1263. +static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
  1264. +       struct i2c_msg msg[], int num)
  1265. +{
  1266. +       struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
  1267. +       u8 obuf[msg[0].len + 2];
  1268. +       struct i2c_msg msg2[2] = {
  1269. +               {
  1270. +                       .addr = priv->cfg.i2c_address,
  1271. +                       .flags = 0,
  1272. +                       .len = sizeof(obuf),
  1273. +                       .buf = obuf,
  1274. +               }, {
  1275. +                       .addr = priv->cfg.i2c_address,
  1276. +                       .flags = I2C_M_RD,
  1277. +                       .len = msg[1].len,
  1278. +                       .buf = msg[1].buf,
  1279. +               }
  1280. +       };
  1281. +
  1282. +       obuf[0] = 0x09;
  1283. +       obuf[1] = (msg[0].addr << 1);
  1284. +       if (num == 2) { /* I2C read */
  1285. +               obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
  1286. +               msg2[0].len = sizeof(obuf) - 1; /* maybe HW bug ? */
  1287. +       }
  1288. +       memcpy(&obuf[2], msg[0].buf, msg[0].len);
  1289. +
  1290. +       return i2c_transfer(priv->i2c, msg2, num);
  1291. +}
  1292. +
  1293. +static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
  1294. +       .master_xfer   = cxd2820r_tuner_i2c_xfer,
  1295. +       .functionality = cxd2820r_tuner_i2c_func,
  1296. +};
  1297. +
  1298. +struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
  1299. +{
  1300. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1301. +       return &priv->tuner_i2c_adapter;
  1302. +}
  1303. +EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
  1304. +
  1305. +static struct dvb_frontend_ops cxd2820r_ops[2];
  1306. +
  1307. +struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
  1308. +       struct i2c_adapter *i2c, struct dvb_frontend *fe)
  1309. +{
  1310. +       int ret;
  1311. +       struct cxd2820r_priv *priv = NULL;
  1312. +       u8 tmp;
  1313. +
  1314. +       if (fe == NULL) {
  1315. +               /* FE0 */
  1316. +               /* allocate memory for the internal priv */
  1317. +               priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL);
  1318. +               if (priv == NULL)
  1319. +                       goto error;
  1320. +
  1321. +               /* setup the priv */
  1322. +               priv->i2c = i2c;
  1323. +               memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config));
  1324. +               mutex_init(&priv->fe_lock);
  1325. +
  1326. +               priv->active_fe = -1; /* NONE */
  1327. +
  1328. +               /* check if the demod is there */
  1329. +               priv->bank[0] = priv->bank[1] = 0xff;
  1330. +               ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
  1331. +               dbg("%s: chip id=%02x", __func__, tmp);
  1332. +               if (ret || tmp != 0xe1)
  1333. +                       goto error;
  1334. +
  1335. +               /* create frontends */
  1336. +               memcpy(&priv->fe[0].ops, &cxd2820r_ops[0],
  1337. +                       sizeof(struct dvb_frontend_ops));
  1338. +               memcpy(&priv->fe[1].ops, &cxd2820r_ops[1],
  1339. +                       sizeof(struct dvb_frontend_ops));
  1340. +
  1341. +               priv->fe[0].demodulator_priv = priv;
  1342. +               priv->fe[1].demodulator_priv = priv;
  1343. +
  1344. +               /* create tuner i2c adapter */
  1345. +               strlcpy(priv->tuner_i2c_adapter.name,
  1346. +                       "CXD2820R tuner I2C adapter",
  1347. +                       sizeof(priv->tuner_i2c_adapter.name));
  1348. +               priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
  1349. +               priv->tuner_i2c_adapter.algo_data = NULL;
  1350. +               i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
  1351. +               if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
  1352. +                       err("tuner I2C bus could not be initialized");
  1353. +                       goto error;
  1354. +               }
  1355. +
  1356. +               return &priv->fe[0];
  1357. +
  1358. +       } else {
  1359. +               /* FE1: FE0 given as pointer, just return FE1 we have
  1360. +                * already created */
  1361. +               priv = fe->demodulator_priv;
  1362. +               return &priv->fe[1];
  1363. +       }
  1364. +
  1365. +error:
  1366. +       kfree(priv);
  1367. +       return NULL;
  1368. +}
  1369. +EXPORT_SYMBOL(cxd2820r_attach);
  1370. +
  1371. +static struct dvb_frontend_ops cxd2820r_ops[2] = {
  1372. +       {
  1373. +               /* DVB-T/T2 */
  1374. +               .info = {
  1375. +                       .name = "Sony CXD2820R (DVB-T/T2)",
  1376. +                       .type = FE_OFDM,
  1377. +                       .caps =
  1378. +                               FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
  1379. +                               FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
  1380. +                               FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
  1381. +                               FE_CAN_QPSK | FE_CAN_QAM_16 |
  1382. +                               FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
  1383. +                               FE_CAN_TRANSMISSION_MODE_AUTO |
  1384. +                               FE_CAN_GUARD_INTERVAL_AUTO |
  1385. +                               FE_CAN_HIERARCHY_AUTO |
  1386. +                               FE_CAN_MUTE_TS |
  1387. +                               FE_CAN_2G_MODULATION
  1388. +               },
  1389. +
  1390. +               .release = cxd2820r_release,
  1391. +               .init = cxd2820r_init,
  1392. +               .sleep = cxd2820r_sleep,
  1393. +
  1394. +               .get_tune_settings = cxd2820r_get_tune_settings,
  1395. +
  1396. +               .get_frontend = cxd2820r_get_frontend,
  1397. +
  1398. +               .get_frontend_algo = cxd2820r_get_frontend_algo,
  1399. +               .search = cxd2820r_search,
  1400. +
  1401. +               .read_status = cxd2820r_read_status,
  1402. +               .read_snr = cxd2820r_read_snr,
  1403. +               .read_ber = cxd2820r_read_ber,
  1404. +               .read_ucblocks = cxd2820r_read_ucblocks,
  1405. +               .read_signal_strength = cxd2820r_read_signal_strength,
  1406. +       },
  1407. +       {
  1408. +               /* DVB-C */
  1409. +               .info = {
  1410. +                       .name = "Sony CXD2820R (DVB-C)",
  1411. +                       .type = FE_QAM,
  1412. +                       .caps =
  1413. +                               FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
  1414. +                               FE_CAN_QAM_128 | FE_CAN_QAM_256 |
  1415. +                               FE_CAN_FEC_AUTO
  1416. +               },
  1417. +
  1418. +               .release = cxd2820r_release,
  1419. +               .init = cxd2820r_init,
  1420. +               .sleep = cxd2820r_sleep,
  1421. +
  1422. +               .get_tune_settings = cxd2820r_get_tune_settings,
  1423. +
  1424. +               .set_frontend = cxd2820r_set_frontend,
  1425. +               .get_frontend = cxd2820r_get_frontend,
  1426. +
  1427. +               .read_status = cxd2820r_read_status,
  1428. +               .read_snr = cxd2820r_read_snr,
  1429. +               .read_ber = cxd2820r_read_ber,
  1430. +               .read_ucblocks = cxd2820r_read_ucblocks,
  1431. +               .read_signal_strength = cxd2820r_read_signal_strength,
  1432. +       },
  1433. +};
  1434. +
  1435. +
  1436. +MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
  1437. +MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
  1438. +MODULE_LICENSE("GPL");
  1439. diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h
  1440. new file mode 100644
  1441. index 0000000..d4e2e0b
  1442. --- /dev/null
  1443. +++ b/drivers/media/dvb/frontends/cxd2820r_priv.h
  1444. @@ -0,0 +1,178 @@
  1445. +/*
  1446. + * Sony CXD2820R demodulator driver
  1447. + *
  1448. + * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
  1449. + *
  1450. + *    This program is free software; you can redistribute it and/or modify
  1451. + *    it under the terms of the GNU General Public License as published by
  1452. + *    the Free Software Foundation; either version 2 of the License, or
  1453. + *    (at your option) any later version.
  1454. + *
  1455. + *    This program is distributed in the hope that it will be useful,
  1456. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1457. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1458. + *    GNU General Public License for more details.
  1459. + *
  1460. + *    You should have received a copy of the GNU General Public License along
  1461. + *    with this program; if not, write to the Free Software Foundation, Inc.,
  1462. + *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  1463. + */
  1464. +
  1465. +
  1466. +#ifndef CXD2820R_PRIV_H
  1467. +#define CXD2820R_PRIV_H
  1468. +
  1469. +#include <linux/dvb/version.h>
  1470. +#include "dvb_frontend.h"
  1471. +#include "dvb_math.h"
  1472. +#include "cxd2820r.h"
  1473. +
  1474. +#define LOG_PREFIX "cxd2820r"
  1475. +
  1476. +#undef dbg
  1477. +#define dbg(f, arg...) \
  1478. +       if (cxd2820r_debug) \
  1479. +               printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
  1480. +#undef err
  1481. +#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
  1482. +#undef info
  1483. +#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
  1484. +#undef warn
  1485. +#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
  1486. +
  1487. +/*
  1488. + * FIXME: These are totally wrong and must be added properly to the API.
  1489. + * Only temporary solution in order to get driver compile.
  1490. + */
  1491. +#define SYS_DVBT2             SYS_DAB
  1492. +#define TRANSMISSION_MODE_1K  0
  1493. +#define TRANSMISSION_MODE_16K 0
  1494. +#define TRANSMISSION_MODE_32K 0
  1495. +#define GUARD_INTERVAL_1_128  0
  1496. +#define GUARD_INTERVAL_19_128 0
  1497. +#define GUARD_INTERVAL_19_256 0
  1498. +
  1499. +struct reg_val_mask {
  1500. +       u32 reg;
  1501. +       u8  val;
  1502. +       u8  mask;
  1503. +};
  1504. +
  1505. +struct cxd2820r_priv {
  1506. +       struct i2c_adapter *i2c;
  1507. +       struct dvb_frontend fe[2];
  1508. +       struct cxd2820r_config cfg;
  1509. +       struct i2c_adapter tuner_i2c_adapter;
  1510. +
  1511. +       struct mutex fe_lock; /* FE lock */
  1512. +       int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
  1513. +
  1514. +       int ber_running:1;
  1515. +
  1516. +       u8 bank[2];
  1517. +       u8 gpio[3];
  1518. +
  1519. +       fe_delivery_system_t delivery_system;
  1520. +       int last_tune_failed:1; /* for switch between T and T2 tune */
  1521. +};
  1522. +
  1523. +/* cxd2820r_core.c */
  1524. +
  1525. +extern int cxd2820r_debug;
  1526. +
  1527. +int cxd2820r_gpio(struct dvb_frontend *fe);
  1528. +
  1529. +int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
  1530. +       u8 mask);
  1531. +
  1532. +int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
  1533. +       int len);
  1534. +
  1535. +u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
  1536. +
  1537. +int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
  1538. +       int len);
  1539. +
  1540. +int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
  1541. +       int len);
  1542. +
  1543. +int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val);
  1544. +
  1545. +int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val);
  1546. +
  1547. +/* cxd2820r_c.c */
  1548. +
  1549. +int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
  1550. +       struct dvb_frontend_parameters *p);
  1551. +
  1552. +int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
  1553. +       struct dvb_frontend_parameters *params);
  1554. +
  1555. +int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status);
  1556. +
  1557. +int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
  1558. +
  1559. +int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
  1560. +
  1561. +int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
  1562. +
  1563. +int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
  1564. +
  1565. +int cxd2820r_init_c(struct dvb_frontend *fe);
  1566. +
  1567. +int cxd2820r_sleep_c(struct dvb_frontend *fe);
  1568. +
  1569. +int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
  1570. +       struct dvb_frontend_tune_settings *s);
  1571. +
  1572. +/* cxd2820r_t.c */
  1573. +
  1574. +int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
  1575. +       struct dvb_frontend_parameters *p);
  1576. +
  1577. +int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
  1578. +       struct dvb_frontend_parameters *params);
  1579. +
  1580. +int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status);
  1581. +
  1582. +int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
  1583. +
  1584. +int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
  1585. +
  1586. +int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
  1587. +
  1588. +int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
  1589. +
  1590. +int cxd2820r_init_t(struct dvb_frontend *fe);
  1591. +
  1592. +int cxd2820r_sleep_t(struct dvb_frontend *fe);
  1593. +
  1594. +int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
  1595. +       struct dvb_frontend_tune_settings *s);
  1596. +
  1597. +/* cxd2820r_t2.c */
  1598. +
  1599. +int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
  1600. +       struct dvb_frontend_parameters *p);
  1601. +
  1602. +int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
  1603. +       struct dvb_frontend_parameters *params);
  1604. +
  1605. +int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status);
  1606. +
  1607. +int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
  1608. +
  1609. +int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
  1610. +
  1611. +int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
  1612. +
  1613. +int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
  1614. +
  1615. +int cxd2820r_init_t2(struct dvb_frontend *fe);
  1616. +
  1617. +int cxd2820r_sleep_t2(struct dvb_frontend *fe);
  1618. +
  1619. +int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
  1620. +       struct dvb_frontend_tune_settings *s);
  1621. +
  1622. +#endif /* CXD2820R_PRIV_H */
  1623. diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
  1624. new file mode 100644
  1625. index 0000000..6582564
  1626. --- /dev/null
  1627. +++ b/drivers/media/dvb/frontends/cxd2820r_t.c
  1628. @@ -0,0 +1,449 @@
  1629. +/*
  1630. + * Sony CXD2820R demodulator driver
  1631. + *
  1632. + * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
  1633. + *
  1634. + *    This program is free software; you can redistribute it and/or modify
  1635. + *    it under the terms of the GNU General Public License as published by
  1636. + *    the Free Software Foundation; either version 2 of the License, or
  1637. + *    (at your option) any later version.
  1638. + *
  1639. + *    This program is distributed in the hope that it will be useful,
  1640. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  1641. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1642. + *    GNU General Public License for more details.
  1643. + *
  1644. + *    You should have received a copy of the GNU General Public License along
  1645. + *    with this program; if not, write to the Free Software Foundation, Inc.,
  1646. + *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  1647. + */
  1648. +
  1649. +
  1650. +#include "cxd2820r_priv.h"
  1651. +
  1652. +int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
  1653. +       struct dvb_frontend_parameters *p)
  1654. +{
  1655. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1656. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  1657. +       int ret, i;
  1658. +       u32 if_khz, if_ctl;
  1659. +       u64 num;
  1660. +       u8 buf[3], bw_param;
  1661. +       u8 bw_params1[][5] = {
  1662. +               { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
  1663. +               { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
  1664. +               { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
  1665. +       };
  1666. +       u8 bw_params2[][2] = {
  1667. +               { 0x1f, 0xdc }, /* 6 MHz */
  1668. +               { 0x12, 0xf8 }, /* 7 MHz */
  1669. +               { 0x01, 0xe0 }, /* 8 MHz */
  1670. +       };
  1671. +       struct reg_val_mask tab[] = {
  1672. +               { 0x00080, 0x00, 0xff },
  1673. +               { 0x00081, 0x03, 0xff },
  1674. +               { 0x00085, 0x07, 0xff },
  1675. +               { 0x00088, 0x01, 0xff },
  1676. +
  1677. +               { 0x00070, priv->cfg.ts_mode, 0xff },
  1678. +               { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
  1679. +               { 0x000a5, 0x00, 0x01 },
  1680. +               { 0x00082, 0x20, 0x60 },
  1681. +               { 0x000c2, 0xc3, 0xff },
  1682. +               { 0x0016a, 0x50, 0xff },
  1683. +               { 0x00427, 0x41, 0xff },
  1684. +       };
  1685. +
  1686. +       dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
  1687. +
  1688. +       /* update GPIOs */
  1689. +       ret = cxd2820r_gpio(fe);
  1690. +       if (ret)
  1691. +               goto error;
  1692. +
  1693. +       /* program tuner */
  1694. +       if (fe->ops.tuner_ops.set_params)
  1695. +               fe->ops.tuner_ops.set_params(fe, p);
  1696. +
  1697. +       if (priv->delivery_system != SYS_DVBT) {
  1698. +               for (i = 0; i < ARRAY_SIZE(tab); i++) {
  1699. +                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
  1700. +                               tab[i].val, tab[i].mask);
  1701. +                       if (ret)
  1702. +                               goto error;
  1703. +               }
  1704. +       }
  1705. +
  1706. +       priv->delivery_system = SYS_DVBT;
  1707. +       priv->ber_running = 0; /* tune stops BER counter */
  1708. +
  1709. +       switch (c->bandwidth_hz) {
  1710. +       case 6000000:
  1711. +               if_khz = priv->cfg.if_dvbt_6;
  1712. +               i = 0;
  1713. +               bw_param = 2;
  1714. +               break;
  1715. +       case 7000000:
  1716. +               if_khz = priv->cfg.if_dvbt_7;
  1717. +               i = 1;
  1718. +               bw_param = 1;
  1719. +               break;
  1720. +       case 8000000:
  1721. +               if_khz = priv->cfg.if_dvbt_8;
  1722. +               i = 2;
  1723. +               bw_param = 0;
  1724. +               break;
  1725. +       default:
  1726. +               return -EINVAL;
  1727. +       }
  1728. +
  1729. +       num = if_khz;
  1730. +       num *= 0x1000000;
  1731. +       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
  1732. +       buf[0] = ((if_ctl >> 16) & 0xff);
  1733. +       buf[1] = ((if_ctl >>  8) & 0xff);
  1734. +       buf[2] = ((if_ctl >>  0) & 0xff);
  1735. +
  1736. +       ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
  1737. +       if (ret)
  1738. +               goto error;
  1739. +
  1740. +       ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5);
  1741. +       if (ret)
  1742. +               goto error;
  1743. +
  1744. +       ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
  1745. +       if (ret)
  1746. +               goto error;
  1747. +
  1748. +       ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2);
  1749. +       if (ret)
  1750. +               goto error;
  1751. +
  1752. +       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
  1753. +       if (ret)
  1754. +               goto error;
  1755. +
  1756. +       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
  1757. +       if (ret)
  1758. +               goto error;
  1759. +
  1760. +       return ret;
  1761. +error:
  1762. +       dbg("%s: failed:%d", __func__, ret);
  1763. +       return ret;
  1764. +}
  1765. +
  1766. +int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
  1767. +       struct dvb_frontend_parameters *p)
  1768. +{
  1769. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1770. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  1771. +       int ret;
  1772. +       u8 buf[2];
  1773. +
  1774. +       ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
  1775. +       if (ret)
  1776. +               goto error;
  1777. +
  1778. +       switch ((buf[0] >> 6) & 0x03) {
  1779. +       case 0:
  1780. +               c->modulation = QPSK;
  1781. +               break;
  1782. +       case 1:
  1783. +               c->modulation = QAM_16;
  1784. +               break;
  1785. +       case 2:
  1786. +               c->modulation = QAM_64;
  1787. +               break;
  1788. +       }
  1789. +
  1790. +       switch ((buf[1] >> 1) & 0x03) {
  1791. +       case 0:
  1792. +               c->transmission_mode = TRANSMISSION_MODE_2K;
  1793. +               break;
  1794. +       case 1:
  1795. +               c->transmission_mode = TRANSMISSION_MODE_8K;
  1796. +               break;
  1797. +       }
  1798. +
  1799. +       switch ((buf[1] >> 3) & 0x03) {
  1800. +       case 0:
  1801. +               c->guard_interval = GUARD_INTERVAL_1_32;
  1802. +               break;
  1803. +       case 1:
  1804. +               c->guard_interval = GUARD_INTERVAL_1_16;
  1805. +               break;
  1806. +       case 2:
  1807. +               c->guard_interval = GUARD_INTERVAL_1_8;
  1808. +               break;
  1809. +       case 3:
  1810. +               c->guard_interval = GUARD_INTERVAL_1_4;
  1811. +               break;
  1812. +       }
  1813. +
  1814. +       switch ((buf[0] >> 3) & 0x07) {
  1815. +       case 0:
  1816. +               c->hierarchy = HIERARCHY_NONE;
  1817. +               break;
  1818. +       case 1:
  1819. +               c->hierarchy = HIERARCHY_1;
  1820. +               break;
  1821. +       case 2:
  1822. +               c->hierarchy = HIERARCHY_2;
  1823. +               break;
  1824. +       case 3:
  1825. +               c->hierarchy = HIERARCHY_4;
  1826. +               break;
  1827. +       }
  1828. +
  1829. +       switch ((buf[0] >> 0) & 0x07) {
  1830. +       case 0:
  1831. +               c->code_rate_HP = FEC_1_2;
  1832. +               break;
  1833. +       case 1:
  1834. +               c->code_rate_HP = FEC_2_3;
  1835. +               break;
  1836. +       case 2:
  1837. +               c->code_rate_HP = FEC_3_4;
  1838. +               break;
  1839. +       case 3:
  1840. +               c->code_rate_HP = FEC_5_6;
  1841. +               break;
  1842. +       case 4:
  1843. +               c->code_rate_HP = FEC_7_8;
  1844. +               break;
  1845. +       }
  1846. +
  1847. +       switch ((buf[1] >> 5) & 0x07) {
  1848. +       case 0:
  1849. +               c->code_rate_LP = FEC_1_2;
  1850. +               break;
  1851. +       case 1:
  1852. +               c->code_rate_LP = FEC_2_3;
  1853. +               break;
  1854. +       case 2:
  1855. +               c->code_rate_LP = FEC_3_4;
  1856. +               break;
  1857. +       case 3:
  1858. +               c->code_rate_LP = FEC_5_6;
  1859. +               break;
  1860. +       case 4:
  1861. +               c->code_rate_LP = FEC_7_8;
  1862. +               break;
  1863. +       }
  1864. +
  1865. +       ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
  1866. +       if (ret)
  1867. +               goto error;
  1868. +
  1869. +       switch ((buf[0] >> 0) & 0x01) {
  1870. +       case 0:
  1871. +               c->inversion = INVERSION_OFF;
  1872. +               break;
  1873. +       case 1:
  1874. +               c->inversion = INVERSION_ON;
  1875. +               break;
  1876. +       }
  1877. +
  1878. +       return ret;
  1879. +error:
  1880. +       dbg("%s: failed:%d", __func__, ret);
  1881. +       return ret;
  1882. +}
  1883. +
  1884. +int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
  1885. +{
  1886. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1887. +       int ret;
  1888. +       u8 buf[3], start_ber = 0;
  1889. +       *ber = 0;
  1890. +
  1891. +       if (priv->ber_running) {
  1892. +               ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
  1893. +               if (ret)
  1894. +                       goto error;
  1895. +
  1896. +               if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
  1897. +                       *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
  1898. +                       start_ber = 1;
  1899. +               }
  1900. +       } else {
  1901. +               priv->ber_running = 1;
  1902. +               start_ber = 1;
  1903. +       }
  1904. +
  1905. +       if (start_ber) {
  1906. +               /* (re)start BER */
  1907. +               ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
  1908. +               if (ret)
  1909. +                       goto error;
  1910. +       }
  1911. +
  1912. +       return ret;
  1913. +error:
  1914. +       dbg("%s: failed:%d", __func__, ret);
  1915. +       return ret;
  1916. +}
  1917. +
  1918. +int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
  1919. +       u16 *strength)
  1920. +{
  1921. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1922. +       int ret;
  1923. +       u8 buf[2];
  1924. +       u16 tmp;
  1925. +
  1926. +       ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
  1927. +       if (ret)
  1928. +               goto error;
  1929. +
  1930. +       tmp = (buf[0] & 0x0f) << 8 | buf[1];
  1931. +       tmp = ~tmp & 0x0fff;
  1932. +
  1933. +       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
  1934. +       *strength = tmp * 0xffff / 0x0fff;
  1935. +
  1936. +       return ret;
  1937. +error:
  1938. +       dbg("%s: failed:%d", __func__, ret);
  1939. +       return ret;
  1940. +}
  1941. +
  1942. +int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
  1943. +{
  1944. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1945. +       int ret;
  1946. +       u8 buf[2];
  1947. +       u16 tmp;
  1948. +       /* report SNR in dB * 10 */
  1949. +
  1950. +       ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
  1951. +       if (ret)
  1952. +               goto error;
  1953. +
  1954. +       tmp = (buf[0] & 0x1f) << 8 | buf[1];
  1955. +       #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
  1956. +       if (tmp)
  1957. +               *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
  1958. +                       / 100);
  1959. +       else
  1960. +               *snr = 0;
  1961. +
  1962. +       dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
  1963. +
  1964. +       return ret;
  1965. +error:
  1966. +       dbg("%s: failed:%d", __func__, ret);
  1967. +       return ret;
  1968. +}
  1969. +
  1970. +int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
  1971. +{
  1972. +       *ucblocks = 0;
  1973. +       /* no way to read ? */
  1974. +       return 0;
  1975. +}
  1976. +
  1977. +int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
  1978. +{
  1979. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  1980. +       int ret;
  1981. +       u8 buf[4];
  1982. +       *status = 0;
  1983. +
  1984. +       ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
  1985. +       if (ret)
  1986. +               goto error;
  1987. +
  1988. +       if ((buf[0] & 0x07) == 6) {
  1989. +               ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
  1990. +               if (ret)
  1991. +                       goto error;
  1992. +
  1993. +               if (((buf[1] >> 3) & 0x01) == 1) {
  1994. +                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
  1995. +                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
  1996. +               } else {
  1997. +                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
  1998. +                               FE_HAS_VITERBI | FE_HAS_SYNC;
  1999. +               }
  2000. +       } else {
  2001. +               ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
  2002. +               if (ret)
  2003. +                       goto error;
  2004. +
  2005. +               if ((buf[2] & 0x0f) >= 4) {
  2006. +                       ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
  2007. +                       if (ret)
  2008. +                               goto error;
  2009. +
  2010. +                       if (((buf[3] >> 4) & 0x01) == 1)
  2011. +                               *status |= FE_HAS_SIGNAL;
  2012. +               }
  2013. +       }
  2014. +
  2015. +       dbg("%s: lock=%02x %02x %02x %02x", __func__,
  2016. +               buf[0], buf[1], buf[2], buf[3]);
  2017. +
  2018. +       return ret;
  2019. +error:
  2020. +       dbg("%s: failed:%d", __func__, ret);
  2021. +       return ret;
  2022. +}
  2023. +
  2024. +int cxd2820r_init_t(struct dvb_frontend *fe)
  2025. +{
  2026. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2027. +       int ret;
  2028. +
  2029. +       ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
  2030. +       if (ret)
  2031. +               goto error;
  2032. +
  2033. +       return ret;
  2034. +error:
  2035. +       dbg("%s: failed:%d", __func__, ret);
  2036. +       return ret;
  2037. +}
  2038. +
  2039. +int cxd2820r_sleep_t(struct dvb_frontend *fe)
  2040. +{
  2041. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2042. +       int ret, i;
  2043. +       struct reg_val_mask tab[] = {
  2044. +               { 0x000ff, 0x1f, 0xff },
  2045. +               { 0x00085, 0x00, 0xff },
  2046. +               { 0x00088, 0x01, 0xff },
  2047. +               { 0x00081, 0x00, 0xff },
  2048. +               { 0x00080, 0x00, 0xff },
  2049. +       };
  2050. +
  2051. +       dbg("%s", __func__);
  2052. +
  2053. +       priv->delivery_system = SYS_UNDEFINED;
  2054. +
  2055. +       for (i = 0; i < ARRAY_SIZE(tab); i++) {
  2056. +               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
  2057. +                       tab[i].mask);
  2058. +               if (ret)
  2059. +                       goto error;
  2060. +       }
  2061. +
  2062. +       return ret;
  2063. +error:
  2064. +       dbg("%s: failed:%d", __func__, ret);
  2065. +       return ret;
  2066. +}
  2067. +
  2068. +int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
  2069. +       struct dvb_frontend_tune_settings *s)
  2070. +{
  2071. +       s->min_delay_ms = 500;
  2072. +       s->step_size = fe->ops.info.frequency_stepsize * 2;
  2073. +       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
  2074. +
  2075. +       return 0;
  2076. +}
  2077. +
  2078. diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
  2079. new file mode 100644
  2080. index 0000000..c47b35c
  2081. --- /dev/null
  2082. +++ b/drivers/media/dvb/frontends/cxd2820r_t2.c
  2083. @@ -0,0 +1,423 @@
  2084. +/*
  2085. + * Sony CXD2820R demodulator driver
  2086. + *
  2087. + * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
  2088. + *
  2089. + *    This program is free software; you can redistribute it and/or modify
  2090. + *    it under the terms of the GNU General Public License as published by
  2091. + *    the Free Software Foundation; either version 2 of the License, or
  2092. + *    (at your option) any later version.
  2093. + *
  2094. + *    This program is distributed in the hope that it will be useful,
  2095. + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  2096. + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2097. + *    GNU General Public License for more details.
  2098. + *
  2099. + *    You should have received a copy of the GNU General Public License along
  2100. + *    with this program; if not, write to the Free Software Foundation, Inc.,
  2101. + *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  2102. + */
  2103. +
  2104. +
  2105. +#include "cxd2820r_priv.h"
  2106. +
  2107. +int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
  2108. +       struct dvb_frontend_parameters *params)
  2109. +{
  2110. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2111. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  2112. +       int ret, i;
  2113. +       u32 if_khz, if_ctl;
  2114. +       u64 num;
  2115. +       u8 buf[3], bw_param;
  2116. +       u8 bw_params1[][5] = {
  2117. +               { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */
  2118. +               { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
  2119. +               { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
  2120. +               { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
  2121. +       };
  2122. +       struct reg_val_mask tab[] = {
  2123. +               { 0x00080, 0x02, 0xff },
  2124. +               { 0x00081, 0x20, 0xff },
  2125. +               { 0x00085, 0x07, 0xff },
  2126. +               { 0x00088, 0x01, 0xff },
  2127. +               { 0x02069, 0x01, 0xff },
  2128. +
  2129. +               { 0x0207f, 0x2a, 0xff },
  2130. +               { 0x02082, 0x0a, 0xff },
  2131. +               { 0x02083, 0x0a, 0xff },
  2132. +               { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
  2133. +               { 0x02070, priv->cfg.ts_mode, 0xff },
  2134. +               { 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
  2135. +               { 0x02567, 0x07, 0x0f },
  2136. +               { 0x02569, 0x03, 0x03 },
  2137. +               { 0x02595, 0x1a, 0xff },
  2138. +               { 0x02596, 0x50, 0xff },
  2139. +               { 0x02a8c, 0x00, 0xff },
  2140. +               { 0x02a8d, 0x34, 0xff },
  2141. +               { 0x02a45, 0x06, 0x07 },
  2142. +               { 0x03f10, 0x0d, 0xff },
  2143. +               { 0x03f11, 0x02, 0xff },
  2144. +               { 0x03f12, 0x01, 0xff },
  2145. +               { 0x03f23, 0x2c, 0xff },
  2146. +               { 0x03f51, 0x13, 0xff },
  2147. +               { 0x03f52, 0x01, 0xff },
  2148. +               { 0x03f53, 0x00, 0xff },
  2149. +               { 0x027e6, 0x14, 0xff },
  2150. +               { 0x02786, 0x02, 0x07 },
  2151. +               { 0x02787, 0x40, 0xe0 },
  2152. +               { 0x027ef, 0x10, 0x18 },
  2153. +       };
  2154. +
  2155. +       dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
  2156. +
  2157. +       /* update GPIOs */
  2158. +       ret = cxd2820r_gpio(fe);
  2159. +       if (ret)
  2160. +               goto error;
  2161. +
  2162. +       /* program tuner */
  2163. +       if (fe->ops.tuner_ops.set_params)
  2164. +               fe->ops.tuner_ops.set_params(fe, params);
  2165. +
  2166. +       if (priv->delivery_system != SYS_DVBT2) {
  2167. +               for (i = 0; i < ARRAY_SIZE(tab); i++) {
  2168. +                       ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
  2169. +                               tab[i].val, tab[i].mask);
  2170. +                       if (ret)
  2171. +                               goto error;
  2172. +               }
  2173. +       }
  2174. +
  2175. +       priv->delivery_system = SYS_DVBT2;
  2176. +
  2177. +       switch (c->bandwidth_hz) {
  2178. +       case 5000000:
  2179. +               if_khz = priv->cfg.if_dvbt2_5;
  2180. +               i = 0;
  2181. +               bw_param = 3;
  2182. +               break;
  2183. +       case 6000000:
  2184. +               if_khz = priv->cfg.if_dvbt2_6;
  2185. +               i = 1;
  2186. +               bw_param = 2;
  2187. +               break;
  2188. +       case 7000000:
  2189. +               if_khz = priv->cfg.if_dvbt2_7;
  2190. +               i = 2;
  2191. +               bw_param = 1;
  2192. +               break;
  2193. +       case 8000000:
  2194. +               if_khz = priv->cfg.if_dvbt2_8;
  2195. +               i = 3;
  2196. +               bw_param = 0;
  2197. +               break;
  2198. +       default:
  2199. +               return -EINVAL;
  2200. +       }
  2201. +
  2202. +       num = if_khz;
  2203. +       num *= 0x1000000;
  2204. +       if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
  2205. +       buf[0] = ((if_ctl >> 16) & 0xff);
  2206. +       buf[1] = ((if_ctl >>  8) & 0xff);
  2207. +       buf[2] = ((if_ctl >>  0) & 0xff);
  2208. +
  2209. +       ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
  2210. +       if (ret)
  2211. +               goto error;
  2212. +
  2213. +       ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5);
  2214. +       if (ret)
  2215. +               goto error;
  2216. +
  2217. +       ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0);
  2218. +       if (ret)
  2219. +               goto error;
  2220. +
  2221. +       ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
  2222. +       if (ret)
  2223. +               goto error;
  2224. +
  2225. +       ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
  2226. +       if (ret)
  2227. +               goto error;
  2228. +
  2229. +       return ret;
  2230. +error:
  2231. +       dbg("%s: failed:%d", __func__, ret);
  2232. +       return ret;
  2233. +
  2234. +}
  2235. +
  2236. +int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
  2237. +       struct dvb_frontend_parameters *p)
  2238. +{
  2239. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2240. +       struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  2241. +       int ret;
  2242. +       u8 buf[2];
  2243. +
  2244. +       ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2);
  2245. +       if (ret)
  2246. +               goto error;
  2247. +
  2248. +       switch ((buf[0] >> 0) & 0x07) {
  2249. +       case 0:
  2250. +               c->transmission_mode = TRANSMISSION_MODE_2K;
  2251. +               break;
  2252. +       case 1:
  2253. +               c->transmission_mode = TRANSMISSION_MODE_8K;
  2254. +               break;
  2255. +       case 2:
  2256. +               c->transmission_mode = TRANSMISSION_MODE_4K;
  2257. +               break;
  2258. +       case 3:
  2259. +               c->transmission_mode = TRANSMISSION_MODE_1K;
  2260. +               break;
  2261. +       case 4:
  2262. +               c->transmission_mode = TRANSMISSION_MODE_16K;
  2263. +               break;
  2264. +       case 5:
  2265. +               c->transmission_mode = TRANSMISSION_MODE_32K;
  2266. +               break;
  2267. +       }
  2268. +
  2269. +       switch ((buf[1] >> 4) & 0x07) {
  2270. +       case 0:
  2271. +               c->guard_interval = GUARD_INTERVAL_1_32;
  2272. +               break;
  2273. +       case 1:
  2274. +               c->guard_interval = GUARD_INTERVAL_1_16;
  2275. +               break;
  2276. +       case 2:
  2277. +               c->guard_interval = GUARD_INTERVAL_1_8;
  2278. +               break;
  2279. +       case 3:
  2280. +               c->guard_interval = GUARD_INTERVAL_1_4;
  2281. +               break;
  2282. +       case 4:
  2283. +               c->guard_interval = GUARD_INTERVAL_1_128;
  2284. +               break;
  2285. +       case 5:
  2286. +               c->guard_interval = GUARD_INTERVAL_19_128;
  2287. +               break;
  2288. +       case 6:
  2289. +               c->guard_interval = GUARD_INTERVAL_19_256;
  2290. +               break;
  2291. +       }
  2292. +
  2293. +       ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2);
  2294. +       if (ret)
  2295. +               goto error;
  2296. +
  2297. +       switch ((buf[0] >> 0) & 0x07) {
  2298. +       case 0:
  2299. +               c->fec_inner = FEC_1_2;
  2300. +               break;
  2301. +       case 1:
  2302. +               c->fec_inner = FEC_3_5;
  2303. +               break;
  2304. +       case 2:
  2305. +               c->fec_inner = FEC_2_3;
  2306. +               break;
  2307. +       case 3:
  2308. +               c->fec_inner = FEC_3_4;
  2309. +               break;
  2310. +       case 4:
  2311. +               c->fec_inner = FEC_4_5;
  2312. +               break;
  2313. +       case 5:
  2314. +               c->fec_inner = FEC_5_6;
  2315. +               break;
  2316. +       }
  2317. +
  2318. +       switch ((buf[1] >> 0) & 0x07) {
  2319. +       case 0:
  2320. +               c->modulation = QPSK;
  2321. +               break;
  2322. +       case 1:
  2323. +               c->modulation = QAM_16;
  2324. +               break;
  2325. +       case 2:
  2326. +               c->modulation = QAM_64;
  2327. +               break;
  2328. +       case 3:
  2329. +               c->modulation = QAM_256;
  2330. +               break;
  2331. +       }
  2332. +
  2333. +       ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]);
  2334. +       if (ret)
  2335. +               goto error;
  2336. +
  2337. +       switch ((buf[0] >> 4) & 0x01) {
  2338. +       case 0:
  2339. +               c->inversion = INVERSION_OFF;
  2340. +               break;
  2341. +       case 1:
  2342. +               c->inversion = INVERSION_ON;
  2343. +               break;
  2344. +       }
  2345. +
  2346. +       return ret;
  2347. +error:
  2348. +       dbg("%s: failed:%d", __func__, ret);
  2349. +       return ret;
  2350. +}
  2351. +
  2352. +int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
  2353. +{
  2354. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2355. +       int ret;
  2356. +       u8 buf[1];
  2357. +       *status = 0;
  2358. +
  2359. +       ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]);
  2360. +       if (ret)
  2361. +               goto error;
  2362. +
  2363. +       if ((buf[0] & 0x07) == 6) {
  2364. +               if (((buf[0] >> 5) & 0x01) == 1) {
  2365. +                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
  2366. +                               FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
  2367. +               } else {
  2368. +                       *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
  2369. +                               FE_HAS_VITERBI | FE_HAS_SYNC;
  2370. +               }
  2371. +       }
  2372. +
  2373. +       dbg("%s: lock=%02x", __func__, buf[0]);
  2374. +
  2375. +       return ret;
  2376. +error:
  2377. +       dbg("%s: failed:%d", __func__, ret);
  2378. +       return ret;
  2379. +}
  2380. +
  2381. +int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
  2382. +{
  2383. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2384. +       int ret;
  2385. +       u8 buf[4];
  2386. +       unsigned int errbits;
  2387. +       *ber = 0;
  2388. +       /* FIXME: correct calculation */
  2389. +
  2390. +       ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
  2391. +       if (ret)
  2392. +               goto error;
  2393. +
  2394. +       if ((buf[0] >> 4) & 0x01) {
  2395. +               errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
  2396. +                       buf[2] << 8 | buf[3];
  2397. +
  2398. +               if (errbits)
  2399. +                       *ber = errbits * 64 / 16588800;
  2400. +       }
  2401. +
  2402. +       return ret;
  2403. +error:
  2404. +       dbg("%s: failed:%d", __func__, ret);
  2405. +       return ret;
  2406. +}
  2407. +
  2408. +int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
  2409. +       u16 *strength)
  2410. +{
  2411. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2412. +       int ret;
  2413. +       u8 buf[2];
  2414. +       u16 tmp;
  2415. +
  2416. +       ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
  2417. +       if (ret)
  2418. +               goto error;
  2419. +
  2420. +       tmp = (buf[0] & 0x0f) << 8 | buf[1];
  2421. +       tmp = ~tmp & 0x0fff;
  2422. +
  2423. +       /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
  2424. +       *strength = tmp * 0xffff / 0x0fff;
  2425. +
  2426. +       return ret;
  2427. +error:
  2428. +       dbg("%s: failed:%d", __func__, ret);
  2429. +       return ret;
  2430. +}
  2431. +
  2432. +int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
  2433. +{
  2434. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2435. +       int ret;
  2436. +       u8 buf[2];
  2437. +       u16 tmp;
  2438. +       /* report SNR in dB * 10 */
  2439. +
  2440. +       ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
  2441. +       if (ret)
  2442. +               goto error;
  2443. +
  2444. +       tmp = (buf[0] & 0x0f) << 8 | buf[1];
  2445. +       #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
  2446. +       if (tmp)
  2447. +               *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
  2448. +                       / 100);
  2449. +       else
  2450. +               *snr = 0;
  2451. +
  2452. +       dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
  2453. +
  2454. +       return ret;
  2455. +error:
  2456. +       dbg("%s: failed:%d", __func__, ret);
  2457. +       return ret;
  2458. +}
  2459. +
  2460. +int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
  2461. +{
  2462. +       *ucblocks = 0;
  2463. +       /* no way to read ? */
  2464. +       return 0;
  2465. +}
  2466. +
  2467. +int cxd2820r_sleep_t2(struct dvb_frontend *fe)
  2468. +{
  2469. +       struct cxd2820r_priv *priv = fe->demodulator_priv;
  2470. +       int ret, i;
  2471. +       struct reg_val_mask tab[] = {
  2472. +               { 0x000ff, 0x1f, 0xff },
  2473. +               { 0x00085, 0x00, 0xff },
  2474. +               { 0x00088, 0x01, 0xff },
  2475. +               { 0x02069, 0x00, 0xff },
  2476. +               { 0x00081, 0x00, 0xff },
  2477. +               { 0x00080, 0x00, 0xff },
  2478. +       };
  2479. +
  2480. +       dbg("%s", __func__);
  2481. +
  2482. +       for (i = 0; i < ARRAY_SIZE(tab); i++) {
  2483. +               ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
  2484. +                       tab[i].mask);
  2485. +               if (ret)
  2486. +                       goto error;
  2487. +       }
  2488. +
  2489. +       priv->delivery_system = SYS_UNDEFINED;
  2490. +
  2491. +       return ret;
  2492. +error:
  2493. +       dbg("%s: failed:%d", __func__, ret);
  2494. +       return ret;
  2495. +}
  2496. +
  2497. +int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
  2498. +       struct dvb_frontend_tune_settings *s)
  2499. +{
  2500. +       s->min_delay_ms = 1500;
  2501. +       s->step_size = fe->ops.info.frequency_stepsize * 2;
  2502. +       s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
  2503. +
  2504. +       return 0;
  2505. +}
  2506. +
  2507. diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
  2508. index 985100e..8ef78cd 100644
  2509. --- a/drivers/media/video/em28xx/Kconfig
  2510. +++ b/drivers/media/video/em28xx/Kconfig
  2511. @@ -38,6 +38,7 @@ config VIDEO_EM28XX_DVB
  2512.         select DVB_ZL10353 if !DVB_FE_CUSTOMISE
  2513.         select DVB_TDA10023 if !DVB_FE_CUSTOMISE
  2514.         select DVB_S921 if !DVB_FE_CUSTOMISE
  2515. +       select DVB_CXD2820R if !DVB_FE_CUSTOMISE
  2516.         select VIDEOBUF_DVB
  2517.         ---help---
  2518.           This adds support for DVB cards based on the
  2519. diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
  2520. index 87f77a3..790f0c8 100644
  2521. --- a/drivers/media/video/em28xx/em28xx-cards.c
  2522. +++ b/drivers/media/video/em28xx/em28xx-cards.c
  2523. @@ -282,6 +282,16 @@ static struct em28xx_reg_seq leadership_reset[] = {
  2524.         {       -1,             -1,     -1,     -1},
  2525.  };
  2526.  
  2527. +/* 2013:024f PCTV Systems nanoStick T2 290e
  2528. + * GPIO_6 - demod reset
  2529. + * GPIO_7 - LED
  2530. + */
  2531. +static struct em28xx_reg_seq pctv_290e[] = {
  2532. +       {EM2874_R80_GPIO,       0x00,   0xff,           80},
  2533. +       {EM2874_R80_GPIO,       0x40,   0xff,           80}, /* GPIO_6 = 1 */
  2534. +       {EM2874_R80_GPIO,       0xc0,   0xff,           80}, /* GPIO_7 = 1 */
  2535. +       {-1,                    -1,     -1,             -1},
  2536. +};
  2537.  
  2538.  /*
  2539.   *  Board definitions
  2540. @@ -1749,6 +1759,17 @@ struct em28xx_board em28xx_boards[] = {
  2541.                 .dvb_gpio   = kworld_a340_digital,
  2542.                 .tuner_gpio = default_tuner_gpio,
  2543.         },
  2544. +       /* 2013:024f PCTV Systems nanoStick T2 290e.
  2545. +        * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */
  2546. +       [EM28174_BOARD_PCTV_290E] = {
  2547. +               .i2c_speed      = EM2874_I2C_SECONDARY_BUS_SELECT |
  2548. +                       EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
  2549. +               .xclk          = EM28XX_XCLK_FREQUENCY_12MHZ,
  2550. +               .name          = "PCTV Systems nanoStick T2 290e",
  2551. +               .tuner_type    = TUNER_ABSENT,
  2552. +               .tuner_gpio    = pctv_290e,
  2553. +               .has_dvb       = 1,
  2554. +       },
  2555.  };
  2556.  const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
  2557.  
  2558. @@ -1876,6 +1897,8 @@ struct usb_device_id em28xx_id_table[] = {
  2559.                         .driver_info = EM2860_BOARD_GADMEI_UTV330 },
  2560.         { USB_DEVICE(0x1b80, 0xa340),
  2561.                         .driver_info = EM2870_BOARD_KWORLD_A340 },
  2562. +       { USB_DEVICE(0x2013, 0x024f),
  2563. +                       .driver_info = EM28174_BOARD_PCTV_290E },
  2564.         { },
  2565.  };
  2566.  MODULE_DEVICE_TABLE(usb, em28xx_id_table);
  2567. @@ -2799,6 +2822,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
  2568.                         dev->reg_gpio_num = EM2874_R80_GPIO;
  2569.                         dev->wait_after_write = 0;
  2570.                         break;
  2571. +               case CHIP_ID_EM28174:
  2572. +                       em28xx_info("chip ID is em28174\n");
  2573. +                       dev->reg_gpio_num = EM2874_R80_GPIO;
  2574. +                       dev->wait_after_write = 0;
  2575. +                       break;
  2576.                 case CHIP_ID_EM2883:
  2577.                         em28xx_info("chip ID is em2882/em2883\n");
  2578.                         dev->wait_after_write = 0;
  2579. diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
  2580. index 44c63cb..e33f145 100644
  2581. --- a/drivers/media/video/em28xx/em28xx-core.c
  2582. +++ b/drivers/media/video/em28xx/em28xx-core.c
  2583. @@ -489,7 +489,8 @@ int em28xx_audio_setup(struct em28xx *dev)
  2584.         int vid1, vid2, feat, cfg;
  2585.         u32 vid;
  2586.  
  2587. -       if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874) {
  2588. +       if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
  2589. +               || dev->chip_id == CHIP_ID_EM28174) {
  2590.                 /* Digital only device - don't load any alsa module */
  2591.                 dev->audio_mode.has_audio = 0;
  2592.                 dev->has_audio_class = 0;
  2593. @@ -614,7 +615,7 @@ int em28xx_capture_start(struct em28xx *dev, int start)
  2594.  {
  2595.         int rc;
  2596.  
  2597. -       if (dev->chip_id == CHIP_ID_EM2874) {
  2598. +       if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
  2599.                 /* The Transport Stream Enable Register moved in em2874 */
  2600.                 if (!start) {
  2601.                         rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
  2602. @@ -1111,6 +1112,10 @@ int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
  2603.                 /* FIXME - for now assume 564 like it was before, but the
  2604.                    em2874 code should be added to return the proper value... */
  2605.                 packet_size = 564;
  2606. +       } else if (dev->chip_id == CHIP_ID_EM28174) {
  2607. +               /* FIXME same as em2874. 564 was enough for 22 Mbit DVB-T
  2608. +                  but too much for 44 Mbit DVB-C. */
  2609. +               packet_size = 752;
  2610.         } else {
  2611.                 /* TS max packet size stored in bits 1-0 of R01 */
  2612.                 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
  2613. diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
  2614. index c7c04bf..b939f82 100644
  2615. --- a/drivers/media/video/em28xx/em28xx-dvb.c
  2616. +++ b/drivers/media/video/em28xx/em28xx-dvb.c
  2617. @@ -38,6 +38,7 @@
  2618.  #include "tda1002x.h"
  2619.  #include "tda18271.h"
  2620.  #include "s921.h"
  2621. +#include "cxd2820r.h"
  2622.  
  2623.  MODULE_DESCRIPTION("driver for em28xx based DVB cards");
  2624.  MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
  2625. @@ -58,7 +59,7 @@ if (debug >= level)                                           \
  2626.  #define EM28XX_DVB_MAX_PACKETS 64
  2627.  
  2628.  struct em28xx_dvb {
  2629. -       struct dvb_frontend        *frontend;
  2630. +       struct dvb_frontend        *fe[2];
  2631.  
  2632.         /* feed count management */
  2633.         struct mutex               lock;
  2634. @@ -332,6 +333,26 @@ static struct tda10023_config em28xx_tda10023_config = {
  2635.         .invert = 1,
  2636.  };
  2637.  
  2638. +static struct cxd2820r_config em28xx_cxd2820r_config = {
  2639. +       .i2c_address = (0xd8 >> 1),
  2640. +       .ts_mode = CXD2820R_TS_SERIAL,
  2641. +       .if_dvbt_6  = 3300,
  2642. +       .if_dvbt_7  = 3500,
  2643. +       .if_dvbt_8  = 4000,
  2644. +       .if_dvbt2_6 = 3300,
  2645. +       .if_dvbt2_7 = 3500,
  2646. +       .if_dvbt2_8 = 4000,
  2647. +       .if_dvbc    = 5000,
  2648. +
  2649. +       /* enable LNA for DVB-T2 and DVB-C */
  2650. +       .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
  2651. +       .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
  2652. +};
  2653. +
  2654. +static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
  2655. +       .output_opt = TDA18271_OUTPUT_LT_OFF,
  2656. +};
  2657. +
  2658.  /* ------------------------------------------------------------------ */
  2659.  
  2660.  static int attach_xc3028(u8 addr, struct em28xx *dev)
  2661. @@ -343,17 +364,17 @@ static int attach_xc3028(u8 addr, struct em28xx *dev)
  2662.         cfg.i2c_adap  = &dev->i2c_adap;
  2663.         cfg.i2c_addr  = addr;
  2664.  
  2665. -       if (!dev->dvb->frontend) {
  2666. +       if (!dev->dvb->fe[0]) {
  2667.                 em28xx_errdev("/2: dvb frontend not attached. "
  2668.                                 "Can't attach xc3028\n");
  2669.                 return -EINVAL;
  2670.         }
  2671.  
  2672. -       fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
  2673. +       fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg);
  2674.         if (!fe) {
  2675.                 em28xx_errdev("/2: xc3028 attach failed\n");
  2676. -               dvb_frontend_detach(dev->dvb->frontend);
  2677. -               dev->dvb->frontend = NULL;
  2678. +               dvb_frontend_detach(dev->dvb->fe[0]);
  2679. +               dev->dvb->fe[0] = NULL;
  2680.                 return -EINVAL;
  2681.         }
  2682.  
  2683. @@ -383,16 +404,28 @@ static int register_dvb(struct em28xx_dvb *dvb,
  2684.         }
  2685.  
  2686.         /* Ensure all frontends negotiate bus access */
  2687. -       dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
  2688. +       dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
  2689. +       if (dvb->fe[1])
  2690. +               dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
  2691.  
  2692.         dvb->adapter.priv = dev;
  2693.  
  2694.         /* register frontend */
  2695. -       result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
  2696. +       result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]);
  2697.         if (result < 0) {
  2698.                 printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
  2699.                        dev->name, result);
  2700. -               goto fail_frontend;
  2701. +               goto fail_frontend0;
  2702. +       }
  2703. +
  2704. +       /* register 2nd frontend */
  2705. +       if (dvb->fe[1]) {
  2706. +               result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]);
  2707. +               if (result < 0) {
  2708. +                       printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
  2709. +                               dev->name, result);
  2710. +                       goto fail_frontend1;
  2711. +               }
  2712.         }
  2713.  
  2714.         /* register demux stuff */
  2715. @@ -458,9 +491,14 @@ fail_fe_hw:
  2716.  fail_dmxdev:
  2717.         dvb_dmx_release(&dvb->demux);
  2718.  fail_dmx:
  2719. -       dvb_unregister_frontend(dvb->frontend);
  2720. -fail_frontend:
  2721. -       dvb_frontend_detach(dvb->frontend);
  2722. +       if (dvb->fe[1])
  2723. +               dvb_unregister_frontend(dvb->fe[1]);
  2724. +       dvb_unregister_frontend(dvb->fe[0]);
  2725. +fail_frontend1:
  2726. +       if (dvb->fe[1])
  2727. +               dvb_frontend_detach(dvb->fe[1]);
  2728. +fail_frontend0:
  2729. +       dvb_frontend_detach(dvb->fe[0]);
  2730.         dvb_unregister_adapter(&dvb->adapter);
  2731.  fail_adapter:
  2732.         return result;
  2733. @@ -473,12 +511,15 @@ static void unregister_dvb(struct em28xx_dvb *dvb)
  2734.         dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
  2735.         dvb_dmxdev_release(&dvb->dmxdev);
  2736.         dvb_dmx_release(&dvb->demux);
  2737. -       dvb_unregister_frontend(dvb->frontend);
  2738. -       dvb_frontend_detach(dvb->frontend);
  2739. +       if (dvb->fe[1])
  2740. +               dvb_unregister_frontend(dvb->fe[1]);
  2741. +       dvb_unregister_frontend(dvb->fe[0]);
  2742. +       if (dvb->fe[1])
  2743. +               dvb_frontend_detach(dvb->fe[1]);
  2744. +       dvb_frontend_detach(dvb->fe[0]);
  2745.         dvb_unregister_adapter(&dvb->adapter);
  2746.  }
  2747.  
  2748. -
  2749.  static int dvb_init(struct em28xx *dev)
  2750.  {
  2751.         int result = 0;
  2752. @@ -497,16 +538,17 @@ static int dvb_init(struct em28xx *dev)
  2753.                 return -ENOMEM;
  2754.         }
  2755.         dev->dvb = dvb;
  2756. +       dvb->fe[0] = dvb->fe[1] = NULL;
  2757.  
  2758.         mutex_lock(&dev->lock);
  2759.         em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
  2760.         /* init frontend */
  2761.         switch (dev->model) {
  2762.         case EM2874_LEADERSHIP_ISDBT:
  2763. -               dvb->frontend = dvb_attach(s921_attach,
  2764. +               dvb->fe[0] = dvb_attach(s921_attach,
  2765.                                 &sharp_isdbt, &dev->i2c_adap);
  2766.  
  2767. -               if (!dvb->frontend) {
  2768. +               if (!dvb->fe[0]) {
  2769.                         result = -EINVAL;
  2770.                         goto out_free;
  2771.                 }
  2772. @@ -516,7 +558,7 @@ static int dvb_init(struct em28xx *dev)
  2773.         case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
  2774.         case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
  2775.         case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
  2776. -               dvb->frontend = dvb_attach(lgdt330x_attach,
  2777. +               dvb->fe[0] = dvb_attach(lgdt330x_attach,
  2778.                                            &em2880_lgdt3303_dev,
  2779.                                            &dev->i2c_adap);
  2780.                 if (attach_xc3028(0x61, dev) < 0) {
  2781. @@ -525,7 +567,7 @@ static int dvb_init(struct em28xx *dev)
  2782.                 }
  2783.                 break;
  2784.         case EM2880_BOARD_KWORLD_DVB_310U:
  2785. -               dvb->frontend = dvb_attach(zl10353_attach,
  2786. +               dvb->fe[0] = dvb_attach(zl10353_attach,
  2787.                                            &em28xx_zl10353_with_xc3028,
  2788.                                            &dev->i2c_adap);
  2789.                 if (attach_xc3028(0x61, dev) < 0) {
  2790. @@ -536,7 +578,7 @@ static int dvb_init(struct em28xx *dev)
  2791.         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
  2792.         case EM2882_BOARD_TERRATEC_HYBRID_XS:
  2793.         case EM2880_BOARD_EMPIRE_DUAL_TV:
  2794. -               dvb->frontend = dvb_attach(zl10353_attach,
  2795. +               dvb->fe[0] = dvb_attach(zl10353_attach,
  2796.                                            &em28xx_zl10353_xc3028_no_i2c_gate,
  2797.                                            &dev->i2c_adap);
  2798.                 if (attach_xc3028(0x61, dev) < 0) {
  2799. @@ -549,13 +591,13 @@ static int dvb_init(struct em28xx *dev)
  2800.         case EM2881_BOARD_PINNACLE_HYBRID_PRO:
  2801.         case EM2882_BOARD_DIKOM_DK300:
  2802.         case EM2882_BOARD_KWORLD_VS_DVBT:
  2803. -               dvb->frontend = dvb_attach(zl10353_attach,
  2804. +               dvb->fe[0] = dvb_attach(zl10353_attach,
  2805.                                            &em28xx_zl10353_xc3028_no_i2c_gate,
  2806.                                            &dev->i2c_adap);
  2807. -               if (dvb->frontend == NULL) {
  2808. +               if (dvb->fe[0] == NULL) {
  2809.                         /* This board could have either a zl10353 or a mt352.
  2810.                            If the chip id isn't for zl10353, try mt352 */
  2811. -                       dvb->frontend = dvb_attach(mt352_attach,
  2812. +                       dvb->fe[0] = dvb_attach(mt352_attach,
  2813.                                                    &terratec_xs_mt352_cfg,
  2814.                                                    &dev->i2c_adap);
  2815.                 }
  2816. @@ -567,7 +609,7 @@ static int dvb_init(struct em28xx *dev)
  2817.                 break;
  2818.         case EM2883_BOARD_KWORLD_HYBRID_330U:
  2819.         case EM2882_BOARD_EVGA_INDTUBE:
  2820. -               dvb->frontend = dvb_attach(s5h1409_attach,
  2821. +               dvb->fe[0] = dvb_attach(s5h1409_attach,
  2822.                                            &em28xx_s5h1409_with_xc3028,
  2823.                                            &dev->i2c_adap);
  2824.                 if (attach_xc3028(0x61, dev) < 0) {
  2825. @@ -576,11 +618,11 @@ static int dvb_init(struct em28xx *dev)
  2826.                 }
  2827.                 break;
  2828.         case EM2882_BOARD_KWORLD_ATSC_315U:
  2829. -               dvb->frontend = dvb_attach(lgdt330x_attach,
  2830. +               dvb->fe[0] = dvb_attach(lgdt330x_attach,
  2831.                                            &em2880_lgdt3303_dev,
  2832.                                            &dev->i2c_adap);
  2833. -               if (dvb->frontend != NULL) {
  2834. -                       if (!dvb_attach(simple_tuner_attach, dvb->frontend,
  2835. +               if (dvb->fe[0] != NULL) {
  2836. +                       if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
  2837.                                 &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
  2838.                                 result = -EINVAL;
  2839.                                 goto out_free;
  2840. @@ -602,11 +644,11 @@ static int dvb_init(struct em28xx *dev)
  2841.  #endif
  2842.         case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
  2843.                 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
  2844. -               dvb->frontend = dvb_attach(tda10023_attach,
  2845. +               dvb->fe[0] = dvb_attach(tda10023_attach,
  2846.                         &em28xx_tda10023_config,
  2847.                         &dev->i2c_adap, 0x48);
  2848. -               if (dvb->frontend) {
  2849. -                       if (!dvb_attach(simple_tuner_attach, dvb->frontend,
  2850. +               if (dvb->fe[0]) {
  2851. +                       if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
  2852.                                 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
  2853.                                 result = -EINVAL;
  2854.                                 goto out_free;
  2855. @@ -614,25 +656,53 @@ static int dvb_init(struct em28xx *dev)
  2856.                 }
  2857.                 break;
  2858.         case EM2870_BOARD_KWORLD_A340:
  2859. -               dvb->frontend = dvb_attach(lgdt3305_attach,
  2860. +               dvb->fe[0] = dvb_attach(lgdt3305_attach,
  2861.                                            &em2870_lgdt3304_dev,
  2862.                                            &dev->i2c_adap);
  2863. -               if (dvb->frontend != NULL)
  2864. -                       dvb_attach(tda18271_attach, dvb->frontend, 0x60,
  2865. +               if (dvb->fe[0] != NULL)
  2866. +                       dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
  2867.                                    &dev->i2c_adap, &kworld_a340_config);
  2868.                 break;
  2869. +       case EM28174_BOARD_PCTV_290E:
  2870. +               /* MFE
  2871. +                * FE 0 = DVB-T/T2 + FE 1 = DVB-C, both sharing same tuner. */
  2872. +               /* FE 0 */
  2873. +               dvb->fe[0] = dvb_attach(cxd2820r_attach,
  2874. +                       &em28xx_cxd2820r_config, &dev->i2c_adap, NULL);
  2875. +               if (dvb->fe[0]) {
  2876. +                       struct i2c_adapter *i2c_tuner;
  2877. +                       i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]);
  2878. +                       /* FE 0 attach tuner */
  2879. +                       if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
  2880. +                               i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
  2881. +                               dvb_frontend_detach(dvb->fe[0]);
  2882. +                               result = -EINVAL;
  2883. +                               goto out_free;
  2884. +                       }
  2885. +                       /* FE 1. This dvb_attach() cannot fail. */
  2886. +                       dvb->fe[1] = dvb_attach(cxd2820r_attach, NULL, NULL,
  2887. +                               dvb->fe[0]);
  2888. +                       dvb->fe[1]->id = 1;
  2889. +                       /* FE 1 attach tuner */
  2890. +                       if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60,
  2891. +                               i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
  2892. +                               dvb_frontend_detach(dvb->fe[1]);
  2893. +                               /* leave FE 0 still active */
  2894. +                       }
  2895. +               }
  2896. +               break;
  2897.         default:
  2898.                 em28xx_errdev("/2: The frontend of your DVB/ATSC card"
  2899.                                 " isn't supported yet\n");
  2900.                 break;
  2901.         }
  2902. -       if (NULL == dvb->frontend) {
  2903. +       if (NULL == dvb->fe[0]) {
  2904.                 em28xx_errdev("/2: frontend initialization failed\n");
  2905.                 result = -EINVAL;
  2906.                 goto out_free;
  2907.         }
  2908.         /* define general-purpose callback pointer */
  2909. -       dvb->frontend->callback = em28xx_tuner_callback;
  2910. +       dvb->fe[0]->callback = em28xx_tuner_callback;
  2911.  
  2912.         /* register everything */
  2913.         result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
  2914. diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
  2915. index 71474d3..4739fc7 100644
  2916. --- a/drivers/media/video/em28xx/em28xx-i2c.c
  2917. +++ b/drivers/media/video/em28xx/em28xx-i2c.c
  2918. @@ -332,7 +332,7 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
  2919.         struct em28xx_eeprom *em_eeprom = (void *)eedata;
  2920.         int i, err, size = len, block;
  2921.  
  2922. -       if (dev->chip_id == CHIP_ID_EM2874) {
  2923. +       if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
  2924.                 /* Empia switched to a 16-bit addressable eeprom in newer
  2925.                    devices.  While we could certainly write a routine to read
  2926.                    the eeprom, there is nothing of use in there that cannot be
  2927. diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
  2928. index 91e9055..e92a28e 100644
  2929. --- a/drivers/media/video/em28xx/em28xx-reg.h
  2930. +++ b/drivers/media/video/em28xx/em28xx-reg.h
  2931. @@ -201,6 +201,7 @@ enum em28xx_chip_id {
  2932.         CHIP_ID_EM2870 = 35,
  2933.         CHIP_ID_EM2883 = 36,
  2934.         CHIP_ID_EM2874 = 65,
  2935. +       CHIP_ID_EM28174 = 113,
  2936.  };
  2937.  
  2938.  /*
  2939. diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
  2940. index 6f2795a..60f9c2a 100644
  2941. --- a/drivers/media/video/em28xx/em28xx.h
  2942. +++ b/drivers/media/video/em28xx/em28xx.h
  2943. @@ -118,6 +118,7 @@
  2944.  #define EM2882_BOARD_DIKOM_DK300                 75
  2945.  #define EM2870_BOARD_KWORLD_A340                 76
  2946.  #define EM2874_LEADERSHIP_ISDBT                          77
  2947. +#define EM28174_BOARD_PCTV_290E                   78
  2948.  
  2949.  
  2950.  /* Limits minimum and default number of buffers */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement