]> Git Repo - linux.git/blob - drivers/media/pci/mgb4/mgb4_sysfs_out.c
Linux 6.14-rc3
[linux.git] / drivers / media / pci / mgb4 / mgb4_sysfs_out.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2021-2023 Digiteq Automotive
4  *     author: Martin Tuma <[email protected]>
5  *
6  * This module handles all the sysfs info/configuration that is related to the
7  * v4l2 output devices.
8  */
9
10 #include <linux/device.h>
11 #include <linux/nospec.h>
12 #include "mgb4_core.h"
13 #include "mgb4_i2c.h"
14 #include "mgb4_vout.h"
15 #include "mgb4_vin.h"
16 #include "mgb4_cmt.h"
17 #include "mgb4_sysfs.h"
18
19 static int loopin_cnt(struct mgb4_vin_dev *vindev)
20 {
21         struct mgb4_vout_dev *voutdev;
22         u32 config;
23         int i, cnt = 0;
24
25         for (i = 0; i < MGB4_VOUT_DEVICES; i++) {
26                 voutdev = vindev->mgbdev->vout[i];
27                 if (!voutdev)
28                         continue;
29
30                 config = mgb4_read_reg(&voutdev->mgbdev->video,
31                                        voutdev->config->regs.config);
32                 if ((config & 0xc) >> 2 == vindev->config->id)
33                         cnt++;
34         }
35
36         return cnt;
37 }
38
39 static bool is_busy(struct video_device *dev)
40 {
41         bool ret;
42
43         mutex_lock(dev->lock);
44         ret = vb2_is_busy(dev->queue);
45         mutex_unlock(dev->lock);
46
47         return ret;
48 }
49
50 /* Common for both FPDL3 and GMSL */
51
52 static ssize_t output_id_show(struct device *dev,
53                               struct device_attribute *attr, char *buf)
54 {
55         struct video_device *vdev = to_video_device(dev);
56         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
57
58         return sprintf(buf, "%d\n", voutdev->config->id);
59 }
60
61 static ssize_t video_source_show(struct device *dev,
62                                  struct device_attribute *attr, char *buf)
63 {
64         struct video_device *vdev = to_video_device(dev);
65         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
66         u32 config = mgb4_read_reg(&voutdev->mgbdev->video,
67           voutdev->config->regs.config);
68
69         return sprintf(buf, "%u\n", (config & 0xc) >> 2);
70 }
71
72 /*
73  * Video source change may affect the buffer queue of ANY video input/output on
74  * the card thus if any of the inputs/outputs is in use, we do not allow
75  * the change.
76  *
77  * As we do not want to lock all the video devices at the same time, a two-stage
78  * locking strategy is used. In addition to the video device locking there is
79  * a global (PCI device) variable "io_reconfig" atomically checked/set when
80  * the reconfiguration is running. All the video devices check the variable in
81  * their queue_setup() functions and do not allow to start the queue when
82  * the reconfiguration has started.
83  */
84 static ssize_t video_source_store(struct device *dev,
85                                   struct device_attribute *attr,
86                                   const char *buf, size_t count)
87 {
88         struct video_device *vdev = to_video_device(dev);
89         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
90         struct mgb4_dev *mgbdev = voutdev->mgbdev;
91         struct mgb4_vin_dev *loopin_new = NULL, *loopin_old = NULL;
92         unsigned long val;
93         ssize_t ret;
94         u32 config;
95         int i;
96
97         ret = kstrtoul(buf, 10, &val);
98         if (ret)
99                 return ret;
100         if (val > 3)
101                 return -EINVAL;
102
103         if (test_and_set_bit(0, &mgbdev->io_reconfig))
104                 return -EBUSY;
105
106         ret = -EBUSY;
107         for (i = 0; i < MGB4_VIN_DEVICES; i++)
108                 if (mgbdev->vin[i] && is_busy(&mgbdev->vin[i]->vdev))
109                         goto end;
110         for (i = 0; i < MGB4_VOUT_DEVICES; i++)
111                 if (mgbdev->vout[i] && is_busy(&mgbdev->vout[i]->vdev))
112                         goto end;
113
114         config = mgb4_read_reg(&mgbdev->video, voutdev->config->regs.config);
115
116         if (((config & 0xc) >> 2) < MGB4_VIN_DEVICES)
117                 loopin_old = mgbdev->vin[(config & 0xc) >> 2];
118         if (val < MGB4_VIN_DEVICES) {
119                 val = array_index_nospec(val, MGB4_VIN_DEVICES);
120                 loopin_new = mgbdev->vin[val];
121         }
122         if (loopin_old && loopin_cnt(loopin_old) == 1)
123                 mgb4_mask_reg(&mgbdev->video, loopin_old->config->regs.config,
124                               0x2, 0x0);
125         if (loopin_new)
126                 mgb4_mask_reg(&mgbdev->video, loopin_new->config->regs.config,
127                               0x2, 0x2);
128
129         if (val == voutdev->config->id + MGB4_VIN_DEVICES)
130                 mgb4_write_reg(&mgbdev->video, voutdev->config->regs.config,
131                                config & ~(1 << 1));
132         else
133                 mgb4_write_reg(&mgbdev->video, voutdev->config->regs.config,
134                                config | (1U << 1));
135
136         mgb4_mask_reg(&mgbdev->video, voutdev->config->regs.config, 0xc,
137                       val << 2);
138
139         ret = count;
140 end:
141         clear_bit(0, &mgbdev->io_reconfig);
142
143         return ret;
144 }
145
146 static ssize_t display_width_show(struct device *dev,
147                                   struct device_attribute *attr, char *buf)
148 {
149         struct video_device *vdev = to_video_device(dev);
150         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
151         u32 config = mgb4_read_reg(&voutdev->mgbdev->video,
152           voutdev->config->regs.resolution);
153
154         return sprintf(buf, "%u\n", config >> 16);
155 }
156
157 static ssize_t display_width_store(struct device *dev,
158                                    struct device_attribute *attr,
159                                    const char *buf, size_t count)
160 {
161         struct video_device *vdev = to_video_device(dev);
162         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
163         unsigned long val;
164         int ret;
165
166         ret = kstrtoul(buf, 10, &val);
167         if (ret)
168                 return ret;
169         if (val > 0xFFFF)
170                 return -EINVAL;
171
172         mutex_lock(voutdev->vdev.lock);
173         if (vb2_is_busy(voutdev->vdev.queue)) {
174                 mutex_unlock(voutdev->vdev.lock);
175                 return -EBUSY;
176         }
177
178         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.resolution,
179                       0xFFFF0000, val << 16);
180
181         mutex_unlock(voutdev->vdev.lock);
182
183         return count;
184 }
185
186 static ssize_t display_height_show(struct device *dev,
187                                    struct device_attribute *attr, char *buf)
188 {
189         struct video_device *vdev = to_video_device(dev);
190         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
191         u32 config = mgb4_read_reg(&voutdev->mgbdev->video,
192           voutdev->config->regs.resolution);
193
194         return sprintf(buf, "%u\n", config & 0xFFFF);
195 }
196
197 static ssize_t display_height_store(struct device *dev,
198                                     struct device_attribute *attr,
199                                     const char *buf, size_t count)
200 {
201         struct video_device *vdev = to_video_device(dev);
202         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
203         unsigned long val;
204         int ret;
205
206         ret = kstrtoul(buf, 10, &val);
207         if (ret)
208                 return ret;
209         if (val > 0xFFFF)
210                 return -EINVAL;
211
212         mutex_lock(voutdev->vdev.lock);
213         if (vb2_is_busy(voutdev->vdev.queue)) {
214                 mutex_unlock(voutdev->vdev.lock);
215                 return -EBUSY;
216         }
217
218         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.resolution,
219                       0xFFFF, val);
220
221         mutex_unlock(voutdev->vdev.lock);
222
223         return count;
224 }
225
226 static ssize_t frame_rate_show(struct device *dev,
227                                struct device_attribute *attr, char *buf)
228 {
229         struct video_device *vdev = to_video_device(dev);
230         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
231         u32 period = mgb4_read_reg(&voutdev->mgbdev->video,
232                                    voutdev->config->regs.frame_limit);
233
234         return sprintf(buf, "%u\n", period ? MGB4_HW_FREQ / period : 0);
235 }
236
237 /*
238  * Frame rate change is expected to be called on live streams. Video device
239  * locking/queue check is not needed.
240  */
241 static ssize_t frame_rate_store(struct device *dev,
242                                 struct device_attribute *attr, const char *buf,
243                                 size_t count)
244 {
245         struct video_device *vdev = to_video_device(dev);
246         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
247         unsigned long val;
248         int limit, ret;
249
250         ret = kstrtoul(buf, 10, &val);
251         if (ret)
252                 return ret;
253
254         limit = val ? MGB4_HW_FREQ / val : 0;
255         mgb4_write_reg(&voutdev->mgbdev->video,
256                        voutdev->config->regs.frame_limit, limit);
257
258         return count;
259 }
260
261 static ssize_t hsync_width_show(struct device *dev,
262                                 struct device_attribute *attr, char *buf)
263 {
264         struct video_device *vdev = to_video_device(dev);
265         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
266         u32 sig = mgb4_read_reg(&voutdev->mgbdev->video,
267                                 voutdev->config->regs.hsync);
268
269         return sprintf(buf, "%u\n", (sig & 0x00FF0000) >> 16);
270 }
271
272 /*
273  * HSYNC width change is expected to be called on live streams. Video device
274  * locking/queue check is not needed.
275  */
276 static ssize_t hsync_width_store(struct device *dev,
277                                  struct device_attribute *attr, const char *buf,
278                                  size_t count)
279 {
280         struct video_device *vdev = to_video_device(dev);
281         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
282         unsigned long val;
283         int ret;
284
285         ret = kstrtoul(buf, 10, &val);
286         if (ret)
287                 return ret;
288         if (val > 0xFF)
289                 return -EINVAL;
290
291         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.hsync,
292                       0x00FF0000, val << 16);
293
294         return count;
295 }
296
297 static ssize_t vsync_width_show(struct device *dev,
298                                 struct device_attribute *attr, char *buf)
299 {
300         struct video_device *vdev = to_video_device(dev);
301         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
302         u32 sig = mgb4_read_reg(&voutdev->mgbdev->video,
303                                 voutdev->config->regs.vsync);
304
305         return sprintf(buf, "%u\n", (sig & 0x00FF0000) >> 16);
306 }
307
308 /*
309  * VSYNC vidth change is expected to be called on live streams. Video device
310  * locking/queue check is not needed.
311  */
312 static ssize_t vsync_width_store(struct device *dev,
313                                  struct device_attribute *attr, const char *buf,
314                                  size_t count)
315 {
316         struct video_device *vdev = to_video_device(dev);
317         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
318         unsigned long val;
319         int ret;
320
321         ret = kstrtoul(buf, 10, &val);
322         if (ret)
323                 return ret;
324         if (val > 0xFF)
325                 return -EINVAL;
326
327         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.vsync,
328                       0x00FF0000, val << 16);
329
330         return count;
331 }
332
333 static ssize_t hback_porch_show(struct device *dev,
334                                 struct device_attribute *attr, char *buf)
335 {
336         struct video_device *vdev = to_video_device(dev);
337         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
338         u32 sig = mgb4_read_reg(&voutdev->mgbdev->video,
339                                 voutdev->config->regs.hsync);
340
341         return sprintf(buf, "%u\n", (sig & 0x0000FF00) >> 8);
342 }
343
344 /*
345  * hback porch change is expected to be called on live streams. Video device
346  * locking/queue check is not needed.
347  */
348 static ssize_t hback_porch_store(struct device *dev,
349                                  struct device_attribute *attr, const char *buf,
350                                  size_t count)
351 {
352         struct video_device *vdev = to_video_device(dev);
353         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
354         unsigned long val;
355         int ret;
356
357         ret = kstrtoul(buf, 10, &val);
358         if (ret)
359                 return ret;
360         if (val > 0xFF)
361                 return -EINVAL;
362
363         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.hsync,
364                       0x0000FF00, val << 8);
365
366         return count;
367 }
368
369 static ssize_t vback_porch_show(struct device *dev,
370                                 struct device_attribute *attr, char *buf)
371 {
372         struct video_device *vdev = to_video_device(dev);
373         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
374         u32 sig = mgb4_read_reg(&voutdev->mgbdev->video,
375                                 voutdev->config->regs.vsync);
376
377         return sprintf(buf, "%u\n", (sig & 0x0000FF00) >> 8);
378 }
379
380 /*
381  * vback porch change is expected to be called on live streams. Video device
382  * locking/queue check is not needed.
383  */
384 static ssize_t vback_porch_store(struct device *dev,
385                                  struct device_attribute *attr, const char *buf,
386                                  size_t count)
387 {
388         struct video_device *vdev = to_video_device(dev);
389         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
390         unsigned long val;
391         int ret;
392
393         ret = kstrtoul(buf, 10, &val);
394         if (ret)
395                 return ret;
396         if (val > 0xFF)
397                 return -EINVAL;
398
399         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.vsync,
400                       0x0000FF00, val << 8);
401
402         return count;
403 }
404
405 static ssize_t hfront_porch_show(struct device *dev,
406                                  struct device_attribute *attr, char *buf)
407 {
408         struct video_device *vdev = to_video_device(dev);
409         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
410         u32 sig = mgb4_read_reg(&voutdev->mgbdev->video,
411                                 voutdev->config->regs.hsync);
412
413         return sprintf(buf, "%u\n", (sig & 0x000000FF));
414 }
415
416 /*
417  * hfront porch change is expected to be called on live streams. Video device
418  * locking/queue check is not needed.
419  */
420 static ssize_t hfront_porch_store(struct device *dev,
421                                   struct device_attribute *attr,
422                                   const char *buf, size_t count)
423 {
424         struct video_device *vdev = to_video_device(dev);
425         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
426         unsigned long val;
427         int ret;
428
429         ret = kstrtoul(buf, 10, &val);
430         if (ret)
431                 return ret;
432         if (val > 0xFF)
433                 return -EINVAL;
434
435         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.hsync,
436                       0x000000FF, val);
437
438         return count;
439 }
440
441 static ssize_t vfront_porch_show(struct device *dev,
442                                  struct device_attribute *attr, char *buf)
443 {
444         struct video_device *vdev = to_video_device(dev);
445         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
446         u32 sig = mgb4_read_reg(&voutdev->mgbdev->video,
447                                 voutdev->config->regs.vsync);
448
449         return sprintf(buf, "%u\n", (sig & 0x000000FF));
450 }
451
452 /*
453  * vfront porch change is expected to be called on live streams. Video device
454  * locking/queue check is not needed.
455  */
456 static ssize_t vfront_porch_store(struct device *dev,
457                                   struct device_attribute *attr, const char *buf,
458                                   size_t count)
459 {
460         struct video_device *vdev = to_video_device(dev);
461         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
462         unsigned long val;
463         int ret;
464
465         ret = kstrtoul(buf, 10, &val);
466         if (ret)
467                 return ret;
468         if (val > 0xFF)
469                 return -EINVAL;
470
471         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.vsync,
472                       0x000000FF, val);
473
474         return count;
475 }
476
477 /* FPDL3 only */
478
479 static ssize_t hsync_polarity_show(struct device *dev,
480                                    struct device_attribute *attr, char *buf)
481 {
482         struct video_device *vdev = to_video_device(dev);
483         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
484         u32 config = mgb4_read_reg(&voutdev->mgbdev->video,
485           voutdev->config->regs.hsync);
486
487         return sprintf(buf, "%u\n", (config & (1U << 31)) >> 31);
488 }
489
490 /*
491  * HSYNC polarity change is expected to be called on live streams. Video device
492  * locking/queue check is not needed.
493  */
494 static ssize_t hsync_polarity_store(struct device *dev,
495                                     struct device_attribute *attr,
496                                     const char *buf, size_t count)
497 {
498         struct video_device *vdev = to_video_device(dev);
499         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
500         unsigned long val;
501         int ret;
502
503         ret = kstrtoul(buf, 10, &val);
504         if (ret)
505                 return ret;
506         if (val > 1)
507                 return -EINVAL;
508
509         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.hsync,
510                       (1U << 31), val << 31);
511
512         return count;
513 }
514
515 static ssize_t vsync_polarity_show(struct device *dev,
516                                    struct device_attribute *attr, char *buf)
517 {
518         struct video_device *vdev = to_video_device(dev);
519         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
520         u32 config = mgb4_read_reg(&voutdev->mgbdev->video,
521           voutdev->config->regs.vsync);
522
523         return sprintf(buf, "%u\n", (config & (1U << 31)) >> 31);
524 }
525
526 /*
527  * VSYNC polarity change is expected to be called on live streams. Video device
528  * locking/queue check is not needed.
529  */
530 static ssize_t vsync_polarity_store(struct device *dev,
531                                     struct device_attribute *attr,
532                                     const char *buf, size_t count)
533 {
534         struct video_device *vdev = to_video_device(dev);
535         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
536         unsigned long val;
537         int ret;
538
539         ret = kstrtoul(buf, 10, &val);
540         if (ret)
541                 return ret;
542         if (val > 1)
543                 return -EINVAL;
544
545         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.vsync,
546                       (1U << 31), val << 31);
547
548         return count;
549 }
550
551 static ssize_t de_polarity_show(struct device *dev,
552                                 struct device_attribute *attr, char *buf)
553 {
554         struct video_device *vdev = to_video_device(dev);
555         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
556         u32 config = mgb4_read_reg(&voutdev->mgbdev->video,
557           voutdev->config->regs.vsync);
558
559         return sprintf(buf, "%u\n", (config & (1U << 30)) >> 30);
560 }
561
562 /*
563  * DE polarity change is expected to be called on live streams. Video device
564  * locking/queue check is not needed.
565  */
566 static ssize_t de_polarity_store(struct device *dev,
567                                  struct device_attribute *attr, const char *buf,
568                                  size_t count)
569 {
570         struct video_device *vdev = to_video_device(dev);
571         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
572         unsigned long val;
573         int ret;
574
575         ret = kstrtoul(buf, 10, &val);
576         if (ret)
577                 return ret;
578         if (val > 1)
579                 return -EINVAL;
580
581         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.vsync,
582                       (1U << 30), val << 30);
583
584         return count;
585 }
586
587 static ssize_t fpdl3_output_width_show(struct device *dev,
588                                        struct device_attribute *attr, char *buf)
589 {
590         struct video_device *vdev = to_video_device(dev);
591         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
592         s32 ret;
593
594         mutex_lock(&voutdev->mgbdev->i2c_lock);
595         ret = mgb4_i2c_read_byte(&voutdev->ser, 0x5B);
596         mutex_unlock(&voutdev->mgbdev->i2c_lock);
597         if (ret < 0)
598                 return -EIO;
599
600         switch ((u8)ret & 0x03) {
601         case 0:
602                 return sprintf(buf, "0\n");
603         case 1:
604                 return sprintf(buf, "1\n");
605         case 3:
606                 return sprintf(buf, "2\n");
607         default:
608                 return -EINVAL;
609         }
610 }
611
612 /*
613  * FPD-Link width change is expected to be called on live streams. Video device
614  * locking/queue check is not needed.
615  */
616 static ssize_t fpdl3_output_width_store(struct device *dev,
617                                         struct device_attribute *attr,
618                                         const char *buf, size_t count)
619 {
620         struct video_device *vdev = to_video_device(dev);
621         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
622         u8 i2c_data;
623         unsigned long val;
624         int ret;
625
626         ret = kstrtoul(buf, 10, &val);
627         if (ret)
628                 return ret;
629
630         switch (val) {
631         case 0: /* auto */
632                 i2c_data = 0x00;
633                 break;
634         case 1: /* single */
635                 i2c_data = 0x01;
636                 break;
637         case 2: /* dual */
638                 i2c_data = 0x03;
639                 break;
640         default:
641                 return -EINVAL;
642         }
643
644         mutex_lock(&voutdev->mgbdev->i2c_lock);
645         ret = mgb4_i2c_mask_byte(&voutdev->ser, 0x5B, 0x03, i2c_data);
646         mutex_unlock(&voutdev->mgbdev->i2c_lock);
647         if (ret < 0)
648                 return -EIO;
649
650         return count;
651 }
652
653 static ssize_t pclk_frequency_show(struct device *dev,
654                                    struct device_attribute *attr, char *buf)
655 {
656         struct video_device *vdev = to_video_device(dev);
657         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
658
659         return sprintf(buf, "%u\n", voutdev->freq);
660 }
661
662 static ssize_t pclk_frequency_store(struct device *dev,
663                                     struct device_attribute *attr,
664                                     const char *buf, size_t count)
665 {
666         struct video_device *vdev = to_video_device(dev);
667         struct mgb4_vout_dev *voutdev = video_get_drvdata(vdev);
668         unsigned long val;
669         int ret;
670         unsigned int dp;
671
672         ret = kstrtoul(buf, 10, &val);
673         if (ret)
674                 return ret;
675
676         mutex_lock(voutdev->vdev.lock);
677         if (vb2_is_busy(voutdev->vdev.queue)) {
678                 mutex_unlock(voutdev->vdev.lock);
679                 return -EBUSY;
680         }
681
682         dp = (val > 50000) ? 1 : 0;
683         voutdev->freq = mgb4_cmt_set_vout_freq(voutdev, val >> dp) << dp;
684
685         mgb4_mask_reg(&voutdev->mgbdev->video, voutdev->config->regs.config,
686                       0x10, dp << 4);
687         mutex_lock(&voutdev->mgbdev->i2c_lock);
688         ret = mgb4_i2c_mask_byte(&voutdev->ser, 0x4F, 1 << 6, ((~dp) & 1) << 6);
689         mutex_unlock(&voutdev->mgbdev->i2c_lock);
690
691         mutex_unlock(voutdev->vdev.lock);
692
693         return (ret < 0) ? -EIO : count;
694 }
695
696 static DEVICE_ATTR_RO(output_id);
697 static DEVICE_ATTR_RW(video_source);
698 static DEVICE_ATTR_RW(display_width);
699 static DEVICE_ATTR_RW(display_height);
700 static DEVICE_ATTR_RW(frame_rate);
701 static DEVICE_ATTR_RW(hsync_polarity);
702 static DEVICE_ATTR_RW(vsync_polarity);
703 static DEVICE_ATTR_RW(de_polarity);
704 static DEVICE_ATTR_RW(pclk_frequency);
705 static DEVICE_ATTR_RW(hsync_width);
706 static DEVICE_ATTR_RW(vsync_width);
707 static DEVICE_ATTR_RW(hback_porch);
708 static DEVICE_ATTR_RW(hfront_porch);
709 static DEVICE_ATTR_RW(vback_porch);
710 static DEVICE_ATTR_RW(vfront_porch);
711
712 static DEVICE_ATTR_RW(fpdl3_output_width);
713
714 struct attribute *mgb4_fpdl3_out_attrs[] = {
715         &dev_attr_output_id.attr,
716         &dev_attr_video_source.attr,
717         &dev_attr_display_width.attr,
718         &dev_attr_display_height.attr,
719         &dev_attr_frame_rate.attr,
720         &dev_attr_hsync_polarity.attr,
721         &dev_attr_vsync_polarity.attr,
722         &dev_attr_de_polarity.attr,
723         &dev_attr_pclk_frequency.attr,
724         &dev_attr_hsync_width.attr,
725         &dev_attr_vsync_width.attr,
726         &dev_attr_hback_porch.attr,
727         &dev_attr_hfront_porch.attr,
728         &dev_attr_vback_porch.attr,
729         &dev_attr_vfront_porch.attr,
730         &dev_attr_fpdl3_output_width.attr,
731         NULL
732 };
733
734 struct attribute *mgb4_gmsl_out_attrs[] = {
735         &dev_attr_output_id.attr,
736         &dev_attr_video_source.attr,
737         &dev_attr_display_width.attr,
738         &dev_attr_display_height.attr,
739         &dev_attr_frame_rate.attr,
740         NULL
741 };
This page took 0.072178 seconds and 4 git commands to generate.