[v1,2/8] media: qcom: camss: Add subdev notify support
Commit Message
From: Yongsheng Li <quic_yon@quicinc.com>
The buf done irq and register update register are moved
to CSID in SM8550, so but the write master configuration
in VFE, in case adapt existing code logic. So add buf
done and register related subdev event, and use the notify
interface in the v4l2_device structure to communicate
between CSID and VFE driver.
Signed-off-by: Yongsheng Li <quic_yon@quicinc.com>
---
.../media/platform/qcom/camss/camss-csid.h | 7 +++
.../media/platform/qcom/camss/camss-csiphy.h | 2 +
drivers/media/platform/qcom/camss/camss-vfe.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 50 +++++++++++++++++++
drivers/media/platform/qcom/camss/camss.h | 7 +++
5 files changed, 68 insertions(+)
@@ -147,6 +147,13 @@ struct csid_hw_ops {
* @csid: CSID device
*/
void (*subdev_init)(struct csid_device *csid);
+
+ /*
+ * event - receive event from parent v4l2 device
+ * @csid: CSID device
+ */
+ void (*event)(struct csid_device *csid,
+ unsigned int evt_type, void *arg);
};
struct csid_device {
@@ -61,6 +61,8 @@ struct csiphy_hw_ops {
void (*lanes_disable)(struct csiphy_device *csiphy,
struct csiphy_config *cfg);
irqreturn_t (*isr)(int irq, void *dev);
+ void (*event)(struct csiphy_device *csiphy,
+ unsigned int evt_type, void *arg);
};
struct csiphy_device {
@@ -115,6 +115,8 @@ struct vfe_hw_ops {
int (*vfe_halt)(struct vfe_device *vfe);
void (*violation_read)(struct vfe_device *vfe);
void (*vfe_wm_stop)(struct vfe_device *vfe, u8 wm);
+ void (*event)(struct vfe_device *vfe,
+ unsigned int evt_type, void *arg);
};
struct vfe_isr_ops {
@@ -1904,6 +1904,55 @@ static void camss_genpd_cleanup(struct camss *camss)
dev_pm_domain_detach(camss->genpd, true);
}
+static void camss_v4l2_subdev_notify(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct v4l2_device *v4l2_dev = sd->v4l2_dev;
+ struct camss *camss = to_camss(v4l2_dev);
+ struct vfe_device *vfe;
+ struct vfe_line *vfe_line;
+ struct csid_device *csid;
+ int evt_data = *(int *)arg;
+
+ if (camss->res->version != CAMSS_8550)
+ return;
+
+ switch (cmd) {
+ case NOTIFY_BUF_DONE:
+ csid = v4l2_get_subdevdata(sd);
+ vfe = &(camss->vfe[csid->id]);
+ if (vfe->ops->event)
+ vfe->ops->event(vfe,
+ NOTIFY_BUF_DONE, (void *)&evt_data);
+ break;
+
+ case NOTIFY_RUP:
+ vfe_line = v4l2_get_subdevdata(sd);
+ vfe = to_vfe(vfe_line);
+ csid = &(camss->csid[vfe->id]);
+
+ if (csid->ops->event)
+ csid->ops->event(csid,
+ NOTIFY_RUP, (void *)&evt_data);
+ break;
+
+ case NOTIFY_RUP_CLEAR:
+ vfe_line = v4l2_get_subdevdata(sd);
+ vfe = to_vfe(vfe_line);
+ csid = &(camss->csid[vfe->id]);
+
+ if (csid->ops->event)
+ csid->ops->event(csid,
+ NOTIFY_RUP_CLEAR, (void *)&evt_data);
+
+ break;
+
+ default:
+ dev_err(camss->dev, "Not supported evt type\n");
+ break;
+ }
+}
+
/*
* camss_probe - Probe CAMSS platform device
* @pdev: Pointer to CAMSS platform device
@@ -1974,6 +2023,7 @@ static int camss_probe(struct platform_device *pdev)
media_device_init(&camss->media_dev);
camss->v4l2_dev.mdev = &camss->media_dev;
+ camss->v4l2_dev.notify = camss_v4l2_subdev_notify;
ret = v4l2_device_register(camss->dev, &camss->v4l2_dev);
if (ret < 0) {
dev_err(dev, "Failed to register V4L2 device: %d\n", ret);
@@ -86,6 +86,13 @@ enum icc_count {
ICC_SM8250_COUNT = 4,
};
+enum subdev_notify_evt {
+ NOTIFY_BUF_DONE = 0,
+ NOTIFY_RUP,
+ NOTIFY_RUP_CLEAR,
+ NOTIFY_MAX,
+};
+
struct camss_resources {
enum camss_version version;
const char *pd_name;