1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2021-2023 Digiteq Automotive 4 * author: Martin Tuma <martin.tuma@digiteqautomotive.com> 5 * 6 * This module handles all the sysfs info/configuration that is related to the 7 * v4l2 input devices. 8 */ 9 10 #include <linux/device.h> 11 #include "mgb4_core.h" 12 #include "mgb4_i2c.h" 13 #include "mgb4_vin.h" 14 #include "mgb4_cmt.h" 15 #include "mgb4_sysfs.h" 16 17 /* Common for both FPDL3 and GMSL */ 18 19 static ssize_t input_id_show(struct device *dev, 20 struct device_attribute *attr, char *buf) 21 { 22 struct video_device *vdev = to_video_device(dev); 23 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 24 25 return sprintf(buf, "%d\n", vindev->config->id); 26 } 27 28 static ssize_t oldi_lane_width_show(struct device *dev, 29 struct device_attribute *attr, char *buf) 30 { 31 struct video_device *vdev = to_video_device(dev); 32 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 33 struct mgb4_dev *mgbdev = vindev->mgbdev; 34 u16 i2c_reg; 35 u8 i2c_mask, i2c_single_val, i2c_dual_val; 36 u32 config; 37 int ret; 38 39 i2c_reg = MGB4_IS_GMSL(mgbdev) ? 0x1CE : 0x49; 40 i2c_mask = MGB4_IS_GMSL(mgbdev) ? 0x0E : 0x03; 41 i2c_single_val = MGB4_IS_GMSL(mgbdev) ? 0x00 : 0x02; 42 i2c_dual_val = MGB4_IS_GMSL(mgbdev) ? 0x0E : 0x00; 43 44 mutex_lock(&mgbdev->i2c_lock); 45 ret = mgb4_i2c_read_byte(&vindev->deser, i2c_reg); 46 mutex_unlock(&mgbdev->i2c_lock); 47 if (ret < 0) 48 return -EIO; 49 50 config = mgb4_read_reg(&mgbdev->video, vindev->config->regs.config); 51 52 if (((config & (1U << 9)) && ((ret & i2c_mask) != i2c_dual_val)) || 53 (!(config & (1U << 9)) && ((ret & i2c_mask) != i2c_single_val))) { 54 dev_err(dev, "I2C/FPGA register value mismatch\n"); 55 return -EINVAL; 56 } 57 58 return sprintf(buf, "%s\n", config & (1U << 9) ? "1" : "0"); 59 } 60 61 /* 62 * OLDI lane width change is expected to be called on live streams. Video device 63 * locking/queue check is not needed. 64 */ 65 static ssize_t oldi_lane_width_store(struct device *dev, 66 struct device_attribute *attr, 67 const char *buf, size_t count) 68 { 69 struct video_device *vdev = to_video_device(dev); 70 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 71 struct mgb4_dev *mgbdev = vindev->mgbdev; 72 u32 fpga_data; 73 u16 i2c_reg; 74 u8 i2c_mask, i2c_data; 75 unsigned long val; 76 int ret; 77 78 ret = kstrtoul(buf, 10, &val); 79 if (ret) 80 return ret; 81 82 switch (val) { 83 case 0: /* single */ 84 fpga_data = 0; 85 i2c_data = MGB4_IS_GMSL(mgbdev) ? 0x00 : 0x02; 86 break; 87 case 1: /* dual */ 88 fpga_data = 1U << 9; 89 i2c_data = MGB4_IS_GMSL(mgbdev) ? 0x0E : 0x00; 90 break; 91 default: 92 return -EINVAL; 93 } 94 95 i2c_reg = MGB4_IS_GMSL(mgbdev) ? 0x1CE : 0x49; 96 i2c_mask = MGB4_IS_GMSL(mgbdev) ? 0x0E : 0x03; 97 98 mutex_lock(&mgbdev->i2c_lock); 99 ret = mgb4_i2c_mask_byte(&vindev->deser, i2c_reg, i2c_mask, i2c_data); 100 mutex_unlock(&mgbdev->i2c_lock); 101 if (ret < 0) 102 return -EIO; 103 mgb4_mask_reg(&mgbdev->video, vindev->config->regs.config, 1U << 9, 104 fpga_data); 105 if (MGB4_IS_GMSL(mgbdev)) { 106 /* reset input link */ 107 mutex_lock(&mgbdev->i2c_lock); 108 ret = mgb4_i2c_mask_byte(&vindev->deser, 0x10, 1U << 5, 1U << 5); 109 mutex_unlock(&mgbdev->i2c_lock); 110 if (ret < 0) 111 return -EIO; 112 } 113 114 return count; 115 } 116 117 static ssize_t color_mapping_show(struct device *dev, 118 struct device_attribute *attr, char *buf) 119 { 120 struct video_device *vdev = to_video_device(dev); 121 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 122 u32 config = mgb4_read_reg(&vindev->mgbdev->video, 123 vindev->config->regs.config); 124 125 return sprintf(buf, "%s\n", config & (1U << 8) ? "0" : "1"); 126 } 127 128 /* 129 * Color mapping change is expected to be called on live streams. Video device 130 * locking/queue check is not needed. 131 */ 132 static ssize_t color_mapping_store(struct device *dev, 133 struct device_attribute *attr, 134 const char *buf, size_t count) 135 { 136 struct video_device *vdev = to_video_device(dev); 137 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 138 u32 fpga_data; 139 unsigned long val; 140 int ret; 141 142 ret = kstrtoul(buf, 10, &val); 143 if (ret) 144 return ret; 145 146 switch (val) { 147 case 0: /* OLDI/JEIDA */ 148 fpga_data = (1U << 8); 149 break; 150 case 1: /* SPWG/VESA */ 151 fpga_data = 0; 152 break; 153 default: 154 return -EINVAL; 155 } 156 157 mgb4_mask_reg(&vindev->mgbdev->video, vindev->config->regs.config, 158 1U << 8, fpga_data); 159 160 return count; 161 } 162 163 static ssize_t link_status_show(struct device *dev, 164 struct device_attribute *attr, char *buf) 165 { 166 struct video_device *vdev = to_video_device(dev); 167 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 168 u32 status = mgb4_read_reg(&vindev->mgbdev->video, 169 vindev->config->regs.status); 170 171 return sprintf(buf, "%s\n", status & (1U << 2) ? "1" : "0"); 172 } 173 174 static ssize_t stream_status_show(struct device *dev, 175 struct device_attribute *attr, char *buf) 176 { 177 struct video_device *vdev = to_video_device(dev); 178 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 179 u32 status = mgb4_read_reg(&vindev->mgbdev->video, 180 vindev->config->regs.status); 181 182 return sprintf(buf, "%s\n", ((status & (1 << 14)) && 183 (status & (1 << 2)) && (status & (3 << 9))) ? "1" : "0"); 184 } 185 186 static ssize_t video_width_show(struct device *dev, 187 struct device_attribute *attr, char *buf) 188 { 189 struct video_device *vdev = to_video_device(dev); 190 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 191 u32 config = mgb4_read_reg(&vindev->mgbdev->video, 192 vindev->config->regs.resolution); 193 194 return sprintf(buf, "%u\n", config >> 16); 195 } 196 197 static ssize_t video_height_show(struct device *dev, 198 struct device_attribute *attr, char *buf) 199 { 200 struct video_device *vdev = to_video_device(dev); 201 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 202 u32 config = mgb4_read_reg(&vindev->mgbdev->video, 203 vindev->config->regs.resolution); 204 205 return sprintf(buf, "%u\n", config & 0xFFFF); 206 } 207 208 static ssize_t hsync_status_show(struct device *dev, 209 struct device_attribute *attr, char *buf) 210 { 211 struct video_device *vdev = to_video_device(dev); 212 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 213 u32 status = mgb4_read_reg(&vindev->mgbdev->video, 214 vindev->config->regs.status); 215 u32 res; 216 217 if (!(status & (1U << 11))) 218 res = 0x02; // not available 219 else if (status & (1U << 12)) 220 res = 0x01; // active high 221 else 222 res = 0x00; // active low 223 224 return sprintf(buf, "%u\n", res); 225 } 226 227 static ssize_t vsync_status_show(struct device *dev, 228 struct device_attribute *attr, char *buf) 229 { 230 struct video_device *vdev = to_video_device(dev); 231 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 232 u32 status = mgb4_read_reg(&vindev->mgbdev->video, 233 vindev->config->regs.status); 234 u32 res; 235 236 if (!(status & (1U << 11))) 237 res = 0x02; // not available 238 else if (status & (1U << 13)) 239 res = 0x01; // active high 240 else 241 res = 0x00; // active low 242 243 return sprintf(buf, "%u\n", res); 244 } 245 246 static ssize_t hsync_gap_length_show(struct device *dev, 247 struct device_attribute *attr, 248 char *buf) 249 { 250 struct video_device *vdev = to_video_device(dev); 251 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 252 u32 sync = mgb4_read_reg(&vindev->mgbdev->video, 253 vindev->config->regs.sync); 254 255 return sprintf(buf, "%u\n", sync >> 16); 256 } 257 258 /* 259 * HSYNC gap length change is expected to be called on live streams. Video 260 * device locking/queue check is not needed. 261 */ 262 static ssize_t hsync_gap_length_store(struct device *dev, 263 struct device_attribute *attr, 264 const char *buf, size_t count) 265 { 266 struct video_device *vdev = to_video_device(dev); 267 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 268 unsigned long val; 269 int ret; 270 271 ret = kstrtoul(buf, 10, &val); 272 if (ret) 273 return ret; 274 if (val > 0xFFFF) 275 return -EINVAL; 276 277 mgb4_mask_reg(&vindev->mgbdev->video, vindev->config->regs.sync, 278 0xFFFF0000, val << 16); 279 280 return count; 281 } 282 283 static ssize_t vsync_gap_length_show(struct device *dev, 284 struct device_attribute *attr, char *buf) 285 { 286 struct video_device *vdev = to_video_device(dev); 287 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 288 u32 sync = mgb4_read_reg(&vindev->mgbdev->video, 289 vindev->config->regs.sync); 290 291 return sprintf(buf, "%u\n", sync & 0xFFFF); 292 } 293 294 /* 295 * VSYNC gap length change is expected to be called on live streams. Video 296 * device locking/queue check is not needed. 297 */ 298 static ssize_t vsync_gap_length_store(struct device *dev, 299 struct device_attribute *attr, 300 const char *buf, size_t count) 301 { 302 struct video_device *vdev = to_video_device(dev); 303 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 304 unsigned long val; 305 int ret; 306 307 ret = kstrtoul(buf, 10, &val); 308 if (ret) 309 return ret; 310 if (val > 0xFFFF) 311 return -EINVAL; 312 313 mgb4_mask_reg(&vindev->mgbdev->video, vindev->config->regs.sync, 0xFFFF, 314 val); 315 316 return count; 317 } 318 319 static ssize_t pclk_frequency_show(struct device *dev, 320 struct device_attribute *attr, char *buf) 321 { 322 struct video_device *vdev = to_video_device(dev); 323 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 324 u32 freq = mgb4_read_reg(&vindev->mgbdev->video, 325 vindev->config->regs.pclk); 326 327 return sprintf(buf, "%u\n", freq); 328 } 329 330 static ssize_t hsync_width_show(struct device *dev, 331 struct device_attribute *attr, char *buf) 332 { 333 struct video_device *vdev = to_video_device(dev); 334 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 335 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 336 vindev->config->regs.signal); 337 338 return sprintf(buf, "%u\n", (sig & 0x00FF0000) >> 16); 339 } 340 341 static ssize_t vsync_width_show(struct device *dev, 342 struct device_attribute *attr, char *buf) 343 { 344 struct video_device *vdev = to_video_device(dev); 345 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 346 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 347 vindev->config->regs.signal2); 348 349 return sprintf(buf, "%u\n", (sig & 0x00FF0000) >> 16); 350 } 351 352 static ssize_t hback_porch_show(struct device *dev, 353 struct device_attribute *attr, char *buf) 354 { 355 struct video_device *vdev = to_video_device(dev); 356 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 357 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 358 vindev->config->regs.signal); 359 360 return sprintf(buf, "%u\n", (sig & 0x0000FF00) >> 8); 361 } 362 363 static ssize_t hfront_porch_show(struct device *dev, 364 struct device_attribute *attr, char *buf) 365 { 366 struct video_device *vdev = to_video_device(dev); 367 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 368 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 369 vindev->config->regs.signal); 370 371 return sprintf(buf, "%u\n", (sig & 0x000000FF)); 372 } 373 374 static ssize_t vback_porch_show(struct device *dev, 375 struct device_attribute *attr, char *buf) 376 { 377 struct video_device *vdev = to_video_device(dev); 378 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 379 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 380 vindev->config->regs.signal2); 381 382 return sprintf(buf, "%u\n", (sig & 0x0000FF00) >> 8); 383 } 384 385 static ssize_t vfront_porch_show(struct device *dev, 386 struct device_attribute *attr, char *buf) 387 { 388 struct video_device *vdev = to_video_device(dev); 389 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 390 u32 sig = mgb4_read_reg(&vindev->mgbdev->video, 391 vindev->config->regs.signal2); 392 393 return sprintf(buf, "%u\n", (sig & 0x000000FF)); 394 } 395 396 static ssize_t frequency_range_show(struct device *dev, 397 struct device_attribute *attr, char *buf) 398 { 399 struct video_device *vdev = to_video_device(dev); 400 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 401 402 return sprintf(buf, "%d\n", vindev->freq_range); 403 } 404 405 static ssize_t frequency_range_store(struct device *dev, 406 struct device_attribute *attr, 407 const char *buf, size_t count) 408 { 409 struct video_device *vdev = to_video_device(dev); 410 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 411 unsigned long val; 412 int ret; 413 414 ret = kstrtoul(buf, 10, &val); 415 if (ret) 416 return ret; 417 if (val > 1) 418 return -EINVAL; 419 420 mutex_lock(vindev->vdev.lock); 421 if (vb2_is_busy(vindev->vdev.queue)) { 422 mutex_unlock(vindev->vdev.lock); 423 return -EBUSY; 424 } 425 426 mgb4_cmt_set_vin_freq_range(vindev, val); 427 vindev->freq_range = val; 428 429 mutex_unlock(vindev->vdev.lock); 430 431 return count; 432 } 433 434 /* FPDL3 only */ 435 436 static ssize_t fpdl3_input_width_show(struct device *dev, 437 struct device_attribute *attr, char *buf) 438 { 439 struct video_device *vdev = to_video_device(dev); 440 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 441 s32 ret; 442 443 mutex_lock(&vindev->mgbdev->i2c_lock); 444 ret = mgb4_i2c_read_byte(&vindev->deser, 0x34); 445 mutex_unlock(&vindev->mgbdev->i2c_lock); 446 if (ret < 0) 447 return -EIO; 448 449 switch ((u8)ret & 0x18) { 450 case 0: 451 return sprintf(buf, "0\n"); 452 case 0x10: 453 return sprintf(buf, "1\n"); 454 case 0x08: 455 return sprintf(buf, "2\n"); 456 default: 457 return -EINVAL; 458 } 459 } 460 461 /* 462 * FPD-Link width change is expected to be called on live streams. Video device 463 * locking/queue check is not needed. 464 */ 465 static ssize_t fpdl3_input_width_store(struct device *dev, 466 struct device_attribute *attr, 467 const char *buf, size_t count) 468 { 469 struct video_device *vdev = to_video_device(dev); 470 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 471 u8 i2c_data; 472 unsigned long val; 473 int ret; 474 475 ret = kstrtoul(buf, 10, &val); 476 if (ret) 477 return ret; 478 479 switch (val) { 480 case 0: /* auto */ 481 i2c_data = 0x00; 482 break; 483 case 1: /* single */ 484 i2c_data = 0x10; 485 break; 486 case 2: /* dual */ 487 i2c_data = 0x08; 488 break; 489 default: 490 return -EINVAL; 491 } 492 493 mutex_lock(&vindev->mgbdev->i2c_lock); 494 ret = mgb4_i2c_mask_byte(&vindev->deser, 0x34, 0x18, i2c_data); 495 mutex_unlock(&vindev->mgbdev->i2c_lock); 496 if (ret < 0) 497 return -EIO; 498 499 return count; 500 } 501 502 /* GMSL only */ 503 504 static ssize_t gmsl_mode_show(struct device *dev, 505 struct device_attribute *attr, char *buf) 506 { 507 struct video_device *vdev = to_video_device(dev); 508 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 509 s32 r1, r300, r3; 510 511 mutex_lock(&vindev->mgbdev->i2c_lock); 512 r1 = mgb4_i2c_read_byte(&vindev->deser, 0x01); 513 r300 = mgb4_i2c_read_byte(&vindev->deser, 0x300); 514 r3 = mgb4_i2c_read_byte(&vindev->deser, 0x03); 515 mutex_unlock(&vindev->mgbdev->i2c_lock); 516 if (r1 < 0 || r300 < 0 || r3 < 0) 517 return -EIO; 518 519 if ((r1 & 0x03) == 0x03 && (r300 & 0x0C) == 0x0C && (r3 & 0xC0) == 0xC0) 520 return sprintf(buf, "0\n"); 521 else if ((r1 & 0x03) == 0x02 && (r300 & 0x0C) == 0x08 && (r3 & 0xC0) == 0x00) 522 return sprintf(buf, "1\n"); 523 else if ((r1 & 0x03) == 0x01 && (r300 & 0x0C) == 0x04 && (r3 & 0xC0) == 0x00) 524 return sprintf(buf, "2\n"); 525 else if ((r1 & 0x03) == 0x00 && (r300 & 0x0C) == 0x00 && (r3 & 0xC0) == 0x00) 526 return sprintf(buf, "3\n"); 527 else 528 return -EINVAL; 529 } 530 531 /* 532 * GMSL mode change is expected to be called on live streams. Video device 533 * locking/queue check is not needed. 534 */ 535 static ssize_t gmsl_mode_store(struct device *dev, 536 struct device_attribute *attr, const char *buf, 537 size_t count) 538 { 539 static const struct mgb4_i2c_kv G12[] = { 540 {0x01, 0x03, 0x03}, {0x300, 0x0C, 0x0C}, {0x03, 0xC0, 0xC0}}; 541 static const struct mgb4_i2c_kv G6[] = { 542 {0x01, 0x03, 0x02}, {0x300, 0x0C, 0x08}, {0x03, 0xC0, 0x00}}; 543 static const struct mgb4_i2c_kv G3[] = { 544 {0x01, 0x03, 0x01}, {0x300, 0x0C, 0x04}, {0x03, 0xC0, 0x00}}; 545 static const struct mgb4_i2c_kv G1[] = { 546 {0x01, 0x03, 0x00}, {0x300, 0x0C, 0x00}, {0x03, 0xC0, 0x00}}; 547 static const struct mgb4_i2c_kv reset[] = { 548 {0x10, 1U << 5, 1U << 5}, {0x300, 1U << 6, 1U << 6}}; 549 struct video_device *vdev = to_video_device(dev); 550 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 551 const struct mgb4_i2c_kv *values; 552 unsigned long val; 553 int ret; 554 555 ret = kstrtoul(buf, 10, &val); 556 if (ret) 557 return ret; 558 559 switch (val) { 560 case 0: /* 12Gb/s */ 561 values = G12; 562 break; 563 case 1: /* 6Gb/s */ 564 values = G6; 565 break; 566 case 2: /* 3Gb/s */ 567 values = G3; 568 break; 569 case 3: /* 1.5Gb/s */ 570 values = G1; 571 break; 572 default: 573 return -EINVAL; 574 } 575 576 mutex_lock(&vindev->mgbdev->i2c_lock); 577 ret = mgb4_i2c_configure(&vindev->deser, values, 3); 578 ret |= mgb4_i2c_configure(&vindev->deser, reset, 2); 579 mutex_unlock(&vindev->mgbdev->i2c_lock); 580 if (ret < 0) 581 return -EIO; 582 583 return count; 584 } 585 586 static ssize_t gmsl_stream_id_show(struct device *dev, 587 struct device_attribute *attr, char *buf) 588 { 589 struct video_device *vdev = to_video_device(dev); 590 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 591 s32 ret; 592 593 mutex_lock(&vindev->mgbdev->i2c_lock); 594 ret = mgb4_i2c_read_byte(&vindev->deser, 0xA0); 595 mutex_unlock(&vindev->mgbdev->i2c_lock); 596 if (ret < 0) 597 return -EIO; 598 599 return sprintf(buf, "%d\n", ret & 0x03); 600 } 601 602 static ssize_t gmsl_stream_id_store(struct device *dev, 603 struct device_attribute *attr, 604 const char *buf, size_t count) 605 { 606 struct video_device *vdev = to_video_device(dev); 607 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 608 unsigned long val; 609 int ret; 610 611 ret = kstrtoul(buf, 10, &val); 612 if (ret) 613 return ret; 614 if (val > 3) 615 return -EINVAL; 616 617 mutex_lock(vindev->vdev.lock); 618 if (vb2_is_busy(vindev->vdev.queue)) { 619 mutex_unlock(vindev->vdev.lock); 620 return -EBUSY; 621 } 622 623 mutex_lock(&vindev->mgbdev->i2c_lock); 624 ret = mgb4_i2c_mask_byte(&vindev->deser, 0xA0, 0x03, (u8)val); 625 mutex_unlock(&vindev->mgbdev->i2c_lock); 626 627 mutex_unlock(vindev->vdev.lock); 628 629 return (ret < 0) ? -EIO : count; 630 } 631 632 static ssize_t gmsl_fec_show(struct device *dev, struct device_attribute *attr, 633 char *buf) 634 { 635 struct video_device *vdev = to_video_device(dev); 636 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 637 s32 r3e0, r308; 638 639 mutex_lock(&vindev->mgbdev->i2c_lock); 640 r3e0 = mgb4_i2c_read_byte(&vindev->deser, 0x3E0); 641 r308 = mgb4_i2c_read_byte(&vindev->deser, 0x308); 642 mutex_unlock(&vindev->mgbdev->i2c_lock); 643 if (r3e0 < 0 || r308 < 0) 644 return -EIO; 645 646 if ((r3e0 & 0x07) == 0x00 && (r308 & 0x01) == 0x00) 647 return sprintf(buf, "0\n"); 648 else if ((r3e0 & 0x07) == 0x07 && (r308 & 0x01) == 0x01) 649 return sprintf(buf, "1\n"); 650 else 651 return -EINVAL; 652 } 653 654 /* 655 * GMSL FEC change is expected to be called on live streams. Video device 656 * locking/queue check is not needed. 657 */ 658 static ssize_t gmsl_fec_store(struct device *dev, struct device_attribute *attr, 659 const char *buf, size_t count) 660 { 661 struct video_device *vdev = to_video_device(dev); 662 struct mgb4_vin_dev *vindev = video_get_drvdata(vdev); 663 static const struct mgb4_i2c_kv enable[] = { 664 {0x3E0, 0x07, 0x07}, {0x308, 0x01, 0x01}}; 665 static const struct mgb4_i2c_kv disable[] = { 666 {0x3E0, 0x07, 0x00}, {0x308, 0x01, 0x00}}; 667 static const struct mgb4_i2c_kv reset[] = { 668 {0x10, 1U << 5, 1U << 5}, {0x300, 1U << 6, 1U << 6}}; 669 const struct mgb4_i2c_kv *values; 670 unsigned long val; 671 int ret; 672 673 ret = kstrtoul(buf, 10, &val); 674 if (ret) 675 return ret; 676 677 switch (val) { 678 case 0: /* disabled */ 679 values = disable; 680 break; 681 case 1: /* enabled */ 682 values = enable; 683 break; 684 default: 685 return -EINVAL; 686 } 687 688 mutex_lock(&vindev->mgbdev->i2c_lock); 689 ret = mgb4_i2c_configure(&vindev->deser, values, 2); 690 ret |= mgb4_i2c_configure(&vindev->deser, reset, 2); 691 mutex_unlock(&vindev->mgbdev->i2c_lock); 692 if (ret < 0) 693 return -EIO; 694 695 return count; 696 } 697 698 static DEVICE_ATTR_RO(input_id); 699 static DEVICE_ATTR_RW(oldi_lane_width); 700 static DEVICE_ATTR_RW(color_mapping); 701 static DEVICE_ATTR_RO(link_status); 702 static DEVICE_ATTR_RO(stream_status); 703 static DEVICE_ATTR_RO(video_width); 704 static DEVICE_ATTR_RO(video_height); 705 static DEVICE_ATTR_RO(hsync_status); 706 static DEVICE_ATTR_RO(vsync_status); 707 static DEVICE_ATTR_RW(hsync_gap_length); 708 static DEVICE_ATTR_RW(vsync_gap_length); 709 static DEVICE_ATTR_RO(pclk_frequency); 710 static DEVICE_ATTR_RO(hsync_width); 711 static DEVICE_ATTR_RO(vsync_width); 712 static DEVICE_ATTR_RO(hback_porch); 713 static DEVICE_ATTR_RO(hfront_porch); 714 static DEVICE_ATTR_RO(vback_porch); 715 static DEVICE_ATTR_RO(vfront_porch); 716 static DEVICE_ATTR_RW(frequency_range); 717 718 static DEVICE_ATTR_RW(fpdl3_input_width); 719 720 static DEVICE_ATTR_RW(gmsl_mode); 721 static DEVICE_ATTR_RW(gmsl_stream_id); 722 static DEVICE_ATTR_RW(gmsl_fec); 723 724 struct attribute *mgb4_fpdl3_in_attrs[] = { 725 &dev_attr_input_id.attr, 726 &dev_attr_link_status.attr, 727 &dev_attr_stream_status.attr, 728 &dev_attr_video_width.attr, 729 &dev_attr_video_height.attr, 730 &dev_attr_hsync_status.attr, 731 &dev_attr_vsync_status.attr, 732 &dev_attr_oldi_lane_width.attr, 733 &dev_attr_color_mapping.attr, 734 &dev_attr_hsync_gap_length.attr, 735 &dev_attr_vsync_gap_length.attr, 736 &dev_attr_pclk_frequency.attr, 737 &dev_attr_hsync_width.attr, 738 &dev_attr_vsync_width.attr, 739 &dev_attr_hback_porch.attr, 740 &dev_attr_hfront_porch.attr, 741 &dev_attr_vback_porch.attr, 742 &dev_attr_vfront_porch.attr, 743 &dev_attr_frequency_range.attr, 744 &dev_attr_fpdl3_input_width.attr, 745 NULL 746 }; 747 748 struct attribute *mgb4_gmsl_in_attrs[] = { 749 &dev_attr_input_id.attr, 750 &dev_attr_link_status.attr, 751 &dev_attr_stream_status.attr, 752 &dev_attr_video_width.attr, 753 &dev_attr_video_height.attr, 754 &dev_attr_hsync_status.attr, 755 &dev_attr_vsync_status.attr, 756 &dev_attr_oldi_lane_width.attr, 757 &dev_attr_color_mapping.attr, 758 &dev_attr_hsync_gap_length.attr, 759 &dev_attr_vsync_gap_length.attr, 760 &dev_attr_pclk_frequency.attr, 761 &dev_attr_hsync_width.attr, 762 &dev_attr_vsync_width.attr, 763 &dev_attr_hback_porch.attr, 764 &dev_attr_hfront_porch.attr, 765 &dev_attr_vback_porch.attr, 766 &dev_attr_vfront_porch.attr, 767 &dev_attr_frequency_range.attr, 768 &dev_attr_gmsl_mode.attr, 769 &dev_attr_gmsl_stream_id.attr, 770 &dev_attr_gmsl_fec.attr, 771 NULL 772 }; 773