📄 i2c_decoder.c
字号:
/* * Copyright (C) 2006 U-Camp Co,LTD. * Youngil.Kim <zeronine@ucamp.co.kr> * * Copyright (C) 2004 Samsung Electronics * SW.LEE <hitchcar@samsung.com> * * Copyright (C) 2000 Russell King : pcf8583.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Driver for TVP5150A video decoder * * ChangeLog * 07.01.03 * - 饭瘤胶磐 悸泼阑 困秦辑 #include <asm/arch/map.h> 眠啊窃 by lovejin * - struct i2c_client_address_data 甫 2.6俊 嘎档废 祈笼窃. (力措肺 悼累窍瘤绰 厘淬 给窃) by lovejin * - decoder_attach() 俊辑 c->id, c->data 何盒阑 林籍 贸府窃. by lovejin * - 2.6 目澄俊绰 I2C_ALGO_S3C 啊 沥狼登绢 乐瘤 臼酒辑 include/linux/i2c-id.h 俊 眠啊窃 by lovejin * ** 咯扁鳖瘤 沁阑 锭 哪颇老篮 登菌澜 悼累且瘤绰 肋 葛福摆澜. by lovejin * */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/i2c.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/init.h>#include <linux/delay.h>//#include <asm/arch/s3c2410.h>//#include <asm/arch/s3c2440.h> /* Helios 2.4 目澄侩 */#include <asm/arch/map.h> /* Helios 2.6 目澄侩栏肺 眠啊窃 by lovejin */#include <asm/arch/regs-gpio.h>#include <asm/io.h>#include <linux/ioport.h>//#define SW_DEBUG#include "camif.h"#include "i2c_decoder.h"//static const char *sensor_version =// "$Id: i2c_decoder.c,v 1.11 2006/02/16 12:45:40 zeronine Exp $";static struct i2c_driver decoder_driver;#define CAM_ID 0xBA//#define CAM_ID 0xB8static unsigned short ignore[] = { I2C_CLIENT_END };static unsigned short normal_addr[] = { (CAM_ID>>1), I2C_CLIENT_END };static struct i2c_client_address_data addr_data = { normal_i2c: normal_addr,// normal_i2c_range: ignore, // lovejin 捞 昏力窃 probe: ignore,// probe_range: ignore, // lovejin 捞 昏力窃 ignore: ignore,// ignore_range: ignore, // lovejin 捞 昏力窃 force: ignore,};unsigned char decoder_i2c_read( struct i2c_adapter *adap, unsigned char subaddr){ int ret; unsigned char buf[1]; struct i2c_msg msg ={ CAM_ID >> 1, 0, 1, buf}; buf[0] = subaddr; ret = i2c_transfer(adap,&msg, 1); msg.flags = I2C_M_RD; ret = i2c_transfer(adap, &msg, 1); printk("decoder reg read : reg = 0x%x, val = 0x%x\n", subaddr, buf[0]); return buf[0];}static intdecoder_i2c_write(struct i2c_adapter *adap, unsigned char subaddr, unsigned short val){ unsigned char buf[2]; struct i2c_msg msg = { CAM_ID >> 1, 0, 2, buf}; printk("decoder reg write : reg = 0x%x, val = 0x%x\n", subaddr, val); buf[0]= subaddr; buf[1]= val & 0xff; return i2c_transfer(adap, &msg, 1);}void inline decoder_init(struct i2c_client *sam_client){// int i; // 荤侩救窍骨肺 林籍贸府窃 by lovejin printk("decoder_init\n");}extern camif_gc_t default_data; // from vide-driver.cstatic intdecoder_attach(struct i2c_adapter *adap, int addr, unsigned short flags,int kind){ int ret = 0; struct i2c_client *c; printk("\tdecoder_attach: start\n"); c = kmalloc(sizeof(*c), GFP_KERNEL); if (!c) return -ENOMEM; printk("\tc->id = 0x%x\n", decoder_driver.id); printk("\tc->addr = 0x%x\n", addr); strcpy(c->name, "TVP5150A");// c->id = decoder_driver.id; // 2.6 俊辑绰 绝绢咙 by lovejin c->flags = I2C_CLIENT_ALLOW_USE; c->addr = addr; c->adapter = adap; c->driver = &decoder_driver; c->data = &default_data; // 2.6 俊辑绰 绝绢咙 by lovejin default_data.decoder = c; camif_register_decoder(c); ret = i2c_attach_client(c); printk("\tdecoder_attach: end\n"); return ret;}static int decoder_probe(struct i2c_adapter *adap){ int ret; printk("decoder_probe(): start\n"); printk("-- start Video Decoder Register Setting!! --\n"); ret = decoder_i2c_read( adap, 0x80 ); // lovejin#if 1 // real decoder setting #if 1 /* ITU-R BT.656 */ /*decoder_i2c_write( adap, 0x00, 0x00 ); */ /*input source is A*/ decoder_i2c_write( adap, 0x00, 0x02 ); /* input source is B*/ decoder_i2c_write( adap, 0x03, 0x01 | 0x08 ); decoder_i2c_write( adap, 0x04, 0x00 ); decoder_i2c_write( adap, 0x0d, 0x47 ); decoder_i2c_write( adap, 0x0f, 0x18 ); decoder_i2c_write( adap, 0x28, 0x00 ); /* video standard -> autoswitch*/ #else /* ITU-R BT.601 */ decoder_i2c_write( adap, 0x00, 0x00 ); // input source is A decoder_i2c_write( adap, 0x03, 0x0d ); // YOUT, HSYNC/VSYNC, SCLK enable decoder_i2c_write( adap, 0x04, 0x2c ); // only N433 is autoswichable decoder_i2c_write( adap, 0x0d, 0x30 ); // ITU-R BT.601, 8-bit 4:2:2 YCbCr decoder_i2c_write( adap, 0x0f, 0x18 ); decoder_i2c_write( adap, 0x28, 0x00 ); // video standard -> autoswitch #endif ret = decoder_i2c_read( adap, 0x00 ); ret = decoder_i2c_read( adap, 0x01 ); ret = decoder_i2c_read( adap, 0x02 ); ret = decoder_i2c_read( adap, 0x03 ); ret = decoder_i2c_read( adap, 0x04 ); ret = decoder_i2c_read( adap, 0x0d ); ret = decoder_i2c_read( adap, 0x0f ); ret = decoder_i2c_read( adap, 0x16 ); ret = decoder_i2c_read( adap, 0x28 ); ret = decoder_i2c_read( adap, 0x30 ); ret = decoder_i2c_read( adap, 0x88 ); ret = decoder_i2c_read( adap, 0x8c ); ret = decoder_i2c_read( adap, 0xc2 );#else // ID Check ret = decoder_i2c_read( adap, 0x80 );#endif /* 公炼扒 Port B, 溜 CAM 墨皋扼甫 混府档废 秦 初疽嚼聪促. by lovejin */ printk("select Decoder Input Port B\n"); ret = decoder_i2c_write( adap, 0x00, 0x02 ); // by lovejin#if 0 // raw i2c read, write example { unsigned char buf[2]; struct i2c_msg msg ={ 0xba >> 1, 0, 2, buf}; buf[0] = 0x03; buf[1] = 0x08 | 0x01;// | 0x04; printk(">> write reg 0x%x, val = 0x%x\n", buf[0], buf[1]); ret = i2c_transfer(adap, &msg, 1);// == 1 ? 0 : -EIO; printk("> ret = %d\n", ret); } { unsigned char buf[1]; struct i2c_msg msg = { 0xbb >>1, 0, 1, buf }; buf[0] = 0x03; printk(">> read reg 0x%x", buf[0]); ret = i2c_transfer( adap, &msg, 1 ); msg.flags = I2C_M_RD; ret = i2c_transfer( adap, &msg, 1 ); printk(", ret = 0x%x\n", buf[0]); }#endif printk("--- End of Video Decoder Register Setting!! --\n");#if 1 // original printk("\tdecoder_probe: start adap->name %s\n", adap->name); ret = i2c_probe(adap, &addr_data, decoder_attach); printk("\tdecoder_probe: end\n"); #else // remove i2c_probe ret = decoder_attach( adap, &addr_data, 0, 0);#endif return ret;}static int decoder_detach(struct i2c_client *client){ printk("\tdecoder_detach: start\n"); i2c_detach_client(client); //camif_unregister_decoder(client); return 0;}static intdecoder_command(struct i2c_client *client, unsigned int cmd, void *arg){ unsigned long val = 0; printk("\tdecoder_command start\n"); switch (cmd) {#if 0 case SENSOR_INIT: printk("decoder_command: SENSOR_INIT\n"); decoder_init(client); break; case USER_ADD: printk("decoder_command: MOD_INC_USE_COUNT\n"); MOD_INC_USE_COUNT; break; case USER_EXIT: printk("SRCPND = 0x%08x\n", rSRCPND ); printk("INTPND = 0x%08x\n", rINTPND ); printk("SUBSRCPND = 0x%08x\n", rSUBSRCPND ); printk("INTOFFSET = 0x%08x\n", rINTOFFSET ); printk("CAMDIVN = 0x%08x\n", rCAMDIVN ); printk("decoder_command: MOD_DEC_USE_COUNT\n"); MOD_DEC_USE_COUNT; break;#endif/* Todo case SENSOR_BRIGHTNESS: change_sensor(); break;*/ case DECODER_VIDEO_A: printk(">>>>>>>>>>>>> DECODER_VIDEO_A\n"); // turn off camera on wallpad printk("turn off camera of wallpad\n"); rGPEDAT &= ~( 1 << 11 ); // input source is A decoder_i2c_write( client->adapter, 0x00, 0x00 ); break; case DECODER_VIDEO_B: printk(">>>>>>>>>>>>> DECODER_VIDEO_B\n"); // turn on camera on wallpad printk("turn on camera of wallpad power\n"); rGPEDAT |= ( 1 << 11 ); // input source is B decoder_i2c_write( client->adapter, 0x00, 0x02 ); break; default: panic("Unexpect Sensor Command \n"); break; } return 0;}static struct i2c_driver decoder_driver = { name: "TVP5150A", id: I2C_ALGO_S3C, flags: I2C_DF_NOTIFY, attach_adapter: decoder_probe, detach_client: decoder_detach, command: decoder_command};static void iic_gpio_port(void) { rGPECON &= ~(0xf <<28); rGPECON |= 0xa <<28;}static void decoder_reset(void){/* rGPACON &= ~(0x1 << 21); printk("rGPACON = 0x%08x\n", rGPACON); printk("rGPADAT = 0x%08x\n", rGPADAT); rGPADAT |= (0x1 << 21); printk("rGPADAT = 0x%08x\n", rGPADAT); rGPADAT &= ~(0x1 << 21); printk("rGPADAT = 0x%08x\n", rGPADAT); rGPADAT |= (0x1 << 21); printk("rGPADAT = 0x%08x\n", rGPADAT); udelay(200); rGPACON |= (0x1 << 21);*/}static __init int camif_sensor_init(void){ int ret; printk("[ camif_sensor_init() S ]\n"); iic_gpio_port(); decoder_reset(); ret = i2c_add_driver(&decoder_driver); printk("[ camif_sensor_init() E ]\n"); return ret;}static __exit void camif_sensor_exit(void){ printk("camif_sensor_exit start\n"); i2c_del_driver(&decoder_driver); printk("camif_sensor_exit end\n");}module_init(camif_sensor_init)module_exit(camif_sensor_exit)MODULE_AUTHOR("Youngil.Kim <zeronine@ucamp.co.kr>");MODULE_DESCRIPTION("I2C Client Driver For TVP5150A MISC Driver");MODULE_LICENSE("GPL");/* * Local variables: * c-basic-offset: 8 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -