bt819.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:12k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.     bt819 - BT819A VideoStream Decoder (Rockwell Part)
  3.     Copyright (C) 1999 Mike Bernson <mike@mlb.org>
  4.     Copyright (C) 1998 Dave Perks <dperks@ibm.net>
  5.     Modifications for LML33/DC10plus unified driver
  6.     Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
  7.     
  8.     This code was modify/ported from the saa7111 driver written
  9.     by Dave Perks.
  10.     This program is free software; you can redistribute it and/or modify
  11.     it under the terms of the GNU General Public License as published by
  12.     the Free Software Foundation; either version 2 of the License, or
  13.     (at your option) any later version.
  14.     This program is distributed in the hope that it will be useful,
  15.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.     GNU General Public License for more details.
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program; if not, write to the Free Software
  20.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21. */
  22. #include <linux/module.h>
  23. #include <linux/init.h>
  24. #include <linux/delay.h>
  25. #include <linux/errno.h>
  26. #include <linux/fs.h>
  27. #include <linux/kernel.h>
  28. #include <linux/slab.h>
  29. #include <linux/mm.h>
  30. #include <linux/pci.h>
  31. #include <linux/signal.h>
  32. #include <linux/sched.h>
  33. #include <linux/videodev.h>
  34. #include <linux/i2c-old.h>
  35. #include <linux/video_decoder.h>
  36. #define DEBUG(x)       x /* Debug driver */
  37. /* ----------------------------------------------------------------------- */
  38. struct bt819 {
  39. struct i2c_bus *bus;
  40. int addr;
  41. unsigned char reg[32];
  42. int initialized;
  43. int norm;
  44. int input;
  45. int enable;
  46. int bright;
  47. int contrast;
  48. int hue;
  49. int sat;
  50. };
  51. struct timing {
  52. int hactive;
  53. int hdelay;
  54. int vactive;
  55. int vdelay;
  56. int hscale;
  57. int vscale;
  58. };
  59. struct timing timing_data[] = {
  60. {864 - 24, 2, 623, 1, 0x0504, 0x0000},
  61. {858 - 24, 2, 523, 1, 0x00f8, 0x0000},
  62. //      { 858-68, 64, 523, 1, 0x00f8, 0x0000 },
  63. };
  64. #define   I2C_BT819        0x8a
  65. #define   I2C_DELAY   10
  66. /* ----------------------------------------------------------------------- */
  67. static int bt819_write(struct bt819 *dev, unsigned char subaddr,
  68.        unsigned char data)
  69. {
  70. int ack;
  71. LOCK_I2C_BUS(dev->bus);
  72. i2c_start(dev->bus);
  73. i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
  74. i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
  75. ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
  76. dev->reg[subaddr] = data;
  77. i2c_stop(dev->bus);
  78. UNLOCK_I2C_BUS(dev->bus);
  79. return ack;
  80. }
  81. static int bt819_setbit(struct bt819 *dev, int subaddr, int bit, int data)
  82. {
  83. return bt819_write(dev, subaddr, (dev->reg[subaddr] & ~(1 << bit)) | (data ? (1 << bit) : 0));
  84. }
  85. static int bt819_write_block(struct bt819 *dev, unsigned const char *data,
  86.      unsigned int len)
  87. {
  88. int ack;
  89. unsigned subaddr;
  90. ack = 0;
  91. while (len > 1) {
  92. LOCK_I2C_BUS(dev->bus);
  93. i2c_start(dev->bus);
  94. i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
  95. ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
  96. ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++),
  97.  I2C_DELAY);
  98. len -= 2;
  99. while (len > 1 && *data == ++subaddr) {
  100. data++;
  101. ack =
  102.     i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
  103. len -= 2;
  104. }
  105. i2c_stop(dev->bus);
  106. UNLOCK_I2C_BUS(dev->bus);
  107. }
  108. return ack;
  109. }
  110. static int bt819_read(struct bt819 *dev, unsigned char subaddr)
  111. {
  112. int data;
  113. LOCK_I2C_BUS(dev->bus);
  114. i2c_start(dev->bus);
  115. i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
  116. i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
  117. i2c_start(dev->bus);
  118. i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
  119. data = i2c_readbyte(dev->bus, 1);
  120. i2c_stop(dev->bus);
  121. UNLOCK_I2C_BUS(dev->bus);
  122. return data;
  123. }
  124. static int bt819_init(struct i2c_device *device)
  125. {
  126. struct bt819 *decoder;
  127. static unsigned char init[] = {
  128. //0x1f, 0x00,     /* Reset */
  129. 0x01, 0x59, /* 0x01 input format */
  130. 0x02, 0x00, /* 0x02 temporal decimation */
  131. 0x03, 0x12, /* 0x03 Cropping msb */
  132. 0x04, 0x16, /* 0x04 Vertical Delay, lsb */
  133. 0x05, 0xe0, /* 0x05 Vertical Active lsb */
  134. 0x06, 0x80, /* 0x06 Horizontal Delay lsb */
  135. 0x07, 0xd0, /* 0x07 Horizontal Active lsb */
  136. 0x08, 0x00, /* 0x08 Horizontal Scaling msb */
  137. 0x09, 0xf8, /* 0x09 Horizontal Scaling lsb */
  138. 0x0a, 0x00, /* 0x0a Brightness control */
  139. 0x0b, 0x30, /* 0x0b Miscellaneous control */
  140. 0x0c, 0xd8, /* 0x0c Luma Gain lsb */
  141. 0x0d, 0xfe, /* 0x0d Chroma Gain (U) lsb */
  142. 0x0e, 0xb4, /* 0x0e Chroma Gain (V) msb */
  143. 0x0f, 0x00, /* 0x0f Hue control */
  144. 0x12, 0x04, /* 0x12 Output Format */
  145. 0x13, 0x20, /* 0x13 Vertial Scaling msb 0x60, */
  146. 0x14, 0x00, /* 0x14 Vertial Scaling lsb */
  147. 0x16, 0x04, /* 0x16 Video Timing Polarity 0x02, */
  148. 0x18, 0x68, /* 0x18 AGC Delay */
  149. 0x19, 0x5d, /* 0x19 Burst Gate Delay */
  150. 0x1a, 0x80, /* 0x1a ADC Interface */
  151. };
  152. struct timing *timing;
  153. decoder = device->data;
  154. timing = &timing_data[decoder->norm];
  155. init[3 * 2 - 1] = (((timing->vdelay >> 8) & 0x03) << 6) |
  156.     (((timing->vactive >> 8) & 0x03) << 4) |
  157.     (((timing->hdelay >> 8) & 0x03) << 2) |
  158.     ((timing->hactive >> 8) & 0x03);
  159. init[4 * 2 - 1] = timing->vdelay & 0xff;
  160. init[5 * 2 - 1] = timing->vactive & 0xff;
  161. init[6 * 2 - 1] = timing->hdelay & 0xff;
  162. init[7 * 2 - 1] = timing->hactive & 0xff;
  163. init[8 * 2 - 1] = timing->hscale >> 8;
  164. init[9 * 2 - 1] = timing->hscale & 0xff;
  165. bt819_write(decoder, 0x1f, 0x00);
  166. mdelay(1);
  167. return bt819_write_block(decoder, init, sizeof(init));
  168. }
  169. /* ----------------------------------------------------------------------- */
  170. static int bt819_attach(struct i2c_device *device)
  171. {
  172. int i;
  173. struct bt819 *decoder;
  174. MOD_INC_USE_COUNT;
  175. device->data = decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
  176. if (decoder == NULL) {
  177. MOD_DEC_USE_COUNT;
  178. return -ENOMEM;
  179. }
  180. memset(decoder, 0, sizeof(struct bt819));
  181. strcpy(device->name, "bt819");
  182. decoder->bus = device->bus;
  183. decoder->addr = device->addr;
  184. decoder->norm = VIDEO_MODE_NTSC;
  185. decoder->input = 0;
  186. decoder->enable = 1;
  187. decoder->bright = 32768;
  188. decoder->contrast = 32768;
  189. decoder->hue = 32768;
  190. decoder->sat = 32768;
  191. decoder->initialized = 0;
  192. i = bt819_init(device);
  193. if (i < 0) {
  194. printk(KERN_ERR "%s: bt819_attach: init status %dn",
  195.        decoder->bus->name, i);
  196. } else {
  197. printk(KERN_INFO "%s: bt819_attach: chip version %xn",
  198.        decoder->bus->name, bt819_read(decoder,
  199.       0x17) & 0x0f);
  200. }
  201. return 0;
  202. }
  203. static int bt819_detach(struct i2c_device *device)
  204. {
  205. kfree(device->data);
  206. MOD_DEC_USE_COUNT;
  207. return 0;
  208. }
  209. static int bt819_command(struct i2c_device *device, unsigned int cmd, void *arg)
  210. {
  211. int temp;
  212. struct bt819 *decoder = device->data;
  213. //return 0;
  214. if (!decoder->initialized) { // First call to bt819_init could be
  215. bt819_init(device); // without #FRST = 0
  216. decoder->initialized = 1;
  217. }
  218. switch (cmd) {
  219. case DECODER_GET_CAPABILITIES:
  220. {
  221. struct video_decoder_capability *cap = arg;
  222. cap->flags
  223.     = VIDEO_DECODER_PAL
  224.     | VIDEO_DECODER_NTSC | VIDEO_DECODER_CCIR;
  225. cap->inputs = 8;
  226. cap->outputs = 1;
  227. }
  228. break;
  229. case DECODER_GET_STATUS:
  230. {
  231. int *iarg = arg;
  232. int status;
  233. int res;
  234. status = bt819_read(decoder, 0x00);
  235. res = 0;
  236. if ((status & 0x80)) {
  237. res |= DECODER_STATUS_GOOD;
  238. }
  239. switch (decoder->norm) {
  240. case VIDEO_MODE_NTSC:
  241. res |= DECODER_STATUS_NTSC;
  242. break;
  243. case VIDEO_MODE_PAL:
  244. res |= DECODER_STATUS_PAL;
  245. break;
  246. default:
  247. case VIDEO_MODE_AUTO:
  248. if ((status & 0x10)) {
  249. res |= DECODER_STATUS_PAL;
  250. } else {
  251. res |= DECODER_STATUS_NTSC;
  252. }
  253. break;
  254. }
  255. res |= DECODER_STATUS_COLOR;
  256. *iarg = res;
  257. DEBUG(printk(KERN_INFO "%s-bt819: get status %xn",
  258.      decoder->bus->name, *iarg));
  259. }
  260. break;
  261. case DECODER_SET_NORM:
  262. {
  263. int *iarg = arg;
  264. struct timing *timing;
  265. DEBUG(printk(KERN_INFO "%s-bt819: set norm %xn",
  266.      decoder->bus->name, *iarg));
  267. if (*iarg == VIDEO_MODE_NTSC) {
  268. bt819_setbit(decoder, 0x01, 0, 1);
  269. bt819_setbit(decoder, 0x01, 1, 0);
  270. bt819_write(decoder, 0x18, 0x68);
  271. bt819_write(decoder, 0x19, 0x5d);
  272. //bt819_setbit(decoder, 0x1a,  5, 1);
  273. timing = &timing_data[VIDEO_MODE_NTSC];
  274. } else {
  275. bt819_setbit(decoder, 0x01, 0, 1);
  276. bt819_setbit(decoder, 0x01, 1, 1);
  277. bt819_write(decoder, 0x18, 0x7f);
  278. bt819_write(decoder, 0x19, 0x72);
  279. //bt819_setbit(decoder, 0x1a,  5, 0);
  280. timing = &timing_data[VIDEO_MODE_PAL];
  281. }
  282. bt819_write(decoder, 0x03,
  283.     (((timing->vdelay >> 8) & 0x03) << 6) |
  284.     (((timing->
  285.        vactive >> 8) & 0x03) << 4) |
  286.     (((timing->
  287.        hdelay >> 8) & 0x03) << 2) |
  288.     ((timing->hactive >> 8) & 0x03));
  289. bt819_write(decoder, 0x04, timing->vdelay & 0xff);
  290. bt819_write(decoder, 0x05, timing->vactive & 0xff);
  291. bt819_write(decoder, 0x06, timing->hdelay & 0xff);
  292. bt819_write(decoder, 0x07, timing->hactive & 0xff);
  293. bt819_write(decoder, 0x08, timing->hscale >> 8);
  294. bt819_write(decoder, 0x09, timing->hscale & 0xff);
  295. decoder->norm = *iarg;
  296. }
  297. break;
  298. case DECODER_SET_INPUT:
  299. {
  300. int *iarg = arg;
  301. DEBUG(printk(KERN_INFO "%s-bt819: set input %xn",
  302.      decoder->bus->name, *iarg));
  303. if (*iarg < 0 || *iarg > 7) {
  304. return -EINVAL;
  305. }
  306. if (decoder->input != *iarg) {
  307. decoder->input = *iarg;
  308. /* select mode */
  309. if (decoder->input == 0) {
  310. bt819_setbit(decoder, 0x0b, 6, 0);
  311. bt819_setbit(decoder, 0x1a, 1, 1);
  312. } else {
  313. bt819_setbit(decoder, 0x0b, 6, 1);
  314. bt819_setbit(decoder, 0x1a, 1, 0);
  315. }
  316. }
  317. }
  318. break;
  319. case DECODER_SET_OUTPUT:
  320. {
  321. int *iarg = arg;
  322. DEBUG(printk(KERN_INFO "%s-bt819: set output %xn",
  323.      decoder->bus->name, *iarg));
  324. /* not much choice of outputs */
  325. if (*iarg != 0) {
  326. return -EINVAL;
  327. }
  328. }
  329. break;
  330. case DECODER_ENABLE_OUTPUT:
  331. {
  332. int *iarg = arg;
  333. int enable = (*iarg != 0);
  334. DEBUG(printk
  335.       (KERN_INFO "%s-bt819: enable output %xn",
  336.        decoder->bus->name, *iarg));
  337. if (decoder->enable != enable) {
  338. decoder->enable = enable;
  339. if (decoder->enable) {
  340. bt819_setbit(decoder, 0x16, 7, 0);
  341. } else {
  342. bt819_setbit(decoder, 0x16, 7, 1);
  343. }
  344. }
  345. }
  346. break;
  347. case DECODER_SET_PICTURE:
  348. {
  349. struct video_picture *pic = arg;
  350. DEBUG(printk
  351.       (KERN_INFO
  352.        "%s-bt819: set picture brightness %d contrast %d colour %dn",
  353.        decoder->bus->name, pic->brightness,
  354.        pic->contrast, pic->colour));
  355. if (decoder->bright != pic->brightness) {
  356. /* We want -128 to 127 we get 0-65535 */
  357. decoder->bright = pic->brightness;
  358. bt819_write(decoder, 0x0a,
  359.     (decoder->bright >> 8) - 128);
  360. }
  361. if (decoder->contrast != pic->contrast) {
  362. /* We want 0 to 511 we get 0-65535 */
  363. decoder->contrast = pic->contrast;
  364. bt819_write(decoder, 0x0c,
  365.     (decoder->
  366.      contrast >> 7) & 0xff);
  367. bt819_setbit(decoder, 0x0b, 2,
  368.      ((decoder->
  369.        contrast >> 15) & 0x01));
  370. }
  371. if (decoder->sat != pic->colour) {
  372. /* We want 0 to 511 we get 0-65535 */
  373. decoder->sat = pic->colour;
  374. bt819_write(decoder, 0x0d,
  375.     (decoder->sat >> 7) & 0xff);
  376. bt819_setbit(decoder, 0x0b, 1,
  377.      ((decoder->
  378.        sat >> 15) & 0x01));
  379. temp = (decoder->sat * 201) / 237;
  380. bt819_write(decoder, 0x0e,
  381.     (temp >> 7) & 0xff);
  382. bt819_setbit(decoder, 0x0b, 0,
  383.      (temp >> 15) & 0x01);
  384. }
  385. if (decoder->hue != pic->hue) {
  386. /* We want -128 to 127 we get 0-65535 */
  387. decoder->hue = pic->hue;
  388. bt819_write(decoder, 0x0f,
  389.     128 - (decoder->hue >> 8));
  390. }
  391. }
  392. break;
  393. default:
  394. return -EINVAL;
  395. }
  396. return 0;
  397. }
  398. /* ----------------------------------------------------------------------- */
  399. static struct i2c_driver i2c_driver_bt819 = {
  400. "bt819", /* name */
  401. I2C_DRIVERID_VIDEODECODER, /* ID */
  402. I2C_BT819, I2C_BT819 + 1,
  403. bt819_attach,
  404. bt819_detach,
  405. bt819_command
  406. };
  407. EXPORT_NO_SYMBOLS;
  408. static int bt819_setup(void)
  409. {
  410. return i2c_register_driver(&i2c_driver_bt819);
  411. }
  412. static void bt819_exit(void)
  413. {
  414. i2c_unregister_driver(&i2c_driver_bt819);
  415. }
  416. module_init(bt819_setup);
  417. module_exit(bt819_exit);
  418. MODULE_LICENSE("GPL");