dst.c 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. /*
  2. Frontend/Card driver for TwinHan DST Frontend
  3. Copyright (C) 2003 Jamie Honan
  4. Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/init.h>
  20. #include <linux/string.h>
  21. #include <linux/slab.h>
  22. #include <linux/vmalloc.h>
  23. #include <linux/delay.h>
  24. #include <asm/div64.h>
  25. #include "dvb_frontend.h"
  26. #include "dst_priv.h"
  27. #include "dst_common.h"
  28. static unsigned int verbose = 1;
  29. module_param(verbose, int, 0644);
  30. MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
  31. static unsigned int dst_addons;
  32. module_param(dst_addons, int, 0644);
  33. MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)");
  34. static unsigned int dst_algo;
  35. module_param(dst_algo, int, 0644);
  36. MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)");
  37. #define HAS_LOCK 1
  38. #define ATTEMPT_TUNE 2
  39. #define HAS_POWER 4
  40. #define DST_ERROR 0
  41. #define DST_NOTICE 1
  42. #define DST_INFO 2
  43. #define DST_DEBUG 3
  44. #define dprintk(x, y, z, format, arg...) do { \
  45. if (z) { \
  46. if ((x > DST_ERROR) && (x > y)) \
  47. printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \
  48. else if ((x > DST_NOTICE) && (x > y)) \
  49. printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \
  50. else if ((x > DST_INFO) && (x > y)) \
  51. printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \
  52. else if ((x > DST_DEBUG) && (x > y)) \
  53. printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \
  54. } else { \
  55. if (x > y) \
  56. printk(format, ##arg); \
  57. } \
  58. } while(0)
  59. static void dst_packsize(struct dst_state *state, int psize)
  60. {
  61. union dst_gpio_packet bits;
  62. bits.psize = psize;
  63. bt878_device_control(state->bt, DST_IG_TS, &bits);
  64. }
  65. int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, u32 outhigh, int delay)
  66. {
  67. union dst_gpio_packet enb;
  68. union dst_gpio_packet bits;
  69. int err;
  70. enb.enb.mask = mask;
  71. enb.enb.enable = enbb;
  72. dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh);
  73. if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) {
  74. dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb);
  75. return -EREMOTEIO;
  76. }
  77. udelay(1000);
  78. /* because complete disabling means no output, no need to do output packet */
  79. if (enbb == 0)
  80. return 0;
  81. if (delay)
  82. msleep(10);
  83. bits.outp.mask = enbb;
  84. bits.outp.highvals = outhigh;
  85. if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) {
  86. dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh);
  87. return -EREMOTEIO;
  88. }
  89. return 0;
  90. }
  91. EXPORT_SYMBOL(dst_gpio_outb);
  92. int dst_gpio_inb(struct dst_state *state, u8 *result)
  93. {
  94. union dst_gpio_packet rd_packet;
  95. int err;
  96. *result = 0;
  97. if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) {
  98. dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err);
  99. return -EREMOTEIO;
  100. }
  101. *result = (u8) rd_packet.rd.value;
  102. return 0;
  103. }
  104. EXPORT_SYMBOL(dst_gpio_inb);
  105. int rdc_reset_state(struct dst_state *state)
  106. {
  107. dprintk(verbose, DST_INFO, 1, "Resetting state machine");
  108. if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) {
  109. dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
  110. return -1;
  111. }
  112. msleep(10);
  113. if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) {
  114. dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
  115. msleep(10);
  116. return -1;
  117. }
  118. return 0;
  119. }
  120. EXPORT_SYMBOL(rdc_reset_state);
  121. int rdc_8820_reset(struct dst_state *state)
  122. {
  123. dprintk(verbose, DST_DEBUG, 1, "Resetting DST");
  124. if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) {
  125. dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
  126. return -1;
  127. }
  128. udelay(1000);
  129. if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) {
  130. dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
  131. return -1;
  132. }
  133. return 0;
  134. }
  135. EXPORT_SYMBOL(rdc_8820_reset);
  136. int dst_pio_enable(struct dst_state *state)
  137. {
  138. if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) {
  139. dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
  140. return -1;
  141. }
  142. udelay(1000);
  143. return 0;
  144. }
  145. EXPORT_SYMBOL(dst_pio_enable);
  146. int dst_pio_disable(struct dst_state *state)
  147. {
  148. if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) {
  149. dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !");
  150. return -1;
  151. }
  152. if (state->type_flags & DST_TYPE_HAS_FW_1)
  153. udelay(1000);
  154. return 0;
  155. }
  156. EXPORT_SYMBOL(dst_pio_disable);
  157. int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode)
  158. {
  159. u8 reply;
  160. int i;
  161. for (i = 0; i < 200; i++) {
  162. if (dst_gpio_inb(state, &reply) < 0) {
  163. dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !");
  164. return -1;
  165. }
  166. if ((reply & RDC_8820_PIO_0_ENABLE) == 0) {
  167. dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i);
  168. return 1;
  169. }
  170. msleep(10);
  171. }
  172. dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i);
  173. return 0;
  174. }
  175. EXPORT_SYMBOL(dst_wait_dst_ready);
  176. int dst_error_recovery(struct dst_state *state)
  177. {
  178. dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors.");
  179. dst_pio_disable(state);
  180. msleep(10);
  181. dst_pio_enable(state);
  182. msleep(10);
  183. return 0;
  184. }
  185. EXPORT_SYMBOL(dst_error_recovery);
  186. int dst_error_bailout(struct dst_state *state)
  187. {
  188. dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error.");
  189. rdc_8820_reset(state);
  190. dst_pio_disable(state);
  191. msleep(10);
  192. return 0;
  193. }
  194. EXPORT_SYMBOL(dst_error_bailout);
  195. int dst_comm_init(struct dst_state *state)
  196. {
  197. dprintk(verbose, DST_INFO, 1, "Initializing DST.");
  198. if ((dst_pio_enable(state)) < 0) {
  199. dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed");
  200. return -1;
  201. }
  202. if ((rdc_reset_state(state)) < 0) {
  203. dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed.");
  204. return -1;
  205. }
  206. if (state->type_flags & DST_TYPE_HAS_FW_1)
  207. msleep(100);
  208. else
  209. msleep(5);
  210. return 0;
  211. }
  212. EXPORT_SYMBOL(dst_comm_init);
  213. int write_dst(struct dst_state *state, u8 *data, u8 len)
  214. {
  215. struct i2c_msg msg = {
  216. .addr = state->config->demod_address,
  217. .flags = 0,
  218. .buf = data,
  219. .len = len
  220. };
  221. int err;
  222. u8 cnt, i;
  223. dprintk(verbose, DST_NOTICE, 0, "writing [ ");
  224. for (i = 0; i < len; i++)
  225. dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]);
  226. dprintk(verbose, DST_NOTICE, 0, "]\n");
  227. for (cnt = 0; cnt < 2; cnt++) {
  228. if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
  229. dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]);
  230. dst_error_recovery(state);
  231. continue;
  232. } else
  233. break;
  234. }
  235. if (cnt >= 2) {
  236. dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
  237. dst_error_bailout(state);
  238. return -1;
  239. }
  240. return 0;
  241. }
  242. EXPORT_SYMBOL(write_dst);
  243. int read_dst(struct dst_state *state, u8 *ret, u8 len)
  244. {
  245. struct i2c_msg msg = {
  246. .addr = state->config->demod_address,
  247. .flags = I2C_M_RD,
  248. .buf = ret,
  249. .len = len
  250. };
  251. int err;
  252. int cnt;
  253. for (cnt = 0; cnt < 2; cnt++) {
  254. if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) {
  255. dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]);
  256. dst_error_recovery(state);
  257. continue;
  258. } else
  259. break;
  260. }
  261. if (cnt >= 2) {
  262. dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET");
  263. dst_error_bailout(state);
  264. return -1;
  265. }
  266. dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]);
  267. for (err = 1; err < len; err++)
  268. dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]);
  269. if (err > 1)
  270. dprintk(verbose, DST_DEBUG, 0, "\n");
  271. return 0;
  272. }
  273. EXPORT_SYMBOL(read_dst);
  274. static int dst_set_polarization(struct dst_state *state)
  275. {
  276. switch (state->voltage) {
  277. case SEC_VOLTAGE_13: /* Vertical */
  278. dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]");
  279. state->tx_tuna[8] &= ~0x40;
  280. break;
  281. case SEC_VOLTAGE_18: /* Horizontal */
  282. dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]");
  283. state->tx_tuna[8] |= 0x40;
  284. break;
  285. case SEC_VOLTAGE_OFF:
  286. break;
  287. }
  288. return 0;
  289. }
  290. static int dst_set_freq(struct dst_state *state, u32 freq)
  291. {
  292. state->frequency = freq;
  293. dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq);
  294. if (state->dst_type == DST_TYPE_IS_SAT) {
  295. freq = freq / 1000;
  296. if (freq < 950 || freq > 2150)
  297. return -EINVAL;
  298. state->tx_tuna[2] = (freq >> 8);
  299. state->tx_tuna[3] = (u8) freq;
  300. state->tx_tuna[4] = 0x01;
  301. state->tx_tuna[8] &= ~0x04;
  302. if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
  303. if (freq < 1531)
  304. state->tx_tuna[8] |= 0x04;
  305. }
  306. } else if (state->dst_type == DST_TYPE_IS_TERR) {
  307. freq = freq / 1000;
  308. if (freq < 137000 || freq > 858000)
  309. return -EINVAL;
  310. state->tx_tuna[2] = (freq >> 16) & 0xff;
  311. state->tx_tuna[3] = (freq >> 8) & 0xff;
  312. state->tx_tuna[4] = (u8) freq;
  313. } else if (state->dst_type == DST_TYPE_IS_CABLE) {
  314. freq = freq / 1000;
  315. state->tx_tuna[2] = (freq >> 16) & 0xff;
  316. state->tx_tuna[3] = (freq >> 8) & 0xff;
  317. state->tx_tuna[4] = (u8) freq;
  318. } else if (state->dst_type == DST_TYPE_IS_ATSC) {
  319. freq = freq / 1000;
  320. if (freq < 51000 || freq > 858000)
  321. return -EINVAL;
  322. state->tx_tuna[2] = (freq >> 16) & 0xff;
  323. state->tx_tuna[3] = (freq >> 8) & 0xff;
  324. state->tx_tuna[4] = (u8) freq;
  325. state->tx_tuna[5] = 0x00; /* ATSC */
  326. state->tx_tuna[6] = 0x00;
  327. if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG)
  328. state->tx_tuna[7] = 0x00; /* Digital */
  329. } else
  330. return -EINVAL;
  331. return 0;
  332. }
  333. static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth)
  334. {
  335. state->bandwidth = bandwidth;
  336. if (state->dst_type != DST_TYPE_IS_TERR)
  337. return 0;
  338. switch (bandwidth) {
  339. case BANDWIDTH_6_MHZ:
  340. if (state->dst_hw_cap & DST_TYPE_HAS_CA)
  341. state->tx_tuna[7] = 0x06;
  342. else {
  343. state->tx_tuna[6] = 0x06;
  344. state->tx_tuna[7] = 0x00;
  345. }
  346. break;
  347. case BANDWIDTH_7_MHZ:
  348. if (state->dst_hw_cap & DST_TYPE_HAS_CA)
  349. state->tx_tuna[7] = 0x07;
  350. else {
  351. state->tx_tuna[6] = 0x07;
  352. state->tx_tuna[7] = 0x00;
  353. }
  354. break;
  355. case BANDWIDTH_8_MHZ:
  356. if (state->dst_hw_cap & DST_TYPE_HAS_CA)
  357. state->tx_tuna[7] = 0x08;
  358. else {
  359. state->tx_tuna[6] = 0x08;
  360. state->tx_tuna[7] = 0x00;
  361. }
  362. break;
  363. default:
  364. return -EINVAL;
  365. }
  366. return 0;
  367. }
  368. static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion)
  369. {
  370. state->inversion = inversion;
  371. switch (inversion) {
  372. case INVERSION_OFF: /* Inversion = Normal */
  373. state->tx_tuna[8] &= ~0x80;
  374. break;
  375. case INVERSION_ON:
  376. state->tx_tuna[8] |= 0x80;
  377. break;
  378. default:
  379. return -EINVAL;
  380. }
  381. return 0;
  382. }
  383. static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec)
  384. {
  385. state->fec = fec;
  386. return 0;
  387. }
  388. static fe_code_rate_t dst_get_fec(struct dst_state *state)
  389. {
  390. return state->fec;
  391. }
  392. static int dst_set_symbolrate(struct dst_state *state, u32 srate)
  393. {
  394. u32 symcalc;
  395. u64 sval;
  396. state->symbol_rate = srate;
  397. if (state->dst_type == DST_TYPE_IS_TERR) {
  398. return 0;
  399. }
  400. dprintk(verbose, DST_INFO, 1, "set symrate %u", srate);
  401. srate /= 1000;
  402. if (state->type_flags & DST_TYPE_HAS_SYMDIV) {
  403. sval = srate;
  404. sval <<= 20;
  405. do_div(sval, 88000);
  406. symcalc = (u32) sval;
  407. dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc);
  408. state->tx_tuna[5] = (u8) (symcalc >> 12);
  409. state->tx_tuna[6] = (u8) (symcalc >> 4);
  410. state->tx_tuna[7] = (u8) (symcalc << 4);
  411. } else {
  412. state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f;
  413. state->tx_tuna[6] = (u8) (srate >> 8);
  414. state->tx_tuna[7] = (u8) srate;
  415. }
  416. state->tx_tuna[8] &= ~0x20;
  417. if (state->type_flags & DST_TYPE_HAS_OBS_REGS) {
  418. if (srate > 8000)
  419. state->tx_tuna[8] |= 0x20;
  420. }
  421. return 0;
  422. }
  423. static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation)
  424. {
  425. if (state->dst_type != DST_TYPE_IS_CABLE)
  426. return 0;
  427. state->modulation = modulation;
  428. switch (modulation) {
  429. case QAM_16:
  430. state->tx_tuna[8] = 0x10;
  431. break;
  432. case QAM_32:
  433. state->tx_tuna[8] = 0x20;
  434. break;
  435. case QAM_64:
  436. state->tx_tuna[8] = 0x40;
  437. break;
  438. case QAM_128:
  439. state->tx_tuna[8] = 0x80;
  440. break;
  441. case QAM_256:
  442. state->tx_tuna[8] = 0x00;
  443. break;
  444. case QPSK:
  445. case QAM_AUTO:
  446. case VSB_8:
  447. case VSB_16:
  448. default:
  449. return -EINVAL;
  450. }
  451. return 0;
  452. }
  453. static fe_modulation_t dst_get_modulation(struct dst_state *state)
  454. {
  455. return state->modulation;
  456. }
  457. u8 dst_check_sum(u8 *buf, u32 len)
  458. {
  459. u32 i;
  460. u8 val = 0;
  461. if (!len)
  462. return 0;
  463. for (i = 0; i < len; i++) {
  464. val += buf[i];
  465. }
  466. return ((~val) + 1);
  467. }
  468. EXPORT_SYMBOL(dst_check_sum);
  469. static void dst_type_flags_print(u32 type_flags)
  470. {
  471. dprintk(verbose, DST_ERROR, 0, "DST type flags :");
  472. if (type_flags & DST_TYPE_HAS_NEWTUNE)
  473. dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE);
  474. if (type_flags & DST_TYPE_HAS_NEWTUNE_2)
  475. dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2);
  476. if (type_flags & DST_TYPE_HAS_TS204)
  477. dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204);
  478. if (type_flags & DST_TYPE_HAS_SYMDIV)
  479. dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV);
  480. if (type_flags & DST_TYPE_HAS_FW_1)
  481. dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1);
  482. if (type_flags & DST_TYPE_HAS_FW_2)
  483. dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2);
  484. if (type_flags & DST_TYPE_HAS_FW_3)
  485. dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3);
  486. dprintk(verbose, DST_ERROR, 0, "\n");
  487. }
  488. static int dst_type_print(u8 type)
  489. {
  490. char *otype;
  491. switch (type) {
  492. case DST_TYPE_IS_SAT:
  493. otype = "satellite";
  494. break;
  495. case DST_TYPE_IS_TERR:
  496. otype = "terrestrial";
  497. break;
  498. case DST_TYPE_IS_CABLE:
  499. otype = "cable";
  500. break;
  501. case DST_TYPE_IS_ATSC:
  502. otype = "atsc";
  503. break;
  504. default:
  505. dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type);
  506. return -EINVAL;
  507. }
  508. dprintk(verbose, DST_INFO, 1, "DST type: %s", otype);
  509. return 0;
  510. }
  511. struct tuner_types tuner_list[] = {
  512. {
  513. .tuner_type = 2,
  514. .tuner_name = "L 64724",
  515. .board_name = " "
  516. },
  517. {
  518. .tuner_type = 4,
  519. .tuner_name = "STV 0299",
  520. .board_name = "VP1030"
  521. },
  522. {
  523. .tuner_type = 8,
  524. .tuner_name = "MB 86A15",
  525. .board_name = "VP1025"
  526. },
  527. {
  528. .tuner_type = 16,
  529. .tuner_name = "NXT 200x",
  530. .board_name = "VP3250"
  531. }
  532. };
  533. /*
  534. Known cards list
  535. Satellite
  536. -------------------
  537. 200103A
  538. VP-1020 DST-MOT LG(old), TS=188
  539. VP-1020 DST-03T LG(new), TS=204
  540. VP-1022 DST-03T LG(new), TS=204
  541. VP-1025 DST-03T LG(new), TS=204
  542. VP-1030 DSTMCI, LG(new), TS=188
  543. VP-1032 DSTMCI, LG(new), TS=188
  544. Cable
  545. -------------------
  546. VP-2030 DCT-CI, Samsung, TS=204
  547. VP-2021 DCT-CI, Unknown, TS=204
  548. VP-2031 DCT-CI, Philips, TS=188
  549. VP-2040 DCT-CI, Philips, TS=188, with CA daughter board
  550. VP-2040 DCT-CI, Philips, TS=204, without CA daughter board
  551. Terrestrial
  552. -------------------
  553. VP-3050 DTTNXT TS=188
  554. VP-3040 DTT-CI, Philips, TS=188
  555. VP-3040 DTT-CI, Philips, TS=204
  556. ATSC
  557. -------------------
  558. VP-3220 ATSCDI, TS=188
  559. VP-3250 ATSCAD, TS=188
  560. */
  561. static struct dst_types dst_tlist[] = {
  562. {
  563. .device_id = "200103A",
  564. .offset = 0,
  565. .dst_type = DST_TYPE_IS_SAT,
  566. .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS,
  567. .dst_feature = 0,
  568. .tuner_type = 0
  569. }, /* obsolete */
  570. {
  571. .device_id = "DST-020",
  572. .offset = 0,
  573. .dst_type = DST_TYPE_IS_SAT,
  574. .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
  575. .dst_feature = 0,
  576. .tuner_type = 0
  577. }, /* obsolete */
  578. {
  579. .device_id = "DST-030",
  580. .offset = 0,
  581. .dst_type = DST_TYPE_IS_SAT,
  582. .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
  583. .dst_feature = 0,
  584. .tuner_type = 0
  585. }, /* obsolete */
  586. {
  587. .device_id = "DST-03T",
  588. .offset = 0,
  589. .dst_type = DST_TYPE_IS_SAT,
  590. .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2,
  591. .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5
  592. | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO,
  593. .tuner_type = TUNER_TYPE_MULTI
  594. },
  595. {
  596. .device_id = "DST-MOT",
  597. .offset = 0,
  598. .dst_type = DST_TYPE_IS_SAT,
  599. .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1,
  600. .dst_feature = 0,
  601. .tuner_type = 0
  602. }, /* obsolete */
  603. {
  604. .device_id = "DST-CI",
  605. .offset = 1,
  606. .dst_type = DST_TYPE_IS_SAT,
  607. .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1,
  608. .dst_feature = DST_TYPE_HAS_CA,
  609. .tuner_type = 0
  610. }, /* An OEM board */
  611. {
  612. .device_id = "DSTMCI",
  613. .offset = 1,
  614. .dst_type = DST_TYPE_IS_SAT,
  615. .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT,
  616. .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4
  617. | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC,
  618. .tuner_type = TUNER_TYPE_MULTI
  619. },
  620. {
  621. .device_id = "DSTFCI",
  622. .offset = 1,
  623. .dst_type = DST_TYPE_IS_SAT,
  624. .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1,
  625. .dst_feature = 0,
  626. .tuner_type = 0
  627. }, /* unknown to vendor */
  628. {
  629. .device_id = "DCT-CI",
  630. .offset = 1,
  631. .dst_type = DST_TYPE_IS_CABLE,
  632. .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2,
  633. .dst_feature = DST_TYPE_HAS_CA,
  634. .tuner_type = 0
  635. },
  636. {
  637. .device_id = "DCTNEW",
  638. .offset = 1,
  639. .dst_type = DST_TYPE_IS_CABLE,
  640. .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD,
  641. .dst_feature = 0,
  642. .tuner_type = 0
  643. },
  644. {
  645. .device_id = "DTT-CI",
  646. .offset = 1,
  647. .dst_type = DST_TYPE_IS_TERR,
  648. .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE,
  649. .dst_feature = DST_TYPE_HAS_CA,
  650. .tuner_type = 0
  651. },
  652. {
  653. .device_id = "DTTDIG",
  654. .offset = 1,
  655. .dst_type = DST_TYPE_IS_TERR,
  656. .type_flags = DST_TYPE_HAS_FW_2,
  657. .dst_feature = 0,
  658. .tuner_type = 0
  659. },
  660. {
  661. .device_id = "DTTNXT",
  662. .offset = 1,
  663. .dst_type = DST_TYPE_IS_TERR,
  664. .type_flags = DST_TYPE_HAS_FW_2,
  665. .dst_feature = DST_TYPE_HAS_ANALOG,
  666. .tuner_type = 0
  667. },
  668. {
  669. .device_id = "ATSCDI",
  670. .offset = 1,
  671. .dst_type = DST_TYPE_IS_ATSC,
  672. .type_flags = DST_TYPE_HAS_FW_2,
  673. .dst_feature = 0,
  674. .tuner_type = 0
  675. },
  676. {
  677. .device_id = "ATSCAD",
  678. .offset = 1,
  679. .dst_type = DST_TYPE_IS_ATSC,
  680. .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD,
  681. .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG,
  682. .tuner_type = 0
  683. },
  684. { }
  685. };
  686. static int dst_get_mac(struct dst_state *state)
  687. {
  688. u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  689. get_mac[7] = dst_check_sum(get_mac, 7);
  690. if (dst_command(state, get_mac, 8) < 0) {
  691. dprintk(verbose, DST_INFO, 1, "Unsupported Command");
  692. return -1;
  693. }
  694. memset(&state->mac_address, '\0', 8);
  695. memcpy(&state->mac_address, &state->rxbuffer, 6);
  696. dprintk(verbose, DST_ERROR, 1, "MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]",
  697. state->mac_address[0], state->mac_address[1], state->mac_address[2],
  698. state->mac_address[4], state->mac_address[5], state->mac_address[6]);
  699. return 0;
  700. }
  701. static int dst_fw_ver(struct dst_state *state)
  702. {
  703. u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  704. get_ver[7] = dst_check_sum(get_ver, 7);
  705. if (dst_command(state, get_ver, 8) < 0) {
  706. dprintk(verbose, DST_INFO, 1, "Unsupported Command");
  707. return -1;
  708. }
  709. memset(&state->fw_version, '\0', 8);
  710. memcpy(&state->fw_version, &state->rxbuffer, 8);
  711. dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x",
  712. state->fw_version[0] >> 4, state->fw_version[0] & 0x0f,
  713. state->fw_version[1],
  714. state->fw_version[5], state->fw_version[6],
  715. state->fw_version[4], state->fw_version[3], state->fw_version[2]);
  716. return 0;
  717. }
  718. static int dst_card_type(struct dst_state *state)
  719. {
  720. int j;
  721. struct tuner_types *p_tuner_list = NULL;
  722. u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  723. get_type[7] = dst_check_sum(get_type, 7);
  724. if (dst_command(state, get_type, 8) < 0) {
  725. dprintk(verbose, DST_INFO, 1, "Unsupported Command");
  726. return -1;
  727. }
  728. memset(&state->card_info, '\0', 8);
  729. memcpy(&state->card_info, &state->rxbuffer, 7);
  730. dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]);
  731. for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
  732. if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) {
  733. state->tuner_type = p_tuner_list->tuner_type;
  734. dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]\n",
  735. p_tuner_list->tuner_name, p_tuner_list->tuner_type);
  736. }
  737. }
  738. return 0;
  739. }
  740. static int dst_get_vendor(struct dst_state *state)
  741. {
  742. u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  743. get_vendor[7] = dst_check_sum(get_vendor, 7);
  744. if (dst_command(state, get_vendor, 8) < 0) {
  745. dprintk(verbose, DST_INFO, 1, "Unsupported Command");
  746. return -1;
  747. }
  748. memset(&state->vendor, '\0', 8);
  749. memcpy(&state->vendor, &state->rxbuffer, 7);
  750. dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]);
  751. return 0;
  752. }
  753. static int dst_get_tuner_info(struct dst_state *state)
  754. {
  755. u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  756. u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  757. get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
  758. get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
  759. dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE");
  760. if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
  761. // if (dst_command(state, get_tuner_2, 8) < 0) {
  762. if (dst_command(state, get_tuner_1, 8) < 0) {
  763. dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported");
  764. return -1;
  765. }
  766. } else {
  767. // if (dst_command(state, get_tuner_1, 8) < 0) {
  768. if (dst_command(state, get_tuner_2, 8) < 0) {
  769. dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported");
  770. return -1;
  771. }
  772. }
  773. memset(&state->board_info, '\0', 8);
  774. memcpy(&state->board_info, &state->rxbuffer, 8);
  775. if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
  776. dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
  777. /*
  778. if (state->board_info[1] == 0x0b) {
  779. if (state->type_flags & DST_TYPE_HAS_TS204)
  780. state->type_flags &= ~DST_TYPE_HAS_TS204;
  781. state->type_flags |= DST_TYPE_HAS_NEWTUNE;
  782. dprintk(verbose, DST_INFO, 1, "DST type has TS=188");
  783. } else {
  784. if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
  785. state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
  786. state->type_flags |= DST_TYPE_HAS_TS204;
  787. dprintk(verbose, DST_INFO, 1, "DST type has TS=204");
  788. }
  789. } else {
  790. */
  791. }
  792. if (state->board_info[0] == 0xbc) {
  793. // if (state->type_flags & DST_TYPE_HAS_TS204)
  794. // state->type_flags &= ~DST_TYPE_HAS_TS204;
  795. // state->type_flags |= DST_TYPE_HAS_NEWTUNE;
  796. if (!(state->type_flags & DST_TYPE_IS_ATSC)) {
  797. state->type_flags |= DST_TYPE_HAS_NEWTUNE;
  798. } else {
  799. state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
  800. }
  801. dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
  802. } else if (state->board_info[0] == 0xcc) {
  803. // if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
  804. // state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
  805. state->type_flags |= DST_TYPE_HAS_TS204;
  806. dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
  807. }
  808. // }
  809. return 0;
  810. }
  811. static int dst_get_device_id(struct dst_state *state)
  812. {
  813. u8 reply;
  814. int i, j;
  815. struct dst_types *p_dst_type;
  816. struct tuner_types *p_tuner_list;
  817. u8 use_dst_type = 0;
  818. u32 use_type_flags = 0;
  819. static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
  820. device_type[7] = dst_check_sum(device_type, 7);
  821. if (write_dst(state, device_type, FIXED_COMM))
  822. return -1; /* Write failed */
  823. if ((dst_pio_disable(state)) < 0)
  824. return -1;
  825. if (read_dst(state, &reply, GET_ACK))
  826. return -1; /* Read failure */
  827. if (reply != ACK) {
  828. dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply);
  829. return -1; /* Unack'd write */
  830. }
  831. if (!dst_wait_dst_ready(state, DEVICE_INIT))
  832. return -1; /* DST not ready yet */
  833. if (read_dst(state, state->rxbuffer, FIXED_COMM))
  834. return -1;
  835. dst_pio_disable(state);
  836. if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
  837. dprintk(verbose, DST_INFO, 1, "Checksum failure!");
  838. return -1; /* Checksum failure */
  839. }
  840. state->rxbuffer[7] = '\0';
  841. for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) {
  842. if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) {
  843. use_type_flags = p_dst_type->type_flags;
  844. use_dst_type = p_dst_type->dst_type;
  845. /* Card capabilities */
  846. state->dst_hw_cap = p_dst_type->dst_feature;
  847. dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id);
  848. if (p_dst_type->tuner_type != TUNER_TYPE_MULTI) {
  849. state->tuner_type = p_dst_type->tuner_type;
  850. for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) {
  851. if (p_dst_type->tuner_type == p_tuner_list->tuner_type) {
  852. state->tuner_type = p_tuner_list->tuner_type;
  853. dprintk(verbose, DST_ERROR, 1, "DST has a [%s] based tuner\n", p_tuner_list->tuner_name);
  854. }
  855. }
  856. }
  857. break;
  858. }
  859. }
  860. if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) {
  861. dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
  862. dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
  863. use_dst_type = DST_TYPE_IS_SAT;
  864. use_type_flags = DST_TYPE_HAS_SYMDIV;
  865. }
  866. dst_type_print(use_dst_type);
  867. state->type_flags = use_type_flags;
  868. state->dst_type = use_dst_type;
  869. dst_type_flags_print(state->type_flags);
  870. return 0;
  871. }
  872. static int dst_probe(struct dst_state *state)
  873. {
  874. mutex_init(&state->dst_mutex);
  875. if (dst_addons & DST_TYPE_HAS_CA) {
  876. if ((rdc_8820_reset(state)) < 0) {
  877. dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
  878. return -1;
  879. }
  880. msleep(4000);
  881. } else {
  882. msleep(100);
  883. }
  884. if ((dst_comm_init(state)) < 0) {
  885. dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed.");
  886. return -1;
  887. }
  888. msleep(100);
  889. if (dst_get_device_id(state) < 0) {
  890. dprintk(verbose, DST_ERROR, 1, "unknown device.");
  891. return -1;
  892. }
  893. if (dst_get_mac(state) < 0) {
  894. dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
  895. return 0;
  896. }
  897. if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
  898. if (dst_get_tuner_info(state) < 0)
  899. dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
  900. }
  901. if (state->type_flags & DST_TYPE_HAS_TS204) {
  902. dst_packsize(state, 204);
  903. }
  904. if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
  905. if (dst_fw_ver(state) < 0) {
  906. dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
  907. return 0;
  908. }
  909. if (dst_card_type(state) < 0) {
  910. dprintk(verbose, DST_INFO, 1, "Card: Unsupported command");
  911. return 0;
  912. }
  913. if (dst_get_vendor(state) < 0) {
  914. dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command");
  915. return 0;
  916. }
  917. }
  918. return 0;
  919. }
  920. int dst_command(struct dst_state *state, u8 *data, u8 len)
  921. {
  922. u8 reply;
  923. mutex_lock(&state->dst_mutex);
  924. if ((dst_comm_init(state)) < 0) {
  925. dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
  926. goto error;
  927. }
  928. if (write_dst(state, data, len)) {
  929. dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
  930. if ((dst_error_recovery(state)) < 0) {
  931. dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
  932. goto error;
  933. }
  934. goto error;
  935. }
  936. if ((dst_pio_disable(state)) < 0) {
  937. dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
  938. goto error;
  939. }
  940. if (state->type_flags & DST_TYPE_HAS_FW_1)
  941. udelay(3000);
  942. if (read_dst(state, &reply, GET_ACK)) {
  943. dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
  944. if ((dst_error_recovery(state)) < 0) {
  945. dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
  946. goto error;
  947. }
  948. goto error;
  949. }
  950. if (reply != ACK) {
  951. dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
  952. goto error;
  953. }
  954. if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
  955. goto error;
  956. if (state->type_flags & DST_TYPE_HAS_FW_1)
  957. udelay(3000);
  958. else
  959. udelay(2000);
  960. if (!dst_wait_dst_ready(state, NO_DELAY))
  961. goto error;
  962. if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
  963. dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
  964. if ((dst_error_recovery(state)) < 0) {
  965. dprintk(verbose, DST_INFO, 1, "Recovery failed.");
  966. goto error;
  967. }
  968. goto error;
  969. }
  970. if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
  971. dprintk(verbose, DST_INFO, 1, "checksum failure");
  972. goto error;
  973. }
  974. mutex_unlock(&state->dst_mutex);
  975. return 0;
  976. error:
  977. mutex_unlock(&state->dst_mutex);
  978. return -EIO;
  979. }
  980. EXPORT_SYMBOL(dst_command);
  981. static int dst_get_signal(struct dst_state *state)
  982. {
  983. int retval;
  984. u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb };
  985. //dprintk("%s: Getting Signal strength and other parameters\n", __FUNCTION__);
  986. if ((state->diseq_flags & ATTEMPT_TUNE) == 0) {
  987. state->decode_lock = state->decode_strength = state->decode_snr = 0;
  988. return 0;
  989. }
  990. if (0 == (state->diseq_flags & HAS_LOCK)) {
  991. state->decode_lock = state->decode_strength = state->decode_snr = 0;
  992. return 0;
  993. }
  994. if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) {
  995. retval = dst_command(state, get_signal, 8);
  996. if (retval < 0)
  997. return retval;
  998. if (state->dst_type == DST_TYPE_IS_SAT) {
  999. state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0;
  1000. state->decode_strength = state->rxbuffer[5] << 8;
  1001. state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
  1002. } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) {
  1003. state->decode_lock = (state->rxbuffer[1]) ? 1 : 0;
  1004. state->decode_strength = state->rxbuffer[4] << 8;
  1005. state->decode_snr = state->rxbuffer[3] << 8;
  1006. } else if (state->dst_type == DST_TYPE_IS_ATSC) {
  1007. state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0;
  1008. state->decode_strength = state->rxbuffer[4] << 8;
  1009. state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3];
  1010. }
  1011. state->cur_jiff = jiffies;
  1012. }
  1013. return 0;
  1014. }
  1015. static int dst_tone_power_cmd(struct dst_state *state)
  1016. {
  1017. u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 };
  1018. if (state->dst_type == DST_TYPE_IS_TERR)
  1019. return 0;
  1020. paket[4] = state->tx_tuna[4];
  1021. paket[2] = state->tx_tuna[2];
  1022. paket[3] = state->tx_tuna[3];
  1023. paket[7] = dst_check_sum (paket, 7);
  1024. dst_command(state, paket, 8);
  1025. return 0;
  1026. }
  1027. static int dst_get_tuna(struct dst_state *state)
  1028. {
  1029. int retval;
  1030. if ((state->diseq_flags & ATTEMPT_TUNE) == 0)
  1031. return 0;
  1032. state->diseq_flags &= ~(HAS_LOCK);
  1033. if (!dst_wait_dst_ready(state, NO_DELAY))
  1034. return -EIO;
  1035. if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
  1036. /* how to get variable length reply ???? */
  1037. retval = read_dst(state, state->rx_tuna, 10);
  1038. else
  1039. retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
  1040. if (retval < 0) {
  1041. dprintk(verbose, DST_DEBUG, 1, "read not successful");
  1042. return retval;
  1043. }
  1044. if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
  1045. if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
  1046. dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
  1047. return -EIO;
  1048. }
  1049. } else {
  1050. if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
  1051. dprintk(verbose, DST_INFO, 1, "checksum failure? ");
  1052. return -EIO;
  1053. }
  1054. }
  1055. if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
  1056. return 0;
  1057. if (state->dst_type == DST_TYPE_IS_SAT) {
  1058. state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
  1059. } else {
  1060. state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
  1061. }
  1062. state->decode_freq = state->decode_freq * 1000;
  1063. state->decode_lock = 1;
  1064. state->diseq_flags |= HAS_LOCK;
  1065. return 1;
  1066. }
  1067. static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
  1068. static int dst_write_tuna(struct dvb_frontend *fe)
  1069. {
  1070. struct dst_state *state = fe->demodulator_priv;
  1071. int retval;
  1072. u8 reply;
  1073. dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags);
  1074. state->decode_freq = 0;
  1075. state->decode_lock = state->decode_strength = state->decode_snr = 0;
  1076. if (state->dst_type == DST_TYPE_IS_SAT) {
  1077. if (!(state->diseq_flags & HAS_POWER))
  1078. dst_set_voltage(fe, SEC_VOLTAGE_13);
  1079. }
  1080. state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
  1081. mutex_lock(&state->dst_mutex);
  1082. if ((dst_comm_init(state)) < 0) {
  1083. dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
  1084. goto error;
  1085. }
  1086. if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
  1087. state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
  1088. retval = write_dst(state, &state->tx_tuna[0], 10);
  1089. } else {
  1090. state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7);
  1091. retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM);
  1092. }
  1093. if (retval < 0) {
  1094. dst_pio_disable(state);
  1095. dprintk(verbose, DST_DEBUG, 1, "write not successful");
  1096. goto werr;
  1097. }
  1098. if ((dst_pio_disable(state)) < 0) {
  1099. dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
  1100. goto error;
  1101. }
  1102. if ((read_dst(state, &reply, GET_ACK) < 0)) {
  1103. dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
  1104. goto error;
  1105. }
  1106. if (reply != ACK) {
  1107. dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
  1108. goto error;
  1109. }
  1110. state->diseq_flags |= ATTEMPT_TUNE;
  1111. retval = dst_get_tuna(state);
  1112. werr:
  1113. mutex_unlock(&state->dst_mutex);
  1114. return retval;
  1115. error:
  1116. mutex_unlock(&state->dst_mutex);
  1117. return -EIO;
  1118. }
  1119. /*
  1120. * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00
  1121. * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00
  1122. * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00
  1123. * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00
  1124. * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00
  1125. * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
  1126. * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00
  1127. * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec
  1128. * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8
  1129. * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4
  1130. * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0
  1131. */
  1132. static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
  1133. {
  1134. struct dst_state *state = fe->demodulator_priv;
  1135. u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec };
  1136. if (state->dst_type != DST_TYPE_IS_SAT)
  1137. return 0;
  1138. if (cmd->msg_len == 0 || cmd->msg_len > 4)
  1139. return -EINVAL;
  1140. memcpy(&paket[3], cmd->msg, cmd->msg_len);
  1141. paket[7] = dst_check_sum(&paket[0], 7);
  1142. dst_command(state, paket, 8);
  1143. return 0;
  1144. }
  1145. static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
  1146. {
  1147. int need_cmd;
  1148. struct dst_state *state = fe->demodulator_priv;
  1149. state->voltage = voltage;
  1150. if (state->dst_type != DST_TYPE_IS_SAT)
  1151. return 0;
  1152. need_cmd = 0;
  1153. switch (voltage) {
  1154. case SEC_VOLTAGE_13:
  1155. case SEC_VOLTAGE_18:
  1156. if ((state->diseq_flags & HAS_POWER) == 0)
  1157. need_cmd = 1;
  1158. state->diseq_flags |= HAS_POWER;
  1159. state->tx_tuna[4] = 0x01;
  1160. break;
  1161. case SEC_VOLTAGE_OFF:
  1162. need_cmd = 1;
  1163. state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE);
  1164. state->tx_tuna[4] = 0x00;
  1165. break;
  1166. default:
  1167. return -EINVAL;
  1168. }
  1169. if (need_cmd)
  1170. dst_tone_power_cmd(state);
  1171. return 0;
  1172. }
  1173. static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
  1174. {
  1175. struct dst_state *state = fe->demodulator_priv;
  1176. state->tone = tone;
  1177. if (state->dst_type != DST_TYPE_IS_SAT)
  1178. return 0;
  1179. switch (tone) {
  1180. case SEC_TONE_OFF:
  1181. if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
  1182. state->tx_tuna[2] = 0x00;
  1183. else
  1184. state->tx_tuna[2] = 0xff;
  1185. break;
  1186. case SEC_TONE_ON:
  1187. state->tx_tuna[2] = 0x02;
  1188. break;
  1189. default:
  1190. return -EINVAL;
  1191. }
  1192. dst_tone_power_cmd(state);
  1193. return 0;
  1194. }
  1195. static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd)
  1196. {
  1197. struct dst_state *state = fe->demodulator_priv;
  1198. if (state->dst_type != DST_TYPE_IS_SAT)
  1199. return 0;
  1200. state->minicmd = minicmd;
  1201. switch (minicmd) {
  1202. case SEC_MINI_A:
  1203. state->tx_tuna[3] = 0x02;
  1204. break;
  1205. case SEC_MINI_B:
  1206. state->tx_tuna[3] = 0xff;
  1207. break;
  1208. }
  1209. dst_tone_power_cmd(state);
  1210. return 0;
  1211. }
  1212. static int dst_init(struct dvb_frontend *fe)
  1213. {
  1214. struct dst_state *state = fe->demodulator_priv;
  1215. static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 };
  1216. static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 };
  1217. static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
  1218. static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
  1219. static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
  1220. static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
  1221. static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 };
  1222. state->inversion = INVERSION_OFF;
  1223. state->voltage = SEC_VOLTAGE_13;
  1224. state->tone = SEC_TONE_OFF;
  1225. state->diseq_flags = 0;
  1226. state->k22 = 0x02;
  1227. state->bandwidth = BANDWIDTH_7_MHZ;
  1228. state->cur_jiff = jiffies;
  1229. if (state->dst_type == DST_TYPE_IS_SAT)
  1230. memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204));
  1231. else if (state->dst_type == DST_TYPE_IS_TERR)
  1232. memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204));
  1233. else if (state->dst_type == DST_TYPE_IS_CABLE)
  1234. memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204));
  1235. else if (state->dst_type == DST_TYPE_IS_ATSC)
  1236. memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner));
  1237. return 0;
  1238. }
  1239. static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status)
  1240. {
  1241. struct dst_state *state = fe->demodulator_priv;
  1242. *status = 0;
  1243. if (state->diseq_flags & HAS_LOCK) {
  1244. // dst_get_signal(state); // don't require(?) to ask MCU
  1245. if (state->decode_lock)
  1246. *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI;
  1247. }
  1248. return 0;
  1249. }
  1250. static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
  1251. {
  1252. struct dst_state *state = fe->demodulator_priv;
  1253. dst_get_signal(state);
  1254. *strength = state->decode_strength;
  1255. return 0;
  1256. }
  1257. static int dst_read_snr(struct dvb_frontend *fe, u16 *snr)
  1258. {
  1259. struct dst_state *state = fe->demodulator_priv;
  1260. dst_get_signal(state);
  1261. *snr = state->decode_snr;
  1262. return 0;
  1263. }
  1264. static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
  1265. {
  1266. struct dst_state *state = fe->demodulator_priv;
  1267. if (p != NULL) {
  1268. dst_set_freq(state, p->frequency);
  1269. dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
  1270. if (state->dst_type == DST_TYPE_IS_SAT) {
  1271. if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
  1272. dst_set_inversion(state, p->inversion);
  1273. dst_set_fec(state, p->u.qpsk.fec_inner);
  1274. dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
  1275. dst_set_polarization(state);
  1276. dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
  1277. } else if (state->dst_type == DST_TYPE_IS_TERR)
  1278. dst_set_bandwidth(state, p->u.ofdm.bandwidth);
  1279. else if (state->dst_type == DST_TYPE_IS_CABLE) {
  1280. dst_set_fec(state, p->u.qam.fec_inner);
  1281. dst_set_symbolrate(state, p->u.qam.symbol_rate);
  1282. dst_set_modulation(state, p->u.qam.modulation);
  1283. }
  1284. dst_write_tuna(fe);
  1285. }
  1286. return 0;
  1287. }
  1288. static int dst_tune_frontend(struct dvb_frontend* fe,
  1289. struct dvb_frontend_parameters* p,
  1290. unsigned int mode_flags,
  1291. int *delay,
  1292. fe_status_t *status)
  1293. {
  1294. struct dst_state *state = fe->demodulator_priv;
  1295. if (p != NULL) {
  1296. dst_set_freq(state, p->frequency);
  1297. dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency);
  1298. if (state->dst_type == DST_TYPE_IS_SAT) {
  1299. if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
  1300. dst_set_inversion(state, p->inversion);
  1301. dst_set_fec(state, p->u.qpsk.fec_inner);
  1302. dst_set_symbolrate(state, p->u.qpsk.symbol_rate);
  1303. dst_set_polarization(state);
  1304. dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate);
  1305. } else if (state->dst_type == DST_TYPE_IS_TERR)
  1306. dst_set_bandwidth(state, p->u.ofdm.bandwidth);
  1307. else if (state->dst_type == DST_TYPE_IS_CABLE) {
  1308. dst_set_fec(state, p->u.qam.fec_inner);
  1309. dst_set_symbolrate(state, p->u.qam.symbol_rate);
  1310. dst_set_modulation(state, p->u.qam.modulation);
  1311. }
  1312. dst_write_tuna(fe);
  1313. }
  1314. if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
  1315. dst_read_status(fe, status);
  1316. *delay = HZ/10;
  1317. return 0;
  1318. }
  1319. static int dst_get_tuning_algo(struct dvb_frontend *fe)
  1320. {
  1321. return dst_algo;
  1322. }
  1323. static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
  1324. {
  1325. struct dst_state *state = fe->demodulator_priv;
  1326. p->frequency = state->decode_freq;
  1327. if (state->dst_type == DST_TYPE_IS_SAT) {
  1328. if (state->type_flags & DST_TYPE_HAS_OBS_REGS)
  1329. p->inversion = state->inversion;
  1330. p->u.qpsk.symbol_rate = state->symbol_rate;
  1331. p->u.qpsk.fec_inner = dst_get_fec(state);
  1332. } else if (state->dst_type == DST_TYPE_IS_TERR) {
  1333. p->u.ofdm.bandwidth = state->bandwidth;
  1334. } else if (state->dst_type == DST_TYPE_IS_CABLE) {
  1335. p->u.qam.symbol_rate = state->symbol_rate;
  1336. p->u.qam.fec_inner = dst_get_fec(state);
  1337. p->u.qam.modulation = dst_get_modulation(state);
  1338. }
  1339. return 0;
  1340. }
  1341. static void dst_release(struct dvb_frontend *fe)
  1342. {
  1343. struct dst_state *state = fe->demodulator_priv;
  1344. kfree(state);
  1345. }
  1346. static struct dvb_frontend_ops dst_dvbt_ops;
  1347. static struct dvb_frontend_ops dst_dvbs_ops;
  1348. static struct dvb_frontend_ops dst_dvbc_ops;
  1349. static struct dvb_frontend_ops dst_atsc_ops;
  1350. struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter)
  1351. {
  1352. /* check if the ASIC is there */
  1353. if (dst_probe(state) < 0) {
  1354. kfree(state);
  1355. return NULL;
  1356. }
  1357. /* determine settings based on type */
  1358. /* create dvb_frontend */
  1359. switch (state->dst_type) {
  1360. case DST_TYPE_IS_TERR:
  1361. memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops));
  1362. break;
  1363. case DST_TYPE_IS_CABLE:
  1364. memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops));
  1365. break;
  1366. case DST_TYPE_IS_SAT:
  1367. memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops));
  1368. break;
  1369. case DST_TYPE_IS_ATSC:
  1370. memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops));
  1371. break;
  1372. default:
  1373. dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
  1374. kfree(state);
  1375. return NULL;
  1376. }
  1377. state->frontend.demodulator_priv = state;
  1378. return state; /* Manu (DST is a card not a frontend) */
  1379. }
  1380. EXPORT_SYMBOL(dst_attach);
  1381. static struct dvb_frontend_ops dst_dvbt_ops = {
  1382. .info = {
  1383. .name = "DST DVB-T",
  1384. .type = FE_OFDM,
  1385. .frequency_min = 137000000,
  1386. .frequency_max = 858000000,
  1387. .frequency_stepsize = 166667,
  1388. .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
  1389. },
  1390. .release = dst_release,
  1391. .init = dst_init,
  1392. .tune = dst_tune_frontend,
  1393. .set_frontend = dst_set_frontend,
  1394. .get_frontend = dst_get_frontend,
  1395. .get_frontend_algo = dst_get_tuning_algo,
  1396. .read_status = dst_read_status,
  1397. .read_signal_strength = dst_read_signal_strength,
  1398. .read_snr = dst_read_snr,
  1399. };
  1400. static struct dvb_frontend_ops dst_dvbs_ops = {
  1401. .info = {
  1402. .name = "DST DVB-S",
  1403. .type = FE_QPSK,
  1404. .frequency_min = 950000,
  1405. .frequency_max = 2150000,
  1406. .frequency_stepsize = 1000, /* kHz for QPSK frontends */
  1407. .frequency_tolerance = 29500,
  1408. .symbol_rate_min = 1000000,
  1409. .symbol_rate_max = 45000000,
  1410. /* . symbol_rate_tolerance = ???,*/
  1411. .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK
  1412. },
  1413. .release = dst_release,
  1414. .init = dst_init,
  1415. .tune = dst_tune_frontend,
  1416. .set_frontend = dst_set_frontend,
  1417. .get_frontend = dst_get_frontend,
  1418. .get_frontend_algo = dst_get_tuning_algo,
  1419. .read_status = dst_read_status,
  1420. .read_signal_strength = dst_read_signal_strength,
  1421. .read_snr = dst_read_snr,
  1422. .diseqc_send_burst = dst_send_burst,
  1423. .diseqc_send_master_cmd = dst_set_diseqc,
  1424. .set_voltage = dst_set_voltage,
  1425. .set_tone = dst_set_tone,
  1426. };
  1427. static struct dvb_frontend_ops dst_dvbc_ops = {
  1428. .info = {
  1429. .name = "DST DVB-C",
  1430. .type = FE_QAM,
  1431. .frequency_stepsize = 62500,
  1432. .frequency_min = 51000000,
  1433. .frequency_max = 858000000,
  1434. .symbol_rate_min = 1000000,
  1435. .symbol_rate_max = 45000000,
  1436. /* . symbol_rate_tolerance = ???,*/
  1437. .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO
  1438. },
  1439. .release = dst_release,
  1440. .init = dst_init,
  1441. .tune = dst_tune_frontend,
  1442. .set_frontend = dst_set_frontend,
  1443. .get_frontend = dst_get_frontend,
  1444. .get_frontend_algo = dst_get_tuning_algo,
  1445. .read_status = dst_read_status,
  1446. .read_signal_strength = dst_read_signal_strength,
  1447. .read_snr = dst_read_snr,
  1448. };
  1449. static struct dvb_frontend_ops dst_atsc_ops = {
  1450. .info = {
  1451. .name = "DST ATSC",
  1452. .type = FE_ATSC,
  1453. .frequency_stepsize = 62500,
  1454. .frequency_min = 510000000,
  1455. .frequency_max = 858000000,
  1456. .symbol_rate_min = 1000000,
  1457. .symbol_rate_max = 45000000,
  1458. .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
  1459. },
  1460. .release = dst_release,
  1461. .init = dst_init,
  1462. .tune = dst_tune_frontend,
  1463. .set_frontend = dst_set_frontend,
  1464. .get_frontend = dst_get_frontend,
  1465. .get_frontend_algo = dst_get_tuning_algo,
  1466. .read_status = dst_read_status,
  1467. .read_signal_strength = dst_read_signal_strength,
  1468. .read_snr = dst_read_snr,
  1469. };
  1470. MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver");
  1471. MODULE_AUTHOR("Jamie Honan, Manu Abraham");
  1472. MODULE_LICENSE("GPL");