devtv.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197
  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 {
  212. ushort vid;
  213. ushort did;
  214. char *name;
  215. } Variant;
  216. typedef struct {
  217. ulong devstat; // 000
  218. ulong iform; // 004
  219. ulong tdec; // 008
  220. ulong ecrop; // 00C
  221. ulong evdelaylo; // 010
  222. ulong evactivelo; // 014
  223. ulong ehdelaylo; // 018
  224. ulong ehactivelo; // 01C
  225. ulong ehscalehi; // 020
  226. ulong ehscalelo; // 024
  227. ulong bright; // 028
  228. ulong econtrol; // 02C
  229. ulong contrastlo; // 030
  230. ulong satulo; // 034
  231. ulong satvlo; // 038
  232. ulong hue; // 03C
  233. ulong escloop; // 040
  234. ulong pad0; // 044
  235. ulong oform; // 048
  236. ulong evscalehi; // 04C
  237. ulong evscalelo; // 050
  238. ulong test; // 054
  239. ulong pad1[2]; // 058-05C
  240. ulong adelay; // 060
  241. ulong bdelay; // 064
  242. ulong adc; // 068
  243. ulong evtc; // 06C
  244. ulong pad2[3]; // 070-078
  245. ulong sreset; // 07C
  246. ulong tglb; // 080
  247. ulong tgctrl; // 084
  248. ulong pad3; // 088
  249. ulong ocrop; // 08C
  250. ulong ovdelaylo; // 090
  251. ulong ovactivelo; // 094
  252. ulong ohdelaylo; // 098
  253. ulong ohactivelo; // 09C
  254. ulong ohscalehi; // 0A0
  255. ulong ohscalelo; // 0A4
  256. ulong pad4; // 0A8
  257. ulong ocontrol; // 0AC
  258. ulong pad5[4]; // 0B0-0BC
  259. ulong oscloop; // 0C0
  260. ulong pad6[2]; // 0C4-0C8
  261. ulong ovscalehi; // 0CC
  262. ulong ovscalelo; // 0D0
  263. ulong colorfmt; // 0D4
  264. ulong colorctl; // 0D8
  265. ulong capctl; // 0DC
  266. ulong vbipacksize; // 0E0
  267. ulong vbipackdel; // 0E4
  268. ulong fcap; // 0E8
  269. ulong ovtc; // 0EC
  270. ulong pllflo; // 0F0
  271. ulong pllfhi; // 0F4
  272. ulong pllxci; // 0F8
  273. ulong dvsif; // 0FC
  274. ulong intstat; // 100
  275. ulong intmask; // 104
  276. ulong pad7; // 108
  277. ulong gpiodmactl; // 10C
  278. ulong i2c; // 110
  279. ulong riscstrtadd; // 114
  280. ulong gpioouten; // 118
  281. ulong gpioreginp; // 11C
  282. ulong risccount; // 120
  283. ulong pad8[55]; // 124-1FC
  284. ulong gpiodata[64]; // 200-2FC
  285. } Bt848;
  286. #define packetlen i2c
  287. typedef struct {
  288. char *name;
  289. ushort freq_vhfh; // Start frequency
  290. ushort freq_uhf;
  291. uchar VHF_L;
  292. uchar VHF_H;
  293. uchar UHF;
  294. uchar cfg;
  295. ushort offs;
  296. } Tuner;
  297. typedef struct {
  298. ulong *fstart;
  299. ulong *fjmp;
  300. uchar *fbase;
  301. } Frame;
  302. typedef struct {
  303. Lock;
  304. Rendez;
  305. Bt848 *bt848;
  306. Bt848 *bt878; // Really only audio control registers
  307. Variant *variant;
  308. Tuner *tuner;
  309. Pcidev *pci;
  310. uchar i2ctuneraddr;
  311. uchar i2ccmd; // I2C command
  312. int board; // What board is this?
  313. ulong cfmt; // Current color format.
  314. int channel; // Current channel
  315. Ref fref; // Copying images?
  316. int nframes; // Number of frames to capture.
  317. Frame *frames; // DMA program
  318. int lvframe; // Last video frame DMAed
  319. uchar *amux; // Audio multiplexer.
  320. int nablocks; // Number of audio blocks allocated
  321. int absize; // Audio block size
  322. int narblocks; // Number of audio blocks received
  323. ulong *arisc; // Audio risc bloc
  324. uchar *abuf; // Audio data buffers
  325. char ainfo[128];
  326. // WinTV/PVR stuff.
  327. int msp;
  328. Lock kfirlock;
  329. ulong i2cstate; // Last i2c state.
  330. int gpiostate; // Current GPIO state
  331. ulong alterareg; // Last used altera register
  332. ulong alteraclock; // Used to clock the altera
  333. int asrate; // Audio sample rate
  334. uchar aleft, aright; // Left and right audio volume
  335. ulong kfirclock;
  336. Ref aref; // Copying audio?
  337. } Tv;
  338. enum {
  339. TemicPAL = 0,
  340. PhilipsPAL,
  341. PhilipsNTSC,
  342. PhilipsSECAM,
  343. Notuner,
  344. PhilipsPALI,
  345. TemicNTSC,
  346. TemicPALI,
  347. Temic4036,
  348. AlpsTSBH1,
  349. AlpsTSBE1,
  350. Freqmultiplier = 16,
  351. };
  352. static Tuner tuners[] = {
  353. {"Temic PAL", Freqmultiplier * 140.25, Freqmultiplier * 463.25,
  354. 0x02, 0x04, 0x01, 0x8e, 623 },
  355. {"Philips PAL_I", Freqmultiplier * 140.25, Freqmultiplier * 463.25,
  356. 0xa0, 0x90, 0x30, 0x8e, 623 },
  357. {"Philips NTSC", Freqmultiplier * 157.25, Freqmultiplier * 451.25,
  358. 0xA0, 0x90, 0x30, 0x8e, 732 },
  359. {"Philips SECAM", Freqmultiplier * 168.25, Freqmultiplier * 447.25,
  360. 0xA7, 0x97, 0x37, 0x8e, 623 },
  361. {"NoTuner", 0, 0,
  362. 0x00, 0x00, 0x00, 0x00, 0 },
  363. {"Philips PAL", Freqmultiplier * 168.25, Freqmultiplier * 447.25,
  364. 0xA0, 0x90, 0x30, 0x8e, 623 },
  365. {"Temic NTSC", Freqmultiplier * 157.25, Freqmultiplier * 463.25,
  366. 0x02, 0x04, 0x01, 0x8e, 732 },
  367. {"TEMIC PAL_I", Freqmultiplier * 170.00, Freqmultiplier * 450.00,
  368. 0x02, 0x04, 0x01, 0x8e, 623 },
  369. {"Temic 4036 FY5 NTSC", Freqmultiplier * 157.25, Freqmultiplier * 463.25,
  370. 0xa0, 0x90, 0x30, 0x8e, 732 },
  371. {"Alps TSBH1", Freqmultiplier * 137.25, Freqmultiplier * 385.25,
  372. 0x01, 0x02, 0x08, 0x8e, 732 },
  373. {"Alps TSBE1", Freqmultiplier * 137.25, Freqmultiplier * 385.25,
  374. 0x01, 0x02, 0x08, 0x8e, 732 },
  375. };
  376. static int hp_tuners[] = {
  377. Notuner,
  378. Notuner,
  379. Notuner,
  380. Notuner,
  381. Notuner,
  382. PhilipsNTSC,
  383. Notuner,
  384. Notuner,
  385. PhilipsPAL,
  386. PhilipsSECAM,
  387. PhilipsNTSC,
  388. PhilipsPALI,
  389. Notuner,
  390. Notuner,
  391. TemicPAL,
  392. TemicPALI,
  393. Notuner,
  394. PhilipsSECAM,
  395. PhilipsNTSC,
  396. PhilipsPALI,
  397. Notuner,
  398. PhilipsPAL,
  399. Notuner,
  400. PhilipsNTSC,
  401. };
  402. enum {
  403. CMvstart,
  404. CMastart,
  405. CMastop,
  406. CMvgastart,
  407. CMvstop,
  408. CMchannel,
  409. CMcolormode,
  410. CMvolume,
  411. CMmute,
  412. };
  413. static Cmdtab tvctlmsg[] = {
  414. CMvstart, "vstart", 2,
  415. CMastart, "astart", 5,
  416. CMastop, "astop", 1,
  417. CMvgastart, "vgastart", 3,
  418. CMvstop, "vstop", 1,
  419. CMchannel, "channel", 3,
  420. CMcolormode, "colormode", 2,
  421. CMvolume, "volume", 3,
  422. CMmute, "mute", 1,
  423. };
  424. static Variant variant[] = {
  425. { Brooktree_vid, Brooktree_848_did, "Brooktree 848 TV tuner", },
  426. { Brooktree_vid, Brooktree_878_did, "Brooktree 878 TV tuner", },
  427. };
  428. static char *boards[] = {
  429. "MIRO PRO",
  430. "MIRO",
  431. "Hauppauge Bt878",
  432. };
  433. static ushort Adspfsample[] = {
  434. 0x500, 0x700, 0x400, 0x600, 0x300, 0x200, 0x000, 0x100
  435. };
  436. static ushort Adspstereorates[] = {
  437. 64, 96, 112, 128, 160, 192, 224, 256, 320, 384
  438. };
  439. static uchar miroamux[] = { 2, 0, 0, 0, 10, 0 };
  440. static uchar hauppaugeamux[] = { 0, 1, 2, 3, 4, 0 };
  441. static char *nicamstate[] = {
  442. "analog", "???", "digital", "bad digital receiption"
  443. };
  444. static Tv tvs[Ntvs];
  445. static int ntvs;
  446. static int i2cread(Tv *, uchar, uchar *);
  447. static int i2cwrite(Tv *, uchar, uchar, uchar, int);
  448. static void tvinterrupt(Ureg *, Tv *);
  449. static void vgastart(Tv *, ulong, int);
  450. static void vstart(Tv *, int, int, int, int);
  451. static void astart(Tv *, char *, uint, uint, uint);
  452. static void vstop(Tv *);
  453. static void astop(Tv *);
  454. static void colormode(Tv *, char *);
  455. static void frequency(Tv *, int, int);
  456. static int getbitspp(Tv *);
  457. static char *getcolormode(ulong);
  458. static int mspreset(Tv *);
  459. static void i2cscan(Tv *);
  460. static int kfirinitialize(Tv *);
  461. static void msptune(Tv *);
  462. static void mspvolume(Tv *, int, int, int);
  463. static void gpioenable(Tv *, ulong, ulong);
  464. static void gpiowrite(Tv *, ulong, ulong);
  465. static void
  466. tvinit(void)
  467. {
  468. Pcidev *pci;
  469. ulong intmask;
  470. // Test for a triton memory controller.
  471. intmask = 0;
  472. if (pcimatch(nil, Intel_vid, Intel_82437_did))
  473. intmask = intmask_etbf;
  474. pci = nil;
  475. while ((pci = pcimatch(pci, 0, 0)) != nil) {
  476. int i, t;
  477. Tv *tv;
  478. Bt848 *bt848;
  479. ushort hscale, hdelay;
  480. uchar v;
  481. for (i = 0; i != nelem(variant); i++)
  482. if (pci->vid == variant[i].vid && pci->did == variant[i].did)
  483. break;
  484. if (i == nelem(variant))
  485. continue;
  486. if (ntvs >= Ntvs) {
  487. print("#V: Too many TV cards found\n");
  488. continue;
  489. }
  490. tv = &tvs[ntvs++];
  491. tv->variant = &variant[i];
  492. tv->pci = pci;
  493. tv->bt848 = (Bt848 *)upamalloc(pci->mem[0].bar & ~0x0F, 4 * K, K);
  494. if (tv->bt848 == nil)
  495. panic("#V: Cannot allocate memory for Bt848");
  496. bt848 = tv->bt848;
  497. // i2c stuff.
  498. if (pci->did >= 878)
  499. tv->i2ccmd = 0x83;
  500. else
  501. tv->i2ccmd = i2c_timing | i2c_bt848scl | i2c_bt848sda;
  502. t = 0;
  503. if (i2cread(tv, i2c_haupee, &v)) {
  504. uchar ee[256];
  505. Pcidev *pci878;
  506. Bt848 *bt878;
  507. tv->board = Bt878_hauppauge;
  508. if (!i2cwrite(tv, i2c_haupee, 0, 0, 0))
  509. panic("#V: Cannot write to Hauppauge EEPROM");
  510. for (i = 0; i != sizeof ee; i++)
  511. if (!i2cread(tv, i2c_haupee + 1, &ee[i]))
  512. panic("#V: Cannot read from Hauppauge EEPROM");
  513. if (ee[9] > sizeof hp_tuners / sizeof hp_tuners[0])
  514. panic("#V: Tuner out of range (max %d, this %d)",
  515. sizeof hp_tuners / sizeof hp_tuners[0], ee[9]);
  516. t = hp_tuners[ee[9]];
  517. // Initialize the audio channel.
  518. if ((pci878 = pcimatch(nil, Brooktree_vid, 0x878)) == nil)
  519. panic("#V: Unsupported Hauppage board");
  520. tv->bt878 = bt878 =
  521. (Bt848 *)upamalloc(pci878->mem[0].bar & ~0x0F, 4 * K, K);
  522. if (bt878 == nil)
  523. panic("#V: Cannot allocate memory for the Bt878");
  524. kfirinitialize(tv);
  525. // i2cscan(tv);
  526. mspreset(tv);
  527. bt878->gpiodmactl = 0;
  528. bt878->intstat = (ulong)-1;
  529. intrenable(pci878->intl, (void (*)(Ureg *, void *))tvinterrupt,
  530. tv, pci878->tbdf, "tv");
  531. tv->amux = hauppaugeamux;
  532. }
  533. else if (i2cread(tv, i2c_stbee, &v)) {
  534. USED(t);
  535. panic("#V: Cannot deal with STB cards\n");
  536. }
  537. else if (i2cread(tv, i2c_miroproee, &v)) {
  538. tv->board = Bt848_miropro;
  539. t = ((bt848->gpiodata[0] >> 10) - 1) & 7;
  540. tv->amux = miroamux;
  541. }
  542. else {
  543. tv->board = Bt848_miro;
  544. tv->amux = miroamux;
  545. t = ((bt848->gpiodata[0] >> 10) - 1) & 7;
  546. }
  547. if (t >= nelem(tuners))
  548. t = 4;
  549. tv->tuner = &tuners[t];
  550. tv->i2ctuneraddr =
  551. i2cread(tv, 0xc1, &v)? 0xc0:
  552. i2cread(tv, 0xc3, &v)? 0xc2:
  553. i2cread(tv, 0xc5, &v)? 0xc4:
  554. i2cread(tv, 0xc7, &v)? 0xc6: -1;
  555. bt848->capctl = capctl_fullframe;
  556. bt848->adelay = adelay_ntsc;
  557. bt848->bdelay = bdelay_ntsc;
  558. bt848->iform = iform_muxsel0|iform_xtauto|iform_ntsc;
  559. bt848->vbipacksize = vbipacksize & 0xff;
  560. bt848->vbipackdel = (vbipacksize >> 8) & 1;
  561. // setpll(bt848);
  562. tv->cfmt = bt848->colorfmt = colorfmt_rgb16;
  563. hscale = (ntsc_rawpixels * 4096) / ntsc_sqpixels - 4096;
  564. hdelay = (ntsc_clkx1delay * ntsc_hactive) / ntsc_clkx1hactive;
  565. bt848->ovtc = bt848->evtc = 0;
  566. bt848->ehscalehi = bt848->ohscalehi = (hscale >> 8) & 0xff;
  567. bt848->ehscalelo = bt848->ohscalelo = hscale & 0xff;
  568. bt848->evscalehi &= ~0x1f;
  569. bt848->ovscalehi &= ~0x1f;
  570. bt848->evscalehi |= vscale_interlaced | ((ntsc_vscale >> 8) & 0x1f);
  571. bt848->ovscalehi |= vscale_interlaced | (ntsc_vscale >> 8) & 0x1f;
  572. bt848->evscalelo = bt848->ovscalelo = ntsc_vscale & 0xff;
  573. bt848->ehactivelo = bt848->ohactivelo = ntsc_hactive & 0xff;
  574. bt848->ehdelaylo = bt848->ohdelaylo = hdelay & 0xff;
  575. bt848->evactivelo = bt848->ovactivelo = ntsc_vactive & 0xff;
  576. bt848->evdelaylo = bt848->ovdelaylo = ntsc_vdelay & 0xff;
  577. bt848->ecrop = bt848->ocrop =
  578. ((ntsc_hactive >> 8) & 0x03) |
  579. ((hdelay >> 6) & 0x0C) |
  580. ((ntsc_vactive >> 4) & 0x30) |
  581. ((ntsc_vdelay >> 2) & 0xC0);
  582. bt848->colorctl = colorctl_gamma;
  583. bt848->capctl = 0;
  584. bt848->gpiodmactl = gpiodmactl_pltp23_16 |
  585. gpiodmactl_pltp1_16 | gpiodmactl_pktp_32;
  586. bt848->gpioreginp = 0;
  587. bt848->contrastlo = contrast_100percent;
  588. bt848->bright = 16;
  589. bt848->adc = (2 << 6) | adc_crush;
  590. bt848->econtrol = bt848->ocontrol = control_ldec;
  591. bt848->escloop = bt848->oscloop = 0;
  592. bt848->intstat = (ulong)-1;
  593. bt848->intmask = intmask |
  594. intstat_vsync | intstat_scerr | intstat_risci | intstat_ocerr |
  595. intstat_vpress | intstat_fmtchg;
  596. if (tv->amux) {
  597. gpioenable(tv, ~0xfff, 0xfff);
  598. gpiowrite(tv, ~0xfff, tv->amux[AudioRadio]);
  599. }
  600. print("#V%ld: %s (rev %d) (%s/%s) intl %d\n",
  601. tv - tvs, tv->variant->name, pci->rid, boards[tv->board],
  602. tv->tuner->name, pci->intl);
  603. intrenable(pci->intl, (void (*)(Ureg *, void *))tvinterrupt,
  604. tv, pci->tbdf, "tv");
  605. }
  606. }
  607. static Chan*
  608. tvattach(char *spec)
  609. {
  610. return devattach('V', spec);
  611. }
  612. #define TYPE(q) ((int)((q).path & 0xff))
  613. #define DEV(q) ((int)(((q).path >> 8) & 0xff))
  614. #define QID(d, t) ((((d) & 0xff) << 8) | (t))
  615. static int
  616. tv1gen(Chan *c, int i, Dir *dp)
  617. {
  618. Qid qid;
  619. switch (i) {
  620. case Qvdata:
  621. mkqid(&qid, QID(DEV(c->qid), Qvdata), 0, QTFILE);
  622. devdir(c, qid, "video", 0, eve, 0444, dp);
  623. return 1;
  624. case Qadata:
  625. mkqid(&qid, QID(DEV(c->qid), Qadata), 0, QTFILE);
  626. devdir(c, qid, "audio", 0, eve, 0444, dp);
  627. return 1;
  628. case Qctl:
  629. mkqid(&qid, QID(DEV(c->qid), Qctl), 0, QTFILE);
  630. devdir(c, qid, "ctl", 0, eve, 0444, dp);
  631. return 1;
  632. case Qregs:
  633. mkqid(&qid, QID(DEV(c->qid), Qregs), 0, QTFILE);
  634. devdir(c, qid, "regs", 0, eve, 0444, dp);
  635. return 1;
  636. }
  637. return -1;
  638. }
  639. static int
  640. tvgen(Chan *c, char *, Dirtab *, int, int i, Dir *dp)
  641. {
  642. Qid qid;
  643. int dev;
  644. dev = DEV(c->qid);
  645. switch (TYPE(c->qid)) {
  646. case Qdir:
  647. if (i == DEVDOTDOT) {
  648. mkqid(&qid, Qdir, 0, QTDIR);
  649. devdir(c, qid, "#V", 0, eve, 0555, dp);
  650. return 1;
  651. }
  652. if (i >= ntvs)
  653. return -1;
  654. mkqid(&qid, QID(i, Qsubdir), 0, QTDIR);
  655. snprint(up->genbuf, sizeof(up->genbuf), "tv%d", i);
  656. devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
  657. return 1;
  658. case Qsubdir:
  659. if (i == DEVDOTDOT) {
  660. mkqid(&qid, QID(dev, Qdir), 0, QTDIR);
  661. snprint(up->genbuf, sizeof(up->genbuf), "tv%d", dev);
  662. devdir(c, qid, up->genbuf, 0, eve, 0555, dp);
  663. return 1;
  664. }
  665. return tv1gen(c, i + Qsubbase, dp);
  666. case Qvdata:
  667. case Qadata:
  668. case Qctl:
  669. case Qregs:
  670. return tv1gen(c, TYPE(c->qid), dp);
  671. default:
  672. return -1;
  673. }
  674. }
  675. static Walkqid *
  676. tvwalk(Chan *c, Chan *nc, char **name, int nname)
  677. {
  678. return devwalk(c, nc, name, nname, 0, 0, tvgen);
  679. }
  680. static int
  681. tvstat(Chan *c, uchar *db, int n)
  682. {
  683. return devstat(c, db, n, 0, 0, tvgen);
  684. }
  685. static Chan*
  686. tvopen(Chan *c, int omode)
  687. {
  688. if (omode != OREAD &&
  689. TYPE(c->qid) != Qctl && TYPE(c->qid) != Qvdata)
  690. error(Eperm);
  691. switch (TYPE(c->qid)) {
  692. case Qdir:
  693. return devopen(c, omode, nil, 0, tvgen);
  694. case Qadata:
  695. if (tvs[DEV(c->qid)].bt878 == nil)
  696. error(Enonexist);
  697. break;
  698. }
  699. c->mode = openmode(omode);
  700. c->flag |= COPEN;
  701. c->offset = 0;
  702. if (TYPE(c->qid) == Qadata)
  703. c->session = (Session *)0;
  704. return c;
  705. }
  706. static void
  707. tvclose(Chan *)
  708. {}
  709. static int
  710. audioblock(void *)
  711. {
  712. return 1;
  713. }
  714. static long
  715. tvread(Chan *c, void *a, long n, vlong offset)
  716. {
  717. static char regs[10 * K];
  718. static int regslen;
  719. Tv *tv;
  720. char *e, *p;
  721. uchar *src;
  722. USED(offset);
  723. switch(TYPE(c->qid)) {
  724. case Qdir:
  725. case Qsubdir:
  726. return devdirread(c, a, n, 0, 0, tvgen);
  727. case Qvdata: {
  728. int bpf, nb;
  729. tv = &tvs[DEV(c->qid)];
  730. bpf = ntsc_hactive * ntsc_vactive * getbitspp(tv) / 8;
  731. if (offset >= bpf)
  732. return 0;
  733. nb = n;
  734. if (offset + nb > bpf)
  735. nb = bpf - offset;
  736. ilock(tv);
  737. if (tv->frames == nil || tv->lvframe >= tv->nframes ||
  738. tv->frames[tv->lvframe].fbase == nil) {
  739. iunlock(tv);
  740. return 0;
  741. }
  742. src = tv->frames[tv->lvframe].fbase;
  743. incref(&tv->fref);
  744. iunlock(tv);
  745. memmove(a, src + offset, nb);
  746. decref(&tv->fref);
  747. return nb;
  748. }
  749. case Qadata: {
  750. ulong uablock = (ulong)c->session, bnum, tvablock;
  751. int boffs, nbytes;
  752. tv = &tvs[DEV(c->qid)];
  753. if (tv->bt878 == nil)
  754. error("#V: No audio device");
  755. if (tv->absize == 0)
  756. error("#V: audio not initialized");
  757. bnum = offset / tv->absize;
  758. boffs = offset % tv->absize;
  759. nbytes = tv->absize - boffs;
  760. incref(&tv->aref);
  761. while (1) {
  762. tvablock = tv->narblocks; // Current tv block.
  763. if (uablock == 0)
  764. uablock = tvablock - 1;
  765. if (tvablock >= uablock + bnum + tv->narblocks)
  766. uablock = tvablock - 1 - bnum;
  767. if (uablock + bnum == tvablock) {
  768. sleep(tv, audioblock, nil);
  769. continue;
  770. }
  771. break;
  772. }
  773. print("uablock %ld, bnum %ld, boffs %d, nbytes %d, tvablock %ld\n",
  774. uablock, bnum, boffs, nbytes, tvablock);
  775. src = tv->abuf + ((uablock + bnum) % tv->nablocks) * tv->absize;
  776. print("copying from %.8ulX (abuf %.8ulX), nbytes %d (block %ld.%ld)\n",
  777. src + boffs, tv->abuf, nbytes, uablock, bnum);
  778. memmove(a, src + boffs, nbytes);
  779. decref(&tv->aref);
  780. uablock += (boffs + nbytes) % tv->absize;
  781. c->session = (Session *)uablock;
  782. return nbytes;
  783. }
  784. case Qctl: {
  785. char str[128];
  786. tv = &tvs[DEV(c->qid)];
  787. snprint(str, sizeof str, "%dx%dx%d %s channel %d %s\n",
  788. ntsc_hactive, ntsc_vactive, getbitspp(tv),
  789. getcolormode(tv->cfmt), tv->channel,
  790. tv->ainfo);
  791. return readstr(offset, a, strlen(str) + 1, str);
  792. }
  793. case Qregs:
  794. if (offset == 0) {
  795. Bt848 *bt848;
  796. int i;
  797. tv = &tvs[DEV(c->qid)];
  798. bt848 = tv->bt848;
  799. e = regs + sizeof(regs);
  800. p = regs;
  801. for (i = 0; i < 0x300 >> 2; i++)
  802. p = seprint(p, e, "%.3X %.8ulX\n", i << 2, ((ulong *)bt848)[i]);
  803. if (tv->bt878) {
  804. bt848 = tv->bt878;
  805. for (i = 0; i < 0x300 >> 2; i++)
  806. p = seprint(p, e, "%.3X %.8ulX\n",
  807. i << 2, ((ulong *)bt848)[i]);
  808. }
  809. regslen = p - regs;
  810. }
  811. if (offset >= regslen)
  812. return 0;
  813. if (offset + n > regslen)
  814. n = regslen - offset;
  815. return readstr(offset, a, n, &regs[offset]);
  816. default:
  817. n = 0;
  818. break;
  819. }
  820. return n;
  821. }
  822. static long
  823. tvwrite(Chan *c, void *a, long n, vlong)
  824. {
  825. Cmdbuf *cb;
  826. Cmdtab *ct;
  827. Tv *tv;
  828. tv = &tvs[DEV(c->qid)];
  829. switch(TYPE(c->qid)) {
  830. case Qctl:
  831. cb = parsecmd(a, n);
  832. if(waserror()){
  833. free(cb);
  834. nexterror();
  835. }
  836. ct = lookupcmd(cb, tvctlmsg, nelem(tvctlmsg));
  837. switch (ct->index) {
  838. case CMvstart:
  839. vstart(tv, (int)strtol(cb->f[1], (char **)nil, 0),
  840. ntsc_hactive, ntsc_vactive, ntsc_hactive);
  841. break;
  842. case CMastart:
  843. astart(tv, cb->f[1], (uint)strtol(cb->f[2], (char **)nil, 0),
  844. (uint)strtol(cb->f[3], (char **)nil, 0),
  845. (uint)strtol(cb->f[4], (char **)nil, 0));
  846. break;
  847. case CMastop:
  848. astop(tv);
  849. break;
  850. case CMvgastart:
  851. vgastart(tv, strtoul(cb->f[1], (char **)nil, 0),
  852. (int)strtoul(cb->f[2], (char **)nil, 0));
  853. break;
  854. case CMvstop:
  855. vstop(tv);
  856. break;
  857. case CMchannel:
  858. frequency(tv, (int)strtol(cb->f[1], (char **)nil, 0),
  859. (int)strtol(cb->f[2], (char **)nil, 0));
  860. break;
  861. case CMcolormode:
  862. colormode(tv, cb->f[1]);
  863. break;
  864. case CMvolume:
  865. if (!tv->msp)
  866. error("#V: No volume control");
  867. mspvolume(tv, 0, (int)strtol(cb->f[1], (char **)nil, 0),
  868. (int)strtol(cb->f[2], (char **)nil, 0));
  869. break;
  870. case CMmute:
  871. if (!tv->msp)
  872. error("#V: No volume control");
  873. mspvolume(tv, 1, 0, 0);
  874. break;
  875. }
  876. poperror();
  877. free(cb);
  878. break;
  879. default:
  880. error(Eio);
  881. }
  882. return n;
  883. }
  884. Dev tvdevtab = {
  885. 'V',
  886. "tv",
  887. devreset,
  888. tvinit,
  889. devshutdown,
  890. tvattach,
  891. tvwalk,
  892. tvstat,
  893. tvopen,
  894. devcreate,
  895. tvclose,
  896. tvread,
  897. devbread,
  898. tvwrite,
  899. devbwrite,
  900. devremove,
  901. devwstat,
  902. };
  903. static void
  904. tvinterrupt(Ureg *, Tv *tv)
  905. {
  906. Bt848 *bt848 = tv->bt848,
  907. *bt878 = tv->bt878;
  908. while (1) {
  909. ulong vstat, astat;
  910. uchar fnum;
  911. vstat = bt848->intstat;
  912. fnum = (vstat >> intstat_riscstatshift) & 0xf;
  913. vstat &= bt848->intmask;
  914. if (bt878)
  915. astat = bt878->intstat & bt878->intmask;
  916. else
  917. astat = 0;
  918. if (vstat == 0 && astat == 0)
  919. break;
  920. if (astat)
  921. print("vstat %.8luX, astat %.8luX\n", vstat, astat);
  922. bt848->intstat = vstat;
  923. if (bt878)
  924. bt878->intstat = astat;
  925. if ((vstat & intstat_fmtchg) == intstat_fmtchg) {
  926. iprint("int: fmtchg\n");
  927. vstat &= ~intstat_fmtchg;
  928. }
  929. if ((vstat & intstat_vpress) == intstat_vpress) {
  930. // iprint("int: vpress\n");
  931. vstat &= ~intstat_vpress;
  932. }
  933. if ((vstat & intstat_vsync) == intstat_vsync) {
  934. vstat &= ~intstat_vsync;
  935. }
  936. if ((vstat & intstat_scerr) == intstat_scerr) {
  937. iprint("int: scerr\n");
  938. bt848->gpiodmactl &=
  939. ~(gpiodmactl_riscenable|gpiodmactl_fifoenable);
  940. bt848->gpiodmactl |= gpiodmactl_fifoenable;
  941. bt848->gpiodmactl |= gpiodmactl_riscenable;
  942. vstat &= ~intstat_scerr;
  943. }
  944. if ((vstat & intstat_risci) == intstat_risci) {
  945. tv->lvframe = fnum;
  946. vstat &= ~intstat_risci;
  947. }
  948. if ((vstat & intstat_ocerr) == intstat_ocerr) {
  949. iprint("int: ocerr\n");
  950. vstat &= ~intstat_ocerr;
  951. }
  952. if ((vstat & intstat_fbus) == intstat_fbus) {
  953. iprint("int: fbus\n");
  954. vstat &= ~intstat_fbus;
  955. }
  956. if (vstat)
  957. iprint("int: (v) ignored interrupts %.8ulX\n", vstat);
  958. if ((astat & intstat_risci) == intstat_risci) {
  959. tv->narblocks++;
  960. if ((tv->narblocks % 100) == 0)
  961. print("a");
  962. wakeup(tv);
  963. astat &= ~intstat_risci;
  964. }
  965. if ((astat & intstat_fdsr) == intstat_fdsr) {
  966. iprint("int: (a) fdsr\n");
  967. bt848->gpiodmactl &=
  968. ~(gpiodmactl_acapenable |
  969. gpiodmactl_riscenable | gpiodmactl_fifoenable);
  970. astat &= ~intstat_fdsr;
  971. }
  972. if (astat)
  973. iprint("int: (a) ignored interrupts %.8ulX\n", astat);
  974. }
  975. }
  976. static int
  977. i2cread(Tv *tv, uchar off, uchar *v)
  978. {
  979. Bt848 *bt848 = tv->bt848;
  980. ulong intstat;
  981. int i;
  982. bt848->intstat = intstat_i2cdone;
  983. bt848->i2c = (off << 24) | tv->i2ccmd;
  984. intstat = -1;
  985. for (i = 0; i != 1000; i++) {
  986. if ((intstat = bt848->intstat) & intstat_i2cdone)
  987. break;
  988. microdelay(1000);
  989. }
  990. if (i == 1000) {
  991. print("i2cread: timeout\n");
  992. return 0;
  993. }
  994. if ((intstat & intstat_i2crack) == 0)
  995. return 0;
  996. *v = bt848->i2c >> 8;
  997. return 1;
  998. }
  999. static int
  1000. i2cwrite(Tv *tv, uchar addr, uchar sub, uchar data, int both)
  1001. {
  1002. Bt848 *bt848 = tv->bt848;
  1003. ulong intstat, d;
  1004. int i;
  1005. bt848->intstat = intstat_i2cdone;
  1006. d = (addr << 24) | (sub << 16) | tv->i2ccmd;
  1007. if (both)
  1008. d |= (data << 8) | i2c_bt848w3b;
  1009. bt848->i2c = d;
  1010. intstat = 0;
  1011. for (i = 0; i != 1000; i++) {
  1012. if ((intstat = bt848->intstat) & intstat_i2cdone)
  1013. break;
  1014. microdelay(1000);
  1015. }
  1016. if (i == i2c_timeout) {
  1017. print("i2cwrite: timeout\n");
  1018. return 0;
  1019. }
  1020. if ((intstat & intstat_i2crack) == 0)
  1021. return 0;
  1022. return 1;
  1023. }
  1024. static ulong *
  1025. riscpacked(ulong paddr, int fnum, int w, int h, int stride, ulong **lastjmp)
  1026. {
  1027. ulong *p, *pbase;
  1028. int i;
  1029. pbase = p = (ulong *)malloc((h + 6) * 2 * sizeof(ulong));
  1030. assert(p);
  1031. assert(w <= 0x7FF);
  1032. *p++ = riscsync | riscsync_resync | riscsync_vre;
  1033. *p++ = 0;
  1034. *p++ = riscsync | riscsync_fm1;
  1035. *p++ = 0;
  1036. for (i = 0; i != h / 2; i++) {
  1037. *p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
  1038. *p++ = paddr + i * 2 * stride;
  1039. }
  1040. *p++ = riscsync | riscsync_resync | riscsync_vro;
  1041. *p++ = 0;
  1042. *p++ = riscsync | riscsync_fm1;
  1043. *p++ = 0;
  1044. for (i = 0; i != h / 2; i++) {
  1045. *p++ = riscwrite | w | riscwrite_sol | riscwrite_eol;
  1046. *p++ = paddr + (i * 2 + 1) * stride;
  1047. }
  1048. // reset status. you really need two instructions ;-(.
  1049. *p++ = riscjmp | (0xf << risclabelshift_reset);
  1050. *p++ = PADDR(p);
  1051. *p++ = riscjmp | riscirq | (fnum << risclabelshift_set);
  1052. *lastjmp = p;
  1053. return pbase;
  1054. }
  1055. static ulong *
  1056. riscplanar411(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
  1057. {
  1058. ulong *p, *pbase, Cw, Yw, Ch;
  1059. uchar *Ybase, *Cbbase, *Crbase;
  1060. int i, bitspp;
  1061. bitspp = 6;
  1062. assert(w * bitspp / 8 <= 0x7FF);
  1063. pbase = p = (ulong *)malloc((h + 6) * 5 * sizeof(ulong));
  1064. assert(p);
  1065. Yw = w;
  1066. Ybase = (uchar *)paddr;
  1067. Cw = w >> 1;
  1068. Ch = h >> 1;
  1069. Cbbase = Ybase + Yw * h;
  1070. Crbase = Cbbase + Cw * Ch;
  1071. *p++ = riscsync | riscsync_resync | riscsync_vre;
  1072. *p++ = 0;
  1073. *p++ = riscsync | riscsync_fm3;
  1074. *p++ = 0;
  1075. for (i = 0; i != h / 2; i++) {
  1076. *p++ = riscwrite123 | Yw | riscwrite_sol | riscwrite_eol;
  1077. *p++ = (Cw << 16) | Cw;
  1078. *p++ = (ulong)(Ybase + i * 2 * Yw);
  1079. *p++ = (ulong)(Cbbase + i * Cw); // Do not interlace
  1080. *p++ = (ulong)(Crbase + i * Cw);
  1081. }
  1082. *p++ = riscsync | riscsync_resync | riscsync_vro;
  1083. *p++ = 0;
  1084. *p++ = riscsync | riscsync_fm3;
  1085. *p++ = 0;
  1086. for (i = 0; i != h / 2; i++) {
  1087. *p++ = riscwrite1s23 | Yw | riscwrite_sol | riscwrite_eol;
  1088. *p++ = (Cw << 16) | Cw;
  1089. *p++ = (ulong)(Ybase + (i * 2 + 1) * Yw);
  1090. }
  1091. // reset status. you really need two instructions ;-(.
  1092. *p++ = riscjmp | (0xf << risclabelshift_reset);
  1093. *p++ = PADDR(p);
  1094. *p++ = riscjmp | riscirq | (fnum << risclabelshift_set);
  1095. *lastjmp = p;
  1096. return pbase;
  1097. }
  1098. static ulong *
  1099. riscplanar422(ulong paddr, int fnum, int w, int h, ulong **lastjmp)
  1100. {
  1101. ulong *p, *pbase, Cw, Yw;
  1102. uchar *Ybase, *Cbbase, *Crbase;
  1103. int i, bpp;
  1104. bpp = 2;
  1105. assert(w * bpp <= 0x7FF);
  1106. pbase = p = (ulong *)malloc((h + 6) * 5 * sizeof(ulong));
  1107. assert(p);
  1108. Yw = w;
  1109. Ybase = (uchar *)paddr;
  1110. Cw = w >> 1;
  1111. Cbbase = Ybase + Yw * h;
  1112. Crbase = Cbbase + Cw * h;
  1113. *p++ = riscsync | riscsync_resync | riscsync_vre;
  1114. *p++ = 0;
  1115. *p++ = riscsync | riscsync_fm3;
  1116. *p++ = 0;
  1117. for (i = 0; i != h / 2; i++) {
  1118. *p++ = riscwrite123 | Yw | riscwrite_sol | riscwrite_eol;
  1119. *p++ = (Cw << 16) | Cw;
  1120. *p++ = (ulong)(Ybase + i * 2 * Yw);
  1121. *p++ = (ulong)(Cbbase + i * 2 * Cw);
  1122. *p++ = (ulong)(Crbase + i * 2 * Cw);
  1123. }
  1124. *p++ = riscsync | riscsync_resync | riscsync_vro;
  1125. *p++ = 0;
  1126. *p++ = riscsync | riscsync_fm3;
  1127. *p++ = 0;
  1128. for (i = 0; i != h / 2; i++) {
  1129. *p++ = riscwrite123 | Yw | riscwrite_sol | riscwrite_eol;
  1130. *p++ = (Cw << 16) | Cw;
  1131. *p++ = (ulong)(Ybase + (i * 2 + 1) * Yw);
  1132. *p++ = (ulong)(Cbbase + (i * 2 + 1) * Cw);
  1133. *p++ = (ulong)(Crbase + (i * 2 + 1) * Cw);
  1134. }
  1135. // reset status. you really need two instructions ;-(.
  1136. *p++ = riscjmp | (0xf << risclabelshift_reset);
  1137. *p++ = PADDR(p);
  1138. *p++ = riscjmp | riscirq | (fnum << risclabelshift_set);
  1139. *lastjmp = p;
  1140. return pbase;
  1141. }
  1142. static ulong *
  1143. riscaudio(ulong paddr, int nblocks, int bsize)
  1144. {
  1145. ulong *p, *pbase;
  1146. int i;
  1147. pbase = p = (ulong *)malloc((nblocks + 3) * 2 * sizeof(ulong));
  1148. assert(p);
  1149. *p++ = riscsync|riscsync_fm1;
  1150. *p++ = 0;
  1151. for (i = 0; i != nblocks; i++) {
  1152. *p++ = riscwrite | riscwrite_sol | riscwrite_eol | bsize | riscirq |
  1153. ((i & 0xf) << risclabelshift_set) |
  1154. ((~i & 0xf) << risclabelshift_reset);
  1155. *p++ = paddr + i * bsize;
  1156. }
  1157. *p++ = riscsync | riscsync_vro;
  1158. *p++ = 0;
  1159. *p++ = riscjmp;
  1160. *p++ = PADDR(pbase);
  1161. USED(p);
  1162. return pbase;
  1163. }
  1164. static void
  1165. vactivate(Tv *tv, Frame *frames, int nframes)
  1166. {
  1167. Bt848 *bt848 = tv->bt848;
  1168. ilock(tv);
  1169. if (tv->frames) {
  1170. iunlock(tv);
  1171. error(Einuse);
  1172. }
  1173. poperror();
  1174. tv->frames = frames;
  1175. tv->nframes = nframes;
  1176. bt848->riscstrtadd = PADDR(tv->frames[0].fstart);
  1177. bt848->capctl |= capctl_captureodd|capctl_captureeven;
  1178. bt848->gpiodmactl |= gpiodmactl_fifoenable;
  1179. bt848->gpiodmactl |= gpiodmactl_riscenable;
  1180. iunlock(tv);
  1181. }
  1182. static void
  1183. vstart(Tv *tv, int nframes, int w, int h, int stride)
  1184. {
  1185. Frame *frames;
  1186. int bitspp, i, bpf;
  1187. if (nframes >= 0x10)
  1188. error(Ebadarg);
  1189. bitspp = getbitspp(tv);
  1190. bpf = w * h * bitspp / 8;
  1191. // Add one as a spare.
  1192. frames = (Frame *)malloc(nframes * sizeof(Frame));
  1193. assert(frames);
  1194. if (waserror()) {
  1195. for (i = 0; i != nframes; i++)
  1196. if (frames[i].fbase)
  1197. free(frames[i].fbase);
  1198. free(frames);
  1199. nexterror();
  1200. }
  1201. memset(frames, 0, nframes * sizeof(Frame));
  1202. for (i = 0; i != nframes; i++) {
  1203. if ((frames[i].fbase = (uchar *)malloc(bpf)) == nil)
  1204. error(Enomem);
  1205. switch (tv->cfmt) {
  1206. case colorfmt_YCbCr422:
  1207. frames[i].fstart = riscplanar422(PADDR(frames[i].fbase), i,
  1208. w, h, &frames[i].fjmp);
  1209. break;
  1210. case colorfmt_YCbCr411:
  1211. frames[i].fstart = riscplanar411(PADDR(frames[i].fbase), i,
  1212. w, h, &frames[i].fjmp);
  1213. break;
  1214. case colorfmt_rgb16:
  1215. frames[i].fstart = riscpacked(PADDR(frames[i].fbase), i,
  1216. w * bitspp / 8, h, stride * bitspp / 8,
  1217. &frames[i].fjmp);
  1218. break;
  1219. default:
  1220. panic("vstart: Unsupport colorformat\n");
  1221. }
  1222. }
  1223. for (i = 0; i != nframes; i++)
  1224. *frames[i].fjmp =
  1225. PADDR((i == nframes - 1)? frames[0].fstart: frames[i + 1].fstart);
  1226. vactivate(tv, frames, nframes);
  1227. }
  1228. static void
  1229. astart(Tv *tv, char *input, uint rate, uint nab, uint nasz)
  1230. {
  1231. Bt848 *bt878 = tv->bt878;
  1232. ulong *arisc;
  1233. int selector;
  1234. uchar *abuf;
  1235. int s, d;
  1236. if (bt878 == nil || tv->amux == nil)
  1237. error("#V: Card does not support audio");
  1238. selector = 0;
  1239. if (!strcmp(input, "tv"))
  1240. selector = asel_tv;
  1241. else if (!strcmp(input, "radio"))
  1242. selector = asel_radio;
  1243. else if (!strcmp(input, "mic"))
  1244. selector = asel_mic;
  1245. else if (!strcmp(input, "smxc"))
  1246. selector = asel_smxc;
  1247. else
  1248. error("#V: Invalid input");
  1249. if (nasz > 0xfff)
  1250. error("#V: Audio block size too big (max 0xfff)");
  1251. abuf = (uchar *)malloc(nab * nasz * sizeof(uchar));
  1252. assert(abuf);
  1253. arisc = riscaudio(PADDR(abuf), nab, nasz);
  1254. ilock(tv);
  1255. if (tv->arisc) {
  1256. iunlock(tv);
  1257. free(abuf);
  1258. free(arisc);
  1259. error(Einuse);
  1260. }
  1261. tv->arisc = arisc;
  1262. tv->abuf = abuf;
  1263. tv->nablocks = nab;
  1264. tv->absize = nasz;
  1265. bt878->riscstrtadd = PADDR(tv->arisc);
  1266. bt878->packetlen = (nab << 16) | nasz;
  1267. bt878->intmask =
  1268. intstat_scerr | intstat_ocerr | intstat_risci |
  1269. intstat_pabort | intstat_riperr | intstat_pperr |
  1270. intstat_fdsr | intstat_ftrgt | intstat_fbus;
  1271. /* Assume analog, 16bpp */
  1272. for (s = 0; s < 16; s++)
  1273. if (rate << s > Hwbase_ad * 4 / 15)
  1274. break;
  1275. for (d = 15; d >= 4; d--)
  1276. if (rate << s < Hwbase_ad * 4 / d)
  1277. break;
  1278. print("astart: sampleshift %d, decimation %d\n", s, d);
  1279. tv->narblocks = 0;
  1280. bt878->gpiodmactl = gpiodmactl_fifoenable |
  1281. gpiodmactl_riscenable | gpiodmactl_acapenable |
  1282. gpiodmactl_daes2 | /* gpiodmactl_apwrdn | */
  1283. gpiodmactl_daiomda | (d << 8) | (9 << 28) | (selector << 24);
  1284. print("dmactl %.8ulX\n", bt878->gpiodmactl);
  1285. iunlock(tv);
  1286. }
  1287. static void
  1288. astop(Tv *tv)
  1289. {
  1290. Bt848 *bt878 = tv->bt878;
  1291. ilock(tv);
  1292. if (tv->aref.ref > 0) {
  1293. iunlock(tv);
  1294. error(Einuse);
  1295. }
  1296. if (tv->abuf) {
  1297. bt878->gpiodmactl &= ~gpiodmactl_riscenable;
  1298. bt878->gpiodmactl &= ~gpiodmactl_fifoenable;
  1299. free(tv->abuf);
  1300. tv->abuf = nil;
  1301. free(tv->arisc);
  1302. tv->arisc = nil;
  1303. }
  1304. iunlock(tv);
  1305. }
  1306. static void
  1307. vgastart(Tv *tv, ulong paddr, int stride)
  1308. {
  1309. Frame *frame;
  1310. frame = (Frame *)malloc(sizeof(Frame));
  1311. assert(frame);
  1312. if (waserror()) {
  1313. free(frame);
  1314. nexterror();
  1315. }
  1316. frame->fbase = nil;
  1317. frame->fstart = riscpacked(paddr, 0, ntsc_hactive * getbitspp(tv) / 8,
  1318. ntsc_vactive, stride * getbitspp(tv) / 8,
  1319. &frame->fjmp);
  1320. *frame->fjmp = PADDR(frame->fstart);
  1321. vactivate(tv, frame, 1);
  1322. }
  1323. static void
  1324. vstop(Tv *tv)
  1325. {
  1326. Bt848 *bt848 = tv->bt848;
  1327. ilock(tv);
  1328. if (tv->fref.ref > 0) {
  1329. iunlock(tv);
  1330. error(Einuse);
  1331. }
  1332. if (tv->frames) {
  1333. int i;
  1334. bt848->gpiodmactl &= ~gpiodmactl_riscenable;
  1335. bt848->gpiodmactl &= ~gpiodmactl_fifoenable;
  1336. bt848->capctl &= ~(capctl_captureodd|capctl_captureeven);
  1337. for (i = 0; i != tv->nframes; i++)
  1338. if (tv->frames[i].fbase)
  1339. free(tv->frames[i].fbase);
  1340. free(tv->frames);
  1341. tv->frames = nil;
  1342. }
  1343. iunlock(tv);
  1344. }
  1345. static long
  1346. 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. }
  1711. for (i = 0xf0; i != 0xff; i++) {
  1712. i2c_start(tv);
  1713. ack = i2c_wr8(tv, i, 0);
  1714. i2c_stop(tv);
  1715. if (ack)
  1716. print("i2c device may be at @%.2uX\n", i);
  1717. }
  1718. }
  1719. static void
  1720. gpioenable(Tv *tv, ulong mask, ulong data)
  1721. {
  1722. Bt848 *bt848 = tv->bt848;
  1723. bt848->gpioouten = (bt848->gpioouten & mask) | data;
  1724. }
  1725. static void
  1726. gpiowrite(Tv *tv, ulong mask, ulong data)
  1727. {
  1728. Bt848 *bt848 = tv->bt848;
  1729. bt848->gpiodata[0] = (bt848->gpiodata[0] & mask) | data;
  1730. }
  1731. static void
  1732. alteraoutput(Tv *tv)
  1733. {
  1734. if (tv->gpiostate == Gpiooutput)
  1735. return;
  1736. gpioenable(tv, ~0xffffff, 0x56ffff);
  1737. microdelay(10);
  1738. tv->gpiostate = Gpiooutput;
  1739. }
  1740. static void
  1741. alterainput(Tv *tv)
  1742. {
  1743. if (tv->gpiostate == Gpioinput)
  1744. return;
  1745. gpioenable(tv, ~0xffffff, 0x570000);
  1746. microdelay(10);
  1747. tv->gpiostate = Gpioinput;
  1748. }
  1749. static void
  1750. alterareg(Tv *tv, ulong reg)
  1751. {
  1752. if (tv->alterareg == reg)
  1753. return;
  1754. gpiowrite(tv, ~0x56ffff, (reg & 0x54ffff) | tv->alteraclock);
  1755. microdelay(10);
  1756. tv->alterareg = reg;
  1757. }
  1758. static void
  1759. alterawrite(Tv *tv, ulong reg, ushort data)
  1760. {
  1761. alteraoutput(tv);
  1762. alterareg(tv, reg);
  1763. tv->alteraclock ^= 0x20000;
  1764. gpiowrite(tv, ~0x56ffff, (reg & 0x540000) | data | tv->alteraclock);
  1765. microdelay(10);
  1766. }
  1767. static void
  1768. alteraread(Tv *tv, int reg, ushort *data)
  1769. {
  1770. Bt848 *bt848 = tv->bt848;
  1771. if (tv->alterareg != reg) {
  1772. alteraoutput(tv);
  1773. alterareg(tv, reg);
  1774. }
  1775. else {
  1776. gpioenable(tv, ~0xffffff, 0x560000);
  1777. microdelay(10);
  1778. }
  1779. alterainput(tv);
  1780. gpiowrite(tv, ~0x570000, (reg & 0x560000) | tv->alteraclock);
  1781. microdelay(10);
  1782. *data = (ushort)bt848->gpiodata[0];
  1783. microdelay(10);
  1784. }
  1785. static void
  1786. kfirloadu(Tv *tv, uchar *u, int ulen)
  1787. {
  1788. Bt848 *bt848 = tv->bt848;
  1789. int i, j;
  1790. ilock(&tv->kfirlock);
  1791. bt848->gpioouten &= 0xff000000;
  1792. bt848->gpioouten |= gpio_altera_data |
  1793. gpio_altera_clock | gpio_altera_nconfig;
  1794. bt848->gpiodata[0] &= 0xff000000;
  1795. microdelay(10);
  1796. bt848->gpiodata[0] |= gpio_altera_nconfig;
  1797. microdelay(10);
  1798. // Download the microcode
  1799. for (i = 0; i != ulen; i++)
  1800. for (j = 0; j != 8; j++) {
  1801. bt848->gpiodata[0] &= ~(gpio_altera_clock|gpio_altera_data);
  1802. if (u[i] & 1)
  1803. bt848->gpiodata[0] |= gpio_altera_data;
  1804. bt848->gpiodata[0] |= gpio_altera_clock;
  1805. u[i] >>= 1;
  1806. }
  1807. bt848->gpiodata[0] &= ~gpio_altera_clock;
  1808. microdelay(100);
  1809. // Initialize.
  1810. for (i = 0; i != 30; i++) {
  1811. bt848->gpiodata[0] &= ~gpio_altera_clock;
  1812. bt848->gpiodata[0] |= gpio_altera_clock;
  1813. }
  1814. bt848->gpiodata[0] &= ~(gpio_altera_clock|gpio_altera_data);
  1815. iunlock(&tv->kfirlock);
  1816. tv->gpiostate = Gpioinit;
  1817. }
  1818. static void
  1819. kfirreset(Tv *tv)
  1820. {
  1821. alterawrite(tv, 0, 0);
  1822. microdelay(10);
  1823. alterawrite(tv, 0x40000, 0);
  1824. microdelay(10);
  1825. alterawrite(tv, 0x40006, 0x80);
  1826. microdelay(10);
  1827. alterawrite(tv, 8, 1);
  1828. microdelay(10);
  1829. alterawrite(tv, 0x40004, 2);
  1830. microdelay(10);
  1831. alterawrite(tv, 4, 3);
  1832. microdelay(3);
  1833. }
  1834. static int
  1835. kfirinitialize(Tv *tv)
  1836. {
  1837. // Initialize parameters?
  1838. tv->gpiostate = Gpioinit;
  1839. tv->alterareg = -1;
  1840. tv->alteraclock = 0x20000;
  1841. kfirloadu(tv, hcwAMC, sizeof hcwAMC);
  1842. kfirreset(tv);
  1843. return 1;
  1844. }