summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/camss/camss-csid.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/camss/camss-csid.c')
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.c661
1 files changed, 57 insertions, 604 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index be3fe76f3dc3..cc11fbfdae13 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -22,409 +22,52 @@
#include <media/v4l2-subdev.h>
#include "camss-csid.h"
+#include "camss-csid-gen1.h"
#include "camss.h"
#define MSM_CSID_NAME "msm_csid"
-#define CAMSS_CSID_HW_VERSION 0x0
-#define CAMSS_CSID_CORE_CTRL_0 0x004
-#define CAMSS_CSID_CORE_CTRL_1 0x008
-#define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010)
-#define CAMSS_CSID_CID_LUT_VC_n(v, n) \
- (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n))
-#define CAMSS_CSID_CID_n_CFG(v, n) \
- (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n))
-#define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
-#define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
-#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
-#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
-#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
-#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
-#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
-#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
-#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
-#define CAMSS_CSID_IRQ_CLEAR_CMD(v) ((v) == CAMSS_8x16 ? 0x060 : 0x064)
-#define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068)
-#define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c)
-#define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8)
-#define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
-#define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
-#define CAMSS_CSID_TG_VC_CFG(v) ((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac)
-#define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
-#define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
-#define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \
- (((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n))
-#define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \
- (((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n))
-#define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \
- (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n))
-
-#define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12
-#define DATA_TYPE_YUV422_8BIT 0x1e
-#define DATA_TYPE_RAW_6BIT 0x28
-#define DATA_TYPE_RAW_8BIT 0x2a
-#define DATA_TYPE_RAW_10BIT 0x2b
-#define DATA_TYPE_RAW_12BIT 0x2c
-#define DATA_TYPE_RAW_14BIT 0x2d
-
-#define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0
-#define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
-#define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
-#define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3
-#define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8
-
-#define CSID_RESET_TIMEOUT_MS 500
-
-struct csid_format {
- u32 code;
- u8 data_type;
- u8 decode_format;
- u8 bpp;
- u8 spp; /* bus samples per pixel */
-};
-
-static const struct csid_format csid_formats_8x16[] = {
- {
- MEDIA_BUS_FMT_UYVY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_VYUY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YUYV8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YVYU8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_SBGGR8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_Y10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
-};
-
-static const struct csid_format csid_formats_8x96[] = {
- {
- MEDIA_BUS_FMT_UYVY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_VYUY8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YUYV8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_YVYU8_2X8,
- DATA_TYPE_YUV422_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 2,
- },
- {
- MEDIA_BUS_FMT_SBGGR8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB8_1X8,
- DATA_TYPE_RAW_8BIT,
- DECODE_FORMAT_UNCOMPRESSED_8_BIT,
- 8,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB12_1X12,
- DATA_TYPE_RAW_12BIT,
- DECODE_FORMAT_UNCOMPRESSED_12_BIT,
- 12,
- 1,
- },
- {
- MEDIA_BUS_FMT_SBGGR14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGBRG14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_SGRBG14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_SRGGB14_1X14,
- DATA_TYPE_RAW_14BIT,
- DECODE_FORMAT_UNCOMPRESSED_14_BIT,
- 14,
- 1,
- },
- {
- MEDIA_BUS_FMT_Y10_1X10,
- DATA_TYPE_RAW_10BIT,
- DECODE_FORMAT_UNCOMPRESSED_10_BIT,
- 10,
- 1,
- },
+const char * const csid_testgen_modes[] = {
+ "Disabled",
+ "Incrementing",
+ "Alternating 0x55/0xAA",
+ "All Zeros 0x00",
+ "All Ones 0xFF",
+ "Pseudo-random Data",
+ "User Specified",
+ "Complex pattern",
+ "Color box",
+ "Color bars",
+ NULL
};
-static u32 csid_find_code(u32 *code, unsigned int n_code,
- unsigned int index, u32 req_code)
+u32 csid_find_code(u32 *codes, unsigned int ncodes,
+ unsigned int match_format_idx, u32 match_code)
{
int i;
- if (!req_code && (index >= n_code))
+ if (!match_code && (match_format_idx >= ncodes))
return 0;
- for (i = 0; i < n_code; i++)
- if (req_code) {
- if (req_code == code[i])
- return req_code;
+ for (i = 0; i < ncodes; i++)
+ if (match_code) {
+ if (codes[i] == match_code)
+ return match_code;
} else {
- if (i == index)
- return code[i];
+ if (i == match_format_idx)
+ return codes[i];
}
- return code[0];
+ return codes[0];
}
-static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
- unsigned int index, u32 src_req_code)
-{
- if (csid->camss->version == CAMSS_8x16) {
- if (index > 0)
- return 0;
-
- return sink_code;
- } else if (csid->camss->version == CAMSS_8x96 ||
- csid->camss->version == CAMSS_660) {
- switch (sink_code) {
- case MEDIA_BUS_FMT_SBGGR10_1X10:
- {
- u32 src_code[] = {
- MEDIA_BUS_FMT_SBGGR10_1X10,
- MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
- };
-
- return csid_find_code(src_code, ARRAY_SIZE(src_code),
- index, src_req_code);
- }
- case MEDIA_BUS_FMT_Y10_1X10:
- {
- u32 src_code[] = {
- MEDIA_BUS_FMT_Y10_1X10,
- MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
- };
-
- return csid_find_code(src_code, ARRAY_SIZE(src_code),
- index, src_req_code);
- }
- default:
- if (index > 0)
- return 0;
-
- return sink_code;
- }
- } else {
- return 0;
- }
-}
-
-static const struct csid_format *csid_get_fmt_entry(
- const struct csid_format *formats,
- unsigned int nformat,
- u32 code)
+const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats,
+ unsigned int nformats,
+ u32 code)
{
unsigned int i;
- for (i = 0; i < nformat; i++)
+ for (i = 0; i < nformats; i++)
if (code == formats[i].code)
return &formats[i];
@@ -434,41 +77,23 @@ static const struct csid_format *csid_get_fmt_entry(
}
/*
- * csid_isr - CSID module interrupt handler
- * @irq: Interrupt line
- * @dev: CSID device
- *
- * Return IRQ_HANDLED on success
- */
-static irqreturn_t csid_isr(int irq, void *dev)
-{
- struct csid_device *csid = dev;
- enum camss_version ver = csid->camss->version;
- u32 value;
-
- value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver));
- writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver));
-
- if ((value >> 11) & 0x1)
- complete(&csid->reset_complete);
-
- return IRQ_HANDLED;
-}
-
-/*
* csid_set_clock_rates - Calculate and set clock rates on CSID module
* @csiphy: CSID device
*/
static int csid_set_clock_rates(struct csid_device *csid)
{
struct device *dev = csid->camss->dev;
- u32 pixel_clock;
+ const struct csid_format *fmt;
+ s64 link_freq;
int i, j;
int ret;
- ret = camss_get_pixel_clock(&csid->subdev.entity, &pixel_clock);
- if (ret)
- pixel_clock = 0;
+ fmt = csid_get_fmt_entry(csid->formats, csid->nformats,
+ csid->fmt[MSM_CSIPHY_PAD_SINK].code);
+ link_freq = camss_get_link_freq(&csid->subdev.entity, fmt->bpp,
+ csid->phy.lane_cnt);
+ if (link_freq < 0)
+ link_freq = 0;
for (i = 0; i < csid->nclocks; i++) {
struct camss_clock *clock = &csid->clock[i];
@@ -477,13 +102,7 @@ static int csid_set_clock_rates(struct csid_device *csid)
!strcmp(clock->name, "csi1") ||
!strcmp(clock->name, "csi2") ||
!strcmp(clock->name, "csi3")) {
- const struct csid_format *f = csid_get_fmt_entry(
- csid->formats,
- csid->nformats,
- csid->fmt[MSM_CSIPHY_PAD_SINK].code);
- u8 num_lanes = csid->phy.lane_cnt;
- u64 min_rate = pixel_clock * f->bpp /
- (2 * num_lanes * 4);
+ u64 min_rate = link_freq / 4;
long rate;
camss_add_clock_margin(&min_rate);
@@ -515,6 +134,8 @@ static int csid_set_clock_rates(struct csid_device *csid)
dev_err(dev, "clk set rate failed: %d\n", ret);
return ret;
}
+ } else if (clock->nfreqs) {
+ clk_set_rate(clock->clk, clock->freq[0]);
}
}
@@ -522,31 +143,6 @@ static int csid_set_clock_rates(struct csid_device *csid)
}
/*
- * csid_reset - Trigger reset on CSID module and wait to complete
- * @csid: CSID device
- *
- * Return 0 on success or a negative error code otherwise
- */
-static int csid_reset(struct csid_device *csid)
-{
- unsigned long time;
-
- reinit_completion(&csid->reset_complete);
-
- writel_relaxed(0x7fff, csid->base +
- CAMSS_CSID_RST_CMD(csid->camss->version));
-
- time = wait_for_completion_timeout(&csid->reset_complete,
- msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
- if (!time) {
- dev_err(csid->camss->dev, "CSID reset timeout\n");
- return -EIO;
- }
-
- return 0;
-}
-
-/*
* csid_set_power - Power on/off CSID module
* @sd: CSID V4L2 subdevice
* @on: Requested power state
@@ -560,8 +156,6 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
int ret;
if (on) {
- u32 hw_version;
-
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
pm_runtime_put_sync(dev);
@@ -590,7 +184,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
enable_irq(csid->irq);
- ret = csid_reset(csid);
+ ret = csid->ops->reset(csid);
if (ret < 0) {
disable_irq(csid->irq);
camss_disable_clocks(csid->nclocks, csid->clock);
@@ -599,8 +193,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
return ret;
}
- hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
- dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version);
+ csid->ops->hw_version(csid);
} else {
disable_irq(csid->irq);
camss_disable_clocks(csid->nclocks, csid->clock);
@@ -623,16 +216,9 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
static int csid_set_stream(struct v4l2_subdev *sd, int enable)
{
struct csid_device *csid = v4l2_get_subdevdata(sd);
- struct csid_testgen_config *tg = &csid->testgen;
- enum camss_version ver = csid->camss->version;
- u32 val;
+ int ret;
if (enable) {
- u8 vc = 0; /* Virtual Channel 0 */
- u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
- u8 dt, dt_shift, df;
- int ret;
-
ret = v4l2_ctrl_handler_setup(&csid->ctrls);
if (ret < 0) {
dev_err(csid->camss->dev,
@@ -640,116 +226,13 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
}
- if (!tg->enabled &&
+ if (!csid->testgen.enabled &&
!media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
return -ENOLINK;
-
- if (tg->enabled) {
- /* Config Test Generator */
- struct v4l2_mbus_framefmt *f =
- &csid->fmt[MSM_CSID_PAD_SRC];
- const struct csid_format *format = csid_get_fmt_entry(
- csid->formats, csid->nformats, f->code);
- u32 num_bytes_per_line =
- f->width * format->bpp * format->spp / 8;
- u32 num_lines = f->height;
-
- /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
- /* 1:0 VC */
- val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
- ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_VC_CFG(ver));
-
- /* 28:16 bytes per lines, 12:0 num of lines */
- val = ((num_bytes_per_line & 0x1fff) << 16) |
- (num_lines & 0x1fff);
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_DT_n_CGG_0(ver, 0));
-
- dt = format->data_type;
-
- /* 5:0 data type */
- val = dt;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_DT_n_CGG_1(ver, 0));
-
- /* 2:0 output test pattern */
- val = tg->payload_mode;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_DT_n_CGG_2(ver, 0));
-
- df = format->decode_format;
- } else {
- struct v4l2_mbus_framefmt *f =
- &csid->fmt[MSM_CSID_PAD_SINK];
- const struct csid_format *format = csid_get_fmt_entry(
- csid->formats, csid->nformats, f->code);
- struct csid_phy_config *phy = &csid->phy;
-
- val = phy->lane_cnt - 1;
- val |= phy->lane_assign << 4;
-
- writel_relaxed(val,
- csid->base + CAMSS_CSID_CORE_CTRL_0);
-
- val = phy->csiphy_id << 17;
- val |= 0x9;
-
- writel_relaxed(val,
- csid->base + CAMSS_CSID_CORE_CTRL_1);
-
- dt = format->data_type;
- df = format->decode_format;
- }
-
- /* Config LUT */
-
- dt_shift = (cid % 4) * 8;
-
- val = readl_relaxed(csid->base +
- CAMSS_CSID_CID_LUT_VC_n(ver, vc));
- val &= ~(0xff << dt_shift);
- val |= dt << dt_shift;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_CID_LUT_VC_n(ver, vc));
-
- val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
- val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
- val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
- val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
-
- if (csid->camss->version == CAMSS_8x96 ||
- csid->camss->version == CAMSS_660) {
- u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
- u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
-
- if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
- src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
- (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
- src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
- val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
- val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
- val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
- }
- }
-
- writel_relaxed(val, csid->base +
- CAMSS_CSID_CID_n_CFG(ver, cid));
-
- if (tg->enabled) {
- val = CAMSS_CSID_TG_CTRL_ENABLE;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_CTRL(ver));
- }
- } else {
- if (tg->enabled) {
- val = CAMSS_CSID_TG_CTRL_DISABLE;
- writel_relaxed(val, csid->base +
- CAMSS_CSID_TG_CTRL(ver));
- }
}
+ csid->ops->configure_stream(csid, enable);
+
return 0;
}
@@ -818,7 +301,7 @@ static void csid_try_format(struct csid_device *csid,
*fmt = *__csid_get_format(csid, cfg,
MSM_CSID_PAD_SINK, which);
- fmt->code = csid_src_pad_code(csid, fmt->code, 0, code);
+ fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code);
} else {
/* Test generator is enabled, set format on source */
/* pad to allow test generator usage */
@@ -868,7 +351,7 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd,
MSM_CSID_PAD_SINK,
code->which);
- code->code = csid_src_pad_code(csid, sink_fmt->code,
+ code->code = csid->ops->src_pad_code(csid, sink_fmt->code,
code->index, 0);
if (!code->code)
return -EINVAL;
@@ -1004,15 +487,6 @@ static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
return csid_set_format(sd, fh ? fh->pad : NULL, &format);
}
-static const char * const csid_test_pattern_menu[] = {
- "Disabled",
- "Incrementing",
- "Alternating 0x55/0xAA",
- "All Zeros 0x00",
- "All Ones 0xFF",
- "Pseudo-random Data",
-};
-
/*
* csid_set_test_pattern - Set test generator's pattern mode
* @csid: CSID device
@@ -1030,25 +504,7 @@ static int csid_set_test_pattern(struct csid_device *csid, s32 value)
tg->enabled = !!value;
- switch (value) {
- case 1:
- tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING;
- break;
- case 2:
- tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA;
- break;
- case 3:
- tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES;
- break;
- case 4:
- tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES;
- break;
- case 5:
- tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM;
- break;
- }
-
- return 0;
+ return csid->ops->configure_testgen_pattern(csid, value);
}
/*
@@ -1097,26 +553,23 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->id = id;
if (camss->version == CAMSS_8x16) {
- csid->formats = csid_formats_8x16;
- csid->nformats =
- ARRAY_SIZE(csid_formats_8x16);
+ csid->ops = &csid_ops_4_1;
} else if (camss->version == CAMSS_8x96 ||
camss->version == CAMSS_660) {
- csid->formats = csid_formats_8x96;
- csid->nformats =
- ARRAY_SIZE(csid_formats_8x96);
+ csid->ops = &csid_ops_4_7;
+ } else if (camss->version == CAMSS_845) {
+ csid->ops = &csid_ops_170;
} else {
return -EINVAL;
}
+ csid->ops->subdev_init(csid);
/* Memory */
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
csid->base = devm_ioremap_resource(dev, r);
- if (IS_ERR(csid->base)) {
- dev_err(dev, "could not map memory\n");
+ if (IS_ERR(csid->base))
return PTR_ERR(csid->base);
- }
/* Interrupt */
@@ -1130,8 +583,8 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->irq = r->start;
snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
dev_name(dev), MSM_CSID_NAME, csid->id);
- ret = devm_request_irq(dev, csid->irq, csid_isr,
- IRQF_TRIGGER_RISING, csid->irq_name, csid);
+ ret = devm_request_irq(dev, csid->irq, csid->ops->isr,
+ IRQF_TRIGGER_RISING, csid->irq_name, csid);
if (ret < 0) {
dev_err(dev, "request_irq failed: %d\n", ret);
return ret;
@@ -1341,8 +794,8 @@ int msm_csid_register_entity(struct csid_device *csid,
csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
&csid_ctrl_ops, V4L2_CID_TEST_PATTERN,
- ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0,
- csid_test_pattern_menu);
+ csid->testgen.nmodes, 0, 0,
+ csid->testgen.modes);
if (csid->ctrls.error) {
dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);