w9966.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. /*
  2. Winbond w9966cf Webcam parport driver.
  3. Version 0.32
  4. Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. /*
  18. Supported devices:
  19. *Lifeview FlyCam Supra (using the Philips saa7111a chip)
  20. Does any other model using the w9966 interface chip exist ?
  21. Todo:
  22. *Add a working EPP mode, since DMA ECP read isn't implemented
  23. in the parport drivers. (That's why it's so sloow)
  24. *Add support for other ccd-control chips than the saa7111
  25. please send me feedback on what kind of chips you have.
  26. *Add proper probing. I don't know what's wrong with the IEEE1284
  27. parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
  28. and nibble read seems to be broken for some peripherals.
  29. *Add probing for onboard SRAM, port directions etc. (if possible)
  30. *Add support for the hardware compressed modes (maybe using v4l2)
  31. *Fix better support for the capture window (no skewed images, v4l
  32. interface to capt. window)
  33. *Probably some bugs that I don't know of
  34. Please support me by sending feedback!
  35. Changes:
  36. Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE
  37. and owner support for newer module locks
  38. */
  39. #include <linux/module.h>
  40. #include <linux/init.h>
  41. #include <linux/delay.h>
  42. #include <linux/videodev2.h>
  43. #include <media/v4l2-common.h>
  44. #include <media/v4l2-ioctl.h>
  45. #include <linux/parport.h>
  46. /*#define DEBUG*/ /* Undef me for production */
  47. #ifdef DEBUG
  48. #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a)
  49. #else
  50. #define DPRINTF(x...)
  51. #endif
  52. /*
  53. * Defines, simple typedefs etc.
  54. */
  55. #define W9966_DRIVERNAME "W9966CF Webcam"
  56. #define W9966_MAXCAMS 4 // Maximum number of cameras
  57. #define W9966_RBUFFER 2048 // Read buffer (must be an even number)
  58. #define W9966_SRAMSIZE 131072 // 128kb
  59. #define W9966_SRAMID 0x02 // check w9966cf.pdf
  60. // Empirically determined window limits
  61. #define W9966_WND_MIN_X 16
  62. #define W9966_WND_MIN_Y 14
  63. #define W9966_WND_MAX_X 705
  64. #define W9966_WND_MAX_Y 253
  65. #define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
  66. #define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
  67. // Keep track of our current state
  68. #define W9966_STATE_PDEV 0x01
  69. #define W9966_STATE_CLAIMED 0x02
  70. #define W9966_STATE_VDEV 0x04
  71. #define W9966_I2C_W_ID 0x48
  72. #define W9966_I2C_R_ID 0x49
  73. #define W9966_I2C_R_DATA 0x08
  74. #define W9966_I2C_R_CLOCK 0x04
  75. #define W9966_I2C_W_DATA 0x02
  76. #define W9966_I2C_W_CLOCK 0x01
  77. struct w9966_dev {
  78. unsigned char dev_state;
  79. unsigned char i2c_state;
  80. unsigned short ppmode;
  81. struct parport* pport;
  82. struct pardevice* pdev;
  83. struct video_device vdev;
  84. unsigned short width;
  85. unsigned short height;
  86. unsigned char brightness;
  87. signed char contrast;
  88. signed char color;
  89. signed char hue;
  90. unsigned long in_use;
  91. };
  92. /*
  93. * Module specific properties
  94. */
  95. MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
  96. MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
  97. MODULE_LICENSE("GPL");
  98. #ifdef MODULE
  99. static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""};
  100. #else
  101. static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
  102. #endif
  103. module_param_array(pardev, charp, NULL, 0);
  104. MODULE_PARM_DESC(pardev, "pardev: where to search for\n\
  105. \teach camera. 'aggressive' means brute-force search.\n\
  106. \tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\
  107. \tcam 1 to parport3 and search every parport for cam 2 etc...");
  108. static int parmode;
  109. module_param(parmode, int, 0);
  110. MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
  111. static int video_nr = -1;
  112. module_param(video_nr, int, 0);
  113. /*
  114. * Private data
  115. */
  116. static struct w9966_dev w9966_cams[W9966_MAXCAMS];
  117. /*
  118. * Private function declares
  119. */
  120. static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
  121. static inline int w9966_getState(struct w9966_dev* cam, int mask, int val);
  122. static inline void w9966_pdev_claim(struct w9966_dev *vdev);
  123. static inline void w9966_pdev_release(struct w9966_dev *vdev);
  124. static int w9966_rReg(struct w9966_dev* cam, int reg);
  125. static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
  126. #if 0
  127. static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
  128. #endif
  129. static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
  130. static int w9966_findlen(int near, int size, int maxlen);
  131. static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
  132. static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
  133. static int w9966_init(struct w9966_dev* cam, struct parport* port);
  134. static void w9966_term(struct w9966_dev* cam);
  135. static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
  136. static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state);
  137. static inline int w9966_i2c_getsda(struct w9966_dev* cam);
  138. static inline int w9966_i2c_getscl(struct w9966_dev* cam);
  139. static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
  140. #if 0
  141. static int w9966_i2c_rbyte(struct w9966_dev* cam);
  142. #endif
  143. static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
  144. unsigned int cmd, unsigned long arg);
  145. static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
  146. size_t count, loff_t *ppos);
  147. static int w9966_exclusive_open(struct inode *inode, struct file *file)
  148. {
  149. struct w9966_dev *cam = video_drvdata(file);
  150. return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0;
  151. }
  152. static int w9966_exclusive_release(struct inode *inode, struct file *file)
  153. {
  154. struct w9966_dev *cam = video_drvdata(file);
  155. clear_bit(0, &cam->in_use);
  156. return 0;
  157. }
  158. static const struct file_operations w9966_fops = {
  159. .owner = THIS_MODULE,
  160. .open = w9966_exclusive_open,
  161. .release = w9966_exclusive_release,
  162. .ioctl = w9966_v4l_ioctl,
  163. #ifdef CONFIG_COMPAT
  164. .compat_ioctl = v4l_compat_ioctl32,
  165. #endif
  166. .read = w9966_v4l_read,
  167. .llseek = no_llseek,
  168. };
  169. static struct video_device w9966_template = {
  170. .name = W9966_DRIVERNAME,
  171. .fops = &w9966_fops,
  172. .release = video_device_release_empty,
  173. };
  174. /*
  175. * Private function defines
  176. */
  177. // Set camera phase flags, so we know what to uninit when terminating
  178. static inline void w9966_setState(struct w9966_dev* cam, int mask, int val)
  179. {
  180. cam->dev_state = (cam->dev_state & ~mask) ^ val;
  181. }
  182. // Get camera phase flags
  183. static inline int w9966_getState(struct w9966_dev* cam, int mask, int val)
  184. {
  185. return ((cam->dev_state & mask) == val);
  186. }
  187. // Claim parport for ourself
  188. static inline void w9966_pdev_claim(struct w9966_dev* cam)
  189. {
  190. if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
  191. return;
  192. parport_claim_or_block(cam->pdev);
  193. w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
  194. }
  195. // Release parport for others to use
  196. static inline void w9966_pdev_release(struct w9966_dev* cam)
  197. {
  198. if (w9966_getState(cam, W9966_STATE_CLAIMED, 0))
  199. return;
  200. parport_release(cam->pdev);
  201. w9966_setState(cam, W9966_STATE_CLAIMED, 0);
  202. }
  203. // Read register from W9966 interface-chip
  204. // Expects a claimed pdev
  205. // -1 on error, else register data (byte)
  206. static int w9966_rReg(struct w9966_dev* cam, int reg)
  207. {
  208. // ECP, read, regtransfer, REG, REG, REG, REG, REG
  209. const unsigned char addr = 0x80 | (reg & 0x1f);
  210. unsigned char val;
  211. if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
  212. return -1;
  213. if (parport_write(cam->pport, &addr, 1) != 1)
  214. return -1;
  215. if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
  216. return -1;
  217. if (parport_read(cam->pport, &val, 1) != 1)
  218. return -1;
  219. return val;
  220. }
  221. // Write register to W9966 interface-chip
  222. // Expects a claimed pdev
  223. // -1 on error
  224. static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
  225. {
  226. // ECP, write, regtransfer, REG, REG, REG, REG, REG
  227. const unsigned char addr = 0xc0 | (reg & 0x1f);
  228. const unsigned char val = data;
  229. if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
  230. return -1;
  231. if (parport_write(cam->pport, &addr, 1) != 1)
  232. return -1;
  233. if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
  234. return -1;
  235. if (parport_write(cam->pport, &val, 1) != 1)
  236. return -1;
  237. return 0;
  238. }
  239. // Initialize camera device. Setup all internal flags, set a
  240. // default video mode, setup ccd-chip, register v4l device etc..
  241. // Also used for 'probing' of hardware.
  242. // -1 on error
  243. static int w9966_init(struct w9966_dev* cam, struct parport* port)
  244. {
  245. if (cam->dev_state != 0)
  246. return -1;
  247. cam->pport = port;
  248. cam->brightness = 128;
  249. cam->contrast = 64;
  250. cam->color = 64;
  251. cam->hue = 0;
  252. // Select requested transfer mode
  253. switch(parmode)
  254. {
  255. default: // Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
  256. case 0:
  257. if (port->modes & PARPORT_MODE_ECP)
  258. cam->ppmode = IEEE1284_MODE_ECP;
  259. else if (port->modes & PARPORT_MODE_EPP)
  260. cam->ppmode = IEEE1284_MODE_EPP;
  261. else
  262. cam->ppmode = IEEE1284_MODE_ECP;
  263. break;
  264. case 1: // hw- or sw-ecp
  265. cam->ppmode = IEEE1284_MODE_ECP;
  266. break;
  267. case 2: // hw- or sw-epp
  268. cam->ppmode = IEEE1284_MODE_EPP;
  269. break;
  270. }
  271. // Tell the parport driver that we exists
  272. cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
  273. if (cam->pdev == NULL) {
  274. DPRINTF("parport_register_device() failed\n");
  275. return -1;
  276. }
  277. w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
  278. w9966_pdev_claim(cam);
  279. // Setup a default capture mode
  280. if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
  281. DPRINTF("w9966_setup() failed.\n");
  282. return -1;
  283. }
  284. w9966_pdev_release(cam);
  285. // Fill in the video_device struct and register us to v4l
  286. memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
  287. video_set_drvdata(&cam->vdev, cam);
  288. if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
  289. return -1;
  290. w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
  291. // All ok
  292. printk(
  293. "w9966cf: Found and initialized a webcam on %s.\n",
  294. cam->pport->name
  295. );
  296. return 0;
  297. }
  298. // Terminate everything gracefully
  299. static void w9966_term(struct w9966_dev* cam)
  300. {
  301. // Unregister from v4l
  302. if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
  303. video_unregister_device(&cam->vdev);
  304. w9966_setState(cam, W9966_STATE_VDEV, 0);
  305. }
  306. // Terminate from IEEE1284 mode and release pdev block
  307. if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
  308. w9966_pdev_claim(cam);
  309. parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
  310. w9966_pdev_release(cam);
  311. }
  312. // Unregister from parport
  313. if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
  314. parport_unregister_device(cam->pdev);
  315. w9966_setState(cam, W9966_STATE_PDEV, 0);
  316. }
  317. }
  318. // Find a good length for capture window (used both for W and H)
  319. // A bit ugly but pretty functional. The capture length
  320. // have to match the downscale
  321. static int w9966_findlen(int near, int size, int maxlen)
  322. {
  323. int bestlen = size;
  324. int besterr = abs(near - bestlen);
  325. int len;
  326. for(len = size+1;len < maxlen;len++)
  327. {
  328. int err;
  329. if ( ((64*size) %len) != 0)
  330. continue;
  331. err = abs(near - len);
  332. // Only continue as long as we keep getting better values
  333. if (err > besterr)
  334. break;
  335. besterr = err;
  336. bestlen = len;
  337. }
  338. return bestlen;
  339. }
  340. // Modify capture window (if necessary)
  341. // and calculate downscaling
  342. // Return -1 on error
  343. static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor)
  344. {
  345. int maxlen = max - min;
  346. int len = *end - *beg + 1;
  347. int newlen = w9966_findlen(len, size, maxlen);
  348. int err = newlen - len;
  349. // Check for bad format
  350. if (newlen > maxlen || newlen < size)
  351. return -1;
  352. // Set factor (6 bit fixed)
  353. *factor = (64*size) / newlen;
  354. if (*factor == 64)
  355. *factor = 0x00; // downscale is disabled
  356. else
  357. *factor |= 0x80; // set downscale-enable bit
  358. // Modify old beginning and end
  359. *beg -= err / 2;
  360. *end += err - (err / 2);
  361. // Move window if outside borders
  362. if (*beg < min) {
  363. *end += min - *beg;
  364. *beg += min - *beg;
  365. }
  366. if (*end > max) {
  367. *beg -= *end - max;
  368. *end -= *end - max;
  369. }
  370. return 0;
  371. }
  372. // Setup the cameras capture window etc.
  373. // Expects a claimed pdev
  374. // return -1 on error
  375. static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
  376. {
  377. unsigned int i;
  378. unsigned int enh_s, enh_e;
  379. unsigned char scale_x, scale_y;
  380. unsigned char regs[0x1c];
  381. unsigned char saa7111_regs[] = {
  382. 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
  383. 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
  384. 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  385. 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
  386. };
  387. if (w*h*2 > W9966_SRAMSIZE)
  388. {
  389. DPRINTF("capture window exceeds SRAM size!.\n");
  390. w = 200; h = 160; // Pick default values
  391. }
  392. w &= ~0x1;
  393. if (w < 2) w = 2;
  394. if (h < 1) h = 1;
  395. if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W;
  396. if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H;
  397. cam->width = w;
  398. cam->height = h;
  399. enh_s = 0;
  400. enh_e = w*h*2;
  401. // Modify capture window if necessary and calculate downscaling
  402. if (
  403. w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
  404. w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0
  405. ) return -1;
  406. DPRINTF(
  407. "%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
  408. w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80
  409. );
  410. // Setup registers
  411. regs[0x00] = 0x00; // Set normal operation
  412. regs[0x01] = 0x18; // Capture mode
  413. regs[0x02] = scale_y; // V-scaling
  414. regs[0x03] = scale_x; // H-scaling
  415. // Capture window
  416. regs[0x04] = (x1 & 0x0ff); // X-start (8 low bits)
  417. regs[0x05] = (x1 & 0x300)>>8; // X-start (2 high bits)
  418. regs[0x06] = (y1 & 0x0ff); // Y-start (8 low bits)
  419. regs[0x07] = (y1 & 0x300)>>8; // Y-start (2 high bits)
  420. regs[0x08] = (x2 & 0x0ff); // X-end (8 low bits)
  421. regs[0x09] = (x2 & 0x300)>>8; // X-end (2 high bits)
  422. regs[0x0a] = (y2 & 0x0ff); // Y-end (8 low bits)
  423. regs[0x0c] = W9966_SRAMID; // SRAM-banks (1x 128kb)
  424. // Enhancement layer
  425. regs[0x0d] = (enh_s& 0x000ff); // Enh. start (0-7)
  426. regs[0x0e] = (enh_s& 0x0ff00)>>8; // Enh. start (8-15)
  427. regs[0x0f] = (enh_s& 0x70000)>>16; // Enh. start (16-17/18??)
  428. regs[0x10] = (enh_e& 0x000ff); // Enh. end (0-7)
  429. regs[0x11] = (enh_e& 0x0ff00)>>8; // Enh. end (8-15)
  430. regs[0x12] = (enh_e& 0x70000)>>16; // Enh. end (16-17/18??)
  431. // Misc
  432. regs[0x13] = 0x40; // VEE control (raw 4:2:2)
  433. regs[0x17] = 0x00; // ???
  434. regs[0x18] = cam->i2c_state = 0x00; // Serial bus
  435. regs[0x19] = 0xff; // I/O port direction control
  436. regs[0x1a] = 0xff; // I/O port data register
  437. regs[0x1b] = 0x10; // ???
  438. // SAA7111 chip settings
  439. saa7111_regs[0x0a] = cam->brightness;
  440. saa7111_regs[0x0b] = cam->contrast;
  441. saa7111_regs[0x0c] = cam->color;
  442. saa7111_regs[0x0d] = cam->hue;
  443. // Reset (ECP-fifo & serial-bus)
  444. if (w9966_wReg(cam, 0x00, 0x03) == -1)
  445. return -1;
  446. // Write regs to w9966cf chip
  447. for (i = 0; i < 0x1c; i++)
  448. if (w9966_wReg(cam, i, regs[i]) == -1)
  449. return -1;
  450. // Write regs to saa7111 chip
  451. for (i = 0; i < 0x20; i++)
  452. if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1)
  453. return -1;
  454. return 0;
  455. }
  456. /*
  457. * Ugly and primitive i2c protocol functions
  458. */
  459. // Sets the data line on the i2c bus.
  460. // Expects a claimed pdev.
  461. static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
  462. {
  463. if (state)
  464. cam->i2c_state |= W9966_I2C_W_DATA;
  465. else
  466. cam->i2c_state &= ~W9966_I2C_W_DATA;
  467. w9966_wReg(cam, 0x18, cam->i2c_state);
  468. udelay(5);
  469. }
  470. // Get peripheral clock line
  471. // Expects a claimed pdev.
  472. static inline int w9966_i2c_getscl(struct w9966_dev* cam)
  473. {
  474. const unsigned char state = w9966_rReg(cam, 0x18);
  475. return ((state & W9966_I2C_R_CLOCK) > 0);
  476. }
  477. // Sets the clock line on the i2c bus.
  478. // Expects a claimed pdev. -1 on error
  479. static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
  480. {
  481. unsigned long timeout;
  482. if (state)
  483. cam->i2c_state |= W9966_I2C_W_CLOCK;
  484. else
  485. cam->i2c_state &= ~W9966_I2C_W_CLOCK;
  486. w9966_wReg(cam, 0x18, cam->i2c_state);
  487. udelay(5);
  488. // we go to high, we also expect the peripheral to ack.
  489. if (state) {
  490. timeout = jiffies + 100;
  491. while (!w9966_i2c_getscl(cam)) {
  492. if (time_after(jiffies, timeout))
  493. return -1;
  494. }
  495. }
  496. return 0;
  497. }
  498. // Get peripheral data line
  499. // Expects a claimed pdev.
  500. static inline int w9966_i2c_getsda(struct w9966_dev* cam)
  501. {
  502. const unsigned char state = w9966_rReg(cam, 0x18);
  503. return ((state & W9966_I2C_R_DATA) > 0);
  504. }
  505. // Write a byte with ack to the i2c bus.
  506. // Expects a claimed pdev. -1 on error
  507. static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
  508. {
  509. int i;
  510. for (i = 7; i >= 0; i--)
  511. {
  512. w9966_i2c_setsda(cam, (data >> i) & 0x01);
  513. if (w9966_i2c_setscl(cam, 1) == -1)
  514. return -1;
  515. w9966_i2c_setscl(cam, 0);
  516. }
  517. w9966_i2c_setsda(cam, 1);
  518. if (w9966_i2c_setscl(cam, 1) == -1)
  519. return -1;
  520. w9966_i2c_setscl(cam, 0);
  521. return 0;
  522. }
  523. // Read a data byte with ack from the i2c-bus
  524. // Expects a claimed pdev. -1 on error
  525. #if 0
  526. static int w9966_i2c_rbyte(struct w9966_dev* cam)
  527. {
  528. unsigned char data = 0x00;
  529. int i;
  530. w9966_i2c_setsda(cam, 1);
  531. for (i = 0; i < 8; i++)
  532. {
  533. if (w9966_i2c_setscl(cam, 1) == -1)
  534. return -1;
  535. data = data << 1;
  536. if (w9966_i2c_getsda(cam))
  537. data |= 0x01;
  538. w9966_i2c_setscl(cam, 0);
  539. }
  540. return data;
  541. }
  542. #endif
  543. // Read a register from the i2c device.
  544. // Expects claimed pdev. -1 on error
  545. #if 0
  546. static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
  547. {
  548. int data;
  549. w9966_i2c_setsda(cam, 0);
  550. w9966_i2c_setscl(cam, 0);
  551. if (
  552. w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
  553. w9966_i2c_wbyte(cam, reg) == -1
  554. )
  555. return -1;
  556. w9966_i2c_setsda(cam, 1);
  557. if (w9966_i2c_setscl(cam, 1) == -1)
  558. return -1;
  559. w9966_i2c_setsda(cam, 0);
  560. w9966_i2c_setscl(cam, 0);
  561. if (
  562. w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 ||
  563. (data = w9966_i2c_rbyte(cam)) == -1
  564. )
  565. return -1;
  566. w9966_i2c_setsda(cam, 0);
  567. if (w9966_i2c_setscl(cam, 1) == -1)
  568. return -1;
  569. w9966_i2c_setsda(cam, 1);
  570. return data;
  571. }
  572. #endif
  573. // Write a register to the i2c device.
  574. // Expects claimed pdev. -1 on error
  575. static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
  576. {
  577. w9966_i2c_setsda(cam, 0);
  578. w9966_i2c_setscl(cam, 0);
  579. if (
  580. w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
  581. w9966_i2c_wbyte(cam, reg) == -1 ||
  582. w9966_i2c_wbyte(cam, data) == -1
  583. )
  584. return -1;
  585. w9966_i2c_setsda(cam, 0);
  586. if (w9966_i2c_setscl(cam, 1) == -1)
  587. return -1;
  588. w9966_i2c_setsda(cam, 1);
  589. return 0;
  590. }
  591. /*
  592. * Video4linux interfacing
  593. */
  594. static int w9966_v4l_do_ioctl(struct inode *inode, struct file *file,
  595. unsigned int cmd, void *arg)
  596. {
  597. struct w9966_dev *cam = video_drvdata(file);
  598. switch(cmd)
  599. {
  600. case VIDIOCGCAP:
  601. {
  602. static struct video_capability vcap = {
  603. .name = W9966_DRIVERNAME,
  604. .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
  605. .channels = 1,
  606. .maxwidth = W9966_WND_MAX_W,
  607. .maxheight = W9966_WND_MAX_H,
  608. .minwidth = 2,
  609. .minheight = 1,
  610. };
  611. struct video_capability *cap = arg;
  612. *cap = vcap;
  613. return 0;
  614. }
  615. case VIDIOCGCHAN:
  616. {
  617. struct video_channel *vch = arg;
  618. if(vch->channel != 0) // We only support one channel (#0)
  619. return -EINVAL;
  620. memset(vch,0,sizeof(*vch));
  621. strcpy(vch->name, "CCD-input");
  622. vch->type = VIDEO_TYPE_CAMERA;
  623. return 0;
  624. }
  625. case VIDIOCSCHAN:
  626. {
  627. struct video_channel *vch = arg;
  628. if(vch->channel != 0)
  629. return -EINVAL;
  630. return 0;
  631. }
  632. case VIDIOCGTUNER:
  633. {
  634. struct video_tuner *vtune = arg;
  635. if(vtune->tuner != 0)
  636. return -EINVAL;
  637. strcpy(vtune->name, "no tuner");
  638. vtune->rangelow = 0;
  639. vtune->rangehigh = 0;
  640. vtune->flags = VIDEO_TUNER_NORM;
  641. vtune->mode = VIDEO_MODE_AUTO;
  642. vtune->signal = 0xffff;
  643. return 0;
  644. }
  645. case VIDIOCSTUNER:
  646. {
  647. struct video_tuner *vtune = arg;
  648. if (vtune->tuner != 0)
  649. return -EINVAL;
  650. if (vtune->mode != VIDEO_MODE_AUTO)
  651. return -EINVAL;
  652. return 0;
  653. }
  654. case VIDIOCGPICT:
  655. {
  656. struct video_picture vpic = {
  657. cam->brightness << 8, // brightness
  658. (cam->hue + 128) << 8, // hue
  659. cam->color << 9, // color
  660. cam->contrast << 9, // contrast
  661. 0x8000, // whiteness
  662. 16, VIDEO_PALETTE_YUV422// bpp, palette format
  663. };
  664. struct video_picture *pic = arg;
  665. *pic = vpic;
  666. return 0;
  667. }
  668. case VIDIOCSPICT:
  669. {
  670. struct video_picture *vpic = arg;
  671. if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV))
  672. return -EINVAL;
  673. cam->brightness = vpic->brightness >> 8;
  674. cam->hue = (vpic->hue >> 8) - 128;
  675. cam->color = vpic->colour >> 9;
  676. cam->contrast = vpic->contrast >> 9;
  677. w9966_pdev_claim(cam);
  678. if (
  679. w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
  680. w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
  681. w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
  682. w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
  683. ) {
  684. w9966_pdev_release(cam);
  685. return -EIO;
  686. }
  687. w9966_pdev_release(cam);
  688. return 0;
  689. }
  690. case VIDIOCSWIN:
  691. {
  692. int ret;
  693. struct video_window *vwin = arg;
  694. if (vwin->flags != 0)
  695. return -EINVAL;
  696. if (vwin->clipcount != 0)
  697. return -EINVAL;
  698. if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
  699. return -EINVAL;
  700. if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
  701. return -EINVAL;
  702. // Update camera regs
  703. w9966_pdev_claim(cam);
  704. ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
  705. w9966_pdev_release(cam);
  706. if (ret != 0) {
  707. DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
  708. return -EIO;
  709. }
  710. return 0;
  711. }
  712. case VIDIOCGWIN:
  713. {
  714. struct video_window *vwin = arg;
  715. memset(vwin, 0, sizeof(*vwin));
  716. vwin->width = cam->width;
  717. vwin->height = cam->height;
  718. return 0;
  719. }
  720. // Unimplemented
  721. case VIDIOCCAPTURE:
  722. case VIDIOCGFBUF:
  723. case VIDIOCSFBUF:
  724. case VIDIOCKEY:
  725. case VIDIOCGFREQ:
  726. case VIDIOCSFREQ:
  727. case VIDIOCGAUDIO:
  728. case VIDIOCSAUDIO:
  729. return -EINVAL;
  730. default:
  731. return -ENOIOCTLCMD;
  732. }
  733. return 0;
  734. }
  735. static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
  736. unsigned int cmd, unsigned long arg)
  737. {
  738. return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl);
  739. }
  740. // Capture data
  741. static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
  742. size_t count, loff_t *ppos)
  743. {
  744. struct w9966_dev *cam = video_drvdata(file);
  745. unsigned char addr = 0xa0; // ECP, read, CCD-transfer, 00000
  746. unsigned char __user *dest = (unsigned char __user *)buf;
  747. unsigned long dleft = count;
  748. unsigned char *tbuf;
  749. // Why would anyone want more than this??
  750. if (count > cam->width * cam->height * 2)
  751. return -EINVAL;
  752. w9966_pdev_claim(cam);
  753. w9966_wReg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer
  754. w9966_wReg(cam, 0x00, 0x00); // Return to normal operation
  755. w9966_wReg(cam, 0x01, 0x98); // Enable capture
  756. // write special capture-addr and negotiate into data transfer
  757. if (
  758. (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 )||
  759. (parport_write(cam->pport, &addr, 1) != 1 )||
  760. (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0 )
  761. ) {
  762. w9966_pdev_release(cam);
  763. return -EFAULT;
  764. }
  765. tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
  766. if (tbuf == NULL) {
  767. count = -ENOMEM;
  768. goto out;
  769. }
  770. while(dleft > 0)
  771. {
  772. unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
  773. if (parport_read(cam->pport, tbuf, tsize) < tsize) {
  774. count = -EFAULT;
  775. goto out;
  776. }
  777. if (copy_to_user(dest, tbuf, tsize) != 0) {
  778. count = -EFAULT;
  779. goto out;
  780. }
  781. dest += tsize;
  782. dleft -= tsize;
  783. }
  784. w9966_wReg(cam, 0x01, 0x18); // Disable capture
  785. out:
  786. kfree(tbuf);
  787. w9966_pdev_release(cam);
  788. return count;
  789. }
  790. // Called once for every parport on init
  791. static void w9966_attach(struct parport *port)
  792. {
  793. int i;
  794. for (i = 0; i < W9966_MAXCAMS; i++)
  795. {
  796. if (w9966_cams[i].dev_state != 0) // Cam is already assigned
  797. continue;
  798. if (
  799. strcmp(pardev[i], "aggressive") == 0 ||
  800. strcmp(pardev[i], port->name) == 0
  801. ) {
  802. if (w9966_init(&w9966_cams[i], port) != 0)
  803. w9966_term(&w9966_cams[i]);
  804. break; // return
  805. }
  806. }
  807. }
  808. // Called once for every parport on termination
  809. static void w9966_detach(struct parport *port)
  810. {
  811. int i;
  812. for (i = 0; i < W9966_MAXCAMS; i++)
  813. if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
  814. w9966_term(&w9966_cams[i]);
  815. }
  816. static struct parport_driver w9966_ppd = {
  817. .name = W9966_DRIVERNAME,
  818. .attach = w9966_attach,
  819. .detach = w9966_detach,
  820. };
  821. // Module entry point
  822. static int __init w9966_mod_init(void)
  823. {
  824. int i;
  825. for (i = 0; i < W9966_MAXCAMS; i++)
  826. w9966_cams[i].dev_state = 0;
  827. return parport_register_driver(&w9966_ppd);
  828. }
  829. // Module cleanup
  830. static void __exit w9966_mod_term(void)
  831. {
  832. parport_unregister_driver(&w9966_ppd);
  833. }
  834. module_init(w9966_mod_init);
  835. module_exit(w9966_mod_term);