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