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
input_id_show(struct device * dev,struct device_attribute * attr,char * buf)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
oldi_lane_width_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
oldi_lane_width_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
color_mapping_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
color_mapping_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
link_status_show(struct device * dev,struct device_attribute * attr,char * buf)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
stream_status_show(struct device * dev,struct device_attribute * attr,char * buf)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
video_width_show(struct device * dev,struct device_attribute * attr,char * buf)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
video_height_show(struct device * dev,struct device_attribute * attr,char * buf)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
hsync_status_show(struct device * dev,struct device_attribute * attr,char * buf)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
vsync_status_show(struct device * dev,struct device_attribute * attr,char * buf)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
hsync_gap_length_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
hsync_gap_length_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
vsync_gap_length_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
vsync_gap_length_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
pclk_frequency_show(struct device * dev,struct device_attribute * attr,char * buf)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
hsync_width_show(struct device * dev,struct device_attribute * attr,char * buf)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
vsync_width_show(struct device * dev,struct device_attribute * attr,char * buf)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
hback_porch_show(struct device * dev,struct device_attribute * attr,char * buf)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
hfront_porch_show(struct device * dev,struct device_attribute * attr,char * buf)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
vback_porch_show(struct device * dev,struct device_attribute * attr,char * buf)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
vfront_porch_show(struct device * dev,struct device_attribute * attr,char * buf)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
frequency_range_show(struct device * dev,struct device_attribute * attr,char * buf)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
frequency_range_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
fpdl3_input_width_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
fpdl3_input_width_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
gmsl_mode_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
gmsl_mode_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
gmsl_stream_id_show(struct device * dev,struct device_attribute * attr,char * buf)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
gmsl_stream_id_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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
gmsl_fec_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
gmsl_fec_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)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