zr36060.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:14k
- /*
- * for the Matrox Marvel G200 and Rainbow Runner-G series
- *
- * This module is an interface to the ZR3606 jpeg codec chip.
- *
- * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- *****************************************************************************
- */
- #ifndef __KERNEL__
- #define __KERNEL__
- #endif
- #ifndef MODULE
- #define MODULE
- #endif
- #include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <asm/io.h>
- #include <linux/i2c.h>
- #include "mgavideo.h"
- #include "zr36060.h"
- #define dprintk if (debug) printk
- #define XGENIOCTRL 0x2a
- #define XGENIODATA 0x2b
- static int debug = 1; /* insmod parameter */
- /****************************************************************************
- * linux kernel module api
- ****************************************************************************/
- #ifdef MODULE
- int init_module(void)
- #else
- int zr36060_init(void)
- #endif
- {
- return 0;
- }
- #ifdef MODULE
- void cleanup_module(void)
- {
- }
- #endif
- #ifdef NEVER
- static void
- zr36060_codechostptr(struct codec *codec, int size)
- {
- writew(zr->codechostptr, size/8);
- }
- #endif
- static int
- zr36060_load_memory(struct codec *codec)
- {
- int i;
- char status;
- char data[1];
- data[0] = 0x80;
- codec->codec_write_memory(codec, data, 0, 1);
- for(i=0; i < 1000; i++) {
- codec->codec_read_memory(codec, &status, 1, 1);
- if ((status & 0x80) == 0) {
- return 0;
- }
- udelay(10);
- }
- printk("zr36060: load from memory did not complete status=0x%xn",
- status);
- return -1;
- }
- static u8 SOF[19] = {
- 0xff, 0xc0, /* Start of frame marker */
- 0x00, 0x11, /* Length of this segment */
- 0x08, /* Precision */
- 240/8, 240&0xff, /* number of lines */
- 704/8, 704&0xff, /* line length */
- 3, /* number of components */
- 0, 0x21, 0, /* Y component */
- 1, 0x11, 1, /* U component */
- 2, 0x11, 1 /* V component */
- };
- static u8 SOS[] = {
- 0xff, 0xda, /* start of Scan marker */
- 0x00, 0x0c, /* lenght of this segment */
- 0x03, /* number of components */
- 0x00, 0x00, /* Y component */
- 0x01, 0x11, /* U component */
- 0x02, 0x11, /* V component */
- 0x00, 0x3f, 0x00 /* constant */
- };
- static u8 DRI[] = {
- 0xff, 0xdd, /* define Restart Interval */
- 0x00, 0x04, /* length of this segment */
- 0x00, 0x08, /* lenght of restart interval in mcu units */
- };
- static u8 DQT[] = {
- 0xff, 0xdb, /* DQT marker */
- 0x00, 0x84, /* DQT length */
- 0x00, /* table ID 0 */
- 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
- 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
- 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
- 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
- 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
- 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
- 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
- 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
- 0x01, /* table ID 1 */
- 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
- 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
- };
- static u8 DHT[] = {
- 0xff, 0xc4, /* DHT marker */
- 0x01, 0xa2, /* DHT length */
- 0x00, /* table class 0, ID 0 */
- 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, /* # codes of length 1..8 */
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* # codes of length 8..16 */
- 0x00, /* values for codes of length 2 */
- 0x01, 0x02, 0x03, 0x04, 0x05, /* values for codes of length 3 */
- 0x06, /* values for codes of length 4 */
- 0x07, /* values for codes of length 5 */
- 0x08, /* values for codes of length 6 */
- 0x09, /* values for codes of length 7 */
- 0x0a, /* values for codes of length 8 */
- 0x0b, /* values for codes of length 9 */
- 0x01, /* table class 0, ID 1 */
- 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* # codes of length 1..8 */
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* # codes of length 9..16 */
- 0x00, 0x01, 0x02, /* values for codes of length 2 */
- 0x03, /* values for codes of length 3 */
- 0x04, /* values for codes of length 4 */
- 0x05, /* values for codes of length 5 */
- 0x06, /* values for codes of length 6 */
- 0x07, /* values for codes of length 7 */
- 0x08, /* values for codes of length 8 */
- 0x09, /* values for codes of length 9 */
- 0x0a, /* values for codes of length 10 */
- 0x0b, /* values for codes of length 11 */
- 0x10,
- 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- 0xf9, 0xfa, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04,
- 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00,
- 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
- 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
- 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08,
- 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23,
- 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a,
- 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
- 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35,
- 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
- 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55,
- 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
- 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
- 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84,
- 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
- 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2,
- 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
- 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
- 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8,
- 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
- 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5,
- 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
- };
- static u8 APP[] = {
- 0xff, 0xe0, /* APP marker */
- 0x00, 0x02, /* APP length */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- static u8 COM[] = {
- 0xff, 0xfe, /* COM marker */
- 0x00, 0x02, /* COM length */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
-
- static int
- zr36060_memory(struct codec *codec, int width, int height,
- int compress_mode, int quality)
- {
- u8 sof[19];
- u8 data[96];
- u32 size;
- data[0] = 0x01;
- codec->codec_write_memory(codec, data, 0, 1);
- data[0x02] = 0x01; /* slave mode, 8 bit buss */
- if (compress_mode) {
- data[0x03] = 0xa4; /* compress pass, variable scaling */
- } else {
- data[0x03] = 0x00; /* decompress pass */
- }
- data[0x04] = 0x00; /* reserved */
- data[0x05] = 0xff; /* max block code volume in bits (510) */
- data[0x06] = 0x38; /* Marks DRI, DQT, DHT */
- data[0x07] = 0x00; /* interrupts none */
- size = (width * height) * 16;
- size = (size * quality) / 400;
- if (size < 8192)
- size = 8192;
- if ((size * 2)> ((256 * 1024) * 7))
- size = (256 * 1024 * 7);
- data[0x09] = (size >> 24) & 0xff;
- data[0x0a] = (size >> 16) & 0xff;
- data[0x0b] = (size >> 8) & 0xff;
- data[0x0c] = size & 0xff;
- data[0x11] = 0x01; /* Scale Factor 1:1 */
- data[0x12] = 0x00;
- data[0x13] = 0xff; /* Allocation factor Must be 0xffffff */
- data[0x14] = 0xff;
- data[0x15] = 0xff;
- data[0x24] = 0x00; /* Test Control Must be 0x0000 */
- data[0x25] = 0x00;
- data[0x30] = 0x40;
- data[0x31] = 0x21;
- data[0x32] = 0x00; /* No scaling */
- data[0x33] = 0x80; /* Background color y */
- data[0x34] = 0xe0; /* Background color u */
- data[0x35] = 0xe0; /* Background color v */
- data[0x36] = 524 >> 8; /* Vtotal for sync master */
- data[0x37] = 524 & 0xff;
- data[0x38] = 857 >> 8; /* Htotal for sync master */
- data[0x39] = 857 & 0xff;
- data[0x3a] = 5; /* Vsync for sync master */
- data[0x3b] = 31; /* Hsync for sync master */
- data[0x3c] = 11; /* BVstart for sync master */
- data[0x3d] = 99; /* BHstart for sync master */
- data[0x3e] = 241 >> 8; /* BVend for sync master */
- data[0x3f] = 241;
- data[0x40] = 720 >> 8; /* BHend for sync master */
- data[0x41] = 720 & 0xff;
- data[0x42] = 11 >> 8; /* VSTART for active area */
- data[0x43] = 11;
- data[0x44] = 262 >> 8; /* VEND for active area */
- data[0x45] = 262 & 0xff;
- data[0x46] = 12 >> 8; /* HSTART for active area */
- data[0x47] = 12;
- data[0x48] = 720 >> 8; /* HEND for active area */
- data[0x49] = 720 & 0xff;
- data[0x4a] = 12 >> 8;
- data[0x4b] = 12;
- data[0x4c] = height >> 8;
- data[0x4d] = height;
- data[0x4e] = 11 >> 8;
- data[0x4f] = 11;
- data[0x50] = width >> 8;
- data[0x51] = width;
- /* set video mode */
- memcpy(sof, SOF, sizeof(sof));
- sof[5] = width >> 8;
- sof[6] = width;
- sof[7] = height >> 8;
- sof[8] = height;
- if (codec->codec_write_memory(codec, &data[2], 0x02, 6))
- return -1;
- if (codec->codec_write_memory(codec, &data[9], 0x09, 4))
- return -1;
- if (codec->codec_write_memory(codec, &data[0x11], 0x11, 5))
- return -1;
- if (codec->codec_write_memory(codec, &data[0x24], 0x24, 2))
- return -1;
- if (codec->codec_write_memory(codec, &data[0x30], 0x30, 34))
- return -1;
- if (codec->codec_write_memory(codec, sof, 0x60, sizeof(sof)))
- return -1;
- if (codec->codec_write_memory(codec, SOS, 0x7a, sizeof(SOS)))
- return -1;
- if (codec->codec_write_memory(codec, DRI, 0xc0, sizeof(DRI)))
- return -1;
- if (codec->codec_write_memory(codec, DQT, 0xcc, sizeof(DQT)))
- return -1;
- if (codec->codec_write_memory(codec, DHT, 0x1d4, sizeof(DHT)))
- return -1;
- if (codec->codec_write_memory(codec, APP, 0x380, sizeof(APP)))
- return -1;
- if (codec->codec_write_memory(codec, COM, 0x3c0, sizeof(COM)))
- return -1;
- return zr36060_load_memory(codec);
- }
- int
- zr36060_interrupt(struct codec *codec)
- {
- printk("zr36060: command compelete interruptn");
- #ifdef NEVER
- zr->state = ZR_IDLE_STATE;
- /* remove pending command complete */
- writeb(VI_CMDCMPL, zr->viclear);
- #endif
- return 0;
- }
- int
- zr36060_compress_image(struct codec *codec)
- {
- printk("zr36060: compress imagen");
- if (codec->state != ZR_IDLE_STATE) {
- printk("zr36060: compression image but zr36060 not idlen");
- return -1;
- }
- /* for now compress the whole frame */
- if (zr36060_memory(codec, 704, 240, 1, 100))
- return -1;
- /* Start image compressing */
- (*codec->codec_start)(codec);
- printk("zr36060: compression startedn");
- mdelay(1000);
- {
- struct mga_dev *mga;
- char data;
- int i;
- int *ptr;
- codec->codec_read_memory(codec, &data, 0x08, 1);
- printk("zr36060: interrupt status: %xn", data);
- printk("zr36060: image_data: ");
- mga = codec->private;
- ptr = (int *)mga->interface_base;
- for(i=0; i < 16; i++) {
- printk("%4x ", *ptr++);
- }
- printk("n");
- }
- return 0;
- }
- int
- zr36060_decompress_image(struct codec *codec)
- {
- return 0;
- }
- int
- zr36060_attach(struct codec *codec)
- {
- char chip_id[2];
- if (debug)
- printk("zr36060: reseting zr36060n");
- codec->codec_reset(codec);
- /* read id from zr36060 */
- if (debug)
- printk("zr36060: reading chip idn");
- if (codec->codec_read_memory(codec, chip_id, 0x22, 2)) {
- printk("zr36060: Read errorn");
- return -1;
- }
- if (chip_id[0] == 0x33) {
- printk("zr36060: zr36060 found revision %xn", chip_id[1]);
- } else {
- printk("zr36060: zr36060 not found (%x %x)n",
- chip_id[0], chip_id[1]);
- return -1;
- }
- if (debug)
- printk("zr36060: Loading default parmetersn");
- zr36060_memory(codec, 704, 240, 1, 100);
- #ifdef NEVER
- MOD_INC_USE_COUNT;
- #endif
- return 0;
- }
- int
- zr36060_deattach(struct codec *codec)
- {
- #ifdef NEVER
- /* reset the codec interface */
- writeb(0x00, zr->codecctl);
- writeb(0x01, zr->codecctl);
- writeb(0x00, zr->codecctl);
- MOD_DEC_USE_COUNT;
- #endif
- return 0;
- }