budget-ci.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012
  1. /*
  2. * budget-ci.c: driver for the SAA7146 based Budget DVB cards
  3. *
  4. * Compiled from various sources by Michael Hunold <michael@mihu.de>
  5. *
  6. * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
  7. * partially based on the Siemens DVB driver by Ralph+Marcus Metzler
  8. *
  9. * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License
  13. * as published by the Free Software Foundation; either version 2
  14. * of the License, or (at your option) any later version.
  15. *
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  26. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  27. *
  28. *
  29. * the project's page is at http://www.linuxtv.org/dvb/
  30. */
  31. #include "budget.h"
  32. #include <linux/module.h>
  33. #include <linux/errno.h>
  34. #include <linux/slab.h>
  35. #include <linux/interrupt.h>
  36. #include <linux/input.h>
  37. #include <linux/spinlock.h>
  38. #include "dvb_ca_en50221.h"
  39. #include "stv0299.h"
  40. #include "tda1004x.h"
  41. #define DEBIADDR_IR 0x1234
  42. #define DEBIADDR_CICONTROL 0x0000
  43. #define DEBIADDR_CIVERSION 0x4000
  44. #define DEBIADDR_IO 0x1000
  45. #define DEBIADDR_ATTR 0x3000
  46. #define CICONTROL_RESET 0x01
  47. #define CICONTROL_ENABLETS 0x02
  48. #define CICONTROL_CAMDETECT 0x08
  49. #define DEBICICTL 0x00420000
  50. #define DEBICICAM 0x02420000
  51. #define SLOTSTATUS_NONE 1
  52. #define SLOTSTATUS_PRESENT 2
  53. #define SLOTSTATUS_RESET 4
  54. #define SLOTSTATUS_READY 8
  55. #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
  56. struct budget_ci {
  57. struct budget budget;
  58. struct input_dev input_dev;
  59. struct tasklet_struct msp430_irq_tasklet;
  60. struct tasklet_struct ciintf_irq_tasklet;
  61. int slot_status;
  62. struct dvb_ca_en50221 ca;
  63. char ir_dev_name[50];
  64. u8 tuner_pll_address; /* used for philips_tdm1316l configs */
  65. };
  66. /* from reading the following remotes:
  67. Zenith Universal 7 / TV Mode 807 / VCR Mode 837
  68. Hauppauge (from NOVA-CI-s box product)
  69. i've taken a "middle of the road" approach and note the differences
  70. */
  71. static u16 key_map[64] = {
  72. /* 0x0X */
  73. KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
  74. KEY_9,
  75. KEY_ENTER,
  76. KEY_RED,
  77. KEY_POWER, /* RADIO on Hauppauge */
  78. KEY_MUTE,
  79. 0,
  80. KEY_A, /* TV on Hauppauge */
  81. /* 0x1X */
  82. KEY_VOLUMEUP, KEY_VOLUMEDOWN,
  83. 0, 0,
  84. KEY_B,
  85. 0, 0, 0, 0, 0, 0, 0,
  86. KEY_UP, KEY_DOWN,
  87. KEY_OPTION, /* RESERVED on Hauppauge */
  88. KEY_BREAK,
  89. /* 0x2X */
  90. KEY_CHANNELUP, KEY_CHANNELDOWN,
  91. KEY_PREVIOUS, /* Prev. Ch on Zenith, SOURCE on Hauppauge */
  92. 0, KEY_RESTART, KEY_OK,
  93. KEY_CYCLEWINDOWS, /* MINIMIZE on Hauppauge */
  94. 0,
  95. KEY_ENTER, /* VCR mode on Zenith */
  96. KEY_PAUSE,
  97. 0,
  98. KEY_RIGHT, KEY_LEFT,
  99. 0,
  100. KEY_MENU, /* FULL SCREEN on Hauppauge */
  101. 0,
  102. /* 0x3X */
  103. KEY_SLOW,
  104. KEY_PREVIOUS, /* VCR mode on Zenith */
  105. KEY_REWIND,
  106. 0,
  107. KEY_FASTFORWARD,
  108. KEY_PLAY, KEY_STOP,
  109. KEY_RECORD,
  110. KEY_TUNER, /* TV/VCR on Zenith */
  111. 0,
  112. KEY_C,
  113. 0,
  114. KEY_EXIT,
  115. KEY_POWER2,
  116. KEY_TUNER, /* VCR mode on Zenith */
  117. 0,
  118. };
  119. static void msp430_ir_debounce(unsigned long data)
  120. {
  121. struct input_dev *dev = (struct input_dev *) data;
  122. if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
  123. input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
  124. return;
  125. }
  126. dev->rep[0] = 0;
  127. dev->timer.expires = jiffies + HZ * 350 / 1000;
  128. add_timer(&dev->timer);
  129. input_event(dev, EV_KEY, key_map[dev->repeat_key], 2); /* REPEAT */
  130. }
  131. static void msp430_ir_interrupt(unsigned long data)
  132. {
  133. struct budget_ci *budget_ci = (struct budget_ci *) data;
  134. struct input_dev *dev = &budget_ci->input_dev;
  135. unsigned int code =
  136. ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
  137. if (code & 0x40) {
  138. code &= 0x3f;
  139. if (timer_pending(&dev->timer)) {
  140. if (code == dev->repeat_key) {
  141. ++dev->rep[0];
  142. return;
  143. }
  144. del_timer(&dev->timer);
  145. input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
  146. }
  147. if (!key_map[code]) {
  148. printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code);
  149. return;
  150. }
  151. /* initialize debounce and repeat */
  152. dev->repeat_key = code;
  153. /* Zenith remote _always_ sends 2 sequences */
  154. dev->rep[0] = ~0;
  155. /* 350 milliseconds */
  156. dev->timer.expires = jiffies + HZ * 350 / 1000;
  157. /* MAKE */
  158. input_event(dev, EV_KEY, key_map[code], !0);
  159. add_timer(&dev->timer);
  160. }
  161. }
  162. static int msp430_ir_init(struct budget_ci *budget_ci)
  163. {
  164. struct saa7146_dev *saa = budget_ci->budget.dev;
  165. int i;
  166. memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
  167. sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
  168. budget_ci->input_dev.name = budget_ci->ir_dev_name;
  169. set_bit(EV_KEY, budget_ci->input_dev.evbit);
  170. for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
  171. if (key_map[i])
  172. set_bit(key_map[i], budget_ci->input_dev.keybit);
  173. input_register_device(&budget_ci->input_dev);
  174. budget_ci->input_dev.timer.function = msp430_ir_debounce;
  175. saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
  176. saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
  177. return 0;
  178. }
  179. static void msp430_ir_deinit(struct budget_ci *budget_ci)
  180. {
  181. struct saa7146_dev *saa = budget_ci->budget.dev;
  182. struct input_dev *dev = &budget_ci->input_dev;
  183. saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
  184. saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
  185. if (del_timer(&dev->timer))
  186. input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
  187. input_unregister_device(dev);
  188. }
  189. static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
  190. {
  191. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  192. if (slot != 0)
  193. return -EINVAL;
  194. return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
  195. DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
  196. }
  197. static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
  198. {
  199. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  200. if (slot != 0)
  201. return -EINVAL;
  202. return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
  203. DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
  204. }
  205. static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
  206. {
  207. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  208. if (slot != 0)
  209. return -EINVAL;
  210. return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
  211. DEBIADDR_IO | (address & 3), 1, 1, 0);
  212. }
  213. static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
  214. {
  215. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  216. if (slot != 0)
  217. return -EINVAL;
  218. return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
  219. DEBIADDR_IO | (address & 3), 1, value, 1, 0);
  220. }
  221. static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
  222. {
  223. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  224. struct saa7146_dev *saa = budget_ci->budget.dev;
  225. if (slot != 0)
  226. return -EINVAL;
  227. // trigger on RISING edge during reset so we know when READY is re-asserted
  228. saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
  229. budget_ci->slot_status = SLOTSTATUS_RESET;
  230. ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
  231. msleep(1);
  232. ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
  233. CICONTROL_RESET, 1, 0);
  234. saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
  235. ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
  236. return 0;
  237. }
  238. static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
  239. {
  240. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  241. struct saa7146_dev *saa = budget_ci->budget.dev;
  242. if (slot != 0)
  243. return -EINVAL;
  244. saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
  245. ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
  246. return 0;
  247. }
  248. static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
  249. {
  250. struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
  251. struct saa7146_dev *saa = budget_ci->budget.dev;
  252. int tmp;
  253. if (slot != 0)
  254. return -EINVAL;
  255. saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
  256. tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
  257. ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
  258. tmp | CICONTROL_ENABLETS, 1, 0);
  259. ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
  260. return 0;
  261. }
  262. static void ciintf_interrupt(unsigned long data)
  263. {
  264. struct budget_ci *budget_ci = (struct budget_ci *) data;
  265. struct saa7146_dev *saa = budget_ci->budget.dev;
  266. unsigned int flags;
  267. // ensure we don't get spurious IRQs during initialisation
  268. if (!budget_ci->budget.ci_present)
  269. return;
  270. // read the CAM status
  271. flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
  272. if (flags & CICONTROL_CAMDETECT) {
  273. // GPIO should be set to trigger on falling edge if a CAM is present
  274. saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
  275. if (budget_ci->slot_status & SLOTSTATUS_NONE) {
  276. // CAM insertion IRQ
  277. budget_ci->slot_status = SLOTSTATUS_PRESENT;
  278. dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
  279. DVB_CA_EN50221_CAMCHANGE_INSERTED);
  280. } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
  281. // CAM ready (reset completed)
  282. budget_ci->slot_status = SLOTSTATUS_READY;
  283. dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
  284. } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
  285. // FR/DA IRQ
  286. dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
  287. }
  288. } else {
  289. // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
  290. // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
  291. // the CAM might not actually be ready yet.
  292. saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
  293. // generate a CAM removal IRQ if we haven't already
  294. if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
  295. // CAM removal IRQ
  296. budget_ci->slot_status = SLOTSTATUS_NONE;
  297. dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
  298. DVB_CA_EN50221_CAMCHANGE_REMOVED);
  299. }
  300. }
  301. }
  302. static int ciintf_init(struct budget_ci *budget_ci)
  303. {
  304. struct saa7146_dev *saa = budget_ci->budget.dev;
  305. int flags;
  306. int result;
  307. memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
  308. // enable DEBI pins
  309. saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
  310. // test if it is there
  311. if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
  312. result = -ENODEV;
  313. goto error;
  314. }
  315. // determine whether a CAM is present or not
  316. flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
  317. budget_ci->slot_status = SLOTSTATUS_NONE;
  318. if (flags & CICONTROL_CAMDETECT)
  319. budget_ci->slot_status = SLOTSTATUS_PRESENT;
  320. // register CI interface
  321. budget_ci->ca.owner = THIS_MODULE;
  322. budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
  323. budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
  324. budget_ci->ca.read_cam_control = ciintf_read_cam_control;
  325. budget_ci->ca.write_cam_control = ciintf_write_cam_control;
  326. budget_ci->ca.slot_reset = ciintf_slot_reset;
  327. budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
  328. budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
  329. budget_ci->ca.data = budget_ci;
  330. if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
  331. &budget_ci->ca,
  332. DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
  333. DVB_CA_EN50221_FLAG_IRQ_FR |
  334. DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
  335. printk("budget_ci: CI interface detected, but initialisation failed.\n");
  336. goto error;
  337. }
  338. // Setup CI slot IRQ
  339. tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
  340. if (budget_ci->slot_status != SLOTSTATUS_NONE) {
  341. saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
  342. } else {
  343. saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
  344. }
  345. saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
  346. ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
  347. CICONTROL_RESET, 1, 0);
  348. // success!
  349. printk("budget_ci: CI interface initialised\n");
  350. budget_ci->budget.ci_present = 1;
  351. // forge a fake CI IRQ so the CAM state is setup correctly
  352. flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
  353. if (budget_ci->slot_status != SLOTSTATUS_NONE)
  354. flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
  355. dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
  356. return 0;
  357. error:
  358. saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
  359. return result;
  360. }
  361. static void ciintf_deinit(struct budget_ci *budget_ci)
  362. {
  363. struct saa7146_dev *saa = budget_ci->budget.dev;
  364. // disable CI interrupts
  365. saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
  366. saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
  367. tasklet_kill(&budget_ci->ciintf_irq_tasklet);
  368. ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
  369. msleep(1);
  370. ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
  371. CICONTROL_RESET, 1, 0);
  372. // disable TS data stream to CI interface
  373. saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
  374. // release the CA device
  375. dvb_ca_en50221_release(&budget_ci->ca);
  376. // disable DEBI pins
  377. saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
  378. }
  379. static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
  380. {
  381. struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
  382. dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
  383. if (*isr & MASK_06)
  384. tasklet_schedule(&budget_ci->msp430_irq_tasklet);
  385. if (*isr & MASK_10)
  386. ttpci_budget_irq10_handler(dev, isr);
  387. if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
  388. tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
  389. }
  390. static u8 alps_bsru6_inittab[] = {
  391. 0x01, 0x15,
  392. 0x02, 0x00,
  393. 0x03, 0x00,
  394. 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
  395. 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
  396. 0x06, 0x40, /* DAC not used, set to high impendance mode */
  397. 0x07, 0x00, /* DAC LSB */
  398. 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
  399. 0x09, 0x00, /* FIFO */
  400. 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
  401. 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
  402. 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
  403. 0x10, 0x3f, // AGC2 0x3d
  404. 0x11, 0x84,
  405. 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
  406. 0x15, 0xc9, // lock detector threshold
  407. 0x16, 0x00,
  408. 0x17, 0x00,
  409. 0x18, 0x00,
  410. 0x19, 0x00,
  411. 0x1a, 0x00,
  412. 0x1f, 0x50,
  413. 0x20, 0x00,
  414. 0x21, 0x00,
  415. 0x22, 0x00,
  416. 0x23, 0x00,
  417. 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
  418. 0x29, 0x1e, // 1/2 threshold
  419. 0x2a, 0x14, // 2/3 threshold
  420. 0x2b, 0x0f, // 3/4 threshold
  421. 0x2c, 0x09, // 5/6 threshold
  422. 0x2d, 0x05, // 7/8 threshold
  423. 0x2e, 0x01,
  424. 0x31, 0x1f, // test all FECs
  425. 0x32, 0x19, // viterbi and synchro search
  426. 0x33, 0xfc, // rs control
  427. 0x34, 0x93, // error control
  428. 0x0f, 0x52,
  429. 0xff, 0xff
  430. };
  431. static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
  432. {
  433. u8 aclk = 0;
  434. u8 bclk = 0;
  435. if (srate < 1500000) {
  436. aclk = 0xb7;
  437. bclk = 0x47;
  438. } else if (srate < 3000000) {
  439. aclk = 0xb7;
  440. bclk = 0x4b;
  441. } else if (srate < 7000000) {
  442. aclk = 0xb7;
  443. bclk = 0x4f;
  444. } else if (srate < 14000000) {
  445. aclk = 0xb7;
  446. bclk = 0x53;
  447. } else if (srate < 30000000) {
  448. aclk = 0xb6;
  449. bclk = 0x53;
  450. } else if (srate < 45000000) {
  451. aclk = 0xb4;
  452. bclk = 0x51;
  453. }
  454. stv0299_writereg(fe, 0x13, aclk);
  455. stv0299_writereg(fe, 0x14, bclk);
  456. stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
  457. stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
  458. stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
  459. return 0;
  460. }
  461. static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
  462. {
  463. struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
  464. u8 buf[4];
  465. u32 div;
  466. struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
  467. if ((params->frequency < 950000) || (params->frequency > 2150000))
  468. return -EINVAL;
  469. div = (params->frequency + (125 - 1)) / 125; // round correctly
  470. buf[0] = (div >> 8) & 0x7f;
  471. buf[1] = div & 0xff;
  472. buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
  473. buf[3] = 0xC4;
  474. if (params->frequency > 1530000)
  475. buf[3] = 0xc0;
  476. if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
  477. return -EIO;
  478. return 0;
  479. }
  480. static struct stv0299_config alps_bsru6_config = {
  481. .demod_address = 0x68,
  482. .inittab = alps_bsru6_inittab,
  483. .mclk = 88000000UL,
  484. .invert = 1,
  485. .enhanced_tuning = 0,
  486. .skip_reinit = 0,
  487. .lock_output = STV0229_LOCKOUTPUT_1,
  488. .volt13_op0_op1 = STV0299_VOLT13_OP1,
  489. .min_delay_ms = 100,
  490. .set_symbol_rate = alps_bsru6_set_symbol_rate,
  491. .pll_set = alps_bsru6_pll_set,
  492. };
  493. static u8 philips_su1278_tt_inittab[] = {
  494. 0x01, 0x0f,
  495. 0x02, 0x30,
  496. 0x03, 0x00,
  497. 0x04, 0x5b,
  498. 0x05, 0x85,
  499. 0x06, 0x02,
  500. 0x07, 0x00,
  501. 0x08, 0x02,
  502. 0x09, 0x00,
  503. 0x0C, 0x01,
  504. 0x0D, 0x81,
  505. 0x0E, 0x44,
  506. 0x0f, 0x14,
  507. 0x10, 0x3c,
  508. 0x11, 0x84,
  509. 0x12, 0xda,
  510. 0x13, 0x97,
  511. 0x14, 0x95,
  512. 0x15, 0xc9,
  513. 0x16, 0x19,
  514. 0x17, 0x8c,
  515. 0x18, 0x59,
  516. 0x19, 0xf8,
  517. 0x1a, 0xfe,
  518. 0x1c, 0x7f,
  519. 0x1d, 0x00,
  520. 0x1e, 0x00,
  521. 0x1f, 0x50,
  522. 0x20, 0x00,
  523. 0x21, 0x00,
  524. 0x22, 0x00,
  525. 0x23, 0x00,
  526. 0x28, 0x00,
  527. 0x29, 0x28,
  528. 0x2a, 0x14,
  529. 0x2b, 0x0f,
  530. 0x2c, 0x09,
  531. 0x2d, 0x09,
  532. 0x31, 0x1f,
  533. 0x32, 0x19,
  534. 0x33, 0xfc,
  535. 0x34, 0x93,
  536. 0xff, 0xff
  537. };
  538. static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
  539. {
  540. stv0299_writereg(fe, 0x0e, 0x44);
  541. if (srate >= 10000000) {
  542. stv0299_writereg(fe, 0x13, 0x97);
  543. stv0299_writereg(fe, 0x14, 0x95);
  544. stv0299_writereg(fe, 0x15, 0xc9);
  545. stv0299_writereg(fe, 0x17, 0x8c);
  546. stv0299_writereg(fe, 0x1a, 0xfe);
  547. stv0299_writereg(fe, 0x1c, 0x7f);
  548. stv0299_writereg(fe, 0x2d, 0x09);
  549. } else {
  550. stv0299_writereg(fe, 0x13, 0x99);
  551. stv0299_writereg(fe, 0x14, 0x8d);
  552. stv0299_writereg(fe, 0x15, 0xce);
  553. stv0299_writereg(fe, 0x17, 0x43);
  554. stv0299_writereg(fe, 0x1a, 0x1d);
  555. stv0299_writereg(fe, 0x1c, 0x12);
  556. stv0299_writereg(fe, 0x2d, 0x05);
  557. }
  558. stv0299_writereg(fe, 0x0e, 0x23);
  559. stv0299_writereg(fe, 0x0f, 0x94);
  560. stv0299_writereg(fe, 0x10, 0x39);
  561. stv0299_writereg(fe, 0x15, 0xc9);
  562. stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
  563. stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
  564. stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
  565. return 0;
  566. }
  567. static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
  568. struct dvb_frontend_parameters *params)
  569. {
  570. struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
  571. u32 div;
  572. u8 buf[4];
  573. struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
  574. if ((params->frequency < 950000) || (params->frequency > 2150000))
  575. return -EINVAL;
  576. div = (params->frequency + (500 - 1)) / 500; // round correctly
  577. buf[0] = (div >> 8) & 0x7f;
  578. buf[1] = div & 0xff;
  579. buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
  580. buf[3] = 0x20;
  581. if (params->u.qpsk.symbol_rate < 4000000)
  582. buf[3] |= 1;
  583. if (params->frequency < 1250000)
  584. buf[3] |= 0;
  585. else if (params->frequency < 1550000)
  586. buf[3] |= 0x40;
  587. else if (params->frequency < 2050000)
  588. buf[3] |= 0x80;
  589. else if (params->frequency < 2150000)
  590. buf[3] |= 0xC0;
  591. if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
  592. return -EIO;
  593. return 0;
  594. }
  595. static struct stv0299_config philips_su1278_tt_config = {
  596. .demod_address = 0x68,
  597. .inittab = philips_su1278_tt_inittab,
  598. .mclk = 64000000UL,
  599. .invert = 0,
  600. .enhanced_tuning = 1,
  601. .skip_reinit = 1,
  602. .lock_output = STV0229_LOCKOUTPUT_1,
  603. .volt13_op0_op1 = STV0299_VOLT13_OP1,
  604. .min_delay_ms = 50,
  605. .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
  606. .pll_set = philips_su1278_tt_pll_set,
  607. };
  608. static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
  609. {
  610. struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
  611. static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
  612. static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
  613. struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len =
  614. sizeof(td1316_init) };
  615. // setup PLL configuration
  616. if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
  617. return -EIO;
  618. msleep(1);
  619. // disable the mc44BC374c (do not check for errors)
  620. tuner_msg.addr = 0x65;
  621. tuner_msg.buf = disable_mc44BC374c;
  622. tuner_msg.len = sizeof(disable_mc44BC374c);
  623. if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
  624. i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
  625. }
  626. return 0;
  627. }
  628. static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
  629. {
  630. struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
  631. u8 tuner_buf[4];
  632. struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
  633. int tuner_frequency = 0;
  634. u8 band, cp, filter;
  635. // determine charge pump
  636. tuner_frequency = params->frequency + 36130000;
  637. if (tuner_frequency < 87000000)
  638. return -EINVAL;
  639. else if (tuner_frequency < 130000000)
  640. cp = 3;
  641. else if (tuner_frequency < 160000000)
  642. cp = 5;
  643. else if (tuner_frequency < 200000000)
  644. cp = 6;
  645. else if (tuner_frequency < 290000000)
  646. cp = 3;
  647. else if (tuner_frequency < 420000000)
  648. cp = 5;
  649. else if (tuner_frequency < 480000000)
  650. cp = 6;
  651. else if (tuner_frequency < 620000000)
  652. cp = 3;
  653. else if (tuner_frequency < 830000000)
  654. cp = 5;
  655. else if (tuner_frequency < 895000000)
  656. cp = 7;
  657. else
  658. return -EINVAL;
  659. // determine band
  660. if (params->frequency < 49000000)
  661. return -EINVAL;
  662. else if (params->frequency < 159000000)
  663. band = 1;
  664. else if (params->frequency < 444000000)
  665. band = 2;
  666. else if (params->frequency < 861000000)
  667. band = 4;
  668. else
  669. return -EINVAL;
  670. // setup PLL filter and TDA9889
  671. switch (params->u.ofdm.bandwidth) {
  672. case BANDWIDTH_6_MHZ:
  673. tda1004x_write_byte(fe, 0x0C, 0x14);
  674. filter = 0;
  675. break;
  676. case BANDWIDTH_7_MHZ:
  677. tda1004x_write_byte(fe, 0x0C, 0x80);
  678. filter = 0;
  679. break;
  680. case BANDWIDTH_8_MHZ:
  681. tda1004x_write_byte(fe, 0x0C, 0x14);
  682. filter = 1;
  683. break;
  684. default:
  685. return -EINVAL;
  686. }
  687. // calculate divisor
  688. // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
  689. tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
  690. // setup tuner buffer
  691. tuner_buf[0] = tuner_frequency >> 8;
  692. tuner_buf[1] = tuner_frequency & 0xff;
  693. tuner_buf[2] = 0xca;
  694. tuner_buf[3] = (cp << 5) | (filter << 3) | band;
  695. if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
  696. return -EIO;
  697. msleep(1);
  698. return 0;
  699. }
  700. static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
  701. const struct firmware **fw, char *name)
  702. {
  703. struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
  704. return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
  705. }
  706. static struct tda1004x_config philips_tdm1316l_config = {
  707. .demod_address = 0x8,
  708. .invert = 0,
  709. .invert_oclk = 0,
  710. .xtal_freq = TDA10046_XTAL_4M,
  711. .agc_config = TDA10046_AGC_DEFAULT,
  712. .if_freq = TDA10046_FREQ_3617,
  713. .pll_init = philips_tdm1316l_pll_init,
  714. .pll_set = philips_tdm1316l_pll_set,
  715. .pll_sleep = NULL,
  716. .request_firmware = philips_tdm1316l_request_firmware,
  717. };
  718. static void frontend_init(struct budget_ci *budget_ci)
  719. {
  720. switch (budget_ci->budget.dev->pci->subsystem_device) {
  721. case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
  722. budget_ci->budget.dvb_frontend =
  723. stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
  724. if (budget_ci->budget.dvb_frontend) {
  725. break;
  726. }
  727. break;
  728. case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
  729. budget_ci->budget.dvb_frontend =
  730. stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
  731. if (budget_ci->budget.dvb_frontend) {
  732. break;
  733. }
  734. break;
  735. case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
  736. budget_ci->tuner_pll_address = 0x63;
  737. budget_ci->budget.dvb_frontend =
  738. tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
  739. if (budget_ci->budget.dvb_frontend) {
  740. break;
  741. }
  742. break;
  743. case 0x1012: // Hauppauge/TT Nova-T CI budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
  744. budget_ci->tuner_pll_address = 0x60;
  745. budget_ci->budget.dvb_frontend =
  746. tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
  747. if (budget_ci->budget.dvb_frontend) {
  748. break;
  749. }
  750. break;
  751. }
  752. if (budget_ci->budget.dvb_frontend == NULL) {
  753. printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
  754. budget_ci->budget.dev->pci->vendor,
  755. budget_ci->budget.dev->pci->device,
  756. budget_ci->budget.dev->pci->subsystem_vendor,
  757. budget_ci->budget.dev->pci->subsystem_device);
  758. } else {
  759. if (dvb_register_frontend
  760. (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
  761. printk("budget-ci: Frontend registration failed!\n");
  762. if (budget_ci->budget.dvb_frontend->ops->release)
  763. budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
  764. budget_ci->budget.dvb_frontend = NULL;
  765. }
  766. }
  767. }
  768. static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
  769. {
  770. struct budget_ci *budget_ci;
  771. int err;
  772. if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL)))
  773. return -ENOMEM;
  774. dprintk(2, "budget_ci: %p\n", budget_ci);
  775. budget_ci->budget.ci_present = 0;
  776. dev->ext_priv = budget_ci;
  777. if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) {
  778. kfree(budget_ci);
  779. return err;
  780. }
  781. tasklet_init(&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
  782. (unsigned long) budget_ci);
  783. msp430_ir_init(budget_ci);
  784. ciintf_init(budget_ci);
  785. budget_ci->budget.dvb_adapter.priv = budget_ci;
  786. frontend_init(budget_ci);
  787. return 0;
  788. }
  789. static int budget_ci_detach(struct saa7146_dev *dev)
  790. {
  791. struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv;
  792. struct saa7146_dev *saa = budget_ci->budget.dev;
  793. int err;
  794. if (budget_ci->budget.ci_present)
  795. ciintf_deinit(budget_ci);
  796. if (budget_ci->budget.dvb_frontend)
  797. dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
  798. err = ttpci_budget_deinit(&budget_ci->budget);
  799. tasklet_kill(&budget_ci->msp430_irq_tasklet);
  800. msp430_ir_deinit(budget_ci);
  801. // disable frontend and CI interface
  802. saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
  803. kfree(budget_ci);
  804. return err;
  805. }
  806. static struct saa7146_extension budget_extension;
  807. MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
  808. MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
  809. MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
  810. static struct pci_device_id pci_tbl[] = {
  811. MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
  812. MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
  813. MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
  814. MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
  815. {
  816. .vendor = 0,
  817. }
  818. };
  819. MODULE_DEVICE_TABLE(pci, pci_tbl);
  820. static struct saa7146_extension budget_extension = {
  821. .name = "budget_ci dvb\0",
  822. .flags = 0,
  823. .module = THIS_MODULE,
  824. .pci_tbl = &pci_tbl[0],
  825. .attach = budget_ci_attach,
  826. .detach = budget_ci_detach,
  827. .irq_mask = MASK_03 | MASK_06 | MASK_10,
  828. .irq_func = budget_ci_irq,
  829. };
  830. static int __init budget_ci_init(void)
  831. {
  832. return saa7146_register_extension(&budget_extension);
  833. }
  834. static void __exit budget_ci_exit(void)
  835. {
  836. saa7146_unregister_extension(&budget_extension);
  837. }
  838. module_init(budget_ci_init);
  839. module_exit(budget_ci_exit);
  840. MODULE_LICENSE("GPL");
  841. MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
  842. MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
  843. "budget PCI DVB cards w/ CI-module produced by "
  844. "Siemens, Technotrend, Hauppauge");