saa7164-api.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. /*
  2. * Driver for the NXP SAA7164 PCIe bridge
  3. *
  4. * Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. *
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <linux/wait.h>
  22. #include <linux/slab.h>
  23. #include "saa7164.h"
  24. int saa7164_api_set_gop_size(struct saa7164_port *port)
  25. {
  26. struct saa7164_dev *dev = port->dev;
  27. tmComResEncVideoGopStructure_t gs;
  28. int ret;
  29. dprintk(DBGLVL_ENC, "%s()\n", __func__);
  30. gs.ucRefFrameDist = SAA7164_ENCODER_DEFAULT_GOP_DIST;
  31. gs.ucGOPSize = SAA7164_ENCODER_DEFAULT_GOP_SIZE;
  32. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
  33. EU_VIDEO_GOP_STRUCTURE_CONTROL,
  34. sizeof(gs), &gs);
  35. if (ret != SAA_OK)
  36. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  37. return ret;
  38. }
  39. int saa7164_api_set_encoder(struct saa7164_port *port)
  40. {
  41. struct saa7164_dev *dev = port->dev;
  42. tmComResEncVideoBitRate_t vb;
  43. tmComResEncAudioBitRate_t ab;
  44. int ret;
  45. dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__,
  46. port->hwcfg.sourceid);
  47. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
  48. EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
  49. if (ret != SAA_OK)
  50. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  51. /* Establish video bitrates */
  52. vb.ucVideoBitRateMode = 0;
  53. vb.dwVideoBitRate = port->encoder_params.bitrate;
  54. vb.dwVideoBitRatePeak = vb.dwVideoBitRate;
  55. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
  56. EU_VIDEO_BIT_RATE_CONTROL, sizeof(tmComResEncVideoBitRate_t), &vb);
  57. if (ret != SAA_OK)
  58. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  59. /* Establish audio bitrates */
  60. ab.ucAudioBitRateMode = 0;
  61. ab.dwAudioBitRate = 384000;
  62. ab.dwAudioBitRatePeak = ab.dwAudioBitRate;
  63. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
  64. EU_AUDIO_BIT_RATE_CONTROL, sizeof(tmComResEncAudioBitRate_t), &ab);
  65. if (ret != SAA_OK)
  66. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  67. saa7164_api_set_aspect_ratio(port);
  68. saa7164_api_set_gop_size(port);
  69. return ret;
  70. }
  71. int saa7164_api_get_encoder(struct saa7164_port *port)
  72. {
  73. struct saa7164_dev *dev = port->dev;
  74. tmComResEncVideoBitRate_t v;
  75. tmComResEncAudioBitRate_t a;
  76. tmComResEncVideoInputAspectRatio_t ar;
  77. int ret;
  78. dprintk(DBGLVL_ENC, "%s() unitid=0x%x\n", __func__, port->hwcfg.sourceid);
  79. port->encoder_profile = 0;
  80. port->video_format = 0;
  81. port->video_resolution = 0;
  82. port->audio_format = 0;
  83. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
  84. EU_PROFILE_CONTROL, sizeof(u8), &port->encoder_profile);
  85. if (ret != SAA_OK)
  86. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  87. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
  88. EU_VIDEO_FORMAT_CONTROL, sizeof(u8), &port->video_format);
  89. if (ret != SAA_OK)
  90. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  91. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
  92. EU_VIDEO_BIT_RATE_CONTROL, sizeof(v), &v);
  93. if (ret != SAA_OK)
  94. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  95. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
  96. EU_AUDIO_FORMAT_CONTROL, sizeof(u8), &port->audio_format);
  97. if (ret != SAA_OK)
  98. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  99. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
  100. EU_AUDIO_BIT_RATE_CONTROL, sizeof(a), &a);
  101. if (ret != SAA_OK)
  102. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  103. /* Aspect Ratio */
  104. ar.width = 0;
  105. ar.height = 0;
  106. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, GET_CUR,
  107. EU_VIDEO_INPUT_ASPECT_CONTROL,
  108. sizeof(tmComResEncVideoInputAspectRatio_t), &ar);
  109. if (ret != SAA_OK)
  110. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  111. dprintk(DBGLVL_ENC, "encoder_profile = %d\n", port->encoder_profile);
  112. dprintk(DBGLVL_ENC, "video_format = %d\n", port->video_format);
  113. dprintk(DBGLVL_ENC, "audio_format = %d\n", port->audio_format);
  114. dprintk(DBGLVL_ENC, "video_resolution= %d\n", port->video_resolution);
  115. dprintk(DBGLVL_ENC, "v.ucVideoBitRateMode = %d\n", v.ucVideoBitRateMode);
  116. dprintk(DBGLVL_ENC, "v.dwVideoBitRate = %d\n", v.dwVideoBitRate);
  117. dprintk(DBGLVL_ENC, "v.dwVideoBitRatePeak = %d\n", v.dwVideoBitRatePeak);
  118. dprintk(DBGLVL_ENC, "a.ucVideoBitRateMode = %d\n", a.ucAudioBitRateMode);
  119. dprintk(DBGLVL_ENC, "a.dwVideoBitRate = %d\n", a.dwAudioBitRate);
  120. dprintk(DBGLVL_ENC, "a.dwVideoBitRatePeak = %d\n", a.dwAudioBitRatePeak);
  121. dprintk(DBGLVL_ENC, "aspect.width / height = %d:%d\n", ar.width, ar.height);
  122. return ret;
  123. }
  124. int saa7164_api_set_aspect_ratio(struct saa7164_port *port)
  125. {
  126. struct saa7164_dev *dev = port->dev;
  127. tmComResEncVideoInputAspectRatio_t ar;
  128. int ret;
  129. dprintk(DBGLVL_ENC, "%s(%d)\n", __func__,
  130. port->encoder_params.ctl_aspect);
  131. switch (port->encoder_params.ctl_aspect) {
  132. case V4L2_MPEG_VIDEO_ASPECT_1x1:
  133. ar.width = 1;
  134. ar.height = 1;
  135. break;
  136. case V4L2_MPEG_VIDEO_ASPECT_4x3:
  137. ar.width = 4;
  138. ar.height = 3;
  139. break;
  140. case V4L2_MPEG_VIDEO_ASPECT_16x9:
  141. ar.width = 16;
  142. ar.height = 9;
  143. break;
  144. case V4L2_MPEG_VIDEO_ASPECT_221x100:
  145. ar.width = 221;
  146. ar.height = 100;
  147. break;
  148. default:
  149. BUG();
  150. }
  151. dprintk(DBGLVL_ENC, "%s(%d) now %d:%d\n", __func__,
  152. port->encoder_params.ctl_aspect,
  153. ar.width, ar.height);
  154. /* Aspect Ratio */
  155. ret = saa7164_cmd_send(port->dev, port->hwcfg.sourceid, SET_CUR,
  156. EU_VIDEO_INPUT_ASPECT_CONTROL,
  157. sizeof(tmComResEncVideoInputAspectRatio_t), &ar);
  158. if (ret != SAA_OK)
  159. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  160. return ret;
  161. }
  162. int saa7164_api_set_usercontrol(struct saa7164_port *port, u8 ctl)
  163. {
  164. struct saa7164_dev *dev = port->dev;
  165. int ret;
  166. u16 val;
  167. if (ctl == PU_BRIGHTNESS_CONTROL)
  168. val = port->ctl_brightness;
  169. else
  170. if (ctl == PU_CONTRAST_CONTROL)
  171. val = port->ctl_contrast;
  172. else
  173. if (ctl == PU_HUE_CONTROL)
  174. val = port->ctl_hue;
  175. else
  176. if (ctl == PU_SATURATION_CONTROL)
  177. val = port->ctl_saturation;
  178. else
  179. if (ctl == PU_SHARPNESS_CONTROL)
  180. val = port->ctl_sharpness;
  181. else
  182. return -EINVAL;
  183. dprintk(DBGLVL_ENC, "%s() unitid=0x%x ctl=%d, val=%d\n",
  184. __func__, port->encunit.vsourceid, ctl, val);
  185. ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, SET_CUR,
  186. ctl, sizeof(u16), &val);
  187. if (ret != SAA_OK)
  188. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  189. return ret;
  190. }
  191. int saa7164_api_get_usercontrol(struct saa7164_port *port, u8 ctl)
  192. {
  193. struct saa7164_dev *dev = port->dev;
  194. int ret;
  195. u16 val;
  196. ret = saa7164_cmd_send(port->dev, port->encunit.vsourceid, GET_CUR,
  197. ctl, sizeof(u16), &val);
  198. if (ret != SAA_OK) {
  199. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  200. return ret;
  201. }
  202. dprintk(DBGLVL_ENC, "%s() ctl=%d, val=%d\n",
  203. __func__, ctl, val);
  204. if (ctl == PU_BRIGHTNESS_CONTROL)
  205. port->ctl_brightness = val;
  206. else
  207. if (ctl == PU_CONTRAST_CONTROL)
  208. port->ctl_contrast = val;
  209. else
  210. if (ctl == PU_HUE_CONTROL)
  211. port->ctl_hue = val;
  212. else
  213. if (ctl == PU_SATURATION_CONTROL)
  214. port->ctl_saturation = val;
  215. else
  216. if (ctl == PU_SHARPNESS_CONTROL)
  217. port->ctl_sharpness = val;
  218. return ret;
  219. }
  220. int saa7164_api_set_videomux(struct saa7164_port *port)
  221. {
  222. struct saa7164_dev *dev = port->dev;
  223. u8 inputs[] = { 1, 2, 2, 2, 5, 5, 5 };
  224. int ret;
  225. dprintk(DBGLVL_ENC, "%s() v_mux=%d a_mux=%d\n",
  226. __func__, port->mux_input, inputs[ port->mux_input - 1 ]);
  227. /* Audio Mute */
  228. ret = saa7164_api_audio_mute(port, 1);
  229. if (ret != SAA_OK)
  230. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  231. /* Video Mux */
  232. ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, SET_CUR,
  233. SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
  234. if (ret != SAA_OK)
  235. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  236. /* Audio Mux */
  237. ret = saa7164_cmd_send(port->dev, port->audfeat.sourceid, SET_CUR,
  238. SU_INPUT_SELECT_CONTROL, sizeof(u8), &inputs[ port->mux_input - 1 ]);
  239. if (ret != SAA_OK)
  240. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  241. /* Audio UnMute */
  242. ret = saa7164_api_audio_mute(port, 0);
  243. if (ret != SAA_OK)
  244. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  245. return ret;
  246. }
  247. int saa7164_api_audio_mute(struct saa7164_port *port, int mute)
  248. {
  249. struct saa7164_dev *dev = port->dev;
  250. u8 v = mute;
  251. int ret;
  252. dprintk(DBGLVL_API, "%s(%d)\n", __func__, mute);
  253. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
  254. MUTE_CONTROL, sizeof(u8), &v);
  255. if (ret != SAA_OK)
  256. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  257. return ret;
  258. }
  259. /* 0 = silence, 0xff = full */
  260. int saa7164_api_set_audio_volume(struct saa7164_port *port, s8 level)
  261. {
  262. struct saa7164_dev *dev = port->dev;
  263. s16 v, min, max;
  264. int ret;
  265. dprintk(DBGLVL_API, "%s(%d)\n", __func__, level);
  266. /* Obtain the min/max ranges */
  267. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MIN,
  268. VOLUME_CONTROL, sizeof(u16), &min);
  269. if (ret != SAA_OK)
  270. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  271. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_MAX,
  272. VOLUME_CONTROL, sizeof(u16), &max);
  273. if (ret != SAA_OK)
  274. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  275. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
  276. ( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
  277. if (ret != SAA_OK)
  278. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  279. dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
  280. v = level;
  281. if (v < min)
  282. v = min;
  283. if (v > max)
  284. v = max;
  285. /* Left */
  286. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
  287. ( 0x01 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);
  288. if (ret != SAA_OK)
  289. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  290. /* Right */
  291. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
  292. ( 0x02 << 8 ) | VOLUME_CONTROL, sizeof(s16), &v);
  293. if (ret != SAA_OK)
  294. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  295. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, GET_CUR,
  296. ( 0x01 << 8) | VOLUME_CONTROL, sizeof(u16), &v);
  297. if (ret != SAA_OK)
  298. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  299. dprintk(DBGLVL_API, "%s(%d) min=%d max=%d cur=%d\n", __func__, level, min, max, v);
  300. return ret;
  301. }
  302. int saa7164_api_set_audio_std(struct saa7164_port *port)
  303. {
  304. struct saa7164_dev *dev = port->dev;
  305. tmComResAudioDefaults_t lvl;
  306. tmComResTunerStandard_t tvaudio;
  307. int ret;
  308. dprintk(DBGLVL_API, "%s()\n", __func__);
  309. /* Establish default levels */
  310. lvl.ucDecoderLevel = TMHW_LEV_ADJ_DECLEV_DEFAULT;
  311. lvl.ucDecoderFM_Level = TMHW_LEV_ADJ_DECLEV_DEFAULT;
  312. lvl.ucMonoLevel = TMHW_LEV_ADJ_MONOLEV_DEFAULT;
  313. lvl.ucNICAM_Level = TMHW_LEV_ADJ_NICLEV_DEFAULT;
  314. lvl.ucSAP_Level = TMHW_LEV_ADJ_SAPLEV_DEFAULT;
  315. lvl.ucADC_Level = TMHW_LEV_ADJ_ADCLEV_DEFAULT;
  316. ret = saa7164_cmd_send(port->dev, port->audfeat.unitid, SET_CUR,
  317. AUDIO_DEFAULT_CONTROL, sizeof(tmComResAudioDefaults_t), &lvl);
  318. if (ret != SAA_OK)
  319. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  320. /* Manually select the appropriate TV audio standard */
  321. if (port->encodernorm.id & V4L2_STD_NTSC) {
  322. tvaudio.std = TU_STANDARD_NTSC_M;
  323. tvaudio.country = 1;
  324. } else {
  325. tvaudio.std = TU_STANDARD_PAL_I;
  326. tvaudio.country = 44;
  327. }
  328. ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
  329. TU_STANDARD_CONTROL, sizeof(tvaudio), &tvaudio);
  330. if (ret != SAA_OK)
  331. printk(KERN_ERR "%s() TU_STANDARD_CONTROL error, ret = 0x%x\n", __func__, ret);
  332. return ret;
  333. }
  334. int saa7164_api_set_audio_detection(struct saa7164_port *port, int autodetect)
  335. {
  336. struct saa7164_dev *dev = port->dev;
  337. tmComResTunerStandardAuto_t p;
  338. int ret;
  339. dprintk(DBGLVL_API, "%s(%d)\n", __func__, autodetect);
  340. /* Disable TV Audio autodetect if not already set (buggy) */
  341. if (autodetect)
  342. p.mode = TU_STANDARD_AUTO;
  343. else
  344. p.mode = TU_STANDARD_MANUAL;
  345. ret = saa7164_cmd_send(port->dev, port->tunerunit.unitid, SET_CUR,
  346. TU_STANDARD_AUTO_CONTROL, sizeof(p), &p);
  347. if (ret != SAA_OK)
  348. printk(KERN_ERR "%s() TU_STANDARD_AUTO_CONTROL error, ret = 0x%x\n", __func__, ret);
  349. return ret;
  350. }
  351. int saa7164_api_get_videomux(struct saa7164_port *port)
  352. {
  353. struct saa7164_dev *dev = port->dev;
  354. int ret;
  355. ret = saa7164_cmd_send(port->dev, port->vidproc.sourceid, GET_CUR,
  356. SU_INPUT_SELECT_CONTROL, sizeof(u8), &port->mux_input);
  357. if (ret != SAA_OK)
  358. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  359. dprintk(DBGLVL_ENC, "%s() v_mux=%d\n",
  360. __func__, port->mux_input);
  361. return ret;
  362. }
  363. int saa7164_api_set_dif(struct saa7164_port *port, u8 reg, u8 val)
  364. {
  365. struct saa7164_dev *dev = port->dev;
  366. u16 len = 0;
  367. u8 buf[256];
  368. int ret;
  369. u8 mas;
  370. dprintk(DBGLVL_API, "%s()\n", __func__);
  371. if (port->nr == 0)
  372. mas = 0xd0;
  373. else
  374. mas = 0xe0;
  375. memset(buf, 0, sizeof(buf));
  376. buf[0x00] = 0x04;
  377. buf[0x01] = 0x00;
  378. buf[0x02] = 0x00;
  379. buf[0x03] = 0x00;
  380. buf[0x04] = 0x04;
  381. buf[0x05] = 0x00;
  382. buf[0x06] = 0x00;
  383. buf[0x07] = 0x00;
  384. buf[0x08] = reg;
  385. buf[0x09] = 0x26;
  386. buf[0x0a] = mas;
  387. buf[0x0b] = 0xb0;
  388. buf[0x0c] = val;
  389. buf[0x0d] = 0x00;
  390. buf[0x0e] = 0x00;
  391. buf[0x0f] = 0x00;
  392. ret = saa7164_cmd_send(dev, port->ifunit.unitid, GET_LEN,
  393. EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
  394. if (ret != SAA_OK) {
  395. printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
  396. return -EIO;
  397. }
  398. ret = saa7164_cmd_send(dev, port->ifunit.unitid, SET_CUR,
  399. EXU_REGISTER_ACCESS_CONTROL, len, &buf);
  400. if (ret != SAA_OK)
  401. printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
  402. //saa7164_dumphex16(dev, buf, 16);
  403. return ret == SAA_OK ? 0 : -EIO;
  404. }
  405. /* Disable the IF block AGC controls */
  406. int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
  407. {
  408. struct saa7164_dev *dev = port->dev;
  409. int ret = 0;
  410. u8 agc_disable;
  411. dprintk(DBGLVL_API, "%s(%p, 0x%x)\n", __func__, port, std);
  412. if (std & V4L2_STD_NTSC) {
  413. dprintk(DBGLVL_API, " NTSC\n");
  414. saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
  415. agc_disable = 0;
  416. } else if (std & V4L2_STD_PAL_I) {
  417. dprintk(DBGLVL_API, " PAL-I\n");
  418. saa7164_api_set_dif(port, 0x00, 0x08); /* Video Standard */
  419. agc_disable = 0;
  420. } else if (std & V4L2_STD_PAL_M) {
  421. dprintk(DBGLVL_API, " PAL-M\n");
  422. saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
  423. agc_disable = 0;
  424. } else if (std & V4L2_STD_PAL_N) {
  425. dprintk(DBGLVL_API, " PAL-N\n");
  426. saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
  427. agc_disable = 0;
  428. } else if (std & V4L2_STD_PAL_Nc) {
  429. dprintk(DBGLVL_API, " PAL-Nc\n");
  430. saa7164_api_set_dif(port, 0x00, 0x01); /* Video Standard */
  431. agc_disable = 0;
  432. } else if (std & V4L2_STD_PAL_B) {
  433. dprintk(DBGLVL_API, " PAL-B\n");
  434. saa7164_api_set_dif(port, 0x00, 0x02); /* Video Standard */
  435. agc_disable = 0;
  436. } else if (std & V4L2_STD_PAL_DK) {
  437. dprintk(DBGLVL_API, " PAL-DK\n");
  438. saa7164_api_set_dif(port, 0x00, 0x10); /* Video Standard */
  439. agc_disable = 0;
  440. } else if (std & V4L2_STD_SECAM_L) {
  441. dprintk(DBGLVL_API, " SECAM-L\n");
  442. saa7164_api_set_dif(port, 0x00, 0x20); /* Video Standard */
  443. agc_disable = 0;
  444. } else {
  445. /* Unknown standard, assume DTV */
  446. dprintk(DBGLVL_API, " Unknown (assuming DTV)\n");
  447. saa7164_api_set_dif(port, 0x00, 0x80); /* Undefined Video Standard */
  448. agc_disable = 1;
  449. }
  450. saa7164_api_set_dif(port, 0x48, 0xa0); /* AGC Functions 1 */
  451. saa7164_api_set_dif(port, 0xc0, agc_disable); /* AGC Output Disable */
  452. saa7164_api_set_dif(port, 0x7c, 0x04); /* CVBS EQ */
  453. saa7164_api_set_dif(port, 0x04, 0x01); /* Active */
  454. msleep(100);
  455. saa7164_api_set_dif(port, 0x04, 0x00); /* Active (again) */
  456. msleep(100);
  457. return ret;
  458. }
  459. /* Ensure the dif is in the correct state for the operating mode
  460. * (analog / dtv). We only configure the diff through the analog encoder
  461. * so when we're in digital mode we need to find the appropriate encoder
  462. * and use it to configure the DIF.
  463. */
  464. int saa7164_api_initialize_dif(struct saa7164_port *port)
  465. {
  466. struct saa7164_dev *dev = port->dev;
  467. struct saa7164_port *p = 0;
  468. int ret = -EINVAL;
  469. u32 std = 0;
  470. if (port->type == SAA7164_MPEG_ENCODER) {
  471. /* Pick any analog standard to init the diff.
  472. * we'll come back during encoder_init'
  473. * and set the correct standard if requried.
  474. */
  475. std = V4L2_STD_NTSC;
  476. } else
  477. if (port->type == SAA7164_MPEG_DVB) {
  478. if (port->nr == SAA7164_PORT_TS1)
  479. p = &dev->ports[ SAA7164_PORT_ENC1 ];
  480. else
  481. p = &dev->ports[ SAA7164_PORT_ENC2 ];
  482. } else
  483. BUG();
  484. if (p)
  485. ret = saa7164_api_configure_dif(p, std);
  486. return ret;
  487. }
  488. int saa7164_api_transition_port(struct saa7164_port *port, u8 mode)
  489. {
  490. int ret;
  491. ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
  492. SAA_STATE_CONTROL, sizeof(mode), &mode);
  493. if (ret != SAA_OK)
  494. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  495. return ret;
  496. }
  497. int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
  498. {
  499. int ret;
  500. ret = saa7164_cmd_send(dev, 0, GET_CUR,
  501. GET_FW_VERSION_CONTROL, sizeof(u32), version);
  502. if (ret != SAA_OK)
  503. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  504. return ret;
  505. }
  506. int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
  507. {
  508. u8 reg[] = { 0x0f, 0x00 };
  509. if (buflen < 128)
  510. return -ENOMEM;
  511. /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
  512. /* TODO: Pull the details from the boards struct */
  513. return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
  514. &reg[0], 128, buf);
  515. }
  516. int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
  517. struct saa7164_port *port,
  518. tmComResTSFormatDescrHeader_t *tsfmt)
  519. {
  520. dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
  521. dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
  522. dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
  523. dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
  524. dprintk(DBGLVL_API, " bguid = (....)\n");
  525. /* Cache the hardware configuration in the port */
  526. port->bufcounter = port->hwcfg.BARLocation;
  527. port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
  528. port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
  529. port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
  530. port->bufptr32l = port->hwcfg.BARLocation +
  531. (4 * sizeof(u32)) +
  532. (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
  533. port->bufptr32h = port->hwcfg.BARLocation +
  534. (4 * sizeof(u32)) +
  535. (sizeof(u32) * port->hwcfg.buffercount);
  536. port->bufptr64 = port->hwcfg.BARLocation +
  537. (4 * sizeof(u32)) +
  538. (sizeof(u32) * port->hwcfg.buffercount);
  539. dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
  540. port->hwcfg.BARLocation);
  541. dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
  542. port->nr);
  543. return 0;
  544. }
  545. int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
  546. struct saa7164_port *port,
  547. tmComResPSFormatDescrHeader_t *fmt)
  548. {
  549. dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", fmt->bFormatIndex);
  550. dprintk(DBGLVL_API, " wPacketLength= 0x%x\n", fmt->wPacketLength);
  551. dprintk(DBGLVL_API, " wPackLength= 0x%x\n", fmt->wPackLength);
  552. dprintk(DBGLVL_API, " bPackDataType= 0x%x\n", fmt->bPackDataType);
  553. /* Cache the hardware configuration in the port */
  554. /* TODO: CHECK THIS in the port config */
  555. port->bufcounter = port->hwcfg.BARLocation;
  556. port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
  557. port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
  558. port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
  559. port->bufptr32l = port->hwcfg.BARLocation +
  560. (4 * sizeof(u32)) +
  561. (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
  562. port->bufptr32h = port->hwcfg.BARLocation +
  563. (4 * sizeof(u32)) +
  564. (sizeof(u32) * port->hwcfg.buffercount);
  565. port->bufptr64 = port->hwcfg.BARLocation +
  566. (4 * sizeof(u32)) +
  567. (sizeof(u32) * port->hwcfg.buffercount);
  568. dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
  569. port->hwcfg.BARLocation);
  570. dprintk(DBGLVL_API, " = VS_FORMAT_MPEGPS (becomes dev->enc[%d])\n",
  571. port->nr);
  572. return 0;
  573. }
  574. int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
  575. {
  576. struct saa7164_port *tsport = 0;
  577. struct saa7164_port *encport = 0;
  578. u32 idx, next_offset;
  579. int i;
  580. tmComResDescrHeader_t *hdr, *t;
  581. tmComResExtDevDescrHeader_t *exthdr;
  582. tmComResPathDescrHeader_t *pathhdr;
  583. tmComResAntTermDescrHeader_t *anttermhdr;
  584. tmComResTunerDescrHeader_t *tunerunithdr;
  585. tmComResDMATermDescrHeader_t *vcoutputtermhdr;
  586. tmComResTSFormatDescrHeader_t *tsfmt;
  587. tmComResPSFormatDescrHeader_t *psfmt;
  588. tmComResSelDescrHeader_t *psel;
  589. tmComResProcDescrHeader_t *pdh;
  590. tmComResAFeatureDescrHeader_t *afd;
  591. tmComResEncoderDescrHeader_t *edh;
  592. u32 currpath = 0;
  593. dprintk(DBGLVL_API,
  594. "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
  595. __func__, len, (u32)sizeof(tmComResDescrHeader_t));
  596. for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
  597. hdr = (tmComResDescrHeader_t *)(buf + idx);
  598. if (hdr->type != CS_INTERFACE)
  599. return SAA_ERR_NOT_SUPPORTED;
  600. dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
  601. switch (hdr->subtype) {
  602. case GENERAL_REQUEST:
  603. dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
  604. break;
  605. case VC_TUNER_PATH:
  606. dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
  607. pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
  608. dprintk(DBGLVL_API, " pathid = 0x%x\n",
  609. pathhdr->pathid);
  610. currpath = pathhdr->pathid;
  611. break;
  612. case VC_INPUT_TERMINAL:
  613. dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
  614. anttermhdr =
  615. (tmComResAntTermDescrHeader_t *)(buf + idx);
  616. dprintk(DBGLVL_API, " terminalid = 0x%x\n",
  617. anttermhdr->terminalid);
  618. dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
  619. anttermhdr->terminaltype);
  620. switch (anttermhdr->terminaltype) {
  621. case ITT_ANTENNA:
  622. dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
  623. break;
  624. case LINE_CONNECTOR:
  625. dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
  626. break;
  627. case SPDIF_CONNECTOR:
  628. dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
  629. break;
  630. case COMPOSITE_CONNECTOR:
  631. dprintk(DBGLVL_API,
  632. " = COMPOSITE_CONNECTOR\n");
  633. break;
  634. case SVIDEO_CONNECTOR:
  635. dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
  636. break;
  637. case COMPONENT_CONNECTOR:
  638. dprintk(DBGLVL_API,
  639. " = COMPONENT_CONNECTOR\n");
  640. break;
  641. case STANDARD_DMA:
  642. dprintk(DBGLVL_API, " = STANDARD_DMA\n");
  643. break;
  644. default:
  645. dprintk(DBGLVL_API, " = undefined (0x%x)\n",
  646. anttermhdr->terminaltype);
  647. }
  648. dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
  649. anttermhdr->assocterminal);
  650. dprintk(DBGLVL_API, " iterminal = 0x%x\n",
  651. anttermhdr->iterminal);
  652. dprintk(DBGLVL_API, " controlsize = 0x%x\n",
  653. anttermhdr->controlsize);
  654. break;
  655. case VC_OUTPUT_TERMINAL:
  656. dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
  657. vcoutputtermhdr =
  658. (tmComResDMATermDescrHeader_t *)(buf + idx);
  659. dprintk(DBGLVL_API, " unitid = 0x%x\n",
  660. vcoutputtermhdr->unitid);
  661. dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
  662. vcoutputtermhdr->terminaltype);
  663. switch (vcoutputtermhdr->terminaltype) {
  664. case ITT_ANTENNA:
  665. dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
  666. break;
  667. case LINE_CONNECTOR:
  668. dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
  669. break;
  670. case SPDIF_CONNECTOR:
  671. dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
  672. break;
  673. case COMPOSITE_CONNECTOR:
  674. dprintk(DBGLVL_API,
  675. " = COMPOSITE_CONNECTOR\n");
  676. break;
  677. case SVIDEO_CONNECTOR:
  678. dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
  679. break;
  680. case COMPONENT_CONNECTOR:
  681. dprintk(DBGLVL_API,
  682. " = COMPONENT_CONNECTOR\n");
  683. break;
  684. case STANDARD_DMA:
  685. dprintk(DBGLVL_API, " = STANDARD_DMA\n");
  686. break;
  687. default:
  688. dprintk(DBGLVL_API, " = undefined (0x%x)\n",
  689. vcoutputtermhdr->terminaltype);
  690. }
  691. dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
  692. vcoutputtermhdr->assocterminal);
  693. dprintk(DBGLVL_API, " sourceid = 0x%x\n",
  694. vcoutputtermhdr->sourceid);
  695. dprintk(DBGLVL_API, " iterminal = 0x%x\n",
  696. vcoutputtermhdr->iterminal);
  697. dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
  698. vcoutputtermhdr->BARLocation);
  699. dprintk(DBGLVL_API, " flags = 0x%x\n",
  700. vcoutputtermhdr->flags);
  701. dprintk(DBGLVL_API, " interruptid = 0x%x\n",
  702. vcoutputtermhdr->interruptid);
  703. dprintk(DBGLVL_API, " buffercount = 0x%x\n",
  704. vcoutputtermhdr->buffercount);
  705. dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
  706. vcoutputtermhdr->metadatasize);
  707. dprintk(DBGLVL_API, " controlsize = 0x%x\n",
  708. vcoutputtermhdr->controlsize);
  709. dprintk(DBGLVL_API, " numformats = 0x%x\n",
  710. vcoutputtermhdr->numformats);
  711. t = (tmComResDescrHeader_t *)
  712. ((tmComResDMATermDescrHeader_t *)(buf + idx));
  713. next_offset = idx + (vcoutputtermhdr->len);
  714. for (i = 0; i < vcoutputtermhdr->numformats; i++) {
  715. t = (tmComResDescrHeader_t *)
  716. (buf + next_offset);
  717. switch (t->subtype) {
  718. case VS_FORMAT_MPEG2TS:
  719. tsfmt =
  720. (tmComResTSFormatDescrHeader_t *)t;
  721. if (currpath == 1)
  722. tsport = &dev->ports[ SAA7164_PORT_TS1 ];
  723. else
  724. tsport = &dev->ports[ SAA7164_PORT_TS2 ];
  725. memcpy(&tsport->hwcfg, vcoutputtermhdr,
  726. sizeof(*vcoutputtermhdr));
  727. saa7164_api_configure_port_mpeg2ts(dev,
  728. tsport, tsfmt);
  729. break;
  730. case VS_FORMAT_MPEG2PS:
  731. psfmt =
  732. (tmComResPSFormatDescrHeader_t *)t;
  733. if (currpath == 1)
  734. encport = &dev->ports[ SAA7164_PORT_ENC1 ];
  735. else
  736. encport = &dev->ports[ SAA7164_PORT_ENC2 ];
  737. memcpy(&encport->hwcfg, vcoutputtermhdr,
  738. sizeof(*vcoutputtermhdr));
  739. saa7164_api_configure_port_mpeg2ps(dev,
  740. encport, psfmt);
  741. break;
  742. case VS_FORMAT_VBI:
  743. dprintk(DBGLVL_API,
  744. " = VS_FORMAT_VBI\n");
  745. break;
  746. case VS_FORMAT_RDS:
  747. dprintk(DBGLVL_API,
  748. " = VS_FORMAT_RDS\n");
  749. break;
  750. case VS_FORMAT_UNCOMPRESSED:
  751. dprintk(DBGLVL_API,
  752. " = VS_FORMAT_UNCOMPRESSED\n");
  753. break;
  754. case VS_FORMAT_TYPE:
  755. dprintk(DBGLVL_API,
  756. " = VS_FORMAT_TYPE\n");
  757. break;
  758. default:
  759. dprintk(DBGLVL_API,
  760. " = undefined (0x%x)\n",
  761. t->subtype);
  762. }
  763. next_offset += t->len;
  764. }
  765. break;
  766. case TUNER_UNIT:
  767. dprintk(DBGLVL_API, " TUNER_UNIT\n");
  768. tunerunithdr =
  769. (tmComResTunerDescrHeader_t *)(buf + idx);
  770. dprintk(DBGLVL_API, " unitid = 0x%x\n",
  771. tunerunithdr->unitid);
  772. dprintk(DBGLVL_API, " sourceid = 0x%x\n",
  773. tunerunithdr->sourceid);
  774. dprintk(DBGLVL_API, " iunit = 0x%x\n",
  775. tunerunithdr->iunit);
  776. dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
  777. tunerunithdr->tuningstandards);
  778. dprintk(DBGLVL_API, " controlsize = 0x%x\n",
  779. tunerunithdr->controlsize);
  780. dprintk(DBGLVL_API, " controls = 0x%x\n",
  781. tunerunithdr->controls);
  782. if (tunerunithdr->unitid == tunerunithdr->iunit) {
  783. if (currpath == 1)
  784. encport = &dev->ports[ SAA7164_PORT_ENC1 ];
  785. else
  786. encport = &dev->ports[ SAA7164_PORT_ENC2 ];
  787. memcpy(&encport->tunerunit, tunerunithdr,
  788. sizeof(tmComResTunerDescrHeader_t));
  789. dprintk(DBGLVL_API, " (becomes dev->enc[%d] tuner)\n", encport->nr);
  790. }
  791. break;
  792. case VC_SELECTOR_UNIT:
  793. psel = (tmComResSelDescrHeader_t *)(buf + idx);
  794. dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
  795. dprintk(DBGLVL_API, " unitid = 0x%x\n",
  796. psel->unitid);
  797. dprintk(DBGLVL_API, " nrinpins = 0x%x\n",
  798. psel->nrinpins);
  799. dprintk(DBGLVL_API, " sourceid = 0x%x\n",
  800. psel->sourceid);
  801. break;
  802. case VC_PROCESSING_UNIT:
  803. pdh = (tmComResProcDescrHeader_t *)(buf + idx);
  804. dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
  805. dprintk(DBGLVL_API, " unitid = 0x%x\n",
  806. pdh->unitid);
  807. dprintk(DBGLVL_API, " sourceid = 0x%x\n",
  808. pdh->sourceid);
  809. dprintk(DBGLVL_API, " controlsize = 0x%x\n",
  810. pdh->controlsize);
  811. if (pdh->controlsize == 0x04) {
  812. if (currpath == 1)
  813. encport = &dev->ports[ SAA7164_PORT_ENC1 ];
  814. else
  815. encport = &dev->ports[ SAA7164_PORT_ENC2 ];
  816. memcpy(&encport->vidproc, pdh,
  817. sizeof(tmComResProcDescrHeader_t));
  818. dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
  819. }
  820. break;
  821. case FEATURE_UNIT:
  822. afd = (tmComResAFeatureDescrHeader_t *)(buf + idx);
  823. dprintk(DBGLVL_API, " FEATURE_UNIT\n");
  824. dprintk(DBGLVL_API, " unitid = 0x%x\n",
  825. afd->unitid);
  826. dprintk(DBGLVL_API, " sourceid = 0x%x\n",
  827. afd->sourceid);
  828. dprintk(DBGLVL_API, " controlsize = 0x%x\n",
  829. afd->controlsize);
  830. if (currpath == 1)
  831. encport = &dev->ports[ SAA7164_PORT_ENC1 ];
  832. else
  833. encport = &dev->ports[ SAA7164_PORT_ENC2 ];
  834. memcpy(&encport->audfeat, afd,
  835. sizeof(tmComResAFeatureDescrHeader_t));
  836. dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
  837. break;
  838. case ENCODER_UNIT:
  839. edh = (tmComResEncoderDescrHeader_t *)(buf + idx);
  840. dprintk(DBGLVL_API, " ENCODER_UNIT\n");
  841. dprintk(DBGLVL_API, " subtype = 0x%x\n", edh->subtype);
  842. dprintk(DBGLVL_API, " unitid = 0x%x\n", edh->unitid);
  843. dprintk(DBGLVL_API, " vsourceid = 0x%x\n", edh->vsourceid);
  844. dprintk(DBGLVL_API, " asourceid = 0x%x\n", edh->asourceid);
  845. dprintk(DBGLVL_API, " iunit = 0x%x\n", edh->iunit);
  846. if (edh->iunit == edh->unitid) {
  847. if (currpath == 1)
  848. encport = &dev->ports[ SAA7164_PORT_ENC1 ];
  849. else
  850. encport = &dev->ports[ SAA7164_PORT_ENC2 ];
  851. memcpy(&encport->encunit, edh,
  852. sizeof(tmComResEncoderDescrHeader_t));
  853. dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
  854. }
  855. break;
  856. case EXTENSION_UNIT:
  857. dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
  858. exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
  859. dprintk(DBGLVL_API, " unitid = 0x%x\n",
  860. exthdr->unitid);
  861. dprintk(DBGLVL_API, " deviceid = 0x%x\n",
  862. exthdr->deviceid);
  863. dprintk(DBGLVL_API, " devicetype = 0x%x\n",
  864. exthdr->devicetype);
  865. if (exthdr->devicetype & 0x1)
  866. dprintk(DBGLVL_API, " = Decoder Device\n");
  867. if (exthdr->devicetype & 0x2)
  868. dprintk(DBGLVL_API, " = GPIO Source\n");
  869. if (exthdr->devicetype & 0x4)
  870. dprintk(DBGLVL_API, " = Video Decoder\n");
  871. if (exthdr->devicetype & 0x8)
  872. dprintk(DBGLVL_API, " = Audio Decoder\n");
  873. if (exthdr->devicetype & 0x20)
  874. dprintk(DBGLVL_API, " = Crossbar\n");
  875. if (exthdr->devicetype & 0x40)
  876. dprintk(DBGLVL_API, " = Tuner\n");
  877. if (exthdr->devicetype & 0x80)
  878. dprintk(DBGLVL_API, " = IF PLL\n");
  879. if (exthdr->devicetype & 0x100)
  880. dprintk(DBGLVL_API, " = Demodulator\n");
  881. if (exthdr->devicetype & 0x200)
  882. dprintk(DBGLVL_API, " = RDS Decoder\n");
  883. if (exthdr->devicetype & 0x400)
  884. dprintk(DBGLVL_API, " = Encoder\n");
  885. if (exthdr->devicetype & 0x800)
  886. dprintk(DBGLVL_API, " = IR Decoder\n");
  887. if (exthdr->devicetype & 0x1000)
  888. dprintk(DBGLVL_API, " = EEPROM\n");
  889. if (exthdr->devicetype & 0x2000)
  890. dprintk(DBGLVL_API,
  891. " = VBI Decoder\n");
  892. if (exthdr->devicetype & 0x10000)
  893. dprintk(DBGLVL_API,
  894. " = Streaming Device\n");
  895. if (exthdr->devicetype & 0x20000)
  896. dprintk(DBGLVL_API,
  897. " = DRM Device\n");
  898. if (exthdr->devicetype & 0x40000000)
  899. dprintk(DBGLVL_API,
  900. " = Generic Device\n");
  901. if (exthdr->devicetype & 0x80000000)
  902. dprintk(DBGLVL_API,
  903. " = Config Space Device\n");
  904. dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
  905. exthdr->numgpiopins);
  906. dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
  907. exthdr->numgpiogroups);
  908. dprintk(DBGLVL_API, " controlsize = 0x%x\n",
  909. exthdr->controlsize);
  910. if (exthdr->devicetype & 0x80) {
  911. if (currpath == 1)
  912. encport = &dev->ports[ SAA7164_PORT_ENC1 ];
  913. else
  914. encport = &dev->ports[ SAA7164_PORT_ENC2 ];
  915. memcpy(&encport->ifunit, exthdr,
  916. sizeof(tmComResExtDevDescrHeader_t));
  917. dprintk(DBGLVL_API, " (becomes dev->enc[%d])\n", encport->nr);
  918. }
  919. break;
  920. case PVC_INFRARED_UNIT:
  921. dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
  922. break;
  923. case DRM_UNIT:
  924. dprintk(DBGLVL_API, " DRM_UNIT\n");
  925. break;
  926. default:
  927. dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
  928. }
  929. dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
  930. dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
  931. dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
  932. dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
  933. idx += hdr->len;
  934. }
  935. return 0;
  936. }
  937. int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
  938. {
  939. int ret;
  940. u32 buflen = 0;
  941. u8 *buf;
  942. dprintk(DBGLVL_API, "%s()\n", __func__);
  943. /* Get the total descriptor length */
  944. ret = saa7164_cmd_send(dev, 0, GET_LEN,
  945. GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
  946. if (ret != SAA_OK)
  947. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  948. dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
  949. __func__, buflen);
  950. /* Allocate enough storage for all of the descs */
  951. buf = kzalloc(buflen, GFP_KERNEL);
  952. if (buf == NULL)
  953. return SAA_ERR_NO_RESOURCES;
  954. /* Retrieve them */
  955. ret = saa7164_cmd_send(dev, 0, GET_CUR,
  956. GET_DESCRIPTORS_CONTROL, buflen, buf);
  957. if (ret != SAA_OK) {
  958. printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
  959. goto out;
  960. }
  961. if (saa_debug & DBGLVL_API)
  962. saa7164_dumphex16(dev, buf, (buflen/16)*16);
  963. saa7164_api_dump_subdevs(dev, buf, buflen);
  964. out:
  965. kfree(buf);
  966. return ret;
  967. }
  968. int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
  969. u32 datalen, u8 *data)
  970. {
  971. struct saa7164_dev *dev = bus->dev;
  972. u16 len = 0;
  973. int unitid;
  974. u32 regval;
  975. u8 buf[256];
  976. int ret;
  977. dprintk(DBGLVL_API, "%s()\n", __func__);
  978. if (reglen > 4)
  979. return -EIO;
  980. if (reglen == 1)
  981. regval = *(reg);
  982. else
  983. if (reglen == 2)
  984. regval = ((*(reg) << 8) || *(reg+1));
  985. else
  986. if (reglen == 3)
  987. regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
  988. else
  989. if (reglen == 4)
  990. regval = ((*(reg) << 24) | (*(reg+1) << 16) |
  991. (*(reg+2) << 8) | *(reg+3));
  992. /* Prepare the send buffer */
  993. /* Bytes 00-03 source register length
  994. * 04-07 source bytes to read
  995. * 08... register address
  996. */
  997. memset(buf, 0, sizeof(buf));
  998. memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
  999. *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
  1000. *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
  1001. unitid = saa7164_i2caddr_to_unitid(bus, addr);
  1002. if (unitid < 0) {
  1003. printk(KERN_ERR
  1004. "%s() error, cannot translate regaddr 0x%x to unitid\n",
  1005. __func__, addr);
  1006. return -EIO;
  1007. }
  1008. ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
  1009. EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
  1010. if (ret != SAA_OK) {
  1011. printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
  1012. return -EIO;
  1013. }
  1014. dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
  1015. if (saa_debug & DBGLVL_I2C)
  1016. saa7164_dumphex16(dev, buf, 2 * 16);
  1017. ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
  1018. EXU_REGISTER_ACCESS_CONTROL, len, &buf);
  1019. if (ret != SAA_OK)
  1020. printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
  1021. else {
  1022. if (saa_debug & DBGLVL_I2C)
  1023. saa7164_dumphex16(dev, buf, sizeof(buf));
  1024. memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
  1025. }
  1026. return ret == SAA_OK ? 0 : -EIO;
  1027. }
  1028. /* For a given 8 bit i2c address device, write the buffer */
  1029. int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
  1030. u8 *data)
  1031. {
  1032. struct saa7164_dev *dev = bus->dev;
  1033. u16 len = 0;
  1034. int unitid;
  1035. int reglen;
  1036. u8 buf[256];
  1037. int ret;
  1038. dprintk(DBGLVL_API, "%s()\n", __func__);
  1039. if ((datalen == 0) || (datalen > 232))
  1040. return -EIO;
  1041. memset(buf, 0, sizeof(buf));
  1042. unitid = saa7164_i2caddr_to_unitid(bus, addr);
  1043. if (unitid < 0) {
  1044. printk(KERN_ERR
  1045. "%s() error, cannot translate regaddr 0x%x to unitid\n",
  1046. __func__, addr);
  1047. return -EIO;
  1048. }
  1049. reglen = saa7164_i2caddr_to_reglen(bus, addr);
  1050. if (reglen < 0) {
  1051. printk(KERN_ERR
  1052. "%s() error, cannot translate regaddr to reglen\n",
  1053. __func__);
  1054. return -EIO;
  1055. }
  1056. ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
  1057. EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
  1058. if (ret != SAA_OK) {
  1059. printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
  1060. return -EIO;
  1061. }
  1062. dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
  1063. /* Prepare the send buffer */
  1064. /* Bytes 00-03 dest register length
  1065. * 04-07 dest bytes to write
  1066. * 08... register address
  1067. */
  1068. *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
  1069. *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
  1070. memcpy((buf + 2 * sizeof(u32)), data, datalen);
  1071. if (saa_debug & DBGLVL_I2C)
  1072. saa7164_dumphex16(dev, buf, sizeof(buf));
  1073. ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
  1074. EXU_REGISTER_ACCESS_CONTROL, len, &buf);
  1075. if (ret != SAA_OK)
  1076. printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
  1077. return ret == SAA_OK ? 0 : -EIO;
  1078. }
  1079. int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
  1080. u8 pin, u8 state)
  1081. {
  1082. int ret;
  1083. tmComResGPIO_t t;
  1084. dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
  1085. __func__, unitid, pin, state);
  1086. if ((pin > 7) || (state > 2))
  1087. return SAA_ERR_BAD_PARAMETER;
  1088. t.pin = pin;
  1089. t.state = state;
  1090. ret = saa7164_cmd_send(dev, unitid, SET_CUR,
  1091. EXU_GPIO_CONTROL, sizeof(t), &t);
  1092. if (ret != SAA_OK)
  1093. printk(KERN_ERR "%s() error, ret = 0x%x\n",
  1094. __func__, ret);
  1095. return ret;
  1096. }
  1097. int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
  1098. u8 pin)
  1099. {
  1100. return saa7164_api_modify_gpio(dev, unitid, pin, 1);
  1101. }
  1102. int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
  1103. u8 pin)
  1104. {
  1105. return saa7164_api_modify_gpio(dev, unitid, pin, 0);
  1106. }