devtv.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194
  1. /*
  2. * Driver for Bt848 TV tuner.
  3. *
  4. */
  5. #include "u.h"
  6. #include "../port/lib.h"
  7. #include "mem.h"
  8. #include "dat.h"
  9. #include "fns.h"
  10. #include "../port/error.h"
  11. #include "io.h"
  12. #include "hcwAMC.h"
  13. #define max(a, b) (((a) > (b))? (a): (b))
  14. enum {
  15. Qdir = 0,
  16. Qsubdir,
  17. Qsubbase,
  18. Qvdata = Qsubbase,
  19. Qadata,
  20. Qctl,
  21. Qregs,
  22. Brooktree_vid = 0x109e,
  23. Brooktree_848_did = 0x0350,
  24. Brooktree_878_did = 0x036E,
  25. Intel_vid = 0x8086,
  26. Intel_82437_did = 0x122d,
  27. K = 1024,
  28. M = K * K,
  29. Ntvs = 4,
  30. Numring = 16,
  31. ntsc_rawpixels = 910,
  32. ntsc_sqpixels = 780, /* Including blanking & inactive */
  33. ntsc_hactive = 640,
  34. ntsc_vactive = 480,
  35. ntsc_clkx1delay = 135, /* Clock ticks. */
  36. ntsc_clkx1hactive = 754,
  37. ntsc_vdelay = 26, /* # of scan lines. */
  38. ntsc_vscale = 0,
  39. i2c_nostop = 1 << 5,
  40. i2c_nos1b = 1 << 4,
  41. i2c_timing = 7 << 4,
  42. i2c_bt848w3b = 1 << 2,
  43. i2c_bt848scl = 1 << 1,
  44. i2c_bt848sda = 1 << 0,
  45. i2c_scl = i2c_bt848scl,
  46. i2c_sda = i2c_bt848sda,
  47. i2c_miroproee = 0x80, /* MIRO PRO EEPROM */
  48. i2c_tea6300 = 0x80,
  49. i2c_tda8425 = 0x82,
  50. i2c_tda9840 = 0x84,
  51. i2c_tda9850 = 0xb6,
  52. i2c_haupee = 0xa0, /* Hauppage EEPROM */
  53. i2c_stbee = 0xae, /* STB EEPROM */
  54. i2c_msp3400 = 0x80,
  55. i2c_timeout = 1000,
  56. i2c_delay = 10,
  57. Bt848_miropro = 0,
  58. Bt848_miro,
  59. Bt878_hauppauge,
  60. /* Bit fields. */
  61. iform_muxsel1 = 3 << 5, /* 004 */
  62. iform_muxsel0 = 2 << 5,
  63. iform_xtselmask = 3 << 3,
  64. iform_xtauto = 3 << 3,
  65. iform_formatmask = 7 << 0,
  66. iform_ntsc = 1 << 0,
  67. control_ldec = 1 << 5, /* 02C */
  68. contrast_100percent = 0xd8, /* 030 */
  69. vscale_interlaced = 1 << 5, /* 04C */
  70. adelay_ntsc = 104, /* 060 */
  71. bdelay_ntsc = 93, /* 064 */
  72. adc_crush = 1 << 0, /* 068 */
  73. colorfmt_rgb16 = 2 << 4 | 2 << 0, /* 0D4 */
  74. colorfmt_YCbCr422 = 8 << 4 | 8 << 0,
  75. colorfmt_YCbCr411 = 9 << 4 | 9 << 0,
  76. colorctl_gamma = 1 << 4, /* 0D8 */
  77. capctl_fullframe = 1 << 4, /* 0DC */
  78. capctl_captureodd = 1 << 1,
  79. capctl_captureeven = 1 << 0,
  80. vbipacksize = 0x190, /* 0E0 */
  81. intstat_riscstatshift = 28, /* 100 */
  82. intstat_i2crack = 1 << 25,
  83. intstat_scerr = 1 << 19,
  84. intstat_ocerr = 1 << 18,
  85. intstat_pabort = 1 << 17,
  86. intstat_riperr = 1 << 16,
  87. intstat_pperr = 1 << 15,
  88. intstat_fdsr = 1 << 14,
  89. intstat_ftrgt = 1 << 13,
  90. intstat_fbus = 1 << 12,
  91. intstat_risci = 1 << 11,
  92. intstat_i2cdone = 1 << 8,
  93. intstat_vpress = 1 << 5,
  94. intstat_hlock = 1 << 4,
  95. intstat_vsync = 1 << 1,
  96. intstat_fmtchg = 1 << 0,
  97. intmask_etbf = 1 << 23, /* 104 */
  98. gpiodmactl_apwrdn = 1 << 26, /* 10C */
  99. gpiodmactl_daes2 = 1 << 13,
  100. gpiodmactl_daiomda = 1 << 6,
  101. gpiodmactl_pltp23_16 = 2 << 6,
  102. gpiodmactl_pltp23_0 = 0 << 6,
  103. gpiodmactl_pltp1_16 = 2 << 4,
  104. gpiodmactl_pltp1_0 = 0 << 4,
  105. gpiodmactl_acapenable = 1 << 4,
  106. gpiodmactl_pktp_32 = 3 << 2,
  107. gpiodmactl_pktp_0 = 0 << 2,
  108. gpiodmactl_riscenable = 1 << 1,
  109. gpiodmactl_fifoenable = 1 << 0,
  110. /* RISC instructions and parameters. */
  111. fifo_vre = 0x4,
  112. fifo_vro = 0xc,
  113. fifo_fm1 = 0x6,
  114. fifo_fm3 = 0xe,
  115. riscirq = 1 << 24,
  116. riscwrite = 1 << 28,
  117. riscwrite123 = 9 << 28,
  118. riscwrite1s23 = 11 << 28,
  119. riscwrite_sol = 1 << 27,
  120. riscwrite_eol = 1 << 26,
  121. riscskip = 0x2 << 28,
  122. riscjmp = 0x7 << 28,
  123. riscsync = 0x8 << 28,
  124. riscsync_resync = 1 << 15,
  125. riscsync_vre = fifo_vre << 0,
  126. riscsync_vro = fifo_vro << 0,
  127. riscsync_fm1 = fifo_fm1 << 0,
  128. riscsync_fm3 = fifo_fm3 << 0,
  129. risclabelshift_set = 16,
  130. risclabelshift_reset = 20,
  131. AudioTuner = 0,
  132. AudioRadio,
  133. AudioExtern,
  134. AudioIntern,
  135. AudioOff,
  136. AudioOn,
  137. asel_tv = 0,
  138. asel_radio,
  139. asel_mic,
  140. asel_smxc,
  141. Hwbase_ad = 448000,
  142. msp_dem = 0x10,
  143. msp_bbp = 0x12,
  144. /* Altera definitions. */
  145. gpio_altera_data = 1 << 0,
  146. gpio_altera_clock = 1 << 20,
  147. gpio_altera_nconfig = 1 << 23,
  148. Ial = 0x140001,
  149. Idma = 0x100002,
  150. Adsp = 0x7fd8,
  151. Adsp_verifysystem = 1,
  152. Adsp_querysupportplay,
  153. Adsp_setstyle,
  154. Adsp_setsrate,
  155. Adsp_setchannels,
  156. Adsp_setresolution,
  157. Adsp_setcrcoptions,
  158. Adsp_bufenqfor,
  159. Adsp_logbuffer,
  160. Adsp_startplay,
  161. Adsp_stopplay,
  162. Adsp_autostop,
  163. Adsp_startrecord,
  164. Adsp_stoprecord,
  165. Adsp_getlastprocessed,
  166. Adsp_pause,
  167. Adsp_resume,
  168. Adsp_setvolume,
  169. Adsp_querysupportrecord,
  170. Adsp_generalbufenq,
  171. Adsp_setdownmixtype,
  172. Adsp_setigain,
  173. Adsp_setlineout,
  174. Adsp_setlangmixtype,
  175. Kfir_gc = 0,
  176. Kfir_dsp_riscmc,
  177. Kfir_dsp_risccram,
  178. Kfir_dsp_unitmc,
  179. Kfir_bsm_mc,
  180. Kfir_mux_mc,
  181. Kfir_devid_gc = 7,
  182. Kfir_devid_dsp = 4,
  183. Kfir_devid_bsm = 5,
  184. Kfir_devid_mux = 8,
  185. Kfir_200 = 200,
  186. Kfir_dev_inst = Kfir_200,
  187. Kfir_201 = 201,
  188. Kfir_exec = Kfir_201,
  189. Kfir_202 = 202,
  190. Kfir_adr_eready = 254,
  191. Kfir_d_eready_encoding = 0,
  192. Kfir_d_eready_ready,
  193. Kfir_d_eready_test,
  194. Kfir_d_eready_stopdetect,
  195. Kfir_d_eready_seqend,
  196. VT_KFIR_OFF = 0,
  197. VT_KFIR_ON,
  198. VT_KFIR_LAYER_II = 1,
  199. VT_KFIR_STEREO = 1,
  200. Gpioinit = 0,
  201. Gpiooutput,
  202. Gpioinput,
  203. Srate_5512 = 0,
  204. Srate_11025 = 2,
  205. Srate_16000 = 3,
  206. Srate_22050 = 4,
  207. Srate_32000 = 5,
  208. Srate_44100 = 6,
  209. Srate_48000 = 7,
  210. };
  211. typedef struct Variant Variant;
  212. struct Variant {
  213. ushort vid;
  214. ushort did;
  215. char *name;
  216. };
  217. typedef struct Bt848 Bt848;
  218. struct Bt848 {
  219. ulong devstat; /* 000 */
  220. ulong iform; /* 004 */
  221. ulong tdec; /* 008 */
  222. ulong ecrop; /* 00C */
  223. ulong evdelaylo; /* 010 */
  224. ulong evactivelo; /* 014 */
  225. ulong ehdelaylo; /* 018 */
  226. ulong ehactivelo; /* 01C */
  227. ulong ehscalehi; /* 020 */
  228. ulong ehscalelo; /* 024 */
  229. ulong bright; /* 028 */
  230. ulong econtrol; /* 02C */
  231. ulong contrastlo; /* 030 */
  232. ulong satulo; /* 034 */
  233. ulong satvlo; /* 038 */
  234. ulong hue; /* 03C */
  235. ulong escloop; /* 040 */
  236. ulong pad0; /* 044 */
  237. ulong oform; /* 048 */
  238. ulong evscalehi; /* 04C */
  239. ulong evscalelo; /* 050 */
  240. ulong test; /* 054 */
  241. ulong pad1[2]; /* 058-05C */
  242. ulong adelay; /* 060 */
  243. ulong bdelay; /* 064 */
  244. ulong adc; /* 068 */
  245. ulong evtc; /* 06C */
  246. ulong pad2[3]; /* 070-078 */
  247. ulong sreset; /* 07C */
  248. ulong tglb; /* 080 */
  249. ulong tgctrl; /* 084 */
  250. ulong pad3; /* 088 */
  251. ulong ocrop; /* 08C */
  252. ulong ovdelaylo; /* 090 */
  253. ulong ovactivelo; /* 094 */
  254. ulong ohdelaylo; /* 098 */
  255. ulong ohactivelo; /* 09C */
  256. ulong ohscalehi; /* 0A0 */
  257. ulong ohscalelo; /* 0A4 */
  258. ulong pad4; /* 0A8 */
  259. ulong ocontrol; /* 0AC */
  260. ulong pad5[4]; /* 0B0-0BC */
  261. ulong oscloop; /* 0C0 */
  262. ulong pad6[2]; /* 0C4-0C8 */
  263. ulong ovscalehi; /* 0CC */
  264. ulong ovscalelo; /* 0D0 */
  265. ulong colorfmt; /* 0D4 */
  266. ulong colorctl; /* 0D8 */
  267. ulong capctl; /* 0DC */
  268. ulong vbipacksize; /* 0E0 */
  269. ulong vbipackdel; /* 0E4 */
  270. ulong fcap; /* 0E8 */
  271. ulong ovtc; /* 0EC */
  272. ulong pllflo; /* 0F0 */
  273. ulong pllfhi; /* 0F4 */
  274. ulong pllxci; /* 0F8 */
  275. ulong dvsif; /* 0FC */
  276. ulong intstat; /* 100 */
  277. ulong intmask; /* 104 */
  278. ulong pad7; /* 108 */
  279. ulong gpiodmactl; /* 10C */
  280. ulong i2c; /* 110 */
  281. ulong riscstrtadd; /* 114 */
  282. ulong gpioouten; /* 118 */
  283. ulong gpioreginp; /* 11C */
  284. ulong risccount; /* 120 */
  285. ulong pad8[55]; /* 124-1FC */
  286. ulong gpiodata[64]; /* 200-2FC */
  287. };
  288. #define packetlen i2c
  289. typedef struct Tuner Tuner;
  290. struct Tuner {
  291. char *name;
  292. ushort freq_vhfh; /* Start frequency */
  293. ushort freq_uhf;
  294. uchar VHF_L;
  295. uchar VHF_H;
  296. uchar UHF;
  297. uchar cfg;
  298. ushort offs;
  299. };
  300. typedef struct Frame Frame;
  301. struct Frame {
  302. ulong *fstart;
  303. ulong *fjmp;
  304. uchar *fbase;
  305. };
  306. typedef struct Tv Tv;
  307. struct Tv {
  308. Lock;
  309. Rendez;
  310. Bt848 *bt848;
  311. Bt848 *bt878; /* Really only audio control registers */
  312. Variant *variant;
  313. Tuner *tuner;
  314. Pcidev *pci;
  315. uchar i2ctuneraddr;
  316. uchar i2ccmd; /* I2C command */
  317. int board; /* What board is this? */
  318. ulong cfmt; /* Current color format. */
  319. int channel; /* Current channel */
  320. Ref fref; /* Copying images? */
  321. int nframes; /* Number of frames to capture. */
  322. Frame *frames; /* DMA program */
  323. int lvframe; /* Last video frame DMAed */
  324. uchar *amux; /* Audio multiplexer. */
  325. int nablocks; /* Number of audio blocks allocated */
  326. int absize; /* Audio block size */
  327. int narblocks; /* Number of audio blocks received */
  328. ulong *arisc; /* Audio risc bloc */
  329. uchar *abuf; /* Audio data buffers */
  330. char ainfo[128];
  331. /* WinTV/PVR stuff. */
  332. int msp;
  333. Lock kfirlock;
  334. ulong i2cstate; /* Last i2c state. */
  335. int gpiostate; /* Current GPIO state */
  336. ulong alterareg; /* Last used altera register */
  337. ulong alteraclock; /* Used to clock the altera */
  338. int asrate; /* Audio sample rate */
  339. uchar aleft, aright; /* Left and right audio volume */
  340. ulong kfirclock;
  341. Ref aref; /* Copying audio? */
  342. };
  343. enum {
  344. TemicPAL = 0,
  345. PhilipsPAL,
  346. PhilipsNTSC,
  347. PhilipsSECAM,
  348. Notuner,
  349. PhilipsPALI,
  350. TemicNTSC,
  351. TemicPALI,
  352. Temic4036,
  353. AlpsTSBH1,
  354. AlpsTSBE1,
  355. Freqmultiplier = 16,
  356. };
  357. static Tuner tuners[] = {
  358. {"Temic PAL", Freqmultiplier * 140.25, Freqmultiplier * 463.25,
  359. 0x02, 0x04, 0x01, 0x8e, 623 },
  360. {"Philips PAL_I", Freqmultiplier * 140.25, Freqmultiplier * 463.25,
  361. 0xa0, 0x90, 0x30, 0x8e, 623 },
  362. {"Philips NTSC", Freqmultiplier * 157.25, Freqmultiplier * 451.25,
  363. 0xA0, 0x90, 0x30, 0x8e, 732 },
  364. {"Philips SECAM", Freqmultiplier * 168.25, Freqmultiplier * 447.25,
  365. 0xA7, 0x97, 0x37, 0x8e, 623 },
  366. {"NoTuner", 0, 0,
  367. 0x00, 0x00, 0x00, 0x00, 0 },
  368. {"Philips PAL", Freqmultiplier * 168.25, Freqmultiplier * 447.25,
  369. 0xA0, 0x90, 0x30, 0x8e, 623 },
  370. {"Temic NTSC", Freqmultiplier * 157.25, Freqmultiplier * 463.25,
  371. 0x02, 0x04, 0x01, 0x8e, 732 },
  372. {"TEMIC PAL_I", Freqmultiplier * 170.00, Freqmultiplier * 450.00,
  373. 0x02, 0x04, 0x01, 0x8e, 623 },
  374. {"Temic 4036 FY5 NTSC", Freqmultiplier * 157.25, Freqmultiplier * 463.25,
  375. 0xa0, 0x90, 0x30, 0x8e, 732 },
  376. {"Alps TSBH1", Freqmultiplier * 137.25, Freqmultiplier * 385.25,
  377. 0x01, 0x02, 0x08, 0x8e, 732 },
  378. {"Alps TSBE1", Freqmultiplier * 137.25, Freqmultiplier * 385.25,
  379. 0x01, 0x02, 0x08, 0x8e, 732 },
  380. };
  381. static int hp_tuners[] = {
  382. Notuner,
  383. Notuner,
  384. Notuner,
  385. Notuner,
  386. Notuner,
  387. PhilipsNTSC,
  388. Notuner,
  389. Notuner,
  390. PhilipsPAL,
  391. PhilipsSECAM,
  392. PhilipsNTSC,
  393. PhilipsPALI,
  394. Notuner,
  395. Notuner,
  396. TemicPAL,
  397. TemicPALI,
  398. Notuner,
  399. PhilipsSECAM,
  400. PhilipsNTSC,
  401. PhilipsPALI,
  402. Notuner,
  403. PhilipsPAL,
  404. Notuner,
  405. PhilipsNTSC,
  406. };
  407. enum {
  408. CMvstart,
  409. CMastart,
  410. CMastop,
  411. CMvgastart,
  412. CMvstop,
  413. CMchannel,
  414. CMcolormode,
  415. CMvolume,
  416. CMmute,
  417. };
  418. static Cmdtab tvctlmsg[] = {
  419. CMvstart, "vstart", 2,
  420. CMastart, "astart", 5,
  421. CMastop, "astop", 1,
  422. CMvgastart, "vgastart", 3,
  423. CMvstop, "vstop", 1,
  424. CMchannel, "channel", 3,
  425. CMcolormode, "colormode", 2,
  426. CMvolume, "volume", 3,
  427. CMmute, "mute", 1,
  428. };
  429. static Variant variant[] = {
  430. { Brooktree_vid, Brooktree_848_did, "Brooktree 848 TV tuner", },
  431. { Brooktree_vid, Brooktree_878_did, "Brooktree 878 TV tuner", },
  432. };
  433. static char *boards[] = {
  434. "MIRO PRO",
  435. "MIRO",
  436. "Hauppauge Bt878",
  437. };
  438. static ushort Adspfsample[] = {
  439. 0x500, 0x700, 0x400, 0x600, 0x300, 0x200, 0x000, 0x100
  440. };
  441. static ushort Adspstereorates[] = {
  442. 64, 96, 112, 128, 160, 192, 224, 256, 320, 384
  443. };
  444. static uchar miroamux[] = { 2, 0, 0, 0, 10, 0 };
  445. static uchar hauppaugeamux[] = { 0, 1, 2, 3, 4, 0 };
  446. static char *nicamstate[] = {
  447. "analog", "???", "digital", "bad digital receiption"
  448. };
  449. static Tv tvs[Ntvs];
  450. static int ntvs;
  451. static int i2cread(Tv *, uchar, uchar *);
  452. static int i2cwrite(Tv *, uchar, uchar, uchar, int);
  453. static void tvinterrupt(Ureg *, Tv *);
  454. static void vgastart(Tv *, ulong, int);
  455. static void vstart(Tv *, int, int, int, int);
  456. static void astart(Tv *, char *, uint, uint, uint);
  457. static void vstop(Tv *);
  458. static void astop(Tv *);
  459. static void colormode(Tv *, char *);
  460. static void frequency(Tv *, int, int);
  461. static int getbitspp(Tv *);
  462. static char *getcolormode(ulong);
  463. static int mspreset(Tv *);
  464. static void i2cscan(Tv *);
  465. static int kfirinitialize(Tv *);
  466. static void msptune(Tv *);
  467. static void mspvolume(Tv *, int, int, int);
  468. static void gpioenable(Tv *, ulong, ulong);
  469. static void gpiowrite(Tv *, ulong, ulong);
  470. static void
  471. tvinit(void)
  472. {
  473. Pcidev *pci;
  474. ulong intmask;
  475. /* Test for a triton memory controller. */
  476. intmask = 0;
  477. if (pcimatch(nil, Intel_vid, Intel_82437_did))
  478. intmask = intmask_etbf;
  479. pci = nil;
  480. while ((pci = pcimatch(pci, 0, 0)) != nil) {
  481. int i, t;
  482. Tv *tv;
  483. Bt848 *bt848;
  484. ushort hscale, hdelay;
  485. uchar v;
  486. for (i = 0; i != nelem(variant); i++)
  487. if (pci->vid == variant[i].vid && pci->did == variant[i].did)
  488. break;
  489. if (i == nelem(variant))
  490. continue;
  491. if (ntvs >= Ntvs) {
  492. print("#V: Too many TV cards found\n");
  493. continue;
  494. }
  495. tv = &tvs[ntvs++];
  496. tv->variant = &variant[i];
  497. tv->pci = pci;
  498. tv->bt848 = (Bt848 *)vmap(pci->mem[0].bar & ~0x0F, 4 * K);
  499. if (tv->bt848 == nil)
  500. panic("#V: Cannot allocate memory for Bt848");
  501. bt848 = tv->bt848;
  502. /* i2c stuff. */
  503. if (pci->did >= 878)
  504. tv->i2ccmd = 0x83;
  505. else
  506. tv->i2ccmd = i2c_timing | i2c_bt848scl | i2c_bt848sda;
  507. t = 0;
  508. if (i2cread(tv, i2c_haupee, &v)) {
  509. uchar ee[256];
  510. Pcidev *pci878;
  511. Bt848 *bt878;
  512. tv->board = Bt878_hauppauge;
  513. if (!i2cwrite(tv, i2c_haupee, 0, 0, 0))
  514. panic("#V: Cannot write to Hauppauge EEPROM");
  515. for (i = 0; i != sizeof ee; i++)
  516. if (!i2cread(tv, i2c_haupee + 1, &ee[i]))
  517. panic("#V: Cannot read from Hauppauge EEPROM");
  518. if (ee[9] > sizeof hp_tuners / sizeof hp_tuners[0])
  519. panic("#V: Tuner out of range (max %d, this %d)",
  520. sizeof hp_tuners / sizeof hp_tuners[0], ee[9]);
  521. t = hp_tuners[ee[9]];
  522. /* Initialize the audio channel. */
  523. if ((pci878 = pcimatch(nil, Brooktree_vid, 0x878)) == nil)
  524. panic("#V: Unsupported Hauppage board");
  525. tv->bt878 = bt878 =
  526. (Bt848 *)vmap(pci878->mem[0].bar & ~0x0F, 4 * K);
  527. if (bt878 == nil)
  528. panic("#V: Cannot allocate memory for the Bt878");
  529. kfirinitialize(tv);
  530. // i2cscan(tv);
  531. mspreset(tv);
  532. bt878->gpiodmactl = 0;
  533. bt878->intstat = (ulong)-1;
  534. intrenable(pci878->intl, (void (*)(Ureg *, void *))tvinterrupt,
  535. tv, pci878->tbdf, "tv");
  536. tv->amux = hauppaugeamux;
  537. }
  538. else if (i2cread(tv, i2c_stbee, &v)) {
  539. USED(t);
  540. panic("#V: Cannot deal with STB cards\n");
  541. }
  542. else if (i2cread(tv, i2c_miroproee, &v)) {
  543. tv->board = Bt848_miropro;
  544. t = ((bt848->gpiodata[0] >> 10) - 1) & 7;
  545. tv->amux = miroamux;
  546. }
  547. else {
  548. tv->board = Bt848_miro;
  549. tv->amux = miroamux;
  550. t = ((bt848->gpiodata[0] >> 10) - 1) & 7;
  551. }
  552. if (t >= nelem(tuners))
  553. t = 4;
  554. tv->tuner = &tuners[t];
  555. tv->i2ctuneraddr =
  556. i2cread(tv, 0xc1, &v)? 0xc0:
  557. i2cread(tv, 0xc3, &v)? 0xc2:
  558. i2cread(tv, 0xc5, &v)? 0xc4:
  559. i2cread(tv, 0xc7, &v)? 0xc6: -1;
  560. bt848->capctl = capctl_fullframe;
  561. bt848->adelay = adelay_ntsc;
  562. bt848->bdelay = bdelay_ntsc;
  563. bt848->iform = iform_muxsel0|iform_xtauto|iform_ntsc;
  564. bt848->vbipacksize = vbipacksize & 0xff;
  565. bt848->vbipackdel = (vbipacksize >> 8) & 1;
  566. // setpll(bt848);
  567. tv->cfmt = bt848->colorfmt = colorfmt_rgb16;
  568. hscale = (ntsc_rawpixels * 4096) / ntsc_sqpixels - 4096;
  569. hdelay = (ntsc_clkx1delay * ntsc_hactive) / ntsc_clkx1hactive;
  570. bt848->ovtc = bt848->evtc = 0;
  571. bt848->ehscalehi = bt848->ohscalehi = (hscale >> 8) & 0xff;
  572. bt848->ehscalelo = bt848->ohscalelo = hscale & 0xff;
  573. bt848->evscalehi &= ~0x1f;
  574. bt848->ovscalehi &= ~0x1f;
  575. bt848->evscalehi |= vscale_interlaced | ((ntsc_vscale >> 8) & 0x1f);
  576. bt848->ovscalehi |= vscale_interlaced | (ntsc_vscale >> 8) & 0x1f;
  577. bt848->evscalelo = bt848->ovscalelo = ntsc_vscale & 0xff;
  578. bt848->ehactivelo = bt848->ohactivelo = ntsc_hactive & 0xff;
  579. bt848->ehdelaylo = bt848->ohdelaylo = hdelay & 0xff;
  580. bt848->evactivelo = bt848->ovactivelo = ntsc_vactive & 0xff;
  581. bt848->evdelaylo = bt848->ovdelaylo = ntsc_vdelay & 0xff;
  582. bt848->ecrop = bt848->ocrop =
  583. ((ntsc_hactive >> 8) & 0x03) |
  584. ((hdelay >> 6) & 0x0C) |
  585. ((ntsc_vactive >> 4) & 0x30) |
  586. ((ntsc_vdelay >> 2) & 0xC0);
  587. bt848->colorctl = colorctl_gamma;
  588. bt848->capctl = 0;
  589. bt848->gpiodmactl = gpiodmactl_pltp23_16 |
  590. gpiodmactl_pltp1_16 | gpiodmactl_pktp_32;
  591. bt848->gpioreginp = 0;
  592. bt848->contrastlo = contrast_100percent;
  593. bt848->bright = 16;
  594. bt848->adc = (2 << 6) | adc_crush;
  595. bt848->econtrol = bt848->ocontrol = control_ldec;
  596. bt848->escloop = bt848->oscloop = 0;
  597. bt848->intstat = (ulong)-1;
  598. bt848->intmask = intmask |
  599. intstat_vsync | intstat_scerr | intstat_risci | intstat_ocerr |
  600. intstat_vpress | intstat_fmtchg;
  601. if (tv->amux) {
  602. gpioenable(tv, ~0xfff, 0xfff);
  603. gpiowrite(tv, ~0xfff, tv->amux[AudioRadio]);
  604. }
  605. print("#V%ld: %s (rev %d) (%s/%s) intl %d\n",
  606. tv - tvs, tv->variant->name, pci->rid, boards[tv->board],
  607. tv->tuner->name, pci->intl);
  608. intrenable(pci->intl, (void (*)(Ureg *, void *))tvinterrupt,
  609. tv, pci->tbdf, "tv");
  610. }
  611. }
  612. static Chan*
  613. tvattach(char *spec)
  614. {
  615. return devattach('V', spec);
  616. }
  617. #define TYPE(q) ((int)((q).path & 0xff))
  618. #define DEV(q) ((int)(((q).path >> 8) & 0xff))
  619. #define QID(d, t) ((((d) & 0xff) << 8) | (t))
  620. static int
  621. tv1gen(Chan *c, int i, Dir *dp)
  622. {
  623. Qid qid;
  624. switch (i) {
  625. case Qvdata:
  626. mkqid(&qid, QID(DEV(c->qid), Qvdata), 0, QTFILE);
  627. devdir(c, qid, "video", 0, eve, 0444, dp);
  628. return 1;
  629. case Qadata:
  630. mkqid(&qid, QID(DEV(c->qid), Qadata), 0, QTFILE);
  631. devdir(c, qid, "audio", 0, eve, 0444, dp);
  632. return 1;
  633. case Qctl:
  634. mkqid(&qid, QID(DEV(c->qid), Qctl), 0, QTFILE);
  635. devdir(c, qid, "ctl", 0, eve, 0444, dp);
  636. return 1;
  637. case Qregs:
  638. mkqid(&qid, QID(DEV(c->qid), Qregs), 0, QTFILE);
  639. devdir(c, qid, "regs", 0, eve, 0444, dp);
  640. return 1;
  641. }
  642. return -1;
  643. }
  644. static int
  645. tvgen(Chan *c, char *, Dirtab *, int, int i, Dir *dp)
  646. {
  647. Qid qid;
  648. int dev;
  649. dev = DEV(c->qid);
  650. switch (TYPE(c->qid)) {
  651. case Qdir:
  652. if (i == DEVDOTDOT) {
  653. mkqid(&qid, Qdir, 0, QTDIR);
  654. devdir(c, qid, "#V", 0, eve, 0555, dp);
  655. return 1;
  656. }
  657. if (i >= ntvs)
  658. return -1;
  659. mkqid(&qid, QID(i, Qsubdir), 0, QTDIR);
  660. snprint(up->genbuf, sizeof(up->genbuf), "tv%d", i);
  661. devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
  662. return 1;
  663. case Qsubdir:
  664. if (i == DEVDOTDOT) {
  665. mkqid(&qid, QID(dev, Qdir), 0, QTDIR);
  666. snprint(up->genbuf, sizeof(up->genbuf), "tv%d", dev);
  667. devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
  668. return 1;
  669. }
  670. return tv1gen(c, i + Qsubbase, dp);
  671. case Qvdata:
  672. case Qadata:
  673. case Qctl:
  674. case Qregs:
  675. return tv1gen(c, TYPE(c->qid), dp);
  676. default:
  677. return -1;
  678. }
  679. }
  680. static Walkqid *
  681. tvwalk(Chan *c, Chan *nc, char **name, int nname)
  682. {
  683. return devwalk(c, nc, name, nname, 0, 0, tvgen);
  684. }
  685. static int
  686. tvstat(Chan *c, uchar *db, int n)
  687. {
  688. return devstat(c, db, n, 0, 0, tvgen);
  689. }
  690. static Chan*
  691. tvopen(Chan *c, int omode)
  692. {
  693. if (omode != OREAD &&
  694. TYPE(c->qid) != Qctl && TYPE(c->qid) != Qvdata)
  695. error(Eperm);
  696. switch (TYPE(c->qid)) {
  697. case Qdir:
  698. return devopen(c, omode, nil, 0, tvgen);
  699. case Qadata:
  700. if (tvs[DEV(c->qid)].bt878 == nil)
  701. error(Enonexist);
  702. break;
  703. }
  704. c->mode = openmode(omode);
  705. c->flag |= COPEN;
  706. c->offset = 0;
  707. if (TYPE(c->qid) == Qadata)
  708. c->aux = nil;
  709. return c;
  710. }
  711. static void
  712. tvclose(Chan *)
  713. {
  714. }
  715. static int
  716. audioblock(void *)
  717. {
  718. return 1;
  719. }
  720. static long
  721. tvread(Chan *c, void *a, long n, vlong offset)
  722. {
  723. static char regs[10 * K];
  724. static int regslen;
  725. Tv *tv;
  726. char *e, *p;
  727. uchar *src;
  728. USED(offset);
  729. switch(TYPE(c->qid)) {
  730. case Qdir:
  731. case Qsubdir:
  732. return devdirread(c, a, n, 0, 0, tvgen);
  733. case Qvdata: {
  734. int bpf, nb;
  735. tv = &tvs[DEV(c->qid)];
  736. bpf = ntsc_hactive * ntsc_vactive * getbitspp(tv) / 8;
  737. if (offset >= bpf)
  738. return 0;
  739. nb = n;
  740. if (offset + nb > bpf)
  741. nb = bpf - offset;
  742. ilock(tv);
  743. if (tv->frames == nil || tv->lvframe >= tv->nframes ||
  744. tv->frames[tv->lvframe].fbase == nil) {
  745. iunlock(tv);
  746. return 0;
  747. }
  748. src = tv->frames[tv->lvframe].fbase;
  749. incref(&tv->fref);
  750. iunlock(tv);
  751. memmove(a, src + offset, nb);
  752. decref(&tv->fref);
  753. return nb;
  754. }
  755. case Qadata: {
  756. ulong uablock = (ulong)c->aux, bnum, tvablock;
  757. int boffs, nbytes;
  758. tv = &tvs[DEV(c->qid)];
  759. if (tv->bt878 == nil)
  760. error("#V: No audio device");
  761. if (tv->absize == 0)
  762. error("#V: audio not initialized");
  763. bnum = offset / tv->absize;
  764. boffs = offset % tv->absize;
  765. nbytes = tv->absize - boffs;
  766. incref(&tv->aref);
  767. for (;;) {
  768. tvablock = tv->narblocks; /* Current tv block. */
  769. if (uablock == 0)
  770. uablock = tvablock - 1;
  771. if (tvablock >= uablock + bnum + tv->narblocks)
  772. uablock = tvablock - 1 - bnum;
  773. if (uablock + bnum == tvablock) {
  774. sleep(tv, audioblock, nil);
  775. continue;
  776. }
  777. break;
  778. }
  779. print("uablock %ld, bnum %ld, boffs %d, nbytes %d, tvablock %ld\n",
  780. uablock, bnum, boffs, nbytes, tvablock);
  781. src = tv->abuf + ((uablock + bnum) % tv->nablocks) * tv->absize;
  782. print("copying from %#p (abuf %#p), nbytes %d (block %ld.%ld)\n",
  783. src + boffs, tv->abuf, nbytes, uablock, bnum);
  784. memmove(a, src + boffs, nbytes);
  785. decref(&tv->aref);
  786. uablock += (boffs + nbytes) % tv->absize;
  787. c->aux = (void*)uablock;
  788. return nbytes;
  789. }
  790. case Qctl: {
  791. char str[128];
  792. tv = &tvs[DEV(c->qid)];
  793. snprint(str, sizeof str, "%dx%dx%d %s channel %d %s\n",
  794. ntsc_hactive, ntsc_vactive, getbitspp(tv),
  795. getcolormode(tv->cfmt), tv->channel, tv->ainfo);
  796. return readstr(offset, a, strlen(str) + 1, str);
  797. }
  798. case Qregs:
  799. if (offset == 0) {
  800. Bt848 *bt848;
  801. int i;
  802. tv = &tvs[DEV(c->qid)];
  803. bt848 = tv->bt848;
  804. e = regs + sizeof(regs);
  805. p = regs;
  806. for (i = 0; i < 0x300 >> 2; i++)
  807. p = seprint(p, e, "%.3X %.8ulX\n", i << 2,
  808. ((ulong *)bt848)[i]);
  809. if (tv->bt878) {
  810. bt848 = tv->bt878;
  811. for (i = 0; i < 0x300 >> 2; i++)
  812. p = seprint(p, e, "%.3X %.8ulX\n",
  813. i << 2, ((ulong *)bt848)[i]);
  814. }
  815. regslen = p - regs;
  816. }
  817. if (offset >= regslen)
  818. return 0;
  819. if (offset + n > regslen)
  820. n = regslen - offset;
  821. return readstr(offset, a, n, &regs[offset]);
  822. default:
  823. n = 0;
  824. break;
  825. }
  826. return n;
  827. }
  828. static long
  829. tvwrite(Chan *c, void *a, long n, vlong)
  830. {
  831. Cmdbuf *cb;
  832. Cmdtab *ct;
  833. Tv *tv;
  834. tv = &tvs[DEV(c->qid)];
  835. switch(TYPE(c->qid)) {
  836. case Qctl:
  837. cb = parsecmd(a, n);
  838. if(waserror()){
  839. free(cb);
  840. nexterror();
  841. }
  842. ct = lookupcmd(cb, tvctlmsg, nelem(tvctlmsg));
  843. switch (ct->index) {
  844. case CMvstart:
  845. vstart(tv, (int)strtol(cb->f[1], (char **)nil, 0),
  846. ntsc_hactive, ntsc_vactive, ntsc_hactive);
  847. break;
  848. case CMastart:
  849. astart(tv, cb->f[1], (uint)strtol(cb->f[2], (char **)nil, 0),
  850. (uint)strtol(cb->f[3], (char **)nil, 0),
  851. (uint)strtol(cb->f[4], (char **)nil, 0));
  852. break;
  853. case CMastop:
  854. astop(tv);
  855. break;
  856. case CMvgastart:
  857. vgastart(tv, strtoul(cb->f[1], (char **)nil, 0),
  858. (int)strtoul(cb->f[2], (char **)nil, 0));
  859. break;
  860. case CMvstop:
  861. vstop(tv);
  862. break;
  863. case CMchannel:
  864. frequency(tv, (int)strtol(cb->f[1], (char **)nil, 0),
  865. (int)strtol(cb->f[2], (char **)nil, 0));
  866. break;
  867. case CMcolormode:
  868. colormode(tv, cb->f[1]);
  869. break;
  870. case CMvolume:
  871. if (!tv->msp)
  872. error("#V: No volume control");
  873. mspvolume(tv, 0, (int)strtol(cb->f[1], (char **)nil, 0),
  874. (int)strtol(cb->f[2], (char **)nil, 0));
  875. break;
  876. case CMmute:
  877. if (!tv->msp)
  878. error("#V: No volume control");
  879. mspvolume(tv, 1, 0, 0);
  880. break;
  881. }
  882. poperror();
  883. free(cb);
  884. break;
  885. default:
  886. error(Eio);
  887. }
  888. return n;
  889. }
  890. Dev tvdevtab = {
  891. 'V',
  892. "tv",
  893. devreset,
  894. tvinit,
  895. devshutdown,
  896. tvattach,
  897. tvwalk,
  898. tvstat,
  899. tvopen,
  900. devcreate,
  901. tvclose,
  902. tvread,
  903. devbread,
  904. tvwrite,
  905. devbwrite,
  906. devremove,
  907. devwstat,
  908. };
  909. static void
  910. tvinterrupt(Ureg *, Tv *tv)
  911. {
  912. Bt848 *bt848 = tv->bt848, *bt878 = tv->bt878;
  913. for (;;) {
  914. ulong vstat, astat;
  915. uchar fnum;
  916. vstat = bt848->intstat;
  917. fnum = (vstat >> intstat_riscstatshift) & 0xf;
  918. vstat &= bt848->intmask;
  919. if (bt878)
  920. astat = bt878->intstat & bt878->intmask;
  921. else
  922. astat = 0;
  923. if (vstat == 0 && astat == 0)
  924. break;
  925. if (astat)
  926. print("vstat %.8luX, astat %.8luX\n", vstat, astat);
  927. bt848->intstat = vstat;
  928. if (bt878)
  929. bt878->intstat = astat;
  930. if ((vstat & intstat_fmtchg) == intstat_fmtchg) {
  931. iprint("int: fmtchg\n");
  932. vstat &= ~intstat_fmtchg;
  933. }
  934. if ((vstat & intstat_vpress) == intstat_vpress) {
  935. // iprint("int: vpress\n");
  936. vstat &= ~intstat_vpress;
  937. }
  938. if ((vstat & intstat_vsync) == intstat_vsync)
  939. vstat &= ~intstat_vsync;
  940. if ((vstat & intstat_scerr) == intstat_scerr) {
  941. iprint("int: scerr\n");
  942. bt848->gpiodmactl &=
  943. ~(gpiodmactl_riscenable|gpiodmactl_fifoenable);
  944. bt848->gpiodmactl |= gpiodmactl_fifoenable;
  945. bt848->gpiodmactl |= gpiodmactl_riscenable;
  946. vstat &= ~intstat_scerr;
  947. }
  948. if ((vstat & intstat_risci) == intstat_risci) {
  949. tv->lvframe = fnum;
  950. vstat &= ~intstat_risci;
  951. }
  952. if ((vstat & intstat_ocerr) == intstat_ocerr) {
  953. iprint("int: ocerr\n");
  954. vstat &= ~intstat_ocerr;
  955. }
  956. if ((vstat & intstat_fbus) == intstat_fbus) {
  957. iprint("int: fbus\n");
  958. vstat &= ~intstat_fbus;
  959. }
  960. if (vstat)
  961. iprint("int: (v) ignored interrupts %.8ulX\n", vstat);
  962. if ((astat & intstat_risci) == intstat_risci) {
  963. tv->narblocks++;
  964. if ((tv->narblocks % 100) == 0)
  965. print("a");
  966. wakeup(tv);
  967. astat &= ~intstat_risci;
  968. }
  969. if ((astat & intstat_fdsr) == intstat_fdsr) {
  970. iprint("int: (a) fdsr\n");
  971. bt848->gpiodmactl &=
  972. ~(gpiodmactl_acapenable |
  973. gpiodmactl_riscenable | gpiodmactl_fifoenable);
  974. astat &= ~intstat_fdsr;
  975. }
  976. if (astat)
  977. iprint("int: (a) ignored interrupts %.8ulX\n", astat);
  978. }
  979. }
  980. static int
  981. i2cread(Tv *tv, uchar off, uchar *v)
  982. {
  983. Bt848 *bt848 = tv->bt848;
  984. ulong intstat;
  985. int i;
  986. bt848->intstat = intstat_i2cdone;
  987. bt848->i2c = (off << 24) | tv->i2ccmd;
  988. intstat = -1;
  989. for (i = 0; i != 1000; i++) {
  990. if ((intstat = bt848->intstat) & intstat_i2cdone)
  991. break;
  992. microdelay(1000);
  993. }
  994. if (i == 1000) {
  995. print("i2cread: timeout\n");
  996. return 0;
  997. }
  998. if ((intstat & intstat_i2crack) == 0)
  999. return 0;
  1000. *v = bt848->i2c >> 8;
  1001. return 1;
  1002. }
  1003. static int
  1004. i2cwrite(Tv *tv, uchar addr, uchar sub, uchar data, int both)
  1005. {
  1006. Bt848 *bt848 = tv->bt848;
  1007. ulong intstat, d;
  1008. int i;
  1009. bt848->intstat = intstat_i2cdone;
  1010. d = (addr << 24) | (sub << 16) | tv->i2ccmd;
  1011. if (both)
  1012. d |= (data << 8) | i2c_bt848w3b;
  1013. bt848->i2c = d;
  1014. intstat = 0;
  1015. for (i = 0; i != 1000; i++) {
  1016. if ((intstat = bt848->intstat) & intstat_i2cdone)
  1017. break;
  1018. microdelay(1000);
  1019. }
  1020. if (i == i2c_timeout) {
  1021. print("i2cwrite: timeout\n");
  1022. return 0;
  1023. }
  1024. if ((intstat & intstat_i2crack) == 0)
  1025. return 0;
  1026. return 1;
  1027. }
  1028. static ulong *
  1029. riscpacked(ulong pa, int fnum, int w, int h, int stride, ulong **lastjmp)
  1030. {
  1031. ulong *p, *pbase;
  1032. int i;
  1033. pbase = p = (ulong *)malloc((h + 6) * 2 * sizeof(ulong));
  1034. assert(p);
  1035. assert(w <= 0x7FF);
  1036. *p++ = riscsync | riscsync_resync | riscsync_vre;
  1037. *p++ = 0;
  1038. *p++ = riscsync | riscsync_fm1;
  1039. *p++ = 0;
  1040. for (i = 0; i != h / 2; i++) {
  1041. *p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
  1042. *p++ = pa + i * 2 * stride;
  1043. }
  1044. *p++ = riscsync | riscsync_resync | riscsync_vro;
  1045. *p++ = 0;
  1046. *p++ = riscsync | riscsync_fm1;
  1047. *p++ = 0;
  1048. for (i = 0; i != h / 2; i++) {
  1049. *p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
  1050. *p++ = pa + (i * 2 + 1) * stride;
  1051. }
  1052. /* reset status. you really need two instructions ;-(. */
  1053. *p++ = riscjmp | (0xf << risclabelshift_reset);
  1054. *p++ = PADDR(p);
  1055. *p++ = riscjmp | riscirq | (fnum << risclabelshift_set);
  1056. *lastjmp = p;
  1057. return pbase;
  1058. }
  1059. static ulong *
  1060. riscplanar411(ulong pa, int fnum, int w, int h, ulong **lastjmp)
  1061. {
  1062. ulong *p, *pbase, Cw, Yw, Ch;
  1063. uchar *Ybase, *Cbbase, *Crbase;
  1064. int i, bitspp;
  1065. bitspp = 6;
  1066. assert(w * bitspp / 8 <= 0x7FF);
  1067. pbase = p = (ulong *)malloc((h + 6) * 5 * sizeof(ulong));
  1068. assert(p);
  1069. Yw = w;
  1070. Ybase = (uchar *)pa;
  1071. Cw = w >> 1;
  1072. Ch = h >> 1;
  1073. Cbbase = Ybase + Yw * h;
  1074. Crbase = Cbbase + Cw * Ch;
  1075. *p++ = riscsync | riscsync_resync | riscsync_vre;
  1076. *p++ = 0;
  1077. *p++ = riscsync | riscsync_fm3;
  1078. *p++ = 0;
  1079. for (i = 0; i != h / 2; i++) {
  1080. *p++ = riscwrite123 | Yw | riscwrite_sol | riscwrite_eol;
  1081. *p++ = (Cw << 16) | Cw;
  1082. *p++ = (ulong)(Ybase + i * 2 * Yw);
  1083. *p++ = (ulong)(Cbbase + i * Cw); /* Do not interlace */
  1084. *p++ = (ulong)(Crbase + i * Cw);
  1085. }
  1086. *p++ = riscsync | riscsync_resync | riscsync_vro;
  1087. *p++ = 0;
  1088. *p++ = riscsync | riscsync_fm3;
  1089. *p++ = 0;
  1090. for (i = 0; i != h / 2; i++) {
  1091. *p++ = riscwrite1s23 | Yw | riscwrite_sol | riscwrite_eol;
  1092. *p++ = (Cw << 16) | Cw;
  1093. *p++ = (ulong)(Ybase + (i * 2 + 1) * Yw);
  1094. }
  1095. /* reset status. you really need two instructions ;-(. */
  1096. *p++ = riscjmp | (0xf << risclabelshift_reset);
  1097. *p++ = PADDR(p);
  1098. *p++ = riscjmp | riscirq | (fnum << risclabelshift_set);
  1099. *lastjmp = p;
  1100. return pbase;
  1101. }
  1102. static ulong *
  1103. riscplanar422(ulong pa, int fnum, int w, int h, ulong **lastjmp)
  1104. {
  1105. ulong *p, *pbase, Cw, Yw;
  1106. uchar *Ybase, *Cbbase, *Crbase;
  1107. int i, bpp;
  1108. bpp = 2;
  1109. assert(w * bpp <= 0x7FF);
  1110. pbase = p = (ulong *)malloc((h + 6) * 5 * sizeof(ulong));
  1111. assert(p);
  1112. Yw = w;
  1113. Ybase = (uchar *)pa;
  1114. Cw = w >> 1;
  1115. Cbbase = Ybase + Yw * h;
  1116. Crbase = Cbbase + Cw * h;
  1117. *p++ = riscsync | riscsync_resync | riscsync_vre;
  1118. *p++ = 0;
  1119. *p++ = riscsync | riscsync_fm3;
  1120. *p++ = 0;
  1121. for (i = 0; i != h / 2; i++) {
  1122. *p++ = riscwrite123 | Yw | riscwrite_sol | riscwrite_eol;
  1123. *p++ = (Cw << 16) | Cw;
  1124. *p++ = (ulong)(Ybase + i * 2 * Yw);
  1125. *p++ = (ulong)(Cbbase + i * 2 * Cw);
  1126. *p++ = (ulong)(Crbase + i * 2 * Cw);
  1127. }
  1128. *p++ = riscsync | riscsync_resync | riscsync_vro;
  1129. *p++ = 0;
  1130. *p++ = riscsync | riscsync_fm3;
  1131. *p++ = 0;
  1132. for (i = 0; i != h / 2; i++) {
  1133. *p++ = riscwrite123 | Yw | riscwrite_sol | riscwrite_eol;
  1134. *p++ = (Cw << 16) | Cw;
  1135. *p++ = (ulong)(Ybase + (i * 2 + 1) * Yw);
  1136. *p++ = (ulong)(Cbbase + (i * 2 + 1) * Cw);
  1137. *p++ = (ulong)(Crbase + (i * 2 + 1) * Cw);
  1138. }
  1139. /* reset status. you really need two instructions ;-(. */
  1140. *p++ = riscjmp | (0xf << risclabelshift_reset);
  1141. *p++ = PADDR(p);
  1142. *p++ = riscjmp | riscirq | (fnum << risclabelshift_set);
  1143. *lastjmp = p;
  1144. return pbase;
  1145. }
  1146. static ulong *
  1147. riscaudio(ulong pa, int nblocks, int bsize)
  1148. {
  1149. ulong *p, *pbase;
  1150. int i;
  1151. pbase = p = (ulong *)malloc((nblocks + 3) * 2 * sizeof(ulong));
  1152. assert(p);
  1153. *p++ = riscsync|riscsync_fm1;
  1154. *p++ = 0;
  1155. for (i = 0; i != nblocks; i++) {
  1156. *p++ = riscwrite | riscwrite_sol | riscwrite_eol | bsize | riscirq |
  1157. ((i & 0xf) << risclabelshift_set) |
  1158. ((~i & 0xf) << risclabelshift_reset);
  1159. *p++ = pa + i * bsize;
  1160. }
  1161. *p++ = riscsync | riscsync_vro;
  1162. *p++ = 0;
  1163. *p++ = riscjmp;
  1164. *p++ = PADDR(pbase);
  1165. USED(p);
  1166. return pbase;
  1167. }
  1168. static void
  1169. vactivate(Tv *tv, Frame *frames, int nframes)
  1170. {
  1171. Bt848 *bt848 = tv->bt848;
  1172. ilock(tv);
  1173. if (tv->frames) {
  1174. iunlock(tv);
  1175. error(Einuse);
  1176. }
  1177. poperror();
  1178. tv->frames = frames;
  1179. tv->nframes = nframes;
  1180. bt848->riscstrtadd = PADDR(tv->frames[0].fstart);
  1181. bt848->capctl |= capctl_captureodd|capctl_captureeven;
  1182. bt848->gpiodmactl |= gpiodmactl_fifoenable;
  1183. bt848->gpiodmactl |= gpiodmactl_riscenable;
  1184. iunlock(tv);
  1185. }
  1186. static void
  1187. vstart(Tv *tv, int nframes, int w, int h, int stride)
  1188. {
  1189. Frame *frames;
  1190. int bitspp, i, bpf;
  1191. if (nframes >= 0x10)
  1192. error(Ebadarg);
  1193. bitspp = getbitspp(tv);
  1194. bpf = w * h * bitspp / 8;
  1195. /* Add one as a spare. */
  1196. frames = (Frame *)malloc(nframes * sizeof(Frame));
  1197. assert(frames);
  1198. if (waserror()) {
  1199. for (i = 0; i != nframes; i++)
  1200. if (frames[i].fbase)
  1201. free(frames[i].fbase);
  1202. free(frames);
  1203. nexterror();
  1204. }
  1205. memset(frames, 0, nframes * sizeof(Frame));
  1206. for (i = 0; i != nframes; i++) {
  1207. if ((frames[i].fbase = (uchar *)malloc(bpf)) == nil)
  1208. error(Enomem);
  1209. switch (tv->cfmt) {
  1210. case colorfmt_YCbCr422:
  1211. frames[i].fstart = riscplanar422(PADDR(frames[i].fbase), i, w, h, &frames[i].fjmp);
  1212. break;
  1213. case colorfmt_YCbCr411:
  1214. frames[i].fstart = riscplanar411(PADDR(frames[i].fbase),
  1215. i, w, h, &frames[i].fjmp);
  1216. break;
  1217. case colorfmt_rgb16:
  1218. frames[i].fstart = riscpacked(PADDR(frames[i].fbase), i,
  1219. w * bitspp / 8, h, stride * bitspp / 8,
  1220. &frames[i].fjmp);
  1221. break;
  1222. default:
  1223. panic("vstart: Unsupport colorformat\n");
  1224. }
  1225. }
  1226. for (i = 0; i != nframes; i++)
  1227. *frames[i].fjmp = PADDR(i == nframes - 1? frames[0].fstart:
  1228. frames[i + 1].fstart);
  1229. vactivate(tv, frames, nframes);
  1230. }
  1231. static void
  1232. astart(Tv *tv, char *input, uint rate, uint nab, uint nasz)
  1233. {
  1234. Bt848 *bt878 = tv->bt878;
  1235. ulong *arisc;
  1236. int selector;
  1237. uchar *abuf;
  1238. int s, d;
  1239. if (bt878 == nil || tv->amux == nil)
  1240. error("#V: Card does not support audio");
  1241. selector = 0;
  1242. if (!strcmp(input, "tv"))
  1243. selector = asel_tv;
  1244. else if (!strcmp(input, "radio"))
  1245. selector = asel_radio;
  1246. else if (!strcmp(input, "mic"))
  1247. selector = asel_mic;
  1248. else if (!strcmp(input, "smxc"))
  1249. selector = asel_smxc;
  1250. else
  1251. error("#V: Invalid input");
  1252. if (nasz > 0xfff)
  1253. error("#V: Audio block size too big (max 0xfff)");
  1254. abuf = (uchar *)malloc(nab * nasz * sizeof(uchar));
  1255. assert(abuf);
  1256. arisc = riscaudio(PADDR(abuf), nab, nasz);
  1257. ilock(tv);
  1258. if (tv->arisc) {
  1259. iunlock(tv);
  1260. free(abuf);
  1261. free(arisc);
  1262. error(Einuse);
  1263. }
  1264. tv->arisc = arisc;
  1265. tv->abuf = abuf;
  1266. tv->nablocks = nab;
  1267. tv->absize = nasz;
  1268. bt878->riscstrtadd = PADDR(tv->arisc);
  1269. bt878->packetlen = (nab << 16) | nasz;
  1270. bt878->intmask = intstat_scerr | intstat_ocerr | intstat_risci |
  1271. intstat_pabort | intstat_riperr | intstat_pperr |
  1272. intstat_fdsr | intstat_ftrgt | intstat_fbus;
  1273. /* Assume analog, 16bpp */
  1274. for (s = 0; s < 16; s++)
  1275. if (rate << s > Hwbase_ad * 4 / 15)
  1276. break;
  1277. for (d = 15; d >= 4; d--)
  1278. if (rate << s < Hwbase_ad * 4 / d)
  1279. break;
  1280. print("astart: sampleshift %d, decimation %d\n", s, d);
  1281. tv->narblocks = 0;
  1282. bt878->gpiodmactl = gpiodmactl_fifoenable |
  1283. gpiodmactl_riscenable | gpiodmactl_acapenable |
  1284. gpiodmactl_daes2 | /* gpiodmactl_apwrdn | */
  1285. gpiodmactl_daiomda | d << 8 | 9 << 28 | selector << 24;
  1286. print("dmactl %.8ulX\n", bt878->gpiodmactl);
  1287. iunlock(tv);
  1288. }
  1289. static void
  1290. astop(Tv *tv)
  1291. {
  1292. Bt848 *bt878 = tv->bt878;
  1293. ilock(tv);
  1294. if (tv->aref.ref > 0) {
  1295. iunlock(tv);
  1296. error(Einuse);
  1297. }
  1298. if (tv->abuf) {
  1299. bt878->gpiodmactl &= ~gpiodmactl_riscenable;
  1300. bt878->gpiodmactl &= ~gpiodmactl_fifoenable;
  1301. free(tv->abuf);
  1302. tv->abuf = nil;
  1303. free(tv->arisc);
  1304. tv->arisc = nil;
  1305. }
  1306. iunlock(tv);
  1307. }
  1308. static void
  1309. vgastart(Tv *tv, ulong pa, int stride)
  1310. {
  1311. Frame *frame;
  1312. frame = (Frame *)malloc(sizeof(Frame));
  1313. assert(frame);
  1314. if (waserror()) {
  1315. free(frame);
  1316. nexterror();
  1317. }
  1318. frame->fbase = nil;
  1319. frame->fstart = riscpacked(pa, 0, ntsc_hactive * getbitspp(tv) / 8,
  1320. ntsc_vactive, stride * getbitspp(tv) / 8, &frame->fjmp);
  1321. *frame->fjmp = PADDR(frame->fstart);
  1322. vactivate(tv, frame, 1);
  1323. }
  1324. static void
  1325. vstop(Tv *tv)
  1326. {
  1327. Bt848 *bt848 = tv->bt848;
  1328. ilock(tv);
  1329. if (tv->fref.ref > 0) {
  1330. iunlock(tv);
  1331. error(Einuse);
  1332. }
  1333. if (tv->frames) {
  1334. int i;
  1335. bt848->gpiodmactl &= ~gpiodmactl_riscenable;
  1336. bt848->gpiodmactl &= ~gpiodmactl_fifoenable;
  1337. bt848->capctl &= ~(capctl_captureodd|capctl_captureeven);
  1338. for (i = 0; i != tv->nframes; i++)
  1339. if (tv->frames[i].fbase)
  1340. free(tv->frames[i].fbase);
  1341. free(tv->frames);
  1342. tv->frames = nil;
  1343. }
  1344. iunlock(tv);
  1345. }
  1346. static long hrcfreq[] = { /* HRC CATV frequencies */
  1347. 0, 7200, 5400, 6000, 6600, 7800, 8400, 17400,
  1348. 18000, 18600, 19200, 19800, 20400, 21000, 12000, 12600,
  1349. 13200, 13800, 14400, 15000, 15600, 16200, 16800, 21600,
  1350. 22200, 22800, 23400, 24000, 24600, 25200, 25800, 26400,
  1351. 27000, 27600, 28200, 28800, 29400, 30000, 30600, 31200,
  1352. 31800, 32400, 33000, 33600, 34200, 34800, 35400, 36000,
  1353. 36600, 37200, 37800, 38400, 39000, 39600, 40200, 40800,
  1354. 41400, 42000, 42600, 43200, 43800, 44400, 45000, 45600,
  1355. 46200, 46800, 47400, 48000, 48600, 49200, 49800, 50400,
  1356. 51000, 51600, 52200, 52800, 53400, 54000, 54600, 55200,
  1357. 55800, 56400, 57000, 57600, 58200, 58800, 59400, 60000,
  1358. 60600, 61200, 61800, 62400, 63000, 63600, 64200, 9000,
  1359. 9600, 10200, 10800, 11400, 64800, 65400, 66000, 66600,
  1360. 67200, 67800, 68400, 69000, 69600, 70200, 70800, 71400,
  1361. 72000, 72600, 73200, 73800, 74400, 75000, 75600, 76200,
  1362. 76800, 77400, 78000, 78600, 79200, 79800,
  1363. };
  1364. static void
  1365. frequency(Tv *tv, int channel, int finetune)
  1366. {
  1367. Tuner *tuner = tv->tuner;
  1368. long freq;
  1369. ushort div;
  1370. uchar cfg;
  1371. if (channel < 0 || channel > nelem(hrcfreq))
  1372. error(Ebadarg);
  1373. freq = (hrcfreq[channel] * Freqmultiplier) / 100;
  1374. if (freq < tuner->freq_vhfh)
  1375. cfg = tuner->VHF_L;
  1376. else if (freq < tuner->freq_uhf)
  1377. cfg = tuner->VHF_H;
  1378. else
  1379. cfg = tuner->UHF;
  1380. div = (freq + tuner->offs + finetune) & 0x7fff;
  1381. if (!i2cwrite(tv, tv->i2ctuneraddr, (div >> 8) & 0x7f, div, 1))
  1382. error(Eio);
  1383. if (!i2cwrite(tv, tv->i2ctuneraddr, tuner->cfg, cfg, 1))
  1384. error(Eio);
  1385. tv->channel = channel;
  1386. if (tv->msp)
  1387. msptune(tv);
  1388. }
  1389. static struct {
  1390. char *cmode;
  1391. ulong realmode;
  1392. ulong cbits;
  1393. } colormodes[] = {
  1394. { "RGB16", colorfmt_rgb16, colorfmt_rgb16, },
  1395. { "YCbCr422", colorfmt_YCbCr422, colorfmt_YCbCr422, },
  1396. { "YCbCr411", colorfmt_YCbCr411, colorfmt_YCbCr422, },
  1397. };
  1398. static void
  1399. colormode(Tv *tv, char *colormode)
  1400. {
  1401. Bt848 *bt848 = tv->bt848;
  1402. int i;
  1403. for (i = 0; i != nelem(colormodes); i++)
  1404. if (!strcmp(colormodes[i].cmode, colormode))
  1405. break;
  1406. if (i == nelem(colormodes))
  1407. error(Ebadarg);
  1408. tv->cfmt = colormodes[i].realmode;
  1409. bt848->colorfmt = colormodes[i].cbits;
  1410. }
  1411. static int
  1412. getbitspp(Tv *tv)
  1413. {
  1414. switch (tv->cfmt) {
  1415. case colorfmt_rgb16:
  1416. case colorfmt_YCbCr422:
  1417. return 16;
  1418. case colorfmt_YCbCr411:
  1419. return 12;
  1420. default:
  1421. error("getbitspp: Unsupport color format\n");
  1422. }
  1423. return -1;
  1424. }
  1425. static char *
  1426. getcolormode(ulong cmode)
  1427. {
  1428. switch (cmode) {
  1429. case colorfmt_rgb16:
  1430. return "RGB16";
  1431. case colorfmt_YCbCr411:
  1432. return "YCbCr411";
  1433. case colorfmt_YCbCr422:
  1434. return (cmode == colorfmt_YCbCr422)? "YCbCr422": "YCbCr411";
  1435. default:
  1436. error("getcolormode: Unsupport color format\n");
  1437. }
  1438. return nil;
  1439. }
  1440. static void
  1441. i2c_set(Tv *tv, int scl, int sda)
  1442. {
  1443. Bt848 *bt848 = tv->bt848;
  1444. ulong d;
  1445. bt848->i2c = (scl << 1) | sda;
  1446. d = bt848->i2c;
  1447. USED(d);
  1448. microdelay(i2c_delay);
  1449. }
  1450. static uchar
  1451. i2c_getsda(Tv *tv)
  1452. {
  1453. Bt848 *bt848 = tv->bt848;
  1454. return bt848->i2c & i2c_sda;
  1455. }
  1456. static void
  1457. i2c_start(Tv *tv)
  1458. {
  1459. i2c_set(tv, 0, 1);
  1460. i2c_set(tv, 1, 1);
  1461. i2c_set(tv, 1, 0);
  1462. i2c_set(tv, 0, 0);
  1463. }
  1464. static void
  1465. i2c_stop(Tv *tv)
  1466. {
  1467. i2c_set(tv, 0, 0);
  1468. i2c_set(tv, 1, 0);
  1469. i2c_set(tv, 1, 1);
  1470. }
  1471. static void
  1472. i2c_bit(Tv *tv, int sda)
  1473. {
  1474. i2c_set(tv, 0, sda);
  1475. i2c_set(tv, 1, sda);
  1476. i2c_set(tv, 0, sda);
  1477. }
  1478. static int
  1479. i2c_getack(Tv *tv)
  1480. {
  1481. int ack;
  1482. i2c_set(tv, 0, 1);
  1483. i2c_set(tv, 1, 1);
  1484. ack = i2c_getsda(tv);
  1485. i2c_set(tv, 0, 1);
  1486. return ack;
  1487. }
  1488. static int
  1489. i2c_wr8(Tv *tv, uchar d, int wait)
  1490. {
  1491. int i, ack;
  1492. i2c_set(tv, 0, 0);
  1493. for (i = 0; i != 8; i++) {
  1494. i2c_bit(tv, (d & 0x80)? 1: 0);
  1495. d <<= 1;
  1496. }
  1497. if (wait)
  1498. microdelay(wait);
  1499. ack = i2c_getack(tv);
  1500. return ack == 0;
  1501. }
  1502. static uchar
  1503. i2c_rd8(Tv *tv, int lastbyte)
  1504. {
  1505. int i;
  1506. uchar d;
  1507. d = 0;
  1508. i2c_set(tv, 0, 1);
  1509. for (i = 0; i != 8; i++) {
  1510. i2c_set(tv, 1, 1);
  1511. d <<= 1;
  1512. if (i2c_getsda(tv))
  1513. d |= 1;
  1514. i2c_set(tv, 0, 1);
  1515. }
  1516. i2c_bit(tv, lastbyte? 1: 0);
  1517. return d;
  1518. }
  1519. static int
  1520. mspsend(Tv *tv, uchar *cmd, int ncmd)
  1521. {
  1522. int i, j, delay;
  1523. for (i = 0; i != 3; i++) {
  1524. delay = 2000;
  1525. i2c_start(tv);
  1526. for (j = 0; j != ncmd; j++) {
  1527. if (!i2c_wr8(tv, cmd[j], delay))
  1528. break;
  1529. delay = 0;
  1530. }
  1531. i2c_stop(tv);
  1532. if (j == ncmd)
  1533. return 1;
  1534. microdelay(10000);
  1535. print("mspsend: retrying\n");
  1536. }
  1537. return 0;
  1538. }
  1539. static int
  1540. mspwrite(Tv *tv, uchar sub, ushort reg, ushort v)
  1541. {
  1542. uchar b[6];
  1543. b[0] = i2c_msp3400;
  1544. b[1] = sub;
  1545. b[2] = reg >> 8;
  1546. b[3] = reg;
  1547. b[4] = v >> 8;
  1548. b[5] = v;
  1549. return mspsend(tv, b, sizeof b);
  1550. }
  1551. static int
  1552. mspread(Tv *tv, uchar sub, ushort reg, ushort *data)
  1553. {
  1554. uchar b[4];
  1555. int i;
  1556. b[0] = i2c_msp3400;
  1557. b[1] = sub;
  1558. b[2] = reg >> 8;
  1559. b[3] = reg;
  1560. for (i = 0; i != 3; i++) {
  1561. i2c_start(tv);
  1562. if (!i2c_wr8(tv, b[0], 2000) ||
  1563. !i2c_wr8(tv, b[1] | 1, 0) ||
  1564. !i2c_wr8(tv, b[2], 0) ||
  1565. !i2c_wr8(tv, b[3], 0)) {
  1566. i2c_stop(tv);
  1567. microdelay(10000);
  1568. print("retrying\n");
  1569. continue;
  1570. }
  1571. i2c_start(tv);
  1572. if (!i2c_wr8(tv, b[0] | 1, 2000)) {
  1573. i2c_stop(tv);
  1574. continue;
  1575. }
  1576. *data = i2c_rd8(tv, 0) << 8;
  1577. *data |= i2c_rd8(tv, 1);
  1578. i2c_stop(tv);
  1579. return 1;
  1580. }
  1581. return 0;
  1582. }
  1583. static uchar mspt_reset[] = { i2c_msp3400, 0, 0x80, 0 };
  1584. static uchar mspt_on[] = { i2c_msp3400, 0, 0, 0 };
  1585. static int
  1586. mspreset(Tv *tv)
  1587. {
  1588. ushort v, p;
  1589. Bt848 *bt848 = tv->bt848;
  1590. ulong b;
  1591. b = 1 << 5;
  1592. gpioenable(tv, ~b, b);
  1593. gpiowrite(tv, ~b, 0);
  1594. microdelay(2500);
  1595. gpiowrite(tv, ~b, b);
  1596. bt848->i2c = 0x80;
  1597. microdelay(2000);
  1598. mspsend(tv, mspt_reset, sizeof mspt_reset);
  1599. microdelay(2000);
  1600. if (!mspsend(tv, mspt_on, sizeof mspt_on)) {
  1601. print("#V: Cannot find MSP34x5G on the I2C bus (on)\n");
  1602. return 0;
  1603. }
  1604. microdelay(2000);
  1605. if (!mspread(tv, msp_bbp, 0x001e, &v)) {
  1606. print("#V: Cannot read MSP34xG5 chip version\n");
  1607. return 0;
  1608. }
  1609. if (!mspread(tv, msp_bbp, 0x001f, &p)) {
  1610. print("#V: Cannot read MSP34xG5 product code\n");
  1611. return 0;
  1612. }
  1613. print("#V: MSP34%dg ROM %.d, %d.%d\n",
  1614. (uchar)(p >> 8), (uchar)p, (uchar)(v >> 8), (uchar)v);
  1615. tv->msp = 1;
  1616. return 1;
  1617. }
  1618. static void
  1619. mspvolume(Tv *tv, int mute, int l, int r)
  1620. {
  1621. short v, d;
  1622. ushort b;
  1623. if (mute) {
  1624. v = 0;
  1625. b = 0;
  1626. }
  1627. else {
  1628. tv->aleft = l;
  1629. tv->aright = r;
  1630. d = v = max(l, r);
  1631. if (d == 0)
  1632. d++;
  1633. b = ((r - l) * 0x7f) / d;
  1634. }
  1635. mspwrite(tv, msp_bbp, 0, v << 8);
  1636. mspwrite(tv, msp_bbp, 7, v? 0x4000: 0);
  1637. mspwrite(tv, msp_bbp, 1, b << 8);
  1638. }
  1639. static char *
  1640. mspaformat(int f)
  1641. {
  1642. switch (f) {
  1643. case 0:
  1644. return "unknown";
  1645. case 2:
  1646. case 0x20:
  1647. case 0x30:
  1648. return "M-BTSC";
  1649. case 3:
  1650. return "B/G-FM";
  1651. case 4:
  1652. case 9:
  1653. case 0xB:
  1654. return "L-AM/NICAM D/Kn";
  1655. case 8:
  1656. return "B/G-NICAM";
  1657. case 0xA:
  1658. return "I";
  1659. case 0x40:
  1660. return "FM-Radio";
  1661. }
  1662. return "unknown format";
  1663. }
  1664. static void
  1665. msptune(Tv *tv)
  1666. {
  1667. ushort d, s, nicam;
  1668. int i;
  1669. mspvolume(tv, 1, 0, 0);
  1670. if (!mspwrite(tv, msp_dem, 0x0030, 0x2033))
  1671. error("#V: Cannot set MODUS register");
  1672. if (!mspwrite(tv, msp_bbp, 0x0008, 0x0320))
  1673. error("#V: Cannot set loadspeaker input");
  1674. if (!mspwrite(tv, msp_dem, 0x0040, 0x0001))
  1675. error("#V: Cannot set I2S clock freq");
  1676. if (!mspwrite(tv, msp_bbp, 0x000d, 0x1900))
  1677. error("#V: Cannot set SCART prescale");
  1678. if (!mspwrite(tv, msp_bbp, 0x000e, 0x2403))
  1679. error("#V: Cannot set FM/AM prescale");
  1680. if (!mspwrite(tv, msp_bbp, 0x0010, 0x5a00))
  1681. error("#V: Cannot set NICAM prescale");
  1682. if (!mspwrite(tv, msp_dem, 0x0020, 0x0001))
  1683. error("#V: Cannot start auto detect");
  1684. for (d = (ushort)-1, i = 0; i != 10; i++) {
  1685. if (!mspread(tv, msp_dem, 0x007e, &d))
  1686. error("#V: Cannot get autodetect info MSP34xG5");
  1687. if (d == 0 || d < 0x800)
  1688. break;
  1689. delay(50);
  1690. }
  1691. if (!mspread(tv, msp_dem, 0x0200, &s))
  1692. error("#V: Cannot get status info MSP34xG5");
  1693. mspvolume(tv, 0, tv->aleft, tv->aright);
  1694. nicam = ((s >> 4) & 2) | ((s >> 9) & 1);
  1695. snprint(tv->ainfo, sizeof tv->ainfo, "%s %s %s",
  1696. mspaformat(d), (s & (1 << 6))? "stereo": "mono",
  1697. nicamstate[nicam]);
  1698. }
  1699. static void
  1700. i2cscan(Tv *tv)
  1701. {
  1702. int i, ack;
  1703. for (i = 0; i < 0x100; i += 2) {
  1704. i2c_start(tv);
  1705. ack = i2c_wr8(tv, i, 0);
  1706. i2c_stop(tv);
  1707. if (ack)
  1708. print("i2c device @%.2uX\n", i);
  1709. }
  1710. for (i = 0xf0; i != 0xff; i++) {
  1711. i2c_start(tv);
  1712. ack = i2c_wr8(tv, i, 0);
  1713. i2c_stop(tv);
  1714. if (ack)
  1715. print("i2c device may be at @%.2uX\n", i);
  1716. }
  1717. }
  1718. static void
  1719. gpioenable(Tv *tv, ulong mask, ulong data)
  1720. {
  1721. Bt848 *bt848 = tv->bt848;
  1722. bt848->gpioouten = (bt848->gpioouten & mask) | data;
  1723. }
  1724. static void
  1725. gpiowrite(Tv *tv, ulong mask, ulong data)
  1726. {
  1727. Bt848 *bt848 = tv->bt848;
  1728. bt848->gpiodata[0] = (bt848->gpiodata[0] & mask) | data;
  1729. }
  1730. static void
  1731. alteraoutput(Tv *tv)
  1732. {
  1733. if (tv->gpiostate == Gpiooutput)
  1734. return;
  1735. gpioenable(tv, ~0xffffff, 0x56ffff);
  1736. microdelay(10);
  1737. tv->gpiostate = Gpiooutput;
  1738. }
  1739. static void
  1740. alterainput(Tv *tv)
  1741. {
  1742. if (tv->gpiostate == Gpioinput)
  1743. return;
  1744. gpioenable(tv, ~0xffffff, 0x570000);
  1745. microdelay(10);
  1746. tv->gpiostate = Gpioinput;
  1747. }
  1748. static void
  1749. alterareg(Tv *tv, ulong reg)
  1750. {
  1751. if (tv->alterareg == reg)
  1752. return;
  1753. gpiowrite(tv, ~0x56ffff, (reg & 0x54ffff) | tv->alteraclock);
  1754. microdelay(10);
  1755. tv->alterareg = reg;
  1756. }
  1757. static void
  1758. alterawrite(Tv *tv, ulong reg, ushort data)
  1759. {
  1760. alteraoutput(tv);
  1761. alterareg(tv, reg);
  1762. tv->alteraclock ^= 0x20000;
  1763. gpiowrite(tv, ~0x56ffff, (reg & 0x540000) | data | tv->alteraclock);
  1764. microdelay(10);
  1765. }
  1766. static void
  1767. alteraread(Tv *tv, int reg, ushort *data)
  1768. {
  1769. Bt848 *bt848 = tv->bt848;
  1770. if (tv->alterareg != reg) {
  1771. alteraoutput(tv);
  1772. alterareg(tv, reg);
  1773. }
  1774. else {
  1775. gpioenable(tv, ~0xffffff, 0x560000);
  1776. microdelay(10);
  1777. }
  1778. alterainput(tv);
  1779. gpiowrite(tv, ~0x570000, (reg & 0x560000) | tv->alteraclock);
  1780. microdelay(10);
  1781. *data = (ushort)bt848->gpiodata[0];
  1782. microdelay(10);
  1783. }
  1784. static void
  1785. kfirloadu(Tv *tv, uchar *u, int ulen)
  1786. {
  1787. Bt848 *bt848 = tv->bt848;
  1788. int i, j;
  1789. ilock(&tv->kfirlock);
  1790. bt848->gpioouten &= 0xff000000;
  1791. bt848->gpioouten |= gpio_altera_data |
  1792. gpio_altera_clock | gpio_altera_nconfig;
  1793. bt848->gpiodata[0] &= 0xff000000;
  1794. microdelay(10);
  1795. bt848->gpiodata[0] |= gpio_altera_nconfig;
  1796. microdelay(10);
  1797. /* Download the microcode */
  1798. for (i = 0; i != ulen; i++)
  1799. for (j = 0; j != 8; j++) {
  1800. bt848->gpiodata[0] &= ~(gpio_altera_clock|gpio_altera_data);
  1801. if (u[i] & 1)
  1802. bt848->gpiodata[0] |= gpio_altera_data;
  1803. bt848->gpiodata[0] |= gpio_altera_clock;
  1804. u[i] >>= 1;
  1805. }
  1806. bt848->gpiodata[0] &= ~gpio_altera_clock;
  1807. microdelay(100);
  1808. /* Initialize. */
  1809. for (i = 0; i != 30; i++) {
  1810. bt848->gpiodata[0] &= ~gpio_altera_clock;
  1811. bt848->gpiodata[0] |= gpio_altera_clock;
  1812. }
  1813. bt848->gpiodata[0] &= ~(gpio_altera_clock|gpio_altera_data);
  1814. iunlock(&tv->kfirlock);
  1815. tv->gpiostate = Gpioinit;
  1816. }
  1817. static void
  1818. kfirreset(Tv *tv)
  1819. {
  1820. alterawrite(tv, 0, 0);
  1821. microdelay(10);
  1822. alterawrite(tv, 0x40000, 0);
  1823. microdelay(10);
  1824. alterawrite(tv, 0x40006, 0x80);
  1825. microdelay(10);
  1826. alterawrite(tv, 8, 1);
  1827. microdelay(10);
  1828. alterawrite(tv, 0x40004, 2);
  1829. microdelay(10);
  1830. alterawrite(tv, 4, 3);
  1831. microdelay(3);
  1832. }
  1833. static int
  1834. kfirinitialize(Tv *tv)
  1835. {
  1836. /* Initialize parameters? */
  1837. tv->gpiostate = Gpioinit;
  1838. tv->alterareg = -1;
  1839. tv->alteraclock = 0x20000;
  1840. kfirloadu(tv, hcwAMC, sizeof hcwAMC);
  1841. kfirreset(tv);
  1842. return 1;
  1843. }