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