📄 tvp5150a.c
字号:
/** * @file tvp5150a.c * * @brief MX21 TVIN/SAA7113H Driver. * * Copyright (C) 2004, Freescale Semiconductor Suzhou Ltd. All Rights Reserved * * Descirption: * This is the source file for TV-in driver. * * Modification History: * Jan 20, 2005. * Added video source detection feature. * Dec 20, 2004. * Added SAA7113H_IOC_READ_CONFIG support. * Added power management support. * Nov 11, 2004. * Document API. * Aug 6, 2004. * Initial version. */#include <linux/config.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/delay.h>#include <linux/slab.h>#include <linux/version.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/ioport.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/hfs_sysdep.h>#include <linux/compatmac.h>#include <linux/hdreg.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include <linux/fs.h>#include <linux/module.h>#include <linux/blkpg.h>#include <linux/i2c.h>#include <linux/i2c-algo-bit.h>#include <linux/i2c-id.h>#include <linux/slab.h>#include <asm/io.h>#include <linux/mm.h>#include <linux/wrapper.h>#include <asm/dma.h>#include <linux/miscdevice.h>#include <linux/proc_fs.h>#include "asm/arch/mx2.h"#include "asm/arch/platform.h"#include "linux/i2c.h"#include "linux/i2c-dev.h"#include "tvp5150a.h"//global staticstatic TVP5150A_CFG g_tvp5150a_cfg = {0, 0, 0, 0, 0, 0, -1}; //default no video source: device disabled.//#define SAA7113H_PM#undef SAA7113H_PM#ifdef SAA7113H_PM#include <linux/pm.h>#define SAA7113H_PMST_SUSPEND 0#define SAA7113H_PMST_RESUME 1static unsigned int g_saa7113h_pm_status = SAA7113H_PMST_RESUME;struct pm_dev *g_saa7113h_pm = 0;#endif/************************************************************************************************* i2c related*************************************************************************************************/#define I2C_DRIVERID_I2CCSI 0xF000#define EMBEDDED_REGISTER 0x01#define I2C_M_READ 0x02#define I2C_M_WT 0x04//saa7113h i2c addr#define TVP5150A_I2C_ADDR 0xB8 //0xBAstatic int i2c_csi_attach_adapter (struct i2c_adapter * adap);static struct i2c_driver i2c_csi_driver ={ name: "i2c-csi client driver", id: I2C_DRIVERID_I2CCSI, flags: I2C_DF_DUMMY | I2C_DF_NOTIFY, attach_adapter: i2c_csi_attach_adapter, detach_client: NULL, /*i2c_csi_detach_client,*/ command: NULL};static struct i2c_client i2c_csi2c_client ={ name: "i2c-csi client", id: 2, flags: 0, addr: -1, adapter: NULL, driver: &i2c_csi_driver, data: NULL};static int i2c_csi_attach_adapter (struct i2c_adapter * adap){ if (memcmp(adap->name, "DBMX I2C Adapter1", 17) != 0 ) return -ENODEV; i2c_csi2c_client.adapter = adap; printk("adapter:%s\n",adap->name); return 0;}static void i2c_init(void){ /* * set the address of the SAA7113H to the client */ i2c_csi2c_client.addr = TVP5150A_I2C_ADDR; /* * call the i2c_add_driver() to register the driver * to the Linux I2C system */ if (i2c_add_driver( &i2c_csi_driver ) != 0) { printk("I2C addr driver failed\n"); return; } /* * attach the client to the adapter by calling the i2c_attach_client() * function of the Linux I2C system */ if (i2c_attach_client(&i2c_csi2c_client ) != 0) { printk("I2C attach client failed\n"); i2c_del_driver(&i2c_csi_driver); return; } i2c_csi2c_client.adapter->inc_use( i2c_csi2c_client.adapter );}static void i2c_cleanup(void){ i2c_csi2c_client.adapter->dec_use(i2c_csi2c_client.adapter); i2c_detach_client(&i2c_csi2c_client ); printk("i2c detach client end\n"); i2c_del_driver(&i2c_csi_driver); printk("i2c del driver end\n");}/** * @brief Write one byte to SAA7113H register * * @param reg SAA7113H register address * @param data Data to be written to the register */static int i2c_write(unsigned int reg, unsigned char data){ struct i2c_msg msg; char buf[2]; int ret; /* * store the register value to the first address of the buffer * the adapter/algorithm driver will regard the first byte * as the register value */ buf[0] = (char)reg; buf[1] = data; /* * initialize the message structure */ msg.addr = i2c_csi2c_client.addr; msg.flags = EMBEDDED_REGISTER | I2C_M_WT; msg.len = 2; msg.buf = buf; ret = i2c_transfer( i2c_csi2c_client.adapter, &msg, 1 ); return ret;}/** * @brief Read one byte from SAA7113H register * * @param reg SAA7113H register address * @param data Data buffer to receive the register value */static int i2c_read(unsigned int reg, unsigned char *data){ struct i2c_msg msg; char buf[2]; int ret; /* * store the register value to the first address of the buffer * the adapter/algorithm driver will regard the first byte * as the register value */ buf[0] = (char)reg; /* * initialize the message structure */ msg.addr = i2c_csi2c_client.addr; msg.flags = EMBEDDED_REGISTER | I2C_M_READ; msg.len = 2; msg.buf = buf; ret = i2c_transfer( i2c_csi2c_client.adapter, &msg, 1 ); *data = buf[0]; return ret;}/************************************************************************************************* saa7113h api*************************************************************************************************/#define CSI_CTL0 0x0040#define CSI_CTL1 0x0020#define CSI_CTL2 0x0010//localstatic void tvp5150a_hard_reset(void);static void tvp5150a_hard_standby_control(int enable);static int tvp5150a_i2c_test(void);static int tvp5150a_init(int type);static void tvp5150a_fill_parm(int video_type);static void tvp5150a_hard_reset(void){ unsigned short data;//assert reset pulse data = _reg_EXP_IO_0; //0xcd000000 data &= ~CSI_CTL1; _reg_EXP_IO_0 = data; udelay(1000); data |= CSI_CTL1; _reg_EXP_IO_0 = data; udelay(300); return;}static void tvp5150a_hard_standby_control(int enable){ unsigned short data; data =_reg_EXP_IO_0; if(enable) data |= CSI_CTL1; else data &= ~CSI_CTL1; _reg_EXP_IO_0 = data; return;}/*** Test on I2C channel* Read / write one of the register* compare and verify if the data is correct*/static int tvp5150a_i2c_test(void){ unsigned char chip_ver; //silicon ID unsigned char rdata, wdata; unsigned int error = 0; printk("I2C Test...\n"); tvp5150a_hard_reset(); //read silicon ID i2c_read(0x00, &chip_ver); printk("Chip version = 0x%02X\n", chip_ver); for(wdata = 0x1; wdata < 0x3F; wdata ++) { //register read write test i2c_write(0x0D, wdata); //test on reg 0x0D i2c_read(0x0D, &rdata); if(rdata != wdata) error = 1; } if(error) printk("tvp5150a: i2c test failed\n"); else printk("tvp5150a: i2c test ok\n"); tvp5150a_hard_reset(); return error;}/*** SAA7113 Basic Init* Composite/S-Video Input** - Accept composite or s-video video from input A11* - Automatic field detection, PAL or NTSC expected* - Standard CCIR656 output enable* - VBI-data slicer disable* - VSYNC & HSYNC out enable* - ITU recommended contrast, brightness & saturation control* - Chrominance processin with nominal BW (800kHz)** @param type SAA7113H_INPUT_COMPOSITE Accept composite video* SAA7113H_INPUT_SVIDEO Accept s-video video*/static int tvp5150a_init(int type){// unsigned int chipVer; unsigned char status; unsigned int reg;//hard reset tvp5150a_hard_reset();//read silicon ID// I2C_read(0x00, &chipVer);// printf("Silicon ID = 0x%02X\n", chipVer);//recommended startup settings/* i2c_write(0x01, 0x08); //increment delay if (type == CVBS) i2c_write(0x02, 0xC0); //analog input control 1 else i2c_write(0x02, 0xC9); //analog input control 1 (S-video in) i2c_write(0x03, 0x33); //analog input control 2 i2c_write(0x04, 0x00); //analog input control 3 i2c_write(0x05, 0x00); //analog input control 4 i2c_write(0x06, 0xE9); //HSYNC start i2c_write(0x07, 0x0D); //HSYNC stop i2c_write(0x08, 0x98); //SYNC control if (type == CVBS) i2c_write(0x09, 0x01); //luminance control else i2c_write(0x09, 0x81); //luminance control (S-video) i2c_write(0x0A, 0x80); //luminance brightness i2c_write(0x0B, 0x47); //luminance contrast i2c_write(0x0C, 0x40); //chrom sat i2c_write(0x0D, 0x00); //chrom hue i2c_write(0x0E, 0x01); //chrom control i2c_write(0x0F, 0x2A); //chrom gain control i2c_write(0x10, 0x00); //format / delay control i2c_write(0x11, 0x0C); //output control 1// i2c_write(0x11, 0x0D); //output control 1 (color kill disable) i2c_write(0x12, 0x7B); //output control 2 i2c_write(0x13, 0x00); //output control 3 i2c_write(0x15, 0x00); //VGATE start i2c_write(0x16, 0x00); //VGATE stop i2c_write(0x17, 0x00); //MSBs for VGATE control i2c_write(0x40, 0x02); //silcer control 1 for(reg = 0x41; reg <= 0x57; reg ++) i2c_write(reg, 0xFF); //line control register 2 to 24 i2c_write(0x58, 0x00); //framing code i2c_write(0x59, 0x54); //horizontal offset for slicer i2c_write(0x5A, 0x07); //vertical offset for slicer i2c_write(0x5B, 0x83); //field offset and SBs for H & V offset i2c_write(0x5E, 0x00); //silced data ID code udelay(100);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -