i34.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:21k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /* -*- linux-c -*- --------------------------------------------------------- *  
  2.  * This module is an interface to the ZORAN zr367x0 dvd decoder chip.
  3.  *
  4.  * Copyright (C) 1999 David Barth <dbarth@besancon.net>
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License
  8.  * as published by the Free Software Foundation; either version 2
  9.  * of the License, or (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  *
  20.  */
  21. #ifndef __KERNEL__
  22. #define __KERNEL__
  23. #endif
  24. #ifndef MODULE
  25. #define MODULE
  26. #endif
  27. #include <linux/module.h>
  28. #include <linux/delay.h>
  29. #include <linux/errno.h>
  30. #include <linux/kernel.h>
  31. #include <linux/mm.h>
  32. #include <linux/poll.h>
  33. #include <asm/io.h>
  34. #include <linux/sched.h>
  35. #include <linux/videodev2.h>
  36. #include <linux/proc_fs.h>
  37. #include "mgavideo.h"
  38. #include "i34.h"
  39. #define dprintk     if (debug) printk
  40. static int debug = 1;    /* insmod parameter */
  41. static int reset = 1; /* insmod parameter */
  42. #if LINUX_VERSION_CODE >= 0x020100
  43. MODULE_PARM(debug,"i");
  44. MODULE_PARM(reset,"i");
  45. #endif
  46. static struct mga_dev *host;
  47. #define I34_STATE_NO_UCODE 0 /* indicates that no microcode has been downloaded so far */
  48. static int state = 0; /* internal state */
  49. static u8 ucode_buffer[16384]; /* buffer holding ucode to download into the chipset */
  50. static u16 ucode_length = 0; /* length of the ucode inside the buffer */
  51. static u16 ucode_wmark = 0; /* number of bytes written to the chipset
  52.    needed so that we can zero-pad ucode when downloading
  53.    a new ucode */
  54. /****************************************************************************
  55.  * DVD/MPEG Add-on board     *
  56.  ****************************************************************************/
  57. /* main registers */
  58. #define ZR_PARAM_ADDR 0x0
  59. #define ZR_PARAM_DATA 0x1
  60. #define ZR_ISR 0x2
  61. #define ZR_STATUS0 0x3
  62. #define ZR_HOSTCMD 0x3
  63. #define ZR_STATUS1 0x4
  64. #define ZR_STATUS2 0x5
  65. #define ZR_DEVICE_ID 0x7
  66. #define ZR_ADP_DATA 0x8
  67. #define ZR_ADP_STATUS 0x8
  68. #define ZR_SYS_CLOCK 0x9
  69. #define ZR_NAV_DATA 0xA
  70. #define ZR_RESERVED1 0xB
  71. #define ZR_SUBPICBUF 0xC
  72. #define ZR_VIDEOBUF 0xD
  73. #define ZR_AUDIOBUF 0xE
  74. #define ZR_RESERVED2 0xF
  75. /* indirect registers */
  76. #define ZR_SYSCONFIG 0x00
  77. #define ZR_VIDCONFIG 0x01
  78. #define ZR_SDCONFIG 0x02
  79. #define ZR_DVPGEN1 0x03
  80. #define ZR_DVPGEN2 0x04
  81. #define ZR_DVPGEN3 0x05
  82. #define ZR_COLORV 0x08
  83. #define ZR_COLORY 0x09
  84. #define ZR_COLORU 0x0A
  85. #define ZR_VIDOUT 0x10
  86. #define ZR_HTOTAL 0x11
  87. #define ZR_VTOTAL 0x12
  88. #define ZR_HSYNCSIZE 0x13
  89. #define ZR_VSYNCSIZE 0x14
  90. #define ZR_CBHSTART 0x15
  91. #define ZR_CBVSTART 0x16
  92. #define ZR_CBHEND 0x17
  93. #define ZR_CBVEND 0x18
  94. #define ZR_ACTIVESTARTX 0x19
  95. #define ZR_ACTIVESTARTY 0x1A
  96. #define ZR_ACTIVEENDX 0x1B
  97. #define ZR_ACTIVEENDY 0x1C
  98. #define ZR_ACTIVESIZEX 0x1D
  99. #define ZR_ACTIVESIZEY 0x1E
  100. #define ZR_IMAGESTARTX 0x19
  101. #define ZR_IMAGESTARTY 0x1A
  102. #define ZR_IMAGEENDX 0x1B
  103. #define ZR_IMAGEENDY 0x1C
  104. #define ZR_IMAGESIZEX 0x1D
  105. #define ZR_IMAGESIZEY 0x1E
  106. #define ZR_CAPTIONOFFSET 0x1F
  107. #define ZR_STARTDISPLAY  0x20
  108. #define ZR_OSDSWITCH 0x2D
  109. #define ZR_PLAYBACKMODE 0x41
  110. #define ZR_AUDSID 0x42
  111. #define ZR_VIDSID 0x43
  112. #define ZR_SPSID 0x44
  113. #define ZR_AUDPORTDELAY 0x45
  114. #define ZR_VIDPORTDELAY 0x46
  115. #define ZR_VIDTOLERANCE 0x47
  116. #define ZR_VIDSYNCMODE 0x48
  117. #define ZR_AUTOSCALING 0x50
  118. #define ZR_AUTOPANSCAN 0x68
  119. #define ZR_BACKGROUNDSWITCH 0x6B
  120. #define ZR_INITFILE_1 0xF0
  121. #define ZR_INITFILE_2 0xF1
  122. #define ZR_INITFILE_3 0xF2
  123. #define ZR_INITFILE_4 0xF3
  124. #define ZR_MICROCODE 0xFD
  125. static u16 shadow_register[0xff]; // Warning: not all registers are 2 bytes long
  126. // but it's enough for those we're interested in
  127. u16 I34_Read(struct mga_dev *mga, u8 reg) {
  128. codec_reset(mga);
  129. codec_read(mga, reg);
  130. codec_exec(mga);
  131. return __swab16(codec_getw(mga));
  132. }
  133. void I34_Write(struct mga_dev *mga, u8 reg, u16 data) {
  134. codec_reset(mga);
  135. codec_write(mga, reg, __swab16(data));
  136. codec_exec(mga);
  137. }
  138. /* see table 32 p. 79 for the protocol to access the indirect address space */
  139. u16 I34_ParameterRead(struct mga_dev *mga, u8 addr) {
  140. codec_reset(mga);
  141. /* addr. in the l.s. bits, m.s. bits must be 0 */
  142. codec_write(mga, ZR_PARAM_ADDR, __swab16(addr));
  143. codec_read(mga, ZR_PARAM_DATA);
  144. codec_exec(mga);
  145. shadow_register[addr] = __swab16(codec_getw(mga));
  146. return shadow_register[addr];
  147. }
  148. void I34_ParameterWrite(struct mga_dev *mga, u8 addr, u16 data) {
  149. shadow_register[addr] = data;
  150. codec_reset(mga);
  151. codec_write(mga, ZR_PARAM_ADDR, __swab16(addr));
  152. codec_write(mga, ZR_PARAM_DATA, __swab16(data));
  153. codec_exec(mga);
  154. }
  155. void I34_ParameterWriteSeq(struct mga_dev *mga, u8 addr, u8* buf, u32 len) {
  156. u32 i;
  157. codec_reset(mga);
  158. codec_write(mga, ZR_PARAM_ADDR, __swab16(addr));
  159. /* multiple read/writes witout modifying the Parameter Address Register */
  160. if (buf == 0) {
  161. for (i=0; i<len; i+=2) // we count the buffer size in bytes, but write a _word_ at a time
  162. codec_write(mga, ZR_PARAM_DATA, 0);
  163.   
  164. } else {
  165. for (i=0; i<len; i+=2)
  166. codec_write(mga, ZR_PARAM_DATA, __swab16(*(((u16 *)buf)++)));
  167. }
  168. codec_exec(mga);
  169. }
  170. int I34_State(struct mga_dev *mga, int *s) {
  171. *s = (I34_Read(mga, ZR_STATUS0) >> 10);
  172. return 0;
  173. }
  174. int I34_Command(struct mga_dev *mga, u16 cmd) {
  175. /* p. 100 ZR HB: check that the host is ready to receive a new command */
  176. u16 status1 = I34_Read(mga, ZR_STATUS1);
  177. u16 hcready = (status1 >> 8) & 0x80;
  178. if (hcready) {
  179. I34_Write(mga, ZR_HOSTCMD, cmd);
  180. return 0;
  181. } else {
  182. I34_Write(mga, ZR_HOSTCMD, cmd);
  183. dprintk("I34: host is not ready to receive commands (%#4.4x)n", status1);
  184. return -EBUSY;
  185. }
  186. }
  187. /* new form: returns an error status and passes the actual result via a pointer */
  188. int I34_ReadInterruptStatus(struct mga_dev *mga, u16 *status) {
  189. *status = I34_Read(mga, ZR_ISR);
  190. return 1;
  191. }
  192. void I34_SetPar_bits(struct mga_dev *mga, u16 addr, u16 or, u16 and) {
  193. // the windows driver uses a shadow register that recalls
  194. // the last read value of the register...
  195. u16 value = (shadow_register[addr] & ~and) | or;
  196. I34_ParameterWrite(mga, addr, value);
  197. }
  198. #define I34_WaitMicroSecond(a) udelay(a)
  199. void I34_ResetPin(struct mga_dev *mga) {
  200. if (reset == 0) return;
  201. codec_miscctl_func1(mga, reset);
  202. I34_WaitMicroSecond(160);
  203. codec_I34_reset(mga);
  204. codec_miscctl(mga, 0x0f, 0xf9);
  205. }
  206. int I34_Reset(struct mga_dev *mga) {
  207. u16 i, isr;
  208. dprintk("I34: Resetn");
  209. I34_ResetPin(mga);
  210. for (i=0; i<5000; i++) {
  211. if (!I34_ReadInterruptStatus(mga, &isr)) {
  212. return 0;
  213. }
  214. #ifdef BYTEORDERHACK
  215. if ((isr & 0x1800) == 0x1800) {
  216. mga->little_endian_codec = 0;
  217. dprintk("I34_Reset ISR = 0x%4.4x Codec big-endian after resetn", isr);
  218. I34_ParameterWrite(mga, 0x0F3, 0xA0);
  219. I34_ParameterWrite(mga, 0x0F3, 0x88);
  220. return 1;
  221. } else if ((isr & 0x18) == 0x18) {
  222. mga->little_endian_codec = 1;
  223. dprintk("I34_Reset ISR = 0x%4.4x Codec little-endian after resetn", isr);
  224. I34_ParameterWrite(mga, 0x0F3, 0xA0);
  225. I34_ParameterWrite(mga, 0x0F3, 0x88);
  226. return 1;
  227. }
  228. #else
  229. if ((isr & 0x1800) == 0x1800) {
  230. I34_ParameterWrite(mga, 0x0F3, 0xA0);
  231. I34_ParameterWrite(mga, 0x0F3, 0x88);
  232. return 1;
  233. }
  234. #endif
  235. I34_WaitMicroSecond(100);
  236. }
  237. dprintk("PLL's NOT locked ---> 0x%4.4xn", isr);
  238. return 0;
  239. }
  240. int I34_Detect(struct mga_dev *mga) {
  241. u32 id;
  242. #ifdef BYTEORDERHACK
  243. mga->little_endian_codec = 0; /* assume the codec is bigendian */
  244. #endif
  245. I34_Reset(mga);
  246. id = I34_Read(mga, ZR_DEVICE_ID);
  247. /* we should obtain: 0x34 m.s. bits, rev in l.s. bits p. 112 ZR HB */
  248. /* warning: this test is arch. dependent ! */
  249. #ifndef __LITTLE_ENDIAN
  250. #error FIX ME
  251. #else
  252. if (((id>>8) & 0xFF) == 0x34) {
  253. dprintk("I34: found chipset rev 0x%2.2x)n", id & 0xFF);
  254. return 1;
  255. } else {
  256. dprintk("I34: too bad, codec said 0x%4.4xn", id);
  257. return 0;
  258. }
  259. #endif
  260. }
  261. int I34_ColorKey(struct mga_dev* mga, struct ColorKey *ck)
  262. {
  263. I34_ParameterWrite(mga, ZR_COLORV, ck->v);
  264. I34_ParameterWrite(mga, ZR_COLORU, ck->y);
  265. I34_ParameterWrite(mga, ZR_COLORY, ck->u);
  266. return 0;
  267. }
  268. static struct VideoStandard pal1 = { // was unk_28E0
  269. 1, // VidFPS => PAL
  270. 0, // ??
  271. 0, // FieldSel
  272. 0, // ??
  273. 864, // HTotal
  274. 625, // VTotal
  275. 64, // HSyncSize
  276. 6, // VSyncSize
  277. 142, // ActiveStartX
  278. 14, // ActiveStartY
  279. 860, // ActiveEndX
  280. 310, // ActiveEndY
  281. 720,  // ActiveSizeX
  282. 288, // ActiveSizeY
  283. 0x4006 // VidConfig
  284. };
  285. static struct VideoStandard ntsc1 = { // was unk_2900
  286. 0, // VidFPS => NTSC
  287. 0, // ??
  288. 0, // FieldSel
  289. 0, // ??
  290. 858, // HTotal
  291. 525, // VTotal
  292. 64, // HSyncSize
  293. 6, // VSyncSize
  294. 136, // ActiveStartX
  295. 14, // ActiveStartY
  296. 856, // ActiveEndX
  297. 260, // ActiveEndY
  298. 720,  // ActiveSizeX
  299. 240, // ActiveSizeY
  300. 0x4006 // VidConfig <=> Video8, Sync8, PixLim
  301. };
  302. static struct VideoStandard pal2 = { // was unk_3930
  303. 1, // VidFPS => PAL
  304. 0, // ??
  305. 0, // FieldSel
  306. 0, // ??
  307. 864, // HTotal
  308. 625, // VTotal
  309. 64, // HSyncSize
  310. 6, // VSyncSize
  311. 142, // ActiveStartX
  312. 16, // ActiveStartY
  313. 862, // ActiveEndX
  314. 310, // ActiveEndY
  315. 720,  // ActiveSizeX
  316. 288, // ActiveSizeY
  317. 0x4006 // VidConfig
  318. };
  319. static struct VideoStandard ntsc2 = { // was unk_2900
  320. 0, // VidFPS => NTSC
  321. 0, // ??
  322. 0, // FieldSel
  323. 0, // ??
  324. 858, // HTotal
  325. 525, // VTotal
  326. 64, // HSyncSize
  327. 6, // VSyncSize
  328. 136, // ActiveStartX
  329. 16, // ActiveStartY
  330. 856, // ActiveEndX
  331. 352, // ActiveEndY
  332. 720,  // ActiveSizeX
  333. 240, // ActiveSizeY
  334. 0x4006 // VidConfig <=> Video8, Sync8, PixLim
  335. };
  336. /* this is pure guess (but works somehow...) */
  337. static struct CompositeBlankSync cbs1 = {
  338. 6,  // HStart
  339. 2,  // VStart;
  340. 857, // HEnd;
  341. 261 // VEnd;
  342. };
  343. static struct ColorKey ckBlank = {
  344. 0,
  345. 0x80,
  346. 0x80
  347. };
  348. int I34_LoadVideoStandard(struct mga_dev *mga, struct VideoStandard *vs) {
  349. I34_ParameterWrite(mga, ZR_VIDOUT, vs->FieldSel | vs->VidFPS);
  350. I34_ParameterWrite(mga, ZR_HTOTAL, vs->HTotal);
  351. I34_ParameterWrite(mga, ZR_VTOTAL, vs->VTotal);
  352. I34_ParameterWrite(mga, ZR_HSYNCSIZE, vs->HSyncSize);
  353. I34_ParameterWrite(mga, ZR_VSYNCSIZE, vs->VSyncSize);
  354. I34_ParameterWrite(mga, ZR_ACTIVESTARTX, vs->ActiveStartX);
  355. I34_ParameterWrite(mga, ZR_ACTIVESTARTY, vs->ActiveStartY);
  356. I34_ParameterWrite(mga, ZR_ACTIVEENDX, vs->ActiveEndX);
  357. I34_ParameterWrite(mga, ZR_ACTIVEENDY, vs->ActiveEndY);
  358. I34_ParameterWrite(mga, ZR_ACTIVESIZEX, vs->ActiveSizeX);
  359. I34_ParameterWrite(mga, ZR_ACTIVESIZEY, vs->ActiveSizeY);
  360. I34_ParameterWrite(mga, ZR_VIDCONFIG, vs->VidConfig);
  361. return 0;
  362. }
  363. int I34_OutputVideoStandard(struct mga_dev *mga, int standard) {
  364. struct VideoStandard *vs;
  365. switch(standard) {
  366. case I34_NTSC:
  367. vs = &ntsc1;
  368. break;
  369. case I34_NTSC_ALT:
  370. vs = &ntsc2;
  371. break;
  372. case I34_PAL:
  373. vs = &pal1;
  374. break;
  375. case I34_PAL_ALT:
  376. default:
  377. vs = &pal2;
  378. break;
  379.     
  380. }
  381. /*  if (standard == 0 || standard == -1) {
  382.     vs = &ntsc2;
  383.     } else if (standard == 1) {
  384.     vs = &pal1;
  385.     } else 
  386.     return 0;
  387. */
  388. return I34_LoadVideoStandard(mga, vs);
  389. }
  390. int I34_CompositeBlankSync(struct mga_dev *mga, struct CompositeBlankSync *cb) {
  391. I34_ParameterWrite(mga, ZR_CBHSTART, cb->CBHStart);
  392. I34_ParameterWrite(mga, ZR_CBVSTART, cb->CBVStart);
  393. I34_ParameterWrite(mga, ZR_CBHEND, cb->CBHEnd);
  394. I34_ParameterWrite(mga, ZR_CBVEND, cb->CBVEnd);
  395. return 0;
  396. }
  397. int I34_StartDisplay(struct mga_dev *mga) {
  398. I34_ParameterWrite(mga, ZR_PLAYBACKMODE, 0);
  399. I34_SetPar_bits(mga, ZR_BACKGROUNDSWITCH, 1, 1);
  400. I34_ParameterWrite(mga, ZR_AUTOSCALING, 1<<15);
  401. I34_ParameterWrite(mga, ZR_AUTOPANSCAN, 1);
  402. I34_ParameterWrite(mga, ZR_OSDSWITCH, 0);        
  403. I34_ParameterWrite(mga, ZR_AUDPORTDELAY, 0);
  404. I34_ParameterWrite(mga, ZR_VIDPORTDELAY, 0);
  405. I34_ParameterWrite(mga, ZR_VIDTOLERANCE, 0);
  406. /* validate the new video parameters */
  407. I34_ParameterWrite(mga, ZR_STARTDISPLAY, 1);
  408. return 0;
  409. }
  410. /* this function progressively fills the ucode buffer prior to downloading */
  411. /* length = size of the new chunk to add in the buffer
  412.    or 0 to reset to the start of the ucode buffer
  413. */
  414. int I34_MicrocodeRead(struct mga_dev *mga, struct i34_ucode_chunk *chunk) {
  415. if ((ucode_length + chunk->length) >= 16384) return -EINVAL;
  416. memcpy(chunk->buffer, ucode_buffer + ucode_length, chunk->length);
  417. ucode_length += chunk->length;
  418. return 0;
  419. }
  420. /* example calls :
  421.      in ADPBoot
  422.       I34_MicrocodeRead(1, 2, offset unk_210, dword ptr [ebp+8])
  423.       I34_MicrocodeRead(edi, 0x3c, offset unk_4c8, dword ptr [ebp+8])
  424.      in DVPMicrocodeDownload
  425. result = I34_MicrocodeRead(1, 2, offset unk_2888, dword ptr [ebp+8])
  426. result = I34_MicrocodeRead(0, 0x3c, result, dword ptr [ebp+8])
  427. I34_ParameterWriteSeq(0xFD, 0, buf);
  428.      in LoadSlotMachine
  429. I34_MicrocodeRead(1, 2, offset unk_4C8, 0x0103)
  430. I34_MicrocodeRead(0, 0x3c, esi, edi)
  431.      in LoadDRAMMapping
  432. I34_MicrocodeRead(1, 0x3c, offset unk_4C8, 0x0104)
  433.    */  
  434. int I34_DVPMicrocodeDownload(struct mga_dev *mga) {
  435. if (ucode_length == 0) return 0;
  436.  
  437. /* In the general case, we should store the size of the last microcode
  438.    and zero-pad it to 16384, and then upload the new code */
  439. if (ucode_wmark != 0)
  440. I34_ParameterWriteSeq(mga, 0xfd, 0, 16384 - ucode_wmark);
  441. dprintk("I34: trying to upload %d bytes into the chipsetn", ucode_length);
  442. I34_ParameterWriteSeq(mga, ZR_MICROCODE, ucode_buffer, ucode_length);
  443. return 1;
  444. /* I need to down/upload : 340EDVD.DVP 340EAC3.ADP & ZI34SLT1.PRG */
  445. }
  446. int I34_Init(struct mga_dev *mga) {
  447. /* According to Annex C p. 248 of the ZR36710 Handbook */
  448. dprintk("I34_initn");
  449. /* Stage 1 : Reset */
  450. if (!I34_Detect(mga)) return -ENODEV;
  451. /* Stage 2 : I/O Port Configuration */
  452. /* SDRAM, Host Bus Port */
  453. I34_ParameterWrite(mga, ZR_SYSCONFIG, 0x1408); // CodeSource = HostBus; Decryption = enable
  454. I34_SetPar_bits(mga, 0xA0, 0x80, 0x80); // ??
  455. I34_SetPar_bits(mga, 0xA0, 0x00, 0x80);
  456. I34_SetPar_bits(mga, 0xA0, 0x0F, 0x0F);
  457. I34_SetPar_bits(mga, 0xA4, 0x00, 0x40);
  458. I34_SetPar_bits(mga, 0xA4, 0x01, 0x07);
  459. I34_ParameterWrite(mga, ZR_SDCONFIG, 0);
  460. return 0;
  461. /* Audio Port */
  462. /* tricky, so I leave it at defaults value for now... */
  463. /* Video Port */
  464. /* mga video-in is an 8-bits bus (Appendix A1.5) */
  465. I34_OutputVideoStandard(mga, I34_NTSC);
  466. I34_CompositeBlankSync(mga, &cbs1);
  467. I34_ColorKey(mga, &ckBlank);
  468. I34_ParameterWrite(mga, ZR_STARTDISPLAY, 1);
  469. I34_SetPar_bits(mga, ZR_BACKGROUNDSWITCH, 1, 1);
  470. /* Stage 3 :  OSD and Preparation for Decoding*/
  471. /* OSD */
  472. I34_ParameterWrite(mga, ZR_OSDSWITCH, 0);        
  473. /* Microcode uploading - DVP and ADP*/
  474. /* we first need to zero-pad the 16384 bytes of the microcode prior to loading a new one */
  475. // I34_ParameterWriteClean(mga, ZR_MICROCODE, 0x0000, 16384);
  476. // dprintk("I34: uploading %d bytes of microcoden", sizeof(microcode));
  477. // I34_ParameterWrite_buffer(mga, ZR_MICROCODE, (u16*)microcode, sizeof(microcode));
  478. I34_StartDisplay(mga);
  479. /* TEST */
  480. I34_Command(mga, I34_CMD_START); /* START */
  481. I34_Command(mga, I34_CMD_END | 1); /* END and display bgnd color */
  482. /* Stage  :  */
  483. /* Stage  :  */
  484. /* Stage  :  */
  485. /* 0 since no bistream is decoded yet (p. 91 ZR-HB) */
  486. I34_ParameterWrite(mga, ZR_AUDPORTDELAY, 0);
  487. I34_ParameterWrite(mga, ZR_VIDPORTDELAY, 0);
  488. I34_ParameterWrite(mga, ZR_VIDTOLERANCE, 0);
  489. /* Stage  :  */
  490. /* Stage  :  */
  491. /* Stage  :  */
  492. /* Stage  :  */
  493. /* Stage  :  */
  494. /* Stage  :  */
  495. /* Stage  :  */
  496. /* Stage  :  */
  497. /* Stage  :  */
  498. /* Stage  :  */
  499. return 0;
  500. }
  501. int codec_read_info(char *buf, char **start, off_t offset, int len, int unused) {
  502. u16 data;
  503.         struct mga_dev* mga = host;
  504. if (host == NULL) return 0;
  505. len = 0;
  506. len += sprintf(buf + len, "Zoran codec interfacen");
  507. data = I34_ParameterRead(mga, ZR_VIDCONFIG);
  508. len += sprintf(buf + len, "VidConfig: 0x%4.4xnn", data);
  509. len += sprintf(buf + len, "PARAM_ADDR %#4.4xn", I34_Read(mga, ZR_PARAM_ADDR));
  510. len += sprintf(buf + len, "PARAM_DATA %#4.4xn", I34_Read(mga, ZR_PARAM_DATA));
  511. len += sprintf(buf + len, "ISR        %#4.4xn", I34_Read(mga, ZR_ISR));
  512. data = I34_Read(mga, ZR_STATUS0);
  513. len += sprintf(buf + len, "STATUS0    %#4.4x (c-state 0x%x)n",
  514.        data, data >> 10);
  515. len += sprintf(buf + len, "STATUS1    %#4.4xn", I34_Read(mga, ZR_STATUS1));
  516. len += sprintf(buf + len, "STATUS2    %#4.4xn", I34_Read(mga, ZR_STATUS2));
  517. len += sprintf(buf + len, "DEV_ID     %#4.4xn", I34_Read(mga, ZR_DEVICE_ID));
  518. len += sprintf(buf + len, "ADP_STATUS %#4.4xn", I34_Read(mga, ZR_ADP_STATUS));
  519. len += sprintf(buf + len, "SYS_CLOCK  %#4.4xn", I34_Read(mga, ZR_SYS_CLOCK));
  520. len += sprintf(buf + len, "NAV_DATA   %#4.4xn", I34_Read(mga, ZR_NAV_DATA));
  521. len += sprintf(buf + len, "RESERVED1  %#4.4xn", I34_Read(mga, ZR_RESERVED1));
  522. len += sprintf(buf + len, "SUBPICBUF  %#4.4xn", I34_Read(mga, ZR_SUBPICBUF));
  523. len += sprintf(buf + len, "VIDEOBUF   %#4.4xn", I34_Read(mga, ZR_VIDEOBUF));
  524. len += sprintf(buf + len, "AUDIOBUF   %#4.4xn", I34_Read(mga, ZR_AUDIOBUF));
  525. len += sprintf(buf + len, "RESERVED2  %#4.4xn", I34_Read(mga, ZR_RESERVED2));
  526. return len;
  527. }
  528. struct proc_dir_entry codec_proc_entry = {
  529.         0,                 /* low_ino: the inode -- dynamic */
  530.         8, "mgacodec",     /* len of name and name */
  531.         S_IFREG | S_IRUGO, /* mode */
  532.         1, 0, 0,           /* nlinks, owner, group */
  533.         0, NULL,           /* size - unused; operations -- use default */
  534.         &codec_read_info,  /* function used to read data */
  535.         /* nothing more */
  536. };
  537. int I34_ioctl(struct mga_dev *mga, unsigned int cmd, void *arg)
  538. {
  539. // dprintk("I34: ioctl %d, arg=%pn", _IOC_NR(cmd), arg);
  540. switch(cmd) {
  541. case I34_IOCSUCODE:
  542. {
  543. return I34_MicrocodeRead(mga, (struct i34_ucode_chunk *)arg);
  544. }
  545. case I34_IOCSVIDEOSTD:
  546. {
  547. return I34_OutputVideoStandard(mga, (int)arg);
  548. }
  549. case I34_IOCSVDSTDCST:
  550. {
  551. return I34_LoadVideoStandard(mga, (struct VideoStandard *)arg);
  552. }
  553. case I34_IOCSCOLORKEY:
  554. {
  555. return I34_ColorKey(mga, (struct ColorKey *)arg);
  556. }
  557. case I34_IOCSCBSYNC:
  558. {
  559. return I34_CompositeBlankSync(mga, (struct CompositeBlankSync *)arg);
  560. }
  561. case I34_IOCGSTATE:
  562. {
  563.         return I34_State(mga, (int *)arg);
  564. }
  565. case I34_IOCTSTRTDSPL:
  566. {
  567. return I34_StartDisplay(mga);
  568. }
  569. case I34_IOCTCMD:
  570. {
  571. return I34_Command(mga, (int)arg);
  572. }
  573. case I34_IOCTINIT:
  574. {
  575. return I34_Init(mga);
  576. }
  577. default:    
  578. return -ENOIOCTLCMD;
  579. }
  580. }
  581. /****************************************************************************
  582. * linux kernel module api
  583. ****************************************************************************/
  584. #ifdef MODULE
  585. int init_module(void)
  586. #else
  587. int i34_init(void)
  588. #endif
  589. {
  590. /* Be sure that the mgavideo module is loaded */
  591. /* I should take a look at get_module_symbol ... */
  592. if ((host = mgavideo_get_codec()) == NULL)
  593. return -ENODEV;
  594.   //  if (!I34_Detect(host))
  595.   //    return -ENODEV;
  596.   //  I34_Init(host);
  597. proc_register(&proc_root, &codec_proc_entry);
  598. return 0;
  599. }
  600. #ifdef MODULE
  601. void cleanup_module(void)
  602. {
  603. proc_unregister(&proc_root, codec_proc_entry.low_ino);
  604. }
  605. #endif
  606. /******************************************************************************/
  607. /*int I34_ResetOrig(struct mga_dev *mga, u16 param1, u16 param2) {
  608.   u16 i, isr;
  609.   dprintk("I34: Resetn");
  610.   if (!(I34_ResetPin(mga, param1))) {
  611.   dprintk("I34: 23 FALSE regn");
  612.   return 0;
  613.   }  
  614.   for (i = 1000; i>0; i--)
  615.   I34_WaitMicroSecond(500);
  616.   if (param1 == 1) {
  617.   for (i=0; i<0x1388; i++) {
  618.   if (!I34_ReadInterruptStatus(mga, &isr)) {
  619.   dprintk("I34: 24 FALSE regn");
  620.   return 0;
  621.   }
  622.   if ((isr & 0x1800) != 0x1800) {
  623.   I34_ParameterWrite(mga, 0xA0, 0x0F3);
  624.   I34_ParameterWrite(mga, 0x88, 0x0F3);
  625.   return 1;
  626.   }
  627.   I34_WaitMicroSecond(100);
  628.   }
  629.   dprintk("PLL's NOT locked ---> 0x%4.4x", isr);
  630.   return 0;
  631.   } else {
  632.   if (param2 == 1)
  633.   // I34_Init(mga);
  634.   return 1;
  635.   }
  636.   return 0;
  637.   }
  638. */
  639. /* ******************************************************************
  640.    Explanation: 
  641.    I frankly don't know how to reliably reset this ^*&#@ !
  642.    This 2-phase sequence _seems_ to succeed in unlocking the card
  643.    and placing it in a state suitable for further operations.
  644.    But who knows if it will work for you.
  645.    _Please_ report any success or failure with the corresponding
  646.    rev number or the answer of the codec.
  647.    ****************************************************************** */
  648. /* taken verbatim from mgallx64 */
  649. /* writeb(codecen, mga->ctrl + CODECCTL);
  650.    writeb(readb(mga->ctrl + CODECCTL + 3) & 0xfb, mga->ctrl + CODECCTL + 3);
  651.    writeb(~codecen, mga->ctrl + CODECCTL);
  652.    mdelay(160); */
  653. /* this one is from Mike's zr36060 driver */
  654. /* writeb(codecen, mga->ctrl + CODECCTL);
  655.    writeb(readb(mga->ctrl + CODECCTL + 3) | 0x40, mga->ctrl + CODECCTL + 3);
  656.    writeb(readb(mga->ctrl + CODECCTL + 3) & ~0x40, mga->ctrl + CODECCTL + 3);
  657.    writeb(~codecen, mga->ctrl + CODECCTL);
  658.    mdelay(160); */
  659. /* writeb(codecen, mga->ctrl + CODECCTL);
  660.    u8 misc;
  661.    u8 value = 0x98;
  662.    misc = ~((value & 0x9f) | (~value & 0x60)) & 0xff;
  663.    writeb(misc, mga->ctrl + CODECCTL + 3);
  664.    writeb(~codecen, mga->ctrl + CODECCTL);
  665.    mdelay(160); */
  666. /* od -vtx1 340edvd.dvp | cut -d" " -f2- | sed -e 's/ /,0x/g' | sed -e's/^/,0x/g' | sed -e 's/$/,/g | sed -e 's/^,//g' > 340edvd.inc '
  667.    do not forget to suppress the last line of the resulting file
  668. */