1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com> 4 * Copyright 2020-2022 Bootlin 5 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com> 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/module.h> 10 #include <linux/of.h> 11 #include <linux/of_device.h> 12 #include <linux/phy/phy.h> 13 #include <linux/platform_device.h> 14 #include <linux/pm_runtime.h> 15 #include <linux/regmap.h> 16 #include <linux/reset.h> 17 #include <media/mipi-csi2.h> 18 #include <media/v4l2-ctrls.h> 19 #include <media/v4l2-device.h> 20 #include <media/v4l2-fwnode.h> 21 22 #include "sun8i_a83t_dphy.h" 23 #include "sun8i_a83t_mipi_csi2.h" 24 #include "sun8i_a83t_mipi_csi2_reg.h" 25 26 /* Format */ 27 28 static const struct sun8i_a83t_mipi_csi2_format 29 sun8i_a83t_mipi_csi2_formats[] = { 30 { 31 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, 32 .data_type = MIPI_CSI2_DT_RAW8, 33 .bpp = 8, 34 }, 35 { 36 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, 37 .data_type = MIPI_CSI2_DT_RAW8, 38 .bpp = 8, 39 }, 40 { 41 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, 42 .data_type = MIPI_CSI2_DT_RAW8, 43 .bpp = 8, 44 }, 45 { 46 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, 47 .data_type = MIPI_CSI2_DT_RAW8, 48 .bpp = 8, 49 }, 50 { 51 .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, 52 .data_type = MIPI_CSI2_DT_RAW10, 53 .bpp = 10, 54 }, 55 { 56 .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, 57 .data_type = MIPI_CSI2_DT_RAW10, 58 .bpp = 10, 59 }, 60 { 61 .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, 62 .data_type = MIPI_CSI2_DT_RAW10, 63 .bpp = 10, 64 }, 65 { 66 .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, 67 .data_type = MIPI_CSI2_DT_RAW10, 68 .bpp = 10, 69 }, 70 }; 71 72 static const struct sun8i_a83t_mipi_csi2_format * 73 sun8i_a83t_mipi_csi2_format_find(u32 mbus_code) 74 { 75 unsigned int i; 76 77 for (i = 0; i < ARRAY_SIZE(sun8i_a83t_mipi_csi2_formats); i++) 78 if (sun8i_a83t_mipi_csi2_formats[i].mbus_code == mbus_code) 79 return &sun8i_a83t_mipi_csi2_formats[i]; 80 81 return NULL; 82 } 83 84 /* Controller */ 85 86 static void 87 sun8i_a83t_mipi_csi2_init(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 88 { 89 struct regmap *regmap = csi2_dev->regmap; 90 91 /* 92 * The Allwinner BSP sets various magic values on a bunch of registers. 93 * This is apparently a necessary initialization process that will cause 94 * the capture to fail with unsolicited interrupts hitting if skipped. 95 * 96 * Most of the registers are set to proper values later, except for the 97 * two reserved registers. They are said to hold a "hardware lock" 98 * value, without more information available. 99 */ 100 101 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG, 0); 102 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG, 103 SUN8I_A83T_MIPI_CSI2_CTRL_INIT_VALUE); 104 105 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_REG, 0); 106 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_REG, 107 SUN8I_A83T_MIPI_CSI2_RX_PKT_NUM_INIT_VALUE); 108 109 regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG, 0); 110 regmap_write(regmap, SUN8I_A83T_DPHY_CTRL_REG, 111 SUN8I_A83T_DPHY_CTRL_INIT_VALUE); 112 113 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD1_REG, 0); 114 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD1_REG, 115 SUN8I_A83T_MIPI_CSI2_RSVD1_HW_LOCK_VALUE); 116 117 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD2_REG, 0); 118 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_RSVD2_REG, 119 SUN8I_A83T_MIPI_CSI2_RSVD2_HW_LOCK_VALUE); 120 121 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG, 0); 122 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG, 123 SUN8I_A83T_MIPI_CSI2_CFG_INIT_VALUE); 124 } 125 126 static void 127 sun8i_a83t_mipi_csi2_enable(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 128 { 129 struct regmap *regmap = csi2_dev->regmap; 130 131 regmap_update_bits(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG, 132 SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN, 133 SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN); 134 } 135 136 static void 137 sun8i_a83t_mipi_csi2_disable(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 138 { 139 struct regmap *regmap = csi2_dev->regmap; 140 141 regmap_update_bits(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG, 142 SUN8I_A83T_MIPI_CSI2_CFG_SYNC_EN, 0); 143 144 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG, 0); 145 } 146 147 static void 148 sun8i_a83t_mipi_csi2_configure(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 149 { 150 struct regmap *regmap = csi2_dev->regmap; 151 unsigned int lanes_count = 152 csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes; 153 struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format; 154 const struct sun8i_a83t_mipi_csi2_format *format; 155 struct device *dev = csi2_dev->dev; 156 u32 version = 0; 157 158 format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code); 159 if (WARN_ON(!format)) 160 return; 161 162 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CTRL_REG, 163 SUN8I_A83T_MIPI_CSI2_CTRL_RESET_N); 164 165 regmap_read(regmap, SUN8I_A83T_MIPI_CSI2_VERSION_REG, &version); 166 167 dev_dbg(dev, "A83T MIPI CSI-2 version: %04x\n", version); 168 169 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_CFG_REG, 170 SUN8I_A83T_MIPI_CSI2_CFG_UNPKT_EN | 171 SUN8I_A83T_MIPI_CSI2_CFG_SYNC_DLY_CYCLE(8) | 172 SUN8I_A83T_MIPI_CSI2_CFG_N_CHANNEL(1) | 173 SUN8I_A83T_MIPI_CSI2_CFG_N_LANE(lanes_count)); 174 175 /* 176 * Only a single virtual channel (index 0) is currently supported. 177 * While the registers do mention multiple physical channels being 178 * available (which can be configured to match a specific virtual 179 * channel or data type), it's unclear whether channels > 0 are actually 180 * connected and available and the reference source code only makes use 181 * of channel 0. 182 * 183 * Using extra channels would also require matching channels to be 184 * available on the CSI (and ISP) side, which is also unsure although 185 * some CSI implementations are said to support multiple channels for 186 * BT656 time-sharing. 187 * 188 * We still configure virtual channel numbers to ensure that virtual 189 * channel 0 only goes to channel 0. 190 */ 191 192 regmap_write(regmap, SUN8I_A83T_MIPI_CSI2_VCDT0_REG, 193 SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(3, 3) | 194 SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(2, 2) | 195 SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(1, 1) | 196 SUN8I_A83T_MIPI_CSI2_VCDT0_CH_VC(0, 0) | 197 SUN8I_A83T_MIPI_CSI2_VCDT0_CH_DT(0, format->data_type)); 198 } 199 200 /* V4L2 Subdev */ 201 202 static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on) 203 { 204 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 205 v4l2_get_subdevdata(subdev); 206 struct v4l2_subdev *source_subdev = csi2_dev->bridge.source_subdev; 207 union phy_configure_opts dphy_opts = { 0 }; 208 struct phy_configure_opts_mipi_dphy *dphy_cfg = &dphy_opts.mipi_dphy; 209 struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format; 210 const struct sun8i_a83t_mipi_csi2_format *format; 211 struct phy *dphy = csi2_dev->dphy; 212 struct device *dev = csi2_dev->dev; 213 struct v4l2_ctrl *ctrl; 214 unsigned int lanes_count = 215 csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes; 216 unsigned long pixel_rate; 217 int ret; 218 219 if (!source_subdev) 220 return -ENODEV; 221 222 if (!on) { 223 v4l2_subdev_call(source_subdev, video, s_stream, 0); 224 ret = 0; 225 goto disable; 226 } 227 228 /* Runtime PM */ 229 230 ret = pm_runtime_resume_and_get(dev); 231 if (ret < 0) 232 return ret; 233 234 /* Sensor pixel rate */ 235 236 ctrl = v4l2_ctrl_find(source_subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); 237 if (!ctrl) { 238 dev_err(dev, "missing sensor pixel rate\n"); 239 ret = -ENODEV; 240 goto error_pm; 241 } 242 243 pixel_rate = (unsigned long)v4l2_ctrl_g_ctrl_int64(ctrl); 244 if (!pixel_rate) { 245 dev_err(dev, "missing (zero) sensor pixel rate\n"); 246 ret = -ENODEV; 247 goto error_pm; 248 } 249 250 /* D-PHY */ 251 252 if (!lanes_count) { 253 dev_err(dev, "missing (zero) MIPI CSI-2 lanes count\n"); 254 ret = -ENODEV; 255 goto error_pm; 256 } 257 258 format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code); 259 if (WARN_ON(!format)) { 260 ret = -ENODEV; 261 goto error_pm; 262 } 263 264 phy_mipi_dphy_get_default_config(pixel_rate, format->bpp, lanes_count, 265 dphy_cfg); 266 267 /* 268 * Note that our hardware is using DDR, which is not taken in account by 269 * phy_mipi_dphy_get_default_config when calculating hs_clk_rate from 270 * the pixel rate, lanes count and bpp. 271 * 272 * The resulting clock rate is basically the symbol rate over the whole 273 * link. The actual clock rate is calculated with division by two since 274 * DDR samples both on rising and falling edges. 275 */ 276 277 dev_dbg(dev, "A83T MIPI CSI-2 config:\n"); 278 dev_dbg(dev, "%ld pixels/s, %u bits/pixel, %u lanes, %lu Hz clock\n", 279 pixel_rate, format->bpp, lanes_count, 280 dphy_cfg->hs_clk_rate / 2); 281 282 ret = phy_reset(dphy); 283 if (ret) { 284 dev_err(dev, "failed to reset MIPI D-PHY\n"); 285 goto error_pm; 286 } 287 288 ret = phy_configure(dphy, &dphy_opts); 289 if (ret) { 290 dev_err(dev, "failed to configure MIPI D-PHY\n"); 291 goto error_pm; 292 } 293 294 /* Controller */ 295 296 sun8i_a83t_mipi_csi2_configure(csi2_dev); 297 sun8i_a83t_mipi_csi2_enable(csi2_dev); 298 299 /* D-PHY */ 300 301 ret = phy_power_on(dphy); 302 if (ret) { 303 dev_err(dev, "failed to power on MIPI D-PHY\n"); 304 goto error_pm; 305 } 306 307 /* Source */ 308 309 ret = v4l2_subdev_call(source_subdev, video, s_stream, 1); 310 if (ret && ret != -ENOIOCTLCMD) 311 goto disable; 312 313 return 0; 314 315 disable: 316 phy_power_off(dphy); 317 sun8i_a83t_mipi_csi2_disable(csi2_dev); 318 319 error_pm: 320 pm_runtime_put(dev); 321 322 return ret; 323 } 324 325 static const struct v4l2_subdev_video_ops 326 sun8i_a83t_mipi_csi2_video_ops = { 327 .s_stream = sun8i_a83t_mipi_csi2_s_stream, 328 }; 329 330 static void 331 sun8i_a83t_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format) 332 { 333 if (!sun8i_a83t_mipi_csi2_format_find(mbus_format->code)) 334 mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code; 335 336 mbus_format->field = V4L2_FIELD_NONE; 337 mbus_format->colorspace = V4L2_COLORSPACE_RAW; 338 mbus_format->quantization = V4L2_QUANTIZATION_DEFAULT; 339 mbus_format->xfer_func = V4L2_XFER_FUNC_DEFAULT; 340 } 341 342 static int sun8i_a83t_mipi_csi2_init_cfg(struct v4l2_subdev *subdev, 343 struct v4l2_subdev_state *state) 344 { 345 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 346 v4l2_get_subdevdata(subdev); 347 unsigned int pad = SUN8I_A83T_MIPI_CSI2_PAD_SINK; 348 struct v4l2_mbus_framefmt *mbus_format = 349 v4l2_subdev_get_try_format(subdev, state, pad); 350 struct mutex *lock = &csi2_dev->bridge.lock; 351 352 mutex_lock(lock); 353 354 mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code; 355 mbus_format->width = 640; 356 mbus_format->height = 480; 357 358 sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format); 359 360 mutex_unlock(lock); 361 362 return 0; 363 } 364 365 static int 366 sun8i_a83t_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev, 367 struct v4l2_subdev_state *state, 368 struct v4l2_subdev_mbus_code_enum *code_enum) 369 { 370 if (code_enum->index >= ARRAY_SIZE(sun8i_a83t_mipi_csi2_formats)) 371 return -EINVAL; 372 373 code_enum->code = 374 sun8i_a83t_mipi_csi2_formats[code_enum->index].mbus_code; 375 376 return 0; 377 } 378 379 static int sun8i_a83t_mipi_csi2_get_fmt(struct v4l2_subdev *subdev, 380 struct v4l2_subdev_state *state, 381 struct v4l2_subdev_format *format) 382 { 383 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 384 v4l2_get_subdevdata(subdev); 385 struct v4l2_mbus_framefmt *mbus_format = &format->format; 386 struct mutex *lock = &csi2_dev->bridge.lock; 387 388 mutex_lock(lock); 389 390 if (format->which == V4L2_SUBDEV_FORMAT_TRY) 391 *mbus_format = *v4l2_subdev_get_try_format(subdev, state, 392 format->pad); 393 else 394 *mbus_format = csi2_dev->bridge.mbus_format; 395 396 mutex_unlock(lock); 397 398 return 0; 399 } 400 401 static int sun8i_a83t_mipi_csi2_set_fmt(struct v4l2_subdev *subdev, 402 struct v4l2_subdev_state *state, 403 struct v4l2_subdev_format *format) 404 { 405 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 406 v4l2_get_subdevdata(subdev); 407 struct v4l2_mbus_framefmt *mbus_format = &format->format; 408 struct mutex *lock = &csi2_dev->bridge.lock; 409 410 mutex_lock(lock); 411 412 sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format); 413 414 if (format->which == V4L2_SUBDEV_FORMAT_TRY) 415 *v4l2_subdev_get_try_format(subdev, state, format->pad) = 416 *mbus_format; 417 else 418 csi2_dev->bridge.mbus_format = *mbus_format; 419 420 mutex_unlock(lock); 421 422 return 0; 423 } 424 425 static const struct v4l2_subdev_pad_ops sun8i_a83t_mipi_csi2_pad_ops = { 426 .init_cfg = sun8i_a83t_mipi_csi2_init_cfg, 427 .enum_mbus_code = sun8i_a83t_mipi_csi2_enum_mbus_code, 428 .get_fmt = sun8i_a83t_mipi_csi2_get_fmt, 429 .set_fmt = sun8i_a83t_mipi_csi2_set_fmt, 430 }; 431 432 static const struct v4l2_subdev_ops sun8i_a83t_mipi_csi2_subdev_ops = { 433 .video = &sun8i_a83t_mipi_csi2_video_ops, 434 .pad = &sun8i_a83t_mipi_csi2_pad_ops, 435 }; 436 437 /* Media Entity */ 438 439 static const struct media_entity_operations sun8i_a83t_mipi_csi2_entity_ops = { 440 .link_validate = v4l2_subdev_link_validate, 441 }; 442 443 /* V4L2 Async */ 444 445 static int 446 sun8i_a83t_mipi_csi2_notifier_bound(struct v4l2_async_notifier *notifier, 447 struct v4l2_subdev *remote_subdev, 448 struct v4l2_async_subdev *async_subdev) 449 { 450 struct v4l2_subdev *subdev = notifier->sd; 451 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 452 container_of(notifier, struct sun8i_a83t_mipi_csi2_device, 453 bridge.notifier); 454 struct media_entity *sink_entity = &subdev->entity; 455 struct media_entity *source_entity = &remote_subdev->entity; 456 struct device *dev = csi2_dev->dev; 457 int sink_pad_index = 0; 458 int source_pad_index; 459 int ret; 460 461 ret = media_entity_get_fwnode_pad(source_entity, remote_subdev->fwnode, 462 MEDIA_PAD_FL_SOURCE); 463 if (ret < 0) { 464 dev_err(dev, "missing source pad in external entity %s\n", 465 source_entity->name); 466 return -EINVAL; 467 } 468 469 source_pad_index = ret; 470 471 dev_dbg(dev, "creating %s:%u -> %s:%u link\n", source_entity->name, 472 source_pad_index, sink_entity->name, sink_pad_index); 473 474 ret = media_create_pad_link(source_entity, source_pad_index, 475 sink_entity, sink_pad_index, 476 MEDIA_LNK_FL_ENABLED | 477 MEDIA_LNK_FL_IMMUTABLE); 478 if (ret) { 479 dev_err(dev, "failed to create %s:%u -> %s:%u link\n", 480 source_entity->name, source_pad_index, 481 sink_entity->name, sink_pad_index); 482 return ret; 483 } 484 485 csi2_dev->bridge.source_subdev = remote_subdev; 486 487 return 0; 488 } 489 490 static const struct v4l2_async_notifier_operations 491 sun8i_a83t_mipi_csi2_notifier_ops = { 492 .bound = sun8i_a83t_mipi_csi2_notifier_bound, 493 }; 494 495 /* Bridge */ 496 497 static int 498 sun8i_a83t_mipi_csi2_bridge_source_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 499 { 500 struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier; 501 struct v4l2_fwnode_endpoint *endpoint = &csi2_dev->bridge.endpoint; 502 struct v4l2_async_subdev *subdev_async; 503 struct fwnode_handle *handle; 504 struct device *dev = csi2_dev->dev; 505 int ret; 506 507 handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 508 FWNODE_GRAPH_ENDPOINT_NEXT); 509 if (!handle) 510 return -ENODEV; 511 512 endpoint->bus_type = V4L2_MBUS_CSI2_DPHY; 513 514 ret = v4l2_fwnode_endpoint_parse(handle, endpoint); 515 if (ret) 516 goto complete; 517 518 subdev_async = 519 v4l2_async_nf_add_fwnode_remote(notifier, handle, 520 struct v4l2_async_subdev); 521 if (IS_ERR(subdev_async)) 522 ret = PTR_ERR(subdev_async); 523 524 complete: 525 fwnode_handle_put(handle); 526 527 return ret; 528 } 529 530 static int 531 sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 532 { 533 struct sun8i_a83t_mipi_csi2_bridge *bridge = &csi2_dev->bridge; 534 struct v4l2_subdev *subdev = &bridge->subdev; 535 struct v4l2_async_notifier *notifier = &bridge->notifier; 536 struct media_pad *pads = bridge->pads; 537 struct device *dev = csi2_dev->dev; 538 bool notifier_registered = false; 539 int ret; 540 541 mutex_init(&bridge->lock); 542 543 /* V4L2 Subdev */ 544 545 v4l2_subdev_init(subdev, &sun8i_a83t_mipi_csi2_subdev_ops); 546 strscpy(subdev->name, SUN8I_A83T_MIPI_CSI2_NAME, sizeof(subdev->name)); 547 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 548 subdev->owner = THIS_MODULE; 549 subdev->dev = dev; 550 551 v4l2_set_subdevdata(subdev, csi2_dev); 552 553 /* Media Entity */ 554 555 subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 556 subdev->entity.ops = &sun8i_a83t_mipi_csi2_entity_ops; 557 558 /* Media Pads */ 559 560 pads[SUN8I_A83T_MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK | 561 MEDIA_PAD_FL_MUST_CONNECT; 562 pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE | 563 MEDIA_PAD_FL_MUST_CONNECT; 564 565 ret = media_entity_pads_init(&subdev->entity, 566 SUN8I_A83T_MIPI_CSI2_PAD_COUNT, pads); 567 if (ret) 568 return ret; 569 570 /* V4L2 Async */ 571 572 v4l2_async_nf_init(notifier); 573 notifier->ops = &sun8i_a83t_mipi_csi2_notifier_ops; 574 575 ret = sun8i_a83t_mipi_csi2_bridge_source_setup(csi2_dev); 576 if (ret && ret != -ENODEV) 577 goto error_v4l2_notifier_cleanup; 578 579 /* Only register the notifier when a sensor is connected. */ 580 if (ret != -ENODEV) { 581 ret = v4l2_async_subdev_nf_register(subdev, notifier); 582 if (ret < 0) 583 goto error_v4l2_notifier_cleanup; 584 585 notifier_registered = true; 586 } 587 588 /* V4L2 Subdev */ 589 590 ret = v4l2_async_register_subdev(subdev); 591 if (ret < 0) 592 goto error_v4l2_notifier_unregister; 593 594 return 0; 595 596 error_v4l2_notifier_unregister: 597 if (notifier_registered) 598 v4l2_async_nf_unregister(notifier); 599 600 error_v4l2_notifier_cleanup: 601 v4l2_async_nf_cleanup(notifier); 602 603 media_entity_cleanup(&subdev->entity); 604 605 return ret; 606 } 607 608 static void 609 sun8i_a83t_mipi_csi2_bridge_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 610 { 611 struct v4l2_subdev *subdev = &csi2_dev->bridge.subdev; 612 struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier; 613 614 v4l2_async_unregister_subdev(subdev); 615 v4l2_async_nf_unregister(notifier); 616 v4l2_async_nf_cleanup(notifier); 617 media_entity_cleanup(&subdev->entity); 618 } 619 620 /* Platform */ 621 622 static int sun8i_a83t_mipi_csi2_suspend(struct device *dev) 623 { 624 struct sun8i_a83t_mipi_csi2_device *csi2_dev = dev_get_drvdata(dev); 625 626 clk_disable_unprepare(csi2_dev->clock_misc); 627 clk_disable_unprepare(csi2_dev->clock_mipi); 628 clk_disable_unprepare(csi2_dev->clock_mod); 629 reset_control_assert(csi2_dev->reset); 630 631 return 0; 632 } 633 634 static int sun8i_a83t_mipi_csi2_resume(struct device *dev) 635 { 636 struct sun8i_a83t_mipi_csi2_device *csi2_dev = dev_get_drvdata(dev); 637 int ret; 638 639 ret = reset_control_deassert(csi2_dev->reset); 640 if (ret) { 641 dev_err(dev, "failed to deassert reset\n"); 642 return ret; 643 } 644 645 ret = clk_prepare_enable(csi2_dev->clock_mod); 646 if (ret) { 647 dev_err(dev, "failed to enable module clock\n"); 648 goto error_reset; 649 } 650 651 ret = clk_prepare_enable(csi2_dev->clock_mipi); 652 if (ret) { 653 dev_err(dev, "failed to enable MIPI clock\n"); 654 goto error_clock_mod; 655 } 656 657 ret = clk_prepare_enable(csi2_dev->clock_misc); 658 if (ret) { 659 dev_err(dev, "failed to enable CSI misc clock\n"); 660 goto error_clock_mipi; 661 } 662 663 sun8i_a83t_mipi_csi2_init(csi2_dev); 664 665 return 0; 666 667 error_clock_mipi: 668 clk_disable_unprepare(csi2_dev->clock_mipi); 669 670 error_clock_mod: 671 clk_disable_unprepare(csi2_dev->clock_mod); 672 673 error_reset: 674 reset_control_assert(csi2_dev->reset); 675 676 return ret; 677 } 678 679 static const struct dev_pm_ops sun8i_a83t_mipi_csi2_pm_ops = { 680 .runtime_suspend = sun8i_a83t_mipi_csi2_suspend, 681 .runtime_resume = sun8i_a83t_mipi_csi2_resume, 682 }; 683 684 static const struct regmap_config sun8i_a83t_mipi_csi2_regmap_config = { 685 .reg_bits = 32, 686 .reg_stride = 4, 687 .val_bits = 32, 688 .max_register = 0x120, 689 }; 690 691 static int 692 sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev, 693 struct platform_device *platform_dev) 694 { 695 struct device *dev = csi2_dev->dev; 696 void __iomem *io_base; 697 int ret; 698 699 /* Registers */ 700 701 io_base = devm_platform_ioremap_resource(platform_dev, 0); 702 if (IS_ERR(io_base)) 703 return PTR_ERR(io_base); 704 705 csi2_dev->regmap = 706 devm_regmap_init_mmio_clk(dev, "bus", io_base, 707 &sun8i_a83t_mipi_csi2_regmap_config); 708 if (IS_ERR(csi2_dev->regmap)) { 709 dev_err(dev, "failed to init register map\n"); 710 return PTR_ERR(csi2_dev->regmap); 711 } 712 713 /* Clocks */ 714 715 csi2_dev->clock_mod = devm_clk_get(dev, "mod"); 716 if (IS_ERR(csi2_dev->clock_mod)) { 717 dev_err(dev, "failed to acquire mod clock\n"); 718 return PTR_ERR(csi2_dev->clock_mod); 719 } 720 721 ret = clk_set_rate_exclusive(csi2_dev->clock_mod, 297000000); 722 if (ret) { 723 dev_err(dev, "failed to set mod clock rate\n"); 724 return ret; 725 } 726 727 csi2_dev->clock_mipi = devm_clk_get(dev, "mipi"); 728 if (IS_ERR(csi2_dev->clock_mipi)) { 729 dev_err(dev, "failed to acquire mipi clock\n"); 730 ret = PTR_ERR(csi2_dev->clock_mipi); 731 goto error_clock_rate_exclusive; 732 } 733 734 csi2_dev->clock_misc = devm_clk_get(dev, "misc"); 735 if (IS_ERR(csi2_dev->clock_misc)) { 736 dev_err(dev, "failed to acquire misc clock\n"); 737 ret = PTR_ERR(csi2_dev->clock_misc); 738 goto error_clock_rate_exclusive; 739 } 740 741 /* Reset */ 742 743 csi2_dev->reset = devm_reset_control_get_shared(dev, NULL); 744 if (IS_ERR(csi2_dev->reset)) { 745 dev_err(dev, "failed to get reset controller\n"); 746 ret = PTR_ERR(csi2_dev->reset); 747 goto error_clock_rate_exclusive; 748 } 749 750 /* D-PHY */ 751 752 ret = sun8i_a83t_dphy_register(csi2_dev); 753 if (ret) { 754 dev_err(dev, "failed to initialize MIPI D-PHY\n"); 755 goto error_clock_rate_exclusive; 756 } 757 758 /* Runtime PM */ 759 760 pm_runtime_enable(dev); 761 762 return 0; 763 764 error_clock_rate_exclusive: 765 clk_rate_exclusive_put(csi2_dev->clock_mod); 766 767 return ret; 768 } 769 770 static void 771 sun8i_a83t_mipi_csi2_resources_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 772 { 773 pm_runtime_disable(csi2_dev->dev); 774 phy_exit(csi2_dev->dphy); 775 clk_rate_exclusive_put(csi2_dev->clock_mod); 776 } 777 778 static int sun8i_a83t_mipi_csi2_probe(struct platform_device *platform_dev) 779 { 780 struct sun8i_a83t_mipi_csi2_device *csi2_dev; 781 struct device *dev = &platform_dev->dev; 782 int ret; 783 784 csi2_dev = devm_kzalloc(dev, sizeof(*csi2_dev), GFP_KERNEL); 785 if (!csi2_dev) 786 return -ENOMEM; 787 788 csi2_dev->dev = dev; 789 platform_set_drvdata(platform_dev, csi2_dev); 790 791 ret = sun8i_a83t_mipi_csi2_resources_setup(csi2_dev, platform_dev); 792 if (ret) 793 return ret; 794 795 ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev); 796 if (ret) 797 goto error_resources; 798 799 return 0; 800 801 error_resources: 802 sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev); 803 804 return ret; 805 } 806 807 static void sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev) 808 { 809 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 810 platform_get_drvdata(platform_dev); 811 812 sun8i_a83t_mipi_csi2_bridge_cleanup(csi2_dev); 813 sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev); 814 } 815 816 static const struct of_device_id sun8i_a83t_mipi_csi2_of_match[] = { 817 { .compatible = "allwinner,sun8i-a83t-mipi-csi2" }, 818 {}, 819 }; 820 MODULE_DEVICE_TABLE(of, sun8i_a83t_mipi_csi2_of_match); 821 822 static struct platform_driver sun8i_a83t_mipi_csi2_platform_driver = { 823 .probe = sun8i_a83t_mipi_csi2_probe, 824 .remove_new = sun8i_a83t_mipi_csi2_remove, 825 .driver = { 826 .name = SUN8I_A83T_MIPI_CSI2_NAME, 827 .of_match_table = of_match_ptr(sun8i_a83t_mipi_csi2_of_match), 828 .pm = &sun8i_a83t_mipi_csi2_pm_ops, 829 }, 830 }; 831 module_platform_driver(sun8i_a83t_mipi_csi2_platform_driver); 832 833 MODULE_DESCRIPTION("Allwinner A83T MIPI CSI-2 and D-PHY Controller Driver"); 834 MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>"); 835 MODULE_LICENSE("GPL"); 836