struct v4l2_rect crop;
u64 pixel_rate;
+ /* HTS as defined in the register set (0x380C/0x380D) */
+ int hts;
struct regval_list *reg_list;
unsigned int num_regs;
unsigned int flags;
struct v4l2_ctrl_handler ctrls;
struct v4l2_ctrl *pixel_rate;
+ struct v4l2_ctrl *hblank;
bool write_mode_regs;
};
.height = 960,
},
.pixel_rate = 77291670,
+ .hts = 1896,
ov5647_640x480_8bit,
ARRAY_SIZE(ov5647_640x480_8bit)
},
.height = 1944
},
.pixel_rate = 87500000,
+ .hts = 2844,
ov5647_2592x1944_10bit,
ARRAY_SIZE(ov5647_2592x1944_10bit)
},
.height = 1080,
},
.pixel_rate = 81666700,
+ .hts = 2416,
ov5647_1080p30_10bit,
ARRAY_SIZE(ov5647_1080p30_10bit)
},
.height = 1944,
},
.pixel_rate = 81666700,
+ .hts = 1896,
ov5647_2x2binned_10bit,
ARRAY_SIZE(ov5647_2x2binned_10bit)
},
.height = 1920,
},
.pixel_rate = 55000000,
+ .hts = 1852,
ov5647_640x480_10bit,
ARRAY_SIZE(ov5647_640x480_10bit)
},
* If we have changed modes, write the I2C register list on
* a stream_on().
*/
+ int hblank;
+
if (state->mode != mode)
state->write_mode_regs = true;
state->mode = mode;
mode->pixel_rate,
mode->pixel_rate, 1,
mode->pixel_rate);
+ hblank = mode->hts - mode->format.width;
+ __v4l2_ctrl_modify_range(state->hblank, hblank, hblank, 1,
+ hblank);
}
mutex_unlock(&state->lock);
case V4L2_CID_PIXEL_RATE:
/* Read-only, but we adjust it based on mode. */
break;
+ case V4L2_CID_HBLANK:
+ /* Read-only, but we adjust it based on mode. */
+ break;
default:
dev_info(&client->dev,
"ctrl(id:0x%x,val:0x%x) is not handled\n",
struct device_node *np = client->dev.of_node;
u32 xclk_freq;
struct v4l2_ctrl *ctrl;
+ int hblank;
sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
mutex_init(&sensor->lock);
/* Initialise controls. */
- v4l2_ctrl_handler_init(&sensor->ctrls, 6);
+ v4l2_ctrl_handler_init(&sensor->ctrls, 7);
v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
V4L2_CID_AUTOGAIN,
0, /* min */
sensor->mode->pixel_rate, 1,
sensor->mode->pixel_rate);
+ /* By default, HBLANK is read only, but it does change per mode */
+ hblank = sensor->mode->hts - sensor->mode->format.width;
+ sensor->hblank = v4l2_ctrl_new_std(&sensor->ctrls, &ov5647_ctrl_ops,
+ V4L2_CID_HBLANK, hblank, hblank, 1,
+ hblank);
+ sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
if (sensor->ctrls.error) {
ret = sensor->ctrls.error;
dev_err(&client->dev, "%s control init failed (%d)\n",
sd = &sensor->sd;
v4l2_i2c_subdev_init(sd, client, &ov5647_subdev_ops);
sensor->sd.internal_ops = &ov5647_subdev_internal_ops;
- sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+ V4L2_SUBDEV_FL_HAS_EVENTS;
sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;