summaryrefslogtreecommitdiff
path: root/drivers/media/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/tegra/as364x.c104
-rw-r--r--drivers/media/video/tegra/imx091.c92
-rw-r--r--drivers/media/video/tegra/max77665-flash.c136
-rw-r--r--drivers/media/video/tegra/ov9772.c2
4 files changed, 216 insertions, 118 deletions
diff --git a/drivers/media/video/tegra/as364x.c b/drivers/media/video/tegra/as364x.c
index 31e223380ea6..cbe8fb1c5be2 100644
--- a/drivers/media/video/tegra/as364x.c
+++ b/drivers/media/video/tegra/as364x.c
@@ -60,7 +60,10 @@
#define AS364X_MAX_FLASH_LEVEL 256
#define AS364X_MAX_TORCH_LEVEL 128
-#define SUSTAINTIME_DEF 820
+#define SUSTAINTIME_DEF 558
+#define DEFAULT_FLASHTIME ((SUSTAINTIME_DEF > 256) ? \
+ ((SUSTAINTIME_DEF - 249) / 8 + 128) : \
+ ((SUSTAINTIME_DEF - 1) / 2))
#define RECHARGEFACTOR_DEF 197
#define as364x_max_flash_cap_size (sizeof(u32) \
@@ -192,28 +195,36 @@ static int as364x_reg_rd(struct as364x_info *info, u8 reg, u8 *val)
return 0;
}
-static int as364x_reg_wr(struct as364x_info *info, u8 reg, u8 val)
+static int as364x_reg_raw_wr(struct as364x_info *info, u8 *buf, u8 num)
{
struct i2c_msg msg;
- u8 buf[2];
- buf[0] = reg;
- buf[1] = val;
msg.addr = info->i2c_client->addr;
msg.flags = 0;
- msg.len = 2;
- msg.buf = &buf[0];
+ msg.len = num;
+ msg.buf = buf;
if (i2c_transfer(info->i2c_client->adapter, &msg, 1) != 1)
return -EIO;
+ dev_dbg(&info->i2c_client->dev, "%s %x %x\n", __func__, buf[0], buf[1]);
return 0;
}
+static int as364x_reg_wr(struct as364x_info *info, u8 reg, u8 val)
+{
+ u8 buf[2];
+
+ dev_dbg(&info->i2c_client->dev, "%s\n", __func__);
+ buf[0] = reg;
+ buf[1] = val;
+ return as364x_reg_raw_wr(info, buf, sizeof(buf));
+}
+
static int as364x_set_leds(struct as364x_info *info,
u8 mask, u8 curr1, u8 curr2)
{
int err = 0;
- u8 val = 0;
+ u8 regs[7];
if (mask & 1) {
if (info->flash_mode == AS364X_REG_CONTROL_MODE_FLASH) {
@@ -223,13 +234,8 @@ static int as364x_set_leds(struct as364x_info *info,
if (curr1 >= info->torch_cap->numberoflevels)
curr1 = info->torch_cap->numberoflevels - 1;
}
-
- err = as364x_reg_wr(info, AS364X_REG_LED1_SET_CURR, curr1);
- if (!err)
- info->regs.led1_curr = curr1;
- else
- goto set_led_end;
- }
+ } else
+ curr1 = 0;
if (mask & 2 && info->caps.led2_support) {
if (info->flash_mode == AS364X_REG_CONTROL_MODE_FLASH) {
@@ -239,25 +245,28 @@ static int as364x_set_leds(struct as364x_info *info,
if (curr2 >= info->torch_cap->numberoflevels)
curr2 = info->torch_cap->numberoflevels - 1;
}
-
- err = as364x_reg_wr(info, AS364X_REG_LED2_SET_CURR, curr2);
- if (!err)
- info->regs.led2_curr = curr2;
- else
- goto set_led_end;
- }
-
- err = as364x_reg_wr(info, AS364X_REG_FLASHTIMER, info->regs.ftime);
- val = info->flash_mode;
+ } else
+ curr2 = 0;
+
+ regs[0] = AS364X_REG_LED1_SET_CURR;
+ regs[1] = curr1;
+ regs[2] = curr2;
+ regs[3] = info->regs.txmask;
+ regs[4] = info->regs.vlow;
+ regs[5] = info->regs.ftime;
if (mask == 0 || (curr1 == 0 && curr2 == 0))
- val &= ~0x08;
+ regs[6] = info->flash_mode & (~0x08);
else
- val |= 0x08;
- dev_dbg(&info->i2c_client->dev, "%s %x %x %x val = %x\n",
- __func__, mask, curr1, curr2, val);
- err |= as364x_reg_wr(info, AS364X_REG_CONTROL, val);
+ regs[6] = info->flash_mode | 0x08;
+ err = as364x_reg_raw_wr(info, regs, sizeof(regs));
+ if (!err) {
+ info->regs.led1_curr = curr1;
+ info->regs.led2_curr = curr2;
+ }
-set_led_end:
+ dev_dbg(&info->i2c_client->dev, "%s %x %x %x %x control = %x\n",
+ __func__, mask, curr1, curr2,
+ info->regs.ftime, regs[6]);
return err;
}
@@ -309,7 +318,7 @@ static int as364x_get_vin_index(u16 mV)
return vin;
}
-static void as364x_update_config(struct as364x_info *info)
+static void as364x_config_init(struct as364x_info *info)
{
struct as364x_config *pcfg = &info->config;
struct as364x_config *pcfg_cust = &info->pdata->config;
@@ -388,6 +397,8 @@ static int as364x_update_settings(struct as364x_info *info)
err |= as364x_set_leds(info,
info->led_mask, info->regs.led1_curr, info->regs.led2_curr);
+ dev_dbg(&info->i2c_client->dev, "UP: strobe: %x pwm_ind: %x vlow: %x\n",
+ info->regs.strobe, info->regs.pwm_ind, info->regs.vlow);
return err;
}
@@ -418,9 +429,11 @@ static int as364x_configure(struct as364x_info *info, bool update)
if (pcfg->load_balance_on)
info->regs.pwm_ind |= 0x20;
- info->regs.strobe = pcfg->strobe_type ? 0xc0 : 0x80;
+ info->regs.strobe = pcfg->strobe_type == 2 ? 0xc0 : 0x80;
info->led_mask = info->pdata->led_mask;
+ info->regs.ftime = DEFAULT_FLASHTIME;
+
if (pcfg->max_peak_current_mA > pcap->max_peak_curr_mA ||
!pcfg->max_peak_current_mA) {
dev_warn(&info->i2c_client->dev,
@@ -789,8 +802,6 @@ static int as364x_set_param(struct as364x_info *info,
case NVC_PARAM_FLASH_LEVEL:
dev_dbg(&info->i2c_client->dev, "%s FLASH_LEVEL: %d\n",
__func__, val);
- info->regs.ftime =
- info->flash_cap->levels[val].rechargefactor;
info->flash_mode = AS364X_REG_CONTROL_MODE_FLASH;
err = as364x_set_leds(info, info->led_mask, val, val);
@@ -1160,7 +1171,7 @@ static int as364x_probe(
memcpy(&info->caps, &as364x_caps[info->pdata->type],
sizeof(info->caps));
- as364x_update_config(info);
+ as364x_config_init(info);
info->flash_mode = AS364X_REG_CONTROL_MODE_ASSIST; /* torch mode */
@@ -1211,6 +1222,7 @@ static int as364x_probe(
static int as364x_status_show(struct seq_file *s, void *data)
{
struct as364x_info *k_info = s->private;
+ struct as364x_config *pcfg = &k_info->config;
pr_info("%s\n", __func__);
@@ -1221,6 +1233,7 @@ static int as364x_status_show(struct seq_file *s, void *data)
" Led2 Current = 0x%02x\n"
" Flash Mode = 0x%02x\n"
" Flash TimeOut = 0x%02x\n"
+ " Flash Strobe = 0x%02x\n"
" Max_Peak_Current = 0x%04dmA\n"
" Use_TxMask = 0x%02x\n"
" TxMask_Current = 0x%04dmA\n"
@@ -1238,13 +1251,14 @@ static int as364x_status_show(struct seq_file *s, void *data)
k_info->regs.led1_curr,
k_info->regs.led2_curr,
k_info->flash_mode, k_info->regs.ftime,
- k_info->config.max_peak_current_mA,
- k_info->config.use_tx_mask,
- k_info->config.txmasked_current_mA,
- k_info->config.freq_switch_on ? "TRUE" : "FALSE",
- k_info->config.vin_low_v_run_mV,
- k_info->config.vin_low_v_mV,
- k_info->config.led_off_when_vin_low ? "TRUE" : "FALSE",
+ pcfg->strobe_type,
+ pcfg->max_peak_current_mA,
+ pcfg->use_tx_mask,
+ pcfg->txmasked_current_mA,
+ pcfg->freq_switch_on ? "TRUE" : "FALSE",
+ pcfg->vin_low_v_run_mV,
+ pcfg->vin_low_v_mV,
+ pcfg->led_off_when_vin_low ? "TRUE" : "FALSE",
k_info->pdata->pinstate.mask,
k_info->pdata->pinstate.values
);
@@ -1331,9 +1345,9 @@ set_attr:
break;
case 'x':
if (val & 0xf)
- k_info->flash_mode = (val & 0xf);
+ k_info->flash_mode = (val & 0xf) - 1;
if (val & 0xf0)
- k_info->config.strobe_type = (val & 0xf0) >> 4;
+ k_info->config.strobe_type = ((val & 0xf0) >> 4) - 1;
if (val & 0xf00)
k_info->config.freq_switch_on =
((val & 0xf00) == 0x200);
diff --git a/drivers/media/video/tegra/imx091.c b/drivers/media/video/tegra/imx091.c
index ebebc57c4b21..df576aabb7af 100644
--- a/drivers/media/video/tegra/imx091.c
+++ b/drivers/media/video/tegra/imx091.c
@@ -120,7 +120,7 @@ static struct nvc_imager_cap imx091_dflt_cap = {
.preferred_mode_index = 1,
.focuser_guid = NVC_FOCUS_GUID(0),
.torch_guid = NVC_TORCH_GUID(0),
- .cap_end = NVC_IMAGER_CAPABILITIES_END,
+ .cap_version = NVC_IMAGER_CAPABILITIES_VERSION2,
};
static struct imx091_platform_data imx091_dflt_pdata = {
@@ -1240,6 +1240,79 @@ static int imx091_test_pattern_wr(struct imx091_info *info, unsigned pattern)
return imx091_i2c_wr_table(info, test_patterns[pattern]);
}
+static int imx091_set_flash_output(struct imx091_info *info)
+{
+ struct imx091_flash_config *fcfg;
+ u8 val = 0;
+ int ret = 0;
+
+ if (!info->pdata)
+ return 0;
+
+ fcfg = &info->pdata->flash_cap;
+ if (fcfg->xvs_trigger_enabled)
+ val |= 0x0c;
+ if (fcfg->sdo_trigger_enabled)
+ val |= 0x02;
+ dev_dbg(&info->i2c_client->dev, "%s: %02x\n", __func__, val);
+ ret = imx091_i2c_wr8(info, 0x3240, val);
+ /* set the control pulse width settings - Gain + Step
+ * Pulse width(sec) = 64 * 2^(Gain) * (Step + 1) / Logic Clk
+ * Logic Clk = ExtClk * PLL Multipiler / Pre_Div / Post_Div
+ * / Logic Clk Division Ratio
+ * Logic Clk Division Ratio = 5 @4lane, 10 @2lane, 20 @1lane
+ */
+ ret |= imx091_i2c_wr8(info, 0x307C, 0x07);
+ ret |= imx091_i2c_wr8(info, 0x307D, 0x3F);
+ return ret;
+}
+
+static void imx091_get_flash_cap(struct imx091_info *info)
+{
+ struct nvc_imager_cap *fcap = info->cap;
+ struct imx091_flash_config *fcfg;
+
+ if (!info->pdata)
+ return;
+
+ fcfg = &info->pdata->flash_cap;
+ fcap->flash_control_enabled =
+ fcfg->xvs_trigger_enabled | fcfg->sdo_trigger_enabled;
+ fcap->adjustable_flash_timing = fcfg->adjustable_flash_timing;
+}
+
+static int imx091_flash_control(
+ struct imx091_info *info, union nvc_imager_flash_control *fm)
+{
+ int ret;
+ u8 f_cntl;
+ u8 f_tim;
+
+ if (!info->pdata)
+ return -EFAULT;
+
+ ret = imx091_i2c_wr8(info, 0x304a, 0);
+ f_tim = 0;
+ f_cntl = 0;
+ if (fm->settings.enable) {
+ if (fm->settings.edge_trig_en) {
+ f_cntl |= 0x10;
+ if (fm->settings.start_edge)
+ f_tim |= 0x08;
+ if (fm->settings.repeat)
+ f_tim |= 0x04;
+ f_tim |= fm->settings.delay_frm & 0x03;
+ } else
+ f_cntl |= 0x20;
+ }
+ ret |= imx091_i2c_wr8(info, 0x307B, f_tim);
+ ret |= imx091_i2c_wr8(info, 0x304A, f_cntl);
+
+ dev_dbg(&info->i2c_client->dev,
+ "%s: %04x %02x %02x\n", __func__, fm->mode, f_tim, f_cntl);
+ return ret;
+}
+
static int imx091_gpio_rd(struct imx091_info *info,
enum imx091_gpio i)
{
@@ -1706,7 +1779,9 @@ static int imx091_mode_wr(struct imx091_info *info,
goto imx091_mode_wr_err;
}
- err = imx091_mode_able(info, true);
+ err = imx091_set_flash_output(info);
+
+ err |= imx091_mode_able(info, true);
if (err < 0)
goto imx091_mode_wr_err;
@@ -1868,7 +1943,6 @@ static int imx091_param_rd(struct imx091_info *info, unsigned long arg)
}
kfree(p_i2c_table);
return err;
-
default:
dev_dbg(&info->i2c_client->dev,
"%s unsupported parameter: %d\n",
@@ -1978,6 +2052,17 @@ static int imx091_param_wr_s(struct imx091_info *info,
kfree(p_i2c_table);
return err;
+ case NVC_PARAM_SET_SENSOR_FLASH_MODE:
+ {
+ union nvc_imager_flash_control fm;
+ if (copy_from_user(&fm,
+ (const void __user *)params->p_value, sizeof(fm))) {
+ pr_info("%s:fail set flash mode.\n", __func__);
+ return -EFAULT;
+ }
+ return imx091_flash_control(info, &fm);
+ }
+
default:
dev_dbg(&info->i2c_client->dev,
"%s unsupported parameter: %d\n",
@@ -2499,6 +2584,7 @@ static int imx091_probe(
spin_unlock(&imx091_spinlock);
imx091_pm_init(info);
imx091_sdata_init(info);
+ imx091_get_flash_cap(info);
if (info->pdata->cfg & (NVC_CFG_NODEV | NVC_CFG_BOOT_INIT)) {
if (info->pdata->probe_clock) {
if (info->cap->initial_clock_rate_khz)
diff --git a/drivers/media/video/tegra/max77665-flash.c b/drivers/media/video/tegra/max77665-flash.c
index ef40641921cb..442390d43ffc 100644
--- a/drivers/media/video/tegra/max77665-flash.c
+++ b/drivers/media/video/tegra/max77665-flash.c
@@ -173,6 +173,7 @@
DIV_ROUND_UP(((x) * MAX77665_F_MAX_TORCH_LEVEL), 1000)
#define SUSTAINTIME_DEF 558
+#define DEFAULT_FLASH_TMR_DUR ((SUSTAINTIME_DEF * 10 - 1) / 625)
/* minimium debounce time 600uS */
#define RECHARGEFACTOR_DEF 600
@@ -241,6 +242,8 @@ struct max77665_f_info {
u8 op_mode;
u8 power_is_on;
u8 s_mode;
+ u8 ftimer_mode;
+ u8 ttimer_mode;
u8 new_ftimer;
u8 new_ttimer;
};
@@ -278,44 +281,51 @@ static DEFINE_SPINLOCK(max77665_f_spinlock);
static inline int max77665_f_reg_wr(struct max77665_f_info *info,
u8 reg, u8 val, bool refresh)
{
+ dev_dbg(info->dev, "%s: %02x - %02x, %s %s\n", __func__, reg, val,
+ info->regs.regs_stale ? "STALE" : "NONE",
+ refresh ? "REFRESH" : "NONE");
if (likely(info->regs.regs_stale || refresh))
return regmap_write(info->regmap, reg, val);
return 0;
}
+static inline int max77665_f_reg_raw_wr(struct max77665_f_info *info,
+ u8 reg, u8 *val, u8 num)
+{
+ dev_dbg(info->dev, "%s: %02x - %02x %02x ...\n",
+ __func__, reg, val[0], val[1]);
+ return regmap_raw_write(info->regmap, reg, val, num);
+}
+
static int max77665_f_set_leds(struct max77665_f_info *info,
u8 mask, u8 curr1, u8 curr2)
{
int err = 0;
- u32 f_levels = info->flash_cap->numberoflevels - 2;
- u32 t_levels = info->torch_cap->numberoflevels - 2;
+ u16 f_levels = info->flash_cap->numberoflevels - 2;
+ u16 t_levels = info->torch_cap->numberoflevels - 2;
u8 fled_en = 0;
u8 t_curr = 0;
- u8 val = 0;
+ u8 regs[6];
- if (info->op_mode == MAXFLASH_MODE_NONE)
- goto update_led_en_reg;
+ memset(regs, 0, sizeof(regs));
+ if (info->op_mode == MAXFLASH_MODE_NONE) {
+ err |= max77665_f_reg_wr(
+ info, MAX77665_F_RW_FLED_ENABLE, 0, true);
+ info->regs.leds_en = 0;
+ goto set_leds_end;
+ }
if (mask & 1) {
if (info->op_mode == MAXFLASH_MODE_FLASH) {
if (curr1 > f_levels)
curr1 = f_levels;
-
- err = max77665_f_reg_wr(info,
- MAX77665_F_RW_FLASH_FLED1CURR, curr1,
- info->regs.led1_curr != curr1);
- if (!err)
- info->regs.led1_curr = curr1;
- else
- goto set_led_end;
-
fled_en |= (info->fled_settings & LED1_FLASH_TRIG_MASK);
+ regs[0] = curr1;
} else {
if (curr1 > t_levels)
curr1 = t_levels;
-
- t_curr = curr1;
fled_en |= (info->fled_settings & LED1_TORCH_TRIG_MASK);
+ t_curr = curr1;
}
}
@@ -323,68 +333,57 @@ static int max77665_f_set_leds(struct max77665_f_info *info,
if (info->op_mode == MAXFLASH_MODE_FLASH) {
if (curr2 > f_levels)
curr2 = f_levels;
-
- err = max77665_f_reg_wr(info,
- MAX77665_F_RW_FLASH_FLED2CURR, curr2,
- info->regs.led2_curr != curr2);
- if (!err)
- info->regs.led2_curr = curr2;
- else
- goto set_led_end;
-
fled_en |= (info->fled_settings & LED2_FLASH_TRIG_MASK);
+ regs[1] = curr2;
} else {
if (curr2 > t_levels)
curr2 = t_levels;
-
- t_curr |= curr2 << 4;
fled_en |= (info->fled_settings & LED2_TORCH_TRIG_MASK);
+ t_curr |= curr2 << 4;
}
}
/* if any led is set as flash, update the flash timer register */
- if (fled_en & (LED1_FLASH_TRIG_MASK | LED2_FLASH_TRIG_MASK)) {
- val = (info->regs.f_timer & FIELD(TIMER_MAX, 7)) |
- info->new_ftimer;
- err = max77665_f_reg_wr(info,
- MAX77665_F_RW_FLASH_TIMER, val,
- (info->regs.f_timer & 0x0f) != info->new_ftimer);
- if (err)
- goto set_led_end;
- info->regs.f_timer = val;
- }
+ if (fled_en & (LED1_FLASH_TRIG_MASK | LED2_FLASH_TRIG_MASK))
+ regs[4] = (info->ftimer_mode & FIELD(TIMER_MAX, 7)) |
+ info->new_ftimer;
/* if any led is set as torch, update the torch timer register */
if (fled_en & (LED1_TORCH_TRIG_MASK | LED2_TORCH_TRIG_MASK)) {
- err = max77665_f_reg_wr(info,
- MAX77665_F_RW_TORCH_FLEDCURR, t_curr,
- info->regs.led_tcurr != t_curr);
- if (!err)
- info->regs.led_tcurr = t_curr;
- else
- goto set_led_end;
-
- val = (info->regs.t_timer & TORCH_TIMER_CTL_MASK) |
- (info->new_ttimer & 0x0f);
- err = max77665_f_reg_wr(info, MAX77665_F_RW_TORCH_TIMER,
- val, true);
- if (err)
- goto set_led_end;
- info->regs.t_timer = val;
+ regs[3] = (info->ttimer_mode & TORCH_TIMER_CTL_MASK) |
+ (info->new_ttimer & 0x0f);
+ regs[2] = t_curr;
}
-update_led_en_reg:
- err = max77665_f_reg_wr(info,
- MAX77665_F_RW_FLED_ENABLE, fled_en,
- info->regs.leds_en != fled_en);
- if (err)
- goto set_led_end;
- info->regs.leds_en = fled_en;
-
- dev_dbg(info->dev, "%s %x %x %x en = %x\n",
- __func__, mask, curr1, curr2, fled_en);
+ regs[5] = fled_en;
+ if ((info->regs.led1_curr != regs[0]) ||
+ (info->regs.led2_curr != regs[1]) ||
+ (info->regs.led_tcurr != regs[2]) ||
+ (info->regs.t_timer != regs[3]) ||
+ (info->regs.f_timer != regs[4]) ||
+ (info->regs.leds_en != regs[5]))
+ info->regs.regs_stale = true;
+
+ if (info->regs.regs_stale) {
+ err = max77665_f_reg_raw_wr(info,
+ MAX77665_F_RW_FLASH_FLED1CURR, regs, sizeof(regs));
+
+ if (!err) {
+ info->regs.led1_curr = regs[0];
+ info->regs.led2_curr = regs[1];
+ info->regs.led_tcurr = regs[2];
+ info->regs.t_timer = regs[3];
+ info->regs.f_timer = regs[4];
+ info->regs.leds_en = regs[5];
+ info->regs.regs_stale = false;
+ }
+ }
-set_led_end:
+set_leds_end:
+ dev_dbg(info->dev,
+ "%s led %x flash: %02x %02x %02x, torch: %02x %02x, en = %x\n",
+ __func__, mask, curr1, curr2, info->regs.f_timer,
+ info->regs.led_tcurr, info->regs.t_timer, fled_en);
return err;
}
@@ -505,20 +504,20 @@ update_end:
info->regs.boost_vout_flash =
max77665_f_get_boost_volt(pcfg->boost_vout_flash_mV);
- info->regs.f_timer = (pcfg->flash_mode == 1) ?
+ info->ftimer_mode = (pcfg->flash_mode == 1) ?
FIELD(TIMER_ONESHOT, 7) : FIELD(TIMER_MAX, 7);
switch (pcfg->torch_mode) {
case 1:
- info->regs.t_timer = FIELD(TIMER_MAX, 7) |
+ info->ttimer_mode = FIELD(TIMER_MAX, 7) |
FIELD(TORCH_TIMER_SAFETY_DIS, 6);
break;
case 2:
- info->regs.t_timer = FIELD(TIMER_ONESHOT, 7);
+ info->ttimer_mode = FIELD(TIMER_ONESHOT, 7);
break;
case 3:
default:
- info->regs.t_timer = FIELD(TIMER_MAX, 7);
+ info->ttimer_mode = FIELD(TIMER_MAX, 7);
break;
}
@@ -995,8 +994,7 @@ static int max77665_f_param_update(struct max77665_f_info *info,
case NVC_PARAM_FLASH_LEVEL:
dev_dbg(info->dev, "%s FLASH_LEVEL: %d\n", __func__, val);
if (val) {
- info->new_ftimer =
- info->flash_cap->levels[val].sustaintime & 0X0F;
+ info->new_ftimer = DEFAULT_FLASH_TMR_DUR;
info->op_mode = MAXFLASH_MODE_FLASH;
val--;
} else
diff --git a/drivers/media/video/tegra/ov9772.c b/drivers/media/video/tegra/ov9772.c
index 603f6a4cce35..70a2f9504125 100644
--- a/drivers/media/video/tegra/ov9772.c
+++ b/drivers/media/video/tegra/ov9772.c
@@ -243,7 +243,7 @@ static struct nvc_imager_cap ov9772_dflt_cap = {
.preferred_mode_index = 0,
.focuser_guid = 0,
.torch_guid = 0,
- .cap_end = NVC_IMAGER_CAPABILITIES_END,
+ .cap_version = NVC_IMAGER_CAPABILITIES_VERSION2,
};
static struct ov9772_platform_data ov9772_dflt_pdata = {