0001
0002
0003
0004
0005
0006
0007 #include <linux/clk.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/io.h>
0010 #include <linux/iopoll.h>
0011 #include <linux/irq.h>
0012 #include <linux/module.h>
0013 #include <linux/of_graph.h>
0014 #include <linux/platform_device.h>
0015 #include <media/v4l2-device.h>
0016 #include <media/v4l2-fwnode.h>
0017 #include <media/v4l2-mc.h>
0018 #include <media/v4l2-subdev.h>
0019 #include "imx-media.h"
0020
0021
0022
0023
0024
0025 #define CSI2_SINK_PAD 0
0026 #define CSI2_NUM_SINK_PADS 1
0027 #define CSI2_NUM_SRC_PADS 4
0028 #define CSI2_NUM_PADS 5
0029
0030
0031
0032
0033
0034 #define CSI2_DEFAULT_MAX_MBPS 849
0035
0036 struct csi2_dev {
0037 struct device *dev;
0038 struct v4l2_subdev sd;
0039 struct v4l2_async_notifier notifier;
0040 struct media_pad pad[CSI2_NUM_PADS];
0041 struct clk *dphy_clk;
0042 struct clk *pllref_clk;
0043 struct clk *pix_clk;
0044 void __iomem *base;
0045
0046 struct v4l2_subdev *remote;
0047 unsigned int remote_pad;
0048 unsigned short data_lanes;
0049
0050
0051 struct mutex lock;
0052
0053 struct v4l2_mbus_framefmt format_mbus;
0054
0055 int stream_count;
0056 struct v4l2_subdev *src_sd;
0057 bool sink_linked[CSI2_NUM_SRC_PADS];
0058 };
0059
0060 #define DEVICE_NAME "imx6-mipi-csi2"
0061
0062
0063 #define CSI2_VERSION 0x000
0064 #define CSI2_N_LANES 0x004
0065 #define CSI2_PHY_SHUTDOWNZ 0x008
0066 #define CSI2_DPHY_RSTZ 0x00c
0067 #define CSI2_RESETN 0x010
0068 #define CSI2_PHY_STATE 0x014
0069 #define PHY_STOPSTATEDATA_BIT 4
0070 #define PHY_STOPSTATEDATA(n) BIT(PHY_STOPSTATEDATA_BIT + (n))
0071 #define PHY_RXCLKACTIVEHS BIT(8)
0072 #define PHY_RXULPSCLKNOT BIT(9)
0073 #define PHY_STOPSTATECLK BIT(10)
0074 #define CSI2_DATA_IDS_1 0x018
0075 #define CSI2_DATA_IDS_2 0x01c
0076 #define CSI2_ERR1 0x020
0077 #define CSI2_ERR2 0x024
0078 #define CSI2_MSK1 0x028
0079 #define CSI2_MSK2 0x02c
0080 #define CSI2_PHY_TST_CTRL0 0x030
0081 #define PHY_TESTCLR BIT(0)
0082 #define PHY_TESTCLK BIT(1)
0083 #define CSI2_PHY_TST_CTRL1 0x034
0084 #define PHY_TESTEN BIT(16)
0085
0086
0087
0088
0089
0090 #define CSI2IPU_GASKET 0xf00
0091 #define CSI2IPU_YUV422_YUYV BIT(2)
0092
0093 static inline struct csi2_dev *sd_to_dev(struct v4l2_subdev *sdev)
0094 {
0095 return container_of(sdev, struct csi2_dev, sd);
0096 }
0097
0098 static inline struct csi2_dev *notifier_to_dev(struct v4l2_async_notifier *n)
0099 {
0100 return container_of(n, struct csi2_dev, notifier);
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 static void csi2_enable(struct csi2_dev *csi2, bool enable)
0132 {
0133 if (enable) {
0134 writel(0x1, csi2->base + CSI2_PHY_SHUTDOWNZ);
0135 writel(0x1, csi2->base + CSI2_DPHY_RSTZ);
0136 writel(0x1, csi2->base + CSI2_RESETN);
0137 } else {
0138 writel(0x0, csi2->base + CSI2_PHY_SHUTDOWNZ);
0139 writel(0x0, csi2->base + CSI2_DPHY_RSTZ);
0140 writel(0x0, csi2->base + CSI2_RESETN);
0141 }
0142 }
0143
0144 static void csi2_set_lanes(struct csi2_dev *csi2, unsigned int lanes)
0145 {
0146 writel(lanes - 1, csi2->base + CSI2_N_LANES);
0147 }
0148
0149 static void dw_mipi_csi2_phy_write(struct csi2_dev *csi2,
0150 u32 test_code, u32 test_data)
0151 {
0152
0153 writel(PHY_TESTCLR, csi2->base + CSI2_PHY_TST_CTRL0);
0154 writel(0x0, csi2->base + CSI2_PHY_TST_CTRL1);
0155 writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
0156
0157
0158 writel(PHY_TESTCLK, csi2->base + CSI2_PHY_TST_CTRL0);
0159
0160
0161 writel(PHY_TESTEN | test_code, csi2->base + CSI2_PHY_TST_CTRL1);
0162 writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
0163
0164
0165 writel(test_data, csi2->base + CSI2_PHY_TST_CTRL1);
0166 writel(PHY_TESTCLK, csi2->base + CSI2_PHY_TST_CTRL0);
0167
0168
0169 writel(0x0, csi2->base + CSI2_PHY_TST_CTRL0);
0170 }
0171
0172
0173
0174
0175
0176
0177 static const struct {
0178 u32 max_mbps;
0179 u32 hsfreqrange_sel;
0180 } hsfreq_map[] = {
0181 { 90, 0x00}, {100, 0x20}, {110, 0x40}, {125, 0x02},
0182 {140, 0x22}, {150, 0x42}, {160, 0x04}, {180, 0x24},
0183 {200, 0x44}, {210, 0x06}, {240, 0x26}, {250, 0x46},
0184 {270, 0x08}, {300, 0x28}, {330, 0x48}, {360, 0x2a},
0185 {400, 0x4a}, {450, 0x0c}, {500, 0x2c}, {550, 0x0e},
0186 {600, 0x2e}, {650, 0x10}, {700, 0x30}, {750, 0x12},
0187 {800, 0x32}, {850, 0x14}, {900, 0x34}, {950, 0x54},
0188 {1000, 0x74},
0189 };
0190
0191 static int max_mbps_to_hsfreqrange_sel(u32 max_mbps)
0192 {
0193 int i;
0194
0195 for (i = 0; i < ARRAY_SIZE(hsfreq_map); i++)
0196 if (hsfreq_map[i].max_mbps > max_mbps)
0197 return hsfreq_map[i].hsfreqrange_sel;
0198
0199 return -EINVAL;
0200 }
0201
0202 static int csi2_dphy_init(struct csi2_dev *csi2)
0203 {
0204 struct v4l2_ctrl *ctrl;
0205 u32 mbps_per_lane;
0206 int sel;
0207
0208 ctrl = v4l2_ctrl_find(csi2->src_sd->ctrl_handler,
0209 V4L2_CID_LINK_FREQ);
0210 if (!ctrl)
0211 mbps_per_lane = CSI2_DEFAULT_MAX_MBPS;
0212 else
0213 mbps_per_lane = DIV_ROUND_UP_ULL(2 * ctrl->qmenu_int[ctrl->val],
0214 USEC_PER_SEC);
0215
0216 sel = max_mbps_to_hsfreqrange_sel(mbps_per_lane);
0217 if (sel < 0)
0218 return sel;
0219
0220 dw_mipi_csi2_phy_write(csi2, 0x44, sel);
0221
0222 return 0;
0223 }
0224
0225
0226
0227
0228
0229 static int __maybe_unused csi2_dphy_wait_ulp(struct csi2_dev *csi2)
0230 {
0231 u32 reg;
0232 int ret;
0233
0234
0235 ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
0236 !(reg & PHY_RXULPSCLKNOT), 0, 500000);
0237 if (ret) {
0238 v4l2_err(&csi2->sd, "ULP timeout, phy_state = 0x%08x\n", reg);
0239 return ret;
0240 }
0241
0242
0243 ret = readl_poll_timeout(csi2->base + CSI2_ERR1, reg,
0244 reg == 0x0, 0, 500000);
0245 if (ret) {
0246 v4l2_err(&csi2->sd, "stable bus timeout, err1 = 0x%08x\n", reg);
0247 return ret;
0248 }
0249
0250 return 0;
0251 }
0252
0253
0254 static void csi2_dphy_wait_stopstate(struct csi2_dev *csi2, unsigned int lanes)
0255 {
0256 u32 mask, reg;
0257 int ret;
0258
0259 mask = PHY_STOPSTATECLK | (((1 << lanes) - 1) << PHY_STOPSTATEDATA_BIT);
0260
0261 ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
0262 (reg & mask) == mask, 0, 500000);
0263 if (ret) {
0264 v4l2_warn(&csi2->sd, "LP-11 wait timeout, likely a sensor driver bug, expect capture failures.\n");
0265 v4l2_warn(&csi2->sd, "phy_state = 0x%08x\n", reg);
0266 }
0267 }
0268
0269
0270 static int csi2_dphy_wait_clock_lane(struct csi2_dev *csi2)
0271 {
0272 u32 reg;
0273 int ret;
0274
0275 ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
0276 (reg & PHY_RXCLKACTIVEHS), 0, 500000);
0277 if (ret) {
0278 v4l2_err(&csi2->sd, "clock lane timeout, phy_state = 0x%08x\n",
0279 reg);
0280 return ret;
0281 }
0282
0283 return 0;
0284 }
0285
0286
0287 static void csi2ipu_gasket_init(struct csi2_dev *csi2)
0288 {
0289 u32 reg = 0;
0290
0291 switch (csi2->format_mbus.code) {
0292 case MEDIA_BUS_FMT_YUYV8_2X8:
0293 case MEDIA_BUS_FMT_YUYV8_1X16:
0294 reg = CSI2IPU_YUV422_YUYV;
0295 break;
0296 default:
0297 break;
0298 }
0299
0300 writel(reg, csi2->base + CSI2IPU_GASKET);
0301 }
0302
0303 static int csi2_get_active_lanes(struct csi2_dev *csi2, unsigned int *lanes)
0304 {
0305 struct v4l2_mbus_config mbus_config = { 0 };
0306 int ret;
0307
0308 *lanes = csi2->data_lanes;
0309
0310 ret = v4l2_subdev_call(csi2->remote, pad, get_mbus_config,
0311 csi2->remote_pad, &mbus_config);
0312 if (ret == -ENOIOCTLCMD) {
0313 dev_dbg(csi2->dev, "No remote mbus configuration available\n");
0314 return 0;
0315 }
0316
0317 if (ret) {
0318 dev_err(csi2->dev, "Failed to get remote mbus configuration\n");
0319 return ret;
0320 }
0321
0322 if (mbus_config.type != V4L2_MBUS_CSI2_DPHY) {
0323 dev_err(csi2->dev, "Unsupported media bus type %u\n",
0324 mbus_config.type);
0325 return -EINVAL;
0326 }
0327
0328 if (mbus_config.bus.mipi_csi2.num_data_lanes > csi2->data_lanes) {
0329 dev_err(csi2->dev,
0330 "Unsupported mbus config: too many data lanes %u\n",
0331 mbus_config.bus.mipi_csi2.num_data_lanes);
0332 return -EINVAL;
0333 }
0334
0335 *lanes = mbus_config.bus.mipi_csi2.num_data_lanes;
0336
0337 return 0;
0338 }
0339
0340 static int csi2_start(struct csi2_dev *csi2)
0341 {
0342 unsigned int lanes;
0343 int ret;
0344
0345 ret = clk_prepare_enable(csi2->pix_clk);
0346 if (ret)
0347 return ret;
0348
0349
0350 csi2ipu_gasket_init(csi2);
0351
0352
0353 ret = csi2_dphy_init(csi2);
0354 if (ret)
0355 goto err_disable_clk;
0356
0357 ret = csi2_get_active_lanes(csi2, &lanes);
0358 if (ret)
0359 goto err_disable_clk;
0360
0361
0362 csi2_set_lanes(csi2, lanes);
0363 csi2_enable(csi2, true);
0364
0365
0366 ret = v4l2_subdev_call(csi2->src_sd, video, pre_streamon,
0367 V4L2_SUBDEV_PRE_STREAMON_FL_MANUAL_LP);
0368 if (ret && ret != -ENOIOCTLCMD)
0369 goto err_assert_reset;
0370 csi2_dphy_wait_stopstate(csi2, lanes);
0371
0372
0373 ret = v4l2_subdev_call(csi2->src_sd, video, s_stream, 1);
0374 ret = (ret && ret != -ENOIOCTLCMD) ? ret : 0;
0375 if (ret)
0376 goto err_stop_lp11;
0377
0378
0379 ret = csi2_dphy_wait_clock_lane(csi2);
0380 if (ret)
0381 goto err_stop_upstream;
0382
0383 return 0;
0384
0385 err_stop_upstream:
0386 v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
0387 err_stop_lp11:
0388 v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
0389 err_assert_reset:
0390 csi2_enable(csi2, false);
0391 err_disable_clk:
0392 clk_disable_unprepare(csi2->pix_clk);
0393 return ret;
0394 }
0395
0396 static void csi2_stop(struct csi2_dev *csi2)
0397 {
0398
0399 v4l2_subdev_call(csi2->src_sd, video, s_stream, 0);
0400 v4l2_subdev_call(csi2->src_sd, video, post_streamoff);
0401
0402 csi2_enable(csi2, false);
0403 clk_disable_unprepare(csi2->pix_clk);
0404 }
0405
0406
0407
0408
0409
0410 static int csi2_s_stream(struct v4l2_subdev *sd, int enable)
0411 {
0412 struct csi2_dev *csi2 = sd_to_dev(sd);
0413 int i, ret = 0;
0414
0415 mutex_lock(&csi2->lock);
0416
0417 if (!csi2->src_sd) {
0418 ret = -EPIPE;
0419 goto out;
0420 }
0421
0422 for (i = 0; i < CSI2_NUM_SRC_PADS; i++) {
0423 if (csi2->sink_linked[i])
0424 break;
0425 }
0426 if (i >= CSI2_NUM_SRC_PADS) {
0427 ret = -EPIPE;
0428 goto out;
0429 }
0430
0431
0432
0433
0434
0435 if (csi2->stream_count != !enable)
0436 goto update_count;
0437
0438 dev_dbg(csi2->dev, "stream %s\n", enable ? "ON" : "OFF");
0439 if (enable)
0440 ret = csi2_start(csi2);
0441 else
0442 csi2_stop(csi2);
0443 if (ret)
0444 goto out;
0445
0446 update_count:
0447 csi2->stream_count += enable ? 1 : -1;
0448 if (csi2->stream_count < 0)
0449 csi2->stream_count = 0;
0450 out:
0451 mutex_unlock(&csi2->lock);
0452 return ret;
0453 }
0454
0455 static int csi2_link_setup(struct media_entity *entity,
0456 const struct media_pad *local,
0457 const struct media_pad *remote, u32 flags)
0458 {
0459 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
0460 struct csi2_dev *csi2 = sd_to_dev(sd);
0461 struct v4l2_subdev *remote_sd;
0462 int ret = 0;
0463
0464 dev_dbg(csi2->dev, "link setup %s -> %s", remote->entity->name,
0465 local->entity->name);
0466
0467 remote_sd = media_entity_to_v4l2_subdev(remote->entity);
0468
0469 mutex_lock(&csi2->lock);
0470
0471 if (local->flags & MEDIA_PAD_FL_SOURCE) {
0472 if (flags & MEDIA_LNK_FL_ENABLED) {
0473 if (csi2->sink_linked[local->index - 1]) {
0474 ret = -EBUSY;
0475 goto out;
0476 }
0477 csi2->sink_linked[local->index - 1] = true;
0478 } else {
0479 csi2->sink_linked[local->index - 1] = false;
0480 }
0481 } else {
0482 if (flags & MEDIA_LNK_FL_ENABLED) {
0483 if (csi2->src_sd) {
0484 ret = -EBUSY;
0485 goto out;
0486 }
0487 csi2->src_sd = remote_sd;
0488 } else {
0489 csi2->src_sd = NULL;
0490 }
0491 }
0492
0493 out:
0494 mutex_unlock(&csi2->lock);
0495 return ret;
0496 }
0497
0498 static struct v4l2_mbus_framefmt *
0499 __csi2_get_fmt(struct csi2_dev *csi2, struct v4l2_subdev_state *sd_state,
0500 unsigned int pad, enum v4l2_subdev_format_whence which)
0501 {
0502 if (which == V4L2_SUBDEV_FORMAT_TRY)
0503 return v4l2_subdev_get_try_format(&csi2->sd, sd_state, pad);
0504 else
0505 return &csi2->format_mbus;
0506 }
0507
0508 static int csi2_get_fmt(struct v4l2_subdev *sd,
0509 struct v4l2_subdev_state *sd_state,
0510 struct v4l2_subdev_format *sdformat)
0511 {
0512 struct csi2_dev *csi2 = sd_to_dev(sd);
0513 struct v4l2_mbus_framefmt *fmt;
0514
0515 mutex_lock(&csi2->lock);
0516
0517 fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
0518
0519 sdformat->format = *fmt;
0520
0521 mutex_unlock(&csi2->lock);
0522
0523 return 0;
0524 }
0525
0526 static int csi2_set_fmt(struct v4l2_subdev *sd,
0527 struct v4l2_subdev_state *sd_state,
0528 struct v4l2_subdev_format *sdformat)
0529 {
0530 struct csi2_dev *csi2 = sd_to_dev(sd);
0531 struct v4l2_mbus_framefmt *fmt;
0532 int ret = 0;
0533
0534 if (sdformat->pad >= CSI2_NUM_PADS)
0535 return -EINVAL;
0536
0537 mutex_lock(&csi2->lock);
0538
0539 if (csi2->stream_count > 0) {
0540 ret = -EBUSY;
0541 goto out;
0542 }
0543
0544
0545 if (sdformat->pad != CSI2_SINK_PAD)
0546 sdformat->format = csi2->format_mbus;
0547
0548 fmt = __csi2_get_fmt(csi2, sd_state, sdformat->pad, sdformat->which);
0549
0550 *fmt = sdformat->format;
0551 out:
0552 mutex_unlock(&csi2->lock);
0553 return ret;
0554 }
0555
0556 static int csi2_registered(struct v4l2_subdev *sd)
0557 {
0558 struct csi2_dev *csi2 = sd_to_dev(sd);
0559
0560
0561 return imx_media_init_mbus_fmt(&csi2->format_mbus,
0562 IMX_MEDIA_DEF_PIX_WIDTH,
0563 IMX_MEDIA_DEF_PIX_HEIGHT, 0,
0564 V4L2_FIELD_NONE, NULL);
0565 }
0566
0567 static const struct media_entity_operations csi2_entity_ops = {
0568 .link_setup = csi2_link_setup,
0569 .link_validate = v4l2_subdev_link_validate,
0570 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
0571 };
0572
0573 static const struct v4l2_subdev_video_ops csi2_video_ops = {
0574 .s_stream = csi2_s_stream,
0575 };
0576
0577 static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
0578 .init_cfg = imx_media_init_cfg,
0579 .get_fmt = csi2_get_fmt,
0580 .set_fmt = csi2_set_fmt,
0581 };
0582
0583 static const struct v4l2_subdev_ops csi2_subdev_ops = {
0584 .video = &csi2_video_ops,
0585 .pad = &csi2_pad_ops,
0586 };
0587
0588 static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
0589 .registered = csi2_registered,
0590 };
0591
0592 static int csi2_notify_bound(struct v4l2_async_notifier *notifier,
0593 struct v4l2_subdev *sd,
0594 struct v4l2_async_subdev *asd)
0595 {
0596 struct csi2_dev *csi2 = notifier_to_dev(notifier);
0597 struct media_pad *sink = &csi2->sd.entity.pads[CSI2_SINK_PAD];
0598 int pad;
0599
0600 pad = media_entity_get_fwnode_pad(&sd->entity, asd->match.fwnode,
0601 MEDIA_PAD_FL_SOURCE);
0602 if (pad < 0) {
0603 dev_err(csi2->dev, "Failed to find pad for %s\n", sd->name);
0604 return pad;
0605 }
0606
0607 csi2->remote = sd;
0608 csi2->remote_pad = pad;
0609
0610 dev_dbg(csi2->dev, "Bound %s pad: %d\n", sd->name, pad);
0611
0612 return v4l2_create_fwnode_links_to_pad(sd, sink, 0);
0613 }
0614
0615 static void csi2_notify_unbind(struct v4l2_async_notifier *notifier,
0616 struct v4l2_subdev *sd,
0617 struct v4l2_async_subdev *asd)
0618 {
0619 struct csi2_dev *csi2 = notifier_to_dev(notifier);
0620
0621 csi2->remote = NULL;
0622 }
0623
0624 static const struct v4l2_async_notifier_operations csi2_notify_ops = {
0625 .bound = csi2_notify_bound,
0626 .unbind = csi2_notify_unbind,
0627 };
0628
0629 static int csi2_async_register(struct csi2_dev *csi2)
0630 {
0631 struct v4l2_fwnode_endpoint vep = {
0632 .bus_type = V4L2_MBUS_CSI2_DPHY,
0633 };
0634 struct v4l2_async_subdev *asd;
0635 struct fwnode_handle *ep;
0636 int ret;
0637
0638 v4l2_async_nf_init(&csi2->notifier);
0639
0640 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi2->dev), 0, 0,
0641 FWNODE_GRAPH_ENDPOINT_NEXT);
0642 if (!ep)
0643 return -ENOTCONN;
0644
0645 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
0646 if (ret)
0647 goto err_parse;
0648
0649 csi2->data_lanes = vep.bus.mipi_csi2.num_data_lanes;
0650
0651 dev_dbg(csi2->dev, "data lanes: %d\n", vep.bus.mipi_csi2.num_data_lanes);
0652 dev_dbg(csi2->dev, "flags: 0x%08x\n", vep.bus.mipi_csi2.flags);
0653
0654 asd = v4l2_async_nf_add_fwnode_remote(&csi2->notifier, ep,
0655 struct v4l2_async_subdev);
0656 fwnode_handle_put(ep);
0657
0658 if (IS_ERR(asd))
0659 return PTR_ERR(asd);
0660
0661 csi2->notifier.ops = &csi2_notify_ops;
0662
0663 ret = v4l2_async_subdev_nf_register(&csi2->sd, &csi2->notifier);
0664 if (ret)
0665 return ret;
0666
0667 return v4l2_async_register_subdev(&csi2->sd);
0668
0669 err_parse:
0670 fwnode_handle_put(ep);
0671 return ret;
0672 }
0673
0674 static int csi2_probe(struct platform_device *pdev)
0675 {
0676 struct csi2_dev *csi2;
0677 struct resource *res;
0678 int i, ret;
0679
0680 csi2 = devm_kzalloc(&pdev->dev, sizeof(*csi2), GFP_KERNEL);
0681 if (!csi2)
0682 return -ENOMEM;
0683
0684 csi2->dev = &pdev->dev;
0685
0686 v4l2_subdev_init(&csi2->sd, &csi2_subdev_ops);
0687 v4l2_set_subdevdata(&csi2->sd, &pdev->dev);
0688 csi2->sd.internal_ops = &csi2_internal_ops;
0689 csi2->sd.entity.ops = &csi2_entity_ops;
0690 csi2->sd.dev = &pdev->dev;
0691 csi2->sd.owner = THIS_MODULE;
0692 csi2->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
0693 strscpy(csi2->sd.name, DEVICE_NAME, sizeof(csi2->sd.name));
0694 csi2->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
0695 csi2->sd.grp_id = IMX_MEDIA_GRP_ID_CSI2;
0696
0697 for (i = 0; i < CSI2_NUM_PADS; i++) {
0698 csi2->pad[i].flags = (i == CSI2_SINK_PAD) ?
0699 MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
0700 }
0701
0702 ret = media_entity_pads_init(&csi2->sd.entity, CSI2_NUM_PADS,
0703 csi2->pad);
0704 if (ret)
0705 return ret;
0706
0707 csi2->pllref_clk = devm_clk_get(&pdev->dev, "ref");
0708 if (IS_ERR(csi2->pllref_clk)) {
0709 v4l2_err(&csi2->sd, "failed to get pll reference clock\n");
0710 return PTR_ERR(csi2->pllref_clk);
0711 }
0712
0713 csi2->dphy_clk = devm_clk_get(&pdev->dev, "dphy");
0714 if (IS_ERR(csi2->dphy_clk)) {
0715 v4l2_err(&csi2->sd, "failed to get dphy clock\n");
0716 return PTR_ERR(csi2->dphy_clk);
0717 }
0718
0719 csi2->pix_clk = devm_clk_get(&pdev->dev, "pix");
0720 if (IS_ERR(csi2->pix_clk)) {
0721 v4l2_err(&csi2->sd, "failed to get pixel clock\n");
0722 return PTR_ERR(csi2->pix_clk);
0723 }
0724
0725 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0726 if (!res) {
0727 v4l2_err(&csi2->sd, "failed to get platform resources\n");
0728 return -ENODEV;
0729 }
0730
0731 csi2->base = devm_ioremap(&pdev->dev, res->start, PAGE_SIZE);
0732 if (!csi2->base)
0733 return -ENOMEM;
0734
0735 mutex_init(&csi2->lock);
0736
0737 ret = clk_prepare_enable(csi2->pllref_clk);
0738 if (ret) {
0739 v4l2_err(&csi2->sd, "failed to enable pllref_clk\n");
0740 goto rmmutex;
0741 }
0742
0743 ret = clk_prepare_enable(csi2->dphy_clk);
0744 if (ret) {
0745 v4l2_err(&csi2->sd, "failed to enable dphy_clk\n");
0746 goto pllref_off;
0747 }
0748
0749 platform_set_drvdata(pdev, &csi2->sd);
0750
0751 ret = csi2_async_register(csi2);
0752 if (ret)
0753 goto clean_notifier;
0754
0755 return 0;
0756
0757 clean_notifier:
0758 v4l2_async_nf_unregister(&csi2->notifier);
0759 v4l2_async_nf_cleanup(&csi2->notifier);
0760 clk_disable_unprepare(csi2->dphy_clk);
0761 pllref_off:
0762 clk_disable_unprepare(csi2->pllref_clk);
0763 rmmutex:
0764 mutex_destroy(&csi2->lock);
0765 return ret;
0766 }
0767
0768 static int csi2_remove(struct platform_device *pdev)
0769 {
0770 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
0771 struct csi2_dev *csi2 = sd_to_dev(sd);
0772
0773 v4l2_async_nf_unregister(&csi2->notifier);
0774 v4l2_async_nf_cleanup(&csi2->notifier);
0775 v4l2_async_unregister_subdev(sd);
0776 clk_disable_unprepare(csi2->dphy_clk);
0777 clk_disable_unprepare(csi2->pllref_clk);
0778 mutex_destroy(&csi2->lock);
0779 media_entity_cleanup(&sd->entity);
0780
0781 return 0;
0782 }
0783
0784 static const struct of_device_id csi2_dt_ids[] = {
0785 { .compatible = "fsl,imx6-mipi-csi2", },
0786 { }
0787 };
0788 MODULE_DEVICE_TABLE(of, csi2_dt_ids);
0789
0790 static struct platform_driver csi2_driver = {
0791 .driver = {
0792 .name = DEVICE_NAME,
0793 .of_match_table = csi2_dt_ids,
0794 },
0795 .probe = csi2_probe,
0796 .remove = csi2_remove,
0797 };
0798
0799 module_platform_driver(csi2_driver);
0800
0801 MODULE_DESCRIPTION("i.MX5/6 MIPI CSI-2 Receiver driver");
0802 MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
0803 MODULE_LICENSE("GPL");