Hi ALL!
At this moment, I use DM365EVM (DVSDK4.02) with TVP5150 (instead of TVP5146) for PAL cam.
TVP5150 was placed on a custom daughter card into IMAGER interface (J10).
This is small how to.
Step 1: "drivers/media/video/tvp5150.c"
I made a few changes:
1. The outputs is in tristate mode (disabled) by defaults. You need to enable outputs!!!
Look at 'static inline void tvp5150_selmux()'
----
/* Svideo should enable YCrCb output and disable GPCL output
* For Composite and TV, it should be the reverse
*/
val = tvp5150_read(sd, TVP5150_MISC_CTL);
if (decoder->input == TVP5150_SVIDEO)
val = (val & ~0x40) | 0x10;
else
val = (val & ~0x10) | 0x40;
val = val | 0x08; //!!! My fix. (enable outputs)
tvp5150_write(sd, TVP5150_MISC_CTL, val);
----
2. You can modify printout of i2c adr at 'tvp5150_probe()' and 'tvp5150_remove()' so driver will print more intelligible i2c adr (eg, '5D' instead of 'BA').
Simple change "c->addr << 1" to "c->addr".
I think that nothing else do not need to touch in this 'tvp5150.c' file!
But, you really have something to edit the file "vpfe-capture.c".
Step 2: "drivers/media/video/davinci/vpfe_capture.c"
1)
static int vpfe_config_ccdc_image_format()
----
/* At CCDC we need to set pix format based on source. */
if (vpfe_dev->imp_chained) {
if (vpfe_dev->current_subdev->is_camera)
pix_fmt = V4L2_PIX_FMT_SBGGR16;
else if (pix_fmt == V4L2_PIX_FMT_NV12)
pix_fmt = V4L2_PIX_FMT_UYVY;
}
pix_fmt = V4L2_PIX_FMT_UYVY; //!!! My fix!
if (ccdc_dev->hw_ops.set_pixel_format(pix_fmt) < 0) {
v4l2_err(&vpfe_dev->v4l2_dev,
"couldn't set pix format in ccdc\n");
return -EINVAL;
}
/* configure the image window */
ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
vpfe_dev->fmt.fmt.pix.field=V4L2_FIELD_INTERLACED; //!!! My fix!
switch (vpfe_dev->fmt.fmt.pix.field) {
case V4L2_FIELD_INTERLACED:
----
2)
static int vpfe_config_image_format()
----
/* first field and frame format based on standard frame format */
if (vpfe_dev->std_info.frame_format) {
vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
/* assume V4L2_PIX_FMT_UYVY as default */
vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
} else {
vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE;
vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
}
// sd_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
sd_fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; //!!! My fix!
/* if sub device supports g_fmt, override the defaults */
ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
----
Very important! the driver will not work if sd_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE !!!
You need change it to sd_fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE
3)
static int vpfe_s_input()
----
/* set the default image parameters in the device */
if (vpfe_dev->current_subdev->is_camera) {
vpfe_dev->std_index = -1;
/* for camera, use ccdc default parameters */
ret = vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt);
/* also set the current default format in the sensor */
if (ret)
goto unlock_out;
ret = vpfe_set_format_in_sensor(vpfe_dev, &vpfe_dev->fmt);
} else {
//vpfe_dev->std_index = 0; //NTSC
vpfe_dev->std_index = 1; //!!!My fix for PAL
/*
* For non-camera sub device, use standard to configure vpfe
* default
*/
ret = vpfe_config_image_format(vpfe_dev,
&vpfe_standards[vpfe_dev->std_index].std_id);
}
----
vpfe_dev->std_index =1; //(my settings for PAL)
see "const struct vpfe_standard vpfe_standards[]" at the top of "vpfe-capture.c" for details.
That's all that I corrected in the file 'vpfe-capture.c'.
Step 3: "include/media/davinci/vpfe_capture.h"
I added the 'tvp5150' device into 'include/media/davinci/vpfe_capture.h'
----
enum vpfe_subdev_id {
VPFE_SUBDEV_TVP5146 = 1,
VPFE_SUBDEV_MT9T031 = 2,
VPFE_SUBDEV_TVP7002 = 3,
VPFE_SUBDEV_MT9P031 = 4,
VPFE_SUBDEV_TVP5150 = 5, //!!!
};
----
The next changes are arch specific.
In my case I edited 'arch/arm/mach-davinci/board-dm365-evm.c'
Step 4: "arch/arm/mach-davinci/board-dm365-evm.c"
My TVP5150 is connected to DM365EVM via IMAGER interface, because I needed to make the correct switching of the multiplexer.
Also in this file, I prescribed a "tvp5150_inputs []" and yet something.
----
#include <media/tvp5150.h>
--- -
#define TVP5150_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
/* Inputs available at the TVP5150 */
static struct v4l2_input tvp5150_inputs[] = {
{
.index = 0,
.name = "Composite",
.type = V4L2_INPUT_TYPE_CAMERA,
.std = TVP5150_STD_ALL,
},
{
.index = 1,
.name = "Composite1",
.type = V4L2_INPUT_TYPE_CAMERA,
.std = TVP5150_STD_ALL,
},
};
----
static struct vpfe_route tvp5150_routes[] = {
{ //see "include/media/tvp5150.h"
.input = TVP5150_COMPOSITE0,
.output = TVP5150_NORMAL,
},
};
----
static struct vpfe_subdev_info vpfe_sub_devs[] = {
{
.module_name = "tvp5150",
.grp_id = VPFE_SUBDEV_TVP5150,
.num_inputs = ARRAY_SIZE(tvp5150_inputs),
.inputs = tvp5150_inputs,
.routes = tvp5150_routes,
.can_route = 1,
.ccdc_if_params = {
.if_type = VPFE_BT656,
.hdpol = VPFE_PINPOL_POSITIVE,
.vdpol = VPFE_PINPOL_POSITIVE,
},
.board_info = {
I2C_BOARD_INFO("tvp5150", 0x5c), // <- place correct i2c adr here!
},
},
/*
ALL OTHERS CODECS (tvp5146,tvp7002,ths7353,mt9p031) ARE COMMENTED HERE! = disabled
*/
}; //end of struct vpfe_subdev_info vpfe_sub_devs[]
----
static int dm365evm_setup_video_input(enum vpfe_subdev_id id)
{
const char *label;
u8 mux, resets;
mux = __raw_readb(cpld + CPLD_MUX);
mux &= ~CPLD_VIDEO_INPUT_MUX_MASK;
resets = __raw_readb(cpld + CPLD_RESETS);
switch (id) {
case VPFE_SUBDEV_TVP5150:
mux |= CPLD_VIDEO_INPUT_MUX_IMAGER;
label = "tvp5150 SD";
break;
case VPFE_SUBDEV_TVP5146:
mux |= CPLD_VIDEO_INPUT_MUX_TVP5146;
resets &= ~BIT(0);
label = "tvp5146 SD";
dm365evm_reset_imager(0);
break;
----
That's all for 'board-dm365-evm.c'.
Step 5: Kernel Config (.config)
#
# Video decoders
#
…
CONFIG_VIDEO_TVP5150=y
…
Step 6: TEST IT!
SO! I HAVE IT ALL WORKS!
PS: I also got to change on the fly: Brightness, Contrast, Saturation and Hue.
Step 7: $DVSDK/dmai_2_20_00_15/packages/ti/sdo/dmai/linux/dm365/Capture.c
at the end of 'Capture_Handle Capture_create()'
----
...
hCapture->started = TRUE;
Tvp5150_fd = hCapture->fd; //store file id
return hCapture;
} //end of Capture_Handle Capture_create
...
----
at the top of 'Capture.c' file
----
...
extern Int Resizer_continuous_delete(int fd);
extern Int Previewer_continuous_delete(int fd);
int Tvp5150_fd=-1;
void Capture_chngTVPCtrl(unsigned char id, unsigned char val) {
if(Tvp5150_fd<0) {
printf("DMAI_Capture: TVP5150Ctl: Tvp5150_fd < 0\n");
return;
}
struct v4l2_control ctrl;
__s32 vv=val;
switch (id) {
case 0:
ctrl.id = V4L2_CID_BRIGHTNESS;
break;
case 1:
ctrl.id = V4L2_CID_CONTRAST;
break;
case 2:
ctrl.id = V4L2_CID_SATURATION;
break;
case 3:
ctrl.id = V4L2_CID_HUE;
vv=(__s32)val-128;
break;
default:
return;
}
ctrl.value = vv;
if (-1 == ioctl (Tvp5150_fd, VIDIOC_S_CTRL, &ctrl)) {
printf("DMAI_Capture: TVP5150Ctl: VIDIOC_S_CTRL failed!\n");
}
}
/******************************************************************************
* cleanup
******************************************************************************/
static Int cleanup(Capture_Handle hCapture)
...
----
Step 8: Change brightness and so on from DVSDK-DEMO (encode) EXAMPLE.
$DVSDK/dvsdk-demos_4_02_00_01/dm365/ctrl.c
------
#include <ti/sdo/dmai/Capture.h>
…
// Try other values!
unsigned char brt=128; //brightness 0..255
unsigned char con=128; //contrast 0..255
unsigned char sat=128; //saturation 0..255
unsigned char hue=128; //HUE 0..255
Capture_chngTVPCtrl(0,brt); //set brightness
Capture_chngTVPCtrl(1,con); //set contrast
Capture_chngTVPCtrl(2,sat); //set saturation
Capture_chngTVPCtrl(3,hue); //set hue
...
------
IT WORKS! :-)
Good luck!