isl7998x.c 54 KB

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