@@ -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;