#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include "nvp6158c.h"
#define I2C_ADDR_CNT 2
static unsigned char nvp6158c_dev_addr[I2C_ADDR_CNT] = {0x60, 0x62/*, 0x64, 0x66*/};
/* --------------------------------------------------------------------------------------------------- */
typedef struct {
struct i2c_client *client;
unsigned char chip_id;
} Nvp6158cDev;
static Nvp6158cDev *nvp6158c_dev[I2C_ADDR_CNT];
static int nvp6158c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = 0, i = 0;
unsigned char val = 0;
printk("%s: I2C Addr 0x%02X ...\n", __func__, client->addr);
for(i=0; i<I2C_ADDR_CNT; i++) {
if(client->addr == nvp6158c_dev_addr[i]) {
break;
}
}
if(i >= I2C_ADDR_CNT) {
printk("!!! %s: cannot handle 0x%02X\n", __func__, client->addr);
return -ENODEV;
}
if(nvp6158c_dev[i]) {
printk("!!! %s: 0x%02X handled before\n", __func__, client->addr);
return -EBUSY;
}
nvp6158c_dev[i] = kzalloc(sizeof(Nvp6158cDev), GFP_KERNEL);
if(!nvp6158c_dev[i]) {
printk("!!! %s: handle 0x%02X alloc err\n", __func__, client->addr);
return -ENOMEM;
}
nvp6158c_dev[i]->client = client;
nvp6158c_write(client, 0xFF, 0x00/* Blank#0 */);
val = nvp6158c_read(client, 0xF4);
if(val != NVP6158_R0_ID && val != NVP6158C_R0_ID) {
printk("%s: chip_id 0x%02X error\n", __func__, val);
goto end;
}
nvp6158c_dev[i]->chip_id = val;
nvp6158c_write(client, 0xFF, 0x00/* Blank#0 */);
val = nvp6158c_read(client, 0xF5);
printk("%s: chip_id 0x%02X, rev_id 0x%02X\n", __func__, nvp6158c_dev[i]->chip_id, val);
/* initialize common value of AHD */
nvp6158c_i2c_write_init(client, nvp6158c_dev[i]->chip_id);
if(NVP6158C_R0_ID == nvp6158c_dev[i]->chip_id || NVP6158_R0_ID == nvp6158c_dev[i]->chip_id) {
nvp6158_i2c_write_additionalFor3MoverDef(client);
}
else {
nvp6158c_write(client, 0xff, 0x01);
nvp6158c_write(client, 0x97, 0x00); // CH_RST ON
nvp6158c_write(client, 0x97, 0x0f); // CH_RST OFF
nvp6158c_write(client, 0x7a, 0x0f); // Clock Auto ON
nvp6158c_write(client, 0xca, 0xff); // VCLK_EN, VDO_EN
for(val=0; val<4; val++) {
nvp6158c_write(client, 0xff, 0x05 + val);
nvp6158c_write(client, 0x00, 0xd0);
nvp6158c_write(client, 0x05, 0x04);
nvp6158c_write(client, 0x08, 0x55);
nvp6158c_write(client, 0x47, 0xEE);
nvp6158c_write(client, 0x59, 0x00);
nvp6158c_write(client, 0x76, 0x00);
nvp6158c_write(client, 0x77, 0x80);
nvp6158c_write(client, 0x78, 0x00);
nvp6158c_write(client, 0x79, 0x11);
nvp6158c_write(client, 0xB8, 0xB8); // H_PLL_BYPASS
nvp6158c_write(client, 0x7B, 0x11); // v_rst_on
nvp6158c_write(client, 0xb9, 0x72);
nvp6158c_write(client, 0xB8, 0xB8); // No Video Set
nvp6158c_write(client, 0xff, 0x00);
nvp6158c_write(client, 0x00 + val, 0x10);
nvp6158c_write(client, 0x22 + (val * 0x04), 0x0b);
}
nvp6158c_write(client, 0xff, 0x13);
nvp6158c_write(client, 0x12, 0x04);
nvp6158c_write(client, 0x2E, 0x10);
nvp6158c_write(client, 0x30, 0x00);
nvp6158c_write(client, 0x77, 0xff);
nvp6158c_write(client, 0x3a, 0xff);
nvp6158c_write(client, 0x3b, 0xff);
nvp6158c_write(client, 0x3c, 0xff);
nvp6158c_write(client, 0x3d, 0xff);
nvp6158c_write(client, 0x3e, 0xff);
nvp6158c_write(client, 0x3f, 0x0f);
nvp6158c_write(client, 0x70, 0x00);
nvp6158c_write(client, 0x72, 0x05);
nvp6158c_write(client, 0x7A, 0xf0);
// nvp6158c_write(client, 0x61, 0x03);
// nvp6158c_write(client, 0x62, 0x00);
// nvp6158c_write(client, 0x63, 0x03);
// nvp6158c_write(client, 0x64, 0x00);
// nvp6158c_write(client, 0x65, 0x03);
// nvp6158c_write(client, 0x66, 0x00);
// nvp6158c_write(client, 0x67, 0x03);
// nvp6158c_write(client, 0x68, 0x00);
// nvp6158c_write(client, 0x60, 0x0f);
// nvp6158c_write(client, 0x60, 0x00);
nvp6158c_write(client, 0x07, 0x47);
nvp6158c_write(client, 0x59, 0x24);
/* SAM Range */
nvp6158c_write(client, 0x74, 0x00);
nvp6158c_write(client, 0x76, 0x00);
nvp6158c_write(client, 0x78, 0x00);
nvp6158c_write(client, 0x75, 0xff);
nvp6158c_write(client, 0x77, 0xff);
nvp6158c_write(client, 0x79, 0xff);
nvp6158c_write(client, 0x01, 0x0c);
nvp6158c_write(client, 0x2f, 0xc8);
// EQ Stage Get
nvp6158c_write(client, 0x73, 0x23);
nvp6158c_write(client, 0xff, 0x09);
nvp6158c_write(client, 0x96, 0x03);
nvp6158c_write(client, 0xB6, 0x03);
nvp6158c_write(client, 0xD6, 0x03);
nvp6158c_write(client, 0xF6, 0x03);
/********************************************************
* Audio Default Setting
********************************************************/
nvp6158c_write(client, 0xff, 0x01);
nvp6158c_write(client, 0x05, 0x09);
nvp6158c_write(client, 0x58, 0x02);
nvp6158c_write(client, 0x59, 0x00);
}
#if 0
for(val=0; val<4; val++) {
det_mode[i * 4 + val] = NVP6158_DET_MODE_AUTO;
vin_auto_det.ch = val;
vin_auto_det.devnum = i;
#ifdef _NVP6168_USE_MANUAL_MODE_
vin_manual_det.ch = val;
vin_manual_det.dev_num = i;
#endif
if(chip_id[0]==NVP6158C_R0_ID || chip_id[0]==NVP6158_R0_ID)
{
video_input_auto_detect_set(&vin_auto_det);
nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
}
else
{
nvp6168_video_input_auto_detect_set(&vin_auto_det);
#ifdef _NVP6168_USE_MANUAL_MODE_
nvp6168_video_input_manual_mode_set(&vin_manual_det);
#endif
nvp6168_set_chnmode(i * 4 + val, NC_VIVO_CH_FORMATDEF_UNKNOWN);
}
}
if(chip_id[chip] == NVP6158_R0_ID || chip_id[chip] == NVP6168_R0_ID)
{
//设置nvp6158 4个port的输出模式 0~3 port口可用
nvp6158_set_portmode(chip, 0, NVP6158_OUTMODE_1MUX_FHD, 0);
nvp6158_set_portmode(chip, 1, NVP6158_OUTMODE_1MUX_FHD, 1);
nvp6158_set_portmode(chip, 2, NVP6158_OUTMODE_1MUX_FHD, 2);
nvp6158_set_portmode(chip, 3, NVP6158_OUTMODE_1MUX_FHD, 3);
}
else //if(chip_id[chip] == NVP6158C_R0_ID)
{
//设置nvp6158C 2个port的输出模式, 1/2 port口可用
nvp6158_set_portmode(chip, 1, NVP6158_OUTMODE_2MUX_FHD, 0);
nvp6158_set_portmode(chip, 2, NVP6158_OUTMODE_2MUX_FHD, 1);
}
/* initialize Audio
* recmaster, pbmaster, ch_num, samplerate, bits */
if(chip_id[0]==NVP6158C_R0_ID || chip_id[0]==NVP6158_R0_ID)
audio_init(1,0,16,0,0);
else
nvp6168_audio_init(1,0,16,0,0);
#endif
ret = 0;
end:
printk("%s: I2C Addr 0x%02X ... end(%d)\n", __func__, client->addr, ret);
return ret;
}
static int nvp6158c_remove(struct i2c_client *client)
{
int i = 0;
printk("%s: I2C Addr 0x%02X ...\n", __func__, client->addr);
for(i=0; i<I2C_ADDR_CNT; i++) {
if(client->addr == nvp6158c_dev_addr[i]) {
break;
}
}
if(i >= I2C_ADDR_CNT) {
printk("!!! %s: cannot handle 0x%02X\n", __func__, client->addr);
return -ENODEV;
}
if(!nvp6158c_dev[i]) {
printk("!!! %s: 0x%02X handled before\n", __func__, client->addr);
return 0;
}
kfree(nvp6158c_dev[i]);
nvp6158c_dev[i] = NULL;
printk("%s: I2C Addr 0x%02X ... end\n", __func__, client->addr);
return 0;
}
static const struct i2c_device_id nvp6158c_idt[] = {
{ DRV_NAME, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, nvp6158c_idt);
static struct i2c_driver nvp6158c_i2c_drv = {
.probe = nvp6158c_probe,
.remove = nvp6158c_remove,
.driver = {
.name = DRV_NAME,
},
.id_table = nvp6158c_idt,
};
/* --------------------------------------------------------------------------------------------------- */
static int nvp6158c_open(struct inode *in, struct file *fl)
{
unsigned char i = 0;
unsigned int cnt = 0;
for(i=0; i<I2C_ADDR_CNT; i++) {
if(nvp6158c_dev_addr[i]) {
cnt |= (1 << i);
}
}
if(0 == cnt) {
printk("%s: no nvp6158c i2c dev connected !!!\n", __func__);
retur
nvp6158c_nvp6158c_
版权申诉
5星 · 超过95%的资源 158 浏览量
2021-09-30
08:26:17
上传
评论
收藏 7KB ZIP 举报
摇滚死兔子
- 粉丝: 54
- 资源: 4227
最新资源
- 3122080306 邹子轩 实验报告二.docx
- 基于STM32 NUCLEO板设计彩色LED照明灯(纯cubeMX开发)(大赛作品,文档完整,可直接运行)
- 发那科工业机器人保养大全
- Sphere.h
- REMD固有时间尺度分解信号分量可视化(Matlab完整源码和数据)
- 嵌入式系统双单片机STC89C52+STC15W104多功能学习板电路图可扩展 适用于单片机初学者和教学
- 基于STM32蓝牙控制小车系统设计(硬件+源代码+论文)大赛作品
- XILINXFPGA源码基于Spartan3火龙刀系列FPGA开发板VGA测试例程
- Java聊天室的设计与实现【尚学堂·百战程序员】
- python中matplotlib教程
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页