media: hi556: add 2592x1444 resolution
Adding additional cropped 2592x1444 resolution for QHD output from Hi556 sensor Also implement the get_selection pad operation for the Hi556 sensor driver. The supported targets report the sensor's native size, the crop default rectangle and the crop rectangle. Signed-off-by: Jim Lai <jim.lai@intel.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
This commit is contained in:
parent
8255140ee6
commit
c0bc1ca0b3
|
@ -63,6 +63,14 @@
|
|||
#define HI556_REG_ISP_TPG_EN 0x01
|
||||
#define HI556_REG_TEST_PATTERN 0x0201
|
||||
|
||||
/* HI556 native and active pixel array size. */
|
||||
#define HI556_NATIVE_WIDTH 2592U
|
||||
#define HI556_NATIVE_HEIGHT 1944U
|
||||
#define HI556_PIXEL_ARRAY_LEFT 0U
|
||||
#define HI556_PIXEL_ARRAY_TOP 0U
|
||||
#define HI556_PIXEL_ARRAY_WIDTH 2592U
|
||||
#define HI556_PIXEL_ARRAY_HEIGHT 1944U
|
||||
|
||||
enum {
|
||||
HI556_LINK_FREQ_437MHZ_INDEX,
|
||||
};
|
||||
|
@ -88,6 +96,9 @@ struct hi556_mode {
|
|||
/* Frame height in pixels */
|
||||
u32 height;
|
||||
|
||||
/* Analog crop rectangle. */
|
||||
struct v4l2_rect crop;
|
||||
|
||||
/* Horizontal timining size */
|
||||
u32 llp;
|
||||
|
||||
|
@ -378,6 +389,49 @@ static const struct hi556_reg mode_2592x1944_regs[] = {
|
|||
{0x0958, 0xbb80},
|
||||
};
|
||||
|
||||
static const struct hi556_reg mode_2592x1444_regs[] = {
|
||||
{0x0a00, 0x0000},
|
||||
{0x0b0a, 0x8252},
|
||||
{0x0f30, 0xe545},
|
||||
{0x0f32, 0x7067},
|
||||
{0x004a, 0x0100},
|
||||
{0x004c, 0x0000},
|
||||
{0x000c, 0x0022},
|
||||
{0x0008, 0x0b00},
|
||||
{0x005a, 0x0202},
|
||||
{0x0012, 0x000e},
|
||||
{0x0018, 0x0a33},
|
||||
{0x0022, 0x0008},
|
||||
{0x0028, 0x0017},
|
||||
{0x0024, 0x0122},
|
||||
{0x002a, 0x0127},
|
||||
{0x0026, 0x012a},
|
||||
{0x002c, 0x06cf},
|
||||
{0x002e, 0x1111},
|
||||
{0x0030, 0x1111},
|
||||
{0x0032, 0x1111},
|
||||
{0x0006, 0x0821},
|
||||
{0x0a22, 0x0000},
|
||||
{0x0a12, 0x0a20},
|
||||
{0x0a14, 0x05a4},
|
||||
{0x003e, 0x0000},
|
||||
{0x0074, 0x081f},
|
||||
{0x0070, 0x040f},
|
||||
{0x0804, 0x0300},
|
||||
{0x0806, 0x0100},
|
||||
{0x0a04, 0x014a},
|
||||
{0x090c, 0x0fdc},
|
||||
{0x090e, 0x002d},
|
||||
{0x0902, 0x4319},
|
||||
{0x0914, 0xc10a},
|
||||
{0x0916, 0x071f},
|
||||
{0x0918, 0x0408},
|
||||
{0x091a, 0x0c0d},
|
||||
{0x091c, 0x0f09},
|
||||
{0x091e, 0x0a00},
|
||||
{0x0958, 0xbb80},
|
||||
};
|
||||
|
||||
static const struct hi556_reg mode_1296x972_regs[] = {
|
||||
{0x0a00, 0x0000},
|
||||
{0x0b0a, 0x8259},
|
||||
|
@ -450,8 +504,14 @@ static const struct hi556_link_freq_config link_freq_configs[] = {
|
|||
|
||||
static const struct hi556_mode supported_modes[] = {
|
||||
{
|
||||
.width = 2592,
|
||||
.height = 1944,
|
||||
.width = HI556_PIXEL_ARRAY_WIDTH,
|
||||
.height = HI556_PIXEL_ARRAY_HEIGHT,
|
||||
.crop = {
|
||||
.left = HI556_PIXEL_ARRAY_LEFT,
|
||||
.top = HI556_PIXEL_ARRAY_TOP,
|
||||
.width = HI556_PIXEL_ARRAY_WIDTH,
|
||||
.height = HI556_PIXEL_ARRAY_HEIGHT
|
||||
},
|
||||
.fll_def = HI556_FLL_30FPS,
|
||||
.fll_min = HI556_FLL_30FPS_MIN,
|
||||
.llp = 0x0b00,
|
||||
|
@ -461,9 +521,33 @@ static const struct hi556_mode supported_modes[] = {
|
|||
},
|
||||
.link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = HI556_PIXEL_ARRAY_WIDTH,
|
||||
.height = 1444,
|
||||
.crop = {
|
||||
.left = HI556_PIXEL_ARRAY_LEFT,
|
||||
.top = 250,
|
||||
.width = HI556_PIXEL_ARRAY_WIDTH,
|
||||
.height = 1444
|
||||
},
|
||||
.fll_def = 0x821,
|
||||
.fll_min = 0x821,
|
||||
.llp = 0x0b00,
|
||||
.reg_list = {
|
||||
.num_of_regs = ARRAY_SIZE(mode_2592x1444_regs),
|
||||
.regs = mode_2592x1444_regs,
|
||||
},
|
||||
.link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,
|
||||
},
|
||||
{
|
||||
.width = 1296,
|
||||
.height = 972,
|
||||
.crop = {
|
||||
.left = HI556_PIXEL_ARRAY_LEFT,
|
||||
.top = HI556_PIXEL_ARRAY_TOP,
|
||||
.width = HI556_PIXEL_ARRAY_WIDTH,
|
||||
.height = HI556_PIXEL_ARRAY_HEIGHT
|
||||
},
|
||||
.fll_def = HI556_FLL_30FPS,
|
||||
.fll_min = HI556_FLL_30FPS_MIN,
|
||||
.llp = 0x0b00,
|
||||
|
@ -785,6 +869,58 @@ static int hi556_identify_module(struct hi556 *hi556)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_rect *
|
||||
__hi556_get_pad_crop(struct hi556 *hi556,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
unsigned int pad, enum v4l2_subdev_format_whence which)
|
||||
{
|
||||
switch (which) {
|
||||
case V4L2_SUBDEV_FORMAT_TRY:
|
||||
return v4l2_subdev_get_try_crop(&hi556->sd, sd_state, pad);
|
||||
case V4L2_SUBDEV_FORMAT_ACTIVE:
|
||||
return &hi556->cur_mode->crop;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int hi556_get_selection(struct v4l2_subdev *sd,
|
||||
struct v4l2_subdev_state *sd_state,
|
||||
struct v4l2_subdev_selection *sel)
|
||||
{
|
||||
switch (sel->target) {
|
||||
case V4L2_SEL_TGT_CROP: {
|
||||
struct hi556 *hi556 = to_hi556(sd);
|
||||
|
||||
mutex_lock(&hi556->mutex);
|
||||
sel->r = *__hi556_get_pad_crop(hi556, sd_state, sel->pad,
|
||||
sel->which);
|
||||
mutex_unlock(&hi556->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case V4L2_SEL_TGT_NATIVE_SIZE:
|
||||
sel->r.top = 0;
|
||||
sel->r.left = 0;
|
||||
sel->r.width = HI556_NATIVE_WIDTH;
|
||||
sel->r.height = HI556_NATIVE_HEIGHT;
|
||||
|
||||
return 0;
|
||||
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.top = HI556_PIXEL_ARRAY_TOP;
|
||||
sel->r.left = HI556_PIXEL_ARRAY_LEFT;
|
||||
sel->r.width = HI556_PIXEL_ARRAY_WIDTH;
|
||||
sel->r.height = HI556_PIXEL_ARRAY_HEIGHT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hi556_start_streaming(struct hi556 *hi556)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
|
||||
|
@ -1000,10 +1136,19 @@ static int hi556_enum_frame_size(struct v4l2_subdev *sd,
|
|||
static int hi556_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
{
|
||||
struct hi556 *hi556 = to_hi556(sd);
|
||||
struct v4l2_rect *try_crop;
|
||||
|
||||
mutex_lock(&hi556->mutex);
|
||||
hi556_assign_pad_format(&supported_modes[0],
|
||||
v4l2_subdev_get_try_format(sd, fh->state, 0));
|
||||
|
||||
/* Initialize try_crop rectangle. */
|
||||
try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
|
||||
try_crop->top = HI556_PIXEL_ARRAY_TOP;
|
||||
try_crop->left = HI556_PIXEL_ARRAY_LEFT;
|
||||
try_crop->width = HI556_PIXEL_ARRAY_WIDTH;
|
||||
try_crop->height = HI556_PIXEL_ARRAY_HEIGHT;
|
||||
|
||||
mutex_unlock(&hi556->mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -1016,6 +1161,7 @@ static const struct v4l2_subdev_video_ops hi556_video_ops = {
|
|||
static const struct v4l2_subdev_pad_ops hi556_pad_ops = {
|
||||
.set_fmt = hi556_set_format,
|
||||
.get_fmt = hi556_get_format,
|
||||
.get_selection = hi556_get_selection,
|
||||
.enum_mbus_code = hi556_enum_mbus_code,
|
||||
.enum_frame_size = hi556_enum_frame_size,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue