avc_api.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /*
  2. * FireSAT AVC driver
  3. *
  4. * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
  5. * Copyright (c) 2008 Ben Backx <ben@bbackx.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. */
  12. #include "firesat.h"
  13. #include <ieee1394_transactions.h>
  14. #include <nodemgr.h>
  15. #include <asm/byteorder.h>
  16. #include <linux/delay.h>
  17. #include "avc_api.h"
  18. #include "firesat-rc.h"
  19. #define RESPONSE_REGISTER 0xFFFFF0000D00ULL
  20. #define COMMAND_REGISTER 0xFFFFF0000B00ULL
  21. #define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
  22. static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
  23. /* Frees an allocated packet */
  24. static void avc_free_packet(struct hpsb_packet *packet)
  25. {
  26. hpsb_free_tlabel(packet);
  27. hpsb_free_packet(packet);
  28. }
  29. /*
  30. * Goofy routine that basically does a down_timeout function.
  31. * Stolen from sbp2.c
  32. */
  33. static int avc_down_timeout(atomic_t *done, int timeout)
  34. {
  35. int i;
  36. for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
  37. set_current_state(TASK_INTERRUPTIBLE);
  38. if (schedule_timeout(HZ/10)) /* 100ms */
  39. return(1);
  40. }
  41. return ((i > 0) ? 0:1);
  42. }
  43. static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
  44. struct hpsb_packet *packet;
  45. struct node_entry *ne;
  46. ne = firesat->nodeentry;
  47. if(!ne) {
  48. printk("%s: lost node!\n",__func__);
  49. return -EIO;
  50. }
  51. /* need all input data */
  52. if(!firesat || !ne || !CmdFrm)
  53. return -EINVAL;
  54. // printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode);
  55. // for(k=0;k<CmdFrm->length;k++)
  56. // printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]);
  57. packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER,
  58. (quadlet_t*)CmdFrm, CmdFrm->length);
  59. hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet,
  60. packet);
  61. hpsb_node_fill_packet(ne, packet);
  62. if(RspFrm)
  63. atomic_set(&firesat->avc_reply_received, 0);
  64. if (hpsb_send_packet(packet) < 0) {
  65. avc_free_packet(packet);
  66. atomic_set(&firesat->avc_reply_received, 1);
  67. return -EIO;
  68. }
  69. if(RspFrm) {
  70. if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) {
  71. printk("%s: timeout waiting for avc response\n",__func__);
  72. atomic_set(&firesat->avc_reply_received, 1);
  73. return -ETIMEDOUT;
  74. }
  75. memcpy(RspFrm,firesat->respfrm,firesat->resp_length);
  76. }
  77. return 0;
  78. }
  79. int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
  80. int ret;
  81. if(down_interruptible(&firesat->avc_sem))
  82. return -EINTR;
  83. ret = __AVCWrite(firesat, CmdFrm, RspFrm);
  84. up(&firesat->avc_sem);
  85. return ret;
  86. }
  87. static void do_schedule_remotecontrol(unsigned long ignored);
  88. DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0);
  89. static void do_schedule_remotecontrol(unsigned long ignored) {
  90. struct firesat *firesat;
  91. unsigned long flags;
  92. spin_lock_irqsave(&firesat_list_lock, flags);
  93. list_for_each_entry(firesat,&firesat_list,list) {
  94. if(atomic_read(&firesat->reschedule_remotecontrol) == 1) {
  95. if(down_trylock(&firesat->avc_sem))
  96. tasklet_schedule(&schedule_remotecontrol);
  97. else {
  98. if(__AVCRegisterRemoteControl(firesat, 1) == 0)
  99. atomic_set(&firesat->reschedule_remotecontrol, 0);
  100. else
  101. tasklet_schedule(&schedule_remotecontrol);
  102. up(&firesat->avc_sem);
  103. }
  104. }
  105. }
  106. spin_unlock_irqrestore(&firesat_list_lock, flags);
  107. }
  108. int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
  109. // printk(KERN_INFO "%s\n",__func__);
  110. // remote control handling
  111. AVCRspFrm *RspFrm = (AVCRspFrm*)data;
  112. if(/*RspFrm->length >= 8 && ###*/
  113. ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 &&
  114. RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 &&
  115. RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2)) &&
  116. RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
  117. if(RspFrm->resp == CHANGED) {
  118. // printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]);
  119. firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5]));
  120. // schedule
  121. atomic_set(&firesat->reschedule_remotecontrol, 1);
  122. tasklet_schedule(&schedule_remotecontrol);
  123. } else if(RspFrm->resp != INTERIM)
  124. printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp);
  125. return 0;
  126. }
  127. if(atomic_read(&firesat->avc_reply_received) == 1) {
  128. printk("%s: received out-of-order AVC response, ignored\n",__func__);
  129. return -EINVAL;
  130. }
  131. // AVCRspFrm *resp=(AVCRspFrm *)data;
  132. // int k;
  133. /*
  134. printk(KERN_INFO "resp=0x%x\n",resp->resp);
  135. printk(KERN_INFO "cts=0x%x\n",resp->cts);
  136. printk(KERN_INFO "suid=0x%x\n",resp->suid);
  137. printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
  138. printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
  139. printk(KERN_INFO "length=%d\n",resp->length);
  140. */
  141. // for(k=0;k<2;k++)
  142. // printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
  143. memcpy(firesat->respfrm,data,length);
  144. firesat->resp_length=length;
  145. atomic_set(&firesat->avc_reply_received, 1);
  146. return 0;
  147. }
  148. // tuning command for setting the relative LNB frequency (not supported by the AVC standard)
  149. static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) {
  150. memset(CmdFrm, 0, sizeof(AVCCmdFrm));
  151. CmdFrm->cts = AVC;
  152. CmdFrm->ctype = CONTROL;
  153. CmdFrm->sutyp = 0x5;
  154. CmdFrm->suid = firesat->subunit;
  155. CmdFrm->opcode = VENDOR;
  156. CmdFrm->operand[0]=SFE_VENDOR_DE_COMPANYID_0;
  157. CmdFrm->operand[1]=SFE_VENDOR_DE_COMPANYID_1;
  158. CmdFrm->operand[2]=SFE_VENDOR_DE_COMPANYID_2;
  159. CmdFrm->operand[3]=SFE_VENDOR_OPCODE_TUNE_QPSK;
  160. printk(KERN_INFO "%s: tuning to frequency %u\n",__func__,params->frequency);
  161. CmdFrm->operand[4] = (params->frequency >> 24) & 0xFF;
  162. CmdFrm->operand[5] = (params->frequency >> 16) & 0xFF;
  163. CmdFrm->operand[6] = (params->frequency >> 8) & 0xFF;
  164. CmdFrm->operand[7] = params->frequency & 0xFF;
  165. printk(KERN_INFO "%s: symbol rate = %uBd\n",__func__,params->u.qpsk.symbol_rate);
  166. CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate/1000) >> 8) & 0xFF;
  167. CmdFrm->operand[9] = (params->u.qpsk.symbol_rate/1000) & 0xFF;
  168. switch(params->u.qpsk.fec_inner) {
  169. case FEC_1_2:
  170. CmdFrm->operand[10] = 0x1;
  171. break;
  172. case FEC_2_3:
  173. CmdFrm->operand[10] = 0x2;
  174. break;
  175. case FEC_3_4:
  176. CmdFrm->operand[10] = 0x3;
  177. break;
  178. case FEC_5_6:
  179. CmdFrm->operand[10] = 0x4;
  180. break;
  181. case FEC_7_8:
  182. CmdFrm->operand[10] = 0x5;
  183. break;
  184. case FEC_4_5:
  185. case FEC_8_9:
  186. case FEC_AUTO:
  187. default:
  188. CmdFrm->operand[10] = 0x0;
  189. }
  190. if(firesat->voltage == 0xff)
  191. CmdFrm->operand[11] = 0xff;
  192. else
  193. CmdFrm->operand[11] = (firesat->voltage==SEC_VOLTAGE_18)?0:1; // polarisation
  194. if(firesat->tone == 0xff)
  195. CmdFrm->operand[12] = 0xff;
  196. else
  197. CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band
  198. CmdFrm->length = 16;
  199. }
  200. int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) {
  201. AVCCmdFrm CmdFrm;
  202. AVCRspFrm RspFrm;
  203. M_VALID_FLAGS flags;
  204. int k;
  205. // printk(KERN_INFO "%s\n", __func__);
  206. if (firesat->type == FireSAT_DVB_S || firesat->type == FireSAT_DVB_S2)
  207. AVCTuner_tuneQPSK(firesat, params, &CmdFrm);
  208. else {
  209. if(firesat->type == FireSAT_DVB_T) {
  210. flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO);
  211. flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO);
  212. flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO);
  213. flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO);
  214. flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO);
  215. flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO);
  216. flags.Bits_T.CenterFrequency = 1;
  217. flags.Bits_T.reserved1 = 0;
  218. flags.Bits_T.reserved2 = 0;
  219. flags.Bits_T.OtherFrequencyFlag = 0;
  220. flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
  221. flags.Bits_T.NetworkId = 0;
  222. } else {
  223. flags.Bits.Modulation = 0;
  224. if(firesat->type == FireSAT_DVB_S) {
  225. flags.Bits.FEC_inner = 1;
  226. } else if(firesat->type == FireSAT_DVB_C) {
  227. flags.Bits.FEC_inner = 0;
  228. }
  229. flags.Bits.FEC_outer = 0;
  230. flags.Bits.Symbol_Rate = 1;
  231. flags.Bits.Frequency = 1;
  232. flags.Bits.Orbital_Pos = 0;
  233. if(firesat->type == FireSAT_DVB_S) {
  234. flags.Bits.Polarisation = 1;
  235. } else if(firesat->type == FireSAT_DVB_C) {
  236. flags.Bits.Polarisation = 0;
  237. }
  238. flags.Bits.reserved_fields = 0;
  239. flags.Bits.reserved1 = 0;
  240. flags.Bits.Network_ID = 0;
  241. }
  242. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  243. CmdFrm.cts = AVC;
  244. CmdFrm.ctype = CONTROL;
  245. CmdFrm.sutyp = 0x5;
  246. CmdFrm.suid = firesat->subunit;
  247. CmdFrm.opcode = DSD;
  248. CmdFrm.operand[0] = 0; // source plug
  249. CmdFrm.operand[1] = 0xD2; // subfunction replace
  250. CmdFrm.operand[2] = 0x20; // system id = DVB
  251. CmdFrm.operand[3] = 0x00; // antenna number
  252. CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
  253. CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
  254. CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
  255. if(firesat->type == FireSAT_DVB_T) {
  256. CmdFrm.operand[7] = 0x0;
  257. CmdFrm.operand[8] = (params->frequency/10) >> 24;
  258. CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF;
  259. CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF;
  260. CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
  261. switch(params->u.ofdm.bandwidth) {
  262. case BANDWIDTH_7_MHZ:
  263. CmdFrm.operand[12] = 0x20;
  264. break;
  265. case BANDWIDTH_8_MHZ:
  266. case BANDWIDTH_6_MHZ: // not defined by AVC spec
  267. case BANDWIDTH_AUTO:
  268. default:
  269. CmdFrm.operand[12] = 0x00;
  270. }
  271. switch(params->u.ofdm.constellation) {
  272. case QAM_16:
  273. CmdFrm.operand[13] = 1 << 6;
  274. break;
  275. case QAM_64:
  276. CmdFrm.operand[13] = 2 << 6;
  277. break;
  278. case QPSK:
  279. default:
  280. CmdFrm.operand[13] = 0x00;
  281. }
  282. switch(params->u.ofdm.hierarchy_information) {
  283. case HIERARCHY_1:
  284. CmdFrm.operand[13] |= 1 << 3;
  285. break;
  286. case HIERARCHY_2:
  287. CmdFrm.operand[13] |= 2 << 3;
  288. break;
  289. case HIERARCHY_4:
  290. CmdFrm.operand[13] |= 3 << 3;
  291. break;
  292. case HIERARCHY_AUTO:
  293. case HIERARCHY_NONE:
  294. default:
  295. break;
  296. }
  297. switch(params->u.ofdm.code_rate_HP) {
  298. case FEC_2_3:
  299. CmdFrm.operand[13] |= 1;
  300. break;
  301. case FEC_3_4:
  302. CmdFrm.operand[13] |= 2;
  303. break;
  304. case FEC_5_6:
  305. CmdFrm.operand[13] |= 3;
  306. break;
  307. case FEC_7_8:
  308. CmdFrm.operand[13] |= 4;
  309. break;
  310. case FEC_1_2:
  311. default:
  312. break;
  313. }
  314. switch(params->u.ofdm.code_rate_LP) {
  315. case FEC_2_3:
  316. CmdFrm.operand[14] = 1 << 5;
  317. break;
  318. case FEC_3_4:
  319. CmdFrm.operand[14] = 2 << 5;
  320. break;
  321. case FEC_5_6:
  322. CmdFrm.operand[14] = 3 << 5;
  323. break;
  324. case FEC_7_8:
  325. CmdFrm.operand[14] = 4 << 5;
  326. break;
  327. case FEC_1_2:
  328. default:
  329. CmdFrm.operand[14] = 0x00;
  330. break;
  331. }
  332. switch(params->u.ofdm.guard_interval) {
  333. case GUARD_INTERVAL_1_16:
  334. CmdFrm.operand[14] |= 1 << 3;
  335. break;
  336. case GUARD_INTERVAL_1_8:
  337. CmdFrm.operand[14] |= 2 << 3;
  338. break;
  339. case GUARD_INTERVAL_1_4:
  340. CmdFrm.operand[14] |= 3 << 3;
  341. break;
  342. case GUARD_INTERVAL_1_32:
  343. case GUARD_INTERVAL_AUTO:
  344. default:
  345. break;
  346. }
  347. switch(params->u.ofdm.transmission_mode) {
  348. case TRANSMISSION_MODE_8K:
  349. CmdFrm.operand[14] |= 1 << 1;
  350. break;
  351. case TRANSMISSION_MODE_2K:
  352. case TRANSMISSION_MODE_AUTO:
  353. default:
  354. break;
  355. }
  356. CmdFrm.operand[15] = 0x00; // network_ID[0]
  357. CmdFrm.operand[16] = 0x00; // network_ID[1]
  358. CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
  359. CmdFrm.length = 20;
  360. } else {
  361. CmdFrm.operand[7] = 0x00;
  362. CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */
  363. CmdFrm.operand[9] = 0x00;
  364. CmdFrm.operand[10] = 0x00;
  365. if(firesat->type == FireSAT_DVB_S) {
  366. /* ### relative frequency -> absolute frequency */
  367. CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
  368. CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF;
  369. CmdFrm.operand[13] = (params->frequency/4) & 0xFF;
  370. } else if(firesat->type == FireSAT_DVB_C) {
  371. CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
  372. CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF;
  373. CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
  374. }
  375. CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
  376. CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
  377. CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
  378. CmdFrm.operand[17] = 0x00;
  379. switch(params->u.qpsk.fec_inner) {
  380. case FEC_1_2:
  381. CmdFrm.operand[18] = 0x1;
  382. break;
  383. case FEC_2_3:
  384. CmdFrm.operand[18] = 0x2;
  385. break;
  386. case FEC_3_4:
  387. CmdFrm.operand[18] = 0x3;
  388. break;
  389. case FEC_5_6:
  390. CmdFrm.operand[18] = 0x4;
  391. break;
  392. case FEC_7_8:
  393. CmdFrm.operand[18] = 0x5;
  394. break;
  395. case FEC_4_5:
  396. case FEC_8_9:
  397. case FEC_AUTO:
  398. default:
  399. CmdFrm.operand[18] = 0x0;
  400. }
  401. if(firesat->type == FireSAT_DVB_S) {
  402. CmdFrm.operand[19] = 0x08; // modulation
  403. } else if(firesat->type == FireSAT_DVB_C) {
  404. switch(params->u.qam.modulation) {
  405. case QAM_16:
  406. CmdFrm.operand[19] = 0x08; // modulation
  407. break;
  408. case QAM_32:
  409. CmdFrm.operand[19] = 0x10; // modulation
  410. break;
  411. case QAM_64:
  412. CmdFrm.operand[19] = 0x18; // modulation
  413. break;
  414. case QAM_128:
  415. CmdFrm.operand[19] = 0x20; // modulation
  416. break;
  417. case QAM_256:
  418. CmdFrm.operand[19] = 0x28; // modulation
  419. break;
  420. case QAM_AUTO:
  421. default:
  422. CmdFrm.operand[19] = 0x00; // modulation
  423. }
  424. }
  425. CmdFrm.operand[20] = 0x00;
  426. CmdFrm.operand[21] = 0x00;
  427. CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
  428. CmdFrm.length=28;
  429. }
  430. } // AVCTuner_DSD_direct
  431. if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
  432. return k;
  433. // msleep(250);
  434. mdelay(500);
  435. if(status)
  436. *status=RspFrm.operand[2];
  437. return 0;
  438. }
  439. int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
  440. AVCCmdFrm CmdFrm;
  441. AVCRspFrm RspFrm;
  442. int pos,k;
  443. printk(KERN_INFO "%s\n", __func__);
  444. if(pidc > 16 && pidc != 0xFF)
  445. return -EINVAL;
  446. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  447. CmdFrm.cts = AVC;
  448. CmdFrm.ctype = CONTROL;
  449. CmdFrm.sutyp = 0x5;
  450. CmdFrm.suid = firesat->subunit;
  451. CmdFrm.opcode = DSD;
  452. CmdFrm.operand[0] = 0; // source plug
  453. CmdFrm.operand[1] = 0xD2; // subfunction replace
  454. CmdFrm.operand[2] = 0x20; // system id = DVB
  455. CmdFrm.operand[3] = 0x00; // antenna number
  456. CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length
  457. CmdFrm.operand[5] = 0x00; // valid_flags [0]
  458. CmdFrm.operand[6] = 0x00; // valid_flags [1]
  459. if(firesat->type == FireSAT_DVB_T) {
  460. /* CmdFrm.operand[7] = 0x00;
  461. CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24;
  462. CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF;
  463. CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF;
  464. CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF;
  465. CmdFrm.operand[12] = 0x00;
  466. CmdFrm.operand[13] = 0x00;
  467. CmdFrm.operand[14] = 0x00;
  468. CmdFrm.operand[15] = 0x00; // network_ID[0]
  469. CmdFrm.operand[16] = 0x00; // network_ID[1]
  470. */ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs
  471. pos=18;
  472. } else {
  473. /* CmdFrm.operand[7] = 0x00;
  474. CmdFrm.operand[8] = 0x00;
  475. CmdFrm.operand[9] = 0x00;
  476. CmdFrm.operand[10] = 0x00;
  477. CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
  478. CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF;
  479. CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF;
  480. CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
  481. CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
  482. CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
  483. CmdFrm.operand[17] = 0x00;
  484. CmdFrm.operand[18] = 0x00;
  485. CmdFrm.operand[19] = 0x00; // modulation
  486. CmdFrm.operand[20] = 0x00;
  487. CmdFrm.operand[21] = 0x00;*/
  488. CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs
  489. pos=23;
  490. }
  491. if(pidc != 0xFF)
  492. for(k=0;k<pidc;k++) {
  493. CmdFrm.operand[pos++] = 0x13; // flowfunction relay
  494. CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
  495. CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F;
  496. CmdFrm.operand[pos++] = pid[k] & 0xFF;
  497. CmdFrm.operand[pos++] = 0x00; // tableID
  498. CmdFrm.operand[pos++] = 0x00; // filter_length
  499. }
  500. CmdFrm.length = pos+3;
  501. if((pos+3)%4)
  502. CmdFrm.length += 4 - ((pos+3)%4);
  503. if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
  504. return k;
  505. mdelay(250);
  506. return 0;
  507. }
  508. int AVCTuner_GetTS(struct firesat *firesat){
  509. AVCCmdFrm CmdFrm;
  510. AVCRspFrm RspFrm;
  511. int k;
  512. printk(KERN_INFO "%s\n", __func__);
  513. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  514. CmdFrm.cts = AVC;
  515. CmdFrm.ctype = CONTROL;
  516. CmdFrm.sutyp = 0x5;
  517. CmdFrm.suid = firesat->subunit;
  518. CmdFrm.opcode = DSIT;
  519. CmdFrm.operand[0] = 0; // source plug
  520. CmdFrm.operand[1] = 0xD2; // subfunction replace
  521. CmdFrm.operand[2] = 0xFF; //status
  522. CmdFrm.operand[3] = 0x20; // system id = DVB
  523. CmdFrm.operand[4] = 0x00; // antenna number
  524. CmdFrm.operand[5] = 0x0; // system_specific_search_flags
  525. CmdFrm.operand[6] = 0x11; // system_specific_multiplex selection_length
  526. CmdFrm.operand[7] = 0x00; // valid_flags [0]
  527. CmdFrm.operand[8] = 0x00; // valid_flags [1]
  528. CmdFrm.operand[24] = 0x00; // nr_of_dsit_sel_specs (always 0)
  529. CmdFrm.length = 28;
  530. if((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) return k;
  531. mdelay(250);
  532. return 0;
  533. }
  534. int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) {
  535. AVCCmdFrm CmdFrm;
  536. AVCRspFrm RspFrm;
  537. memset(&CmdFrm,0,sizeof(AVCCmdFrm));
  538. CmdFrm.cts = AVC;
  539. CmdFrm.ctype = CONTROL;
  540. CmdFrm.sutyp = 0x5; // tuner
  541. CmdFrm.suid = firesat->subunit;
  542. CmdFrm.opcode = READ_DESCRIPTOR;
  543. CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER;
  544. CmdFrm.operand[1]=0xff;
  545. CmdFrm.operand[2]=0x00;
  546. CmdFrm.operand[3]=0x00; // length highbyte
  547. CmdFrm.operand[4]=0x08; // length lowbyte
  548. CmdFrm.operand[5]=0x00; // offset highbyte
  549. CmdFrm.operand[6]=0x0d; // offset lowbyte
  550. CmdFrm.length=12;
  551. if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0)
  552. return -EIO;
  553. if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
  554. printk("%s: AVCWrite returned error code %d\n",__func__,RspFrm.resp);
  555. return -EINVAL;
  556. }
  557. if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) {
  558. printk("%s: Invalid response length\n",__func__);
  559. return -EINVAL;
  560. }
  561. if(systemId)
  562. *systemId = RspFrm.operand[7];
  563. if(has_ci)
  564. *has_ci = (RspFrm.operand[14] >> 4) & 0x1;
  565. return 0;
  566. }
  567. int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) {
  568. AVCCmdFrm CmdFrm;
  569. AVCRspFrm RspFrm;
  570. int length;
  571. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  572. CmdFrm.cts=AVC;
  573. CmdFrm.ctype=CONTROL;
  574. CmdFrm.sutyp=0x05; // tuner
  575. CmdFrm.suid=firesat->subunit;
  576. CmdFrm.opcode=READ_DESCRIPTOR;
  577. CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
  578. CmdFrm.operand[1]=0xff;
  579. CmdFrm.operand[2]=0x00;
  580. CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8;
  581. CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF;
  582. CmdFrm.operand[5]=0x00;
  583. CmdFrm.operand[6]=0x03;
  584. CmdFrm.length=12;
  585. //Absenden des AVC request und warten auf response
  586. if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
  587. return -EIO;
  588. if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
  589. printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp);
  590. return -EINVAL;
  591. }
  592. length = (RspFrm.operand[3] << 8) + RspFrm.operand[4];
  593. if(length == sizeof(ANTENNA_INPUT_INFO))
  594. {
  595. memcpy(antenna_input_info,&RspFrm.operand[7],length);
  596. return 0;
  597. }
  598. printk("%s: invalid info returned from AVC\n",__func__);
  599. return -EINVAL;
  600. }
  601. int AVCLNBControl(struct firesat *firesat, char voltage, char burst,
  602. char conttone, char nrdiseq,
  603. struct dvb_diseqc_master_cmd *diseqcmd)
  604. {
  605. AVCCmdFrm CmdFrm;
  606. AVCRspFrm RspFrm;
  607. int i,j;
  608. printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",__func__,voltage,burst,conttone);
  609. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  610. CmdFrm.cts=AVC;
  611. CmdFrm.ctype=CONTROL;
  612. CmdFrm.sutyp=0x05;
  613. CmdFrm.suid=firesat->subunit;
  614. CmdFrm.opcode=VENDOR;
  615. CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
  616. CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
  617. CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
  618. CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL;
  619. CmdFrm.operand[4]=voltage;
  620. CmdFrm.operand[5]=nrdiseq;
  621. i=6;
  622. for(j=0;j<nrdiseq;j++) {
  623. int k;
  624. printk(KERN_INFO "%s: diseq %d len %x\n",__func__,j,diseqcmd[j].msg_len);
  625. CmdFrm.operand[i++]=diseqcmd[j].msg_len;
  626. for(k=0;k<diseqcmd[j].msg_len;k++) {
  627. printk(KERN_INFO "%s: diseq %d msg[%d] = %x\n",__func__,j,k,diseqcmd[j].msg[k]);
  628. CmdFrm.operand[i++]=diseqcmd[j].msg[k];
  629. }
  630. }
  631. CmdFrm.operand[i++]=burst;
  632. CmdFrm.operand[i++]=conttone;
  633. CmdFrm.length=i+3;
  634. if((i+3)%4)
  635. CmdFrm.length += 4 - ((i+3)%4);
  636. /* for(j=0;j<CmdFrm.length;j++)
  637. printk(KERN_INFO "%s: CmdFrm.operand[%d]=0x%x\n",__func__,j,CmdFrm.operand[j]);
  638. printk(KERN_INFO "%s: cmdfrm.length = %u\n",__func__,CmdFrm.length);
  639. */
  640. if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
  641. return -EIO;
  642. if(RspFrm.resp != ACCEPTED) {
  643. printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp);
  644. return -EINVAL;
  645. }
  646. return 0;
  647. }
  648. int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount)
  649. {
  650. AVCCmdFrm CmdFrm;
  651. AVCRspFrm RspFrm;
  652. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  653. CmdFrm.cts = AVC;
  654. CmdFrm.ctype = STATUS;
  655. CmdFrm.sutyp = 0x1f;
  656. CmdFrm.suid = 0x7;
  657. CmdFrm.opcode = SUBUNIT_Info;
  658. CmdFrm.operand[0] = 0x07;
  659. CmdFrm.operand[1] = 0xff;
  660. CmdFrm.operand[2] = 0xff;
  661. CmdFrm.operand[3] = 0xff;
  662. CmdFrm.operand[4] = 0xff;
  663. CmdFrm.length = 8;
  664. if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
  665. return -EIO;
  666. if(RspFrm.resp != STABLE) {
  667. printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp);
  668. return -EINVAL;
  669. }
  670. if(subunitcount)
  671. *subunitcount = (RspFrm.operand[1] & 0x7) + 1;
  672. return 0;
  673. }
  674. static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal)
  675. {
  676. AVCCmdFrm CmdFrm;
  677. // printk(KERN_INFO "%s\n",__func__);
  678. memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
  679. CmdFrm.cts = AVC;
  680. CmdFrm.ctype = NOTIFY;
  681. CmdFrm.sutyp = 0x1f;
  682. CmdFrm.suid = 0x7;
  683. CmdFrm.opcode = VENDOR;
  684. CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
  685. CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
  686. CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
  687. CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
  688. CmdFrm.length = 8;
  689. if(internal) {
  690. if(__AVCWrite(firesat,&CmdFrm,NULL) < 0)
  691. return -EIO;
  692. } else
  693. if(AVCWrite(firesat,&CmdFrm,NULL) < 0)
  694. return -EIO;
  695. return 0;
  696. }
  697. int AVCRegisterRemoteControl(struct firesat*firesat)
  698. {
  699. return __AVCRegisterRemoteControl(firesat, 0);
  700. }