xref: /openbmc/linux/drivers/media/i2c/isl7998x.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1  // SPDX-License-Identifier: GPL-2.0
2  /*
3   * Intersil ISL7998x analog to MIPI CSI-2 or BT.656 decoder driver.
4   *
5   * Copyright (C) 2018-2019 Marek Vasut <marex@denx.de>
6   * Copyright (C) 2021 Michael Tretter <kernel@pengutronix.de>
7   */
8  
9  #include <linux/bitfield.h>
10  #include <linux/delay.h>
11  #include <linux/gpio/consumer.h>
12  #include <linux/i2c.h>
13  #include <linux/module.h>
14  #include <linux/of_graph.h>
15  #include <linux/pm_runtime.h>
16  #include <linux/regmap.h>
17  #include <linux/slab.h>
18  #include <linux/v4l2-mediabus.h>
19  #include <linux/videodev2.h>
20  
21  #include <media/v4l2-async.h>
22  #include <media/v4l2-common.h>
23  #include <media/v4l2-ctrls.h>
24  #include <media/v4l2-device.h>
25  #include <media/v4l2-fwnode.h>
26  #include <media/v4l2-ioctl.h>
27  
28  /*
29   * This control allows to activate and deactivate the test pattern on
30   * selected output channels.
31   * This value is ISL7998x specific.
32   */
33  #define V4L2_CID_TEST_PATTERN_CHANNELS	(V4L2_CID_USER_ISL7998X_BASE + 0)
34  
35  /*
36   * This control allows to specify the color of the test pattern.
37   * This value is ISL7998x specific.
38   */
39  #define V4L2_CID_TEST_PATTERN_COLOR	(V4L2_CID_USER_ISL7998X_BASE + 1)
40  
41  /*
42   * This control allows to specify the bar pattern in the test pattern.
43   * This value is ISL7998x specific.
44   */
45  #define V4L2_CID_TEST_PATTERN_BARS	(V4L2_CID_USER_ISL7998X_BASE + 2)
46  
47  #define ISL7998X_INPUTS			4
48  
49  #define ISL7998X_REG(page, reg)		(((page) << 8) | (reg))
50  
51  #define ISL7998X_REG_PN_SIZE			256
52  #define ISL7998X_REG_PN_BASE(n)			((n) * ISL7998X_REG_PN_SIZE)
53  
54  #define ISL7998X_REG_PX_DEC_PAGE(page)		ISL7998X_REG((page), 0xff)
55  #define ISL7998X_REG_PX_DEC_PAGE_MASK		0xf
56  #define ISL7998X_REG_P0_PRODUCT_ID_CODE		ISL7998X_REG(0, 0x00)
57  #define ISL7998X_REG_P0_PRODUCT_REV_CODE	ISL7998X_REG(0, 0x01)
58  #define ISL7998X_REG_P0_SW_RESET_CTL		ISL7998X_REG(0, 0x02)
59  #define ISL7998X_REG_P0_IO_BUFFER_CTL		ISL7998X_REG(0, 0x03)
60  #define ISL7998X_REG_P0_IO_BUFFER_CTL_1_1	ISL7998X_REG(0, 0x04)
61  #define ISL7998X_REG_P0_IO_PAD_PULL_EN_CTL	ISL7998X_REG(0, 0x05)
62  #define ISL7998X_REG_P0_IO_BUFFER_CTL_1_2	ISL7998X_REG(0, 0x06)
63  #define ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL	ISL7998X_REG(0, 0x07)
64  #define ISL7998X_REG_P0_CLK_CTL_1		ISL7998X_REG(0, 0x08)
65  #define ISL7998X_REG_P0_CLK_CTL_2		ISL7998X_REG(0, 0x09)
66  #define ISL7998X_REG_P0_CLK_CTL_3		ISL7998X_REG(0, 0x0a)
67  #define ISL7998X_REG_P0_CLK_CTL_4		ISL7998X_REG(0, 0x0b)
68  #define ISL7998X_REG_P0_MPP1_SYNC_CTL		ISL7998X_REG(0, 0x0c)
69  #define ISL7998X_REG_P0_MPP2_SYNC_CTL		ISL7998X_REG(0, 0x0d)
70  #define ISL7998X_REG_P0_IRQ_SYNC_CTL		ISL7998X_REG(0, 0x0e)
71  #define ISL7998X_REG_P0_INTERRUPT_STATUS	ISL7998X_REG(0, 0x10)
72  #define ISL7998X_REG_P0_CHAN_1_IRQ		ISL7998X_REG(0, 0x11)
73  #define ISL7998X_REG_P0_CHAN_2_IRQ		ISL7998X_REG(0, 0x12)
74  #define ISL7998X_REG_P0_CHAN_3_IRQ		ISL7998X_REG(0, 0x13)
75  #define ISL7998X_REG_P0_CHAN_4_IRQ		ISL7998X_REG(0, 0x14)
76  #define ISL7998X_REG_P0_SHORT_DIAG_IRQ		ISL7998X_REG(0, 0x15)
77  #define ISL7998X_REG_P0_CHAN_1_IRQ_EN		ISL7998X_REG(0, 0x16)
78  #define ISL7998X_REG_P0_CHAN_2_IRQ_EN		ISL7998X_REG(0, 0x17)
79  #define ISL7998X_REG_P0_CHAN_3_IRQ_EN		ISL7998X_REG(0, 0x18)
80  #define ISL7998X_REG_P0_CHAN_4_IRQ_EN		ISL7998X_REG(0, 0x19)
81  #define ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN	ISL7998X_REG(0, 0x1a)
82  #define ISL7998X_REG_P0_CHAN_1_STATUS		ISL7998X_REG(0, 0x1b)
83  #define ISL7998X_REG_P0_CHAN_2_STATUS		ISL7998X_REG(0, 0x1c)
84  #define ISL7998X_REG_P0_CHAN_3_STATUS		ISL7998X_REG(0, 0x1d)
85  #define ISL7998X_REG_P0_CHAN_4_STATUS		ISL7998X_REG(0, 0x1e)
86  #define ISL7998X_REG_P0_SHORT_DIAG_STATUS	ISL7998X_REG(0, 0x1f)
87  #define ISL7998X_REG_P0_CLOCK_DELAY		ISL7998X_REG(0, 0x20)
88  
89  #define ISL7998X_REG_PX_DEC_INPUT_FMT(pg)	ISL7998X_REG((pg), 0x02)
90  #define ISL7998X_REG_PX_DEC_STATUS_1(pg)	ISL7998X_REG((pg), 0x03)
91  #define ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS	BIT(7)
92  #define ISL7998X_REG_PX_DEC_STATUS_1_HLOCK	BIT(6)
93  #define ISL7998X_REG_PX_DEC_STATUS_1_VLOCK	BIT(3)
94  #define ISL7998X_REG_PX_DEC_HS_DELAY_CTL(pg)	ISL7998X_REG((pg), 0x04)
95  #define ISL7998X_REG_PX_DEC_ANCTL(pg)		ISL7998X_REG((pg), 0x06)
96  #define ISL7998X_REG_PX_DEC_CROP_HI(pg)		ISL7998X_REG((pg), 0x07)
97  #define ISL7998X_REG_PX_DEC_VDELAY_LO(pg)	ISL7998X_REG((pg), 0x08)
98  #define ISL7998X_REG_PX_DEC_VACTIVE_LO(pg)	ISL7998X_REG((pg), 0x09)
99  #define ISL7998X_REG_PX_DEC_HDELAY_LO(pg)	ISL7998X_REG((pg), 0x0a)
100  #define ISL7998X_REG_PX_DEC_HACTIVE_LO(pg)	ISL7998X_REG((pg), 0x0b)
101  #define ISL7998X_REG_PX_DEC_CNTRL1(pg)		ISL7998X_REG((pg), 0x0c)
102  #define ISL7998X_REG_PX_DEC_CSC_CTL(pg)		ISL7998X_REG((pg), 0x0d)
103  #define ISL7998X_REG_PX_DEC_BRIGHT(pg)		ISL7998X_REG((pg), 0x10)
104  #define ISL7998X_REG_PX_DEC_CONTRAST(pg)	ISL7998X_REG((pg), 0x11)
105  #define ISL7998X_REG_PX_DEC_SHARPNESS(pg)	ISL7998X_REG((pg), 0x12)
106  #define ISL7998X_REG_PX_DEC_SAT_U(pg)		ISL7998X_REG((pg), 0x13)
107  #define ISL7998X_REG_PX_DEC_SAT_V(pg)		ISL7998X_REG((pg), 0x14)
108  #define ISL7998X_REG_PX_DEC_HUE(pg)		ISL7998X_REG((pg), 0x15)
109  #define ISL7998X_REG_PX_DEC_VERT_PEAK(pg)	ISL7998X_REG((pg), 0x17)
110  #define ISL7998X_REG_PX_DEC_CORING(pg)		ISL7998X_REG((pg), 0x18)
111  #define ISL7998X_REG_PX_DEC_SDT(pg)		ISL7998X_REG((pg), 0x1c)
112  #define ISL7998X_REG_PX_DEC_SDT_DET		BIT(7)
113  #define ISL7998X_REG_PX_DEC_SDT_NOW		GENMASK(6, 4)
114  #define ISL7998X_REG_PX_DEC_SDT_STANDARD	GENMASK(2, 0)
115  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_M		0
116  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL		1
117  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_SECAM		2
118  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_443	3
119  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_M		4
120  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_CN		5
121  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_60		6
122  #define ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN	7
123  #define ISL7998X_REG_PX_DEC_SDTR(pg)		ISL7998X_REG((pg), 0x1d)
124  #define ISL7998X_REG_PX_DEC_SDTR_ATSTART	BIT(7)
125  #define ISL7998X_REG_PX_DEC_CLMPG(pg)		ISL7998X_REG((pg), 0x20)
126  #define ISL7998X_REG_PX_DEC_IAGC(pg)		ISL7998X_REG((pg), 0x21)
127  #define ISL7998X_REG_PX_DEC_AGCGAIN(pg)		ISL7998X_REG((pg), 0x22)
128  #define ISL7998X_REG_PX_DEC_PEAKWT(pg)		ISL7998X_REG((pg), 0x23)
129  #define ISL7998X_REG_PX_DEC_CLMPL(pg)		ISL7998X_REG((pg), 0x24)
130  #define ISL7998X_REG_PX_DEC_SYNCT(pg)		ISL7998X_REG((pg), 0x25)
131  #define ISL7998X_REG_PX_DEC_MISSCNT(pg)		ISL7998X_REG((pg), 0x26)
132  #define ISL7998X_REG_PX_DEC_PCLAMP(pg)		ISL7998X_REG((pg), 0x27)
133  #define ISL7998X_REG_PX_DEC_VERT_CTL_1(pg)	ISL7998X_REG((pg), 0x28)
134  #define ISL7998X_REG_PX_DEC_VERT_CTL_2(pg)	ISL7998X_REG((pg), 0x29)
135  #define ISL7998X_REG_PX_DEC_CLR_KILL_LVL(pg)	ISL7998X_REG((pg), 0x2a)
136  #define ISL7998X_REG_PX_DEC_COMB_FILTER_CTL(pg)	ISL7998X_REG((pg), 0x2b)
137  #define ISL7998X_REG_PX_DEC_LUMA_DELAY(pg)	ISL7998X_REG((pg), 0x2c)
138  #define ISL7998X_REG_PX_DEC_MISC1(pg)		ISL7998X_REG((pg), 0x2d)
139  #define ISL7998X_REG_PX_DEC_MISC2(pg)		ISL7998X_REG((pg), 0x2e)
140  #define ISL7998X_REG_PX_DEC_MISC3(pg)		ISL7998X_REG((pg), 0x2f)
141  #define ISL7998X_REG_PX_DEC_MVSN(pg)		ISL7998X_REG((pg), 0x30)
142  #define ISL7998X_REG_PX_DEC_CSTATUS2(pg)	ISL7998X_REG((pg), 0x31)
143  #define ISL7998X_REG_PX_DEC_HFREF(pg)		ISL7998X_REG((pg), 0x32)
144  #define ISL7998X_REG_PX_DEC_CLMD(pg)		ISL7998X_REG((pg), 0x33)
145  #define ISL7998X_REG_PX_DEC_ID_DET_CTL(pg)	ISL7998X_REG((pg), 0x34)
146  #define ISL7998X_REG_PX_DEC_CLCNTL(pg)		ISL7998X_REG((pg), 0x35)
147  #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_1(pg)	ISL7998X_REG((pg), 0x36)
148  #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_2(pg)	ISL7998X_REG((pg), 0x37)
149  #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_3(pg)	ISL7998X_REG((pg), 0x38)
150  #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_4(pg)	ISL7998X_REG((pg), 0x39)
151  #define ISL7998X_REG_PX_DEC_SHORT_DET_CTL(pg)	ISL7998X_REG((pg), 0x3a)
152  #define ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(pg)	ISL7998X_REG((pg), 0x3b)
153  #define ISL7998X_REG_PX_DEC_AFE_TST_MUX_CTL(pg)	ISL7998X_REG((pg), 0x3c)
154  #define ISL7998X_REG_PX_DEC_DATA_CONV(pg)	ISL7998X_REG((pg), 0x3d)
155  #define ISL7998X_REG_PX_DEC_INTERNAL_TEST(pg)	ISL7998X_REG((pg), 0x3f)
156  #define ISL7998X_REG_PX_DEC_H_DELAY_CTL(pg)	ISL7998X_REG((pg), 0x43)
157  #define ISL7998X_REG_PX_DEC_H_DELAY_II_HI(pg)	ISL7998X_REG((pg), 0x44)
158  #define ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(pg)	ISL7998X_REG((pg), 0x45)
159  
160  #define ISL7998X_REG_PX_ACA_CTL_1(pg)		ISL7998X_REG((pg), 0x80)
161  #define ISL7998X_REG_PX_ACA_GAIN_CTL(pg)	ISL7998X_REG((pg), 0x81)
162  #define ISL7998X_REG_PX_ACA_Y_AVG_HI_LIMIT(pg)	ISL7998X_REG((pg), 0x82)
163  #define ISL7998X_REG_PX_ACA_Y_AVG_LO_LIMIT(pg)	ISL7998X_REG((pg), 0x83)
164  #define ISL7998X_REG_PX_ACA_Y_DET_THRESHOLD(pg)	ISL7998X_REG((pg), 0x84)
165  #define ISL7998X_REG_PX_ACA_BLACK_LVL(pg)	ISL7998X_REG((pg), 0x85)
166  #define ISL7998X_REG_PX_ACA_CENTER_LVL(pg)	ISL7998X_REG((pg), 0x86)
167  #define ISL7998X_REG_PX_ACA_WHITE_LVL(pg)	ISL7998X_REG((pg), 0x87)
168  #define ISL7998X_REG_PX_ACA_MEAN_OFF_LIMIT(pg)	ISL7998X_REG((pg), 0x88)
169  #define ISL7998X_REG_PX_ACA_MEAN_OFF_UPGAIN(pg)	ISL7998X_REG((pg), 0x89)
170  #define ISL7998X_REG_PX_ACA_MEAN_OFF_SLOPE(pg)	ISL7998X_REG((pg), 0x8a)
171  #define ISL7998X_REG_PX_ACA_MEAN_OFF_DNGAIN(pg)	ISL7998X_REG((pg), 0x8b)
172  #define ISL7998X_REG_PX_ACA_DELTA_CO_THRES(pg)	ISL7998X_REG((pg), 0x8c)
173  #define ISL7998X_REG_PX_ACA_DELTA_SLOPE(pg)	ISL7998X_REG((pg), 0x8d)
174  #define ISL7998X_REG_PX_ACA_LO_HI_AVG_THRES(pg)	ISL7998X_REG((pg), 0x8e)
175  #define ISL7998X_REG_PX_ACA_LO_MAX_LVL_CTL(pg)	ISL7998X_REG((pg), 0x8f)
176  #define ISL7998X_REG_PX_ACA_HI_MAX_LVL_CTL(pg)	ISL7998X_REG((pg), 0x90)
177  #define ISL7998X_REG_PX_ACA_LO_UPGAIN_CTL(pg)	ISL7998X_REG((pg), 0x91)
178  #define ISL7998X_REG_PX_ACA_LO_DNGAIN_CTL(pg)	ISL7998X_REG((pg), 0x92)
179  #define ISL7998X_REG_PX_ACA_HI_UPGAIN_CTL(pg)	ISL7998X_REG((pg), 0x93)
180  #define ISL7998X_REG_PX_ACA_HI_DNGAIN_CTL(pg)	ISL7998X_REG((pg), 0x94)
181  #define ISL7998X_REG_PX_ACA_LOPASS_FLT_COEF(pg)	ISL7998X_REG((pg), 0x95)
182  #define ISL7998X_REG_PX_ACA_PDF_INDEX(pg)	ISL7998X_REG((pg), 0x96)
183  #define ISL7998X_REG_PX_ACA_HIST_WIN_H_STT(pg)	ISL7998X_REG((pg), 0x97)
184  #define ISL7998X_REG_PX_ACA_HIST_WIN_H_SZ1(pg)	ISL7998X_REG((pg), 0x98)
185  #define ISL7998X_REG_PX_ACA_HIST_WIN_H_SZ2(pg)	ISL7998X_REG((pg), 0x99)
186  #define ISL7998X_REG_PX_ACA_HIST_WIN_V_STT(pg)	ISL7998X_REG((pg), 0x9a)
187  #define ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ1(pg)	ISL7998X_REG((pg), 0x9b)
188  #define ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(pg)	ISL7998X_REG((pg), 0x9c)
189  #define ISL7998X_REG_PX_ACA_Y_AVG(pg)		ISL7998X_REG((pg), 0xa0)
190  #define ISL7998X_REG_PX_ACA_Y_AVG_LIM(pg)	ISL7998X_REG((pg), 0xa1)
191  #define ISL7998X_REG_PX_ACA_LO_AVG(pg)		ISL7998X_REG((pg), 0xa2)
192  #define ISL7998X_REG_PX_ACA_HI_AVG(pg)		ISL7998X_REG((pg), 0xa3)
193  #define ISL7998X_REG_PX_ACA_Y_MAX(pg)		ISL7998X_REG((pg), 0xa4)
194  #define ISL7998X_REG_PX_ACA_Y_MIN(pg)		ISL7998X_REG((pg), 0xa5)
195  #define ISL7998X_REG_PX_ACA_MOFFSET(pg)		ISL7998X_REG((pg), 0xa6)
196  #define ISL7998X_REG_PX_ACA_LO_GAIN(pg)		ISL7998X_REG((pg), 0xa7)
197  #define ISL7998X_REG_PX_ACA_HI_GAIN(pg)		ISL7998X_REG((pg), 0xa8)
198  #define ISL7998X_REG_PX_ACA_LL_SLOPE(pg)	ISL7998X_REG((pg), 0xa9)
199  #define ISL7998X_REG_PX_ACA_LH_SLOPE(pg)	ISL7998X_REG((pg), 0xaa)
200  #define ISL7998X_REG_PX_ACA_HL_SLOPE(pg)	ISL7998X_REG((pg), 0xab)
201  #define ISL7998X_REG_PX_ACA_HH_SLOPE(pg)	ISL7998X_REG((pg), 0xac)
202  #define ISL7998X_REG_PX_ACA_X_LOW(pg)		ISL7998X_REG((pg), 0xad)
203  #define ISL7998X_REG_PX_ACA_X_MEAN(pg)		ISL7998X_REG((pg), 0xae)
204  #define ISL7998X_REG_PX_ACA_X_HIGH(pg)		ISL7998X_REG((pg), 0xaf)
205  #define ISL7998X_REG_PX_ACA_Y_LOW(pg)		ISL7998X_REG((pg), 0xb0)
206  #define ISL7998X_REG_PX_ACA_Y_MEAN(pg)		ISL7998X_REG((pg), 0xb1)
207  #define ISL7998X_REG_PX_ACA_Y_HIGH(pg)		ISL7998X_REG((pg), 0xb2)
208  #define ISL7998X_REG_PX_ACA_CTL_2(pg)		ISL7998X_REG((pg), 0xb3)
209  #define ISL7998X_REG_PX_ACA_CTL_3(pg)		ISL7998X_REG((pg), 0xb4)
210  #define ISL7998X_REG_PX_ACA_CTL_4(pg)		ISL7998X_REG((pg), 0xb5)
211  #define ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(pg)	ISL7998X_REG((pg), 0xc0)
212  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TL_H(pg)	ISL7998X_REG((pg), 0xc1)
213  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TL_L(pg)	ISL7998X_REG((pg), 0xc2)
214  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TL_H(pg)	ISL7998X_REG((pg), 0xc3)
215  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TL_L(pg)	ISL7998X_REG((pg), 0xc4)
216  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TR_H(pg)	ISL7998X_REG((pg), 0xc5)
217  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TR_L(pg)	ISL7998X_REG((pg), 0xc6)
218  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TR_H(pg)	ISL7998X_REG((pg), 0xc7)
219  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TR_L(pg)	ISL7998X_REG((pg), 0xc8)
220  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BL_H(pg)	ISL7998X_REG((pg), 0xc9)
221  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BL_L(pg)	ISL7998X_REG((pg), 0xca)
222  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BL_H(pg)	ISL7998X_REG((pg), 0xcb)
223  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BL_L(pg)	ISL7998X_REG((pg), 0xcc)
224  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BR_H(pg)	ISL7998X_REG((pg), 0xcd)
225  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BR_L(pg)	ISL7998X_REG((pg), 0xce)
226  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BR_H(pg)	ISL7998X_REG((pg), 0xcf)
227  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BR_L(pg)	ISL7998X_REG((pg), 0xd0)
228  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_LM_H(pg)	ISL7998X_REG((pg), 0xd1)
229  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_LM_L(pg)	ISL7998X_REG((pg), 0xd2)
230  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_LM_H(pg)	ISL7998X_REG((pg), 0xd3)
231  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_LM_L(pg)	ISL7998X_REG((pg), 0xd4)
232  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TM_H(pg)	ISL7998X_REG((pg), 0xd5)
233  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TM_L(pg)	ISL7998X_REG((pg), 0xd6)
234  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TM_H(pg)	ISL7998X_REG((pg), 0xd7)
235  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TM_L(pg)	ISL7998X_REG((pg), 0xd8)
236  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BM_H(pg)	ISL7998X_REG((pg), 0xd9)
237  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BM_L(pg)	ISL7998X_REG((pg), 0xda)
238  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BM_H(pg)	ISL7998X_REG((pg), 0xdb)
239  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BM_L(pg)	ISL7998X_REG((pg), 0xdc)
240  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_RM_H(pg)	ISL7998X_REG((pg), 0xdd)
241  #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_RM_L(pg)	ISL7998X_REG((pg), 0xde)
242  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_RM_H(pg)	ISL7998X_REG((pg), 0xdf)
243  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_RM_L(pg)	ISL7998X_REG((pg), 0xe0)
244  #define ISL7998X_REG_PX_ACA_HIST_DATA_LO(pg)	ISL7998X_REG((pg), 0xe1)
245  #define ISL7998X_REG_PX_ACA_HIST_DATA_MID(pg)	ISL7998X_REG((pg), 0xe2)
246  #define ISL7998X_REG_PX_ACA_HIST_DATA_HI(pg)	ISL7998X_REG((pg), 0xe3)
247  #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_CLR(pg)	ISL7998X_REG((pg), 0xe4)
248  #define ISL7998X_REG_PX_ACA_FLEX_WIN_CB_CLR(pg)	ISL7998X_REG((pg), 0xe5)
249  #define ISL7998X_REG_PX_ACA_FLEX_WIN_CR_CLR(pg)	ISL7998X_REG((pg), 0xe6)
250  #define ISL7998X_REG_PX_ACA_XFER_HIST_HOST(pg)	ISL7998X_REG((pg), 0xe7)
251  
252  #define ISL7998X_REG_P5_LI_ENGINE_CTL		ISL7998X_REG(5, 0x00)
253  #define ISL7998X_REG_P5_LI_ENGINE_LINE_CTL	ISL7998X_REG(5, 0x01)
254  #define ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH	ISL7998X_REG(5, 0x02)
255  #define ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL	ISL7998X_REG(5, 0x03)
256  #define ISL7998X_REG_P5_LI_ENGINE_VC_ASSIGNMENT	ISL7998X_REG(5, 0x04)
257  #define ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL	ISL7998X_REG(5, 0x05)
258  #define ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL	ISL7998X_REG(5, 0x06)
259  #define ISL7998X_REG_P5_MIPI_READ_START_CTL	ISL7998X_REG(5, 0x07)
260  #define ISL7998X_REG_P5_PSEUDO_FRM_FIELD_CTL	ISL7998X_REG(5, 0x08)
261  #define ISL7998X_REG_P5_ONE_FIELD_MODE_CTL	ISL7998X_REG(5, 0x09)
262  #define ISL7998X_REG_P5_MIPI_INT_HW_TST_CTR	ISL7998X_REG(5, 0x0a)
263  #define ISL7998X_REG_P5_TP_GEN_BAR_PATTERN	ISL7998X_REG(5, 0x0b)
264  #define ISL7998X_REG_P5_MIPI_PCNT_PSFRM		ISL7998X_REG(5, 0x0c)
265  #define ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL	ISL7998X_REG(5, 0x0d)
266  #define ISL7998X_REG_P5_MIPI_VBLANK_PSFRM	ISL7998X_REG(5, 0x0e)
267  #define ISL7998X_REG_P5_LI_ENGINE_CTL_2		ISL7998X_REG(5, 0x0f)
268  #define ISL7998X_REG_P5_MIPI_WCNT_1		ISL7998X_REG(5, 0x10)
269  #define ISL7998X_REG_P5_MIPI_WCNT_2		ISL7998X_REG(5, 0x11)
270  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_1	ISL7998X_REG(5, 0x12)
271  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_2	ISL7998X_REG(5, 0x13)
272  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_3	ISL7998X_REG(5, 0x14)
273  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_4	ISL7998X_REG(5, 0x15)
274  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_5	ISL7998X_REG(5, 0x16)
275  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_6	ISL7998X_REG(5, 0x17)
276  #define ISL7998X_REG_P5_MIPI_DPHY_PARAMS_1	ISL7998X_REG(5, 0x18)
277  #define ISL7998X_REG_P5_MIPI_DPHY_SOT_PERIOD	ISL7998X_REG(5, 0x19)
278  #define ISL7998X_REG_P5_MIPI_DPHY_EOT_PERIOD	ISL7998X_REG(5, 0x1a)
279  #define ISL7998X_REG_P5_MIPI_DPHY_PARAMS_2	ISL7998X_REG(5, 0x1b)
280  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_7	ISL7998X_REG(5, 0x1c)
281  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_8	ISL7998X_REG(5, 0x1d)
282  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_9	ISL7998X_REG(5, 0x1e)
283  #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_10	ISL7998X_REG(5, 0x1f)
284  #define ISL7998X_REG_P5_TP_GEN_MIPI		ISL7998X_REG(5, 0x20)
285  #define ISL7998X_REG_P5_ESC_MODE_TIME_CTL	ISL7998X_REG(5, 0x21)
286  #define ISL7998X_REG_P5_AUTO_TEST_ERR_DET	ISL7998X_REG(5, 0x22)
287  #define ISL7998X_REG_P5_MIPI_TIMING		ISL7998X_REG(5, 0x23)
288  #define ISL7998X_REG_P5_PIC_HEIGHT_HIGH		ISL7998X_REG(5, 0x24)
289  #define ISL7998X_REG_P5_PIC_HEIGHT_LOW		ISL7998X_REG(5, 0x25)
290  #define ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL	ISL7998X_REG(5, 0x26)
291  #define ISL7998X_REG_P5_FIFO_THRSH_CNT_1	ISL7998X_REG(5, 0x28)
292  #define ISL7998X_REG_P5_FIFO_THRSH_CNT_2	ISL7998X_REG(5, 0x29)
293  #define ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1	ISL7998X_REG(5, 0x2a)
294  #define ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2	ISL7998X_REG(5, 0x2b)
295  #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_1	ISL7998X_REG(5, 0x2c)
296  #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_2	ISL7998X_REG(5, 0x2d)
297  #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_3	ISL7998X_REG(5, 0x2e)
298  #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_4	ISL7998X_REG(5, 0x2f)
299  #define ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_1	ISL7998X_REG(5, 0x30)
300  #define ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_2	ISL7998X_REG(5, 0x31)
301  #define ISL7998X_REG_P5_MIPI_ANA_CLK_CTL	ISL7998X_REG(5, 0x32)
302  #define ISL7998X_REG_P5_PLL_ANA_STATUS		ISL7998X_REG(5, 0x33)
303  #define ISL7998X_REG_P5_PLL_ANA_MISC_CTL	ISL7998X_REG(5, 0x34)
304  #define ISL7998X_REG_P5_MIPI_ANA		ISL7998X_REG(5, 0x35)
305  #define ISL7998X_REG_P5_PLL_ANA			ISL7998X_REG(5, 0x36)
306  #define ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1	ISL7998X_REG(5, 0x38)
307  #define ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_2	ISL7998X_REG(5, 0x39)
308  #define ISL7998X_REG_P5_H_LINE_CNT_1		ISL7998X_REG(5, 0x3a)
309  #define ISL7998X_REG_P5_H_LINE_CNT_2		ISL7998X_REG(5, 0x3b)
310  #define ISL7998X_REG_P5_HIST_LINE_CNT_1		ISL7998X_REG(5, 0x3c)
311  #define ISL7998X_REG_P5_HIST_LINE_CNT_2		ISL7998X_REG(5, 0x3d)
312  
313  static const struct reg_sequence isl7998x_init_seq_1[] = {
314  	{ ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN, 0xff },
315  	{ ISL7998X_REG_PX_DEC_SDT(0x1), 0x00 },
316  	{ ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x1), 0x03 },
317  	{ ISL7998X_REG_PX_DEC_SDT(0x2), 0x00 },
318  	{ ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x2), 0x03 },
319  	{ ISL7998X_REG_PX_DEC_SDT(0x3), 0x00 },
320  	{ ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x3), 0x03 },
321  	{ ISL7998X_REG_PX_DEC_SDT(0x4), 0x00 },
322  	{ ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x4), 0x03 },
323  	{ ISL7998X_REG_P5_LI_ENGINE_CTL, 0x00 },
324  	{ ISL7998X_REG_P0_SW_RESET_CTL, 0x1f, 10 },
325  	{ ISL7998X_REG_P0_IO_BUFFER_CTL, 0x00 },
326  	{ ISL7998X_REG_P0_MPP2_SYNC_CTL, 0xc9 },
327  	{ ISL7998X_REG_P0_IRQ_SYNC_CTL, 0xc9 },
328  	{ ISL7998X_REG_P0_CHAN_1_IRQ, 0x03 },
329  	{ ISL7998X_REG_P0_CHAN_2_IRQ, 0x00 },
330  	{ ISL7998X_REG_P0_CHAN_3_IRQ, 0x00 },
331  	{ ISL7998X_REG_P0_CHAN_4_IRQ, 0x00 },
332  	{ ISL7998X_REG_P5_LI_ENGINE_CTL, 0x02 },
333  	{ ISL7998X_REG_P5_LI_ENGINE_LINE_CTL, 0x85 },
334  	{ ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH, 0xa0 },
335  	{ ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL, 0x18 },
336  	{ ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL, 0x40 },
337  	{ ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x40 },
338  	{ ISL7998X_REG_P5_MIPI_WCNT_1, 0x05 },
339  	{ ISL7998X_REG_P5_MIPI_WCNT_2, 0xa0 },
340  	{ ISL7998X_REG_P5_TP_GEN_MIPI, 0x00 },
341  	{ ISL7998X_REG_P5_ESC_MODE_TIME_CTL, 0x0c },
342  	{ ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 0x00 },
343  	{ ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1, 0x00 },
344  	{ ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2, 0x19 },
345  	{ ISL7998X_REG_P5_PSF_FIELD_END_CTL_1, 0x18 },
346  	{ ISL7998X_REG_P5_PSF_FIELD_END_CTL_2, 0xf1 },
347  	{ ISL7998X_REG_P5_PSF_FIELD_END_CTL_3, 0x00 },
348  	{ ISL7998X_REG_P5_PSF_FIELD_END_CTL_4, 0xf1 },
349  	{ ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_1, 0x00 },
350  	{ ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_2, 0x00 },
351  	{ ISL7998X_REG_P5_MIPI_ANA_CLK_CTL, 0x00 },
352  	{ ISL7998X_REG_P5_PLL_ANA_STATUS, 0xc0 },
353  	{ ISL7998X_REG_P5_PLL_ANA_MISC_CTL, 0x18 },
354  	{ ISL7998X_REG_P5_PLL_ANA, 0x00 },
355  	{ ISL7998X_REG_P0_SW_RESET_CTL, 0x10, 10 },
356  	/* Page 0xf means write to all of pages 1,2,3,4 */
357  	{ ISL7998X_REG_PX_DEC_VDELAY_LO(0xf), 0x14 },
358  	{ ISL7998X_REG_PX_DEC_MISC3(0xf), 0xe6 },
359  	{ ISL7998X_REG_PX_DEC_CLMD(0xf), 0x85 },
360  	{ ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(0xf), 0x11 },
361  	{ ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 0x00 },
362  	{ ISL7998X_REG_P0_CLK_CTL_1, 0x1f },
363  	{ ISL7998X_REG_P0_CLK_CTL_2, 0x43 },
364  	{ ISL7998X_REG_P0_CLK_CTL_3, 0x4f },
365  };
366  
367  static const struct reg_sequence isl7998x_init_seq_2[] = {
368  	{ ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL, 0x10 },
369  	{ ISL7998X_REG_P5_LI_ENGINE_VC_ASSIGNMENT, 0xe4 },
370  	{ ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL, 0x00 },
371  	{ ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x60 },
372  	{ ISL7998X_REG_P5_MIPI_READ_START_CTL, 0x2b },
373  	{ ISL7998X_REG_P5_PSEUDO_FRM_FIELD_CTL, 0x02 },
374  	{ ISL7998X_REG_P5_ONE_FIELD_MODE_CTL, 0x00 },
375  	{ ISL7998X_REG_P5_MIPI_INT_HW_TST_CTR, 0x62 },
376  	{ ISL7998X_REG_P5_TP_GEN_BAR_PATTERN, 0x02 },
377  	{ ISL7998X_REG_P5_MIPI_PCNT_PSFRM, 0x36 },
378  	{ ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 0x00 },
379  	{ ISL7998X_REG_P5_MIPI_VBLANK_PSFRM, 0x6c },
380  	{ ISL7998X_REG_P5_LI_ENGINE_CTL_2, 0x00 },
381  	{ ISL7998X_REG_P5_MIPI_WCNT_1, 0x05 },
382  	{ ISL7998X_REG_P5_MIPI_WCNT_2, 0xa0 },
383  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_1, 0x77 },
384  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_2, 0x17 },
385  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_3, 0x08 },
386  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_4, 0x38 },
387  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_5, 0x14 },
388  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_6, 0xf6 },
389  	{ ISL7998X_REG_P5_MIPI_DPHY_PARAMS_1, 0x00 },
390  	{ ISL7998X_REG_P5_MIPI_DPHY_SOT_PERIOD, 0x17 },
391  	{ ISL7998X_REG_P5_MIPI_DPHY_EOT_PERIOD, 0x0a },
392  	{ ISL7998X_REG_P5_MIPI_DPHY_PARAMS_2, 0x71 },
393  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_7, 0x7a },
394  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_8, 0x0f },
395  	{ ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_9, 0x8c },
396  	{ ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 0x08 },
397  	{ ISL7998X_REG_P5_FIFO_THRSH_CNT_1, 0x01 },
398  	{ ISL7998X_REG_P5_FIFO_THRSH_CNT_2, 0x0e },
399  	{ ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1, 0x00 },
400  	{ ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2, 0x00 },
401  	{ ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 0x03 },
402  	{ ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_2, 0xc0 },
403  	{ ISL7998X_REG_P5_H_LINE_CNT_1, 0x06 },
404  	{ ISL7998X_REG_P5_H_LINE_CNT_2, 0xb3 },
405  	{ ISL7998X_REG_P5_HIST_LINE_CNT_1, 0x00 },
406  	{ ISL7998X_REG_P5_HIST_LINE_CNT_2, 0xf1 },
407  	{ ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x00 },
408  	{ ISL7998X_REG_P5_MIPI_ANA, 0x00 },
409  	/*
410  	 * Wait a bit after reset so that the chip can capture a frame
411  	 * and update internal line counters.
412  	 */
413  	{ ISL7998X_REG_P0_SW_RESET_CTL, 0x00, 50 },
414  };
415  
416  enum isl7998x_pads {
417  	ISL7998X_PAD_OUT,
418  	ISL7998X_PAD_VIN1,
419  	ISL7998X_PAD_VIN2,
420  	ISL7998X_PAD_VIN3,
421  	ISL7998X_PAD_VIN4,
422  	ISL7998X_NUM_PADS
423  };
424  
425  struct isl7998x_datafmt {
426  	u32			code;
427  	enum v4l2_colorspace	colorspace;
428  };
429  
430  static const struct isl7998x_datafmt isl7998x_colour_fmts[] = {
431  	{ MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB },
432  };
433  
434  /* Menu items for LINK_FREQ V4L2 control */
435  static const s64 link_freq_menu_items[] = {
436  	/* 1 channel, 1 lane or 2 channels, 2 lanes */
437  	108000000,
438  	/* 2 channels, 1 lane or 4 channels, 2 lanes */
439  	216000000,
440  	/* 4 channels, 1 lane */
441  	432000000,
442  };
443  
444  /* Menu items for TEST_PATTERN V4L2 control */
445  static const char * const isl7998x_test_pattern_menu[] = {
446  	"Disabled",
447  	"Enabled",
448  };
449  
450  static const char * const isl7998x_test_pattern_bars[] = {
451  	"bbbbwb", "bbbwwb", "bbwbwb", "bbwwwb",
452  };
453  
454  static const char * const isl7998x_test_pattern_colors[] = {
455  	"Yellow", "Blue", "Green", "Pink",
456  };
457  
458  struct isl7998x_mode {
459  	unsigned int width;
460  	unsigned int height;
461  	enum v4l2_field field;
462  };
463  
464  static const struct isl7998x_mode supported_modes[] = {
465  	{
466  		.width = 720,
467  		.height = 576,
468  		.field = V4L2_FIELD_SEQ_TB,
469  	},
470  	{
471  		.width = 720,
472  		.height = 480,
473  		.field = V4L2_FIELD_SEQ_BT,
474  	},
475  };
476  
477  static const struct isl7998x_video_std {
478  	const v4l2_std_id norm;
479  	unsigned int id;
480  	const struct isl7998x_mode *mode;
481  } isl7998x_std_res[] = {
482  	{ V4L2_STD_NTSC_443,
483  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_443,
484  	  &supported_modes[1] },
485  	{ V4L2_STD_PAL_M,
486  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_M,
487  	  &supported_modes[1] },
488  	{ V4L2_STD_PAL_Nc,
489  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_CN,
490  	  &supported_modes[0] },
491  	{ V4L2_STD_PAL_N,
492  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL,
493  	  &supported_modes[0] },
494  	{ V4L2_STD_PAL_60,
495  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_60,
496  	  &supported_modes[1] },
497  	{ V4L2_STD_NTSC,
498  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_M,
499  	  &supported_modes[1] },
500  	{ V4L2_STD_PAL,
501  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL,
502  	  &supported_modes[0] },
503  	{ V4L2_STD_SECAM,
504  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_SECAM,
505  	  &supported_modes[0] },
506  	{ V4L2_STD_UNKNOWN,
507  	  ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN,
508  	  &supported_modes[1] },
509  };
510  
511  struct isl7998x {
512  	struct v4l2_subdev		subdev;
513  	struct regmap			*regmap;
514  	struct gpio_desc		*pd_gpio;
515  	struct gpio_desc		*rstb_gpio;
516  	unsigned int			nr_mipi_lanes;
517  	u32				nr_inputs;
518  
519  	const struct isl7998x_datafmt	*fmt;
520  	v4l2_std_id			norm;
521  	struct media_pad		pads[ISL7998X_NUM_PADS];
522  
523  	int				enabled;
524  
525  	/* protect fmt, norm, enabled */
526  	struct mutex			lock;
527  
528  	struct v4l2_ctrl_handler	ctrl_handler;
529  	/* protect ctrl_handler */
530  	struct mutex			ctrl_mutex;
531  
532  	/* V4L2 Controls */
533  	struct v4l2_ctrl		*link_freq;
534  	u8				test_pattern;
535  	u8				test_pattern_bars;
536  	u8				test_pattern_chans;
537  	u8				test_pattern_color;
538  };
539  
sd_to_isl7998x(struct v4l2_subdev * sd)540  static struct isl7998x *sd_to_isl7998x(struct v4l2_subdev *sd)
541  {
542  	return container_of(sd, struct isl7998x, subdev);
543  }
544  
i2c_to_isl7998x(const struct i2c_client * client)545  static struct isl7998x *i2c_to_isl7998x(const struct i2c_client *client)
546  {
547  	return sd_to_isl7998x(i2c_get_clientdata(client));
548  }
549  
isl7998x_norm_to_val(v4l2_std_id norm)550  static unsigned int isl7998x_norm_to_val(v4l2_std_id norm)
551  {
552  	unsigned int i;
553  
554  	for (i = 0; i < ARRAY_SIZE(isl7998x_std_res); i++)
555  		if (isl7998x_std_res[i].norm & norm)
556  			break;
557  	if (i == ARRAY_SIZE(isl7998x_std_res))
558  		return ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN;
559  
560  	return isl7998x_std_res[i].id;
561  }
562  
isl7998x_norm_to_mode(v4l2_std_id norm)563  static const struct isl7998x_mode *isl7998x_norm_to_mode(v4l2_std_id norm)
564  {
565  	unsigned int i;
566  
567  	for (i = 0; i < ARRAY_SIZE(isl7998x_std_res); i++)
568  		if (isl7998x_std_res[i].norm & norm)
569  			break;
570  	/* Use NTSC default resolution during standard detection */
571  	if (i == ARRAY_SIZE(isl7998x_std_res))
572  		return &supported_modes[1];
573  
574  	return isl7998x_std_res[i].mode;
575  }
576  
isl7998x_get_nr_inputs(struct device_node * of_node)577  static int isl7998x_get_nr_inputs(struct device_node *of_node)
578  {
579  	struct device_node *port;
580  	unsigned int inputs = 0;
581  	unsigned int i;
582  
583  	if (of_graph_get_endpoint_count(of_node) > ISL7998X_NUM_PADS)
584  		return -EINVAL;
585  
586  	/*
587  	 * The driver does not provide means to remap the input ports. It
588  	 * always configures input ports to start from VID1. Ensure that the
589  	 * device tree is correct.
590  	 */
591  	for (i = ISL7998X_PAD_VIN1; i <= ISL7998X_PAD_VIN4; i++) {
592  		port = of_graph_get_port_by_id(of_node, i);
593  		if (!port)
594  			continue;
595  
596  		inputs |= BIT(i);
597  		of_node_put(port);
598  	}
599  
600  	switch (inputs) {
601  	case BIT(ISL7998X_PAD_VIN1):
602  		return 1;
603  	case BIT(ISL7998X_PAD_VIN1) | BIT(ISL7998X_PAD_VIN2):
604  		return 2;
605  	case BIT(ISL7998X_PAD_VIN1) | BIT(ISL7998X_PAD_VIN2) |
606  	     BIT(ISL7998X_PAD_VIN3) | BIT(ISL7998X_PAD_VIN4):
607  		return 4;
608  	default:
609  		return -EINVAL;
610  	}
611  }
612  
isl7998x_wait_power_on(struct isl7998x * isl7998x)613  static int isl7998x_wait_power_on(struct isl7998x *isl7998x)
614  {
615  	struct device *dev = isl7998x->subdev.dev;
616  	u32 chip_id;
617  	int ret;
618  	int err;
619  
620  	ret = read_poll_timeout(regmap_read, err, !err, 2000, 20000, false,
621  				isl7998x->regmap,
622  				ISL7998X_REG_P0_PRODUCT_ID_CODE, &chip_id);
623  	if (ret) {
624  		dev_err(dev, "timeout while waiting for ISL7998X\n");
625  		return ret;
626  	}
627  
628  	dev_dbg(dev, "Found ISL799%x\n", chip_id);
629  
630  	return ret;
631  }
632  
isl7998x_set_standard(struct isl7998x * isl7998x,v4l2_std_id norm)633  static int isl7998x_set_standard(struct isl7998x *isl7998x, v4l2_std_id norm)
634  {
635  	const struct isl7998x_mode *mode = isl7998x_norm_to_mode(norm);
636  	unsigned int val = isl7998x_norm_to_val(norm);
637  	unsigned int width = mode->width;
638  	unsigned int i;
639  	int ret;
640  
641  	for (i = 0; i < ISL7998X_INPUTS; i++) {
642  		ret = regmap_write_bits(isl7998x->regmap,
643  					ISL7998X_REG_PX_DEC_SDT(i + 1),
644  					ISL7998X_REG_PX_DEC_SDT_STANDARD,
645  					val);
646  		if (ret)
647  			return ret;
648  	}
649  
650  	ret = regmap_write(isl7998x->regmap,
651  			   ISL7998X_REG_P5_LI_ENGINE_LINE_CTL,
652  			   0x20 | ((width >> 7) & 0x1f));
653  	if (ret)
654  		return ret;
655  
656  	ret = regmap_write(isl7998x->regmap,
657  			   ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH,
658  			   (width << 1) & 0xff);
659  	if (ret)
660  		return ret;
661  
662  	return 0;
663  }
664  
isl7998x_init(struct isl7998x * isl7998x)665  static int isl7998x_init(struct isl7998x *isl7998x)
666  {
667  	const unsigned int lanes = isl7998x->nr_mipi_lanes;
668  	static const u32 isl7998x_video_in_chan_map[] = { 0x00, 0x11, 0x02, 0x02 };
669  	const struct reg_sequence isl7998x_init_seq_custom[] = {
670  		{ ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL,
671  		  isl7998x_video_in_chan_map[isl7998x->nr_inputs - 1] },
672  		{ ISL7998X_REG_P0_CLK_CTL_4,
673  		  (lanes == 1) ? 0x40 : 0x41 },
674  		{ ISL7998X_REG_P5_LI_ENGINE_CTL,
675  		  (lanes == 1) ? 0x01 : 0x02 },
676  	};
677  	struct device *dev = isl7998x->subdev.dev;
678  	struct regmap *regmap = isl7998x->regmap;
679  	int ret;
680  
681  	dev_dbg(dev, "configuring %d lanes for %d inputs (norm %s)\n",
682  		isl7998x->nr_mipi_lanes, isl7998x->nr_inputs,
683  		v4l2_norm_to_name(isl7998x->norm));
684  
685  	ret = regmap_register_patch(regmap, isl7998x_init_seq_1,
686  				    ARRAY_SIZE(isl7998x_init_seq_1));
687  	if (ret)
688  		return ret;
689  
690  	mutex_lock(&isl7998x->lock);
691  	ret = isl7998x_set_standard(isl7998x, isl7998x->norm);
692  	mutex_unlock(&isl7998x->lock);
693  	if (ret)
694  		return ret;
695  
696  	ret = regmap_register_patch(regmap, isl7998x_init_seq_custom,
697  				    ARRAY_SIZE(isl7998x_init_seq_custom));
698  	if (ret)
699  		return ret;
700  
701  	return regmap_register_patch(regmap, isl7998x_init_seq_2,
702  				     ARRAY_SIZE(isl7998x_init_seq_2));
703  }
704  
isl7998x_set_test_pattern(struct isl7998x * isl7998x)705  static int isl7998x_set_test_pattern(struct isl7998x *isl7998x)
706  {
707  	const struct reg_sequence isl7998x_init_seq_tpg_off[] = {
708  		{ ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 0 },
709  		{ ISL7998X_REG_P5_LI_ENGINE_CTL_2, 0 }
710  	};
711  	const struct reg_sequence isl7998x_init_seq_tpg_on[] = {
712  		{ ISL7998X_REG_P5_TP_GEN_BAR_PATTERN,
713  		  isl7998x->test_pattern_bars << 6 },
714  		{ ISL7998X_REG_P5_LI_ENGINE_CTL_2,
715  		  isl7998x->norm & V4L2_STD_PAL ? BIT(2) : 0 },
716  		{ ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL,
717  		  (isl7998x->test_pattern_chans << 4) |
718  		  (isl7998x->test_pattern_color << 2) }
719  	};
720  	struct device *dev = isl7998x->subdev.dev;
721  	struct regmap *regmap = isl7998x->regmap;
722  	int ret;
723  
724  	if (pm_runtime_get_if_in_use(dev) <= 0)
725  		return 0;
726  
727  	if (isl7998x->test_pattern != 0) {
728  		dev_dbg(dev, "enabling test pattern: channels 0x%x, %s, %s\n",
729  			isl7998x->test_pattern_chans,
730  			isl7998x_test_pattern_bars[isl7998x->test_pattern_bars],
731  			isl7998x_test_pattern_colors[isl7998x->test_pattern_color]);
732  		ret = regmap_register_patch(regmap, isl7998x_init_seq_tpg_on,
733  					    ARRAY_SIZE(isl7998x_init_seq_tpg_on));
734  	} else {
735  		ret = regmap_register_patch(regmap, isl7998x_init_seq_tpg_off,
736  					    ARRAY_SIZE(isl7998x_init_seq_tpg_off));
737  	}
738  
739  	pm_runtime_put(dev);
740  
741  	return ret;
742  }
743  
744  #ifdef CONFIG_VIDEO_ADV_DEBUG
isl7998x_g_register(struct v4l2_subdev * sd,struct v4l2_dbg_register * reg)745  static int isl7998x_g_register(struct v4l2_subdev *sd,
746  			       struct v4l2_dbg_register *reg)
747  {
748  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
749  	int ret;
750  	u32 val;
751  
752  	ret = regmap_read(isl7998x->regmap, reg->reg, &val);
753  	if (ret)
754  		return ret;
755  
756  	reg->size = 1;
757  	reg->val = val;
758  
759  	return 0;
760  }
761  
isl7998x_s_register(struct v4l2_subdev * sd,const struct v4l2_dbg_register * reg)762  static int isl7998x_s_register(struct v4l2_subdev *sd,
763  			       const struct v4l2_dbg_register *reg)
764  {
765  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
766  
767  	return regmap_write(isl7998x->regmap, reg->reg, reg->val);
768  }
769  #endif
770  
isl7998x_g_std(struct v4l2_subdev * sd,v4l2_std_id * norm)771  static int isl7998x_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
772  {
773  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
774  
775  	mutex_lock(&isl7998x->lock);
776  	*norm = isl7998x->norm;
777  	mutex_unlock(&isl7998x->lock);
778  
779  	return 0;
780  }
781  
isl7998x_s_std(struct v4l2_subdev * sd,v4l2_std_id norm)782  static int isl7998x_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
783  {
784  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
785  	struct i2c_client *client = v4l2_get_subdevdata(sd);
786  	struct device *dev = &client->dev;
787  	int ret = 0;
788  
789  	mutex_lock(&isl7998x->lock);
790  	if (isl7998x->enabled) {
791  		ret = -EBUSY;
792  		mutex_unlock(&isl7998x->lock);
793  		return ret;
794  	}
795  	isl7998x->norm = norm;
796  	mutex_unlock(&isl7998x->lock);
797  
798  	if (pm_runtime_get_if_in_use(dev) <= 0)
799  		return ret;
800  
801  	ret = isl7998x_set_standard(isl7998x, norm);
802  
803  	pm_runtime_put(dev);
804  
805  	return ret;
806  }
807  
isl7998x_querystd(struct v4l2_subdev * sd,v4l2_std_id * std)808  static int isl7998x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
809  {
810  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
811  	struct i2c_client *client = v4l2_get_subdevdata(sd);
812  	struct device *dev = &client->dev;
813  	unsigned int std_id[ISL7998X_INPUTS];
814  	unsigned int i;
815  	int ret;
816  	u32 reg;
817  
818  	ret = pm_runtime_resume_and_get(dev);
819  	if (ret)
820  		return ret;
821  
822  	dev_dbg(dev, "starting video standard detection\n");
823  
824  	mutex_lock(&isl7998x->lock);
825  	if (isl7998x->enabled) {
826  		ret = -EBUSY;
827  		goto out_unlock;
828  	}
829  
830  	ret = isl7998x_set_standard(isl7998x, V4L2_STD_UNKNOWN);
831  	if (ret)
832  		goto out_unlock;
833  
834  	for (i = 0; i < ISL7998X_INPUTS; i++) {
835  		ret = regmap_write(isl7998x->regmap,
836  				   ISL7998X_REG_PX_DEC_SDTR(i + 1),
837  				   ISL7998X_REG_PX_DEC_SDTR_ATSTART);
838  		if (ret)
839  			goto out_reset_std;
840  	}
841  
842  	for (i = 0; i < ISL7998X_INPUTS; i++) {
843  		ret = regmap_read_poll_timeout(isl7998x->regmap,
844  					       ISL7998X_REG_PX_DEC_SDT(i + 1),
845  					       reg,
846  					       !(reg & ISL7998X_REG_PX_DEC_SDT_DET),
847  					       2000, 500 * USEC_PER_MSEC);
848  		if (ret)
849  			goto out_reset_std;
850  		std_id[i] = FIELD_GET(ISL7998X_REG_PX_DEC_SDT_NOW, reg);
851  	}
852  
853  	/*
854  	 * According to Renesas FAE, all input cameras must have the
855  	 * same standard on this chip.
856  	 */
857  	for (i = 0; i < isl7998x->nr_inputs; i++) {
858  		dev_dbg(dev, "input %d: detected %s\n",
859  			i, v4l2_norm_to_name(isl7998x_std_res[std_id[i]].norm));
860  		if (std_id[0] != std_id[i])
861  			dev_warn(dev,
862  				 "incompatible standards: %s on input %d (expected %s)\n",
863  				 v4l2_norm_to_name(isl7998x_std_res[std_id[i]].norm), i,
864  				 v4l2_norm_to_name(isl7998x_std_res[std_id[0]].norm));
865  	}
866  
867  	*std = isl7998x_std_res[std_id[0]].norm;
868  
869  out_reset_std:
870  	isl7998x_set_standard(isl7998x, isl7998x->norm);
871  out_unlock:
872  	mutex_unlock(&isl7998x->lock);
873  	pm_runtime_put(dev);
874  
875  	return ret;
876  }
877  
isl7998x_g_tvnorms(struct v4l2_subdev * sd,v4l2_std_id * std)878  static int isl7998x_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *std)
879  {
880  	*std = V4L2_STD_ALL;
881  
882  	return 0;
883  }
884  
isl7998x_g_input_status(struct v4l2_subdev * sd,u32 * status)885  static int isl7998x_g_input_status(struct v4l2_subdev *sd, u32 *status)
886  {
887  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
888  	struct i2c_client *client = v4l2_get_subdevdata(sd);
889  	struct device *dev = &client->dev;
890  	unsigned int i;
891  	int ret = 0;
892  	u32 reg;
893  
894  	if (!pm_runtime_active(dev)) {
895  		*status |= V4L2_IN_ST_NO_POWER;
896  		return 0;
897  	}
898  
899  	for (i = 0; i < isl7998x->nr_inputs; i++) {
900  		ret = regmap_read(isl7998x->regmap,
901  				  ISL7998X_REG_PX_DEC_STATUS_1(i + 1), &reg);
902  		if (!ret) {
903  			if (reg & ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS)
904  				*status |= V4L2_IN_ST_NO_SIGNAL;
905  			if (!(reg & ISL7998X_REG_PX_DEC_STATUS_1_HLOCK))
906  				*status |= V4L2_IN_ST_NO_H_LOCK;
907  			if (!(reg & ISL7998X_REG_PX_DEC_STATUS_1_VLOCK))
908  				*status |= V4L2_IN_ST_NO_V_LOCK;
909  		}
910  	}
911  
912  	return ret;
913  }
914  
isl7998x_s_stream(struct v4l2_subdev * sd,int enable)915  static int isl7998x_s_stream(struct v4l2_subdev *sd, int enable)
916  {
917  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
918  	struct i2c_client *client = v4l2_get_subdevdata(sd);
919  	struct device *dev = &client->dev;
920  	int ret = 0;
921  	u32 reg;
922  
923  	dev_dbg(dev, "stream %s\n", enable ? "ON" : "OFF");
924  
925  	mutex_lock(&isl7998x->lock);
926  	if (isl7998x->enabled == enable)
927  		goto out;
928  	isl7998x->enabled = enable;
929  
930  	if (enable) {
931  		ret = isl7998x_set_test_pattern(isl7998x);
932  		if (ret)
933  			goto out;
934  	}
935  
936  	regmap_read(isl7998x->regmap,
937  		    ISL7998X_REG_P5_LI_ENGINE_CTL, &reg);
938  	if (enable)
939  		reg &= ~BIT(7);
940  	else
941  		reg |= BIT(7);
942  	ret = regmap_write(isl7998x->regmap,
943  			   ISL7998X_REG_P5_LI_ENGINE_CTL, reg);
944  
945  out:
946  	mutex_unlock(&isl7998x->lock);
947  
948  	return ret;
949  }
950  
isl7998x_pre_streamon(struct v4l2_subdev * sd,u32 flags)951  static int isl7998x_pre_streamon(struct v4l2_subdev *sd, u32 flags)
952  {
953  	struct i2c_client *client = v4l2_get_subdevdata(sd);
954  	struct device *dev = &client->dev;
955  
956  	return pm_runtime_resume_and_get(dev);
957  }
958  
isl7998x_post_streamoff(struct v4l2_subdev * sd)959  static int isl7998x_post_streamoff(struct v4l2_subdev *sd)
960  {
961  	struct i2c_client *client = v4l2_get_subdevdata(sd);
962  	struct device *dev = &client->dev;
963  
964  	pm_runtime_put(dev);
965  
966  	return 0;
967  }
968  
isl7998x_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_mbus_code_enum * code)969  static int isl7998x_enum_mbus_code(struct v4l2_subdev *sd,
970  				   struct v4l2_subdev_state *sd_state,
971  				   struct v4l2_subdev_mbus_code_enum *code)
972  {
973  	if (code->index >= ARRAY_SIZE(isl7998x_colour_fmts))
974  		return -EINVAL;
975  
976  	code->code = isl7998x_colour_fmts[code->index].code;
977  
978  	return 0;
979  }
980  
isl7998x_enum_frame_size(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_frame_size_enum * fse)981  static int isl7998x_enum_frame_size(struct v4l2_subdev *sd,
982  				    struct v4l2_subdev_state *sd_state,
983  				    struct v4l2_subdev_frame_size_enum *fse)
984  {
985  	if (fse->index >= ARRAY_SIZE(supported_modes))
986  		return -EINVAL;
987  
988  	if (fse->code != isl7998x_colour_fmts[0].code)
989  		return -EINVAL;
990  
991  	fse->min_width = supported_modes[fse->index].width;
992  	fse->max_width = fse->min_width;
993  	fse->min_height = supported_modes[fse->index].height;
994  	fse->max_height = fse->min_height;
995  
996  	return 0;
997  }
998  
isl7998x_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * format)999  static int isl7998x_get_fmt(struct v4l2_subdev *sd,
1000  			    struct v4l2_subdev_state *sd_state,
1001  			    struct v4l2_subdev_format *format)
1002  {
1003  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
1004  	struct v4l2_mbus_framefmt *mf = &format->format;
1005  	const struct isl7998x_mode *mode;
1006  
1007  	mutex_lock(&isl7998x->lock);
1008  
1009  	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
1010  		format->format = *v4l2_subdev_get_try_format(sd, sd_state,
1011  							     format->pad);
1012  		goto out;
1013  	}
1014  
1015  	mode = isl7998x_norm_to_mode(isl7998x->norm);
1016  
1017  	mf->width	= mode->width;
1018  	mf->height	= mode->height;
1019  	mf->code	= isl7998x->fmt->code;
1020  	mf->field	= mode->field;
1021  	mf->colorspace	= 0;
1022  
1023  out:
1024  	mutex_unlock(&isl7998x->lock);
1025  
1026  	return 0;
1027  }
1028  
isl7998x_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_state * sd_state,struct v4l2_subdev_format * format)1029  static int isl7998x_set_fmt(struct v4l2_subdev *sd,
1030  			    struct v4l2_subdev_state *sd_state,
1031  			    struct v4l2_subdev_format *format)
1032  {
1033  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
1034  	struct v4l2_mbus_framefmt *mf = &format->format;
1035  	const struct isl7998x_mode *mode;
1036  
1037  	mutex_lock(&isl7998x->lock);
1038  
1039  	mode = isl7998x_norm_to_mode(isl7998x->norm);
1040  
1041  	mf->width = mode->width;
1042  	mf->height = mode->height;
1043  	mf->code = isl7998x->fmt->code;
1044  	mf->field = mode->field;
1045  
1046  	if (format->which == V4L2_SUBDEV_FORMAT_TRY)
1047  		*v4l2_subdev_get_try_format(sd, sd_state, format->pad) = format->format;
1048  
1049  	mutex_unlock(&isl7998x->lock);
1050  
1051  	return 0;
1052  }
1053  
isl7998x_set_ctrl(struct v4l2_ctrl * ctrl)1054  static int isl7998x_set_ctrl(struct v4l2_ctrl *ctrl)
1055  {
1056  	struct isl7998x *isl7998x = container_of(ctrl->handler,
1057  						 struct isl7998x, ctrl_handler);
1058  	int ret = 0;
1059  
1060  	switch (ctrl->id) {
1061  	case V4L2_CID_TEST_PATTERN_BARS:
1062  		mutex_lock(&isl7998x->lock);
1063  		isl7998x->test_pattern_bars = ctrl->val & 0x3;
1064  		ret = isl7998x_set_test_pattern(isl7998x);
1065  		mutex_unlock(&isl7998x->lock);
1066  		break;
1067  	case V4L2_CID_TEST_PATTERN_CHANNELS:
1068  		mutex_lock(&isl7998x->lock);
1069  		isl7998x->test_pattern_chans = ctrl->val & 0xf;
1070  		ret = isl7998x_set_test_pattern(isl7998x);
1071  		mutex_unlock(&isl7998x->lock);
1072  		break;
1073  	case V4L2_CID_TEST_PATTERN_COLOR:
1074  		mutex_lock(&isl7998x->lock);
1075  		isl7998x->test_pattern_color = ctrl->val & 0x3;
1076  		ret = isl7998x_set_test_pattern(isl7998x);
1077  		mutex_unlock(&isl7998x->lock);
1078  		break;
1079  	case V4L2_CID_TEST_PATTERN:
1080  		mutex_lock(&isl7998x->lock);
1081  		isl7998x->test_pattern = ctrl->val;
1082  		ret = isl7998x_set_test_pattern(isl7998x);
1083  		mutex_unlock(&isl7998x->lock);
1084  		break;
1085  	}
1086  
1087  	return ret;
1088  }
1089  
1090  static const struct v4l2_subdev_core_ops isl7998x_subdev_core_ops = {
1091  #ifdef CONFIG_VIDEO_ADV_DEBUG
1092  	.g_register	= isl7998x_g_register,
1093  	.s_register	= isl7998x_s_register,
1094  #endif
1095  };
1096  
1097  static const struct v4l2_subdev_video_ops isl7998x_subdev_video_ops = {
1098  	.g_std		= isl7998x_g_std,
1099  	.s_std		= isl7998x_s_std,
1100  	.querystd	= isl7998x_querystd,
1101  	.g_tvnorms	= isl7998x_g_tvnorms,
1102  	.g_input_status	= isl7998x_g_input_status,
1103  	.s_stream	= isl7998x_s_stream,
1104  	.pre_streamon	= isl7998x_pre_streamon,
1105  	.post_streamoff	= isl7998x_post_streamoff,
1106  };
1107  
1108  static const struct v4l2_subdev_pad_ops isl7998x_subdev_pad_ops = {
1109  	.enum_mbus_code		= isl7998x_enum_mbus_code,
1110  	.enum_frame_size	= isl7998x_enum_frame_size,
1111  	.get_fmt		= isl7998x_get_fmt,
1112  	.set_fmt		= isl7998x_set_fmt,
1113  };
1114  
1115  static const struct v4l2_subdev_ops isl7998x_subdev_ops = {
1116  	.core		= &isl7998x_subdev_core_ops,
1117  	.video		= &isl7998x_subdev_video_ops,
1118  	.pad		= &isl7998x_subdev_pad_ops,
1119  };
1120  
1121  static const struct media_entity_operations isl7998x_entity_ops = {
1122  	.link_validate = v4l2_subdev_link_validate,
1123  };
1124  
1125  static const struct v4l2_ctrl_ops isl7998x_ctrl_ops = {
1126  	.s_ctrl			= isl7998x_set_ctrl,
1127  };
1128  
1129  static const struct v4l2_ctrl_config isl7998x_ctrls[] = {
1130  	{
1131  		.ops		= &isl7998x_ctrl_ops,
1132  		.id		= V4L2_CID_TEST_PATTERN_BARS,
1133  		.type		= V4L2_CTRL_TYPE_MENU,
1134  		.name		= "Test Pattern Bars",
1135  		.max		= ARRAY_SIZE(isl7998x_test_pattern_bars) - 1,
1136  		.def		= 0,
1137  		.qmenu		= isl7998x_test_pattern_bars,
1138  	}, {
1139  		.ops		= &isl7998x_ctrl_ops,
1140  		.id		= V4L2_CID_TEST_PATTERN_CHANNELS,
1141  		.type		= V4L2_CTRL_TYPE_INTEGER,
1142  		.name		= "Test Pattern Channels",
1143  		.min		= 0,
1144  		.max		= 0xf,
1145  		.step		= 1,
1146  		.def		= 0xf,
1147  		.flags		= 0,
1148  	}, {
1149  		.ops		= &isl7998x_ctrl_ops,
1150  		.id		= V4L2_CID_TEST_PATTERN_COLOR,
1151  		.type		= V4L2_CTRL_TYPE_MENU,
1152  		.name		= "Test Pattern Color",
1153  		.max		= ARRAY_SIZE(isl7998x_test_pattern_colors) - 1,
1154  		.def		= 0,
1155  		.qmenu		= isl7998x_test_pattern_colors,
1156  	},
1157  };
1158  
1159  #define ISL7998X_REG_DECODER_ACA_READABLE_RANGE(page)			\
1160  	/* Decoder range */						\
1161  	regmap_reg_range(ISL7998X_REG_PX_DEC_INPUT_FMT(page),		\
1162  			 ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page)),	\
1163  	regmap_reg_range(ISL7998X_REG_PX_DEC_ANCTL(page),		\
1164  			 ISL7998X_REG_PX_DEC_CSC_CTL(page)),		\
1165  	regmap_reg_range(ISL7998X_REG_PX_DEC_BRIGHT(page),		\
1166  			 ISL7998X_REG_PX_DEC_HUE(page)),		\
1167  	regmap_reg_range(ISL7998X_REG_PX_DEC_VERT_PEAK(page),		\
1168  			 ISL7998X_REG_PX_DEC_CORING(page)),		\
1169  	regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page),			\
1170  			 ISL7998X_REG_PX_DEC_SDTR(page)),		\
1171  	regmap_reg_range(ISL7998X_REG_PX_DEC_CLMPG(page),		\
1172  			 ISL7998X_REG_PX_DEC_DATA_CONV(page)),		\
1173  	regmap_reg_range(ISL7998X_REG_PX_DEC_INTERNAL_TEST(page),	\
1174  			 ISL7998X_REG_PX_DEC_INTERNAL_TEST(page)),	\
1175  	regmap_reg_range(ISL7998X_REG_PX_DEC_H_DELAY_CTL(page),		\
1176  			 ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(page)),	\
1177  	/* ACA range */							\
1178  	regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_1(page),		\
1179  			 ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(page)),	\
1180  	regmap_reg_range(ISL7998X_REG_PX_ACA_Y_AVG(page),		\
1181  			 ISL7998X_REG_PX_ACA_CTL_4(page)),		\
1182  	regmap_reg_range(ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(page),	\
1183  			 ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page)),	\
1184  	regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(page),		\
1185  			 ISL7998X_REG_PX_DEC_PAGE(page))
1186  
1187  #define ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(page)			\
1188  	/* Decoder range */						\
1189  	regmap_reg_range(ISL7998X_REG_PX_DEC_INPUT_FMT(page),		\
1190  			 ISL7998X_REG_PX_DEC_INPUT_FMT(page)),		\
1191  	regmap_reg_range(ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page),	\
1192  			 ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page)),	\
1193  	regmap_reg_range(ISL7998X_REG_PX_DEC_ANCTL(page),		\
1194  			 ISL7998X_REG_PX_DEC_CSC_CTL(page)),		\
1195  	regmap_reg_range(ISL7998X_REG_PX_DEC_BRIGHT(page),		\
1196  			 ISL7998X_REG_PX_DEC_HUE(page)),		\
1197  	regmap_reg_range(ISL7998X_REG_PX_DEC_VERT_PEAK(page),		\
1198  			 ISL7998X_REG_PX_DEC_CORING(page)),		\
1199  	regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page),			\
1200  			 ISL7998X_REG_PX_DEC_SDTR(page)),		\
1201  	regmap_reg_range(ISL7998X_REG_PX_DEC_CLMPG(page),		\
1202  			 ISL7998X_REG_PX_DEC_MISC3(page)),		\
1203  	regmap_reg_range(ISL7998X_REG_PX_DEC_CLMD(page),		\
1204  			 ISL7998X_REG_PX_DEC_DATA_CONV(page)),		\
1205  	regmap_reg_range(ISL7998X_REG_PX_DEC_INTERNAL_TEST(page),	\
1206  			 ISL7998X_REG_PX_DEC_INTERNAL_TEST(page)),	\
1207  	regmap_reg_range(ISL7998X_REG_PX_DEC_H_DELAY_CTL(page),		\
1208  			 ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(page)),	\
1209  	/* ACA range */							\
1210  	regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_1(page),		\
1211  			 ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(page)),	\
1212  	regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_2(page),		\
1213  			 ISL7998X_REG_PX_ACA_CTL_4(page)),		\
1214  	regmap_reg_range(ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(page),	\
1215  			 ISL7998X_REG_PX_ACA_HIST_DATA_LO(page)),	\
1216  	regmap_reg_range(ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page),	\
1217  			 ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page)),	\
1218  	regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(page),		\
1219  			 ISL7998X_REG_PX_DEC_PAGE(page))
1220  
1221  #define ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(page)			\
1222  	/* Decoder range */						\
1223  	regmap_reg_range(ISL7998X_REG_PX_DEC_STATUS_1(page),		\
1224  			 ISL7998X_REG_PX_DEC_STATUS_1(page)),		\
1225  	regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page),			\
1226  			 ISL7998X_REG_PX_DEC_SDT(page)),		\
1227  	regmap_reg_range(ISL7998X_REG_PX_DEC_MVSN(page),		\
1228  			 ISL7998X_REG_PX_DEC_HFREF(page)),		\
1229  	/* ACA range */							\
1230  	regmap_reg_range(ISL7998X_REG_PX_ACA_Y_AVG(page),		\
1231  			 ISL7998X_REG_PX_ACA_Y_HIGH(page)),		\
1232  	regmap_reg_range(ISL7998X_REG_PX_ACA_HIST_DATA_LO(page),	\
1233  			 ISL7998X_REG_PX_ACA_FLEX_WIN_CR_CLR(page))
1234  
1235  static const struct regmap_range isl7998x_readable_ranges[] = {
1236  	regmap_reg_range(ISL7998X_REG_P0_PRODUCT_ID_CODE,
1237  			 ISL7998X_REG_P0_IRQ_SYNC_CTL),
1238  	regmap_reg_range(ISL7998X_REG_P0_INTERRUPT_STATUS,
1239  			 ISL7998X_REG_P0_CLOCK_DELAY),
1240  	regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(0),
1241  			 ISL7998X_REG_PX_DEC_PAGE(0)),
1242  
1243  	ISL7998X_REG_DECODER_ACA_READABLE_RANGE(1),
1244  	ISL7998X_REG_DECODER_ACA_READABLE_RANGE(2),
1245  	ISL7998X_REG_DECODER_ACA_READABLE_RANGE(3),
1246  	ISL7998X_REG_DECODER_ACA_READABLE_RANGE(4),
1247  
1248  	regmap_reg_range(ISL7998X_REG_P5_LI_ENGINE_CTL,
1249  			 ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL),
1250  	regmap_reg_range(ISL7998X_REG_P5_FIFO_THRSH_CNT_1,
1251  			 ISL7998X_REG_P5_PLL_ANA),
1252  	regmap_reg_range(ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1,
1253  			 ISL7998X_REG_P5_HIST_LINE_CNT_2),
1254  	regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(5),
1255  			 ISL7998X_REG_PX_DEC_PAGE(5)),
1256  };
1257  
1258  static const struct regmap_range isl7998x_writeable_ranges[] = {
1259  	regmap_reg_range(ISL7998X_REG_P0_SW_RESET_CTL,
1260  			 ISL7998X_REG_P0_IRQ_SYNC_CTL),
1261  	regmap_reg_range(ISL7998X_REG_P0_CHAN_1_IRQ,
1262  			 ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN),
1263  	regmap_reg_range(ISL7998X_REG_P0_CLOCK_DELAY,
1264  			 ISL7998X_REG_P0_CLOCK_DELAY),
1265  	regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(0),
1266  			 ISL7998X_REG_PX_DEC_PAGE(0)),
1267  
1268  	ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(1),
1269  	ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(2),
1270  	ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(3),
1271  	ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(4),
1272  
1273  	regmap_reg_range(ISL7998X_REG_P5_LI_ENGINE_CTL,
1274  			 ISL7998X_REG_P5_ESC_MODE_TIME_CTL),
1275  	regmap_reg_range(ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL,
1276  			 ISL7998X_REG_P5_PLL_ANA),
1277  	regmap_reg_range(ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1,
1278  			 ISL7998X_REG_P5_HIST_LINE_CNT_2),
1279  	regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(5),
1280  			 ISL7998X_REG_PX_DEC_PAGE(5)),
1281  
1282  	ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(0xf),
1283  };
1284  
1285  static const struct regmap_range isl7998x_volatile_ranges[] = {
1286  	/* Product id code register is used to check availability */
1287  	regmap_reg_range(ISL7998X_REG_P0_PRODUCT_ID_CODE,
1288  			 ISL7998X_REG_P0_PRODUCT_ID_CODE),
1289  	regmap_reg_range(ISL7998X_REG_P0_MPP1_SYNC_CTL,
1290  			 ISL7998X_REG_P0_IRQ_SYNC_CTL),
1291  	regmap_reg_range(ISL7998X_REG_P0_INTERRUPT_STATUS,
1292  			 ISL7998X_REG_P0_INTERRUPT_STATUS),
1293  	regmap_reg_range(ISL7998X_REG_P0_CHAN_1_STATUS,
1294  			 ISL7998X_REG_P0_SHORT_DIAG_STATUS),
1295  
1296  	ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(1),
1297  	ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(2),
1298  	ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(3),
1299  	ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(4),
1300  
1301  	regmap_reg_range(ISL7998X_REG_P5_AUTO_TEST_ERR_DET,
1302  			 ISL7998X_REG_P5_PIC_HEIGHT_LOW),
1303  };
1304  
1305  static const struct regmap_access_table isl7998x_readable_table = {
1306  	.yes_ranges = isl7998x_readable_ranges,
1307  	.n_yes_ranges = ARRAY_SIZE(isl7998x_readable_ranges),
1308  };
1309  
1310  static const struct regmap_access_table isl7998x_writeable_table = {
1311  	.yes_ranges = isl7998x_writeable_ranges,
1312  	.n_yes_ranges = ARRAY_SIZE(isl7998x_writeable_ranges),
1313  };
1314  
1315  static const struct regmap_access_table isl7998x_volatile_table = {
1316  	.yes_ranges = isl7998x_volatile_ranges,
1317  	.n_yes_ranges = ARRAY_SIZE(isl7998x_volatile_ranges),
1318  };
1319  
1320  static const struct regmap_range_cfg isl7998x_ranges[] = {
1321  	{
1322  		.range_min	= ISL7998X_REG_PN_BASE(0),
1323  		.range_max	= ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf),
1324  		.selector_reg	= ISL7998X_REG_PX_DEC_PAGE(0),
1325  		.selector_mask	= ISL7998X_REG_PX_DEC_PAGE_MASK,
1326  		.window_start	= 0,
1327  		.window_len	= 256,
1328  	}
1329  };
1330  
1331  static const struct regmap_config isl7998x_regmap = {
1332  	.reg_bits	= 8,
1333  	.val_bits	= 8,
1334  	.max_register	= ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf),
1335  	.ranges		= isl7998x_ranges,
1336  	.num_ranges	= ARRAY_SIZE(isl7998x_ranges),
1337  	.rd_table	= &isl7998x_readable_table,
1338  	.wr_table	= &isl7998x_writeable_table,
1339  	.volatile_table	= &isl7998x_volatile_table,
1340  	.cache_type	= REGCACHE_RBTREE,
1341  };
1342  
isl7998x_mc_init(struct isl7998x * isl7998x)1343  static int isl7998x_mc_init(struct isl7998x *isl7998x)
1344  {
1345  	unsigned int i;
1346  
1347  	isl7998x->subdev.entity.ops = &isl7998x_entity_ops;
1348  	isl7998x->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
1349  
1350  	isl7998x->pads[ISL7998X_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE;
1351  	for (i = ISL7998X_PAD_VIN1; i < ISL7998X_NUM_PADS; i++)
1352  		isl7998x->pads[i].flags = MEDIA_PAD_FL_SINK;
1353  
1354  	return media_entity_pads_init(&isl7998x->subdev.entity,
1355  				      ISL7998X_NUM_PADS,
1356  				      isl7998x->pads);
1357  }
1358  
get_link_freq_menu_index(unsigned int lanes,unsigned int inputs)1359  static int get_link_freq_menu_index(unsigned int lanes,
1360  				    unsigned int inputs)
1361  {
1362  	int ret = -EINVAL;
1363  
1364  	switch (lanes) {
1365  	case 1:
1366  		if (inputs == 1)
1367  			ret = 0;
1368  		if (inputs == 2)
1369  			ret = 1;
1370  		if (inputs == 4)
1371  			ret = 2;
1372  		break;
1373  	case 2:
1374  		if (inputs == 2)
1375  			ret = 0;
1376  		if (inputs == 4)
1377  			ret = 1;
1378  		break;
1379  	default:
1380  		break;
1381  	}
1382  
1383  	return ret;
1384  }
1385  
isl7998x_remove_controls(struct isl7998x * isl7998x)1386  static void isl7998x_remove_controls(struct isl7998x *isl7998x)
1387  {
1388  	v4l2_ctrl_handler_free(&isl7998x->ctrl_handler);
1389  	mutex_destroy(&isl7998x->ctrl_mutex);
1390  }
1391  
isl7998x_init_controls(struct isl7998x * isl7998x)1392  static int isl7998x_init_controls(struct isl7998x *isl7998x)
1393  {
1394  	struct v4l2_subdev *sd = &isl7998x->subdev;
1395  	int link_freq_index;
1396  	unsigned int i;
1397  	int ret;
1398  
1399  	ret = v4l2_ctrl_handler_init(&isl7998x->ctrl_handler,
1400  				     2 + ARRAY_SIZE(isl7998x_ctrls));
1401  	if (ret)
1402  		return ret;
1403  
1404  	mutex_init(&isl7998x->ctrl_mutex);
1405  	isl7998x->ctrl_handler.lock = &isl7998x->ctrl_mutex;
1406  	link_freq_index = get_link_freq_menu_index(isl7998x->nr_mipi_lanes,
1407  						   isl7998x->nr_inputs);
1408  	if (link_freq_index < 0 ||
1409  	    link_freq_index >= ARRAY_SIZE(link_freq_menu_items)) {
1410  		dev_err(sd->dev,
1411  			"failed to find MIPI link freq: %d lanes, %d inputs\n",
1412  			isl7998x->nr_mipi_lanes, isl7998x->nr_inputs);
1413  		ret = -EINVAL;
1414  		goto err;
1415  	}
1416  
1417  	isl7998x->link_freq = v4l2_ctrl_new_int_menu(&isl7998x->ctrl_handler,
1418  						     &isl7998x_ctrl_ops,
1419  						     V4L2_CID_LINK_FREQ,
1420  						     ARRAY_SIZE(link_freq_menu_items) - 1,
1421  						     link_freq_index,
1422  						     link_freq_menu_items);
1423  	if (isl7998x->link_freq)
1424  		isl7998x->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1425  
1426  	for (i = 0; i < ARRAY_SIZE(isl7998x_ctrls); i++)
1427  		v4l2_ctrl_new_custom(&isl7998x->ctrl_handler,
1428  				     &isl7998x_ctrls[i], NULL);
1429  
1430  	v4l2_ctrl_new_std_menu_items(&isl7998x->ctrl_handler,
1431  				     &isl7998x_ctrl_ops,
1432  				     V4L2_CID_TEST_PATTERN,
1433  				     ARRAY_SIZE(isl7998x_test_pattern_menu) - 1,
1434  				     0, 0, isl7998x_test_pattern_menu);
1435  
1436  	ret = isl7998x->ctrl_handler.error;
1437  	if (ret)
1438  		goto err;
1439  
1440  	isl7998x->subdev.ctrl_handler = &isl7998x->ctrl_handler;
1441  	v4l2_ctrl_handler_setup(&isl7998x->ctrl_handler);
1442  
1443  	return 0;
1444  
1445  err:
1446  	isl7998x_remove_controls(isl7998x);
1447  
1448  	return ret;
1449  }
1450  
isl7998x_probe(struct i2c_client * client)1451  static int isl7998x_probe(struct i2c_client *client)
1452  {
1453  	struct device *dev = &client->dev;
1454  	struct v4l2_fwnode_endpoint endpoint = {
1455  		.bus_type = V4L2_MBUS_CSI2_DPHY,
1456  	};
1457  	struct fwnode_handle *ep;
1458  	struct isl7998x *isl7998x;
1459  	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1460  	int nr_inputs;
1461  	int ret;
1462  
1463  	ret = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA);
1464  	if (!ret) {
1465  		dev_warn(&adapter->dev,
1466  			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
1467  		return -EIO;
1468  	}
1469  
1470  	isl7998x = devm_kzalloc(dev, sizeof(*isl7998x), GFP_KERNEL);
1471  	if (!isl7998x)
1472  		return -ENOMEM;
1473  
1474  	isl7998x->pd_gpio = devm_gpiod_get_optional(dev, "powerdown",
1475  						    GPIOD_OUT_HIGH);
1476  	if (IS_ERR(isl7998x->pd_gpio))
1477  		return dev_err_probe(dev, PTR_ERR(isl7998x->pd_gpio),
1478  				     "Failed to retrieve/request PD GPIO\n");
1479  
1480  	isl7998x->rstb_gpio = devm_gpiod_get_optional(dev, "reset",
1481  						      GPIOD_OUT_HIGH);
1482  	if (IS_ERR(isl7998x->rstb_gpio))
1483  		return dev_err_probe(dev, PTR_ERR(isl7998x->rstb_gpio),
1484  				     "Failed to retrieve/request RSTB GPIO\n");
1485  
1486  	isl7998x->regmap = devm_regmap_init_i2c(client, &isl7998x_regmap);
1487  	if (IS_ERR(isl7998x->regmap))
1488  		return dev_err_probe(dev, PTR_ERR(isl7998x->regmap),
1489  				     "Failed to allocate register map\n");
1490  
1491  	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
1492  					     ISL7998X_PAD_OUT, 0, 0);
1493  	if (!ep)
1494  		return dev_err_probe(dev, -EINVAL, "Missing endpoint node\n");
1495  
1496  	ret = v4l2_fwnode_endpoint_parse(ep, &endpoint);
1497  	fwnode_handle_put(ep);
1498  	if (ret)
1499  		return dev_err_probe(dev, ret, "Failed to parse endpoint\n");
1500  
1501  	if (endpoint.bus.mipi_csi2.num_data_lanes == 0 ||
1502  	    endpoint.bus.mipi_csi2.num_data_lanes > 2)
1503  		return dev_err_probe(dev, -EINVAL,
1504  				     "Invalid number of MIPI lanes\n");
1505  
1506  	isl7998x->nr_mipi_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
1507  
1508  	nr_inputs = isl7998x_get_nr_inputs(dev->of_node);
1509  	if (nr_inputs < 0)
1510  		return dev_err_probe(dev, nr_inputs,
1511  				     "Invalid number of input ports\n");
1512  	isl7998x->nr_inputs = nr_inputs;
1513  
1514  	v4l2_i2c_subdev_init(&isl7998x->subdev, client, &isl7998x_subdev_ops);
1515  	isl7998x->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1516  
1517  	ret = isl7998x_mc_init(isl7998x);
1518  	if (ret < 0)
1519  		return ret;
1520  
1521  	isl7998x->fmt = &isl7998x_colour_fmts[0];
1522  	isl7998x->norm = V4L2_STD_NTSC;
1523  	isl7998x->enabled = 0;
1524  
1525  	mutex_init(&isl7998x->lock);
1526  
1527  	ret = isl7998x_init_controls(isl7998x);
1528  	if (ret)
1529  		goto err_entity_cleanup;
1530  
1531  	ret = v4l2_async_register_subdev(&isl7998x->subdev);
1532  	if (ret < 0)
1533  		goto err_controls_cleanup;
1534  
1535  	pm_runtime_enable(dev);
1536  
1537  	return 0;
1538  
1539  err_controls_cleanup:
1540  	isl7998x_remove_controls(isl7998x);
1541  err_entity_cleanup:
1542  	media_entity_cleanup(&isl7998x->subdev.entity);
1543  
1544  	return ret;
1545  }
1546  
isl7998x_remove(struct i2c_client * client)1547  static void isl7998x_remove(struct i2c_client *client)
1548  {
1549  	struct isl7998x *isl7998x = i2c_to_isl7998x(client);
1550  
1551  	pm_runtime_disable(&client->dev);
1552  	v4l2_async_unregister_subdev(&isl7998x->subdev);
1553  	isl7998x_remove_controls(isl7998x);
1554  	media_entity_cleanup(&isl7998x->subdev.entity);
1555  }
1556  
1557  static const struct of_device_id isl7998x_of_match[] = {
1558  	{ .compatible = "isil,isl79987", },
1559  	{ /* sentinel */ },
1560  };
1561  MODULE_DEVICE_TABLE(of, isl7998x_of_match);
1562  
1563  static const struct i2c_device_id isl7998x_id[] = {
1564  	{ "isl79987", 0 },
1565  	{ /* sentinel */ },
1566  };
1567  MODULE_DEVICE_TABLE(i2c, isl7998x_id);
1568  
isl7998x_runtime_resume(struct device * dev)1569  static int __maybe_unused isl7998x_runtime_resume(struct device *dev)
1570  {
1571  	struct v4l2_subdev *sd = dev_get_drvdata(dev);
1572  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
1573  	int ret;
1574  
1575  	gpiod_set_value(isl7998x->rstb_gpio, 1);
1576  	gpiod_set_value(isl7998x->pd_gpio, 0);
1577  	gpiod_set_value(isl7998x->rstb_gpio, 0);
1578  
1579  	ret = isl7998x_wait_power_on(isl7998x);
1580  	if (ret)
1581  		goto err;
1582  
1583  	ret = isl7998x_init(isl7998x);
1584  	if (ret)
1585  		goto err;
1586  
1587  	return 0;
1588  
1589  err:
1590  	gpiod_set_value(isl7998x->pd_gpio, 1);
1591  
1592  	return ret;
1593  }
1594  
isl7998x_runtime_suspend(struct device * dev)1595  static int __maybe_unused isl7998x_runtime_suspend(struct device *dev)
1596  {
1597  	struct v4l2_subdev *sd = dev_get_drvdata(dev);
1598  	struct isl7998x *isl7998x = sd_to_isl7998x(sd);
1599  
1600  	gpiod_set_value(isl7998x->pd_gpio, 1);
1601  
1602  	return 0;
1603  }
1604  
1605  static const struct dev_pm_ops isl7998x_pm_ops = {
1606  	SET_RUNTIME_PM_OPS(isl7998x_runtime_suspend,
1607  			   isl7998x_runtime_resume,
1608  			   NULL)
1609  };
1610  
1611  static struct i2c_driver isl7998x_i2c_driver = {
1612  	.driver = {
1613  		.name = "isl7998x",
1614  		.of_match_table = isl7998x_of_match,
1615  		.pm = &isl7998x_pm_ops,
1616  	},
1617  	.probe		= isl7998x_probe,
1618  	.remove		= isl7998x_remove,
1619  	.id_table	= isl7998x_id,
1620  };
1621  
1622  module_i2c_driver(isl7998x_i2c_driver);
1623  
1624  MODULE_DESCRIPTION("Intersil ISL7998x Analog to MIPI CSI-2/BT656 decoder");
1625  MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
1626  MODULE_LICENSE("GPL v2");
1627