saa7111.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* 
  2.     saa7111 - Philips SAA7111A video decoder driver version 0.0.3
  3.     Copyright (C) 1998 Dave Perks <dperks@ibm.net>
  4.     Slight changes for video timing and attachment output by
  5.     Wolfgang Scherr <scherr@net4you.net>
  6.     
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <linux/config.h>
  20. #include <linux/init.h>
  21. #include <linux/module.h>
  22. #include <linux/delay.h>
  23. #include <linux/errno.h>
  24. #include <linux/fs.h>
  25. #include <linux/kernel.h>
  26. #include <linux/major.h>
  27. #include <linux/slab.h>
  28. #include <linux/mm.h>
  29. #include <linux/sched.h>
  30. #include <linux/videodev.h>
  31. #include <linux/version.h>
  32. #include <linux/i2c-old.h>
  33. #include <linux/video_decoder.h>
  34. #define DEBUG(x) /* Debug driver */
  35. /* ----------------------------------------------------------------------- */
  36. struct saa7111 {
  37. struct i2c_bus *bus;
  38. int addr;
  39. unsigned char reg[32];
  40. int norm;
  41. int input;
  42. int enable;
  43. int bright;
  44. int contrast;
  45. int hue;
  46. int sat;
  47. };
  48. #define   I2C_SAA7111        0x48
  49. #define   I2C_DELAY   10
  50. /* ----------------------------------------------------------------------- */
  51. static int saa7111_write(struct saa7111 *dev, unsigned char subaddr,
  52.  unsigned char data)
  53. {
  54. int ack;
  55. LOCK_I2C_BUS(dev->bus);
  56. i2c_start(dev->bus);
  57. i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
  58. i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
  59. ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
  60. dev->reg[subaddr] = data;
  61. i2c_stop(dev->bus);
  62. UNLOCK_I2C_BUS(dev->bus);
  63. return ack;
  64. }
  65. static int saa7111_write_block(struct saa7111 *dev,
  66.        unsigned const char *data, unsigned int len)
  67. {
  68. int ack = -1;
  69. unsigned subaddr;
  70. while (len > 1) {
  71. LOCK_I2C_BUS(dev->bus);
  72. i2c_start(dev->bus);
  73. i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
  74. ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
  75. ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
  76. len -= 2;
  77. while (len > 1 && *data == ++subaddr) {
  78. data++;
  79. ack =
  80.     i2c_sendbyte(dev->bus,
  81.  (dev->reg[subaddr] =
  82.   *data++), I2C_DELAY);
  83. len -= 2;
  84. }
  85. i2c_stop(dev->bus);
  86. UNLOCK_I2C_BUS(dev->bus);
  87. }
  88. return ack;
  89. }
  90. static int saa7111_read(struct saa7111 *dev, unsigned char subaddr)
  91. {
  92. int data;
  93. LOCK_I2C_BUS(dev->bus);
  94. i2c_start(dev->bus);
  95. i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
  96. i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
  97. i2c_start(dev->bus);
  98. i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
  99. data = i2c_readbyte(dev->bus, 1);
  100. i2c_stop(dev->bus);
  101. UNLOCK_I2C_BUS(dev->bus);
  102. return data;
  103. }
  104. /* ----------------------------------------------------------------------- */
  105. static int saa7111_attach(struct i2c_device *device)
  106. {
  107. int i;
  108. struct saa7111 *decoder;
  109. static const unsigned char init[] = {
  110. 0x00, 0x00, /* 00 - ID byte */
  111. 0x01, 0x00, /* 01 - reserved */
  112. /*front end */
  113. 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
  114. 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
  115. 0x04, 0x00, /* 04 - GAI1=256 */
  116. 0x05, 0x00, /* 05 - GAI2=256 */
  117. /* decoder */
  118. 0x06, 0xf3, /* 06 - HSB at  13(50Hz) /  17(60Hz) pixels after end of last line */
  119. 0x07, 0x13, /* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
  120. 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
  121. 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
  122. 0x0a, 0x80, /* 0a - BRIG=128 */
  123. 0x0b, 0x47, /* 0b - CONT=1.109 */
  124. 0x0c, 0x40, /* 0c - SATN=1.0 */
  125. 0x0d, 0x00, /* 0d - HUE=0 */
  126. 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
  127. 0x0f, 0x00, /* 0f - reserved */
  128. #ifndef CONFIG_ARCH_NETWINDER
  129. 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
  130. #else
  131. 0x10, 0xc8, /* 10 - OFTS=YUV-CCIR656, HDEL=0, VLRN=1, YDEL=0 */
  132. #endif
  133. 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
  134. 0x12, 0x00, /* 12 - output control 2 */
  135. 0x13, 0x00, /* 13 - output control 3 */
  136. 0x14, 0x00, /* 14 - reserved */
  137. 0x15, 0x00, /* 15 - VBI */
  138. 0x16, 0x00, /* 16 - VBI */
  139. 0x17, 0x00, /* 17 - VBI */
  140. };
  141. MOD_INC_USE_COUNT;
  142. device->data = decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
  143. if (decoder == NULL)
  144. {
  145. MOD_DEC_USE_COUNT;
  146. return -ENOMEM;
  147. }
  148. memset(decoder, 0, sizeof(struct saa7111));
  149. strcpy(device->name, "saa7111");
  150. decoder->bus = device->bus;
  151. decoder->addr = device->addr;
  152. decoder->norm = VIDEO_MODE_NTSC;
  153. decoder->input = 0;
  154. decoder->enable = 1;
  155. decoder->bright = 32768;
  156. decoder->contrast = 32768;
  157. decoder->hue = 32768;
  158. decoder->sat = 32768;
  159. i = saa7111_write_block(decoder, init, sizeof(init));
  160. if (i < 0) {
  161. printk(KERN_ERR "%s_attach: init status %dn",
  162.        device->name, i);
  163. } else {
  164. printk(KERN_INFO "%s_attach: chip version %xn",
  165.        device->name, saa7111_read(decoder, 0x00) >> 4);
  166. }
  167. return 0;
  168. }
  169. static int saa7111_detach(struct i2c_device *device)
  170. {
  171. kfree(device->data);
  172. MOD_DEC_USE_COUNT;
  173. return 0;
  174. }
  175. static int saa7111_command(struct i2c_device *device, unsigned int cmd,
  176.    void *arg)
  177. {
  178. struct saa7111 *decoder = device->data;
  179. switch (cmd) {
  180. #if defined(DECODER_DUMP)
  181. case DECODER_DUMP:
  182. {
  183. int i;
  184. for (i = 0; i < 32; i += 16) {
  185. int j;
  186. printk("KERN_DEBUG %s: %03x", device->name,
  187.        i);
  188. for (j = 0; j < 16; ++j) {
  189. printk(" %02x",
  190.        saa7111_read(decoder,
  191.     i + j));
  192. }
  193. printk("n");
  194. }
  195. }
  196. break;
  197. #endif /* defined(DECODER_DUMP) */
  198. case DECODER_GET_CAPABILITIES:
  199. {
  200. struct video_decoder_capability *cap = arg;
  201. cap->flags
  202.     = VIDEO_DECODER_PAL
  203.     | VIDEO_DECODER_NTSC
  204.     | VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
  205. cap->inputs = 8;
  206. cap->outputs = 1;
  207. }
  208. break;
  209. case DECODER_GET_STATUS:
  210. {
  211. int *iarg = arg;
  212. int status;
  213. int res;
  214. status = saa7111_read(decoder, 0x1f);
  215. res = 0;
  216. if ((status & (1 << 6)) == 0) {
  217. res |= DECODER_STATUS_GOOD;
  218. }
  219. switch (decoder->norm) {
  220. case VIDEO_MODE_NTSC:
  221. res |= DECODER_STATUS_NTSC;
  222. break;
  223. case VIDEO_MODE_PAL:
  224. res |= DECODER_STATUS_PAL;
  225. break;
  226. default:
  227. case VIDEO_MODE_AUTO:
  228. if ((status & (1 << 5)) != 0) {
  229. res |= DECODER_STATUS_NTSC;
  230. } else {
  231. res |= DECODER_STATUS_PAL;
  232. }
  233. break;
  234. }
  235. if ((status & (1 << 0)) != 0) {
  236. res |= DECODER_STATUS_COLOR;
  237. }
  238. *iarg = res;
  239. }
  240. break;
  241. case DECODER_SET_NORM:
  242. {
  243. int *iarg = arg;
  244. switch (*iarg) {
  245. case VIDEO_MODE_NTSC:
  246. saa7111_write(decoder, 0x08,
  247.       (decoder->
  248.        reg[0x08] & 0x3f) | 0x40);
  249. break;
  250. case VIDEO_MODE_PAL:
  251. saa7111_write(decoder, 0x08,
  252.       (decoder->
  253.        reg[0x08] & 0x3f) | 0x00);
  254. break;
  255. case VIDEO_MODE_AUTO:
  256. saa7111_write(decoder, 0x08,
  257.       (decoder->
  258.        reg[0x08] & 0x3f) | 0x80);
  259. break;
  260. default:
  261. return -EINVAL;
  262. }
  263. decoder->norm = *iarg;
  264. }
  265. break;
  266. case DECODER_SET_INPUT:
  267. {
  268. int *iarg = arg;
  269. if (*iarg < 0 || *iarg > 7) {
  270. return -EINVAL;
  271. }
  272. if (decoder->input != *iarg) {
  273. decoder->input = *iarg;
  274. /* select mode */
  275. saa7111_write(decoder, 0x02,
  276.       (decoder->
  277.        reg[0x02] & 0xf8) |
  278.       decoder->input);
  279. /* bypass chrominance trap for modes 4..7 */
  280. saa7111_write(decoder, 0x09,
  281.       (decoder->
  282.        reg[0x09] & 0x7f) |
  283.       ((decoder->input >
  284. 3) ? 0x80 : 0));
  285. }
  286. }
  287. break;
  288. case DECODER_SET_OUTPUT:
  289. {
  290. int *iarg = arg;
  291. /* not much choice of outputs */
  292. if (*iarg != 0) {
  293. return -EINVAL;
  294. }
  295. }
  296. break;
  297. case DECODER_ENABLE_OUTPUT:
  298. {
  299. int *iarg = arg;
  300. int enable = (*iarg != 0);
  301. if (decoder->enable != enable) {
  302. decoder->enable = enable;
  303. // RJ: If output should be disabled (for playing videos), we also need a open PLL.
  304. //     The input is set to 0 (where no input source is connected), although this
  305. //     is not necessary.
  306. //
  307. //     If output should be enabled, we have to reverse the above.
  308. if (decoder->enable) {
  309. saa7111_write(decoder, 0x02,
  310.       (decoder->
  311.        reg[0x02] & 0xf8) |
  312.       decoder->input);
  313. saa7111_write(decoder, 0x08,
  314.       (decoder->
  315.        reg[0x08] & 0xfb));
  316. saa7111_write(decoder, 0x11,
  317.       (decoder->
  318.        reg[0x11] & 0xf3) |
  319.       0x0c);
  320. } else {
  321. saa7111_write(decoder, 0x02,
  322.       (decoder->
  323.        reg[0x02] & 0xf8));
  324. saa7111_write(decoder, 0x08,
  325.       (decoder->
  326.        reg[0x08] & 0xfb) |
  327.       0x04);
  328. saa7111_write(decoder, 0x11,
  329.       (decoder->
  330.        reg[0x11] & 0xf3));
  331. }
  332. }
  333. }
  334. break;
  335. case DECODER_SET_PICTURE:
  336. {
  337. struct video_picture *pic = arg;
  338. if (decoder->bright != pic->brightness) {
  339. /* We want 0 to 255 we get 0-65535 */
  340. decoder->bright = pic->brightness;
  341. saa7111_write(decoder, 0x0a,
  342.       decoder->bright >> 8);
  343. }
  344. if (decoder->contrast != pic->contrast) {
  345. /* We want 0 to 127 we get 0-65535 */
  346. decoder->contrast = pic->contrast;
  347. saa7111_write(decoder, 0x0b,
  348.       decoder->contrast >> 9);
  349. }
  350. if (decoder->sat != pic->colour) {
  351. /* We want 0 to 127 we get 0-65535 */
  352. decoder->sat = pic->colour;
  353. saa7111_write(decoder, 0x0c,
  354.       decoder->sat >> 9);
  355. }
  356. if (decoder->hue != pic->hue) {
  357. /* We want -128 to 127 we get 0-65535 */
  358. decoder->hue = pic->hue;
  359. saa7111_write(decoder, 0x0d,
  360.       (decoder->hue - 32768) >> 8);
  361. }
  362. }
  363. break;
  364. default:
  365. return -EINVAL;
  366. }
  367. return 0;
  368. }
  369. /* ----------------------------------------------------------------------- */
  370. static struct i2c_driver i2c_driver_saa7111 = {
  371. "saa7111", /* name */
  372. I2C_DRIVERID_VIDEODECODER, /* ID */
  373. I2C_SAA7111, I2C_SAA7111 + 1,
  374. saa7111_attach,
  375. saa7111_detach,
  376. saa7111_command
  377. };
  378. EXPORT_NO_SYMBOLS;
  379. static int saa7111_init(void)
  380. {
  381. return i2c_register_driver(&i2c_driver_saa7111);
  382. }
  383. static void saa7111_exit(void)
  384. {
  385. i2c_unregister_driver(&i2c_driver_saa7111);
  386. }
  387. module_init(saa7111_init);
  388. module_exit(saa7111_exit);
  389. MODULE_LICENSE("GPL");