1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * TI Camera Access Layer (CAL) - Driver 4 * 5 * Copyright (c) 2015-2020 Texas Instruments Inc. 6 * 7 * Authors: 8 * Benoit Parrot <bparrot@ti.com> 9 * Laurent Pinchart <laurent.pinchart@ideasonboard.com> 10 */ 11 12 #include <linux/clk.h> 13 #include <linux/interrupt.h> 14 #include <linux/mfd/syscon.h> 15 #include <linux/module.h> 16 #include <linux/of_device.h> 17 #include <linux/platform_device.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/regmap.h> 20 #include <linux/slab.h> 21 #include <linux/videodev2.h> 22 23 #include <media/media-device.h> 24 #include <media/v4l2-async.h> 25 #include <media/v4l2-common.h> 26 #include <media/v4l2-device.h> 27 #include <media/videobuf2-core.h> 28 #include <media/videobuf2-dma-contig.h> 29 30 #include "cal.h" 31 #include "cal_regs.h" 32 33 MODULE_DESCRIPTION("TI CAL driver"); 34 MODULE_AUTHOR("Benoit Parrot, <bparrot@ti.com>"); 35 MODULE_LICENSE("GPL v2"); 36 MODULE_VERSION("0.1.0"); 37 38 int cal_video_nr = -1; 39 module_param_named(video_nr, cal_video_nr, uint, 0644); 40 MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect"); 41 42 unsigned int cal_debug; 43 module_param_named(debug, cal_debug, uint, 0644); 44 MODULE_PARM_DESC(debug, "activates debug info"); 45 46 #ifdef CONFIG_VIDEO_TI_CAL_MC 47 #define CAL_MC_API_DEFAULT 1 48 #else 49 #define CAL_MC_API_DEFAULT 0 50 #endif 51 52 bool cal_mc_api = CAL_MC_API_DEFAULT; 53 module_param_named(mc_api, cal_mc_api, bool, 0444); 54 MODULE_PARM_DESC(mc_api, "activates the MC API"); 55 56 /* ------------------------------------------------------------------ 57 * Format Handling 58 * ------------------------------------------------------------------ 59 */ 60 61 const struct cal_format_info cal_formats[] = { 62 { 63 .fourcc = V4L2_PIX_FMT_YUYV, 64 .code = MEDIA_BUS_FMT_YUYV8_2X8, 65 .bpp = 16, 66 }, { 67 .fourcc = V4L2_PIX_FMT_UYVY, 68 .code = MEDIA_BUS_FMT_UYVY8_2X8, 69 .bpp = 16, 70 }, { 71 .fourcc = V4L2_PIX_FMT_YVYU, 72 .code = MEDIA_BUS_FMT_YVYU8_2X8, 73 .bpp = 16, 74 }, { 75 .fourcc = V4L2_PIX_FMT_VYUY, 76 .code = MEDIA_BUS_FMT_VYUY8_2X8, 77 .bpp = 16, 78 }, { 79 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 80 .code = MEDIA_BUS_FMT_RGB565_2X8_LE, 81 .bpp = 16, 82 }, { 83 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ 84 .code = MEDIA_BUS_FMT_RGB565_2X8_BE, 85 .bpp = 16, 86 }, { 87 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ 88 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, 89 .bpp = 16, 90 }, { 91 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ 92 .code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, 93 .bpp = 16, 94 }, { 95 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ 96 .code = MEDIA_BUS_FMT_RGB888_2X12_LE, 97 .bpp = 24, 98 }, { 99 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ 100 .code = MEDIA_BUS_FMT_RGB888_2X12_BE, 101 .bpp = 24, 102 }, { 103 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ 104 .code = MEDIA_BUS_FMT_ARGB8888_1X32, 105 .bpp = 32, 106 }, { 107 .fourcc = V4L2_PIX_FMT_SBGGR8, 108 .code = MEDIA_BUS_FMT_SBGGR8_1X8, 109 .bpp = 8, 110 }, { 111 .fourcc = V4L2_PIX_FMT_SGBRG8, 112 .code = MEDIA_BUS_FMT_SGBRG8_1X8, 113 .bpp = 8, 114 }, { 115 .fourcc = V4L2_PIX_FMT_SGRBG8, 116 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 117 .bpp = 8, 118 }, { 119 .fourcc = V4L2_PIX_FMT_SRGGB8, 120 .code = MEDIA_BUS_FMT_SRGGB8_1X8, 121 .bpp = 8, 122 }, { 123 .fourcc = V4L2_PIX_FMT_SBGGR10, 124 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 125 .bpp = 10, 126 }, { 127 .fourcc = V4L2_PIX_FMT_SGBRG10, 128 .code = MEDIA_BUS_FMT_SGBRG10_1X10, 129 .bpp = 10, 130 }, { 131 .fourcc = V4L2_PIX_FMT_SGRBG10, 132 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 133 .bpp = 10, 134 }, { 135 .fourcc = V4L2_PIX_FMT_SRGGB10, 136 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 137 .bpp = 10, 138 }, { 139 .fourcc = V4L2_PIX_FMT_SBGGR12, 140 .code = MEDIA_BUS_FMT_SBGGR12_1X12, 141 .bpp = 12, 142 }, { 143 .fourcc = V4L2_PIX_FMT_SGBRG12, 144 .code = MEDIA_BUS_FMT_SGBRG12_1X12, 145 .bpp = 12, 146 }, { 147 .fourcc = V4L2_PIX_FMT_SGRBG12, 148 .code = MEDIA_BUS_FMT_SGRBG12_1X12, 149 .bpp = 12, 150 }, { 151 .fourcc = V4L2_PIX_FMT_SRGGB12, 152 .code = MEDIA_BUS_FMT_SRGGB12_1X12, 153 .bpp = 12, 154 }, 155 }; 156 157 const unsigned int cal_num_formats = ARRAY_SIZE(cal_formats); 158 159 const struct cal_format_info *cal_format_by_fourcc(u32 fourcc) 160 { 161 unsigned int i; 162 163 for (i = 0; i < ARRAY_SIZE(cal_formats); ++i) { 164 if (cal_formats[i].fourcc == fourcc) 165 return &cal_formats[i]; 166 } 167 168 return NULL; 169 } 170 171 const struct cal_format_info *cal_format_by_code(u32 code) 172 { 173 unsigned int i; 174 175 for (i = 0; i < ARRAY_SIZE(cal_formats); ++i) { 176 if (cal_formats[i].code == code) 177 return &cal_formats[i]; 178 } 179 180 return NULL; 181 } 182 183 /* ------------------------------------------------------------------ 184 * Platform Data 185 * ------------------------------------------------------------------ 186 */ 187 188 static const struct cal_camerarx_data dra72x_cal_camerarx[] = { 189 { 190 .fields = { 191 [F_CTRLCLKEN] = { 10, 10 }, 192 [F_CAMMODE] = { 11, 12 }, 193 [F_LANEENABLE] = { 13, 16 }, 194 [F_CSI_MODE] = { 17, 17 }, 195 }, 196 .num_lanes = 4, 197 }, 198 { 199 .fields = { 200 [F_CTRLCLKEN] = { 0, 0 }, 201 [F_CAMMODE] = { 1, 2 }, 202 [F_LANEENABLE] = { 3, 4 }, 203 [F_CSI_MODE] = { 5, 5 }, 204 }, 205 .num_lanes = 2, 206 }, 207 }; 208 209 static const struct cal_data dra72x_cal_data = { 210 .camerarx = dra72x_cal_camerarx, 211 .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx), 212 }; 213 214 static const struct cal_data dra72x_es1_cal_data = { 215 .camerarx = dra72x_cal_camerarx, 216 .num_csi2_phy = ARRAY_SIZE(dra72x_cal_camerarx), 217 .flags = DRA72_CAL_PRE_ES2_LDO_DISABLE, 218 }; 219 220 static const struct cal_camerarx_data dra76x_cal_csi_phy[] = { 221 { 222 .fields = { 223 [F_CTRLCLKEN] = { 8, 8 }, 224 [F_CAMMODE] = { 9, 10 }, 225 [F_CSI_MODE] = { 11, 11 }, 226 [F_LANEENABLE] = { 27, 31 }, 227 }, 228 .num_lanes = 5, 229 }, 230 { 231 .fields = { 232 [F_CTRLCLKEN] = { 0, 0 }, 233 [F_CAMMODE] = { 1, 2 }, 234 [F_CSI_MODE] = { 3, 3 }, 235 [F_LANEENABLE] = { 24, 26 }, 236 }, 237 .num_lanes = 3, 238 }, 239 }; 240 241 static const struct cal_data dra76x_cal_data = { 242 .camerarx = dra76x_cal_csi_phy, 243 .num_csi2_phy = ARRAY_SIZE(dra76x_cal_csi_phy), 244 }; 245 246 static const struct cal_camerarx_data am654_cal_csi_phy[] = { 247 { 248 .fields = { 249 [F_CTRLCLKEN] = { 15, 15 }, 250 [F_CAMMODE] = { 24, 25 }, 251 [F_LANEENABLE] = { 0, 4 }, 252 }, 253 .num_lanes = 5, 254 }, 255 }; 256 257 static const struct cal_data am654_cal_data = { 258 .camerarx = am654_cal_csi_phy, 259 .num_csi2_phy = ARRAY_SIZE(am654_cal_csi_phy), 260 }; 261 262 /* ------------------------------------------------------------------ 263 * I/O Register Accessors 264 * ------------------------------------------------------------------ 265 */ 266 267 void cal_quickdump_regs(struct cal_dev *cal) 268 { 269 unsigned int i; 270 271 cal_info(cal, "CAL Registers @ 0x%pa:\n", &cal->res->start); 272 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, 273 (__force const void *)cal->base, 274 resource_size(cal->res), false); 275 276 for (i = 0; i < cal->data->num_csi2_phy; ++i) { 277 struct cal_camerarx *phy = cal->phy[i]; 278 279 cal_info(cal, "CSI2 Core %u Registers @ %pa:\n", i, 280 &phy->res->start); 281 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4, 282 (__force const void *)phy->base, 283 resource_size(phy->res), 284 false); 285 } 286 } 287 288 /* ------------------------------------------------------------------ 289 * Context Management 290 * ------------------------------------------------------------------ 291 */ 292 293 #define CAL_MAX_PIX_PROC 4 294 295 static int cal_reserve_pix_proc(struct cal_dev *cal) 296 { 297 unsigned long ret; 298 299 spin_lock(&cal->v4l2_dev.lock); 300 301 ret = find_first_zero_bit(&cal->reserved_pix_proc_mask, CAL_MAX_PIX_PROC); 302 303 if (ret == CAL_MAX_PIX_PROC) { 304 spin_unlock(&cal->v4l2_dev.lock); 305 return -ENOSPC; 306 } 307 308 cal->reserved_pix_proc_mask |= BIT(ret); 309 310 spin_unlock(&cal->v4l2_dev.lock); 311 312 return ret; 313 } 314 315 static void cal_release_pix_proc(struct cal_dev *cal, unsigned int pix_proc_num) 316 { 317 spin_lock(&cal->v4l2_dev.lock); 318 319 cal->reserved_pix_proc_mask &= ~BIT(pix_proc_num); 320 321 spin_unlock(&cal->v4l2_dev.lock); 322 } 323 324 static void cal_ctx_csi2_config(struct cal_ctx *ctx) 325 { 326 u32 val; 327 328 val = cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx)); 329 cal_set_field(&val, ctx->cport, CAL_CSI2_CTX_CPORT_MASK); 330 /* 331 * DT type: MIPI CSI-2 Specs 332 * 0x1: All - DT filter is disabled 333 * 0x24: RGB888 1 pixel = 3 bytes 334 * 0x2B: RAW10 4 pixels = 5 bytes 335 * 0x2A: RAW8 1 pixel = 1 byte 336 * 0x1E: YUV422 2 pixels = 4 bytes 337 */ 338 cal_set_field(&val, ctx->datatype, CAL_CSI2_CTX_DT_MASK); 339 cal_set_field(&val, ctx->vc, CAL_CSI2_CTX_VC_MASK); 340 cal_set_field(&val, ctx->v_fmt.fmt.pix.height, CAL_CSI2_CTX_LINES_MASK); 341 cal_set_field(&val, CAL_CSI2_CTX_ATT_PIX, CAL_CSI2_CTX_ATT_MASK); 342 cal_set_field(&val, CAL_CSI2_CTX_PACK_MODE_LINE, 343 CAL_CSI2_CTX_PACK_MODE_MASK); 344 cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), val); 345 ctx_dbg(3, ctx, "CAL_CSI2_CTX(%u, %u) = 0x%08x\n", 346 ctx->phy->instance, ctx->csi2_ctx, 347 cal_read(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx))); 348 } 349 350 static void cal_ctx_pix_proc_config(struct cal_ctx *ctx) 351 { 352 u32 val, extract, pack; 353 354 switch (ctx->fmtinfo->bpp) { 355 case 8: 356 extract = CAL_PIX_PROC_EXTRACT_B8; 357 pack = CAL_PIX_PROC_PACK_B8; 358 break; 359 case 10: 360 extract = CAL_PIX_PROC_EXTRACT_B10_MIPI; 361 pack = CAL_PIX_PROC_PACK_B16; 362 break; 363 case 12: 364 extract = CAL_PIX_PROC_EXTRACT_B12_MIPI; 365 pack = CAL_PIX_PROC_PACK_B16; 366 break; 367 case 16: 368 extract = CAL_PIX_PROC_EXTRACT_B16_LE; 369 pack = CAL_PIX_PROC_PACK_B16; 370 break; 371 default: 372 /* 373 * If you see this warning then it means that you added 374 * some new entry in the cal_formats[] array with a different 375 * bit per pixel values then the one supported below. 376 * Either add support for the new bpp value below or adjust 377 * the new entry to use one of the value below. 378 * 379 * Instead of failing here just use 8 bpp as a default. 380 */ 381 dev_warn_once(ctx->cal->dev, 382 "%s:%d:%s: bpp:%d unsupported! Overwritten with 8.\n", 383 __FILE__, __LINE__, __func__, ctx->fmtinfo->bpp); 384 extract = CAL_PIX_PROC_EXTRACT_B8; 385 pack = CAL_PIX_PROC_PACK_B8; 386 break; 387 } 388 389 val = cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc)); 390 cal_set_field(&val, extract, CAL_PIX_PROC_EXTRACT_MASK); 391 cal_set_field(&val, CAL_PIX_PROC_DPCMD_BYPASS, CAL_PIX_PROC_DPCMD_MASK); 392 cal_set_field(&val, CAL_PIX_PROC_DPCME_BYPASS, CAL_PIX_PROC_DPCME_MASK); 393 cal_set_field(&val, pack, CAL_PIX_PROC_PACK_MASK); 394 cal_set_field(&val, ctx->cport, CAL_PIX_PROC_CPORT_MASK); 395 cal_set_field(&val, 1, CAL_PIX_PROC_EN_MASK); 396 cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), val); 397 ctx_dbg(3, ctx, "CAL_PIX_PROC(%u) = 0x%08x\n", ctx->pix_proc, 398 cal_read(ctx->cal, CAL_PIX_PROC(ctx->pix_proc))); 399 } 400 401 static void cal_ctx_wr_dma_config(struct cal_ctx *ctx) 402 { 403 unsigned int stride = ctx->v_fmt.fmt.pix.bytesperline; 404 u32 val; 405 406 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)); 407 cal_set_field(&val, ctx->cport, CAL_WR_DMA_CTRL_CPORT_MASK); 408 cal_set_field(&val, ctx->v_fmt.fmt.pix.height, 409 CAL_WR_DMA_CTRL_YSIZE_MASK); 410 cal_set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT, 411 CAL_WR_DMA_CTRL_DTAG_MASK); 412 cal_set_field(&val, CAL_WR_DMA_CTRL_PATTERN_LINEAR, 413 CAL_WR_DMA_CTRL_PATTERN_MASK); 414 cal_set_field(&val, 1, CAL_WR_DMA_CTRL_STALL_RD_MASK); 415 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val); 416 ctx_dbg(3, ctx, "CAL_WR_DMA_CTRL(%d) = 0x%08x\n", ctx->dma_ctx, 417 cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx))); 418 419 cal_write_field(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx), 420 stride / 16, CAL_WR_DMA_OFST_MASK); 421 ctx_dbg(3, ctx, "CAL_WR_DMA_OFST(%d) = 0x%08x\n", ctx->dma_ctx, 422 cal_read(ctx->cal, CAL_WR_DMA_OFST(ctx->dma_ctx))); 423 424 val = cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx)); 425 /* 64 bit word means no skipping */ 426 cal_set_field(&val, 0, CAL_WR_DMA_XSIZE_XSKIP_MASK); 427 /* 428 * The XSIZE field is expressed in 64-bit units and prevents overflows 429 * in case of synchronization issues by limiting the number of bytes 430 * written per line. 431 */ 432 cal_set_field(&val, stride / 8, CAL_WR_DMA_XSIZE_MASK); 433 cal_write(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx), val); 434 ctx_dbg(3, ctx, "CAL_WR_DMA_XSIZE(%d) = 0x%08x\n", ctx->dma_ctx, 435 cal_read(ctx->cal, CAL_WR_DMA_XSIZE(ctx->dma_ctx))); 436 } 437 438 void cal_ctx_set_dma_addr(struct cal_ctx *ctx, dma_addr_t addr) 439 { 440 cal_write(ctx->cal, CAL_WR_DMA_ADDR(ctx->dma_ctx), addr); 441 } 442 443 static void cal_ctx_wr_dma_enable(struct cal_ctx *ctx) 444 { 445 u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)); 446 447 cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST, 448 CAL_WR_DMA_CTRL_MODE_MASK); 449 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val); 450 } 451 452 static void cal_ctx_wr_dma_disable(struct cal_ctx *ctx) 453 { 454 u32 val = cal_read(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx)); 455 456 cal_set_field(&val, CAL_WR_DMA_CTRL_MODE_DIS, 457 CAL_WR_DMA_CTRL_MODE_MASK); 458 cal_write(ctx->cal, CAL_WR_DMA_CTRL(ctx->dma_ctx), val); 459 } 460 461 static bool cal_ctx_wr_dma_stopped(struct cal_ctx *ctx) 462 { 463 bool stopped; 464 465 spin_lock_irq(&ctx->dma.lock); 466 stopped = ctx->dma.state == CAL_DMA_STOPPED; 467 spin_unlock_irq(&ctx->dma.lock); 468 469 return stopped; 470 } 471 472 int cal_ctx_prepare(struct cal_ctx *ctx) 473 { 474 int ret; 475 476 ctx->use_pix_proc = !ctx->fmtinfo->meta; 477 478 if (ctx->use_pix_proc) { 479 ret = cal_reserve_pix_proc(ctx->cal); 480 if (ret < 0) { 481 ctx_err(ctx, "Failed to reserve pix proc: %d\n", ret); 482 return ret; 483 } 484 485 ctx->pix_proc = ret; 486 } 487 488 return 0; 489 } 490 491 void cal_ctx_unprepare(struct cal_ctx *ctx) 492 { 493 if (ctx->use_pix_proc) 494 cal_release_pix_proc(ctx->cal, ctx->pix_proc); 495 } 496 497 void cal_ctx_start(struct cal_ctx *ctx) 498 { 499 ctx->sequence = 0; 500 ctx->dma.state = CAL_DMA_RUNNING; 501 502 /* Configure the CSI-2, pixel processing and write DMA contexts. */ 503 cal_ctx_csi2_config(ctx); 504 if (ctx->use_pix_proc) 505 cal_ctx_pix_proc_config(ctx); 506 cal_ctx_wr_dma_config(ctx); 507 508 /* Enable IRQ_WDMA_END and IRQ_WDMA_START. */ 509 cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(1), 510 CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx)); 511 cal_write(ctx->cal, CAL_HL_IRQENABLE_SET(2), 512 CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx)); 513 514 cal_ctx_wr_dma_enable(ctx); 515 } 516 517 void cal_ctx_stop(struct cal_ctx *ctx) 518 { 519 long timeout; 520 521 /* 522 * Request DMA stop and wait until it completes. If completion times 523 * out, forcefully disable the DMA. 524 */ 525 spin_lock_irq(&ctx->dma.lock); 526 ctx->dma.state = CAL_DMA_STOP_REQUESTED; 527 spin_unlock_irq(&ctx->dma.lock); 528 529 timeout = wait_event_timeout(ctx->dma.wait, cal_ctx_wr_dma_stopped(ctx), 530 msecs_to_jiffies(500)); 531 if (!timeout) { 532 ctx_err(ctx, "failed to disable dma cleanly\n"); 533 cal_ctx_wr_dma_disable(ctx); 534 } 535 536 /* Disable IRQ_WDMA_END and IRQ_WDMA_START. */ 537 cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(1), 538 CAL_HL_IRQ_WDMA_END_MASK(ctx->dma_ctx)); 539 cal_write(ctx->cal, CAL_HL_IRQENABLE_CLR(2), 540 CAL_HL_IRQ_WDMA_START_MASK(ctx->dma_ctx)); 541 542 ctx->dma.state = CAL_DMA_STOPPED; 543 544 /* Disable CSI2 context */ 545 cal_write(ctx->cal, CAL_CSI2_CTX(ctx->phy->instance, ctx->csi2_ctx), 0); 546 547 /* Disable pix proc */ 548 if (ctx->use_pix_proc) 549 cal_write(ctx->cal, CAL_PIX_PROC(ctx->pix_proc), 0); 550 } 551 552 /* ------------------------------------------------------------------ 553 * IRQ Handling 554 * ------------------------------------------------------------------ 555 */ 556 557 static inline void cal_irq_wdma_start(struct cal_ctx *ctx) 558 { 559 spin_lock(&ctx->dma.lock); 560 561 if (ctx->dma.state == CAL_DMA_STOP_REQUESTED) { 562 /* 563 * If a stop is requested, disable the write DMA context 564 * immediately. The CAL_WR_DMA_CTRL_j.MODE field is shadowed, 565 * the current frame will complete and the DMA will then stop. 566 */ 567 cal_ctx_wr_dma_disable(ctx); 568 ctx->dma.state = CAL_DMA_STOP_PENDING; 569 } else if (!list_empty(&ctx->dma.queue) && !ctx->dma.pending) { 570 /* 571 * Otherwise, if a new buffer is available, queue it to the 572 * hardware. 573 */ 574 struct cal_buffer *buf; 575 dma_addr_t addr; 576 577 buf = list_first_entry(&ctx->dma.queue, struct cal_buffer, 578 list); 579 addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0); 580 cal_ctx_set_dma_addr(ctx, addr); 581 582 ctx->dma.pending = buf; 583 list_del(&buf->list); 584 } 585 586 spin_unlock(&ctx->dma.lock); 587 } 588 589 static inline void cal_irq_wdma_end(struct cal_ctx *ctx) 590 { 591 struct cal_buffer *buf = NULL; 592 593 spin_lock(&ctx->dma.lock); 594 595 /* If the DMA context was stopping, it is now stopped. */ 596 if (ctx->dma.state == CAL_DMA_STOP_PENDING) { 597 ctx->dma.state = CAL_DMA_STOPPED; 598 wake_up(&ctx->dma.wait); 599 } 600 601 /* If a new buffer was queued, complete the current buffer. */ 602 if (ctx->dma.pending) { 603 buf = ctx->dma.active; 604 ctx->dma.active = ctx->dma.pending; 605 ctx->dma.pending = NULL; 606 } 607 608 spin_unlock(&ctx->dma.lock); 609 610 if (buf) { 611 buf->vb.vb2_buf.timestamp = ktime_get_ns(); 612 buf->vb.field = ctx->v_fmt.fmt.pix.field; 613 buf->vb.sequence = ctx->sequence++; 614 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE); 615 } 616 } 617 618 static irqreturn_t cal_irq(int irq_cal, void *data) 619 { 620 struct cal_dev *cal = data; 621 u32 status; 622 623 status = cal_read(cal, CAL_HL_IRQSTATUS(0)); 624 if (status) { 625 unsigned int i; 626 627 cal_write(cal, CAL_HL_IRQSTATUS(0), status); 628 629 if (status & CAL_HL_IRQ_OCPO_ERR_MASK) 630 dev_err_ratelimited(cal->dev, "OCPO ERROR\n"); 631 632 for (i = 0; i < cal->data->num_csi2_phy; ++i) { 633 if (status & CAL_HL_IRQ_CIO_MASK(i)) { 634 u32 cio_stat = cal_read(cal, 635 CAL_CSI2_COMPLEXIO_IRQSTATUS(i)); 636 637 dev_err_ratelimited(cal->dev, 638 "CIO%u error: %#08x\n", i, cio_stat); 639 640 cal_write(cal, CAL_CSI2_COMPLEXIO_IRQSTATUS(i), 641 cio_stat); 642 } 643 644 if (status & CAL_HL_IRQ_VC_MASK(i)) { 645 u32 vc_stat = cal_read(cal, CAL_CSI2_VC_IRQSTATUS(i)); 646 647 dev_err_ratelimited(cal->dev, 648 "CIO%u VC error: %#08x\n", 649 i, vc_stat); 650 651 cal_write(cal, CAL_CSI2_VC_IRQSTATUS(i), vc_stat); 652 } 653 } 654 } 655 656 /* Check which DMA just finished */ 657 status = cal_read(cal, CAL_HL_IRQSTATUS(1)); 658 if (status) { 659 unsigned int i; 660 661 /* Clear Interrupt status */ 662 cal_write(cal, CAL_HL_IRQSTATUS(1), status); 663 664 for (i = 0; i < cal->num_contexts; ++i) { 665 if (status & CAL_HL_IRQ_WDMA_END_MASK(i)) 666 cal_irq_wdma_end(cal->ctx[i]); 667 } 668 } 669 670 /* Check which DMA just started */ 671 status = cal_read(cal, CAL_HL_IRQSTATUS(2)); 672 if (status) { 673 unsigned int i; 674 675 /* Clear Interrupt status */ 676 cal_write(cal, CAL_HL_IRQSTATUS(2), status); 677 678 for (i = 0; i < cal->num_contexts; ++i) { 679 if (status & CAL_HL_IRQ_WDMA_START_MASK(i)) 680 cal_irq_wdma_start(cal->ctx[i]); 681 } 682 } 683 684 return IRQ_HANDLED; 685 } 686 687 /* ------------------------------------------------------------------ 688 * Asynchronous V4L2 subdev binding 689 * ------------------------------------------------------------------ 690 */ 691 692 struct cal_v4l2_async_subdev { 693 struct v4l2_async_subdev asd; /* Must be first */ 694 struct cal_camerarx *phy; 695 }; 696 697 static inline struct cal_v4l2_async_subdev * 698 to_cal_asd(struct v4l2_async_subdev *asd) 699 { 700 return container_of(asd, struct cal_v4l2_async_subdev, asd); 701 } 702 703 static int cal_async_notifier_bound(struct v4l2_async_notifier *notifier, 704 struct v4l2_subdev *subdev, 705 struct v4l2_async_subdev *asd) 706 { 707 struct cal_camerarx *phy = to_cal_asd(asd)->phy; 708 int pad; 709 int ret; 710 711 if (phy->source) { 712 phy_info(phy, "Rejecting subdev %s (Already set!!)", 713 subdev->name); 714 return 0; 715 } 716 717 phy->source = subdev; 718 phy_dbg(1, phy, "Using source %s for capture\n", subdev->name); 719 720 pad = media_entity_get_fwnode_pad(&subdev->entity, 721 of_fwnode_handle(phy->source_ep_node), 722 MEDIA_PAD_FL_SOURCE); 723 if (pad < 0) { 724 phy_err(phy, "Source %s has no connected source pad\n", 725 subdev->name); 726 return pad; 727 } 728 729 ret = media_create_pad_link(&subdev->entity, pad, 730 &phy->subdev.entity, CAL_CAMERARX_PAD_SINK, 731 MEDIA_LNK_FL_IMMUTABLE | 732 MEDIA_LNK_FL_ENABLED); 733 if (ret) { 734 phy_err(phy, "Failed to create media link for source %s\n", 735 subdev->name); 736 return ret; 737 } 738 739 return 0; 740 } 741 742 static int cal_async_notifier_complete(struct v4l2_async_notifier *notifier) 743 { 744 struct cal_dev *cal = container_of(notifier, struct cal_dev, notifier); 745 unsigned int i; 746 int ret; 747 748 for (i = 0; i < cal->num_contexts; ++i) { 749 ret = cal_ctx_v4l2_register(cal->ctx[i]); 750 if (ret) 751 goto err_ctx_unreg; 752 } 753 754 if (!cal_mc_api) 755 return 0; 756 757 ret = v4l2_device_register_subdev_nodes(&cal->v4l2_dev); 758 if (ret) 759 goto err_ctx_unreg; 760 761 return 0; 762 763 err_ctx_unreg: 764 for (; i > 0; --i) { 765 if (!cal->ctx[i - 1]) 766 continue; 767 768 cal_ctx_v4l2_unregister(cal->ctx[i - 1]); 769 } 770 771 return ret; 772 } 773 774 static const struct v4l2_async_notifier_operations cal_async_notifier_ops = { 775 .bound = cal_async_notifier_bound, 776 .complete = cal_async_notifier_complete, 777 }; 778 779 static int cal_async_notifier_register(struct cal_dev *cal) 780 { 781 unsigned int i; 782 int ret; 783 784 v4l2_async_nf_init(&cal->notifier); 785 cal->notifier.ops = &cal_async_notifier_ops; 786 787 for (i = 0; i < cal->data->num_csi2_phy; ++i) { 788 struct cal_camerarx *phy = cal->phy[i]; 789 struct cal_v4l2_async_subdev *casd; 790 struct fwnode_handle *fwnode; 791 792 if (!phy->source_node) 793 continue; 794 795 fwnode = of_fwnode_handle(phy->source_node); 796 casd = v4l2_async_nf_add_fwnode(&cal->notifier, 797 fwnode, 798 struct cal_v4l2_async_subdev); 799 if (IS_ERR(casd)) { 800 phy_err(phy, "Failed to add subdev to notifier\n"); 801 ret = PTR_ERR(casd); 802 goto error; 803 } 804 805 casd->phy = phy; 806 } 807 808 ret = v4l2_async_nf_register(&cal->v4l2_dev, &cal->notifier); 809 if (ret) { 810 cal_err(cal, "Error registering async notifier\n"); 811 goto error; 812 } 813 814 return 0; 815 816 error: 817 v4l2_async_nf_cleanup(&cal->notifier); 818 return ret; 819 } 820 821 static void cal_async_notifier_unregister(struct cal_dev *cal) 822 { 823 v4l2_async_nf_unregister(&cal->notifier); 824 v4l2_async_nf_cleanup(&cal->notifier); 825 } 826 827 /* ------------------------------------------------------------------ 828 * Media and V4L2 device handling 829 * ------------------------------------------------------------------ 830 */ 831 832 /* 833 * Register user-facing devices. To be called at the end of the probe function 834 * when all resources are initialized and ready. 835 */ 836 static int cal_media_register(struct cal_dev *cal) 837 { 838 int ret; 839 840 ret = media_device_register(&cal->mdev); 841 if (ret) { 842 cal_err(cal, "Failed to register media device\n"); 843 return ret; 844 } 845 846 /* 847 * Register the async notifier. This may trigger registration of the 848 * V4L2 video devices if all subdevs are ready. 849 */ 850 ret = cal_async_notifier_register(cal); 851 if (ret) { 852 media_device_unregister(&cal->mdev); 853 return ret; 854 } 855 856 return 0; 857 } 858 859 /* 860 * Unregister the user-facing devices, but don't free memory yet. To be called 861 * at the beginning of the remove function, to disallow access from userspace. 862 */ 863 static void cal_media_unregister(struct cal_dev *cal) 864 { 865 unsigned int i; 866 867 /* Unregister all the V4L2 video devices. */ 868 for (i = 0; i < cal->num_contexts; i++) 869 cal_ctx_v4l2_unregister(cal->ctx[i]); 870 871 cal_async_notifier_unregister(cal); 872 media_device_unregister(&cal->mdev); 873 } 874 875 /* 876 * Initialize the in-kernel objects. To be called at the beginning of the probe 877 * function, before the V4L2 device is used by the driver. 878 */ 879 static int cal_media_init(struct cal_dev *cal) 880 { 881 struct media_device *mdev = &cal->mdev; 882 int ret; 883 884 mdev->dev = cal->dev; 885 mdev->hw_revision = cal->revision; 886 strscpy(mdev->model, "CAL", sizeof(mdev->model)); 887 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", 888 dev_name(mdev->dev)); 889 media_device_init(mdev); 890 891 /* 892 * Initialize the V4L2 device (despite the function name, this performs 893 * initialization, not registration). 894 */ 895 cal->v4l2_dev.mdev = mdev; 896 ret = v4l2_device_register(cal->dev, &cal->v4l2_dev); 897 if (ret) { 898 cal_err(cal, "Failed to register V4L2 device\n"); 899 return ret; 900 } 901 902 vb2_dma_contig_set_max_seg_size(cal->dev, DMA_BIT_MASK(32)); 903 904 return 0; 905 } 906 907 /* 908 * Cleanup the in-kernel objects, freeing memory. To be called at the very end 909 * of the remove sequence, when nothing (including userspace) can access the 910 * objects anymore. 911 */ 912 static void cal_media_cleanup(struct cal_dev *cal) 913 { 914 v4l2_device_unregister(&cal->v4l2_dev); 915 media_device_cleanup(&cal->mdev); 916 917 vb2_dma_contig_clear_max_seg_size(cal->dev); 918 } 919 920 /* ------------------------------------------------------------------ 921 * Initialization and module stuff 922 * ------------------------------------------------------------------ 923 */ 924 925 static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst) 926 { 927 struct cal_ctx *ctx; 928 int ret; 929 930 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 931 if (!ctx) 932 return NULL; 933 934 ctx->cal = cal; 935 ctx->phy = cal->phy[inst]; 936 ctx->dma_ctx = inst; 937 ctx->csi2_ctx = inst; 938 ctx->cport = inst; 939 ctx->vc = 0; 940 ctx->datatype = CAL_CSI2_CTX_DT_ANY; 941 942 ret = cal_ctx_v4l2_init(ctx); 943 if (ret) 944 return NULL; 945 946 return ctx; 947 } 948 949 static void cal_ctx_destroy(struct cal_ctx *ctx) 950 { 951 cal_ctx_v4l2_cleanup(ctx); 952 953 kfree(ctx); 954 } 955 956 static const struct of_device_id cal_of_match[] = { 957 { 958 .compatible = "ti,dra72-cal", 959 .data = (void *)&dra72x_cal_data, 960 }, 961 { 962 .compatible = "ti,dra72-pre-es2-cal", 963 .data = (void *)&dra72x_es1_cal_data, 964 }, 965 { 966 .compatible = "ti,dra76-cal", 967 .data = (void *)&dra76x_cal_data, 968 }, 969 { 970 .compatible = "ti,am654-cal", 971 .data = (void *)&am654_cal_data, 972 }, 973 {}, 974 }; 975 MODULE_DEVICE_TABLE(of, cal_of_match); 976 977 /* Get hardware revision and info. */ 978 979 #define CAL_HL_HWINFO_VALUE 0xa3c90469 980 981 static void cal_get_hwinfo(struct cal_dev *cal) 982 { 983 u32 hwinfo; 984 985 cal->revision = cal_read(cal, CAL_HL_REVISION); 986 switch (FIELD_GET(CAL_HL_REVISION_SCHEME_MASK, cal->revision)) { 987 case CAL_HL_REVISION_SCHEME_H08: 988 cal_dbg(3, cal, "CAL HW revision %lu.%lu.%lu (0x%08x)\n", 989 FIELD_GET(CAL_HL_REVISION_MAJOR_MASK, cal->revision), 990 FIELD_GET(CAL_HL_REVISION_MINOR_MASK, cal->revision), 991 FIELD_GET(CAL_HL_REVISION_RTL_MASK, cal->revision), 992 cal->revision); 993 break; 994 995 case CAL_HL_REVISION_SCHEME_LEGACY: 996 default: 997 cal_info(cal, "Unexpected CAL HW revision 0x%08x\n", 998 cal->revision); 999 break; 1000 } 1001 1002 hwinfo = cal_read(cal, CAL_HL_HWINFO); 1003 if (hwinfo != CAL_HL_HWINFO_VALUE) 1004 cal_info(cal, "CAL_HL_HWINFO = 0x%08x, expected 0x%08x\n", 1005 hwinfo, CAL_HL_HWINFO_VALUE); 1006 } 1007 1008 static int cal_init_camerarx_regmap(struct cal_dev *cal) 1009 { 1010 struct platform_device *pdev = to_platform_device(cal->dev); 1011 struct device_node *np = cal->dev->of_node; 1012 struct regmap_config config = { }; 1013 struct regmap *syscon; 1014 struct resource *res; 1015 unsigned int offset; 1016 void __iomem *base; 1017 1018 syscon = syscon_regmap_lookup_by_phandle_args(np, "ti,camerrx-control", 1019 1, &offset); 1020 if (!IS_ERR(syscon)) { 1021 cal->syscon_camerrx = syscon; 1022 cal->syscon_camerrx_offset = offset; 1023 return 0; 1024 } 1025 1026 dev_warn(cal->dev, "failed to get ti,camerrx-control: %ld\n", 1027 PTR_ERR(syscon)); 1028 1029 /* 1030 * Backward DTS compatibility. If syscon entry is not present then 1031 * check if the camerrx_control resource is present. 1032 */ 1033 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 1034 "camerrx_control"); 1035 base = devm_ioremap_resource(cal->dev, res); 1036 if (IS_ERR(base)) { 1037 cal_err(cal, "failed to ioremap camerrx_control\n"); 1038 return PTR_ERR(base); 1039 } 1040 1041 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n", 1042 res->name, &res->start, &res->end); 1043 1044 config.reg_bits = 32; 1045 config.reg_stride = 4; 1046 config.val_bits = 32; 1047 config.max_register = resource_size(res) - 4; 1048 1049 syscon = regmap_init_mmio(NULL, base, &config); 1050 if (IS_ERR(syscon)) { 1051 pr_err("regmap init failed\n"); 1052 return PTR_ERR(syscon); 1053 } 1054 1055 /* 1056 * In this case the base already point to the direct CM register so no 1057 * need for an offset. 1058 */ 1059 cal->syscon_camerrx = syscon; 1060 cal->syscon_camerrx_offset = 0; 1061 1062 return 0; 1063 } 1064 1065 static int cal_probe(struct platform_device *pdev) 1066 { 1067 struct cal_dev *cal; 1068 bool connected = false; 1069 unsigned int i; 1070 int ret; 1071 int irq; 1072 1073 cal = devm_kzalloc(&pdev->dev, sizeof(*cal), GFP_KERNEL); 1074 if (!cal) 1075 return -ENOMEM; 1076 1077 cal->data = of_device_get_match_data(&pdev->dev); 1078 if (!cal->data) { 1079 dev_err(&pdev->dev, "Could not get feature data based on compatible version\n"); 1080 return -ENODEV; 1081 } 1082 1083 cal->dev = &pdev->dev; 1084 platform_set_drvdata(pdev, cal); 1085 1086 /* Acquire resources: clocks, CAMERARX regmap, I/O memory and IRQ. */ 1087 cal->fclk = devm_clk_get(&pdev->dev, "fck"); 1088 if (IS_ERR(cal->fclk)) { 1089 dev_err(&pdev->dev, "cannot get CAL fclk\n"); 1090 return PTR_ERR(cal->fclk); 1091 } 1092 1093 ret = cal_init_camerarx_regmap(cal); 1094 if (ret < 0) 1095 return ret; 1096 1097 cal->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 1098 "cal_top"); 1099 cal->base = devm_ioremap_resource(&pdev->dev, cal->res); 1100 if (IS_ERR(cal->base)) 1101 return PTR_ERR(cal->base); 1102 1103 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n", 1104 cal->res->name, &cal->res->start, &cal->res->end); 1105 1106 irq = platform_get_irq(pdev, 0); 1107 cal_dbg(1, cal, "got irq# %d\n", irq); 1108 ret = devm_request_irq(&pdev->dev, irq, cal_irq, 0, CAL_MODULE_NAME, 1109 cal); 1110 if (ret) 1111 return ret; 1112 1113 /* Read the revision and hardware info to verify hardware access. */ 1114 pm_runtime_enable(&pdev->dev); 1115 ret = pm_runtime_resume_and_get(&pdev->dev); 1116 if (ret) 1117 goto error_pm_runtime; 1118 1119 cal_get_hwinfo(cal); 1120 pm_runtime_put_sync(&pdev->dev); 1121 1122 /* Initialize the media device. */ 1123 ret = cal_media_init(cal); 1124 if (ret < 0) 1125 goto error_pm_runtime; 1126 1127 /* Create CAMERARX PHYs. */ 1128 for (i = 0; i < cal->data->num_csi2_phy; ++i) { 1129 cal->phy[i] = cal_camerarx_create(cal, i); 1130 if (IS_ERR(cal->phy[i])) { 1131 ret = PTR_ERR(cal->phy[i]); 1132 cal->phy[i] = NULL; 1133 goto error_camerarx; 1134 } 1135 1136 if (cal->phy[i]->source_node) 1137 connected = true; 1138 } 1139 1140 if (!connected) { 1141 cal_err(cal, "Neither port is configured, no point in staying up\n"); 1142 ret = -ENODEV; 1143 goto error_camerarx; 1144 } 1145 1146 /* Create contexts. */ 1147 for (i = 0; i < cal->data->num_csi2_phy; ++i) { 1148 if (!cal->phy[i]->source_node) 1149 continue; 1150 1151 cal->ctx[cal->num_contexts] = cal_ctx_create(cal, i); 1152 if (!cal->ctx[cal->num_contexts]) { 1153 cal_err(cal, "Failed to create context %u\n", cal->num_contexts); 1154 ret = -ENODEV; 1155 goto error_context; 1156 } 1157 1158 cal->num_contexts++; 1159 } 1160 1161 /* Register the media device. */ 1162 ret = cal_media_register(cal); 1163 if (ret) 1164 goto error_context; 1165 1166 return 0; 1167 1168 error_context: 1169 for (i = 0; i < cal->num_contexts; i++) 1170 cal_ctx_destroy(cal->ctx[i]); 1171 1172 error_camerarx: 1173 for (i = 0; i < cal->data->num_csi2_phy; i++) 1174 cal_camerarx_destroy(cal->phy[i]); 1175 1176 cal_media_cleanup(cal); 1177 1178 error_pm_runtime: 1179 pm_runtime_disable(&pdev->dev); 1180 1181 return ret; 1182 } 1183 1184 static int cal_remove(struct platform_device *pdev) 1185 { 1186 struct cal_dev *cal = platform_get_drvdata(pdev); 1187 unsigned int i; 1188 int ret; 1189 1190 cal_dbg(1, cal, "Removing %s\n", CAL_MODULE_NAME); 1191 1192 ret = pm_runtime_resume_and_get(&pdev->dev); 1193 1194 cal_media_unregister(cal); 1195 1196 for (i = 0; i < cal->data->num_csi2_phy; i++) 1197 cal_camerarx_disable(cal->phy[i]); 1198 1199 for (i = 0; i < cal->num_contexts; i++) 1200 cal_ctx_destroy(cal->ctx[i]); 1201 1202 for (i = 0; i < cal->data->num_csi2_phy; i++) 1203 cal_camerarx_destroy(cal->phy[i]); 1204 1205 cal_media_cleanup(cal); 1206 1207 if (ret >= 0) 1208 pm_runtime_put_sync(&pdev->dev); 1209 pm_runtime_disable(&pdev->dev); 1210 1211 return 0; 1212 } 1213 1214 static int cal_runtime_resume(struct device *dev) 1215 { 1216 struct cal_dev *cal = dev_get_drvdata(dev); 1217 unsigned int i; 1218 u32 val; 1219 1220 if (cal->data->flags & DRA72_CAL_PRE_ES2_LDO_DISABLE) { 1221 /* 1222 * Apply errata on both port everytime we (re-)enable 1223 * the clock 1224 */ 1225 for (i = 0; i < cal->data->num_csi2_phy; i++) 1226 cal_camerarx_i913_errata(cal->phy[i]); 1227 } 1228 1229 /* 1230 * Enable global interrupts that are not related to a particular 1231 * CAMERARAX or context. 1232 */ 1233 cal_write(cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK); 1234 1235 val = cal_read(cal, CAL_CTRL); 1236 cal_set_field(&val, CAL_CTRL_BURSTSIZE_BURST128, 1237 CAL_CTRL_BURSTSIZE_MASK); 1238 cal_set_field(&val, 0xf, CAL_CTRL_TAGCNT_MASK); 1239 cal_set_field(&val, CAL_CTRL_POSTED_WRITES_NONPOSTED, 1240 CAL_CTRL_POSTED_WRITES_MASK); 1241 cal_set_field(&val, 0xff, CAL_CTRL_MFLAGL_MASK); 1242 cal_set_field(&val, 0xff, CAL_CTRL_MFLAGH_MASK); 1243 cal_write(cal, CAL_CTRL, val); 1244 cal_dbg(3, cal, "CAL_CTRL = 0x%08x\n", cal_read(cal, CAL_CTRL)); 1245 1246 return 0; 1247 } 1248 1249 static const struct dev_pm_ops cal_pm_ops = { 1250 .runtime_resume = cal_runtime_resume, 1251 }; 1252 1253 static struct platform_driver cal_pdrv = { 1254 .probe = cal_probe, 1255 .remove = cal_remove, 1256 .driver = { 1257 .name = CAL_MODULE_NAME, 1258 .pm = &cal_pm_ops, 1259 .of_match_table = cal_of_match, 1260 }, 1261 }; 1262 1263 module_platform_driver(cal_pdrv); 1264