Commit 24d76ba9 authored by Alain Volmat's avatar Alain Volmat Committed by Hans Verkuil

media: i2c: gc2145: addition of RAW8 formats support

Adds support for RAW8 formats (BGGR/RGGB/RBRG/BRBG).
Signed-off-by: default avatarAlain Volmat <alain.volmat@foss.st.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
[hverkuil: fix typo: colospace -> colorspace]
parent 77d32b7e
...@@ -542,45 +542,82 @@ static const struct gc2145_mode supported_modes[] = { ...@@ -542,45 +542,82 @@ static const struct gc2145_mode supported_modes[] = {
/** /**
* struct gc2145_format - GC2145 pixel format description * struct gc2145_format - GC2145 pixel format description
* @code: media bus (MBUS) associated code * @code: media bus (MBUS) associated code
* @colorspace: V4L2 colorspace
* @datatype: MIPI CSI2 data type * @datatype: MIPI CSI2 data type
* @output_fmt: GC2145 output format * @output_fmt: GC2145 output format
* @switch_bit: GC2145 first/second switch * @switch_bit: GC2145 first/second switch
* @row_col_switch: GC2145 switch row and/or column
*/ */
struct gc2145_format { struct gc2145_format {
unsigned int code; unsigned int code;
unsigned int colorspace;
unsigned char datatype; unsigned char datatype;
unsigned char output_fmt; unsigned char output_fmt;
bool switch_bit; bool switch_bit;
unsigned char row_col_switch;
}; };
/* All supported formats */ /* All supported formats */
static const struct gc2145_format supported_formats[] = { static const struct gc2145_format supported_formats[] = {
{ {
.code = MEDIA_BUS_FMT_UYVY8_1X16, .code = MEDIA_BUS_FMT_UYVY8_1X16,
.colorspace = V4L2_COLORSPACE_SRGB,
.datatype = MIPI_CSI2_DT_YUV422_8B, .datatype = MIPI_CSI2_DT_YUV422_8B,
.output_fmt = 0x00, .output_fmt = 0x00,
}, },
{ {
.code = MEDIA_BUS_FMT_VYUY8_1X16, .code = MEDIA_BUS_FMT_VYUY8_1X16,
.colorspace = V4L2_COLORSPACE_SRGB,
.datatype = MIPI_CSI2_DT_YUV422_8B, .datatype = MIPI_CSI2_DT_YUV422_8B,
.output_fmt = 0x01, .output_fmt = 0x01,
}, },
{ {
.code = MEDIA_BUS_FMT_YUYV8_1X16, .code = MEDIA_BUS_FMT_YUYV8_1X16,
.colorspace = V4L2_COLORSPACE_SRGB,
.datatype = MIPI_CSI2_DT_YUV422_8B, .datatype = MIPI_CSI2_DT_YUV422_8B,
.output_fmt = 0x02, .output_fmt = 0x02,
}, },
{ {
.code = MEDIA_BUS_FMT_YVYU8_1X16, .code = MEDIA_BUS_FMT_YVYU8_1X16,
.colorspace = V4L2_COLORSPACE_SRGB,
.datatype = MIPI_CSI2_DT_YUV422_8B, .datatype = MIPI_CSI2_DT_YUV422_8B,
.output_fmt = 0x03, .output_fmt = 0x03,
}, },
{ {
.code = MEDIA_BUS_FMT_RGB565_1X16, .code = MEDIA_BUS_FMT_RGB565_1X16,
.colorspace = V4L2_COLORSPACE_SRGB,
.datatype = MIPI_CSI2_DT_RGB565, .datatype = MIPI_CSI2_DT_RGB565,
.output_fmt = 0x06, .output_fmt = 0x06,
.switch_bit = true, .switch_bit = true,
}, },
{
.code = MEDIA_BUS_FMT_SGRBG8_1X8,
.colorspace = V4L2_COLORSPACE_RAW,
.datatype = MIPI_CSI2_DT_RAW8,
.output_fmt = 0x17,
.row_col_switch = GC2145_SYNC_MODE_COL_SWITCH,
},
{
.code = MEDIA_BUS_FMT_SRGGB8_1X8,
.colorspace = V4L2_COLORSPACE_RAW,
.datatype = MIPI_CSI2_DT_RAW8,
.output_fmt = 0x17,
.row_col_switch = GC2145_SYNC_MODE_COL_SWITCH | GC2145_SYNC_MODE_ROW_SWITCH,
},
{
.code = MEDIA_BUS_FMT_SBGGR8_1X8,
.colorspace = V4L2_COLORSPACE_RAW,
.datatype = MIPI_CSI2_DT_RAW8,
.output_fmt = 0x17,
.row_col_switch = 0,
},
{
.code = MEDIA_BUS_FMT_SGBRG8_1X8,
.colorspace = V4L2_COLORSPACE_RAW,
.datatype = MIPI_CSI2_DT_RAW8,
.output_fmt = 0x17,
.row_col_switch = GC2145_SYNC_MODE_ROW_SWITCH,
},
}; };
struct gc2145_ctrls { struct gc2145_ctrls {
...@@ -641,7 +678,8 @@ gc2145_get_format_code(struct gc2145 *gc2145, u32 code) ...@@ -641,7 +678,8 @@ gc2145_get_format_code(struct gc2145 *gc2145, u32 code)
static void gc2145_update_pad_format(struct gc2145 *gc2145, static void gc2145_update_pad_format(struct gc2145 *gc2145,
const struct gc2145_mode *mode, const struct gc2145_mode *mode,
struct v4l2_mbus_framefmt *fmt, u32 code) struct v4l2_mbus_framefmt *fmt, u32 code,
u32 colorspace)
{ {
fmt->code = code; fmt->code = code;
fmt->width = mode->width; fmt->width = mode->width;
...@@ -663,7 +701,8 @@ static int gc2145_init_state(struct v4l2_subdev *sd, ...@@ -663,7 +701,8 @@ static int gc2145_init_state(struct v4l2_subdev *sd,
/* Initialize pad format */ /* Initialize pad format */
format = v4l2_subdev_state_get_format(state, 0); format = v4l2_subdev_state_get_format(state, 0);
gc2145_update_pad_format(gc2145, &supported_modes[0], format, gc2145_update_pad_format(gc2145, &supported_modes[0], format,
MEDIA_BUS_FMT_RGB565_1X16); MEDIA_BUS_FMT_RGB565_1X16,
V4L2_COLORSPACE_SRGB);
/* Initialize crop rectangle. */ /* Initialize crop rectangle. */
crop = v4l2_subdev_state_get_crop(state, 0); crop = v4l2_subdev_state_get_crop(state, 0);
...@@ -754,7 +793,13 @@ static int gc2145_set_pad_format(struct v4l2_subdev *sd, ...@@ -754,7 +793,13 @@ static int gc2145_set_pad_format(struct v4l2_subdev *sd,
width, height, width, height,
fmt->format.width, fmt->format.height); fmt->format.width, fmt->format.height);
gc2145_update_pad_format(gc2145, mode, &fmt->format, gc2145_fmt->code); /* In RAW mode, VGA is not possible so use 720p instead */
if (gc2145_fmt->colorspace == V4L2_COLORSPACE_RAW &&
mode == &supported_modes[GC2145_MODE_640X480])
mode = &supported_modes[GC2145_MODE_1280X720];
gc2145_update_pad_format(gc2145, mode, &fmt->format, gc2145_fmt->code,
gc2145_fmt->colorspace);
framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
gc2145->mode = mode; gc2145->mode = mode;
...@@ -811,7 +856,11 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145, ...@@ -811,7 +856,11 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145,
* For RAW8, LWC = image width * For RAW8, LWC = image width
* For RAW10, LWC = image width * 1.25 * For RAW10, LWC = image width * 1.25
*/ */
lwc = gc2145->mode->width * 2; if (gc2145_format->colorspace != V4L2_COLORSPACE_RAW)
lwc = gc2145->mode->width * 2;
else
lwc = gc2145->mode->width;
cci_write(gc2145->regmap, GC2145_REG_LWC_HIGH, lwc >> 8, &ret); cci_write(gc2145->regmap, GC2145_REG_LWC_HIGH, lwc >> 8, &ret);
cci_write(gc2145->regmap, GC2145_REG_LWC_LOW, lwc & 0xff, &ret); cci_write(gc2145->regmap, GC2145_REG_LWC_LOW, lwc & 0xff, &ret);
...@@ -821,10 +870,14 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145, ...@@ -821,10 +870,14 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145,
* 1280x720 / 1600x1200 (aka no scaler) non RAW: 0x0001 * 1280x720 / 1600x1200 (aka no scaler) non RAW: 0x0001
* 1600x1200 RAW: 0x0190 * 1600x1200 RAW: 0x0190
*/ */
if (gc2145->mode->width == 1280 || gc2145->mode->width == 1600) if (gc2145_format->colorspace != V4L2_COLORSPACE_RAW) {
fifo_full_lvl = 0x0001; if (gc2145->mode->width == 1280 || gc2145->mode->width == 1600)
else fifo_full_lvl = 0x0001;
else
fifo_full_lvl = 0x0190;
} else {
fifo_full_lvl = 0x0190; fifo_full_lvl = 0x0190;
}
cci_write(gc2145->regmap, GC2145_REG_FIFO_FULL_LVL_HIGH, cci_write(gc2145->regmap, GC2145_REG_FIFO_FULL_LVL_HIGH,
fifo_full_lvl >> 8, &ret); fifo_full_lvl >> 8, &ret);
...@@ -835,7 +888,9 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145, ...@@ -835,7 +888,9 @@ static int gc2145_config_mipi_mode(struct gc2145 *gc2145,
* Set the FIFO gate mode / MIPI wdiv set: * Set the FIFO gate mode / MIPI wdiv set:
* 0xf1 in case of RAW mode and 0xf0 otherwise * 0xf1 in case of RAW mode and 0xf0 otherwise
*/ */
cci_write(gc2145->regmap, GC2145_REG_FIFO_GATE_MODE, 0xf0, &ret); cci_write(gc2145->regmap, GC2145_REG_FIFO_GATE_MODE,
gc2145_format->colorspace == V4L2_COLORSPACE_RAW ?
0xf1 : 0xf0, &ret);
/* Set the MIPI data type */ /* Set the MIPI data type */
cci_write(gc2145->regmap, GC2145_REG_MIPI_DT, cci_write(gc2145->regmap, GC2145_REG_MIPI_DT,
...@@ -883,6 +938,10 @@ static int gc2145_start_streaming(struct gc2145 *gc2145, ...@@ -883,6 +938,10 @@ static int gc2145_start_streaming(struct gc2145 *gc2145,
GC2145_BYPASS_MODE_SWITCH, GC2145_BYPASS_MODE_SWITCH,
gc2145_format->switch_bit ? GC2145_BYPASS_MODE_SWITCH gc2145_format->switch_bit ? GC2145_BYPASS_MODE_SWITCH
: 0, &ret); : 0, &ret);
cci_update_bits(gc2145->regmap, GC2145_REG_SYNC_MODE,
GC2145_SYNC_MODE_COL_SWITCH |
GC2145_SYNC_MODE_ROW_SWITCH,
gc2145_format->row_col_switch, &ret);
if (ret) { if (ret) {
dev_err(&client->dev, "%s failed to write regs\n", __func__); dev_err(&client->dev, "%s failed to write regs\n", __func__);
goto err_rpm_put; goto err_rpm_put;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment