Files
base/drivers/source/camera/csi-baremetal/excam/ex_tp2825.c
2025-11-07 09:57:14 +08:00

568 lines
17 KiB
C

#include "ex_tp2825.h"
#include "camera/sdrv-cam-os-def.h"
//#define SENSOR_OV2K10 1
#define SENSOR_OVX3D 1
//High 2825 7bit Address
#define tp2825_DEVICE_ID 0x44
static uint32_t s_tp2825_width = 1920;
static uint32_t s_tp2825_height = 1080;
#if SENSOR_OV2K10
static uint32_t s_tp2825_fps = 30;
#else
static uint32_t s_tp2825_fps = 29;
#endif
enum tp2825_status {
SERSOR_IDLE,
SERSOR_STREAM_ON,
};
struct tp2825_dev {
struct vdev_device vdev;
void *i2c_handle;
uint8_t deser_addr;
uint8_t serder_addr;
uint32_t gpio_pwr; // power supply pin
uint32_t gpio_rst; // reset pin
osMutexId_t lock;
uint32_t status;
};
static int tp2825_write_reg(struct tp2825_dev *sensor, uint8_t reg, uint8_t val)
{
uint8_t buf[2];
int ret = 0;
//sensor_info("%s: addr=0x%x, reg=0x%x, val=0x%x\n", __func__,sensor->deser_addr, reg, val);
buf[0] = reg;
buf[1] = val;
ret = i2c_write(sensor->i2c_handle, sensor->deser_addr, buf, 2);
if (ret < 0) {
sensor_err("%s: error: reg=0x%x, val=%x\n", __func__, reg, val);
return ret;
}
return ret;
}
static int tp2825_read_reg(struct tp2825_dev *sensor, uint8_t reg, uint8_t *val)
{
uint8_t buf[1];
int ret = 0;
memset(buf, 0, sizeof(buf));
ret = i2c_write_read(sensor->i2c_handle, sensor->deser_addr, &reg, 1, buf, 1);
if (ret < 0) {
sensor_err("%s: error: read reg=0x%02x\n", __func__, reg);
return ret;
}
*val = buf[0];
return 0;
}
__UNUSED static int tp2825_check_chip_id(struct tp2825_dev *sensor)
{
int ret = 0;
uint8_t val[2];
uint16_t chip_id = 0;
ret = tp2825_read_reg(sensor, 0xfe, &val[0]);
ret |= tp2825_read_reg(sensor, 0xff, &val[1]);
chip_id = val[1]<<8 | val[0];
if(chip_id != 0x2850) {
ret = -1;
}
sensor_info("%s 0x%x 0x%x 0x%x\n", __func__, val[0],val[1], chip_id);
return ret;
}
static int tp2825_init_setup(struct tp2825_dev *sensor)
{
sensor_info("%s \r\n",__func__ );
#if SENSOR_OV2K10
tp2825_write_reg(sensor,0x0,0x11);
tp2825_write_reg(sensor,0x1,0x7E);
tp2825_write_reg(sensor,0x2,0x40);
tp2825_write_reg(sensor,0x3,0x03);
tp2825_write_reg(sensor,0x4,0x00);
tp2825_write_reg(sensor,0x5,0x00);
tp2825_write_reg(sensor,0x6,0x32);
tp2825_write_reg(sensor,0x7,0xC0);
tp2825_write_reg(sensor,0x8,0x00);
tp2825_write_reg(sensor,0x9,0x24);
tp2825_write_reg(sensor,0xA,0x48);
tp2825_write_reg(sensor,0xB,0xC0);
tp2825_write_reg(sensor,0xC,0x03);
tp2825_write_reg(sensor,0xD,0x50);
tp2825_write_reg(sensor,0xE,0x00);
tp2825_write_reg(sensor,0xF,0x0);
tp2825_write_reg(sensor,0x10,0x00);
tp2825_write_reg(sensor,0x11,0x40);
tp2825_write_reg(sensor,0x12,0x40);
tp2825_write_reg(sensor,0x13,0x00);
tp2825_write_reg(sensor,0x14,0x00);
tp2825_write_reg(sensor,0x15,0x03);
tp2825_write_reg(sensor,0x16,0xD2);
tp2825_write_reg(sensor,0x17,0x80);
tp2825_write_reg(sensor,0x18,0x29);
tp2825_write_reg(sensor,0x19,0x38);
tp2825_write_reg(sensor,0x1A,0x47);
tp2825_write_reg(sensor,0x1B,0x01);
tp2825_write_reg(sensor,0x1C,0x08);
tp2825_write_reg(sensor,0x1D,0x98);
tp2825_write_reg(sensor,0x1E,0x80);
tp2825_write_reg(sensor,0x1F,0x80);
tp2825_write_reg(sensor,0x20,0x30);
tp2825_write_reg(sensor,0x21,0x84);
tp2825_write_reg(sensor,0x22,0x36);
tp2825_write_reg(sensor,0x23,0x3C);
tp2825_write_reg(sensor,0x24,0x04);
tp2825_write_reg(sensor,0x25,0xFF);
tp2825_write_reg(sensor,0x26,0x05);
tp2825_write_reg(sensor,0x27,0x2D);
tp2825_write_reg(sensor,0x28,0x00);
tp2825_write_reg(sensor,0x29,0x48);
tp2825_write_reg(sensor,0x2A,0x30);
tp2825_write_reg(sensor,0x2B,0x60);
tp2825_write_reg(sensor,0x2C,0x0A);
tp2825_write_reg(sensor,0x2D,0x30);
tp2825_write_reg(sensor,0x2E,0x70);
tp2825_write_reg(sensor,0x2F,0x00);
tp2825_write_reg(sensor,0x30,0x48);
tp2825_write_reg(sensor,0x31,0xBB);
tp2825_write_reg(sensor,0x32,0x2E);
tp2825_write_reg(sensor,0x33,0x90);
tp2825_write_reg(sensor,0x34,0x00);
tp2825_write_reg(sensor,0x35,0x05);
tp2825_write_reg(sensor,0x36,0xDC);
tp2825_write_reg(sensor,0x37,0x00);
tp2825_write_reg(sensor,0x38,0x40);
tp2825_write_reg(sensor,0x39,0x1C);
tp2825_write_reg(sensor,0x3A,0x32);
tp2825_write_reg(sensor,0x3B,0x26);
tp2825_write_reg(sensor,0x3C,0x00);
tp2825_write_reg(sensor,0x3D,0x60);
tp2825_write_reg(sensor,0x3E,0x00);
tp2825_write_reg(sensor,0x3F,0x00);
tp2825_write_reg(sensor,0x40,0x00);
tp2825_write_reg(sensor,0x41,0x00);
tp2825_write_reg(sensor,0x42,0x00);
tp2825_write_reg(sensor,0x43,0x00);
tp2825_write_reg(sensor,0x44,0x00);
tp2825_write_reg(sensor,0x45,0x00);
tp2825_write_reg(sensor,0x46,0x00);
tp2825_write_reg(sensor,0x47,0x00);
tp2825_write_reg(sensor,0x48,0x00);
tp2825_write_reg(sensor,0x49,0x00);
tp2825_write_reg(sensor,0x4A,0x00);
tp2825_write_reg(sensor,0x4B,0x00);
tp2825_write_reg(sensor,0x4C,0x43);
tp2825_write_reg(sensor,0x4D,0x00);
tp2825_write_reg(sensor,0x4E,0x0D);
tp2825_write_reg(sensor,0x4F,0x00);
tp2825_write_reg(sensor,0xF0,0x00);
tp2825_write_reg(sensor,0xF1,0x00);
tp2825_write_reg(sensor,0xF2,0x00);
tp2825_write_reg(sensor,0xF3,0x00);
tp2825_write_reg(sensor,0xF4,0x20);
tp2825_write_reg(sensor,0xF5,0x10);
tp2825_write_reg(sensor,0xF6,0x00);
tp2825_write_reg(sensor,0xF7,0x44);
tp2825_write_reg(sensor,0xF8,0x00);
tp2825_write_reg(sensor,0xF9,0x00);
tp2825_write_reg(sensor,0xFA,0x0b);
tp2825_write_reg(sensor,0xFB,0x00);
tp2825_write_reg(sensor,0xFC,0x00);
tp2825_write_reg(sensor,0xFD,0x80);
tp2825_write_reg(sensor,0xFE,0x28);
tp2825_write_reg(sensor,0xF0,0x00);
tp2825_write_reg(sensor,0xF1,0x00);
tp2825_write_reg(sensor,0xF2,0x00);
tp2825_write_reg(sensor,0xF3,0x00);
tp2825_write_reg(sensor,0xF4,0x20);
tp2825_write_reg(sensor,0xF5,0x10);
tp2825_write_reg(sensor,0xF6,0x00);
tp2825_write_reg(sensor,0xF7,0x44);
tp2825_write_reg(sensor,0xF8,0x00);
tp2825_write_reg(sensor,0xF9,0x00);
tp2825_write_reg(sensor,0xFA,0x0b);
tp2825_write_reg(sensor,0xFB,0x00);
tp2825_write_reg(sensor,0xFC,0x00);
tp2825_write_reg(sensor,0xFD,0x80);
tp2825_write_reg(sensor,0xFE,0x28);
tp2825_write_reg(sensor,0x40,0x08); //mpage select
tp2825_write_reg(sensor,0x13,0x04);
tp2825_write_reg(sensor,0x40,0x00); //back to decoder page
#else
//config 0x3D 1920X1080 29 FPS settings
tp2825_write_reg(sensor,0x00,0x11);
tp2825_write_reg(sensor,0x02,0x40);
tp2825_write_reg(sensor,0x03,0x03);
tp2825_write_reg(sensor,0x05,0x00);
tp2825_write_reg(sensor,0x06,0x32);
tp2825_write_reg(sensor,0x07,0xC0);
tp2825_write_reg(sensor,0x08,0x00);
tp2825_write_reg(sensor,0x09,0x24);
tp2825_write_reg(sensor,0x0A,0x48);
tp2825_write_reg(sensor,0x0B,0xC0);
tp2825_write_reg(sensor,0x0C,0x03);
tp2825_write_reg(sensor,0x0D,0x50);
tp2825_write_reg(sensor,0x0E,0x00);
tp2825_write_reg(sensor,0x0F,0x00);
tp2825_write_reg(sensor,0x10,0x00);
tp2825_write_reg(sensor,0x11,0x40);
tp2825_write_reg(sensor,0x12,0x40);
tp2825_write_reg(sensor,0x13,0x00);
tp2825_write_reg(sensor,0x14,0x00);
tp2825_write_reg(sensor,0x15,0x13);
tp2825_write_reg(sensor,0x16,0xE8);
tp2825_write_reg(sensor,0x17,0x80);
tp2825_write_reg(sensor,0x18,0x54);
tp2825_write_reg(sensor,0x19,0x38);
tp2825_write_reg(sensor,0x1A,0x47);
tp2825_write_reg(sensor,0x1B,0x01);
tp2825_write_reg(sensor,0x1C,0x09);
tp2825_write_reg(sensor,0x1D,0xab);
tp2825_write_reg(sensor,0x1E,0x80);
tp2825_write_reg(sensor,0x1F,0x80);
tp2825_write_reg(sensor,0x20,0x30);
tp2825_write_reg(sensor,0x21,0x84);
tp2825_write_reg(sensor,0x22,0x36);
tp2825_write_reg(sensor,0x23,0x3C);
tp2825_write_reg(sensor,0x24,0x04);
tp2825_write_reg(sensor,0x25,0xFF);
tp2825_write_reg(sensor,0x26,0x05);
tp2825_write_reg(sensor,0x27,0x2D);
tp2825_write_reg(sensor,0x28,0x00);
tp2825_write_reg(sensor,0x29,0x48);
tp2825_write_reg(sensor,0x2A,0x30);
tp2825_write_reg(sensor,0x2B,0x60);
tp2825_write_reg(sensor,0x2C,0x0A);
tp2825_write_reg(sensor,0x2D,0x30);
tp2825_write_reg(sensor,0x2E,0x70);
tp2825_write_reg(sensor,0x2F,0x00);
tp2825_write_reg(sensor,0x30,0x48);
tp2825_write_reg(sensor,0x31,0xBB);
tp2825_write_reg(sensor,0x32,0x2E);
tp2825_write_reg(sensor,0x33,0x90);
tp2825_write_reg(sensor,0x34,0x00);
tp2825_write_reg(sensor,0x35,0x14);
tp2825_write_reg(sensor,0x36,0xB5);
tp2825_write_reg(sensor,0x37,0x00);
tp2825_write_reg(sensor,0x38,0x40);
tp2825_write_reg(sensor,0x39,0x1C);
tp2825_write_reg(sensor,0x3A,0x32);
tp2825_write_reg(sensor,0x3B,0x26);
tp2825_write_reg(sensor,0x3C,0x00);
tp2825_write_reg(sensor,0x3D,0x60);
tp2825_write_reg(sensor,0x3E,0x00);
tp2825_write_reg(sensor,0x3F,0x00);
tp2825_write_reg(sensor,0x40,0x00);
tp2825_write_reg(sensor,0x41,0x00);
tp2825_write_reg(sensor,0x42,0x00);
tp2825_write_reg(sensor,0x43,0x00);
tp2825_write_reg(sensor,0x44,0x00);
tp2825_write_reg(sensor,0x45,0x00);
tp2825_write_reg(sensor,0x46,0x00);
tp2825_write_reg(sensor,0x47,0x00);
tp2825_write_reg(sensor,0x48,0x00);
tp2825_write_reg(sensor,0x49,0x00);
tp2825_write_reg(sensor,0x4A,0x00);
tp2825_write_reg(sensor,0x4B,0x00);
tp2825_write_reg(sensor,0x4C,0x43);
tp2825_write_reg(sensor,0x4D,0x00);
tp2825_write_reg(sensor,0x4E,0x0D);
tp2825_write_reg(sensor,0x4F,0x00);
tp2825_write_reg(sensor,0xF0,0x00);
tp2825_write_reg(sensor,0xF1,0x00);
tp2825_write_reg(sensor,0xF2,0x00);
tp2825_write_reg(sensor,0xF3,0x00);
tp2825_write_reg(sensor,0xF4,0x20);
tp2825_write_reg(sensor,0xF5,0x10);
tp2825_write_reg(sensor,0xF6,0x00);
tp2825_write_reg(sensor,0xF7,0x44);
tp2825_write_reg(sensor,0xF8,0x00);
tp2825_write_reg(sensor,0xF9,0x00);
tp2825_write_reg(sensor,0xFA,0x0b);
tp2825_write_reg(sensor,0xFB,0x00);
tp2825_write_reg(sensor,0xFC,0x00);
tp2825_write_reg(sensor,0xFD,0x80);
tp2825_write_reg(sensor,0xFE,0x28);
tp2825_write_reg(sensor,0x40,0x08); // mpage select
tp2825_write_reg(sensor,0x13,0x04);
tp2825_write_reg(sensor,0x40,0x00);//back to decoder page
#endif
return 0;
}
static int tp2825_s_power(struct vdev_device *vdev, int enable)
{
struct tp2825_dev *sensor;
uint32_t pin;
if (!vdev) {
return -1;
}
sensor = (struct tp2825_dev *)vdev->priv_data;
pin = sensor->gpio_rst;
sensor_info("%s: pin %d\r\n", __func__, pin);
return 0;
}
static int tp2825_s_rst(struct vdev_device *vdev, int enable)
{
struct tp2825_dev *sensor;
uint32_t pin;
if (!vdev) {
return -1;
}
sensor = (struct tp2825_dev *)vdev->priv_data;
pin = sensor->gpio_rst;
sensor_info("%s: pin %d, enable %d\r\n", __func__, pin, enable);
gpio_set(NULL, pin, enable ? true : false);
return 0;
}
static int tp2825_read_regs(struct tp2825_dev *sensor)
{
uint8_t val = 0;
uint8_t reg;
//usleep_range(10000, 11000);
tp2825_write_reg(sensor, 0x40, 0x00);
for(reg =0 ; reg<0xff; reg++)
{
tp2825_read_reg(sensor, reg,&val);
sensor_info("reg:0x%x val 0x%x\n\r", reg,val);
}
sensor_info("tp2825 read switch page\n\r");
tp2825_write_reg(sensor, 0x40, 0x08);
for(int reg =0 ;reg<0xff;reg++)
{
tp2825_read_reg(sensor, reg,&val);
sensor_info("reg:0x%x val 0x%x\n\r",reg,val);
}
return 0;
}
static int tp2825_enum_mbus_fmt(struct vdev_device *vdev,
struct vdev_mbus_framefmt *fme)
{
struct tp2825_dev *sensor;
if ((vdev == NULL) || (fme == NULL)) {
return -1;
}
sensor_err("%s: \r\n", __func__);
sensor = (struct tp2825_dev *)vdev->priv_data;
if (fme->index > 0) {
fme->index = 0;
return -1;
}
fme->code = sensor->vdev.fmt.code;
fme->field = sensor->vdev.fmt.field;
fme->colorspace = sensor->vdev.fmt.colorspace;
return 0;
}
static int tp2825_enum_frame_size(struct vdev_device *vdev,
struct vdev_frame_size_enum *fse)
{
struct tp2825_dev *sensor;
sensor_err("%s: \r\n", __func__);
if (!vdev || !fse) {
return -1;
}
sensor = (struct tp2825_dev *)vdev->priv_data;
if (fse->index > 0) {
fse->index = 0;
return -1;
}
fse->min_width = sensor->vdev.fmt.width;
fse->max_width = sensor->vdev.fmt.width;
fse->min_height = sensor->vdev.fmt.height;
fse->max_height = sensor->vdev.fmt.height;
return 0;
}
static int tp2825_enum_frame_interval(struct vdev_device *vdev,
struct vdev_frame_interval_enum *fie)
{
sensor_err("%s: \r\n", __func__);
return 0;
}
static int tp2825_get_frame_interval(struct vdev_device *vdev,
struct vdev_fract *fi)
{
if (!vdev || !fi) {
return -1;
}
sensor_err("%s: \r\n", __func__);
*fi = vdev->frame_interval;
return 0;
}
static int tp2825_set_frame_interval(struct vdev_device *vdev,
struct vdev_fract fi)
{
sensor_info("%s: \r\n", __func__);
return 0;
}
static int tp2825_get_fmt(struct vdev_device *vdev,
struct vdev_mbus_framefmt *fmt)
{
if (!vdev) {
return -1;
}
sensor_info("%s: \r\n", __func__);
*fmt = vdev->fmt;
return 0;
}
static int tp2825_set_fmt(struct vdev_device *vdev,
struct vdev_mbus_framefmt fmt)
{
sensor_info("%s: \r\n", __func__);
return 0;
}
static int tp2825_s_stream(struct vdev_device *vdev, int enable)
{
int ret = 0;
struct tp2825_dev *sensor;
if (!vdev) {
return -1;
}
sensor_err("%s: \r\n", __func__);
sensor = (struct tp2825_dev *)vdev->priv_data;
osMutexAcquire(sensor->lock, 0);
if (enable == 1) {
if (sensor->status == SERSOR_STREAM_ON) {
sensor_info("%s: already stream on\r\n", __func__);
goto exit;
}
ret = tp2825_init_setup(sensor);
if (ret < 0)
goto exit;
mdelay(800); //delay 700 ms
tp2825_read_regs(sensor);
sensor->status = SERSOR_STREAM_ON;
} else {
sensor->status = SERSOR_IDLE;
}
exit:
osMutexRelease(sensor->lock);
return ret;
}
static int tp2825_deinit(struct vdev_device *vdev)
{
struct tp2825_dev *sensor;
if (!vdev) {
return -1;
}
sensor = (struct tp2825_dev *)vdev->priv_data;
osMutexDelete(sensor->lock);
free(sensor);
return 0;
}
static const struct vdev_dev_ops tp2825_vdev_ops = {
.s_power = tp2825_s_power,
.enum_mbus_fmt = tp2825_enum_mbus_fmt,
.enum_frame_size = tp2825_enum_frame_size,
.enum_frame_interval = tp2825_enum_frame_interval,
.g_frame_interval = tp2825_get_frame_interval,
.s_frame_interval = tp2825_set_frame_interval,
.get_fmt = tp2825_get_fmt,
.set_fmt = tp2825_set_fmt,
.s_stream = tp2825_s_stream,
.close = tp2825_deinit,
};
struct tp2825_dev g_tp2825;
struct vdev_device *tp2825_init(void *init_data)
{
struct tp2825_dev *sensor;
struct camera_res_cfg *cfg = (struct camera_res_cfg *)init_data;
//sensor = malloc(sizeof(struct tp2825_dev));
sensor = &g_tp2825;
if (!sensor || !cfg)
return NULL;
sensor_err("%s: \r\n", __func__);
memset(sensor, 0, sizeof(struct tp2825_dev));
sensor->i2c_handle = cfg->i2c_handle;
sensor->deser_addr = tp2825_DEVICE_ID;
sensor->gpio_rst = cfg->gpio[0]; //rst pin
sensor->gpio_pwr = cfg->gpio[1]; //pwr pin
sensor->vdev.priv_data = (void *)sensor;
sensor->lock = osMutexNew(NULL);
tp2825_s_rst(&sensor->vdev, 1);
usleep_range(1000, 1100);
tp2825_s_rst(&sensor->vdev, 0);
usleep_range(1000, 1000);
tp2825_s_rst(&sensor->vdev, 1);
//ret = tp2825_check_chip_id(sensor);
tp2825_s_stream(&sensor->vdev, 0);
sensor->vdev.ep.bus_type = VDEV_MBUS_BT1120SDR;
sensor->vdev.frame_interval.numerator = 1;
sensor->vdev.frame_interval.denominator = s_tp2825_fps;
sensor->vdev.fmt.width = s_tp2825_width;
sensor->vdev.fmt.height = s_tp2825_height;
sensor->vdev.fmt.code = VDEV_MBUS_FMT_UYVY16; //VDEV_MBUS_FMT_UYVY16 VDEV_MBUS_FMT_UYVY16
sensor->vdev.fmt.field = VDEV_FIELD_NONE;
sensor->vdev.fmt.colorspace = VDEV_COLORSPACE_SRGB;
sensor->vdev.ops = tp2825_vdev_ops;
//g_tp2825 = sensor;
return &sensor->vdev;
}