Hi Maciej, On 08/10/2017 11:50 PM, Maciej S. Szmigiero wrote: > This commit adds pin to pad mapping and output format configuration support > in CX2584x-series chips to cx25840 driver. > > This functionality is then used to allow disabling ivtv-specific hacks > (called a "generic mode"), so cx25840 driver can be used for other devices > not needing them without risking compatibility problems. > > Signed-off-by: Maciej S. Szmigiero <mail@xxxxxxxxxxxxxxxxxxxxx> I'll be honest: this patch is scary! This driver is quite fragile and I don't want to apply this as-is. It would help if you would explain what exactly the 'ivtv-specific' hacks are that prevent you from using this in cxusb. You also seem to support many more io pins than cxusb needs. I would certainly only add support for the minimum you need to make it work. I much prefer the way cx23885_s_io_pin_config is created: it's easier to follow than the maze of macros and mapping functions that this patch introduces. Regards, Hans > --- > drivers/media/i2c/cx25840/cx25840-core.c | 413 ++++++++++++++++++++++++++++++- > drivers/media/i2c/cx25840/cx25840-core.h | 11 + > drivers/media/i2c/cx25840/cx25840-vbi.c | 3 + > drivers/media/pci/ivtv/ivtv-i2c.c | 1 + > include/media/drv-intf/cx25840.h | 74 +++++- > 5 files changed, 500 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c > index 39f51daa7558..078b94ae55ac 100644 > --- a/drivers/media/i2c/cx25840/cx25840-core.c > +++ b/drivers/media/i2c/cx25840/cx25840-core.c > @@ -21,6 +21,9 @@ > * CX23888 DIF support for the HVR1850 > * Copyright (C) 2011 Steven Toth <stoth@xxxxxxxxxxxxxx> > * > + * CX2584x pin to pad mapping and output format configuration support are > + * Copyright (C) 2011 Maciej S. Szmigiero <mail@xxxxxxxxxxxxxxxxxxxxx> > + * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License > * as published by the Free Software Foundation; either version 2 > @@ -316,6 +319,279 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n, > return 0; > } > > +static u8 cx25840_function_to_pad(struct i2c_client *client, u8 function) > +{ > + switch (function) { > + case CX25840_PAD_ACTIVE: > + return 1; > + > + case CX25840_PAD_VACTIVE: > + return 2; > + > + case CX25840_PAD_CBFLAG: > + return 3; > + > + case CX25840_PAD_VID_DATA_EXT0: > + return 4; > + > + case CX25840_PAD_VID_DATA_EXT1: > + return 5; > + > + case CX25840_PAD_GPO0: > + return 6; > + > + case CX25840_PAD_GPO1: > + return 7; > + > + case CX25840_PAD_GPO2: > + return 8; > + > + case CX25840_PAD_GPO3: > + return 9; > + > + case CX25840_PAD_IRQ_N: > + return 10; > + > + case CX25840_PAD_AC_SYNC: > + return 11; > + > + case CX25840_PAD_AC_SDOUT: > + return 12; > + > + case CX25840_PAD_PLL_CLK: > + return 13; > + > + case CX25840_PAD_VRESET: > + return 14; > + > + default: > + if (function != CX25840_PAD_DEFAULT) > + v4l_err(client, > + "invalid function %u, assuming default\n", > + (unsigned int)function); > + return 0; > + } > +} > + > +static void cx25840_set_invert(u8 *pinctrl3, u8 *voutctrl4, u8 function, > + u8 pin, bool invert) > +{ > + if (function != CX25840_PAD_DEFAULT) > + switch (function) { > + case CX25840_PAD_IRQ_N: > + if (invert) > + *pinctrl3 &= ~2; > + else > + *pinctrl3 |= 2; > + break; > + > + case CX25840_PAD_ACTIVE: > + if (invert) > + *voutctrl4 |= BIT(2); > + else > + *voutctrl4 &= ~BIT(2); > + break; > + > + case CX25840_PAD_VACTIVE: > + if (invert) > + *voutctrl4 |= BIT(5); > + else > + *voutctrl4 &= ~BIT(5); > + break; > + > + case CX25840_PAD_CBFLAG: > + if (invert) > + *voutctrl4 |= BIT(4); > + else > + *voutctrl4 &= ~BIT(4); > + break; > + > + case CX25840_PAD_VRESET: > + if (invert) > + *voutctrl4 |= BIT(0); > + else > + *voutctrl4 &= ~BIT(0); > + break; > + > + default: > + break; > + } > + else > + switch (pin) { > + case CX25840_PIN_DVALID_PRGM0: > + if (invert) > + *voutctrl4 |= BIT(6); > + else > + *voutctrl4 &= ~BIT(6); > + break; > + > + case CX25840_PIN_FIELD_PRGM1: > + if (invert) > + *voutctrl4 |= BIT(3); > + else > + *voutctrl4 &= ~BIT(3); > + break; > + > + case CX25840_PIN_HRESET_PRGM2: > + if (invert) > + *voutctrl4 |= BIT(1); > + else > + *voutctrl4 &= ~BIT(1); > + break; > + > + case CX25840_PIN_VRESET_HCTL_PRGM3: > + if (invert) > + *voutctrl4 |= BIT(0); > + else > + *voutctrl4 &= ~BIT(0); > + break; > + > + default: > + break; > + } > +} > + > +#define CX25840_PIN(pin, enable_reg, enable_bit, config_reg, config_msb, \ > + strength_reg, strength_shift) \ > + case pin: \ > + if (p[i].flags & V4L2_SUBDEV_IO_PIN_DISABLE) \ > + pinctrl[enable_reg] &= ~BIT(enable_bit); \ > + else \ > + pinctrl[enable_reg] |= BIT(enable_bit); \ > +\ > + function = cx25840_function_to_pad(client, p[i].function); \ > +\ > + pinconf[config_reg] &= ~(config_msb ? 0xf0 : 0x0f); \ > + pinconf[config_reg] |= function << (config_msb ? 4 : 0); \ > +\ > + cx25840_set_invert(&(pinctrl[3]), &voutctrl4, function, pin, \ > + p[i].flags & V4L2_SUBDEV_IO_PIN_ACTIVE_LOW); \ > +\ > + if (pin == CX25840_PIN_CHIP_SEL_VIPCLK) \ > + break; \ > +\ > + pinctrl[strength_reg] &= ~(3 << (strength_shift)); \ > + switch (strength) { \ > + case CX25840_PIN_DRIVE_SLOW: \ > + pinctrl[strength_reg] |= 1 << (strength_shift); \ > + break; \ > +\ > + case CX25840_PIN_DRIVE_MEDIUM: \ > + pinctrl[strength_reg] |= 0 << (strength_shift); \ > + break; \ > +\ > + case CX25840_PIN_DRIVE_FAST: \ > + pinctrl[strength_reg] |= 2 << (strength_shift); \ > + break; \ > + } \ > + break > + > +static int cx25840_s_io_pin_config(struct v4l2_subdev *sd, size_t n, > + struct v4l2_subdev_io_pin_config *p) > +{ > + struct i2c_client *client = v4l2_get_subdevdata(sd); > + unsigned int i; > + u8 pinctrl[6], pinconf[10], voutctrl4; > + > + for (i = 0; i < 6; i++) > + pinctrl[i] = cx25840_read(client, 0x114 + i); > + > + for (i = 0; i < 10; i++) > + pinconf[i] = cx25840_read(client, 0x11c + i); > + > + voutctrl4 = cx25840_read(client, 0x407); > + > + for (i = 0; i < n; i++) { > + u8 function; > + u8 strength = p[i].strength; > + > + if (strength != CX25840_PIN_DRIVE_SLOW && > + strength != CX25840_PIN_DRIVE_MEDIUM && > + strength != CX25840_PIN_DRIVE_FAST) { > + > + v4l_err(client, > + "invalid drive speed for pin %u (%u), assuming fast\n", > + (unsigned int)p[i].pin, > + (unsigned int)strength); > + > + strength = CX25840_PIN_DRIVE_FAST; > + } > + > + switch (p[i].pin) { > + CX25840_PIN(CX25840_PIN_DVALID_PRGM0, > + 0, 6, 3, 0, 4, 2); > + CX25840_PIN(CX25840_PIN_FIELD_PRGM1, > + 0, 7, 3, 1, 4, 2); > + CX25840_PIN(CX25840_PIN_HRESET_PRGM2, > + 1, 0, 4, 0, 4, 2); > + CX25840_PIN(CX25840_PIN_VRESET_HCTL_PRGM3, > + 1, 1, 4, 1, 5, 0); > + CX25840_PIN(CX25840_PIN_IRQ_N_PRGM4, > + 0, 3, 1, 1, 5, 0); > + CX25840_PIN(CX25840_PIN_IR_RX_PRGM5, > + 0, 4, 2, 0, 5, 0); > + CX25840_PIN(CX25840_PIN_IR_TX_PRGM6, > + 0, 5, 2, 1, 5, 0); > + CX25840_PIN(CX25840_PIN_GPIO0_PRGM8, > + 0, 0, 0, 0, 5, 0); > + CX25840_PIN(CX25840_PIN_GPIO1_PRGM9, > + 0, 1, 0, 1, 5, 0); > + CX25840_PIN(CX25840_PIN_CHIP_SEL_VIPCLK, > + 0, 2, 1, 0, 0, 0); > + > + case CX25840_PIN_PLL_CLK_PRGM7: > + if (p[i].flags & V4L2_SUBDEV_IO_PIN_DISABLE) > + pinctrl[2] &= ~BIT(2); > + else > + pinctrl[2] |= BIT(2); > + > + switch (p[i].function) { > + case CX25840_PAD_XTI_X5_DLL: > + pinconf[6] = 0; > + break; > + > + case CX25840_PAD_AUX_PLL: > + pinconf[6] = 1; > + break; > + > + case CX25840_PAD_VID_PLL: > + pinconf[6] = 5; > + break; > + > + case CX25840_PAD_XTI: > + pinconf[6] = 2; > + break; > + > + default: > + pinconf[6] = 3; > + pinconf[6] |= > + cx25840_function_to_pad(client, > + p[i].function) > + << 4; > + } > + > + break; > + > + default: > + v4l_err(client, "invalid pin %u\n", > + (unsigned int)p[i].pin); > + break; > + } > + } > + > + cx25840_write(client, 0x407, voutctrl4); > + > + for (i = 0; i < 6; i++) > + cx25840_write(client, 0x114 + i, pinctrl[i]); > + > + for (i = 0; i < 10; i++) > + cx25840_write(client, 0x11c + i, pinconf[i]); > + > + return 0; > +} > + > +#undef CX25840_PIN > + > static int common_s_io_pin_config(struct v4l2_subdev *sd, size_t n, > struct v4l2_subdev_io_pin_config *pincfg) > { > @@ -323,6 +599,8 @@ static int common_s_io_pin_config(struct v4l2_subdev *sd, size_t n, > > if (is_cx2388x(state)) > return cx23885_s_io_pin_config(sd, n, pincfg); > + else if (is_cx2584x(state)) > + return cx25840_s_io_pin_config(sd, n, pincfg); > return 0; > } > > @@ -455,6 +733,22 @@ static void cx25840_initialize(struct i2c_client *client) > /* (re)set input */ > set_input(client, state->vid_input, state->aud_input); > > + if (state->generic_mode) { > + /* set datasheet video output defaults */ > + cx25840_vconfig(client, CX25840_VCONFIG_FMT_BT656 | > + CX25840_VCONFIG_RES_8BIT | > + CX25840_VCONFIG_VBIRAW_DISABLED | > + CX25840_VCONFIG_ANCDATA_ENABLED | > + CX25840_VCONFIG_TASKBIT_ONE | > + CX25840_VCONFIG_ACTIVE_HORIZONTAL | > + CX25840_VCONFIG_VALID_NORMAL | > + CX25840_VCONFIG_HRESETW_NORMAL | > + CX25840_VCONFIG_CLKGATE_NONE | > + CX25840_VCONFIG_DCMODE_DWORDS | > + CX25840_VCONFIG_IDID0S_NORMAL | > + CX25840_VCONFIG_VIPCLAMP_DISABLED); > + } > + > /* start microcontroller */ > cx25840_and_or(client, 0x803, ~0x10, 0x10); > } > @@ -1387,7 +1681,9 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd, > Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; > } > > - Vlines = fmt->height + (is_50Hz ? 4 : 7); > + Vlines = fmt->height; > + if (!state->generic_mode) > + Vlines += is_50Hz ? 4 : 7; > > /* > * We keep 1 margin for the Vsrc < Vlines check since the > @@ -1630,6 +1926,117 @@ static void log_audio_status(struct i2c_client *client) > } > } > > +#define CX25840_VCONFIG_OPTION(option_mask) \ > + do { \ > + if (config_in & (option_mask)) { \ > + state->vid_config &= ~(option_mask); \ > + state->vid_config |= config_in & (option_mask); \ > + } \ > + } while (0) > + > +#define CX25840_VCONFIG_SET_BIT(optionmask, reg, bit, oneval) \ > + do { \ > + if (state->vid_config & (optionmask)) { \ > + if ((state->vid_config & (optionmask)) == \ > + (oneval)) \ > + voutctrl[reg] |= BIT(bit); \ > + else \ > + voutctrl[reg] &= ~BIT(bit); \ > + } \ > + } while (0) > + > +int cx25840_vconfig(struct i2c_client *client, u32 config_in) > +{ > + struct cx25840_state *state = to_state(i2c_get_clientdata(client)); > + u8 voutctrl[3]; > + unsigned int i; > + > + /* apply incoming options to the current state */ > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_FMT_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_RES_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_VBIRAW_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_ANCDATA_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_TASKBIT_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_ACTIVE_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_VALID_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_HRESETW_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_CLKGATE_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_DCMODE_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_IDID0S_MASK); > + CX25840_VCONFIG_OPTION(CX25840_VCONFIG_VIPCLAMP_MASK); > + > + for (i = 0; i < 3; i++) > + voutctrl[i] = cx25840_read(client, 0x404 + i); > + > + /* apply state to hardware regs */ > + if (state->vid_config & CX25840_VCONFIG_FMT_MASK) > + voutctrl[0] &= ~(3); > + switch (state->vid_config & CX25840_VCONFIG_FMT_MASK) { > + case CX25840_VCONFIG_FMT_BT656: > + voutctrl[0] |= 1; > + break; > + > + case CX25840_VCONFIG_FMT_VIP11: > + voutctrl[0] |= 2; > + break; > + > + case CX25840_VCONFIG_FMT_VIP2: > + voutctrl[0] |= 3; > + break; > + > + case CX25840_VCONFIG_FMT_BT601: /* zero */ > + default: > + break; > + } > + > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_RES_MASK, 0, 2, > + CX25840_VCONFIG_RES_10BIT); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_VBIRAW_MASK, 0, 3, > + CX25840_VCONFIG_VBIRAW_ENABLED); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_ANCDATA_MASK, 0, 4, > + CX25840_VCONFIG_ANCDATA_ENABLED); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_TASKBIT_MASK, 0, 5, > + CX25840_VCONFIG_TASKBIT_ONE); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_ACTIVE_MASK, 1, 2, > + CX25840_VCONFIG_ACTIVE_HORIZONTAL); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_VALID_MASK, 1, 3, > + CX25840_VCONFIG_VALID_ANDACTIVE); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_HRESETW_MASK, 1, 4, > + CX25840_VCONFIG_HRESETW_PIXCLK); > + > + if (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) > + voutctrl[1] &= ~(3 << 6); > + switch (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) { > + case CX25840_VCONFIG_CLKGATE_VALID: > + voutctrl[1] |= 2; > + break; > + > + case CX25840_VCONFIG_CLKGATE_VALIDACTIVE: > + voutctrl[1] |= 3; > + break; > + > + case CX25840_VCONFIG_CLKGATE_NONE: /* zero */ > + default: > + break; > + } > + > + > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_DCMODE_MASK, 2, 0, > + CX25840_VCONFIG_DCMODE_BYTES); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_IDID0S_MASK, 2, 1, > + CX25840_VCONFIG_IDID0S_LINECNT); > + CX25840_VCONFIG_SET_BIT(CX25840_VCONFIG_VIPCLAMP_MASK, 2, 4, > + CX25840_VCONFIG_VIPCLAMP_ENABLED); > + > + for (i = 0; i < 3; i++) > + cx25840_write(client, 0x404 + i, voutctrl[i]); > + > + return 0; > +} > + > +#undef CX25840_VCONFIG_SET_BIT > +#undef CX25840_VCONFIG_OPTION > + > /* ----------------------------------------------------------------------- */ > > /* This load_fw operation must be called to load the driver's firmware. > @@ -1819,6 +2226,9 @@ static int cx25840_s_video_routing(struct v4l2_subdev *sd, > if (is_cx23888(state)) > cx23888_std_setup(client); > > + if (is_cx2584x(state) && state->generic_mode) > + cx25840_vconfig(client, config); > + > return set_input(client, input, state->aud_input); > } > > @@ -5318,6 +5728,7 @@ static int cx25840_probe(struct i2c_client *client, > struct cx25840_platform_data *pdata = client->dev.platform_data; > > state->pvr150_workaround = pdata->pvr150_workaround; > + state->generic_mode = pdata->generic_mode; > } > > cx25840_ir_probe(sd); > diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h > index 55432ed42714..ea7952551a29 100644 > --- a/drivers/media/i2c/cx25840/cx25840-core.h > +++ b/drivers/media/i2c/cx25840/cx25840-core.h > @@ -55,9 +55,11 @@ struct cx25840_state { > struct v4l2_ctrl *mute; > }; > int pvr150_workaround; > + int generic_mode; > int radio; > v4l2_std_id std; > enum cx25840_video_input vid_input; > + u32 vid_config; > enum cx25840_audio_input aud_input; > u32 audclk_freq; > int audmode; > @@ -90,6 +92,14 @@ static inline bool is_cx2583x(struct cx25840_state *state) > state->id == CX25837; > } > > +static inline bool is_cx2584x(struct cx25840_state *state) > +{ > + return state->id == CX25840 || > + state->id == CX25841 || > + state->id == CX25842 || > + state->id == CX25843; > +} > + > static inline bool is_cx231xx(struct cx25840_state *state) > { > return state->id == CX2310X_AV; > @@ -127,6 +137,7 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value) > int cx25840_and_or4(struct i2c_client *client, u16 addr, u32 and_mask, > u32 or_value); > void cx25840_std_setup(struct i2c_client *client); > +int cx25840_vconfig(struct i2c_client *client, u32 config_in); > > /* ----------------------------------------------------------------------- */ > /* cx25850-firmware.c */ > diff --git a/drivers/media/i2c/cx25840/cx25840-vbi.c b/drivers/media/i2c/cx25840/cx25840-vbi.c > index 8c99a79fb726..23b7c1fb28ab 100644 > --- a/drivers/media/i2c/cx25840/cx25840-vbi.c > +++ b/drivers/media/i2c/cx25840/cx25840-vbi.c > @@ -95,6 +95,7 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format * > memset(svbi->service_lines, 0, sizeof(svbi->service_lines)); > svbi->service_set = 0; > /* we're done if raw VBI is active */ > + /* this will have to be changed for generic_mode VBI */ > if ((cx25840_read(client, 0x404) & 0x10) == 0) > return 0; > > @@ -137,6 +138,7 @@ int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt) > cx25840_write(client, 0x54f, vbi_offset); > else > cx25840_write(client, 0x47f, vbi_offset); > + /* this will have to be changed for generic_mode VBI */ > cx25840_write(client, 0x404, 0x2e); > return 0; > } > @@ -157,6 +159,7 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format * > cx25840_std_setup(client); > > /* Sliced VBI */ > + /* this will have to be changed for generic_mode VBI */ > cx25840_write(client, 0x404, 0x32); /* Ancillary data */ > cx25840_write(client, 0x406, 0x13); > if (is_cx23888(state)) > diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c > index dea80efd5836..8a9d3e2ac14e 100644 > --- a/drivers/media/pci/ivtv/ivtv-i2c.c > +++ b/drivers/media/pci/ivtv/ivtv-i2c.c > @@ -305,6 +305,7 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) > .platform_data = &pdata, > }; > > + memset(&pdata, 0, sizeof(pdata)); > pdata.pvr150_workaround = itv->pvr150_workaround; > sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap, > &cx25840_info, NULL); > diff --git a/include/media/drv-intf/cx25840.h b/include/media/drv-intf/cx25840.h > index 783c5bdd63eb..dbd742bbbf58 100644 > --- a/include/media/drv-intf/cx25840.h > +++ b/include/media/drv-intf/cx25840.h > @@ -88,6 +88,70 @@ enum cx25840_video_input { > CX25840_DIF_ON = 0x80000400, > }; > > +/* arguments to video s_routing config param */ > +#define CX25840_VCONFIG_FMT_SHIFT 0 > +#define CX25840_VCONFIG_FMT_MASK 7 > +#define CX25840_VCONFIG_FMT_BT601 1 > +#define CX25840_VCONFIG_FMT_BT656 2 > +#define CX25840_VCONFIG_FMT_VIP11 3 > +#define CX25840_VCONFIG_FMT_VIP2 4 > + > +#define CX25840_VCONFIG_RES_SHIFT 3 > +#define CX25840_VCONFIG_RES_MASK (3 << 3) > +#define CX25840_VCONFIG_RES_8BIT (1 << 3) > +#define CX25840_VCONFIG_RES_10BIT (2 << 3) > + > +#define CX25840_VCONFIG_VBIRAW_SHIFT 5 > +#define CX25840_VCONFIG_VBIRAW_MASK (3 << 5) > +#define CX25840_VCONFIG_VBIRAW_DISABLED (1 << 5) > +#define CX25840_VCONFIG_VBIRAW_ENABLED (2 << 5) > + > +#define CX25840_VCONFIG_ANCDATA_SHIFT 7 > +#define CX25840_VCONFIG_ANCDATA_MASK (3 << 7) > +#define CX25840_VCONFIG_ANCDATA_DISABLED (1 << 7) > +#define CX25840_VCONFIG_ANCDATA_ENABLED (2 << 7) > + > +#define CX25840_VCONFIG_TASKBIT_SHIFT 9 > +#define CX25840_VCONFIG_TASKBIT_MASK (3 << 9) > +#define CX25840_VCONFIG_TASKBIT_ZERO (1 << 9) > +#define CX25840_VCONFIG_TASKBIT_ONE (2 << 9) > + > +#define CX25840_VCONFIG_ACTIVE_SHIFT 11 > +#define CX25840_VCONFIG_ACTIVE_MASK (3 << 11) > +#define CX25840_VCONFIG_ACTIVE_COMPOSITE (1 << 11) > +#define CX25840_VCONFIG_ACTIVE_HORIZONTAL (2 << 11) > + > +#define CX25840_VCONFIG_VALID_SHIFT 13 > +#define CX25840_VCONFIG_VALID_MASK (3 << 13) > +#define CX25840_VCONFIG_VALID_NORMAL (1 << 13) > +#define CX25840_VCONFIG_VALID_ANDACTIVE (2 << 13) > + > +#define CX25840_VCONFIG_HRESETW_SHIFT 15 > +#define CX25840_VCONFIG_HRESETW_MASK (3 << 15) > +#define CX25840_VCONFIG_HRESETW_NORMAL (1 << 15) > +#define CX25840_VCONFIG_HRESETW_PIXCLK (2 << 15) > + > +#define CX25840_VCONFIG_CLKGATE_SHIFT 17 > +#define CX25840_VCONFIG_CLKGATE_MASK (3 << 17) > +#define CX25840_VCONFIG_CLKGATE_NONE (1 << 17) > +#define CX25840_VCONFIG_CLKGATE_VALID (2 << 17) > +#define CX25840_VCONFIG_CLKGATE_VALIDACTIVE (3 << 17) > + > +#define CX25840_VCONFIG_DCMODE_SHIFT 19 > +#define CX25840_VCONFIG_DCMODE_MASK (3 << 19) > +#define CX25840_VCONFIG_DCMODE_DWORDS (1 << 19) > +#define CX25840_VCONFIG_DCMODE_BYTES (2 << 19) > + > +#define CX25840_VCONFIG_IDID0S_SHIFT 21 > +#define CX25840_VCONFIG_IDID0S_MASK (3 << 21) > +#define CX25840_VCONFIG_IDID0S_NORMAL (1 << 21) > +#define CX25840_VCONFIG_IDID0S_LINECNT (2 << 21) > + > +#define CX25840_VCONFIG_VIPCLAMP_SHIFT 23 > +#define CX25840_VCONFIG_VIPCLAMP_MASK (3 << 23) > +#define CX25840_VCONFIG_VIPCLAMP_ENABLED (1 << 23) > +#define CX25840_VCONFIG_VIPCLAMP_DISABLED (2 << 23) > + > enum cx25840_audio_input { > /* Audio inputs: serial or In4-In8 */ > CX25840_AUDIO_SERIAL, > @@ -180,9 +244,17 @@ enum cx23885_io_pad { > audio autodetect fails on some channels for these models and the workaround > is to select the audio standard explicitly. Many thanks to Hauppauge for > providing this information. > - This platform data only needs to be supplied by the ivtv driver. */ > + This platform data only needs to be supplied by the ivtv driver. > + > + generic_mode disables some of the ivtv-related hacks in this driver, > + enables setting video output config and sets it according to datasheet > + defaults on initialization. > + This flag is to be used for example with USB video capture devices > + using this chip. > +*/ > struct cx25840_platform_data { > int pvr150_workaround; > + int generic_mode; > }; > > #endif >