613 lines
15 KiB
C
613 lines
15 KiB
C
/* extdrv/peripheral/vda/adv7179.c
|
|
*
|
|
*
|
|
* Copyright (c) 2006 Hisilicon Co., Ltd.
|
|
*
|
|
* 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.
|
|
*
|
|
*
|
|
* History:
|
|
* 17-Apr-2006 create this file
|
|
*
|
|
*/
|
|
|
|
#include <linux/string.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/module.h>
|
|
// BEGIN: Modified by x00132463, 2010-8-20 15 : 57 : 28
|
|
//#include <linux/config.h>
|
|
//#include <linux/autoconf.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/miscdevice.h>
|
|
#include <linux/fcntl.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/workqueue.h>
|
|
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/poll.h>
|
|
|
|
//#include <asm/hardware.h>
|
|
#include <asm/bitops.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/irq.h>
|
|
|
|
#include <linux/moduleparam.h>
|
|
#include <linux/ioport.h>
|
|
#include <linux/interrupt.h>
|
|
//#include <linux/kcom.h>
|
|
//#include <kcom/gpio_i2c.h>
|
|
#include "adv7179.h"
|
|
|
|
#include <asm/io.h>
|
|
#include <asm/system.h>
|
|
#include <linux/miscdevice.h>
|
|
|
|
#include <linux/i2c.h>
|
|
|
|
//#define HI_GPIO_I2C
|
|
//#ifdef HI_GPIO_I2C
|
|
//#include "gpio_i2c.h"
|
|
//#else
|
|
//#include "hi_i2c.h"
|
|
//#endif
|
|
|
|
//#ifdef HI_GPIO_I2C
|
|
//#define hi_i2c_write(chip_addr,reg_addr,value) gpio_i2c_write(chip_addr,reg_addr,value)
|
|
//#define hi_i2c_read(chip_addr,reg_addr) gpio_i2c_read(chip_addr,reg_addr)
|
|
//#else
|
|
//#define hi_i2c_write(chip_addr,reg_addr,value) HI_I2C_Write(chip_addr,reg_addr,1,value,1)
|
|
//#define hi_i2c_read(chip_addr,reg_addr) HI_I2C_Read(chip_addr,reg_addr,1,1)
|
|
//#endif
|
|
#define I2C_ADV7179 0x56
|
|
static struct i2c_client* sil_client;
|
|
static struct i2c_board_info sil_i2c_info =
|
|
{
|
|
I2C_BOARD_INFO("sil9034", I2C_ADV7179),
|
|
};
|
|
|
|
unsigned char _hi_i2c_read_byte(unsigned char devaddress, unsigned char address)
|
|
{
|
|
unsigned char ret_data = 0xFF;
|
|
int ret;
|
|
struct i2c_client* client = sil_client;
|
|
unsigned char buf[2];
|
|
|
|
buf[0] = address;
|
|
ret = i2c_master_recv(client, buf, 1);
|
|
if (ret >= 0)
|
|
{
|
|
ret_data = buf[0];
|
|
}
|
|
return ret_data;
|
|
}
|
|
|
|
int _hi_i2c_write_byte(unsigned char devaddress, unsigned char address, unsigned char data)
|
|
{
|
|
int ret;
|
|
unsigned char buf[2];
|
|
struct i2c_client* client = sil_client;
|
|
|
|
buf[0] = address;
|
|
buf[1] = data;
|
|
|
|
ret = i2c_master_send(client, buf, 2);
|
|
return ret;
|
|
}
|
|
static int i2c_client_init(void)
|
|
{
|
|
struct i2c_adapter* i2c_adap;
|
|
|
|
// use i2c1
|
|
i2c_adap = i2c_get_adapter(1);
|
|
sil_client = i2c_new_device(i2c_adap, &sil_i2c_info);
|
|
|
|
i2c_put_adapter(i2c_adap);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void i2c_client_exit(void)
|
|
{
|
|
i2c_unregister_device(sil_client);
|
|
}
|
|
|
|
#define I2CReadByte _hi_i2c_read_byte
|
|
#define I2CWriteByte _hi_i2c_write_byte
|
|
|
|
/* adv7179 i2c slaver address micro-definition. */
|
|
|
|
#define ADV7179_NUM 1
|
|
#define ADV7179_REG_WIDTH 1
|
|
#define ADV7179_DAT_WIDTH 1
|
|
|
|
#define adv7179_NUM_REGISTERS 128
|
|
|
|
|
|
|
|
/* Output filter: S-Video Composite */
|
|
|
|
#define MR050 0x11
|
|
#define MR060 0x14
|
|
|
|
|
|
#define TR0MODE_656 0x08
|
|
#define TR0MODE_601 0x0c
|
|
|
|
|
|
#define TR0RST 0x80
|
|
|
|
#define TR1CAPT 0x00
|
|
#define TR1PLAY 0x00
|
|
|
|
static int norm_mode = VIDEO_NORM_PAL;
|
|
|
|
|
|
static const unsigned char init_656_NTSC[] =
|
|
{
|
|
0x00, 0x00, /* MR0 */
|
|
0x01, 0x00, /* MR1 */
|
|
0x02, 0x00, /* MR2 RTC control: bits 2 and 1 */
|
|
0x03, 0x00, /* MR3 */
|
|
0x04, 0x15, /* MR4 */
|
|
0x05, 0x00, /* Reserved */
|
|
0x06, 0x00, /* Reserved */
|
|
0x07, TR0MODE_656, /* TM0 */
|
|
0x08, TR1CAPT, /* TM1 */
|
|
0x09, 0x16, /* Fsc0 */
|
|
0x0a, 0x7c, /* Fsc1 */
|
|
0x0b, 0xf0, /* Fsc2 */
|
|
0x0c, 0x21, /* Fsc3 */
|
|
0x0d, 0x00, /* Subcarrier Phase */
|
|
0x0e, 0x00, /* Closed Capt. Ext 0 */
|
|
0x0f, 0x00, /* Closed Capt. Ext 1 */
|
|
0x10, 0x00, /* Closed Capt. 0 */
|
|
0x11, 0x00, /* Closed Capt. 1 */
|
|
0x12, 0x00, /* Pedestal Ctl 0 */
|
|
0x13, 0x00, /* Pedestal Ctl 1 */
|
|
0x14, 0x00, /* Pedestal Ctl 2 */
|
|
0x15, 0x00, /* Pedestal Ctl 3 */
|
|
0x16, 0x00, /* CGMS_WSS_0 */
|
|
0x17, 0x00, /* CGMS_WSS_1 */
|
|
0x18, 0x00, /* CGMS_WSS_2 */
|
|
0x19, 0x00, /* Teletext Ctl */
|
|
};
|
|
|
|
|
|
static const unsigned char init_656_PAL[] =
|
|
{
|
|
0x00, 0x05, /* MR0, PAL BDGHI */
|
|
0x01, 0x00, /* MR1 */
|
|
0x02, 0x00, /* MR2 RTC control: bits 2 and 1 */
|
|
0x03, 0x00, /* MR3 */
|
|
0x04, 0x15, /* MR4, RGB OUTPUT */
|
|
0x05, 0x00, /* Reserved */
|
|
0x06, 0x00, /* Reserved */
|
|
0x07, TR0MODE_656, /* TM0 */
|
|
0x08, TR1CAPT, /* TM1 */
|
|
0x09, 0xcb, /* Fsc0 */
|
|
0x0a, 0x8a, /* Fsc1 */
|
|
0x0b, 0x09, /* Fsc2 */
|
|
0x0c, 0x2a, /* Fsc3 */
|
|
0x0d, 0x00, /* Subcarrier Phase */
|
|
0x0e, 0x00, /* Closed Capt. Ext 0 */
|
|
0x0f, 0x00, /* Closed Capt. Ext 1 */
|
|
0x10, 0x00, /* Closed Capt. 0 */
|
|
0x11, 0x00, /* Closed Capt. 1 */
|
|
0x12, 0x00, /* Pedestal Ctl 0 */
|
|
0x13, 0x00, /* Pedestal Ctl 1 */
|
|
0x14, 0x00, /* Pedestal Ctl 2 */
|
|
0x15, 0x00, /* Pedestal Ctl 3 */
|
|
0x16, 0x00, /* CGMS_WSS_0 */
|
|
0x17, 0x00, /* CGMS_WSS_1 */
|
|
0x18, 0x00, /* CGMS_WSS_2 */
|
|
0x19, 0x00, /* Teletext Ctl */
|
|
};
|
|
|
|
|
|
|
|
|
|
static unsigned char init_601_NTSC[] =
|
|
{
|
|
0x00, 0x00, /* MR0 */
|
|
0x01, 0x00, /* MR1 */
|
|
0x02, 0x08, /* MR2 RTC control: bits 2 and 1 */
|
|
0x03, 0x04, /* MR3 */
|
|
0x04, 0x0C, /* MR4 */
|
|
0x05, 0x00, /* Reserved */
|
|
0x06, 0x00, /* Reserved */
|
|
0x07, TR0MODE_601, /* TM0 */
|
|
0x08, TR1CAPT, /* TM1 */
|
|
0x09, 0x16, /* Fsc0 */
|
|
0x0a, 0x7c, /* Fsc1 */
|
|
0x0b, 0xf0, /* Fsc2 */
|
|
0x0c, 0x21, /* Fsc3 */
|
|
0x0d, 0x00, /* Subcarrier Phase */
|
|
0x0e, 0x00, /* Closed Capt. Ext 0 */
|
|
0x0f, 0x00, /* Closed Capt. Ext 1 */
|
|
0x10, 0x00, /* Closed Capt. 0 */
|
|
0x11, 0x00, /* Closed Capt. 1 */
|
|
0x12, 0x00, /* Pedestal Ctl 0 */
|
|
0x13, 0x00, /* Pedestal Ctl 1 */
|
|
0x14, 0x00, /* Pedestal Ctl 2 */
|
|
0x15, 0x00, /* Pedestal Ctl 3 */
|
|
0x16, 0x00, /* CGMS_WSS_0 */
|
|
0x17, 0x00, /* CGMS_WSS_1 */
|
|
0x18, 0x00, /* CGMS_WSS_2 */
|
|
0x19, 0x00, /* Teletext Ctl */
|
|
};
|
|
|
|
|
|
|
|
static unsigned char init_601_PAL[] =
|
|
{
|
|
0x00, 0x05, /* MR0, PAL BDGHI */
|
|
0x01, 0x00, /* MR1 */
|
|
0x02, 0x08, /* MR2 RTC control: bits 2 and 1 */
|
|
0x03, 0x04, /* MR3 */
|
|
0x04, 0x1C, /* MR4, RGB OUTPUT */
|
|
0x05, 0x00, /* Reserved */
|
|
0x06, 0x00, /* Reserved */
|
|
0x07, TR0MODE_601, /* TM0 */
|
|
0x08, TR1CAPT, /* TM1 */
|
|
0x09, 0xcb, /* Fsc0 */
|
|
0x0a, 0x8a, /* Fsc1 */
|
|
0x0b, 0x09, /* Fsc2 */
|
|
0x0c, 0x2a, /* Fsc3 */
|
|
0x0d, 0x00, /* Subcarrier Phase */
|
|
0x0e, 0x00, /* Closed Capt. Ext 0 */
|
|
0x0f, 0x00, /* Closed Capt. Ext 1 */
|
|
0x10, 0x00, /* Closed Capt. 0 */
|
|
0x11, 0x00, /* Closed Capt. 1 */
|
|
0x12, 0x00, /* Pedestal Ctl 0 */
|
|
0x13, 0x00, /* Pedestal Ctl 1 */
|
|
0x14, 0x00, /* Pedestal Ctl 2 */
|
|
0x15, 0x00, /* Pedestal Ctl 3 */
|
|
0x16, 0x00, /* CGMS_WSS_0 */
|
|
0x17, 0x00, /* CGMS_WSS_1 */
|
|
0x18, 0x00, /* CGMS_WSS_2 */
|
|
0x19, 0x00, /* Teletext Ctl */
|
|
};
|
|
|
|
|
|
|
|
|
|
static int write_regs(unsigned char* pdevdata, unsigned long datalen)
|
|
{
|
|
int i = 0;
|
|
|
|
while (i < datalen)
|
|
{
|
|
I2CWriteByte(I2C_ADV7179, pdevdata[i], pdevdata[i + 1]);
|
|
i += 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* adv7179 initialise routine.
|
|
*
|
|
* @param vdaccir: adv7179's working mode:0--VIDEO_MODE_CCIR656; 1--VIDEO_MODE_CCIR601
|
|
* @param vdanorm: adv7179's norm mode;
|
|
* @param vdamaster: adv7179's slave or master mode;
|
|
*
|
|
* @return value:0--success; -1--error.
|
|
*
|
|
*/
|
|
|
|
int init_vda(int vdaccir, int vdanorm, int vdamaster)
|
|
{
|
|
|
|
if ((vdaccir == VIDEO_MODE_CCIR656) && (vdanorm == VIDEO_NORM_PAL))
|
|
{
|
|
if (write_regs((unsigned char*)&init_656_PAL, sizeof(init_656_PAL)) != 0)
|
|
{
|
|
goto err_out;
|
|
}
|
|
}
|
|
else if ((vdaccir == VIDEO_MODE_CCIR656) && (vdanorm == VIDEO_NORM_NTSC))
|
|
{
|
|
if (write_regs((unsigned char*)&init_656_NTSC, sizeof(init_656_NTSC)) != 0)
|
|
{
|
|
goto err_out;
|
|
}
|
|
}
|
|
else if ((vdaccir == VIDEO_MODE_CCIR601) && (vdanorm == VIDEO_NORM_PAL))
|
|
{
|
|
if (vdamaster == VIDEO_MODE_MASTER)
|
|
{
|
|
init_601_PAL[15] |= VIDEO_MODE_MASTER;
|
|
}
|
|
else if (vdamaster == VIDEO_MODE_SLAVER)
|
|
{
|
|
init_601_PAL[15] &= ~VIDEO_MODE_MASTER;
|
|
}
|
|
|
|
if (write_regs((unsigned char*)&init_601_PAL, sizeof(init_601_PAL)) != 0)
|
|
{
|
|
goto err_out;
|
|
}
|
|
}
|
|
else if ((vdaccir == VIDEO_MODE_CCIR601) && (vdanorm == VIDEO_NORM_NTSC))
|
|
{
|
|
if (vdamaster == VIDEO_MODE_MASTER)
|
|
{
|
|
init_601_NTSC[15] |= VIDEO_MODE_MASTER;
|
|
}
|
|
if (vdamaster == VIDEO_MODE_SLAVER)
|
|
{
|
|
init_601_NTSC[15] &= ~VIDEO_MODE_MASTER;
|
|
}
|
|
|
|
if (write_regs((unsigned char*)&init_601_NTSC, sizeof(init_601_NTSC)) != 0)
|
|
{
|
|
goto err_out;
|
|
}
|
|
}
|
|
|
|
if (vdaccir == VIDEO_MODE_CCIR656)
|
|
{
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_656 | TR0RST));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, TR0MODE_656);
|
|
}
|
|
else if (vdaccir == VIDEO_MODE_CCIR601)
|
|
{
|
|
if (vdamaster == VIDEO_MODE_MASTER)
|
|
{
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | TR0RST | VIDEO_MODE_MASTER));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | VIDEO_MODE_MASTER));
|
|
}
|
|
else
|
|
{
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | TR0RST));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, TR0MODE_601);
|
|
}
|
|
}
|
|
|
|
return (0);
|
|
|
|
err_out:
|
|
printk("err_out\n");
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* adv7179 open routine.
|
|
* do nothing.
|
|
*
|
|
*/
|
|
int adv7179_open(struct inode* inode, struct file* file)
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* adv7179 close routine.
|
|
* do nothing.
|
|
*
|
|
*/
|
|
int adv7179_close(struct inode* inode, struct file* file)
|
|
{
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* adv7179 ioctl routine.
|
|
* @param inode: pointer of the node;
|
|
* @param file: pointer of the file;
|
|
*
|
|
* @param cmd: command from the app:
|
|
* ENCODER_SET_NORM(2):set adv7179's work mode.
|
|
*
|
|
* @param arg:arg from app layer.
|
|
*
|
|
* @return value:0-- set success; -1-- set error.
|
|
*
|
|
*/
|
|
static long adv7179_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
|
|
{
|
|
|
|
switch (cmd)
|
|
{
|
|
|
|
case ENCODER_SET_NORM:
|
|
{
|
|
int iarg = (int) arg;
|
|
|
|
|
|
switch (iarg)
|
|
{
|
|
case VIDEO_MODE_656_PAL:
|
|
write_regs((unsigned char*)&init_656_PAL, sizeof(init_656_PAL));
|
|
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_656 | TR0RST));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, TR0MODE_656);
|
|
break;
|
|
|
|
case VIDEO_MODE_656_NTSC:
|
|
write_regs((unsigned char*)&init_656_NTSC, sizeof(init_656_NTSC));
|
|
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_656 | TR0RST));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, TR0MODE_656);
|
|
break;
|
|
|
|
case VIDEO_MODE_601_PAL_MASTER:
|
|
init_601_PAL[15] |= VIDEO_MODE_MASTER;
|
|
write_regs((unsigned char*)&init_601_PAL, sizeof(init_601_PAL));
|
|
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | TR0RST | VIDEO_MODE_MASTER));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | VIDEO_MODE_MASTER));
|
|
break;
|
|
|
|
|
|
case VIDEO_MODE_601_NTSC_MASTER:
|
|
init_601_NTSC[15] |= VIDEO_MODE_MASTER;
|
|
write_regs((unsigned char*)&init_601_NTSC, sizeof(init_601_NTSC));
|
|
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | TR0RST | VIDEO_MODE_MASTER));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | VIDEO_MODE_MASTER));
|
|
break;
|
|
|
|
case VIDEO_MODE_601_PAL_SLAVER:
|
|
init_601_PAL[15] &= ~VIDEO_MODE_MASTER;
|
|
write_regs((unsigned char*)&init_601_PAL, sizeof(init_601_PAL));
|
|
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | TR0RST));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, TR0MODE_601);
|
|
break;
|
|
|
|
case VIDEO_MODE_601_NTSC_SLAVER:
|
|
init_601_NTSC[15] &= ~VIDEO_MODE_MASTER;
|
|
write_regs((unsigned char*)&init_601_NTSC, sizeof(init_601_NTSC));
|
|
|
|
I2CWriteByte(I2C_ADV7179, 0x07, (TR0MODE_601 | TR0RST));
|
|
I2CWriteByte(I2C_ADV7179, 0x07, TR0MODE_601);
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* The various file operations we support.
|
|
*/
|
|
|
|
static struct file_operations adv7179_fops =
|
|
{
|
|
.owner = THIS_MODULE,
|
|
.unlocked_ioctl = adv7179_ioctl,
|
|
.open = adv7179_open ,
|
|
.release = adv7179_close
|
|
};
|
|
|
|
static struct miscdevice adv7179_dev =
|
|
{
|
|
MISC_DYNAMIC_MINOR,
|
|
"adv7179",
|
|
&adv7179_fops,
|
|
};
|
|
|
|
static int adv7179_device_init(void)
|
|
{
|
|
unsigned char regvalue1, regvalue2;
|
|
regvalue1 = I2CReadByte(I2C_ADV7179, 0x07);
|
|
I2CWriteByte(I2C_ADV7179, 0x07, 0xa5);
|
|
regvalue2 = I2CReadByte(I2C_ADV7179, 0x07);
|
|
if (regvalue2 != 0xa5)
|
|
{
|
|
printk("read adv7179 register is %x\n", regvalue2);
|
|
printk("check adv7179 error.\n");
|
|
return -EFAULT;
|
|
}
|
|
I2CWriteByte(I2C_ADV7179, 0x07, regvalue1);
|
|
if (norm_mode == VIDEO_NORM_NTSC)
|
|
{
|
|
if (init_vda(VIDEO_MODE_CCIR656, VIDEO_NORM_NTSC, VIDEO_MODE_MASTER) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (init_vda(VIDEO_MODE_CCIR656, VIDEO_NORM_PAL, VIDEO_MODE_MASTER) == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//DECLARE_KCOM_GPIO_I2C();
|
|
static int __init adv7179_init(void)
|
|
{
|
|
int ret = 0;
|
|
|
|
#if 0
|
|
ret = KCOM_GPIO_I2C_INIT();
|
|
if (ret)
|
|
{
|
|
printk("GPIO I2C module is not load.\n");
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
i2c_client_init();
|
|
|
|
ret = misc_register(&adv7179_dev);
|
|
if (ret)
|
|
{
|
|
//KCOM_GPIO_I2C_EXIT();
|
|
printk("could not register adv7179 devices. \n");
|
|
return -1;
|
|
}
|
|
if (adv7179_device_init() < 0)
|
|
{
|
|
misc_deregister(&adv7179_dev);
|
|
//KCOM_GPIO_I2C_EXIT();
|
|
printk("adv7179 driver init fail for device init error!\n");
|
|
return -1;
|
|
}
|
|
|
|
printk("adv7179 driver init successful!\n");
|
|
return ret;
|
|
}
|
|
|
|
static void __exit adv7179_exit(void)
|
|
{
|
|
i2c_client_exit();
|
|
misc_deregister(&adv7179_dev);
|
|
//KCOM_GPIO_I2C_EXIT();
|
|
|
|
}
|
|
|
|
module_init(adv7179_init);
|
|
module_exit(adv7179_exit);
|
|
|
|
#ifdef MODULE
|
|
//#include <linux/compile.h>
|
|
#endif
|
|
|
|
module_param(norm_mode, int, S_IRUGO);
|
|
|
|
//MODULE_INFO(build, UTS_VERSION);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_AUTHOR("hisilicon");
|
|
|
|
|