mirror of https://github.com/OpenIPC/firmware.git
704 lines
25 KiB
C
Executable File
704 lines
25 KiB
C
Executable File
/*
|
|
* copyright (c) hisilicon technologies co., ltd. 2016-2019. all rights reserved.
|
|
* description: thine_241a242_serdes.c
|
|
* author: hisilicon multimedia software group
|
|
* create: 2019-05-17
|
|
*/
|
|
|
|
#include "thine_241a242_serdes.h"
|
|
|
|
static inline void delay_us(const int us)
|
|
{
|
|
udelay(us);
|
|
return;
|
|
}
|
|
|
|
/* for 242 */
|
|
void write_serdes_rx_register(unsigned char i2c_dev, const unsigned int reg_addr, const unsigned int data)
|
|
{
|
|
unsigned int reg_addr_num = 2;
|
|
unsigned int data_byte_num = 1;
|
|
unsigned char dev_addr = THINE_DEVICE_ADDR;
|
|
|
|
serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);
|
|
|
|
return;
|
|
}
|
|
|
|
void write_serdes_rx_1bype_register(unsigned char i2c_dev, const unsigned int reg_addr, const unsigned int data)
|
|
{
|
|
unsigned int reg_addr_num = 1;
|
|
unsigned int data_byte_num = 1;
|
|
unsigned char dev_addr = THINE_DEVICE_ADDR;
|
|
|
|
serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);
|
|
|
|
return;
|
|
}
|
|
|
|
int read_serdes_rx_register(unsigned char i2c_dev, const unsigned int reg_addr)
|
|
{
|
|
unsigned int r_data = 0;
|
|
unsigned char dev_addr = (THINE_DEVICE_ADDR + 1);
|
|
|
|
serdes_i2c_read(i2c_dev, dev_addr, reg_addr, &r_data);
|
|
return r_data;
|
|
}
|
|
|
|
/* for 241 */
|
|
void write_serdes_tx_1bype_register(unsigned char i2c_dev, unsigned int reg_addr, const unsigned int data)
|
|
{
|
|
unsigned int reg_addr_num = 1;
|
|
unsigned int data_byte_num = 1;
|
|
unsigned char dev_addr = (sensor_dev_addr[i2c_dev] << 1);
|
|
|
|
serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);
|
|
return;
|
|
}
|
|
|
|
void write_serdes_tx_2bype_register(unsigned char i2c_dev, const unsigned int reg_addr, const unsigned int data)
|
|
{
|
|
unsigned int reg_addr_num = 2;
|
|
unsigned int data_byte_num = 1;
|
|
unsigned char dev_addr = (sensor_dev_addr[i2c_dev] << 1);
|
|
|
|
serdes_i2c_write(i2c_dev, dev_addr, reg_addr, reg_addr_num, data, data_byte_num);
|
|
return;
|
|
}
|
|
|
|
void set_serdes_data_rate(unsigned char i2c_dev, serdes_mode_t serdes_mode)
|
|
{
|
|
#if SERDES_DEBUG
|
|
int result = 0;
|
|
#endif
|
|
if (serdes_mode == SERDES_MODE_4LANE_LINEAR) {
|
|
write_serdes_rx_register(i2c_dev, 0x1609, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1609);
|
|
osal_printk("read 242 0x1609: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160A, 0x0C);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160A);
|
|
osal_printk("read 242 0x160A: 0x%x, should be 0x0C\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160B, 0x03);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160B);
|
|
osal_printk("read 242 0x160B: 0x%x, should be 0x03\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160C, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160C);
|
|
osal_printk("read 242 0x160C: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160D, 0x0C);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160D);
|
|
osal_printk("read 242 0x160D: 0x%x, should be 0x0C\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160E, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160E);
|
|
osal_printk("read 242 0x160E: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160F, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160F);
|
|
osal_printk("read 242 0x160F: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1610, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1610);
|
|
osal_printk("read 242 0x1610: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1611, 0x02);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1611);
|
|
osal_printk("read 242 0x1611: 0x%x, should be 0x02\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1612, 0x02);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1612);
|
|
osal_printk("read 242 0x1612: 0x%x, should be 0x02\n", result);
|
|
#endif
|
|
} else if ((serdes_mode == SERDES_MODE_2LANE_LINEAR) ||
|
|
(serdes_mode == SERDES_MODE_4LANE_WDR)) {
|
|
write_serdes_rx_register(i2c_dev, 0x1609, 0x03);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1609);
|
|
osal_printk("read 242 0x1609: 0x%x, should be 0x03\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160A, 0x0F);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160A);
|
|
osal_printk("read 242 0x160A: 0x%x, should be 0x0F\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160B, 0x05);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160B);
|
|
osal_printk("read 242 0x160B: 0x%x, should be 0x05\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160C, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160C);
|
|
osal_printk("read 242 0x160C: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160D, 0x0A);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160D);
|
|
osal_printk("read 242 0x160D: 0x%x, should be 0x0A\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160E, 0x02);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160E);
|
|
osal_printk("read 242 0x160E: 0x%x, should be 0x02\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160F, 0x02);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160F);
|
|
osal_printk("read 242 0x160F: 0x%x, should be 0x02\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1610, 0x03);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1610);
|
|
osal_printk("read 242 0x1610: 0x%x, should be 0x03\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1611, 0x02);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1611);
|
|
osal_printk("read 242 0x1611: 0x%x, should be 0x02\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1612, 0x04);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1612);
|
|
osal_printk("read 242 0x1612: 0x%x, should be 0x04\n", result);
|
|
#endif
|
|
} else if (serdes_mode == SERDES_MODE_2LANE_WDR) {
|
|
write_serdes_rx_register(i2c_dev, 0x1609, 0x04);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1609);
|
|
osal_printk("read 242 0x1609: 0x%x, should be 0x04\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160A, 0x23);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160A);
|
|
osal_printk("read 242 0x160A: 0x%x, should be 0x23\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160B, 0x08);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160B);
|
|
osal_printk("read 242 0x160B: 0x%x, should be 0x08\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160C, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160C);
|
|
osal_printk("read 242 0x160C: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160D, 0x11);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160D);
|
|
osal_printk("read 242 0x160D: 0x%x, should be 0x11\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160E, 0x09);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160E);
|
|
osal_printk("read 242 0x160E: 0x%x, should be 0x09\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x160F, 0x06);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x160F);
|
|
osal_printk("read 242 0x160F: 0x%x, should be 0x06\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1610, 0x06);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1610);
|
|
osal_printk("read 242 0x1610: 0x%x, should be 0x06\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1611, 0x10);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1611);
|
|
osal_printk("read 242 0x1611: 0x%x, should be 0x10\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1612, 0x08);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1612);
|
|
osal_printk("read 242 0x1612: 0x%x, should be 0x08\n", result);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void get_serdes_cfg(serdes_mode_t serdes_mode, serdes_config *cfg)
|
|
{
|
|
if (serdes_mode == SERDES_MODE_4LANE_LINEAR) {
|
|
osal_memcpy(cfg, &imx307_4_lane_linear_12_bit_30_fps_cfg, sizeof(serdes_config));
|
|
} else if (serdes_mode == SERDES_MODE_4LANE_WDR) {
|
|
osal_memcpy(cfg, &imx307_4_lane_wdr_12_bit_30_fps_cfg, sizeof(serdes_config));
|
|
} else if (serdes_mode == SERDES_MODE_2LANE_LINEAR) {
|
|
osal_memcpy(cfg, &imx307_2_lane_linear_12_bit_30_fps_cfg, sizeof(serdes_config));
|
|
} else {
|
|
osal_memcpy(cfg, &imx307_2_lane_wdr_12_bit_30_fps_cfg, sizeof(serdes_config));
|
|
}
|
|
}
|
|
|
|
void serdes_241_242_init(unsigned char i2c_dev, serdes_mode_t serdes_mode)
|
|
{
|
|
int i = 0;
|
|
serdes_config cfg;
|
|
#if SERDES_DEBUG
|
|
int result = 0;
|
|
#endif
|
|
|
|
get_serdes_cfg(serdes_mode, &cfg);
|
|
|
|
/*---------------------------------------------------------
|
|
step1: THCV242 sub-link mode : THCV241A ID
|
|
------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0050, 0x34);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0050);
|
|
osal_printk("read 242 0x0050: 0x%x, should be 0x34\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step1: THCV242 sub-link mode : pass throuth mode
|
|
------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0004, 0x03);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0004);
|
|
osal_printk("read 242 0x0004: 0x%x, should be 0x3\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step2: THCV242 sub link en/pol : lane 0 enable polling off
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0010, 0x10); // polling off
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0010);
|
|
osal_printk("read 242 0x0010: 0x%x, should be 0x10\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step3: THCV242 sub link power on
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x1704, 0x01);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1704);
|
|
osal_printk("read 242 0x1704: 0x%x, should be 0x1\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step4: THCV242 sub link tx term 50ohm
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0102, 0x02); // 50ohm
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0102);
|
|
osal_printk("read 242 0x0102: 0x%x, should be 0x2\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step5: THCV242 sub link tx drv 12ma
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0103, 0x02); // 12m_a
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0103);
|
|
osal_printk("read 242 0x0103: 0x%x, should be 0x2\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step6: THCV242 sub link rx term : 50ohm
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0104, 0x02); // 50ohm
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0104);
|
|
osal_printk("read 242 0x0104: 0x%x, should be 0x2\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step7: THCV242 rx drv : 12ma
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0105, 0x02); // 12mA
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0105);
|
|
osal_printk("read 242 0x0105: 0x%x, should be 0x2\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step8: THCV242 reserved setting : key is unlocked
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0100, 0x03);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0100);
|
|
osal_printk("read 242 0x0100: 0x%x, should be 0x3\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step9: THCV242 reserved setting : key2 is unlocked
|
|
------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x010F, 0x25);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x010F);
|
|
osal_printk("read 242 0x010F: 0x%x, should be 0x25\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step10: THCV242 reserved setting : sub link width
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x010A, 0x15); // 0x15 -> 0x18 -> 0x15
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x010A);
|
|
osal_printk("read 242 0x010A: 0x%x, should be 0x15\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0031, 0x02);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0031);
|
|
osal_printk("read 242 0x0031: 0x%x, should be 0x2\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0032);
|
|
osal_printk("read 242 0x0032: 0x%x, should be 0x10\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step13: THCV241 bank is 00
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_2bype_register(i2c_dev, 0x00FE, 0x11);
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x00);
|
|
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0032);
|
|
osal_printk("read 242 0x0032: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
/*---------------------------------------------------------
|
|
step14: THCV241 sub link tx term / drv setting:50ohm 12ma
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00F2, 0x22); // 50ohm/12mA
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00F3, 0x22); // 50ohm/12mA
|
|
|
|
/*---------------------------------------------------------
|
|
step15: THCV241 reserved setting : key is unlocked
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00F0, 0x03);
|
|
|
|
/*---------------------------------------------------------
|
|
THCV241 reserved setting : key 2 is unlocked
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00FF, 0x19);
|
|
|
|
/*---------------------------------------------------------
|
|
step16: THCV241 reserved setting : sub link width
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00F6, 0x18); // 0x15
|
|
|
|
/*---------------------------------------------------------
|
|
step16: THCV241 I2C freq 400k_hz
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00C9, 0x05);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00CA, 0x05);
|
|
|
|
/*---------------------------------------------------------
|
|
step17: THCV242 sub link en/pol : lane 0 enable polling on
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x0010, 0x11);
|
|
|
|
|
|
/*---------------------------------------------------------
|
|
step18: THCV241 bank is 10
|
|
---------------------------------------------------------*/
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x002C, 0x01);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x002D, cfg.pll_value[i]);
|
|
i += 1;
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0076, 0x10);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0000, 0x00);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0001, 0x00);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x000F, 0x01);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0011, cfg.pll_value[i]);
|
|
i += 1;
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0012, 0x00);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0013, 0x00);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0014, 0x00);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0015, cfg.pll_value[i]);
|
|
i += 1;
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0016, 0x01);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x002B, 0x07);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x002F, 0x00);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x01);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x01);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0027, 0x00);
|
|
|
|
/*---------------------------------------------------------
|
|
step19: THCV242
|
|
---------------------------------------------------------*/
|
|
write_serdes_rx_register(i2c_dev, 0x1010, 0xA1);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1010);
|
|
osal_printk("read 242 0x1010: 0x%x, should be 0xa1\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1021, 0x20);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1021);
|
|
osal_printk("read 242 0x1021: 0x%x, should be 0x20\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1022, cfg.pll_value[i]);
|
|
i += 1;
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1022);
|
|
osal_printk("read 242 0x1022: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1023, cfg.pll_value[i]);
|
|
i += 1;
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1023);
|
|
osal_printk("read 242 0x1023: 0x%x, should be 0x41--4L linear, 0x21--4L wdr\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1024, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1024);
|
|
osal_printk("read 242 0x1024: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1025, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1025);
|
|
osal_printk("read 242 0x1025: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1026, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1026);
|
|
osal_printk("read 242 0x1026: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1027, 0x07);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1027);
|
|
osal_printk("read 242 0x1027: 0x%x, should be 0x07\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1028, cfg.pll_value[i]);
|
|
i += 1;
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1028);
|
|
osal_printk("read 242 0x1028: 0x%x, should be 0x00--4lane, 0x2--2lane\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1030, 0x00);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1030);
|
|
osal_printk("read 242 0x1030: 0x%x, should be 0x00\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1100, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1100);
|
|
osal_printk("read 242 0x1100: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1101, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1101);
|
|
osal_printk("read 242 0x1101: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1102, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1102);
|
|
osal_printk("read 242 0x1102: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1600, 0x1A);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1600);
|
|
osal_printk("read 242 0x1600: 0x%x, should be 0x1a\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1605, cfg.pll_value[i]);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1605);
|
|
osal_printk("read 242 0x1605: 0x%x, should be 0x2b--4lane, 0x29--2lane\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1606, 0x45);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1606);
|
|
osal_printk("read 242 0x1606: 0x%x, should be 0x45\n", result);
|
|
#endif
|
|
|
|
set_serdes_data_rate(i2c_dev, serdes_mode);
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1704, 0x11);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1704);
|
|
osal_printk("read 242 0x1704: 0x%x, should be 0x11\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x1703, 0x01);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x1703);
|
|
osal_printk("read 242 0x1703: 0x%x, should be 0x01\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0032);
|
|
osal_printk("read 242 0x0032: 0x%x, should be 0x10\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0040, 0x1A);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0040);
|
|
osal_printk("read 242 0x0040: 0x%x, should be 0x1a\n", result);
|
|
#endif
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0041, 0x1A);
|
|
#if SERDES_DEBUG
|
|
result = read_serdes_rx_register(i2c_dev, 0x0041);
|
|
osal_printk("read 242 0x0041: 0x%x, should be 0x1a\n", result);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
void serdes_242_reset(unsigned char i2c_dev)
|
|
{
|
|
write_serdes_rx_register(i2c_dev, 0x1701, 0x3F);
|
|
write_serdes_rx_register(i2c_dev, 0x1702, 0x01); // SW reset
|
|
write_serdes_rx_register(i2c_dev, 0x1703, 0x00); // PLL power down
|
|
write_serdes_rx_register(i2c_dev, 0x1704, 0x00); // Vx1HS Sub-Link power down
|
|
write_serdes_rx_register(i2c_dev, 0x0050, 0x34);
|
|
write_serdes_rx_register(i2c_dev, 0x0004, 0x03);
|
|
write_serdes_rx_register(i2c_dev, 0x0010, 0x10);
|
|
write_serdes_rx_register(i2c_dev, 0x1704, 0x01); // Vx1HS Sub-Link power on
|
|
write_serdes_rx_register(i2c_dev, 0x0102, 0x02);
|
|
write_serdes_rx_register(i2c_dev, 0x0103, 0x02);
|
|
write_serdes_rx_register(i2c_dev, 0x0104, 0x02);
|
|
write_serdes_rx_register(i2c_dev, 0x0105, 0x02);
|
|
write_serdes_rx_register(i2c_dev, 0x0100, 0x03);
|
|
write_serdes_rx_register(i2c_dev, 0x010F, 0x25);
|
|
write_serdes_rx_register(i2c_dev, 0x010A, 0x15);
|
|
}
|
|
|
|
void serdes_241a_reset(unsigned char i2c_dev)
|
|
{
|
|
write_serdes_rx_1bype_register(i2c_dev, 0x0031, 0x02);
|
|
write_serdes_rx_1bype_register(i2c_dev, 0x0032, 0x00); // 1byte address, 1byte data access
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x21); // THCV241 bank is 10
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0005, 0x00); // PLL Soft Reset Active
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0006, 0x00); // Vx1HS Soft Reset Active
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0021, 0x00); // MIPI Logic Reset
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0022, 0x00); // Logic Reset
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0023, 0x00); // MIPI Clock Reset
|
|
|
|
delay_us(1000);
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0021, 0x01); // MIPI Logic Reset
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0022, 0x01); // Logic Reset
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x0023, 0x01); // MIPI Clock Reset
|
|
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x00FE, 0x00);
|
|
}
|
|
|
|
void serdes_241_242_exit(unsigned char i2c_dev)
|
|
{
|
|
serdes_242_reset(i2c_dev);
|
|
|
|
serdes_241a_reset(i2c_dev);
|
|
}
|
|
|
|
void serdes_thine_init(int i2c_dev, serdes_mode_t serdes_mode)
|
|
{
|
|
serdes_241_242_init(i2c_dev, serdes_mode);
|
|
}
|
|
|
|
void serdes_thine_exit(int i2c_dev)
|
|
{
|
|
serdes_241_242_exit(i2c_dev);
|
|
}
|
|
|
|
void serdes_reset_unreset_sensor(unsigned char i2c_dev, int reset)
|
|
{
|
|
const unsigned int tmp = reset ? 0x00 : 0x30; // 10/11 -> 00/30
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x00);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0xFE, 0x21);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x3E, tmp);
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
|
|
}
|
|
EXPORT_SYMBOL(serdes_reset_unreset_sensor);
|
|
|
|
void serdes_enable_disable_sensor_clock(unsigned char i2c_dev, int enable)
|
|
{
|
|
const unsigned int tmp = enable ? 0x10 : 0x50;
|
|
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x00);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0xFE, 0x21);
|
|
write_serdes_tx_1bype_register(i2c_dev, 0x76, tmp);
|
|
write_serdes_rx_register(i2c_dev, 0x0032, 0x10);
|
|
}
|
|
EXPORT_SYMBOL(serdes_enable_disable_sensor_clock);
|