151ef2be5SMarek Vasut // SPDX-License-Identifier: GPL-2.0 251ef2be5SMarek Vasut /* 351ef2be5SMarek Vasut * Intersil ISL7998x analog to MIPI CSI-2 or BT.656 decoder driver. 451ef2be5SMarek Vasut * 551ef2be5SMarek Vasut * Copyright (C) 2018-2019 Marek Vasut <marex@denx.de> 651ef2be5SMarek Vasut * Copyright (C) 2021 Michael Tretter <kernel@pengutronix.de> 751ef2be5SMarek Vasut */ 851ef2be5SMarek Vasut 951ef2be5SMarek Vasut #include <linux/bitfield.h> 1051ef2be5SMarek Vasut #include <linux/delay.h> 11f001cc8dSLinus Walleij #include <linux/gpio/consumer.h> 1251ef2be5SMarek Vasut #include <linux/i2c.h> 1351ef2be5SMarek Vasut #include <linux/module.h> 1451ef2be5SMarek Vasut #include <linux/of_graph.h> 1551ef2be5SMarek Vasut #include <linux/pm_runtime.h> 1651ef2be5SMarek Vasut #include <linux/regmap.h> 1751ef2be5SMarek Vasut #include <linux/slab.h> 1851ef2be5SMarek Vasut #include <linux/v4l2-mediabus.h> 1951ef2be5SMarek Vasut #include <linux/videodev2.h> 2051ef2be5SMarek Vasut 2151ef2be5SMarek Vasut #include <media/v4l2-async.h> 2251ef2be5SMarek Vasut #include <media/v4l2-common.h> 2351ef2be5SMarek Vasut #include <media/v4l2-ctrls.h> 2451ef2be5SMarek Vasut #include <media/v4l2-device.h> 2551ef2be5SMarek Vasut #include <media/v4l2-fwnode.h> 2651ef2be5SMarek Vasut #include <media/v4l2-ioctl.h> 2751ef2be5SMarek Vasut 2851ef2be5SMarek Vasut /* 2951ef2be5SMarek Vasut * This control allows to activate and deactivate the test pattern on 3051ef2be5SMarek Vasut * selected output channels. 3151ef2be5SMarek Vasut * This value is ISL7998x specific. 3251ef2be5SMarek Vasut */ 3351ef2be5SMarek Vasut #define V4L2_CID_TEST_PATTERN_CHANNELS (V4L2_CID_USER_ISL7998X_BASE + 0) 3451ef2be5SMarek Vasut 3551ef2be5SMarek Vasut /* 3651ef2be5SMarek Vasut * This control allows to specify the color of the test pattern. 3751ef2be5SMarek Vasut * This value is ISL7998x specific. 3851ef2be5SMarek Vasut */ 3951ef2be5SMarek Vasut #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_ISL7998X_BASE + 1) 4051ef2be5SMarek Vasut 4151ef2be5SMarek Vasut /* 4251ef2be5SMarek Vasut * This control allows to specify the bar pattern in the test pattern. 4351ef2be5SMarek Vasut * This value is ISL7998x specific. 4451ef2be5SMarek Vasut */ 4551ef2be5SMarek Vasut #define V4L2_CID_TEST_PATTERN_BARS (V4L2_CID_USER_ISL7998X_BASE + 2) 4651ef2be5SMarek Vasut 4751ef2be5SMarek Vasut #define ISL7998X_INPUTS 4 4851ef2be5SMarek Vasut 4951ef2be5SMarek Vasut #define ISL7998X_REG(page, reg) (((page) << 8) | (reg)) 5051ef2be5SMarek Vasut 5151ef2be5SMarek Vasut #define ISL7998X_REG_PN_SIZE 256 5251ef2be5SMarek Vasut #define ISL7998X_REG_PN_BASE(n) ((n) * ISL7998X_REG_PN_SIZE) 5351ef2be5SMarek Vasut 5451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_PAGE(page) ISL7998X_REG((page), 0xff) 5551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_PAGE_MASK 0xf 5651ef2be5SMarek Vasut #define ISL7998X_REG_P0_PRODUCT_ID_CODE ISL7998X_REG(0, 0x00) 5751ef2be5SMarek Vasut #define ISL7998X_REG_P0_PRODUCT_REV_CODE ISL7998X_REG(0, 0x01) 5851ef2be5SMarek Vasut #define ISL7998X_REG_P0_SW_RESET_CTL ISL7998X_REG(0, 0x02) 5951ef2be5SMarek Vasut #define ISL7998X_REG_P0_IO_BUFFER_CTL ISL7998X_REG(0, 0x03) 6051ef2be5SMarek Vasut #define ISL7998X_REG_P0_IO_BUFFER_CTL_1_1 ISL7998X_REG(0, 0x04) 6151ef2be5SMarek Vasut #define ISL7998X_REG_P0_IO_PAD_PULL_EN_CTL ISL7998X_REG(0, 0x05) 6251ef2be5SMarek Vasut #define ISL7998X_REG_P0_IO_BUFFER_CTL_1_2 ISL7998X_REG(0, 0x06) 6351ef2be5SMarek Vasut #define ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL ISL7998X_REG(0, 0x07) 6451ef2be5SMarek Vasut #define ISL7998X_REG_P0_CLK_CTL_1 ISL7998X_REG(0, 0x08) 6551ef2be5SMarek Vasut #define ISL7998X_REG_P0_CLK_CTL_2 ISL7998X_REG(0, 0x09) 6651ef2be5SMarek Vasut #define ISL7998X_REG_P0_CLK_CTL_3 ISL7998X_REG(0, 0x0a) 6751ef2be5SMarek Vasut #define ISL7998X_REG_P0_CLK_CTL_4 ISL7998X_REG(0, 0x0b) 6851ef2be5SMarek Vasut #define ISL7998X_REG_P0_MPP1_SYNC_CTL ISL7998X_REG(0, 0x0c) 6951ef2be5SMarek Vasut #define ISL7998X_REG_P0_MPP2_SYNC_CTL ISL7998X_REG(0, 0x0d) 7051ef2be5SMarek Vasut #define ISL7998X_REG_P0_IRQ_SYNC_CTL ISL7998X_REG(0, 0x0e) 7151ef2be5SMarek Vasut #define ISL7998X_REG_P0_INTERRUPT_STATUS ISL7998X_REG(0, 0x10) 7251ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_1_IRQ ISL7998X_REG(0, 0x11) 7351ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_2_IRQ ISL7998X_REG(0, 0x12) 7451ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_3_IRQ ISL7998X_REG(0, 0x13) 7551ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_4_IRQ ISL7998X_REG(0, 0x14) 7651ef2be5SMarek Vasut #define ISL7998X_REG_P0_SHORT_DIAG_IRQ ISL7998X_REG(0, 0x15) 7751ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_1_IRQ_EN ISL7998X_REG(0, 0x16) 7851ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_2_IRQ_EN ISL7998X_REG(0, 0x17) 7951ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_3_IRQ_EN ISL7998X_REG(0, 0x18) 8051ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_4_IRQ_EN ISL7998X_REG(0, 0x19) 8151ef2be5SMarek Vasut #define ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN ISL7998X_REG(0, 0x1a) 8251ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_1_STATUS ISL7998X_REG(0, 0x1b) 8351ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_2_STATUS ISL7998X_REG(0, 0x1c) 8451ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_3_STATUS ISL7998X_REG(0, 0x1d) 8551ef2be5SMarek Vasut #define ISL7998X_REG_P0_CHAN_4_STATUS ISL7998X_REG(0, 0x1e) 8651ef2be5SMarek Vasut #define ISL7998X_REG_P0_SHORT_DIAG_STATUS ISL7998X_REG(0, 0x1f) 8751ef2be5SMarek Vasut #define ISL7998X_REG_P0_CLOCK_DELAY ISL7998X_REG(0, 0x20) 8851ef2be5SMarek Vasut 8951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_INPUT_FMT(pg) ISL7998X_REG((pg), 0x02) 9051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_STATUS_1(pg) ISL7998X_REG((pg), 0x03) 9151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS BIT(7) 9251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_STATUS_1_HLOCK BIT(6) 9351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_STATUS_1_VLOCK BIT(3) 9451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_HS_DELAY_CTL(pg) ISL7998X_REG((pg), 0x04) 9551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_ANCTL(pg) ISL7998X_REG((pg), 0x06) 9651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CROP_HI(pg) ISL7998X_REG((pg), 0x07) 9751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_VDELAY_LO(pg) ISL7998X_REG((pg), 0x08) 9851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_VACTIVE_LO(pg) ISL7998X_REG((pg), 0x09) 9951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_HDELAY_LO(pg) ISL7998X_REG((pg), 0x0a) 10051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_HACTIVE_LO(pg) ISL7998X_REG((pg), 0x0b) 10151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CNTRL1(pg) ISL7998X_REG((pg), 0x0c) 10251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CSC_CTL(pg) ISL7998X_REG((pg), 0x0d) 10351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_BRIGHT(pg) ISL7998X_REG((pg), 0x10) 10451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CONTRAST(pg) ISL7998X_REG((pg), 0x11) 10551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SHARPNESS(pg) ISL7998X_REG((pg), 0x12) 10651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SAT_U(pg) ISL7998X_REG((pg), 0x13) 10751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SAT_V(pg) ISL7998X_REG((pg), 0x14) 10851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_HUE(pg) ISL7998X_REG((pg), 0x15) 10951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_VERT_PEAK(pg) ISL7998X_REG((pg), 0x17) 11051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CORING(pg) ISL7998X_REG((pg), 0x18) 11151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT(pg) ISL7998X_REG((pg), 0x1c) 11251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_DET BIT(7) 11351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_NOW GENMASK(6, 4) 11451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD GENMASK(2, 0) 11551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_M 0 11651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL 1 11751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_SECAM 2 11851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_443 3 11951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_M 4 12051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_CN 5 12151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_60 6 12251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN 7 12351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDTR(pg) ISL7998X_REG((pg), 0x1d) 12451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SDTR_ATSTART BIT(7) 12551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CLMPG(pg) ISL7998X_REG((pg), 0x20) 12651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_IAGC(pg) ISL7998X_REG((pg), 0x21) 12751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_AGCGAIN(pg) ISL7998X_REG((pg), 0x22) 12851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_PEAKWT(pg) ISL7998X_REG((pg), 0x23) 12951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CLMPL(pg) ISL7998X_REG((pg), 0x24) 13051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SYNCT(pg) ISL7998X_REG((pg), 0x25) 13151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_MISSCNT(pg) ISL7998X_REG((pg), 0x26) 13251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_PCLAMP(pg) ISL7998X_REG((pg), 0x27) 13351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_VERT_CTL_1(pg) ISL7998X_REG((pg), 0x28) 13451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_VERT_CTL_2(pg) ISL7998X_REG((pg), 0x29) 13551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CLR_KILL_LVL(pg) ISL7998X_REG((pg), 0x2a) 13651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_COMB_FILTER_CTL(pg) ISL7998X_REG((pg), 0x2b) 13751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_LUMA_DELAY(pg) ISL7998X_REG((pg), 0x2c) 13851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_MISC1(pg) ISL7998X_REG((pg), 0x2d) 13951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_MISC2(pg) ISL7998X_REG((pg), 0x2e) 14051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_MISC3(pg) ISL7998X_REG((pg), 0x2f) 14151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_MVSN(pg) ISL7998X_REG((pg), 0x30) 14251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CSTATUS2(pg) ISL7998X_REG((pg), 0x31) 14351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_HFREF(pg) ISL7998X_REG((pg), 0x32) 14451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CLMD(pg) ISL7998X_REG((pg), 0x33) 14551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_ID_DET_CTL(pg) ISL7998X_REG((pg), 0x34) 14651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_CLCNTL(pg) ISL7998X_REG((pg), 0x35) 14751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_1(pg) ISL7998X_REG((pg), 0x36) 14851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_2(pg) ISL7998X_REG((pg), 0x37) 14951ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_3(pg) ISL7998X_REG((pg), 0x38) 15051ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_DIFF_CLMP_CTL_4(pg) ISL7998X_REG((pg), 0x39) 15151ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SHORT_DET_CTL(pg) ISL7998X_REG((pg), 0x3a) 15251ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(pg) ISL7998X_REG((pg), 0x3b) 15351ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_AFE_TST_MUX_CTL(pg) ISL7998X_REG((pg), 0x3c) 15451ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_DATA_CONV(pg) ISL7998X_REG((pg), 0x3d) 15551ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_INTERNAL_TEST(pg) ISL7998X_REG((pg), 0x3f) 15651ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_H_DELAY_CTL(pg) ISL7998X_REG((pg), 0x43) 15751ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_H_DELAY_II_HI(pg) ISL7998X_REG((pg), 0x44) 15851ef2be5SMarek Vasut #define ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(pg) ISL7998X_REG((pg), 0x45) 15951ef2be5SMarek Vasut 16051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_CTL_1(pg) ISL7998X_REG((pg), 0x80) 16151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_GAIN_CTL(pg) ISL7998X_REG((pg), 0x81) 16251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_AVG_HI_LIMIT(pg) ISL7998X_REG((pg), 0x82) 16351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_AVG_LO_LIMIT(pg) ISL7998X_REG((pg), 0x83) 16451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_DET_THRESHOLD(pg) ISL7998X_REG((pg), 0x84) 16551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_BLACK_LVL(pg) ISL7998X_REG((pg), 0x85) 16651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_CENTER_LVL(pg) ISL7998X_REG((pg), 0x86) 16751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_WHITE_LVL(pg) ISL7998X_REG((pg), 0x87) 16851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_MEAN_OFF_LIMIT(pg) ISL7998X_REG((pg), 0x88) 16951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_MEAN_OFF_UPGAIN(pg) ISL7998X_REG((pg), 0x89) 17051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_MEAN_OFF_SLOPE(pg) ISL7998X_REG((pg), 0x8a) 17151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_MEAN_OFF_DNGAIN(pg) ISL7998X_REG((pg), 0x8b) 17251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_DELTA_CO_THRES(pg) ISL7998X_REG((pg), 0x8c) 17351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_DELTA_SLOPE(pg) ISL7998X_REG((pg), 0x8d) 17451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LO_HI_AVG_THRES(pg) ISL7998X_REG((pg), 0x8e) 17551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LO_MAX_LVL_CTL(pg) ISL7998X_REG((pg), 0x8f) 17651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HI_MAX_LVL_CTL(pg) ISL7998X_REG((pg), 0x90) 17751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LO_UPGAIN_CTL(pg) ISL7998X_REG((pg), 0x91) 17851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LO_DNGAIN_CTL(pg) ISL7998X_REG((pg), 0x92) 17951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HI_UPGAIN_CTL(pg) ISL7998X_REG((pg), 0x93) 18051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HI_DNGAIN_CTL(pg) ISL7998X_REG((pg), 0x94) 18151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LOPASS_FLT_COEF(pg) ISL7998X_REG((pg), 0x95) 18251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_PDF_INDEX(pg) ISL7998X_REG((pg), 0x96) 18351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_WIN_H_STT(pg) ISL7998X_REG((pg), 0x97) 18451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_WIN_H_SZ1(pg) ISL7998X_REG((pg), 0x98) 18551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_WIN_H_SZ2(pg) ISL7998X_REG((pg), 0x99) 18651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_WIN_V_STT(pg) ISL7998X_REG((pg), 0x9a) 18751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ1(pg) ISL7998X_REG((pg), 0x9b) 18851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(pg) ISL7998X_REG((pg), 0x9c) 18951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_AVG(pg) ISL7998X_REG((pg), 0xa0) 19051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_AVG_LIM(pg) ISL7998X_REG((pg), 0xa1) 19151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LO_AVG(pg) ISL7998X_REG((pg), 0xa2) 19251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HI_AVG(pg) ISL7998X_REG((pg), 0xa3) 19351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_MAX(pg) ISL7998X_REG((pg), 0xa4) 19451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_MIN(pg) ISL7998X_REG((pg), 0xa5) 19551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_MOFFSET(pg) ISL7998X_REG((pg), 0xa6) 19651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LO_GAIN(pg) ISL7998X_REG((pg), 0xa7) 19751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HI_GAIN(pg) ISL7998X_REG((pg), 0xa8) 19851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LL_SLOPE(pg) ISL7998X_REG((pg), 0xa9) 19951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_LH_SLOPE(pg) ISL7998X_REG((pg), 0xaa) 20051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HL_SLOPE(pg) ISL7998X_REG((pg), 0xab) 20151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HH_SLOPE(pg) ISL7998X_REG((pg), 0xac) 20251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_X_LOW(pg) ISL7998X_REG((pg), 0xad) 20351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_X_MEAN(pg) ISL7998X_REG((pg), 0xae) 20451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_X_HIGH(pg) ISL7998X_REG((pg), 0xaf) 20551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_LOW(pg) ISL7998X_REG((pg), 0xb0) 20651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_MEAN(pg) ISL7998X_REG((pg), 0xb1) 20751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_Y_HIGH(pg) ISL7998X_REG((pg), 0xb2) 20851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_CTL_2(pg) ISL7998X_REG((pg), 0xb3) 20951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_CTL_3(pg) ISL7998X_REG((pg), 0xb4) 21051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_CTL_4(pg) ISL7998X_REG((pg), 0xb5) 21151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(pg) ISL7998X_REG((pg), 0xc0) 21251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TL_H(pg) ISL7998X_REG((pg), 0xc1) 21351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TL_L(pg) ISL7998X_REG((pg), 0xc2) 21451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TL_H(pg) ISL7998X_REG((pg), 0xc3) 21551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TL_L(pg) ISL7998X_REG((pg), 0xc4) 21651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TR_H(pg) ISL7998X_REG((pg), 0xc5) 21751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TR_L(pg) ISL7998X_REG((pg), 0xc6) 21851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TR_H(pg) ISL7998X_REG((pg), 0xc7) 21951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TR_L(pg) ISL7998X_REG((pg), 0xc8) 22051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BL_H(pg) ISL7998X_REG((pg), 0xc9) 22151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BL_L(pg) ISL7998X_REG((pg), 0xca) 22251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BL_H(pg) ISL7998X_REG((pg), 0xcb) 22351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BL_L(pg) ISL7998X_REG((pg), 0xcc) 22451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BR_H(pg) ISL7998X_REG((pg), 0xcd) 22551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BR_L(pg) ISL7998X_REG((pg), 0xce) 22651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BR_H(pg) ISL7998X_REG((pg), 0xcf) 22751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BR_L(pg) ISL7998X_REG((pg), 0xd0) 22851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_LM_H(pg) ISL7998X_REG((pg), 0xd1) 22951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_LM_L(pg) ISL7998X_REG((pg), 0xd2) 23051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_LM_H(pg) ISL7998X_REG((pg), 0xd3) 23151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_LM_L(pg) ISL7998X_REG((pg), 0xd4) 23251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TM_H(pg) ISL7998X_REG((pg), 0xd5) 23351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_TM_L(pg) ISL7998X_REG((pg), 0xd6) 23451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TM_H(pg) ISL7998X_REG((pg), 0xd7) 23551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_TM_L(pg) ISL7998X_REG((pg), 0xd8) 23651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BM_H(pg) ISL7998X_REG((pg), 0xd9) 23751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_BM_L(pg) ISL7998X_REG((pg), 0xda) 23851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BM_H(pg) ISL7998X_REG((pg), 0xdb) 23951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_BM_L(pg) ISL7998X_REG((pg), 0xdc) 24051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_RM_H(pg) ISL7998X_REG((pg), 0xdd) 24151ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_X_RM_L(pg) ISL7998X_REG((pg), 0xde) 24251ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_RM_H(pg) ISL7998X_REG((pg), 0xdf) 24351ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_RM_L(pg) ISL7998X_REG((pg), 0xe0) 24451ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_DATA_LO(pg) ISL7998X_REG((pg), 0xe1) 24551ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_DATA_MID(pg) ISL7998X_REG((pg), 0xe2) 24651ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_HIST_DATA_HI(pg) ISL7998X_REG((pg), 0xe3) 24751ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_Y_CLR(pg) ISL7998X_REG((pg), 0xe4) 24851ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_CB_CLR(pg) ISL7998X_REG((pg), 0xe5) 24951ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_FLEX_WIN_CR_CLR(pg) ISL7998X_REG((pg), 0xe6) 25051ef2be5SMarek Vasut #define ISL7998X_REG_PX_ACA_XFER_HIST_HOST(pg) ISL7998X_REG((pg), 0xe7) 25151ef2be5SMarek Vasut 25251ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_CTL ISL7998X_REG(5, 0x00) 25351ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_LINE_CTL ISL7998X_REG(5, 0x01) 25451ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH ISL7998X_REG(5, 0x02) 25551ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL ISL7998X_REG(5, 0x03) 25651ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_VC_ASSIGNMENT ISL7998X_REG(5, 0x04) 25751ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL ISL7998X_REG(5, 0x05) 25851ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL ISL7998X_REG(5, 0x06) 25951ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_READ_START_CTL ISL7998X_REG(5, 0x07) 26051ef2be5SMarek Vasut #define ISL7998X_REG_P5_PSEUDO_FRM_FIELD_CTL ISL7998X_REG(5, 0x08) 26151ef2be5SMarek Vasut #define ISL7998X_REG_P5_ONE_FIELD_MODE_CTL ISL7998X_REG(5, 0x09) 26251ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_INT_HW_TST_CTR ISL7998X_REG(5, 0x0a) 26351ef2be5SMarek Vasut #define ISL7998X_REG_P5_TP_GEN_BAR_PATTERN ISL7998X_REG(5, 0x0b) 26451ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_PCNT_PSFRM ISL7998X_REG(5, 0x0c) 26551ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL ISL7998X_REG(5, 0x0d) 26651ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_VBLANK_PSFRM ISL7998X_REG(5, 0x0e) 26751ef2be5SMarek Vasut #define ISL7998X_REG_P5_LI_ENGINE_CTL_2 ISL7998X_REG(5, 0x0f) 26851ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_WCNT_1 ISL7998X_REG(5, 0x10) 26951ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_WCNT_2 ISL7998X_REG(5, 0x11) 27051ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_1 ISL7998X_REG(5, 0x12) 27151ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_2 ISL7998X_REG(5, 0x13) 27251ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_3 ISL7998X_REG(5, 0x14) 27351ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_4 ISL7998X_REG(5, 0x15) 27451ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_5 ISL7998X_REG(5, 0x16) 27551ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_6 ISL7998X_REG(5, 0x17) 27651ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_PARAMS_1 ISL7998X_REG(5, 0x18) 27751ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_SOT_PERIOD ISL7998X_REG(5, 0x19) 27851ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_EOT_PERIOD ISL7998X_REG(5, 0x1a) 27951ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_PARAMS_2 ISL7998X_REG(5, 0x1b) 28051ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_7 ISL7998X_REG(5, 0x1c) 28151ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_8 ISL7998X_REG(5, 0x1d) 28251ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_9 ISL7998X_REG(5, 0x1e) 28351ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_10 ISL7998X_REG(5, 0x1f) 28451ef2be5SMarek Vasut #define ISL7998X_REG_P5_TP_GEN_MIPI ISL7998X_REG(5, 0x20) 28551ef2be5SMarek Vasut #define ISL7998X_REG_P5_ESC_MODE_TIME_CTL ISL7998X_REG(5, 0x21) 28651ef2be5SMarek Vasut #define ISL7998X_REG_P5_AUTO_TEST_ERR_DET ISL7998X_REG(5, 0x22) 28751ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_TIMING ISL7998X_REG(5, 0x23) 28851ef2be5SMarek Vasut #define ISL7998X_REG_P5_PIC_HEIGHT_HIGH ISL7998X_REG(5, 0x24) 28951ef2be5SMarek Vasut #define ISL7998X_REG_P5_PIC_HEIGHT_LOW ISL7998X_REG(5, 0x25) 29051ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL ISL7998X_REG(5, 0x26) 29151ef2be5SMarek Vasut #define ISL7998X_REG_P5_FIFO_THRSH_CNT_1 ISL7998X_REG(5, 0x28) 29251ef2be5SMarek Vasut #define ISL7998X_REG_P5_FIFO_THRSH_CNT_2 ISL7998X_REG(5, 0x29) 29351ef2be5SMarek Vasut #define ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1 ISL7998X_REG(5, 0x2a) 29451ef2be5SMarek Vasut #define ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2 ISL7998X_REG(5, 0x2b) 29551ef2be5SMarek Vasut #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_1 ISL7998X_REG(5, 0x2c) 29651ef2be5SMarek Vasut #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_2 ISL7998X_REG(5, 0x2d) 29751ef2be5SMarek Vasut #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_3 ISL7998X_REG(5, 0x2e) 29851ef2be5SMarek Vasut #define ISL7998X_REG_P5_PSF_FIELD_END_CTL_4 ISL7998X_REG(5, 0x2f) 29951ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_1 ISL7998X_REG(5, 0x30) 30051ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_2 ISL7998X_REG(5, 0x31) 30151ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_ANA_CLK_CTL ISL7998X_REG(5, 0x32) 30251ef2be5SMarek Vasut #define ISL7998X_REG_P5_PLL_ANA_STATUS ISL7998X_REG(5, 0x33) 30351ef2be5SMarek Vasut #define ISL7998X_REG_P5_PLL_ANA_MISC_CTL ISL7998X_REG(5, 0x34) 30451ef2be5SMarek Vasut #define ISL7998X_REG_P5_MIPI_ANA ISL7998X_REG(5, 0x35) 30551ef2be5SMarek Vasut #define ISL7998X_REG_P5_PLL_ANA ISL7998X_REG(5, 0x36) 30651ef2be5SMarek Vasut #define ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1 ISL7998X_REG(5, 0x38) 30751ef2be5SMarek Vasut #define ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_2 ISL7998X_REG(5, 0x39) 30851ef2be5SMarek Vasut #define ISL7998X_REG_P5_H_LINE_CNT_1 ISL7998X_REG(5, 0x3a) 30951ef2be5SMarek Vasut #define ISL7998X_REG_P5_H_LINE_CNT_2 ISL7998X_REG(5, 0x3b) 31051ef2be5SMarek Vasut #define ISL7998X_REG_P5_HIST_LINE_CNT_1 ISL7998X_REG(5, 0x3c) 31151ef2be5SMarek Vasut #define ISL7998X_REG_P5_HIST_LINE_CNT_2 ISL7998X_REG(5, 0x3d) 31251ef2be5SMarek Vasut 31351ef2be5SMarek Vasut static const struct reg_sequence isl7998x_init_seq_1[] = { 31451ef2be5SMarek Vasut { ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN, 0xff }, 31551ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SDT(0x1), 0x00 }, 31651ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x1), 0x03 }, 31751ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SDT(0x2), 0x00 }, 31851ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x2), 0x03 }, 31951ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SDT(0x3), 0x00 }, 32051ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x3), 0x03 }, 32151ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SDT(0x4), 0x00 }, 32251ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_SHORT_DET_CTL_1(0x4), 0x03 }, 32351ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_CTL, 0x00 }, 32451ef2be5SMarek Vasut { ISL7998X_REG_P0_SW_RESET_CTL, 0x1f, 10 }, 32551ef2be5SMarek Vasut { ISL7998X_REG_P0_IO_BUFFER_CTL, 0x00 }, 32651ef2be5SMarek Vasut { ISL7998X_REG_P0_MPP2_SYNC_CTL, 0xc9 }, 32751ef2be5SMarek Vasut { ISL7998X_REG_P0_IRQ_SYNC_CTL, 0xc9 }, 32851ef2be5SMarek Vasut { ISL7998X_REG_P0_CHAN_1_IRQ, 0x03 }, 32951ef2be5SMarek Vasut { ISL7998X_REG_P0_CHAN_2_IRQ, 0x00 }, 33051ef2be5SMarek Vasut { ISL7998X_REG_P0_CHAN_3_IRQ, 0x00 }, 33151ef2be5SMarek Vasut { ISL7998X_REG_P0_CHAN_4_IRQ, 0x00 }, 33251ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_CTL, 0x02 }, 33351ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_LINE_CTL, 0x85 }, 33451ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH, 0xa0 }, 33551ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL, 0x18 }, 33651ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL, 0x40 }, 33751ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x40 }, 33851ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_WCNT_1, 0x05 }, 33951ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_WCNT_2, 0xa0 }, 34051ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_MIPI, 0x00 }, 34151ef2be5SMarek Vasut { ISL7998X_REG_P5_ESC_MODE_TIME_CTL, 0x0c }, 34251ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 0x00 }, 34351ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1, 0x00 }, 34451ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2, 0x19 }, 34551ef2be5SMarek Vasut { ISL7998X_REG_P5_PSF_FIELD_END_CTL_1, 0x18 }, 34651ef2be5SMarek Vasut { ISL7998X_REG_P5_PSF_FIELD_END_CTL_2, 0xf1 }, 34751ef2be5SMarek Vasut { ISL7998X_REG_P5_PSF_FIELD_END_CTL_3, 0x00 }, 34851ef2be5SMarek Vasut { ISL7998X_REG_P5_PSF_FIELD_END_CTL_4, 0xf1 }, 34951ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_1, 0x00 }, 35051ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_ANA_DATA_CTL_2, 0x00 }, 35151ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_ANA_CLK_CTL, 0x00 }, 35251ef2be5SMarek Vasut { ISL7998X_REG_P5_PLL_ANA_STATUS, 0xc0 }, 35351ef2be5SMarek Vasut { ISL7998X_REG_P5_PLL_ANA_MISC_CTL, 0x18 }, 35451ef2be5SMarek Vasut { ISL7998X_REG_P5_PLL_ANA, 0x00 }, 35551ef2be5SMarek Vasut { ISL7998X_REG_P0_SW_RESET_CTL, 0x10, 10 }, 35651ef2be5SMarek Vasut /* Page 0xf means write to all of pages 1,2,3,4 */ 35751ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_VDELAY_LO(0xf), 0x14 }, 35851ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_MISC3(0xf), 0xe6 }, 35951ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_CLMD(0xf), 0x85 }, 36051ef2be5SMarek Vasut { ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(0xf), 0x11 }, 36151ef2be5SMarek Vasut { ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 0x00 }, 36251ef2be5SMarek Vasut { ISL7998X_REG_P0_CLK_CTL_1, 0x1f }, 36351ef2be5SMarek Vasut { ISL7998X_REG_P0_CLK_CTL_2, 0x43 }, 36451ef2be5SMarek Vasut { ISL7998X_REG_P0_CLK_CTL_3, 0x4f }, 36551ef2be5SMarek Vasut }; 36651ef2be5SMarek Vasut 36751ef2be5SMarek Vasut static const struct reg_sequence isl7998x_init_seq_2[] = { 36851ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_SYNC_CTL, 0x10 }, 36951ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_VC_ASSIGNMENT, 0xe4 }, 37051ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_TYPE_CTL, 0x00 }, 37151ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x60 }, 37251ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_READ_START_CTL, 0x2b }, 37351ef2be5SMarek Vasut { ISL7998X_REG_P5_PSEUDO_FRM_FIELD_CTL, 0x02 }, 37451ef2be5SMarek Vasut { ISL7998X_REG_P5_ONE_FIELD_MODE_CTL, 0x00 }, 37551ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_INT_HW_TST_CTR, 0x62 }, 37651ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_BAR_PATTERN, 0x02 }, 37751ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_PCNT_PSFRM, 0x36 }, 37851ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 0x00 }, 37951ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_VBLANK_PSFRM, 0x6c }, 38051ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_CTL_2, 0x00 }, 38151ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_WCNT_1, 0x05 }, 38251ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_WCNT_2, 0xa0 }, 38351ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_1, 0x77 }, 38451ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_2, 0x17 }, 38551ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_3, 0x08 }, 38651ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_4, 0x38 }, 38751ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_5, 0x14 }, 38851ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_6, 0xf6 }, 38951ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_PARAMS_1, 0x00 }, 39051ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_SOT_PERIOD, 0x17 }, 39151ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_EOT_PERIOD, 0x0a }, 39251ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_PARAMS_2, 0x71 }, 39351ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_7, 0x7a }, 39451ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_8, 0x0f }, 39551ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_DPHY_TIMING_CTL_9, 0x8c }, 39651ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 0x08 }, 39751ef2be5SMarek Vasut { ISL7998X_REG_P5_FIFO_THRSH_CNT_1, 0x01 }, 39851ef2be5SMarek Vasut { ISL7998X_REG_P5_FIFO_THRSH_CNT_2, 0x0e }, 39951ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_1, 0x00 }, 40051ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_RND_SYNC_CTL_2, 0x00 }, 40151ef2be5SMarek Vasut { ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 0x03 }, 40251ef2be5SMarek Vasut { ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_2, 0xc0 }, 40351ef2be5SMarek Vasut { ISL7998X_REG_P5_H_LINE_CNT_1, 0x06 }, 40451ef2be5SMarek Vasut { ISL7998X_REG_P5_H_LINE_CNT_2, 0xb3 }, 40551ef2be5SMarek Vasut { ISL7998X_REG_P5_HIST_LINE_CNT_1, 0x00 }, 40651ef2be5SMarek Vasut { ISL7998X_REG_P5_HIST_LINE_CNT_2, 0xf1 }, 40751ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_FIFO_CTL, 0x00 }, 40851ef2be5SMarek Vasut { ISL7998X_REG_P5_MIPI_ANA, 0x00 }, 40951ef2be5SMarek Vasut /* 41051ef2be5SMarek Vasut * Wait a bit after reset so that the chip can capture a frame 41151ef2be5SMarek Vasut * and update internal line counters. 41251ef2be5SMarek Vasut */ 41351ef2be5SMarek Vasut { ISL7998X_REG_P0_SW_RESET_CTL, 0x00, 50 }, 41451ef2be5SMarek Vasut }; 41551ef2be5SMarek Vasut 41651ef2be5SMarek Vasut enum isl7998x_pads { 41751ef2be5SMarek Vasut ISL7998X_PAD_OUT, 41851ef2be5SMarek Vasut ISL7998X_PAD_VIN1, 41951ef2be5SMarek Vasut ISL7998X_PAD_VIN2, 42051ef2be5SMarek Vasut ISL7998X_PAD_VIN3, 42151ef2be5SMarek Vasut ISL7998X_PAD_VIN4, 42251ef2be5SMarek Vasut ISL7998X_NUM_PADS 42351ef2be5SMarek Vasut }; 42451ef2be5SMarek Vasut 42551ef2be5SMarek Vasut struct isl7998x_datafmt { 42651ef2be5SMarek Vasut u32 code; 42751ef2be5SMarek Vasut enum v4l2_colorspace colorspace; 42851ef2be5SMarek Vasut }; 42951ef2be5SMarek Vasut 43051ef2be5SMarek Vasut static const struct isl7998x_datafmt isl7998x_colour_fmts[] = { 43151ef2be5SMarek Vasut { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB }, 43251ef2be5SMarek Vasut }; 43351ef2be5SMarek Vasut 43451ef2be5SMarek Vasut /* Menu items for LINK_FREQ V4L2 control */ 43551ef2be5SMarek Vasut static const s64 link_freq_menu_items[] = { 43651ef2be5SMarek Vasut /* 1 channel, 1 lane or 2 channels, 2 lanes */ 43751ef2be5SMarek Vasut 108000000, 43851ef2be5SMarek Vasut /* 2 channels, 1 lane or 4 channels, 2 lanes */ 43951ef2be5SMarek Vasut 216000000, 44051ef2be5SMarek Vasut /* 4 channels, 1 lane */ 44151ef2be5SMarek Vasut 432000000, 44251ef2be5SMarek Vasut }; 44351ef2be5SMarek Vasut 44451ef2be5SMarek Vasut /* Menu items for TEST_PATTERN V4L2 control */ 44551ef2be5SMarek Vasut static const char * const isl7998x_test_pattern_menu[] = { 44651ef2be5SMarek Vasut "Disabled", 44751ef2be5SMarek Vasut "Enabled", 44851ef2be5SMarek Vasut }; 44951ef2be5SMarek Vasut 45051ef2be5SMarek Vasut static const char * const isl7998x_test_pattern_bars[] = { 45151ef2be5SMarek Vasut "bbbbwb", "bbbwwb", "bbwbwb", "bbwwwb", 45251ef2be5SMarek Vasut }; 45351ef2be5SMarek Vasut 45451ef2be5SMarek Vasut static const char * const isl7998x_test_pattern_colors[] = { 45551ef2be5SMarek Vasut "Yellow", "Blue", "Green", "Pink", 45651ef2be5SMarek Vasut }; 45751ef2be5SMarek Vasut 45851ef2be5SMarek Vasut struct isl7998x_mode { 45951ef2be5SMarek Vasut unsigned int width; 46051ef2be5SMarek Vasut unsigned int height; 46151ef2be5SMarek Vasut enum v4l2_field field; 46251ef2be5SMarek Vasut }; 46351ef2be5SMarek Vasut 46451ef2be5SMarek Vasut static const struct isl7998x_mode supported_modes[] = { 46551ef2be5SMarek Vasut { 46651ef2be5SMarek Vasut .width = 720, 46751ef2be5SMarek Vasut .height = 576, 46851ef2be5SMarek Vasut .field = V4L2_FIELD_SEQ_TB, 46951ef2be5SMarek Vasut }, 47051ef2be5SMarek Vasut { 47151ef2be5SMarek Vasut .width = 720, 47251ef2be5SMarek Vasut .height = 480, 47351ef2be5SMarek Vasut .field = V4L2_FIELD_SEQ_BT, 47451ef2be5SMarek Vasut }, 47551ef2be5SMarek Vasut }; 47651ef2be5SMarek Vasut 47751ef2be5SMarek Vasut static const struct isl7998x_video_std { 47851ef2be5SMarek Vasut const v4l2_std_id norm; 47951ef2be5SMarek Vasut unsigned int id; 48051ef2be5SMarek Vasut const struct isl7998x_mode *mode; 48151ef2be5SMarek Vasut } isl7998x_std_res[] = { 48251ef2be5SMarek Vasut { V4L2_STD_NTSC_443, 48351ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_443, 48451ef2be5SMarek Vasut &supported_modes[1] }, 48551ef2be5SMarek Vasut { V4L2_STD_PAL_M, 48651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_M, 48751ef2be5SMarek Vasut &supported_modes[1] }, 48851ef2be5SMarek Vasut { V4L2_STD_PAL_Nc, 48951ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_CN, 49051ef2be5SMarek Vasut &supported_modes[0] }, 49151ef2be5SMarek Vasut { V4L2_STD_PAL_N, 49251ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL, 49351ef2be5SMarek Vasut &supported_modes[0] }, 49451ef2be5SMarek Vasut { V4L2_STD_PAL_60, 49551ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL_60, 49651ef2be5SMarek Vasut &supported_modes[1] }, 49751ef2be5SMarek Vasut { V4L2_STD_NTSC, 49851ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_NTSC_M, 49951ef2be5SMarek Vasut &supported_modes[1] }, 50051ef2be5SMarek Vasut { V4L2_STD_PAL, 50151ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_PAL, 50251ef2be5SMarek Vasut &supported_modes[0] }, 50351ef2be5SMarek Vasut { V4L2_STD_SECAM, 50451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_SECAM, 50551ef2be5SMarek Vasut &supported_modes[0] }, 50651ef2be5SMarek Vasut { V4L2_STD_UNKNOWN, 50751ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN, 50851ef2be5SMarek Vasut &supported_modes[1] }, 50951ef2be5SMarek Vasut }; 51051ef2be5SMarek Vasut 51151ef2be5SMarek Vasut struct isl7998x { 51251ef2be5SMarek Vasut struct v4l2_subdev subdev; 51351ef2be5SMarek Vasut struct regmap *regmap; 51451ef2be5SMarek Vasut struct gpio_desc *pd_gpio; 51551ef2be5SMarek Vasut struct gpio_desc *rstb_gpio; 51651ef2be5SMarek Vasut unsigned int nr_mipi_lanes; 51751ef2be5SMarek Vasut u32 nr_inputs; 51851ef2be5SMarek Vasut 51951ef2be5SMarek Vasut const struct isl7998x_datafmt *fmt; 52051ef2be5SMarek Vasut v4l2_std_id norm; 52151ef2be5SMarek Vasut struct media_pad pads[ISL7998X_NUM_PADS]; 52251ef2be5SMarek Vasut 52351ef2be5SMarek Vasut int enabled; 52451ef2be5SMarek Vasut 52551ef2be5SMarek Vasut /* protect fmt, norm, enabled */ 52651ef2be5SMarek Vasut struct mutex lock; 52751ef2be5SMarek Vasut 52851ef2be5SMarek Vasut struct v4l2_ctrl_handler ctrl_handler; 52951ef2be5SMarek Vasut /* protect ctrl_handler */ 53051ef2be5SMarek Vasut struct mutex ctrl_mutex; 53151ef2be5SMarek Vasut 53251ef2be5SMarek Vasut /* V4L2 Controls */ 53351ef2be5SMarek Vasut struct v4l2_ctrl *link_freq; 53451ef2be5SMarek Vasut u8 test_pattern; 53551ef2be5SMarek Vasut u8 test_pattern_bars; 53651ef2be5SMarek Vasut u8 test_pattern_chans; 53751ef2be5SMarek Vasut u8 test_pattern_color; 53851ef2be5SMarek Vasut }; 53951ef2be5SMarek Vasut 54051ef2be5SMarek Vasut static struct isl7998x *sd_to_isl7998x(struct v4l2_subdev *sd) 54151ef2be5SMarek Vasut { 54251ef2be5SMarek Vasut return container_of(sd, struct isl7998x, subdev); 54351ef2be5SMarek Vasut } 54451ef2be5SMarek Vasut 54551ef2be5SMarek Vasut static struct isl7998x *i2c_to_isl7998x(const struct i2c_client *client) 54651ef2be5SMarek Vasut { 54751ef2be5SMarek Vasut return sd_to_isl7998x(i2c_get_clientdata(client)); 54851ef2be5SMarek Vasut } 54951ef2be5SMarek Vasut 55051ef2be5SMarek Vasut static unsigned int isl7998x_norm_to_val(v4l2_std_id norm) 55151ef2be5SMarek Vasut { 55251ef2be5SMarek Vasut unsigned int i; 55351ef2be5SMarek Vasut 55451ef2be5SMarek Vasut for (i = 0; i < ARRAY_SIZE(isl7998x_std_res); i++) 55551ef2be5SMarek Vasut if (isl7998x_std_res[i].norm & norm) 55651ef2be5SMarek Vasut break; 55751ef2be5SMarek Vasut if (i == ARRAY_SIZE(isl7998x_std_res)) 55851ef2be5SMarek Vasut return ISL7998X_REG_PX_DEC_SDT_STANDARD_UNKNOWN; 55951ef2be5SMarek Vasut 56051ef2be5SMarek Vasut return isl7998x_std_res[i].id; 56151ef2be5SMarek Vasut } 56251ef2be5SMarek Vasut 56351ef2be5SMarek Vasut static const struct isl7998x_mode *isl7998x_norm_to_mode(v4l2_std_id norm) 56451ef2be5SMarek Vasut { 56551ef2be5SMarek Vasut unsigned int i; 56651ef2be5SMarek Vasut 56751ef2be5SMarek Vasut for (i = 0; i < ARRAY_SIZE(isl7998x_std_res); i++) 56851ef2be5SMarek Vasut if (isl7998x_std_res[i].norm & norm) 56951ef2be5SMarek Vasut break; 57051ef2be5SMarek Vasut /* Use NTSC default resolution during standard detection */ 57151ef2be5SMarek Vasut if (i == ARRAY_SIZE(isl7998x_std_res)) 57251ef2be5SMarek Vasut return &supported_modes[1]; 57351ef2be5SMarek Vasut 57451ef2be5SMarek Vasut return isl7998x_std_res[i].mode; 57551ef2be5SMarek Vasut } 57651ef2be5SMarek Vasut 57751ef2be5SMarek Vasut static int isl7998x_get_nr_inputs(struct device_node *of_node) 57851ef2be5SMarek Vasut { 57951ef2be5SMarek Vasut struct device_node *port; 58051ef2be5SMarek Vasut unsigned int inputs = 0; 58151ef2be5SMarek Vasut unsigned int i; 58251ef2be5SMarek Vasut 58351ef2be5SMarek Vasut if (of_graph_get_endpoint_count(of_node) > ISL7998X_NUM_PADS) 58451ef2be5SMarek Vasut return -EINVAL; 58551ef2be5SMarek Vasut 58651ef2be5SMarek Vasut /* 58751ef2be5SMarek Vasut * The driver does not provide means to remap the input ports. It 58851ef2be5SMarek Vasut * always configures input ports to start from VID1. Ensure that the 58951ef2be5SMarek Vasut * device tree is correct. 59051ef2be5SMarek Vasut */ 59151ef2be5SMarek Vasut for (i = ISL7998X_PAD_VIN1; i <= ISL7998X_PAD_VIN4; i++) { 59251ef2be5SMarek Vasut port = of_graph_get_port_by_id(of_node, i); 59351ef2be5SMarek Vasut if (!port) 59451ef2be5SMarek Vasut continue; 59551ef2be5SMarek Vasut 59651ef2be5SMarek Vasut inputs |= BIT(i); 59751ef2be5SMarek Vasut of_node_put(port); 59851ef2be5SMarek Vasut } 59951ef2be5SMarek Vasut 60051ef2be5SMarek Vasut switch (inputs) { 60151ef2be5SMarek Vasut case BIT(ISL7998X_PAD_VIN1): 60251ef2be5SMarek Vasut return 1; 60351ef2be5SMarek Vasut case BIT(ISL7998X_PAD_VIN1) | BIT(ISL7998X_PAD_VIN2): 60451ef2be5SMarek Vasut return 2; 60551ef2be5SMarek Vasut case BIT(ISL7998X_PAD_VIN1) | BIT(ISL7998X_PAD_VIN2) | 60651ef2be5SMarek Vasut BIT(ISL7998X_PAD_VIN3) | BIT(ISL7998X_PAD_VIN4): 60751ef2be5SMarek Vasut return 4; 60851ef2be5SMarek Vasut default: 60951ef2be5SMarek Vasut return -EINVAL; 61051ef2be5SMarek Vasut } 61151ef2be5SMarek Vasut } 61251ef2be5SMarek Vasut 61351ef2be5SMarek Vasut static int isl7998x_wait_power_on(struct isl7998x *isl7998x) 61451ef2be5SMarek Vasut { 61551ef2be5SMarek Vasut struct device *dev = isl7998x->subdev.dev; 61651ef2be5SMarek Vasut u32 chip_id; 61751ef2be5SMarek Vasut int ret; 61851ef2be5SMarek Vasut int err; 61951ef2be5SMarek Vasut 62051ef2be5SMarek Vasut ret = read_poll_timeout(regmap_read, err, !err, 2000, 20000, false, 62151ef2be5SMarek Vasut isl7998x->regmap, 62251ef2be5SMarek Vasut ISL7998X_REG_P0_PRODUCT_ID_CODE, &chip_id); 62351ef2be5SMarek Vasut if (ret) { 62451ef2be5SMarek Vasut dev_err(dev, "timeout while waiting for ISL7998X\n"); 62551ef2be5SMarek Vasut return ret; 62651ef2be5SMarek Vasut } 62751ef2be5SMarek Vasut 62851ef2be5SMarek Vasut dev_dbg(dev, "Found ISL799%x\n", chip_id); 62951ef2be5SMarek Vasut 63051ef2be5SMarek Vasut return ret; 63151ef2be5SMarek Vasut } 63251ef2be5SMarek Vasut 63351ef2be5SMarek Vasut static int isl7998x_set_standard(struct isl7998x *isl7998x, v4l2_std_id norm) 63451ef2be5SMarek Vasut { 63551ef2be5SMarek Vasut const struct isl7998x_mode *mode = isl7998x_norm_to_mode(norm); 63651ef2be5SMarek Vasut unsigned int val = isl7998x_norm_to_val(norm); 63751ef2be5SMarek Vasut unsigned int width = mode->width; 63851ef2be5SMarek Vasut unsigned int i; 63951ef2be5SMarek Vasut int ret; 64051ef2be5SMarek Vasut 64151ef2be5SMarek Vasut for (i = 0; i < ISL7998X_INPUTS; i++) { 64251ef2be5SMarek Vasut ret = regmap_write_bits(isl7998x->regmap, 64351ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT(i + 1), 64451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT_STANDARD, 64551ef2be5SMarek Vasut val); 64651ef2be5SMarek Vasut if (ret) 64751ef2be5SMarek Vasut return ret; 64851ef2be5SMarek Vasut } 64951ef2be5SMarek Vasut 65051ef2be5SMarek Vasut ret = regmap_write(isl7998x->regmap, 65151ef2be5SMarek Vasut ISL7998X_REG_P5_LI_ENGINE_LINE_CTL, 65251ef2be5SMarek Vasut 0x20 | ((width >> 7) & 0x1f)); 65351ef2be5SMarek Vasut if (ret) 65451ef2be5SMarek Vasut return ret; 65551ef2be5SMarek Vasut 65651ef2be5SMarek Vasut ret = regmap_write(isl7998x->regmap, 65751ef2be5SMarek Vasut ISL7998X_REG_P5_LI_ENGINE_PIC_WIDTH, 65851ef2be5SMarek Vasut (width << 1) & 0xff); 65951ef2be5SMarek Vasut if (ret) 66051ef2be5SMarek Vasut return ret; 66151ef2be5SMarek Vasut 66251ef2be5SMarek Vasut return 0; 66351ef2be5SMarek Vasut } 66451ef2be5SMarek Vasut 66551ef2be5SMarek Vasut static int isl7998x_init(struct isl7998x *isl7998x) 66651ef2be5SMarek Vasut { 66751ef2be5SMarek Vasut const unsigned int lanes = isl7998x->nr_mipi_lanes; 668*d59014e7SColin Ian King static const u32 isl7998x_video_in_chan_map[] = { 0x00, 0x11, 0x02, 0x02 }; 66951ef2be5SMarek Vasut const struct reg_sequence isl7998x_init_seq_custom[] = { 67051ef2be5SMarek Vasut { ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL, 67151ef2be5SMarek Vasut isl7998x_video_in_chan_map[isl7998x->nr_inputs - 1] }, 67251ef2be5SMarek Vasut { ISL7998X_REG_P0_CLK_CTL_4, 67351ef2be5SMarek Vasut (lanes == 1) ? 0x40 : 0x41 }, 67451ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_CTL, 67551ef2be5SMarek Vasut (lanes == 1) ? 0x01 : 0x02 }, 67651ef2be5SMarek Vasut }; 67751ef2be5SMarek Vasut struct device *dev = isl7998x->subdev.dev; 67851ef2be5SMarek Vasut struct regmap *regmap = isl7998x->regmap; 67951ef2be5SMarek Vasut int ret; 68051ef2be5SMarek Vasut 68151ef2be5SMarek Vasut dev_dbg(dev, "configuring %d lanes for %d inputs (norm %s)\n", 68251ef2be5SMarek Vasut isl7998x->nr_mipi_lanes, isl7998x->nr_inputs, 68351ef2be5SMarek Vasut v4l2_norm_to_name(isl7998x->norm)); 68451ef2be5SMarek Vasut 68551ef2be5SMarek Vasut ret = regmap_register_patch(regmap, isl7998x_init_seq_1, 68651ef2be5SMarek Vasut ARRAY_SIZE(isl7998x_init_seq_1)); 68751ef2be5SMarek Vasut if (ret) 68851ef2be5SMarek Vasut return ret; 68951ef2be5SMarek Vasut 69051ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 69151ef2be5SMarek Vasut ret = isl7998x_set_standard(isl7998x, isl7998x->norm); 69251ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 69351ef2be5SMarek Vasut if (ret) 69451ef2be5SMarek Vasut return ret; 69551ef2be5SMarek Vasut 69651ef2be5SMarek Vasut ret = regmap_register_patch(regmap, isl7998x_init_seq_custom, 69751ef2be5SMarek Vasut ARRAY_SIZE(isl7998x_init_seq_custom)); 69851ef2be5SMarek Vasut if (ret) 69951ef2be5SMarek Vasut return ret; 70051ef2be5SMarek Vasut 70151ef2be5SMarek Vasut return regmap_register_patch(regmap, isl7998x_init_seq_2, 70251ef2be5SMarek Vasut ARRAY_SIZE(isl7998x_init_seq_2)); 70351ef2be5SMarek Vasut } 70451ef2be5SMarek Vasut 70551ef2be5SMarek Vasut static int isl7998x_set_test_pattern(struct isl7998x *isl7998x) 70651ef2be5SMarek Vasut { 70751ef2be5SMarek Vasut const struct reg_sequence isl7998x_init_seq_tpg_off[] = { 70851ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 0 }, 70951ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_CTL_2, 0 } 71051ef2be5SMarek Vasut }; 71151ef2be5SMarek Vasut const struct reg_sequence isl7998x_init_seq_tpg_on[] = { 71251ef2be5SMarek Vasut { ISL7998X_REG_P5_TP_GEN_BAR_PATTERN, 71351ef2be5SMarek Vasut isl7998x->test_pattern_bars << 6 }, 71451ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_CTL_2, 71551ef2be5SMarek Vasut isl7998x->norm & V4L2_STD_PAL ? BIT(2) : 0 }, 71651ef2be5SMarek Vasut { ISL7998X_REG_P5_LI_ENGINE_TP_GEN_CTL, 71751ef2be5SMarek Vasut (isl7998x->test_pattern_chans << 4) | 71851ef2be5SMarek Vasut (isl7998x->test_pattern_color << 2) } 71951ef2be5SMarek Vasut }; 72051ef2be5SMarek Vasut struct device *dev = isl7998x->subdev.dev; 72151ef2be5SMarek Vasut struct regmap *regmap = isl7998x->regmap; 72251ef2be5SMarek Vasut int ret; 72351ef2be5SMarek Vasut 72451ef2be5SMarek Vasut if (pm_runtime_get_if_in_use(dev) <= 0) 72551ef2be5SMarek Vasut return 0; 72651ef2be5SMarek Vasut 72751ef2be5SMarek Vasut if (isl7998x->test_pattern != 0) { 72851ef2be5SMarek Vasut dev_dbg(dev, "enabling test pattern: channels 0x%x, %s, %s\n", 72951ef2be5SMarek Vasut isl7998x->test_pattern_chans, 73051ef2be5SMarek Vasut isl7998x_test_pattern_bars[isl7998x->test_pattern_bars], 73151ef2be5SMarek Vasut isl7998x_test_pattern_colors[isl7998x->test_pattern_color]); 73251ef2be5SMarek Vasut ret = regmap_register_patch(regmap, isl7998x_init_seq_tpg_on, 73351ef2be5SMarek Vasut ARRAY_SIZE(isl7998x_init_seq_tpg_on)); 73451ef2be5SMarek Vasut } else { 73551ef2be5SMarek Vasut ret = regmap_register_patch(regmap, isl7998x_init_seq_tpg_off, 73651ef2be5SMarek Vasut ARRAY_SIZE(isl7998x_init_seq_tpg_off)); 73751ef2be5SMarek Vasut } 73851ef2be5SMarek Vasut 73951ef2be5SMarek Vasut pm_runtime_put(dev); 74051ef2be5SMarek Vasut 74151ef2be5SMarek Vasut return ret; 74251ef2be5SMarek Vasut } 74351ef2be5SMarek Vasut 74451ef2be5SMarek Vasut #ifdef CONFIG_VIDEO_ADV_DEBUG 74551ef2be5SMarek Vasut static int isl7998x_g_register(struct v4l2_subdev *sd, 74651ef2be5SMarek Vasut struct v4l2_dbg_register *reg) 74751ef2be5SMarek Vasut { 74851ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 74951ef2be5SMarek Vasut int ret; 75051ef2be5SMarek Vasut u32 val; 75151ef2be5SMarek Vasut 75251ef2be5SMarek Vasut ret = regmap_read(isl7998x->regmap, reg->reg, &val); 75351ef2be5SMarek Vasut if (ret) 75451ef2be5SMarek Vasut return ret; 75551ef2be5SMarek Vasut 75651ef2be5SMarek Vasut reg->size = 1; 75751ef2be5SMarek Vasut reg->val = val; 75851ef2be5SMarek Vasut 75951ef2be5SMarek Vasut return 0; 76051ef2be5SMarek Vasut } 76151ef2be5SMarek Vasut 76251ef2be5SMarek Vasut static int isl7998x_s_register(struct v4l2_subdev *sd, 76351ef2be5SMarek Vasut const struct v4l2_dbg_register *reg) 76451ef2be5SMarek Vasut { 76551ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 76651ef2be5SMarek Vasut 76751ef2be5SMarek Vasut return regmap_write(isl7998x->regmap, reg->reg, reg->val); 76851ef2be5SMarek Vasut } 76951ef2be5SMarek Vasut #endif 77051ef2be5SMarek Vasut 77151ef2be5SMarek Vasut static int isl7998x_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm) 77251ef2be5SMarek Vasut { 77351ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 77451ef2be5SMarek Vasut 77551ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 77651ef2be5SMarek Vasut *norm = isl7998x->norm; 77751ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 77851ef2be5SMarek Vasut 77951ef2be5SMarek Vasut return 0; 78051ef2be5SMarek Vasut } 78151ef2be5SMarek Vasut 78251ef2be5SMarek Vasut static int isl7998x_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) 78351ef2be5SMarek Vasut { 78451ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 78551ef2be5SMarek Vasut struct i2c_client *client = v4l2_get_subdevdata(sd); 78651ef2be5SMarek Vasut struct device *dev = &client->dev; 78751ef2be5SMarek Vasut int ret = 0; 78851ef2be5SMarek Vasut 78951ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 79051ef2be5SMarek Vasut if (isl7998x->enabled) { 79151ef2be5SMarek Vasut ret = -EBUSY; 79251ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 79351ef2be5SMarek Vasut return ret; 79451ef2be5SMarek Vasut } 79551ef2be5SMarek Vasut isl7998x->norm = norm; 79651ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 79751ef2be5SMarek Vasut 79851ef2be5SMarek Vasut if (pm_runtime_get_if_in_use(dev) <= 0) 79951ef2be5SMarek Vasut return ret; 80051ef2be5SMarek Vasut 80151ef2be5SMarek Vasut ret = isl7998x_set_standard(isl7998x, norm); 80251ef2be5SMarek Vasut 80351ef2be5SMarek Vasut pm_runtime_put(dev); 80451ef2be5SMarek Vasut 80551ef2be5SMarek Vasut return ret; 80651ef2be5SMarek Vasut } 80751ef2be5SMarek Vasut 80851ef2be5SMarek Vasut static int isl7998x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std) 80951ef2be5SMarek Vasut { 81051ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 81151ef2be5SMarek Vasut struct i2c_client *client = v4l2_get_subdevdata(sd); 81251ef2be5SMarek Vasut struct device *dev = &client->dev; 81351ef2be5SMarek Vasut unsigned int std_id[ISL7998X_INPUTS]; 81451ef2be5SMarek Vasut unsigned int i; 81551ef2be5SMarek Vasut int ret; 81651ef2be5SMarek Vasut u32 reg; 81751ef2be5SMarek Vasut 81851ef2be5SMarek Vasut ret = pm_runtime_resume_and_get(dev); 81951ef2be5SMarek Vasut if (ret) 82051ef2be5SMarek Vasut return ret; 82151ef2be5SMarek Vasut 82251ef2be5SMarek Vasut dev_dbg(dev, "starting video standard detection\n"); 82351ef2be5SMarek Vasut 82451ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 82551ef2be5SMarek Vasut if (isl7998x->enabled) { 82651ef2be5SMarek Vasut ret = -EBUSY; 82751ef2be5SMarek Vasut goto out_unlock; 82851ef2be5SMarek Vasut } 82951ef2be5SMarek Vasut 83051ef2be5SMarek Vasut ret = isl7998x_set_standard(isl7998x, V4L2_STD_UNKNOWN); 83151ef2be5SMarek Vasut if (ret) 83251ef2be5SMarek Vasut goto out_unlock; 83351ef2be5SMarek Vasut 83451ef2be5SMarek Vasut for (i = 0; i < ISL7998X_INPUTS; i++) { 83551ef2be5SMarek Vasut ret = regmap_write(isl7998x->regmap, 83651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDTR(i + 1), 83751ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDTR_ATSTART); 83851ef2be5SMarek Vasut if (ret) 83951ef2be5SMarek Vasut goto out_reset_std; 84051ef2be5SMarek Vasut } 84151ef2be5SMarek Vasut 84251ef2be5SMarek Vasut for (i = 0; i < ISL7998X_INPUTS; i++) { 84351ef2be5SMarek Vasut ret = regmap_read_poll_timeout(isl7998x->regmap, 84451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT(i + 1), 84551ef2be5SMarek Vasut reg, 84651ef2be5SMarek Vasut !(reg & ISL7998X_REG_PX_DEC_SDT_DET), 84751ef2be5SMarek Vasut 2000, 500 * USEC_PER_MSEC); 84851ef2be5SMarek Vasut if (ret) 84951ef2be5SMarek Vasut goto out_reset_std; 85051ef2be5SMarek Vasut std_id[i] = FIELD_GET(ISL7998X_REG_PX_DEC_SDT_NOW, reg); 85151ef2be5SMarek Vasut } 85251ef2be5SMarek Vasut 85351ef2be5SMarek Vasut /* 85451ef2be5SMarek Vasut * According to Renesas FAE, all input cameras must have the 85551ef2be5SMarek Vasut * same standard on this chip. 85651ef2be5SMarek Vasut */ 85751ef2be5SMarek Vasut for (i = 0; i < isl7998x->nr_inputs; i++) { 85851ef2be5SMarek Vasut dev_dbg(dev, "input %d: detected %s\n", 85951ef2be5SMarek Vasut i, v4l2_norm_to_name(isl7998x_std_res[std_id[i]].norm)); 86051ef2be5SMarek Vasut if (std_id[0] != std_id[i]) 86151ef2be5SMarek Vasut dev_warn(dev, 86251ef2be5SMarek Vasut "incompatible standards: %s on input %d (expected %s)\n", 86351ef2be5SMarek Vasut v4l2_norm_to_name(isl7998x_std_res[std_id[i]].norm), i, 86451ef2be5SMarek Vasut v4l2_norm_to_name(isl7998x_std_res[std_id[0]].norm)); 86551ef2be5SMarek Vasut } 86651ef2be5SMarek Vasut 86751ef2be5SMarek Vasut *std = isl7998x_std_res[std_id[0]].norm; 86851ef2be5SMarek Vasut 86951ef2be5SMarek Vasut out_reset_std: 87051ef2be5SMarek Vasut isl7998x_set_standard(isl7998x, isl7998x->norm); 87151ef2be5SMarek Vasut out_unlock: 87251ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 87351ef2be5SMarek Vasut pm_runtime_put(dev); 87451ef2be5SMarek Vasut 87551ef2be5SMarek Vasut return ret; 87651ef2be5SMarek Vasut } 87751ef2be5SMarek Vasut 87851ef2be5SMarek Vasut static int isl7998x_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *std) 87951ef2be5SMarek Vasut { 88051ef2be5SMarek Vasut *std = V4L2_STD_ALL; 88151ef2be5SMarek Vasut 88251ef2be5SMarek Vasut return 0; 88351ef2be5SMarek Vasut } 88451ef2be5SMarek Vasut 88551ef2be5SMarek Vasut static int isl7998x_g_input_status(struct v4l2_subdev *sd, u32 *status) 88651ef2be5SMarek Vasut { 88751ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 88851ef2be5SMarek Vasut struct i2c_client *client = v4l2_get_subdevdata(sd); 88951ef2be5SMarek Vasut struct device *dev = &client->dev; 89051ef2be5SMarek Vasut unsigned int i; 89151ef2be5SMarek Vasut int ret = 0; 89251ef2be5SMarek Vasut u32 reg; 89351ef2be5SMarek Vasut 89451ef2be5SMarek Vasut if (!pm_runtime_active(dev)) { 89551ef2be5SMarek Vasut *status |= V4L2_IN_ST_NO_POWER; 89651ef2be5SMarek Vasut return 0; 89751ef2be5SMarek Vasut } 89851ef2be5SMarek Vasut 89951ef2be5SMarek Vasut for (i = 0; i < isl7998x->nr_inputs; i++) { 90051ef2be5SMarek Vasut ret = regmap_read(isl7998x->regmap, 90151ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_STATUS_1(i + 1), ®); 90251ef2be5SMarek Vasut if (!ret) { 90351ef2be5SMarek Vasut if (reg & ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS) 90451ef2be5SMarek Vasut *status |= V4L2_IN_ST_NO_SIGNAL; 90551ef2be5SMarek Vasut if (!(reg & ISL7998X_REG_PX_DEC_STATUS_1_HLOCK)) 90651ef2be5SMarek Vasut *status |= V4L2_IN_ST_NO_H_LOCK; 90751ef2be5SMarek Vasut if (!(reg & ISL7998X_REG_PX_DEC_STATUS_1_VLOCK)) 90851ef2be5SMarek Vasut *status |= V4L2_IN_ST_NO_V_LOCK; 90951ef2be5SMarek Vasut } 91051ef2be5SMarek Vasut } 91151ef2be5SMarek Vasut 91251ef2be5SMarek Vasut return ret; 91351ef2be5SMarek Vasut } 91451ef2be5SMarek Vasut 91551ef2be5SMarek Vasut static int isl7998x_s_stream(struct v4l2_subdev *sd, int enable) 91651ef2be5SMarek Vasut { 91751ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 91851ef2be5SMarek Vasut struct i2c_client *client = v4l2_get_subdevdata(sd); 91951ef2be5SMarek Vasut struct device *dev = &client->dev; 92051ef2be5SMarek Vasut int ret = 0; 92151ef2be5SMarek Vasut u32 reg; 92251ef2be5SMarek Vasut 92351ef2be5SMarek Vasut dev_dbg(dev, "stream %s\n", enable ? "ON" : "OFF"); 92451ef2be5SMarek Vasut 92551ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 92651ef2be5SMarek Vasut if (isl7998x->enabled == enable) 92751ef2be5SMarek Vasut goto out; 92851ef2be5SMarek Vasut isl7998x->enabled = enable; 92951ef2be5SMarek Vasut 93051ef2be5SMarek Vasut if (enable) { 93151ef2be5SMarek Vasut ret = isl7998x_set_test_pattern(isl7998x); 93251ef2be5SMarek Vasut if (ret) 93351ef2be5SMarek Vasut goto out; 93451ef2be5SMarek Vasut } 93551ef2be5SMarek Vasut 93651ef2be5SMarek Vasut regmap_read(isl7998x->regmap, 93751ef2be5SMarek Vasut ISL7998X_REG_P5_LI_ENGINE_CTL, ®); 93851ef2be5SMarek Vasut if (enable) 93951ef2be5SMarek Vasut reg &= ~BIT(7); 94051ef2be5SMarek Vasut else 94151ef2be5SMarek Vasut reg |= BIT(7); 94251ef2be5SMarek Vasut ret = regmap_write(isl7998x->regmap, 94351ef2be5SMarek Vasut ISL7998X_REG_P5_LI_ENGINE_CTL, reg); 94451ef2be5SMarek Vasut 94551ef2be5SMarek Vasut out: 94651ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 94751ef2be5SMarek Vasut 94851ef2be5SMarek Vasut return ret; 94951ef2be5SMarek Vasut } 95051ef2be5SMarek Vasut 95151ef2be5SMarek Vasut static int isl7998x_pre_streamon(struct v4l2_subdev *sd, u32 flags) 95251ef2be5SMarek Vasut { 95351ef2be5SMarek Vasut struct i2c_client *client = v4l2_get_subdevdata(sd); 95451ef2be5SMarek Vasut struct device *dev = &client->dev; 95551ef2be5SMarek Vasut 95651ef2be5SMarek Vasut return pm_runtime_resume_and_get(dev); 95751ef2be5SMarek Vasut } 95851ef2be5SMarek Vasut 95951ef2be5SMarek Vasut static int isl7998x_post_streamoff(struct v4l2_subdev *sd) 96051ef2be5SMarek Vasut { 96151ef2be5SMarek Vasut struct i2c_client *client = v4l2_get_subdevdata(sd); 96251ef2be5SMarek Vasut struct device *dev = &client->dev; 96351ef2be5SMarek Vasut 96451ef2be5SMarek Vasut pm_runtime_put(dev); 96551ef2be5SMarek Vasut 96651ef2be5SMarek Vasut return 0; 96751ef2be5SMarek Vasut } 96851ef2be5SMarek Vasut 96951ef2be5SMarek Vasut static int isl7998x_enum_mbus_code(struct v4l2_subdev *sd, 97051ef2be5SMarek Vasut struct v4l2_subdev_state *sd_state, 97151ef2be5SMarek Vasut struct v4l2_subdev_mbus_code_enum *code) 97251ef2be5SMarek Vasut { 97351ef2be5SMarek Vasut if (code->index >= ARRAY_SIZE(isl7998x_colour_fmts)) 97451ef2be5SMarek Vasut return -EINVAL; 97551ef2be5SMarek Vasut 97651ef2be5SMarek Vasut code->code = isl7998x_colour_fmts[code->index].code; 97751ef2be5SMarek Vasut 97851ef2be5SMarek Vasut return 0; 97951ef2be5SMarek Vasut } 98051ef2be5SMarek Vasut 98151ef2be5SMarek Vasut static int isl7998x_enum_frame_size(struct v4l2_subdev *sd, 98251ef2be5SMarek Vasut struct v4l2_subdev_state *sd_state, 98351ef2be5SMarek Vasut struct v4l2_subdev_frame_size_enum *fse) 98451ef2be5SMarek Vasut { 98551ef2be5SMarek Vasut if (fse->index >= ARRAY_SIZE(supported_modes)) 98651ef2be5SMarek Vasut return -EINVAL; 98751ef2be5SMarek Vasut 98851ef2be5SMarek Vasut if (fse->code != isl7998x_colour_fmts[0].code) 98951ef2be5SMarek Vasut return -EINVAL; 99051ef2be5SMarek Vasut 99151ef2be5SMarek Vasut fse->min_width = supported_modes[fse->index].width; 99251ef2be5SMarek Vasut fse->max_width = fse->min_width; 99351ef2be5SMarek Vasut fse->min_height = supported_modes[fse->index].height; 99451ef2be5SMarek Vasut fse->max_height = fse->min_height; 99551ef2be5SMarek Vasut 99651ef2be5SMarek Vasut return 0; 99751ef2be5SMarek Vasut } 99851ef2be5SMarek Vasut 99951ef2be5SMarek Vasut static int isl7998x_get_fmt(struct v4l2_subdev *sd, 100051ef2be5SMarek Vasut struct v4l2_subdev_state *sd_state, 100151ef2be5SMarek Vasut struct v4l2_subdev_format *format) 100251ef2be5SMarek Vasut { 100351ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 100451ef2be5SMarek Vasut struct v4l2_mbus_framefmt *mf = &format->format; 100551ef2be5SMarek Vasut const struct isl7998x_mode *mode; 100651ef2be5SMarek Vasut 100751ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 100851ef2be5SMarek Vasut 100951ef2be5SMarek Vasut if (format->which == V4L2_SUBDEV_FORMAT_TRY) { 101051ef2be5SMarek Vasut format->format = *v4l2_subdev_get_try_format(sd, sd_state, 101151ef2be5SMarek Vasut format->pad); 101251ef2be5SMarek Vasut goto out; 101351ef2be5SMarek Vasut } 101451ef2be5SMarek Vasut 101551ef2be5SMarek Vasut mode = isl7998x_norm_to_mode(isl7998x->norm); 101651ef2be5SMarek Vasut 101751ef2be5SMarek Vasut mf->width = mode->width; 101851ef2be5SMarek Vasut mf->height = mode->height; 101951ef2be5SMarek Vasut mf->code = isl7998x->fmt->code; 102051ef2be5SMarek Vasut mf->field = mode->field; 102151ef2be5SMarek Vasut mf->colorspace = 0; 102251ef2be5SMarek Vasut 102351ef2be5SMarek Vasut out: 102451ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 102551ef2be5SMarek Vasut 102651ef2be5SMarek Vasut return 0; 102751ef2be5SMarek Vasut } 102851ef2be5SMarek Vasut 102951ef2be5SMarek Vasut static int isl7998x_set_fmt(struct v4l2_subdev *sd, 103051ef2be5SMarek Vasut struct v4l2_subdev_state *sd_state, 103151ef2be5SMarek Vasut struct v4l2_subdev_format *format) 103251ef2be5SMarek Vasut { 103351ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 103451ef2be5SMarek Vasut struct v4l2_mbus_framefmt *mf = &format->format; 103551ef2be5SMarek Vasut const struct isl7998x_mode *mode; 103651ef2be5SMarek Vasut 103751ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 103851ef2be5SMarek Vasut 103951ef2be5SMarek Vasut mode = isl7998x_norm_to_mode(isl7998x->norm); 104051ef2be5SMarek Vasut 104151ef2be5SMarek Vasut mf->width = mode->width; 104251ef2be5SMarek Vasut mf->height = mode->height; 104351ef2be5SMarek Vasut mf->code = isl7998x->fmt->code; 104451ef2be5SMarek Vasut mf->field = mode->field; 104551ef2be5SMarek Vasut 104651ef2be5SMarek Vasut if (format->which == V4L2_SUBDEV_FORMAT_TRY) 104751ef2be5SMarek Vasut *v4l2_subdev_get_try_format(sd, sd_state, format->pad) = format->format; 104851ef2be5SMarek Vasut 104951ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 105051ef2be5SMarek Vasut 105151ef2be5SMarek Vasut return 0; 105251ef2be5SMarek Vasut } 105351ef2be5SMarek Vasut 105451ef2be5SMarek Vasut static int isl7998x_set_ctrl(struct v4l2_ctrl *ctrl) 105551ef2be5SMarek Vasut { 105651ef2be5SMarek Vasut struct isl7998x *isl7998x = container_of(ctrl->handler, 105751ef2be5SMarek Vasut struct isl7998x, ctrl_handler); 105851ef2be5SMarek Vasut int ret = 0; 105951ef2be5SMarek Vasut 106051ef2be5SMarek Vasut switch (ctrl->id) { 106151ef2be5SMarek Vasut case V4L2_CID_TEST_PATTERN_BARS: 106251ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 106351ef2be5SMarek Vasut isl7998x->test_pattern_bars = ctrl->val & 0x3; 106451ef2be5SMarek Vasut ret = isl7998x_set_test_pattern(isl7998x); 106551ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 106651ef2be5SMarek Vasut break; 106751ef2be5SMarek Vasut case V4L2_CID_TEST_PATTERN_CHANNELS: 106851ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 106951ef2be5SMarek Vasut isl7998x->test_pattern_chans = ctrl->val & 0xf; 107051ef2be5SMarek Vasut ret = isl7998x_set_test_pattern(isl7998x); 107151ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 107251ef2be5SMarek Vasut break; 107351ef2be5SMarek Vasut case V4L2_CID_TEST_PATTERN_COLOR: 107451ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 107551ef2be5SMarek Vasut isl7998x->test_pattern_color = ctrl->val & 0x3; 107651ef2be5SMarek Vasut ret = isl7998x_set_test_pattern(isl7998x); 107751ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 107851ef2be5SMarek Vasut break; 107951ef2be5SMarek Vasut case V4L2_CID_TEST_PATTERN: 108051ef2be5SMarek Vasut mutex_lock(&isl7998x->lock); 108151ef2be5SMarek Vasut isl7998x->test_pattern = ctrl->val; 108251ef2be5SMarek Vasut ret = isl7998x_set_test_pattern(isl7998x); 108351ef2be5SMarek Vasut mutex_unlock(&isl7998x->lock); 108451ef2be5SMarek Vasut break; 108551ef2be5SMarek Vasut } 108651ef2be5SMarek Vasut 108751ef2be5SMarek Vasut return ret; 108851ef2be5SMarek Vasut } 108951ef2be5SMarek Vasut 109051ef2be5SMarek Vasut static const struct v4l2_subdev_core_ops isl7998x_subdev_core_ops = { 109151ef2be5SMarek Vasut #ifdef CONFIG_VIDEO_ADV_DEBUG 109251ef2be5SMarek Vasut .g_register = isl7998x_g_register, 109351ef2be5SMarek Vasut .s_register = isl7998x_s_register, 109451ef2be5SMarek Vasut #endif 109551ef2be5SMarek Vasut }; 109651ef2be5SMarek Vasut 109751ef2be5SMarek Vasut static const struct v4l2_subdev_video_ops isl7998x_subdev_video_ops = { 109851ef2be5SMarek Vasut .g_std = isl7998x_g_std, 109951ef2be5SMarek Vasut .s_std = isl7998x_s_std, 110051ef2be5SMarek Vasut .querystd = isl7998x_querystd, 110151ef2be5SMarek Vasut .g_tvnorms = isl7998x_g_tvnorms, 110251ef2be5SMarek Vasut .g_input_status = isl7998x_g_input_status, 110351ef2be5SMarek Vasut .s_stream = isl7998x_s_stream, 110451ef2be5SMarek Vasut .pre_streamon = isl7998x_pre_streamon, 110551ef2be5SMarek Vasut .post_streamoff = isl7998x_post_streamoff, 110651ef2be5SMarek Vasut }; 110751ef2be5SMarek Vasut 110851ef2be5SMarek Vasut static const struct v4l2_subdev_pad_ops isl7998x_subdev_pad_ops = { 110951ef2be5SMarek Vasut .enum_mbus_code = isl7998x_enum_mbus_code, 111051ef2be5SMarek Vasut .enum_frame_size = isl7998x_enum_frame_size, 111151ef2be5SMarek Vasut .get_fmt = isl7998x_get_fmt, 111251ef2be5SMarek Vasut .set_fmt = isl7998x_set_fmt, 111351ef2be5SMarek Vasut }; 111451ef2be5SMarek Vasut 111551ef2be5SMarek Vasut static const struct v4l2_subdev_ops isl7998x_subdev_ops = { 111651ef2be5SMarek Vasut .core = &isl7998x_subdev_core_ops, 111751ef2be5SMarek Vasut .video = &isl7998x_subdev_video_ops, 111851ef2be5SMarek Vasut .pad = &isl7998x_subdev_pad_ops, 111951ef2be5SMarek Vasut }; 112051ef2be5SMarek Vasut 112151ef2be5SMarek Vasut static const struct media_entity_operations isl7998x_entity_ops = { 112251ef2be5SMarek Vasut .link_validate = v4l2_subdev_link_validate, 112351ef2be5SMarek Vasut }; 112451ef2be5SMarek Vasut 112551ef2be5SMarek Vasut static const struct v4l2_ctrl_ops isl7998x_ctrl_ops = { 112651ef2be5SMarek Vasut .s_ctrl = isl7998x_set_ctrl, 112751ef2be5SMarek Vasut }; 112851ef2be5SMarek Vasut 112951ef2be5SMarek Vasut static const struct v4l2_ctrl_config isl7998x_ctrls[] = { 113051ef2be5SMarek Vasut { 113151ef2be5SMarek Vasut .ops = &isl7998x_ctrl_ops, 113251ef2be5SMarek Vasut .id = V4L2_CID_TEST_PATTERN_BARS, 113351ef2be5SMarek Vasut .type = V4L2_CTRL_TYPE_MENU, 113451ef2be5SMarek Vasut .name = "Test Pattern Bars", 113551ef2be5SMarek Vasut .max = ARRAY_SIZE(isl7998x_test_pattern_bars) - 1, 113651ef2be5SMarek Vasut .def = 0, 113751ef2be5SMarek Vasut .qmenu = isl7998x_test_pattern_bars, 113851ef2be5SMarek Vasut }, { 113951ef2be5SMarek Vasut .ops = &isl7998x_ctrl_ops, 114051ef2be5SMarek Vasut .id = V4L2_CID_TEST_PATTERN_CHANNELS, 114151ef2be5SMarek Vasut .type = V4L2_CTRL_TYPE_INTEGER, 114251ef2be5SMarek Vasut .name = "Test Pattern Channels", 114351ef2be5SMarek Vasut .min = 0, 114451ef2be5SMarek Vasut .max = 0xf, 114551ef2be5SMarek Vasut .step = 1, 114651ef2be5SMarek Vasut .def = 0xf, 114751ef2be5SMarek Vasut .flags = 0, 114851ef2be5SMarek Vasut }, { 114951ef2be5SMarek Vasut .ops = &isl7998x_ctrl_ops, 115051ef2be5SMarek Vasut .id = V4L2_CID_TEST_PATTERN_COLOR, 115151ef2be5SMarek Vasut .type = V4L2_CTRL_TYPE_MENU, 115251ef2be5SMarek Vasut .name = "Test Pattern Color", 115351ef2be5SMarek Vasut .max = ARRAY_SIZE(isl7998x_test_pattern_colors) - 1, 115451ef2be5SMarek Vasut .def = 0, 115551ef2be5SMarek Vasut .qmenu = isl7998x_test_pattern_colors, 115651ef2be5SMarek Vasut }, 115751ef2be5SMarek Vasut }; 115851ef2be5SMarek Vasut 115951ef2be5SMarek Vasut #define ISL7998X_REG_DECODER_ACA_READABLE_RANGE(page) \ 116051ef2be5SMarek Vasut /* Decoder range */ \ 116151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_INPUT_FMT(page), \ 116251ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page)), \ 116351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_ANCTL(page), \ 116451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_CSC_CTL(page)), \ 116551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_BRIGHT(page), \ 116651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_HUE(page)), \ 116751ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_VERT_PEAK(page), \ 116851ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_CORING(page)), \ 116951ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page), \ 117051ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDTR(page)), \ 117151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_CLMPG(page), \ 117251ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_DATA_CONV(page)), \ 117351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_INTERNAL_TEST(page), \ 117451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_INTERNAL_TEST(page)), \ 117551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_H_DELAY_CTL(page), \ 117651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(page)), \ 117751ef2be5SMarek Vasut /* ACA range */ \ 117851ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_1(page), \ 117951ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(page)), \ 118051ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_Y_AVG(page), \ 118151ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_CTL_4(page)), \ 118251ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(page), \ 118351ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page)), \ 118451ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(page), \ 118551ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_PAGE(page)) 118651ef2be5SMarek Vasut 118751ef2be5SMarek Vasut #define ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(page) \ 118851ef2be5SMarek Vasut /* Decoder range */ \ 118951ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_INPUT_FMT(page), \ 119051ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_INPUT_FMT(page)), \ 119151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page), \ 119251ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_HS_DELAY_CTL(page)), \ 119351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_ANCTL(page), \ 119451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_CSC_CTL(page)), \ 119551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_BRIGHT(page), \ 119651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_HUE(page)), \ 119751ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_VERT_PEAK(page), \ 119851ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_CORING(page)), \ 119951ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page), \ 120051ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDTR(page)), \ 120151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_CLMPG(page), \ 120251ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_MISC3(page)), \ 120351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_CLMD(page), \ 120451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_DATA_CONV(page)), \ 120551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_INTERNAL_TEST(page), \ 120651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_INTERNAL_TEST(page)), \ 120751ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_H_DELAY_CTL(page), \ 120851ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_H_DELAY_II_LOW(page)), \ 120951ef2be5SMarek Vasut /* ACA range */ \ 121051ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_1(page), \ 121151ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_HIST_WIN_V_SZ2(page)), \ 121251ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_CTL_2(page), \ 121351ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_CTL_4(page)), \ 121451ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_FLEX_WIN_HIST(page), \ 121551ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_HIST_DATA_LO(page)), \ 121651ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page), \ 121751ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_XFER_HIST_HOST(page)), \ 121851ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(page), \ 121951ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_PAGE(page)) 122051ef2be5SMarek Vasut 122151ef2be5SMarek Vasut #define ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(page) \ 122251ef2be5SMarek Vasut /* Decoder range */ \ 122351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_STATUS_1(page), \ 122451ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_STATUS_1(page)), \ 122551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_SDT(page), \ 122651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_SDT(page)), \ 122751ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_MVSN(page), \ 122851ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_HFREF(page)), \ 122951ef2be5SMarek Vasut /* ACA range */ \ 123051ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_Y_AVG(page), \ 123151ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_Y_HIGH(page)), \ 123251ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_ACA_HIST_DATA_LO(page), \ 123351ef2be5SMarek Vasut ISL7998X_REG_PX_ACA_FLEX_WIN_CR_CLR(page)) 123451ef2be5SMarek Vasut 123551ef2be5SMarek Vasut static const struct regmap_range isl7998x_readable_ranges[] = { 123651ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_PRODUCT_ID_CODE, 123751ef2be5SMarek Vasut ISL7998X_REG_P0_IRQ_SYNC_CTL), 123851ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_INTERRUPT_STATUS, 123951ef2be5SMarek Vasut ISL7998X_REG_P0_CLOCK_DELAY), 124051ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(0), 124151ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_PAGE(0)), 124251ef2be5SMarek Vasut 124351ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_READABLE_RANGE(1), 124451ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_READABLE_RANGE(2), 124551ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_READABLE_RANGE(3), 124651ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_READABLE_RANGE(4), 124751ef2be5SMarek Vasut 124851ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_LI_ENGINE_CTL, 124951ef2be5SMarek Vasut ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL), 125051ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_FIFO_THRSH_CNT_1, 125151ef2be5SMarek Vasut ISL7998X_REG_P5_PLL_ANA), 125251ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 125351ef2be5SMarek Vasut ISL7998X_REG_P5_HIST_LINE_CNT_2), 125451ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(5), 125551ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_PAGE(5)), 125651ef2be5SMarek Vasut }; 125751ef2be5SMarek Vasut 125851ef2be5SMarek Vasut static const struct regmap_range isl7998x_writeable_ranges[] = { 125951ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_SW_RESET_CTL, 126051ef2be5SMarek Vasut ISL7998X_REG_P0_IRQ_SYNC_CTL), 126151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_CHAN_1_IRQ, 126251ef2be5SMarek Vasut ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN), 126351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_CLOCK_DELAY, 126451ef2be5SMarek Vasut ISL7998X_REG_P0_CLOCK_DELAY), 126551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(0), 126651ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_PAGE(0)), 126751ef2be5SMarek Vasut 126851ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(1), 126951ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(2), 127051ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(3), 127151ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(4), 127251ef2be5SMarek Vasut 127351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_LI_ENGINE_CTL, 127451ef2be5SMarek Vasut ISL7998X_REG_P5_ESC_MODE_TIME_CTL), 127551ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_MIPI_SP_HS_TRL_CTL, 127651ef2be5SMarek Vasut ISL7998X_REG_P5_PLL_ANA), 127751ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_TOTAL_PF_LINE_CNT_1, 127851ef2be5SMarek Vasut ISL7998X_REG_P5_HIST_LINE_CNT_2), 127951ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_PX_DEC_PAGE(5), 128051ef2be5SMarek Vasut ISL7998X_REG_PX_DEC_PAGE(5)), 128151ef2be5SMarek Vasut 128251ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_WRITEABLE_RANGE(0xf), 128351ef2be5SMarek Vasut }; 128451ef2be5SMarek Vasut 128551ef2be5SMarek Vasut static const struct regmap_range isl7998x_volatile_ranges[] = { 128651ef2be5SMarek Vasut /* Product id code register is used to check availability */ 128751ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_PRODUCT_ID_CODE, 128851ef2be5SMarek Vasut ISL7998X_REG_P0_PRODUCT_ID_CODE), 128951ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_MPP1_SYNC_CTL, 129051ef2be5SMarek Vasut ISL7998X_REG_P0_IRQ_SYNC_CTL), 129151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_INTERRUPT_STATUS, 129251ef2be5SMarek Vasut ISL7998X_REG_P0_INTERRUPT_STATUS), 129351ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P0_CHAN_1_STATUS, 129451ef2be5SMarek Vasut ISL7998X_REG_P0_SHORT_DIAG_STATUS), 129551ef2be5SMarek Vasut 129651ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(1), 129751ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(2), 129851ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(3), 129951ef2be5SMarek Vasut ISL7998X_REG_DECODER_ACA_VOLATILE_RANGE(4), 130051ef2be5SMarek Vasut 130151ef2be5SMarek Vasut regmap_reg_range(ISL7998X_REG_P5_AUTO_TEST_ERR_DET, 130251ef2be5SMarek Vasut ISL7998X_REG_P5_PIC_HEIGHT_LOW), 130351ef2be5SMarek Vasut }; 130451ef2be5SMarek Vasut 130551ef2be5SMarek Vasut static const struct regmap_access_table isl7998x_readable_table = { 130651ef2be5SMarek Vasut .yes_ranges = isl7998x_readable_ranges, 130751ef2be5SMarek Vasut .n_yes_ranges = ARRAY_SIZE(isl7998x_readable_ranges), 130851ef2be5SMarek Vasut }; 130951ef2be5SMarek Vasut 131051ef2be5SMarek Vasut static const struct regmap_access_table isl7998x_writeable_table = { 131151ef2be5SMarek Vasut .yes_ranges = isl7998x_writeable_ranges, 131251ef2be5SMarek Vasut .n_yes_ranges = ARRAY_SIZE(isl7998x_writeable_ranges), 131351ef2be5SMarek Vasut }; 131451ef2be5SMarek Vasut 131551ef2be5SMarek Vasut static const struct regmap_access_table isl7998x_volatile_table = { 131651ef2be5SMarek Vasut .yes_ranges = isl7998x_volatile_ranges, 131751ef2be5SMarek Vasut .n_yes_ranges = ARRAY_SIZE(isl7998x_volatile_ranges), 131851ef2be5SMarek Vasut }; 131951ef2be5SMarek Vasut 132051ef2be5SMarek Vasut static const struct regmap_range_cfg isl7998x_ranges[] = { 132151ef2be5SMarek Vasut { 132251ef2be5SMarek Vasut .range_min = ISL7998X_REG_PN_BASE(0), 132351ef2be5SMarek Vasut .range_max = ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 132451ef2be5SMarek Vasut .selector_reg = ISL7998X_REG_PX_DEC_PAGE(0), 132551ef2be5SMarek Vasut .selector_mask = ISL7998X_REG_PX_DEC_PAGE_MASK, 132651ef2be5SMarek Vasut .window_start = 0, 132751ef2be5SMarek Vasut .window_len = 256, 132851ef2be5SMarek Vasut } 132951ef2be5SMarek Vasut }; 133051ef2be5SMarek Vasut 133151ef2be5SMarek Vasut static const struct regmap_config isl7998x_regmap = { 133251ef2be5SMarek Vasut .reg_bits = 8, 133351ef2be5SMarek Vasut .val_bits = 8, 133451ef2be5SMarek Vasut .max_register = ISL7998X_REG_PX_ACA_XFER_HIST_HOST(0xf), 133551ef2be5SMarek Vasut .ranges = isl7998x_ranges, 133651ef2be5SMarek Vasut .num_ranges = ARRAY_SIZE(isl7998x_ranges), 133751ef2be5SMarek Vasut .rd_table = &isl7998x_readable_table, 133851ef2be5SMarek Vasut .wr_table = &isl7998x_writeable_table, 133951ef2be5SMarek Vasut .volatile_table = &isl7998x_volatile_table, 134051ef2be5SMarek Vasut .cache_type = REGCACHE_RBTREE, 134151ef2be5SMarek Vasut }; 134251ef2be5SMarek Vasut 134351ef2be5SMarek Vasut static int isl7998x_mc_init(struct isl7998x *isl7998x) 134451ef2be5SMarek Vasut { 134551ef2be5SMarek Vasut unsigned int i; 134651ef2be5SMarek Vasut 134751ef2be5SMarek Vasut isl7998x->subdev.entity.ops = &isl7998x_entity_ops; 134851ef2be5SMarek Vasut isl7998x->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 134951ef2be5SMarek Vasut 135051ef2be5SMarek Vasut isl7998x->pads[ISL7998X_PAD_OUT].flags = MEDIA_PAD_FL_SOURCE; 135151ef2be5SMarek Vasut for (i = ISL7998X_PAD_VIN1; i < ISL7998X_NUM_PADS; i++) 135251ef2be5SMarek Vasut isl7998x->pads[i].flags = MEDIA_PAD_FL_SINK; 135351ef2be5SMarek Vasut 135451ef2be5SMarek Vasut return media_entity_pads_init(&isl7998x->subdev.entity, 135551ef2be5SMarek Vasut ISL7998X_NUM_PADS, 135651ef2be5SMarek Vasut isl7998x->pads); 135751ef2be5SMarek Vasut } 135851ef2be5SMarek Vasut 135951ef2be5SMarek Vasut static int get_link_freq_menu_index(unsigned int lanes, 136051ef2be5SMarek Vasut unsigned int inputs) 136151ef2be5SMarek Vasut { 136251ef2be5SMarek Vasut int ret = -EINVAL; 136351ef2be5SMarek Vasut 136451ef2be5SMarek Vasut switch (lanes) { 136551ef2be5SMarek Vasut case 1: 136651ef2be5SMarek Vasut if (inputs == 1) 136751ef2be5SMarek Vasut ret = 0; 136851ef2be5SMarek Vasut if (inputs == 2) 136951ef2be5SMarek Vasut ret = 1; 137051ef2be5SMarek Vasut if (inputs == 4) 137151ef2be5SMarek Vasut ret = 2; 137251ef2be5SMarek Vasut break; 137351ef2be5SMarek Vasut case 2: 137451ef2be5SMarek Vasut if (inputs == 2) 137551ef2be5SMarek Vasut ret = 0; 137651ef2be5SMarek Vasut if (inputs == 4) 137751ef2be5SMarek Vasut ret = 1; 137851ef2be5SMarek Vasut break; 137951ef2be5SMarek Vasut default: 138051ef2be5SMarek Vasut break; 138151ef2be5SMarek Vasut } 138251ef2be5SMarek Vasut 138351ef2be5SMarek Vasut return ret; 138451ef2be5SMarek Vasut } 138551ef2be5SMarek Vasut 138651ef2be5SMarek Vasut static void isl7998x_remove_controls(struct isl7998x *isl7998x) 138751ef2be5SMarek Vasut { 138851ef2be5SMarek Vasut v4l2_ctrl_handler_free(&isl7998x->ctrl_handler); 138951ef2be5SMarek Vasut mutex_destroy(&isl7998x->ctrl_mutex); 139051ef2be5SMarek Vasut } 139151ef2be5SMarek Vasut 139251ef2be5SMarek Vasut static int isl7998x_init_controls(struct isl7998x *isl7998x) 139351ef2be5SMarek Vasut { 139451ef2be5SMarek Vasut struct v4l2_subdev *sd = &isl7998x->subdev; 139551ef2be5SMarek Vasut int link_freq_index; 139651ef2be5SMarek Vasut unsigned int i; 139751ef2be5SMarek Vasut int ret; 139851ef2be5SMarek Vasut 139951ef2be5SMarek Vasut ret = v4l2_ctrl_handler_init(&isl7998x->ctrl_handler, 140051ef2be5SMarek Vasut 2 + ARRAY_SIZE(isl7998x_ctrls)); 140151ef2be5SMarek Vasut if (ret) 140251ef2be5SMarek Vasut return ret; 140351ef2be5SMarek Vasut 140451ef2be5SMarek Vasut mutex_init(&isl7998x->ctrl_mutex); 140551ef2be5SMarek Vasut isl7998x->ctrl_handler.lock = &isl7998x->ctrl_mutex; 140651ef2be5SMarek Vasut link_freq_index = get_link_freq_menu_index(isl7998x->nr_mipi_lanes, 140751ef2be5SMarek Vasut isl7998x->nr_inputs); 140851ef2be5SMarek Vasut if (link_freq_index < 0 || 140951ef2be5SMarek Vasut link_freq_index >= ARRAY_SIZE(link_freq_menu_items)) { 141051ef2be5SMarek Vasut dev_err(sd->dev, 141151ef2be5SMarek Vasut "failed to find MIPI link freq: %d lanes, %d inputs\n", 141251ef2be5SMarek Vasut isl7998x->nr_mipi_lanes, isl7998x->nr_inputs); 141351ef2be5SMarek Vasut ret = -EINVAL; 141451ef2be5SMarek Vasut goto err; 141551ef2be5SMarek Vasut } 141651ef2be5SMarek Vasut 141751ef2be5SMarek Vasut isl7998x->link_freq = v4l2_ctrl_new_int_menu(&isl7998x->ctrl_handler, 141851ef2be5SMarek Vasut &isl7998x_ctrl_ops, 141951ef2be5SMarek Vasut V4L2_CID_LINK_FREQ, 142051ef2be5SMarek Vasut ARRAY_SIZE(link_freq_menu_items) - 1, 142151ef2be5SMarek Vasut link_freq_index, 142251ef2be5SMarek Vasut link_freq_menu_items); 142351ef2be5SMarek Vasut if (isl7998x->link_freq) 142451ef2be5SMarek Vasut isl7998x->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; 142551ef2be5SMarek Vasut 142651ef2be5SMarek Vasut for (i = 0; i < ARRAY_SIZE(isl7998x_ctrls); i++) 142751ef2be5SMarek Vasut v4l2_ctrl_new_custom(&isl7998x->ctrl_handler, 142851ef2be5SMarek Vasut &isl7998x_ctrls[i], NULL); 142951ef2be5SMarek Vasut 143051ef2be5SMarek Vasut v4l2_ctrl_new_std_menu_items(&isl7998x->ctrl_handler, 143151ef2be5SMarek Vasut &isl7998x_ctrl_ops, 143251ef2be5SMarek Vasut V4L2_CID_TEST_PATTERN, 143351ef2be5SMarek Vasut ARRAY_SIZE(isl7998x_test_pattern_menu) - 1, 143451ef2be5SMarek Vasut 0, 0, isl7998x_test_pattern_menu); 143551ef2be5SMarek Vasut 143651ef2be5SMarek Vasut ret = isl7998x->ctrl_handler.error; 143751ef2be5SMarek Vasut if (ret) 143851ef2be5SMarek Vasut goto err; 143951ef2be5SMarek Vasut 144051ef2be5SMarek Vasut isl7998x->subdev.ctrl_handler = &isl7998x->ctrl_handler; 144151ef2be5SMarek Vasut v4l2_ctrl_handler_setup(&isl7998x->ctrl_handler); 144251ef2be5SMarek Vasut 144351ef2be5SMarek Vasut return 0; 144451ef2be5SMarek Vasut 144551ef2be5SMarek Vasut err: 144651ef2be5SMarek Vasut isl7998x_remove_controls(isl7998x); 144751ef2be5SMarek Vasut 144851ef2be5SMarek Vasut return ret; 144951ef2be5SMarek Vasut } 145051ef2be5SMarek Vasut 145151ef2be5SMarek Vasut static int isl7998x_probe(struct i2c_client *client) 145251ef2be5SMarek Vasut { 145351ef2be5SMarek Vasut struct device *dev = &client->dev; 145451ef2be5SMarek Vasut struct v4l2_fwnode_endpoint endpoint = { 145551ef2be5SMarek Vasut .bus_type = V4L2_MBUS_CSI2_DPHY, 145651ef2be5SMarek Vasut }; 145751ef2be5SMarek Vasut struct fwnode_handle *ep; 145851ef2be5SMarek Vasut struct isl7998x *isl7998x; 145951ef2be5SMarek Vasut struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 146051ef2be5SMarek Vasut int nr_inputs; 146151ef2be5SMarek Vasut int ret; 146251ef2be5SMarek Vasut 146351ef2be5SMarek Vasut ret = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA); 146451ef2be5SMarek Vasut if (!ret) { 146551ef2be5SMarek Vasut dev_warn(&adapter->dev, 146651ef2be5SMarek Vasut "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); 146751ef2be5SMarek Vasut return -EIO; 146851ef2be5SMarek Vasut } 146951ef2be5SMarek Vasut 147051ef2be5SMarek Vasut isl7998x = devm_kzalloc(dev, sizeof(*isl7998x), GFP_KERNEL); 147151ef2be5SMarek Vasut if (!isl7998x) 147251ef2be5SMarek Vasut return -ENOMEM; 147351ef2be5SMarek Vasut 147451ef2be5SMarek Vasut isl7998x->pd_gpio = devm_gpiod_get_optional(dev, "powerdown", 147551ef2be5SMarek Vasut GPIOD_OUT_HIGH); 147651ef2be5SMarek Vasut if (IS_ERR(isl7998x->pd_gpio)) 147751ef2be5SMarek Vasut return dev_err_probe(dev, PTR_ERR(isl7998x->pd_gpio), 147851ef2be5SMarek Vasut "Failed to retrieve/request PD GPIO\n"); 147951ef2be5SMarek Vasut 148051ef2be5SMarek Vasut isl7998x->rstb_gpio = devm_gpiod_get_optional(dev, "reset", 148151ef2be5SMarek Vasut GPIOD_OUT_HIGH); 148251ef2be5SMarek Vasut if (IS_ERR(isl7998x->rstb_gpio)) 148351ef2be5SMarek Vasut return dev_err_probe(dev, PTR_ERR(isl7998x->rstb_gpio), 148451ef2be5SMarek Vasut "Failed to retrieve/request RSTB GPIO\n"); 148551ef2be5SMarek Vasut 148651ef2be5SMarek Vasut isl7998x->regmap = devm_regmap_init_i2c(client, &isl7998x_regmap); 148751ef2be5SMarek Vasut if (IS_ERR(isl7998x->regmap)) 148851ef2be5SMarek Vasut return dev_err_probe(dev, PTR_ERR(isl7998x->regmap), 148951ef2be5SMarek Vasut "Failed to allocate register map\n"); 149051ef2be5SMarek Vasut 149151ef2be5SMarek Vasut ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 149251ef2be5SMarek Vasut ISL7998X_PAD_OUT, 0, 0); 149351ef2be5SMarek Vasut if (!ep) 149451ef2be5SMarek Vasut return dev_err_probe(dev, -EINVAL, "Missing endpoint node\n"); 149551ef2be5SMarek Vasut 149651ef2be5SMarek Vasut ret = v4l2_fwnode_endpoint_parse(ep, &endpoint); 149751ef2be5SMarek Vasut fwnode_handle_put(ep); 149851ef2be5SMarek Vasut if (ret) 149951ef2be5SMarek Vasut return dev_err_probe(dev, ret, "Failed to parse endpoint\n"); 150051ef2be5SMarek Vasut 150151ef2be5SMarek Vasut if (endpoint.bus.mipi_csi2.num_data_lanes == 0 || 150251ef2be5SMarek Vasut endpoint.bus.mipi_csi2.num_data_lanes > 2) 150351ef2be5SMarek Vasut return dev_err_probe(dev, -EINVAL, 150451ef2be5SMarek Vasut "Invalid number of MIPI lanes\n"); 150551ef2be5SMarek Vasut 150651ef2be5SMarek Vasut isl7998x->nr_mipi_lanes = endpoint.bus.mipi_csi2.num_data_lanes; 150751ef2be5SMarek Vasut 150851ef2be5SMarek Vasut nr_inputs = isl7998x_get_nr_inputs(dev->of_node); 150951ef2be5SMarek Vasut if (nr_inputs < 0) 151051ef2be5SMarek Vasut return dev_err_probe(dev, nr_inputs, 151151ef2be5SMarek Vasut "Invalid number of input ports\n"); 151251ef2be5SMarek Vasut isl7998x->nr_inputs = nr_inputs; 151351ef2be5SMarek Vasut 151451ef2be5SMarek Vasut v4l2_i2c_subdev_init(&isl7998x->subdev, client, &isl7998x_subdev_ops); 151551ef2be5SMarek Vasut isl7998x->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 151651ef2be5SMarek Vasut 151751ef2be5SMarek Vasut ret = isl7998x_mc_init(isl7998x); 151851ef2be5SMarek Vasut if (ret < 0) 151951ef2be5SMarek Vasut return ret; 152051ef2be5SMarek Vasut 152151ef2be5SMarek Vasut isl7998x->fmt = &isl7998x_colour_fmts[0]; 152251ef2be5SMarek Vasut isl7998x->norm = V4L2_STD_NTSC; 152351ef2be5SMarek Vasut isl7998x->enabled = 0; 152451ef2be5SMarek Vasut 152551ef2be5SMarek Vasut mutex_init(&isl7998x->lock); 152651ef2be5SMarek Vasut 152751ef2be5SMarek Vasut ret = isl7998x_init_controls(isl7998x); 152851ef2be5SMarek Vasut if (ret) 152951ef2be5SMarek Vasut goto err_entity_cleanup; 153051ef2be5SMarek Vasut 153151ef2be5SMarek Vasut ret = v4l2_async_register_subdev(&isl7998x->subdev); 153251ef2be5SMarek Vasut if (ret < 0) 153351ef2be5SMarek Vasut goto err_controls_cleanup; 153451ef2be5SMarek Vasut 153551ef2be5SMarek Vasut pm_runtime_enable(dev); 153651ef2be5SMarek Vasut 153751ef2be5SMarek Vasut return 0; 153851ef2be5SMarek Vasut 153951ef2be5SMarek Vasut err_controls_cleanup: 154051ef2be5SMarek Vasut isl7998x_remove_controls(isl7998x); 154151ef2be5SMarek Vasut err_entity_cleanup: 154251ef2be5SMarek Vasut media_entity_cleanup(&isl7998x->subdev.entity); 154351ef2be5SMarek Vasut 154451ef2be5SMarek Vasut return ret; 154551ef2be5SMarek Vasut } 154651ef2be5SMarek Vasut 1547ed5c2f5fSUwe Kleine-König static void isl7998x_remove(struct i2c_client *client) 154851ef2be5SMarek Vasut { 154951ef2be5SMarek Vasut struct isl7998x *isl7998x = i2c_to_isl7998x(client); 155051ef2be5SMarek Vasut 155151ef2be5SMarek Vasut pm_runtime_disable(&client->dev); 155251ef2be5SMarek Vasut v4l2_async_unregister_subdev(&isl7998x->subdev); 155351ef2be5SMarek Vasut isl7998x_remove_controls(isl7998x); 155451ef2be5SMarek Vasut media_entity_cleanup(&isl7998x->subdev.entity); 155551ef2be5SMarek Vasut } 155651ef2be5SMarek Vasut 155751ef2be5SMarek Vasut static const struct of_device_id isl7998x_of_match[] = { 155851ef2be5SMarek Vasut { .compatible = "isil,isl79987", }, 155951ef2be5SMarek Vasut { /* sentinel */ }, 156051ef2be5SMarek Vasut }; 156151ef2be5SMarek Vasut MODULE_DEVICE_TABLE(of, isl7998x_of_match); 156251ef2be5SMarek Vasut 156351ef2be5SMarek Vasut static const struct i2c_device_id isl7998x_id[] = { 156451ef2be5SMarek Vasut { "isl79987", 0 }, 156551ef2be5SMarek Vasut { /* sentinel */ }, 156651ef2be5SMarek Vasut }; 156751ef2be5SMarek Vasut MODULE_DEVICE_TABLE(i2c, isl7998x_id); 156851ef2be5SMarek Vasut 156951ef2be5SMarek Vasut static int __maybe_unused isl7998x_runtime_resume(struct device *dev) 157051ef2be5SMarek Vasut { 157151ef2be5SMarek Vasut struct v4l2_subdev *sd = dev_get_drvdata(dev); 157251ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 157351ef2be5SMarek Vasut int ret; 157451ef2be5SMarek Vasut 157551ef2be5SMarek Vasut gpiod_set_value(isl7998x->rstb_gpio, 1); 157651ef2be5SMarek Vasut gpiod_set_value(isl7998x->pd_gpio, 0); 157751ef2be5SMarek Vasut gpiod_set_value(isl7998x->rstb_gpio, 0); 157851ef2be5SMarek Vasut 157951ef2be5SMarek Vasut ret = isl7998x_wait_power_on(isl7998x); 158051ef2be5SMarek Vasut if (ret) 158151ef2be5SMarek Vasut goto err; 158251ef2be5SMarek Vasut 158351ef2be5SMarek Vasut ret = isl7998x_init(isl7998x); 158451ef2be5SMarek Vasut if (ret) 158551ef2be5SMarek Vasut goto err; 158651ef2be5SMarek Vasut 158751ef2be5SMarek Vasut return 0; 158851ef2be5SMarek Vasut 158951ef2be5SMarek Vasut err: 159051ef2be5SMarek Vasut gpiod_set_value(isl7998x->pd_gpio, 1); 159151ef2be5SMarek Vasut 159251ef2be5SMarek Vasut return ret; 159351ef2be5SMarek Vasut } 159451ef2be5SMarek Vasut 159551ef2be5SMarek Vasut static int __maybe_unused isl7998x_runtime_suspend(struct device *dev) 159651ef2be5SMarek Vasut { 159751ef2be5SMarek Vasut struct v4l2_subdev *sd = dev_get_drvdata(dev); 159851ef2be5SMarek Vasut struct isl7998x *isl7998x = sd_to_isl7998x(sd); 159951ef2be5SMarek Vasut 160051ef2be5SMarek Vasut gpiod_set_value(isl7998x->pd_gpio, 1); 160151ef2be5SMarek Vasut 160251ef2be5SMarek Vasut return 0; 160351ef2be5SMarek Vasut } 160451ef2be5SMarek Vasut 160551ef2be5SMarek Vasut static const struct dev_pm_ops isl7998x_pm_ops = { 160651ef2be5SMarek Vasut SET_RUNTIME_PM_OPS(isl7998x_runtime_suspend, 160751ef2be5SMarek Vasut isl7998x_runtime_resume, 160851ef2be5SMarek Vasut NULL) 160951ef2be5SMarek Vasut }; 161051ef2be5SMarek Vasut 161151ef2be5SMarek Vasut static struct i2c_driver isl7998x_i2c_driver = { 161251ef2be5SMarek Vasut .driver = { 161351ef2be5SMarek Vasut .name = "isl7998x", 161451ef2be5SMarek Vasut .of_match_table = of_match_ptr(isl7998x_of_match), 161551ef2be5SMarek Vasut .pm = &isl7998x_pm_ops, 161651ef2be5SMarek Vasut }, 161751ef2be5SMarek Vasut .probe_new = isl7998x_probe, 161851ef2be5SMarek Vasut .remove = isl7998x_remove, 161951ef2be5SMarek Vasut .id_table = isl7998x_id, 162051ef2be5SMarek Vasut }; 162151ef2be5SMarek Vasut 162251ef2be5SMarek Vasut module_i2c_driver(isl7998x_i2c_driver); 162351ef2be5SMarek Vasut 162451ef2be5SMarek Vasut MODULE_DESCRIPTION("Intersil ISL7998x Analog to MIPI CSI-2/BT656 decoder"); 162551ef2be5SMarek Vasut MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); 162651ef2be5SMarek Vasut MODULE_LICENSE("GPL v2"); 1627