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 ret = v4l2_subdev_call(source_subdev, video, s_stream, 0); 224 goto disable; 225 } 226 227 /* Runtime PM */ 228 229 ret = pm_runtime_resume_and_get(dev); 230 if (ret < 0) 231 return ret; 232 233 /* Sensor pixel rate */ 234 235 ctrl = v4l2_ctrl_find(source_subdev->ctrl_handler, V4L2_CID_PIXEL_RATE); 236 if (!ctrl) { 237 dev_err(dev, "missing sensor pixel rate\n"); 238 ret = -ENODEV; 239 goto error_pm; 240 } 241 242 pixel_rate = (unsigned long)v4l2_ctrl_g_ctrl_int64(ctrl); 243 if (!pixel_rate) { 244 dev_err(dev, "missing (zero) sensor pixel rate\n"); 245 ret = -ENODEV; 246 goto error_pm; 247 } 248 249 /* D-PHY */ 250 251 if (!lanes_count) { 252 dev_err(dev, "missing (zero) MIPI CSI-2 lanes count\n"); 253 ret = -ENODEV; 254 goto error_pm; 255 } 256 257 format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code); 258 if (WARN_ON(!format)) { 259 ret = -ENODEV; 260 goto error_pm; 261 } 262 263 phy_mipi_dphy_get_default_config(pixel_rate, format->bpp, lanes_count, 264 dphy_cfg); 265 266 /* 267 * Note that our hardware is using DDR, which is not taken in account by 268 * phy_mipi_dphy_get_default_config when calculating hs_clk_rate from 269 * the pixel rate, lanes count and bpp. 270 * 271 * The resulting clock rate is basically the symbol rate over the whole 272 * link. The actual clock rate is calculated with division by two since 273 * DDR samples both on rising and falling edges. 274 */ 275 276 dev_dbg(dev, "A83T MIPI CSI-2 config:\n"); 277 dev_dbg(dev, "%ld pixels/s, %u bits/pixel, %u lanes, %lu Hz clock\n", 278 pixel_rate, format->bpp, lanes_count, 279 dphy_cfg->hs_clk_rate / 2); 280 281 ret = phy_reset(dphy); 282 if (ret) { 283 dev_err(dev, "failed to reset MIPI D-PHY\n"); 284 goto error_pm; 285 } 286 287 ret = phy_configure(dphy, &dphy_opts); 288 if (ret) { 289 dev_err(dev, "failed to configure MIPI D-PHY\n"); 290 goto error_pm; 291 } 292 293 /* Controller */ 294 295 sun8i_a83t_mipi_csi2_configure(csi2_dev); 296 sun8i_a83t_mipi_csi2_enable(csi2_dev); 297 298 /* D-PHY */ 299 300 ret = phy_power_on(dphy); 301 if (ret) { 302 dev_err(dev, "failed to power on MIPI D-PHY\n"); 303 goto error_pm; 304 } 305 306 /* Source */ 307 308 ret = v4l2_subdev_call(source_subdev, video, s_stream, 1); 309 if (ret && ret != -ENOIOCTLCMD) 310 goto disable; 311 312 return 0; 313 314 disable: 315 if (!on) 316 ret = 0; 317 phy_power_off(dphy); 318 sun8i_a83t_mipi_csi2_disable(csi2_dev); 319 320 error_pm: 321 pm_runtime_put(dev); 322 323 return ret; 324 } 325 326 static const struct v4l2_subdev_video_ops 327 sun8i_a83t_mipi_csi2_video_ops = { 328 .s_stream = sun8i_a83t_mipi_csi2_s_stream, 329 }; 330 331 static void 332 sun8i_a83t_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format) 333 { 334 if (!sun8i_a83t_mipi_csi2_format_find(mbus_format->code)) 335 mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code; 336 337 mbus_format->field = V4L2_FIELD_NONE; 338 mbus_format->colorspace = V4L2_COLORSPACE_RAW; 339 mbus_format->quantization = V4L2_QUANTIZATION_DEFAULT; 340 mbus_format->xfer_func = V4L2_XFER_FUNC_DEFAULT; 341 } 342 343 static int sun8i_a83t_mipi_csi2_init_cfg(struct v4l2_subdev *subdev, 344 struct v4l2_subdev_state *state) 345 { 346 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 347 v4l2_get_subdevdata(subdev); 348 unsigned int pad = SUN8I_A83T_MIPI_CSI2_PAD_SINK; 349 struct v4l2_mbus_framefmt *mbus_format = 350 v4l2_subdev_get_try_format(subdev, state, pad); 351 struct mutex *lock = &csi2_dev->bridge.lock; 352 353 mutex_lock(lock); 354 355 mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code; 356 mbus_format->width = 640; 357 mbus_format->height = 480; 358 359 sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format); 360 361 mutex_unlock(lock); 362 363 return 0; 364 } 365 366 static int 367 sun8i_a83t_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev, 368 struct v4l2_subdev_state *state, 369 struct v4l2_subdev_mbus_code_enum *code_enum) 370 { 371 if (code_enum->index >= ARRAY_SIZE(sun8i_a83t_mipi_csi2_formats)) 372 return -EINVAL; 373 374 code_enum->code = 375 sun8i_a83t_mipi_csi2_formats[code_enum->index].mbus_code; 376 377 return 0; 378 } 379 380 static int sun8i_a83t_mipi_csi2_get_fmt(struct v4l2_subdev *subdev, 381 struct v4l2_subdev_state *state, 382 struct v4l2_subdev_format *format) 383 { 384 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 385 v4l2_get_subdevdata(subdev); 386 struct v4l2_mbus_framefmt *mbus_format = &format->format; 387 struct mutex *lock = &csi2_dev->bridge.lock; 388 389 mutex_lock(lock); 390 391 if (format->which == V4L2_SUBDEV_FORMAT_TRY) 392 *mbus_format = *v4l2_subdev_get_try_format(subdev, state, 393 format->pad); 394 else 395 *mbus_format = csi2_dev->bridge.mbus_format; 396 397 mutex_unlock(lock); 398 399 return 0; 400 } 401 402 static int sun8i_a83t_mipi_csi2_set_fmt(struct v4l2_subdev *subdev, 403 struct v4l2_subdev_state *state, 404 struct v4l2_subdev_format *format) 405 { 406 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 407 v4l2_get_subdevdata(subdev); 408 struct v4l2_mbus_framefmt *mbus_format = &format->format; 409 struct mutex *lock = &csi2_dev->bridge.lock; 410 411 mutex_lock(lock); 412 413 sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format); 414 415 if (format->which == V4L2_SUBDEV_FORMAT_TRY) 416 *v4l2_subdev_get_try_format(subdev, state, format->pad) = 417 *mbus_format; 418 else 419 csi2_dev->bridge.mbus_format = *mbus_format; 420 421 mutex_unlock(lock); 422 423 return 0; 424 } 425 426 static const struct v4l2_subdev_pad_ops sun8i_a83t_mipi_csi2_pad_ops = { 427 .init_cfg = sun8i_a83t_mipi_csi2_init_cfg, 428 .enum_mbus_code = sun8i_a83t_mipi_csi2_enum_mbus_code, 429 .get_fmt = sun8i_a83t_mipi_csi2_get_fmt, 430 .set_fmt = sun8i_a83t_mipi_csi2_set_fmt, 431 }; 432 433 static const struct v4l2_subdev_ops sun8i_a83t_mipi_csi2_subdev_ops = { 434 .video = &sun8i_a83t_mipi_csi2_video_ops, 435 .pad = &sun8i_a83t_mipi_csi2_pad_ops, 436 }; 437 438 /* Media Entity */ 439 440 static const struct media_entity_operations sun8i_a83t_mipi_csi2_entity_ops = { 441 .link_validate = v4l2_subdev_link_validate, 442 }; 443 444 /* V4L2 Async */ 445 446 static int 447 sun8i_a83t_mipi_csi2_notifier_bound(struct v4l2_async_notifier *notifier, 448 struct v4l2_subdev *remote_subdev, 449 struct v4l2_async_subdev *async_subdev) 450 { 451 struct v4l2_subdev *subdev = notifier->sd; 452 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 453 container_of(notifier, struct sun8i_a83t_mipi_csi2_device, 454 bridge.notifier); 455 struct media_entity *sink_entity = &subdev->entity; 456 struct media_entity *source_entity = &remote_subdev->entity; 457 struct device *dev = csi2_dev->dev; 458 int sink_pad_index = 0; 459 int source_pad_index; 460 int ret; 461 462 ret = media_entity_get_fwnode_pad(source_entity, remote_subdev->fwnode, 463 MEDIA_PAD_FL_SOURCE); 464 if (ret < 0) { 465 dev_err(dev, "missing source pad in external entity %s\n", 466 source_entity->name); 467 return -EINVAL; 468 } 469 470 source_pad_index = ret; 471 472 dev_dbg(dev, "creating %s:%u -> %s:%u link\n", source_entity->name, 473 source_pad_index, sink_entity->name, sink_pad_index); 474 475 ret = media_create_pad_link(source_entity, source_pad_index, 476 sink_entity, sink_pad_index, 477 MEDIA_LNK_FL_ENABLED | 478 MEDIA_LNK_FL_IMMUTABLE); 479 if (ret) { 480 dev_err(dev, "failed to create %s:%u -> %s:%u link\n", 481 source_entity->name, source_pad_index, 482 sink_entity->name, sink_pad_index); 483 return ret; 484 } 485 486 csi2_dev->bridge.source_subdev = remote_subdev; 487 488 return 0; 489 } 490 491 static const struct v4l2_async_notifier_operations 492 sun8i_a83t_mipi_csi2_notifier_ops = { 493 .bound = sun8i_a83t_mipi_csi2_notifier_bound, 494 }; 495 496 /* Bridge */ 497 498 static int 499 sun8i_a83t_mipi_csi2_bridge_source_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 500 { 501 struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier; 502 struct v4l2_fwnode_endpoint *endpoint = &csi2_dev->bridge.endpoint; 503 struct v4l2_async_subdev *subdev_async; 504 struct fwnode_handle *handle; 505 struct device *dev = csi2_dev->dev; 506 int ret; 507 508 handle = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 509 FWNODE_GRAPH_ENDPOINT_NEXT); 510 if (!handle) 511 return -ENODEV; 512 513 endpoint->bus_type = V4L2_MBUS_CSI2_DPHY; 514 515 ret = v4l2_fwnode_endpoint_parse(handle, endpoint); 516 if (ret) 517 goto complete; 518 519 subdev_async = 520 v4l2_async_nf_add_fwnode_remote(notifier, handle, 521 struct v4l2_async_subdev); 522 if (IS_ERR(subdev_async)) 523 ret = PTR_ERR(subdev_async); 524 525 complete: 526 fwnode_handle_put(handle); 527 528 return ret; 529 } 530 531 static int 532 sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 533 { 534 struct sun8i_a83t_mipi_csi2_bridge *bridge = &csi2_dev->bridge; 535 struct v4l2_subdev *subdev = &bridge->subdev; 536 struct v4l2_async_notifier *notifier = &bridge->notifier; 537 struct media_pad *pads = bridge->pads; 538 struct device *dev = csi2_dev->dev; 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 pads[SUN8I_A83T_MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 562 563 ret = media_entity_pads_init(&subdev->entity, 564 SUN8I_A83T_MIPI_CSI2_PAD_COUNT, pads); 565 if (ret) 566 return ret; 567 568 /* V4L2 Async */ 569 570 v4l2_async_nf_init(notifier); 571 notifier->ops = &sun8i_a83t_mipi_csi2_notifier_ops; 572 573 ret = sun8i_a83t_mipi_csi2_bridge_source_setup(csi2_dev); 574 if (ret) 575 goto error_v4l2_notifier_cleanup; 576 577 ret = v4l2_async_subdev_nf_register(subdev, notifier); 578 if (ret < 0) 579 goto error_v4l2_notifier_cleanup; 580 581 /* V4L2 Subdev */ 582 583 ret = v4l2_async_register_subdev(subdev); 584 if (ret < 0) 585 goto error_v4l2_notifier_unregister; 586 587 return 0; 588 589 error_v4l2_notifier_unregister: 590 v4l2_async_nf_unregister(notifier); 591 592 error_v4l2_notifier_cleanup: 593 v4l2_async_nf_cleanup(notifier); 594 595 media_entity_cleanup(&subdev->entity); 596 597 return ret; 598 } 599 600 static void 601 sun8i_a83t_mipi_csi2_bridge_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 602 { 603 struct v4l2_subdev *subdev = &csi2_dev->bridge.subdev; 604 struct v4l2_async_notifier *notifier = &csi2_dev->bridge.notifier; 605 606 v4l2_async_unregister_subdev(subdev); 607 v4l2_async_nf_unregister(notifier); 608 v4l2_async_nf_cleanup(notifier); 609 media_entity_cleanup(&subdev->entity); 610 } 611 612 /* Platform */ 613 614 static int sun8i_a83t_mipi_csi2_suspend(struct device *dev) 615 { 616 struct sun8i_a83t_mipi_csi2_device *csi2_dev = dev_get_drvdata(dev); 617 618 clk_disable_unprepare(csi2_dev->clock_misc); 619 clk_disable_unprepare(csi2_dev->clock_mipi); 620 clk_disable_unprepare(csi2_dev->clock_mod); 621 reset_control_assert(csi2_dev->reset); 622 623 return 0; 624 } 625 626 static int sun8i_a83t_mipi_csi2_resume(struct device *dev) 627 { 628 struct sun8i_a83t_mipi_csi2_device *csi2_dev = dev_get_drvdata(dev); 629 int ret; 630 631 ret = reset_control_deassert(csi2_dev->reset); 632 if (ret) { 633 dev_err(dev, "failed to deassert reset\n"); 634 return ret; 635 } 636 637 ret = clk_prepare_enable(csi2_dev->clock_mod); 638 if (ret) { 639 dev_err(dev, "failed to enable module clock\n"); 640 goto error_reset; 641 } 642 643 ret = clk_prepare_enable(csi2_dev->clock_mipi); 644 if (ret) { 645 dev_err(dev, "failed to enable MIPI clock\n"); 646 goto error_clock_mod; 647 } 648 649 ret = clk_prepare_enable(csi2_dev->clock_misc); 650 if (ret) { 651 dev_err(dev, "failed to enable CSI misc clock\n"); 652 goto error_clock_mipi; 653 } 654 655 sun8i_a83t_mipi_csi2_init(csi2_dev); 656 657 return 0; 658 659 error_clock_mipi: 660 clk_disable_unprepare(csi2_dev->clock_mipi); 661 662 error_clock_mod: 663 clk_disable_unprepare(csi2_dev->clock_mod); 664 665 error_reset: 666 reset_control_assert(csi2_dev->reset); 667 668 return ret; 669 } 670 671 static const struct dev_pm_ops sun8i_a83t_mipi_csi2_pm_ops = { 672 .runtime_suspend = sun8i_a83t_mipi_csi2_suspend, 673 .runtime_resume = sun8i_a83t_mipi_csi2_resume, 674 }; 675 676 static const struct regmap_config sun8i_a83t_mipi_csi2_regmap_config = { 677 .reg_bits = 32, 678 .reg_stride = 4, 679 .val_bits = 32, 680 .max_register = 0x120, 681 }; 682 683 static int 684 sun8i_a83t_mipi_csi2_resources_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev, 685 struct platform_device *platform_dev) 686 { 687 struct device *dev = csi2_dev->dev; 688 void __iomem *io_base; 689 int ret; 690 691 /* Registers */ 692 693 io_base = devm_platform_ioremap_resource(platform_dev, 0); 694 if (IS_ERR(io_base)) 695 return PTR_ERR(io_base); 696 697 csi2_dev->regmap = 698 devm_regmap_init_mmio_clk(dev, "bus", io_base, 699 &sun8i_a83t_mipi_csi2_regmap_config); 700 if (IS_ERR(csi2_dev->regmap)) { 701 dev_err(dev, "failed to init register map\n"); 702 return PTR_ERR(csi2_dev->regmap); 703 } 704 705 /* Clocks */ 706 707 csi2_dev->clock_mod = devm_clk_get(dev, "mod"); 708 if (IS_ERR(csi2_dev->clock_mod)) { 709 dev_err(dev, "failed to acquire mod clock\n"); 710 return PTR_ERR(csi2_dev->clock_mod); 711 } 712 713 ret = clk_set_rate_exclusive(csi2_dev->clock_mod, 297000000); 714 if (ret) { 715 dev_err(dev, "failed to set mod clock rate\n"); 716 return ret; 717 } 718 719 csi2_dev->clock_mipi = devm_clk_get(dev, "mipi"); 720 if (IS_ERR(csi2_dev->clock_mipi)) { 721 dev_err(dev, "failed to acquire mipi clock\n"); 722 return PTR_ERR(csi2_dev->clock_mipi); 723 } 724 725 csi2_dev->clock_misc = devm_clk_get(dev, "misc"); 726 if (IS_ERR(csi2_dev->clock_misc)) { 727 dev_err(dev, "failed to acquire misc clock\n"); 728 return PTR_ERR(csi2_dev->clock_misc); 729 } 730 731 /* Reset */ 732 733 csi2_dev->reset = devm_reset_control_get_shared(dev, NULL); 734 if (IS_ERR(csi2_dev->reset)) { 735 dev_err(dev, "failed to get reset controller\n"); 736 return PTR_ERR(csi2_dev->reset); 737 } 738 739 /* D-PHY */ 740 741 ret = sun8i_a83t_dphy_register(csi2_dev); 742 if (ret) { 743 dev_err(dev, "failed to initialize MIPI D-PHY\n"); 744 return ret; 745 } 746 747 /* Runtime PM */ 748 749 pm_runtime_enable(dev); 750 751 return 0; 752 } 753 754 static void 755 sun8i_a83t_mipi_csi2_resources_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev) 756 { 757 pm_runtime_disable(csi2_dev->dev); 758 phy_exit(csi2_dev->dphy); 759 clk_rate_exclusive_put(csi2_dev->clock_mod); 760 } 761 762 static int sun8i_a83t_mipi_csi2_probe(struct platform_device *platform_dev) 763 { 764 struct sun8i_a83t_mipi_csi2_device *csi2_dev; 765 struct device *dev = &platform_dev->dev; 766 int ret; 767 768 csi2_dev = devm_kzalloc(dev, sizeof(*csi2_dev), GFP_KERNEL); 769 if (!csi2_dev) 770 return -ENOMEM; 771 772 csi2_dev->dev = dev; 773 platform_set_drvdata(platform_dev, csi2_dev); 774 775 ret = sun8i_a83t_mipi_csi2_resources_setup(csi2_dev, platform_dev); 776 if (ret) 777 return ret; 778 779 ret = sun8i_a83t_mipi_csi2_bridge_setup(csi2_dev); 780 if (ret) 781 return ret; 782 783 return 0; 784 } 785 786 static int sun8i_a83t_mipi_csi2_remove(struct platform_device *platform_dev) 787 { 788 struct sun8i_a83t_mipi_csi2_device *csi2_dev = 789 platform_get_drvdata(platform_dev); 790 791 sun8i_a83t_mipi_csi2_bridge_cleanup(csi2_dev); 792 sun8i_a83t_mipi_csi2_resources_cleanup(csi2_dev); 793 794 return 0; 795 } 796 797 static const struct of_device_id sun8i_a83t_mipi_csi2_of_match[] = { 798 { .compatible = "allwinner,sun8i-a83t-mipi-csi2" }, 799 {}, 800 }; 801 MODULE_DEVICE_TABLE(of, sun8i_a83t_mipi_csi2_of_match); 802 803 static struct platform_driver sun8i_a83t_mipi_csi2_platform_driver = { 804 .probe = sun8i_a83t_mipi_csi2_probe, 805 .remove = sun8i_a83t_mipi_csi2_remove, 806 .driver = { 807 .name = SUN8I_A83T_MIPI_CSI2_NAME, 808 .of_match_table = of_match_ptr(sun8i_a83t_mipi_csi2_of_match), 809 .pm = &sun8i_a83t_mipi_csi2_pm_ops, 810 }, 811 }; 812 module_platform_driver(sun8i_a83t_mipi_csi2_platform_driver); 813 814 MODULE_DESCRIPTION("Allwinner A83T MIPI CSI-2 and D-PHY Controller Driver"); 815 MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>"); 816 MODULE_LICENSE("GPL"); 817