Guest User

PCTV_290e_for_2.6.38.2

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