brintos

brintos / linux-shallow public Read only

0
0
Text · 20.6 KiB · 0ba66a2 Raw
773 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2021-2023 Digiteq Automotive4 *     author: Martin Tuma <martin.tuma@digiteqautomotive.com>5 *6 * This module handles all the sysfs info/configuration that is related to the7 * 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 19static 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 28static 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 device63 * locking/queue check is not needed.64 */65static 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 117static 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 device130 * locking/queue check is not needed.131 */132static 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 163static 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 174static 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 186static 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 197static 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 208static 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 available219	else if (status & (1U << 12))220		res = 0x01; // active high221	else222		res = 0x00; // active low223 224	return sprintf(buf, "%u\n", res);225}226 227static 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 available238	else if (status & (1U << 13))239		res = 0x01; // active high240	else241		res = 0x00; // active low242 243	return sprintf(buf, "%u\n", res);244}245 246static 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. Video260 * device locking/queue check is not needed.261 */262static 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 283static 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. Video296 * device locking/queue check is not needed.297 */298static 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 319static 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 330static 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 341static 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 352static 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 363static 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 374static 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 385static 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 396static 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 405static 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 436static 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 device463 * locking/queue check is not needed.464 */465static 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 504static 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	else528		return -EINVAL;529}530 531/*532 * GMSL mode change is expected to be called on live streams. Video device533 * locking/queue check is not needed.534 */535static 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 586static 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 602static 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 632static 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	else651		return -EINVAL;652}653 654/*655 * GMSL FEC change is expected to be called on live streams. Video device656 * locking/queue check is not needed.657 */658static 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 698static DEVICE_ATTR_RO(input_id);699static DEVICE_ATTR_RW(oldi_lane_width);700static DEVICE_ATTR_RW(color_mapping);701static DEVICE_ATTR_RO(link_status);702static DEVICE_ATTR_RO(stream_status);703static DEVICE_ATTR_RO(video_width);704static DEVICE_ATTR_RO(video_height);705static DEVICE_ATTR_RO(hsync_status);706static DEVICE_ATTR_RO(vsync_status);707static DEVICE_ATTR_RW(hsync_gap_length);708static DEVICE_ATTR_RW(vsync_gap_length);709static DEVICE_ATTR_RO(pclk_frequency);710static DEVICE_ATTR_RO(hsync_width);711static DEVICE_ATTR_RO(vsync_width);712static DEVICE_ATTR_RO(hback_porch);713static DEVICE_ATTR_RO(hfront_porch);714static DEVICE_ATTR_RO(vback_porch);715static DEVICE_ATTR_RO(vfront_porch);716static DEVICE_ATTR_RW(frequency_range);717 718static DEVICE_ATTR_RW(fpdl3_input_width);719 720static DEVICE_ATTR_RW(gmsl_mode);721static DEVICE_ATTR_RW(gmsl_stream_id);722static DEVICE_ATTR_RW(gmsl_fec);723 724struct 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	NULL746};747 748struct 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	NULL772};773