1 // SPDX-License-Identifier: GPL-2.0-only
3 * mt9m114.c onsemi MT9M114 sensor driver
5 * Copyright (c) 2020-2023 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
6 * Copyright (c) 2012 Analog Devices Inc.
8 * Almost complete rewrite of work by Scott Jiang <Scott.Jiang.Linux@gmail.com>
9 * itself based on work from Andrew Chew <achew@nvidia.com>.
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/errno.h>
15 #include <linux/gpio/consumer.h>
16 #include <linux/i2c.h>
17 #include <linux/mod_devicetable.h>
18 #include <linux/module.h>
19 #include <linux/mutex.h>
20 #include <linux/pm_runtime.h>
21 #include <linux/regmap.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/types.h>
24 #include <linux/videodev2.h>
26 #include <media/v4l2-async.h>
27 #include <media/v4l2-cci.h>
28 #include <media/v4l2-ctrls.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-fwnode.h>
31 #include <media/v4l2-mediabus.h>
32 #include <media/v4l2-subdev.h>
34 /* Sysctl registers */
35 #define MT9M114_CHIP_ID CCI_REG16(0x0000)
36 #define MT9M114_COMMAND_REGISTER CCI_REG16(0x0080)
37 #define MT9M114_COMMAND_REGISTER_APPLY_PATCH BIT(0)
38 #define MT9M114_COMMAND_REGISTER_SET_STATE BIT(1)
39 #define MT9M114_COMMAND_REGISTER_REFRESH BIT(2)
40 #define MT9M114_COMMAND_REGISTER_WAIT_FOR_EVENT BIT(3)
41 #define MT9M114_COMMAND_REGISTER_OK BIT(15)
42 #define MT9M114_RESET_AND_MISC_CONTROL CCI_REG16(0x001a)
43 #define MT9M114_RESET_SOC BIT(0)
44 #define MT9M114_PAD_SLEW CCI_REG16(0x001e)
45 #define MT9M114_PAD_CONTROL CCI_REG16(0x0032)
48 #define MT9M114_ACCESS_CTL_STAT CCI_REG16(0x0982)
49 #define MT9M114_PHYSICAL_ADDRESS_ACCESS CCI_REG16(0x098a)
50 #define MT9M114_LOGICAL_ADDRESS_ACCESS CCI_REG16(0x098e)
52 /* Sensor Core registers */
53 #define MT9M114_COARSE_INTEGRATION_TIME CCI_REG16(0x3012)
54 #define MT9M114_FINE_INTEGRATION_TIME CCI_REG16(0x3014)
55 #define MT9M114_RESET_REGISTER CCI_REG16(0x301a)
56 #define MT9M114_RESET_REGISTER_LOCK_REG BIT(3)
57 #define MT9M114_RESET_REGISTER_MASK_BAD BIT(9)
58 #define MT9M114_FLASH CCI_REG16(0x3046)
59 #define MT9M114_GREEN1_GAIN CCI_REG16(0x3056)
60 #define MT9M114_BLUE_GAIN CCI_REG16(0x3058)
61 #define MT9M114_RED_GAIN CCI_REG16(0x305a)
62 #define MT9M114_GREEN2_GAIN CCI_REG16(0x305c)
63 #define MT9M114_GLOBAL_GAIN CCI_REG16(0x305e)
64 #define MT9M114_GAIN_DIGITAL_GAIN(n) ((n) << 12)
65 #define MT9M114_GAIN_DIGITAL_GAIN_MASK (0xf << 12)
66 #define MT9M114_GAIN_ANALOG_GAIN(n) ((n) << 0)
67 #define MT9M114_GAIN_ANALOG_GAIN_MASK (0xff << 0)
68 #define MT9M114_CUSTOMER_REV CCI_REG16(0x31fe)
70 /* Monitor registers */
71 #define MT9M114_MON_MAJOR_VERSION CCI_REG16(0x8000)
72 #define MT9M114_MON_MINOR_VERSION CCI_REG16(0x8002)
73 #define MT9M114_MON_RELEASE_VERSION CCI_REG16(0x8004)
75 /* Auto-Exposure Track registers */
76 #define MT9M114_AE_TRACK_ALGO CCI_REG16(0xa804)
77 #define MT9M114_AE_TRACK_EXEC_AUTOMATIC_EXPOSURE BIT(0)
78 #define MT9M114_AE_TRACK_AE_TRACKING_DAMPENING_SPEED CCI_REG8(0xa80a)
80 /* Color Correction Matrix registers */
81 #define MT9M114_CCM_ALGO CCI_REG16(0xb404)
82 #define MT9M114_CCM_EXEC_CALC_CCM_MATRIX BIT(4)
83 #define MT9M114_CCM_DELTA_GAIN CCI_REG8(0xb42a)
85 /* Camera Control registers */
86 #define MT9M114_CAM_SENSOR_CFG_Y_ADDR_START CCI_REG16(0xc800)
87 #define MT9M114_CAM_SENSOR_CFG_X_ADDR_START CCI_REG16(0xc802)
88 #define MT9M114_CAM_SENSOR_CFG_Y_ADDR_END CCI_REG16(0xc804)
89 #define MT9M114_CAM_SENSOR_CFG_X_ADDR_END CCI_REG16(0xc806)
90 #define MT9M114_CAM_SENSOR_CFG_PIXCLK CCI_REG32(0xc808)
91 #define MT9M114_CAM_SENSOR_CFG_ROW_SPEED CCI_REG16(0xc80c)
92 #define MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN CCI_REG16(0xc80e)
93 #define MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX CCI_REG16(0xc810)
94 #define MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES CCI_REG16(0xc812)
95 #define MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES_MAX 65535
96 #define MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK CCI_REG16(0xc814)
97 #define MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK_MAX 8191
98 #define MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION CCI_REG16(0xc816)
99 #define MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW CCI_REG16(0xc818)
100 #define MT9M114_CAM_SENSOR_CFG_REG_0_DATA CCI_REG16(0xc826)
101 #define MT9M114_CAM_SENSOR_CONTROL_READ_MODE CCI_REG16(0xc834)
102 #define MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN BIT(0)
103 #define MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN BIT(1)
104 #define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_NORMAL (0 << 4)
105 #define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SKIPPING (1 << 4)
106 #define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_AVERAGE (2 << 4)
107 #define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SUMMING (3 << 4)
108 #define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK (3 << 4)
109 #define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_NORMAL (0 << 8)
110 #define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SKIPPING (1 << 8)
111 #define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SUMMING (3 << 8)
112 #define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK (3 << 8)
113 #define MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN CCI_REG16(0xc836)
114 #define MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME CCI_REG16(0xc83c)
115 #define MT9M114_CAM_SENSOR_CONTROL_FINE_INTEGRATION_TIME CCI_REG16(0xc83e)
116 #define MT9M114_CAM_MODE_SELECT CCI_REG8(0xc84c)
117 #define MT9M114_CAM_MODE_SELECT_NORMAL (0 << 0)
118 #define MT9M114_CAM_MODE_SELECT_LENS_CALIBRATION (1 << 0)
119 #define MT9M114_CAM_MODE_SELECT_TEST_PATTERN (2 << 0)
120 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT CCI_REG8(0xc84d)
121 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID (1 << 0)
122 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID_BARS (4 << 0)
123 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_RANDOM (5 << 0)
124 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_FADING_BARS (8 << 0)
125 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_10B (10 << 0)
126 #define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_8B (11 << 0)
127 #define MT9M114_CAM_MODE_TEST_PATTERN_RED CCI_REG16(0xc84e)
128 #define MT9M114_CAM_MODE_TEST_PATTERN_GREEN CCI_REG16(0xc850)
129 #define MT9M114_CAM_MODE_TEST_PATTERN_BLUE CCI_REG16(0xc852)
130 #define MT9M114_CAM_CROP_WINDOW_XOFFSET CCI_REG16(0xc854)
131 #define MT9M114_CAM_CROP_WINDOW_YOFFSET CCI_REG16(0xc856)
132 #define MT9M114_CAM_CROP_WINDOW_WIDTH CCI_REG16(0xc858)
133 #define MT9M114_CAM_CROP_WINDOW_HEIGHT CCI_REG16(0xc85a)
134 #define MT9M114_CAM_CROP_CROPMODE CCI_REG8(0xc85c)
135 #define MT9M114_CAM_CROP_MODE_AE_AUTO_CROP_EN BIT(0)
136 #define MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN BIT(1)
137 #define MT9M114_CAM_OUTPUT_WIDTH CCI_REG16(0xc868)
138 #define MT9M114_CAM_OUTPUT_HEIGHT CCI_REG16(0xc86a)
139 #define MT9M114_CAM_OUTPUT_FORMAT CCI_REG16(0xc86c)
140 #define MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE BIT(0)
141 #define MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES BIT(1)
142 #define MT9M114_CAM_OUTPUT_FORMAT_MONO_ENABLE BIT(2)
143 #define MT9M114_CAM_OUTPUT_FORMAT_BT656_ENABLE BIT(3)
144 #define MT9M114_CAM_OUTPUT_FORMAT_BT656_CROP_SCALE_DISABLE BIT(4)
145 #define MT9M114_CAM_OUTPUT_FORMAT_FVLV_DISABLE BIT(5)
146 #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV (0 << 8)
147 #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB (1 << 8)
148 #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER (2 << 8)
149 #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_NONE (3 << 8)
150 #define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK (3 << 8)
151 #define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_RAWR10 (0 << 10)
152 #define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PRELSC_8_2 (1 << 10)
153 #define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_POSTLSC_8_2 (2 << 10)
154 #define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PROCESSED8 (3 << 10)
155 #define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_MASK (3 << 10)
156 #define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB (0 << 12)
157 #define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_555RGB (1 << 12)
158 #define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_444xRGB (2 << 12)
159 #define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_444RGBx (3 << 12)
160 #define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_MASK (3 << 12)
161 #define MT9M114_CAM_OUTPUT_FORMAT_YUV CCI_REG16(0xc86e)
162 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_CLIP BIT(5)
163 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_AUV_OFFSET BIT(4)
164 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_SELECT_601 BIT(3)
165 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_NORMALISE BIT(2)
166 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_EVEN_UV (0 << 0)
167 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_ODD_UV (1 << 0)
168 #define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_EVENU_ODDV (2 << 0)
169 #define MT9M114_CAM_OUTPUT_Y_OFFSET CCI_REG8(0xc870)
170 #define MT9M114_CAM_AET_AEMODE CCI_REG8(0xc878)
171 #define MT9M114_CAM_AET_EXEC_SET_INDOOR BIT(0)
172 #define MT9M114_CAM_AET_DISCRETE_FRAMERATE BIT(1)
173 #define MT9M114_CAM_AET_ADAPTATIVE_TARGET_LUMA BIT(2)
174 #define MT9M114_CAM_AET_ADAPTATIVE_SKIP_FRAMES BIT(3)
175 #define MT9M114_CAM_AET_SKIP_FRAMES CCI_REG8(0xc879)
176 #define MT9M114_CAM_AET_TARGET_AVERAGE_LUMA CCI_REG8(0xc87a)
177 #define MT9M114_CAM_AET_TARGET_AVERAGE_LUMA_DARK CCI_REG8(0xc87b)
178 #define MT9M114_CAM_AET_BLACK_CLIPPING_TARGET CCI_REG16(0xc87c)
179 #define MT9M114_CAM_AET_AE_MIN_VIRT_INT_TIME_PCLK CCI_REG16(0xc87e)
180 #define MT9M114_CAM_AET_AE_MIN_VIRT_DGAIN CCI_REG16(0xc880)
181 #define MT9M114_CAM_AET_AE_MAX_VIRT_DGAIN CCI_REG16(0xc882)
182 #define MT9M114_CAM_AET_AE_MIN_VIRT_AGAIN CCI_REG16(0xc884)
183 #define MT9M114_CAM_AET_AE_MAX_VIRT_AGAIN CCI_REG16(0xc886)
184 #define MT9M114_CAM_AET_AE_VIRT_GAIN_TH_EG CCI_REG16(0xc888)
185 #define MT9M114_CAM_AET_AE_EG_GATE_PERCENTAGE CCI_REG8(0xc88a)
186 #define MT9M114_CAM_AET_FLICKER_FREQ_HZ CCI_REG8(0xc88b)
187 #define MT9M114_CAM_AET_MAX_FRAME_RATE CCI_REG16(0xc88c)
188 #define MT9M114_CAM_AET_MIN_FRAME_RATE CCI_REG16(0xc88e)
189 #define MT9M114_CAM_AET_TARGET_GAIN CCI_REG16(0xc890)
190 #define MT9M114_CAM_AWB_CCM_L(n) CCI_REG16(0xc892 + (n) * 2)
191 #define MT9M114_CAM_AWB_CCM_M(n) CCI_REG16(0xc8a4 + (n) * 2)
192 #define MT9M114_CAM_AWB_CCM_R(n) CCI_REG16(0xc8b6 + (n) * 2)
193 #define MT9M114_CAM_AWB_CCM_L_RG_GAIN CCI_REG16(0xc8c8)
194 #define MT9M114_CAM_AWB_CCM_L_BG_GAIN CCI_REG16(0xc8ca)
195 #define MT9M114_CAM_AWB_CCM_M_RG_GAIN CCI_REG16(0xc8cc)
196 #define MT9M114_CAM_AWB_CCM_M_BG_GAIN CCI_REG16(0xc8ce)
197 #define MT9M114_CAM_AWB_CCM_R_RG_GAIN CCI_REG16(0xc8d0)
198 #define MT9M114_CAM_AWB_CCM_R_BG_GAIN CCI_REG16(0xc8d2)
199 #define MT9M114_CAM_AWB_CCM_L_CTEMP CCI_REG16(0xc8d4)
200 #define MT9M114_CAM_AWB_CCM_M_CTEMP CCI_REG16(0xc8d6)
201 #define MT9M114_CAM_AWB_CCM_R_CTEMP CCI_REG16(0xc8d8)
202 #define MT9M114_CAM_AWB_AWB_XSCALE CCI_REG8(0xc8f2)
203 #define MT9M114_CAM_AWB_AWB_YSCALE CCI_REG8(0xc8f3)
204 #define MT9M114_CAM_AWB_AWB_WEIGHTS(n) CCI_REG16(0xc8f4 + (n) * 2)
205 #define MT9M114_CAM_AWB_AWB_XSHIFT_PRE_ADJ CCI_REG16(0xc904)
206 #define MT9M114_CAM_AWB_AWB_YSHIFT_PRE_ADJ CCI_REG16(0xc906)
207 #define MT9M114_CAM_AWB_AWBMODE CCI_REG8(0xc909)
208 #define MT9M114_CAM_AWB_MODE_AUTO BIT(1)
209 #define MT9M114_CAM_AWB_MODE_EXCLUSIVE_AE BIT(0)
210 #define MT9M114_CAM_AWB_K_R_L CCI_REG8(0xc90c)
211 #define MT9M114_CAM_AWB_K_G_L CCI_REG8(0xc90d)
212 #define MT9M114_CAM_AWB_K_B_L CCI_REG8(0xc90e)
213 #define MT9M114_CAM_AWB_K_R_R CCI_REG8(0xc90f)
214 #define MT9M114_CAM_AWB_K_G_R CCI_REG8(0xc910)
215 #define MT9M114_CAM_AWB_K_B_R CCI_REG8(0xc911)
216 #define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART CCI_REG16(0xc914)
217 #define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART CCI_REG16(0xc916)
218 #define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND CCI_REG16(0xc918)
219 #define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND CCI_REG16(0xc91a)
220 #define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART CCI_REG16(0xc91c)
221 #define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART CCI_REG16(0xc91e)
222 #define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND CCI_REG16(0xc920)
223 #define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND CCI_REG16(0xc922)
224 #define MT9M114_CAM_LL_LLMODE CCI_REG16(0xc924)
225 #define MT9M114_CAM_LL_START_BRIGHTNESS CCI_REG16(0xc926)
226 #define MT9M114_CAM_LL_STOP_BRIGHTNESS CCI_REG16(0xc928)
227 #define MT9M114_CAM_LL_START_SATURATION CCI_REG8(0xc92a)
228 #define MT9M114_CAM_LL_END_SATURATION CCI_REG8(0xc92b)
229 #define MT9M114_CAM_LL_START_DESATURATION CCI_REG8(0xc92c)
230 #define MT9M114_CAM_LL_END_DESATURATION CCI_REG8(0xc92d)
231 #define MT9M114_CAM_LL_START_DEMOSAICING CCI_REG8(0xc92e)
232 #define MT9M114_CAM_LL_START_AP_GAIN CCI_REG8(0xc92f)
233 #define MT9M114_CAM_LL_START_AP_THRESH CCI_REG8(0xc930)
234 #define MT9M114_CAM_LL_STOP_DEMOSAICING CCI_REG8(0xc931)
235 #define MT9M114_CAM_LL_STOP_AP_GAIN CCI_REG8(0xc932)
236 #define MT9M114_CAM_LL_STOP_AP_THRESH CCI_REG8(0xc933)
237 #define MT9M114_CAM_LL_START_NR_RED CCI_REG8(0xc934)
238 #define MT9M114_CAM_LL_START_NR_GREEN CCI_REG8(0xc935)
239 #define MT9M114_CAM_LL_START_NR_BLUE CCI_REG8(0xc936)
240 #define MT9M114_CAM_LL_START_NR_THRESH CCI_REG8(0xc937)
241 #define MT9M114_CAM_LL_STOP_NR_RED CCI_REG8(0xc938)
242 #define MT9M114_CAM_LL_STOP_NR_GREEN CCI_REG8(0xc939)
243 #define MT9M114_CAM_LL_STOP_NR_BLUE CCI_REG8(0xc93a)
244 #define MT9M114_CAM_LL_STOP_NR_THRESH CCI_REG8(0xc93b)
245 #define MT9M114_CAM_LL_START_CONTRAST_BM CCI_REG16(0xc93c)
246 #define MT9M114_CAM_LL_STOP_CONTRAST_BM CCI_REG16(0xc93e)
247 #define MT9M114_CAM_LL_GAMMA CCI_REG16(0xc940)
248 #define MT9M114_CAM_LL_START_CONTRAST_GRADIENT CCI_REG8(0xc942)
249 #define MT9M114_CAM_LL_STOP_CONTRAST_GRADIENT CCI_REG8(0xc943)
250 #define MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE CCI_REG8(0xc944)
251 #define MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE CCI_REG8(0xc945)
252 #define MT9M114_CAM_LL_START_GAIN_METRIC CCI_REG16(0xc946)
253 #define MT9M114_CAM_LL_STOP_GAIN_METRIC CCI_REG16(0xc948)
254 #define MT9M114_CAM_LL_START_FADE_TO_BLACK_LUMA CCI_REG16(0xc94a)
255 #define MT9M114_CAM_LL_STOP_FADE_TO_BLACK_LUMA CCI_REG16(0xc94c)
256 #define MT9M114_CAM_LL_CLUSTER_DC_TH_BM CCI_REG16(0xc94e)
257 #define MT9M114_CAM_LL_CLUSTER_DC_GATE_PERCENTAGE CCI_REG8(0xc950)
258 #define MT9M114_CAM_LL_SUMMING_SENSITIVITY_FACTOR CCI_REG8(0xc951)
259 #define MT9M114_CAM_LL_START_TARGET_LUMA_BM CCI_REG16(0xc952)
260 #define MT9M114_CAM_LL_STOP_TARGET_LUMA_BM CCI_REG16(0xc954)
261 #define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e)
262 #define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e)
263 #define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0)
264 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980)
265 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m))
266 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982)
267 #define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(p) ((p) << 8)
268 #define MT9M114_CAM_PORT_OUTPUT_CONTROL CCI_REG16(0xc984)
269 #define MT9M114_CAM_PORT_PORT_SELECT_PARALLEL (0 << 0)
270 #define MT9M114_CAM_PORT_PORT_SELECT_MIPI (1 << 0)
271 #define MT9M114_CAM_PORT_CLOCK_SLOWDOWN BIT(3)
272 #define MT9M114_CAM_PORT_TRUNCATE_RAW_BAYER BIT(4)
273 #define MT9M114_CAM_PORT_PIXCLK_GATE BIT(5)
274 #define MT9M114_CAM_PORT_CONT_MIPI_CLK BIT(6)
275 #define MT9M114_CAM_PORT_CHAN_NUM(vc) ((vc) << 8)
276 #define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_ZERO CCI_REG16(0xc988)
277 #define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_ZERO_VALUE(n) ((n) << 8)
278 #define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_EXIT_TRAIL CCI_REG16(0xc98a)
279 #define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_EXIT_VALUE(n) ((n) << 8)
280 #define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_TRAIL_VALUE(n) ((n) << 0)
281 #define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_POST_PRE CCI_REG16(0xc98c)
282 #define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_POST_VALUE(n) ((n) << 8)
283 #define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_PRE_VALUE(n) ((n) << 0)
284 #define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_ZERO CCI_REG16(0xc98e)
285 #define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_VALUE(n) ((n) << 8)
286 #define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_ZERO_VALUE(n) ((n) << 0)
288 /* System Manager registers */
289 #define MT9M114_SYSMGR_NEXT_STATE CCI_REG8(0xdc00)
290 #define MT9M114_SYSMGR_CURRENT_STATE CCI_REG8(0xdc01)
291 #define MT9M114_SYSMGR_CMD_STATUS CCI_REG8(0xdc02)
293 /* Patch Loader registers */
294 #define MT9M114_PATCHLDR_LOADER_ADDRESS CCI_REG16(0xe000)
295 #define MT9M114_PATCHLDR_PATCH_ID CCI_REG16(0xe002)
296 #define MT9M114_PATCHLDR_FIRMWARE_ID CCI_REG32(0xe004)
297 #define MT9M114_PATCHLDR_APPLY_STATUS CCI_REG8(0xe008)
298 #define MT9M114_PATCHLDR_NUM_PATCHES CCI_REG8(0xe009)
299 #define MT9M114_PATCHLDR_PATCH_ID_0 CCI_REG16(0xe00a)
300 #define MT9M114_PATCHLDR_PATCH_ID_1 CCI_REG16(0xe00c)
301 #define MT9M114_PATCHLDR_PATCH_ID_2 CCI_REG16(0xe00e)
302 #define MT9M114_PATCHLDR_PATCH_ID_3 CCI_REG16(0xe010)
303 #define MT9M114_PATCHLDR_PATCH_ID_4 CCI_REG16(0xe012)
304 #define MT9M114_PATCHLDR_PATCH_ID_5 CCI_REG16(0xe014)
305 #define MT9M114_PATCHLDR_PATCH_ID_6 CCI_REG16(0xe016)
306 #define MT9M114_PATCHLDR_PATCH_ID_7 CCI_REG16(0xe018)
308 /* SYS_STATE values (for SYSMGR_NEXT_STATE and SYSMGR_CURRENT_STATE) */
309 #define MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE 0x28
310 #define MT9M114_SYS_STATE_STREAMING 0x31
311 #define MT9M114_SYS_STATE_START_STREAMING 0x34
312 #define MT9M114_SYS_STATE_ENTER_SUSPEND 0x40
313 #define MT9M114_SYS_STATE_SUSPENDED 0x41
314 #define MT9M114_SYS_STATE_ENTER_STANDBY 0x50
315 #define MT9M114_SYS_STATE_STANDBY 0x52
316 #define MT9M114_SYS_STATE_LEAVE_STANDBY 0x54
318 /* Result status of last SET_STATE comamnd */
319 #define MT9M114_SET_STATE_RESULT_ENOERR 0x00
320 #define MT9M114_SET_STATE_RESULT_EINVAL 0x0c
321 #define MT9M114_SET_STATE_RESULT_ENOSPC 0x0d
324 * The minimum amount of horizontal and vertical blanking is undocumented. The
325 * minimum values that have been seen in register lists are 303 and 38, use
328 * Set the default to achieve 1280x960 at 30fps.
330 #define MT9M114_MIN_HBLANK 303
331 #define MT9M114_MIN_VBLANK 38
332 #define MT9M114_DEF_HBLANK 323
333 #define MT9M114_DEF_VBLANK 39
335 #define MT9M114_DEF_FRAME_RATE 30
336 #define MT9M114_MAX_FRAME_RATE 120
338 #define MT9M114_PIXEL_ARRAY_WIDTH 1296U
339 #define MT9M114_PIXEL_ARRAY_HEIGHT 976U
342 * These values are not well documented and are semi-arbitrary. The pixel array
343 * minimum output size is 8 pixels larger than the minimum scaler cropped input
344 * width to account for the demosaicing.
346 #define MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH (32U + 8U)
347 #define MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT (32U + 8U)
348 #define MT9M114_SCALER_CROPPED_INPUT_WIDTH 32U
349 #define MT9M114_SCALER_CROPPED_INPUT_HEIGHT 32U
351 /* Indices into the mt9m114.ifp.tpg array. */
352 #define MT9M114_TPG_PATTERN 0
353 #define MT9M114_TPG_RED 1
354 #define MT9M114_TPG_GREEN 2
355 #define MT9M114_TPG_BLUE 3
357 /* -----------------------------------------------------------------------------
361 enum mt9m114_format_flag
{
362 MT9M114_FMT_FLAG_PARALLEL
= BIT(0),
363 MT9M114_FMT_FLAG_CSI2
= BIT(1),
366 struct mt9m114_format_info
{
373 struct i2c_client
*client
;
374 struct regmap
*regmap
;
377 struct gpio_desc
*reset
;
378 struct regulator_bulk_data supplies
[3];
379 struct v4l2_fwnode_endpoint bus_cfg
;
387 unsigned int pixrate
;
392 struct v4l2_subdev sd
;
393 struct media_pad pad
;
395 struct v4l2_ctrl_handler hdl
;
396 struct v4l2_ctrl
*exposure
;
397 struct v4l2_ctrl
*gain
;
398 struct v4l2_ctrl
*hblank
;
399 struct v4l2_ctrl
*vblank
;
402 /* Image Flow Processor */
404 struct v4l2_subdev sd
;
405 struct media_pad pads
[2];
407 struct v4l2_ctrl_handler hdl
;
408 unsigned int frame_rate
;
410 struct v4l2_ctrl
*tpg
[4];
414 /* -----------------------------------------------------------------------------
418 static const struct mt9m114_format_info mt9m114_format_infos
[] = {
421 * The first two entries are used as defaults, for parallel and
422 * CSI-2 buses respectively. Keep them in that order.
424 .code
= MEDIA_BUS_FMT_UYVY8_2X8
,
425 .flags
= MT9M114_FMT_FLAG_PARALLEL
,
426 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV
,
428 .code
= MEDIA_BUS_FMT_UYVY8_1X16
,
429 .flags
= MT9M114_FMT_FLAG_CSI2
,
430 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV
,
432 .code
= MEDIA_BUS_FMT_YUYV8_2X8
,
433 .flags
= MT9M114_FMT_FLAG_PARALLEL
,
434 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV
435 | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES
,
437 .code
= MEDIA_BUS_FMT_YUYV8_1X16
,
438 .flags
= MT9M114_FMT_FLAG_CSI2
,
439 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV
440 | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES
,
442 .code
= MEDIA_BUS_FMT_RGB565_2X8_LE
,
443 .flags
= MT9M114_FMT_FLAG_PARALLEL
,
444 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB
445 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB
446 | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES
,
448 .code
= MEDIA_BUS_FMT_RGB565_2X8_BE
,
449 .flags
= MT9M114_FMT_FLAG_PARALLEL
,
450 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB
451 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB
,
453 .code
= MEDIA_BUS_FMT_RGB565_1X16
,
454 .flags
= MT9M114_FMT_FLAG_CSI2
,
455 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB
456 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB
,
458 .code
= MEDIA_BUS_FMT_SGRBG8_1X8
,
459 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PROCESSED8
460 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER
,
461 .flags
= MT9M114_FMT_FLAG_PARALLEL
| MT9M114_FMT_FLAG_CSI2
,
463 /* Keep the format compatible with the IFP sink pad last. */
464 .code
= MEDIA_BUS_FMT_SGRBG10_1X10
,
465 .output_format
= MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_RAWR10
466 | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER
,
467 .flags
= MT9M114_FMT_FLAG_PARALLEL
| MT9M114_FMT_FLAG_CSI2
,
471 static const struct mt9m114_format_info
*
472 mt9m114_default_format_info(struct mt9m114
*sensor
)
474 if (sensor
->bus_cfg
.bus_type
== V4L2_MBUS_CSI2_DPHY
)
475 return &mt9m114_format_infos
[1];
477 return &mt9m114_format_infos
[0];
480 static const struct mt9m114_format_info
*
481 mt9m114_format_info(struct mt9m114
*sensor
, unsigned int pad
, u32 code
)
483 const unsigned int num_formats
= ARRAY_SIZE(mt9m114_format_infos
);
489 return &mt9m114_format_infos
[num_formats
- 1];
492 if (sensor
->bus_cfg
.bus_type
== V4L2_MBUS_CSI2_DPHY
)
493 flag
= MT9M114_FMT_FLAG_CSI2
;
495 flag
= MT9M114_FMT_FLAG_PARALLEL
;
497 for (i
= 0; i
< num_formats
; ++i
) {
498 const struct mt9m114_format_info
*info
=
499 &mt9m114_format_infos
[i
];
501 if (info
->code
== code
&& info
->flags
& flag
)
505 return mt9m114_default_format_info(sensor
);
512 /* -----------------------------------------------------------------------------
516 static const struct cci_reg_sequence mt9m114_init
[] = {
517 { MT9M114_RESET_REGISTER
, MT9M114_RESET_REGISTER_MASK_BAD
|
518 MT9M114_RESET_REGISTER_LOCK_REG
|
521 /* Sensor optimization */
522 { CCI_REG16(0x316a), 0x8270 },
523 { CCI_REG16(0x316c), 0x8270 },
524 { CCI_REG16(0x3ed0), 0x2305 },
525 { CCI_REG16(0x3ed2), 0x77cf },
526 { CCI_REG16(0x316e), 0x8202 },
527 { CCI_REG16(0x3180), 0x87ff },
528 { CCI_REG16(0x30d4), 0x6080 },
529 { CCI_REG16(0xa802), 0x0008 },
531 { CCI_REG16(0x3e14), 0xff39 },
534 { MT9M114_CAM_PGA_PGA_CONTROL
, 0x0000 },
536 /* Automatic White balance */
537 { MT9M114_CAM_AWB_CCM_L(0), 0x0267 },
538 { MT9M114_CAM_AWB_CCM_L(1), 0xff1a },
539 { MT9M114_CAM_AWB_CCM_L(2), 0xffb3 },
540 { MT9M114_CAM_AWB_CCM_L(3), 0xff80 },
541 { MT9M114_CAM_AWB_CCM_L(4), 0x0166 },
542 { MT9M114_CAM_AWB_CCM_L(5), 0x0003 },
543 { MT9M114_CAM_AWB_CCM_L(6), 0xff9a },
544 { MT9M114_CAM_AWB_CCM_L(7), 0xfeb4 },
545 { MT9M114_CAM_AWB_CCM_L(8), 0x024d },
546 { MT9M114_CAM_AWB_CCM_M(0), 0x01bf },
547 { MT9M114_CAM_AWB_CCM_M(1), 0xff01 },
548 { MT9M114_CAM_AWB_CCM_M(2), 0xfff3 },
549 { MT9M114_CAM_AWB_CCM_M(3), 0xff75 },
550 { MT9M114_CAM_AWB_CCM_M(4), 0x0198 },
551 { MT9M114_CAM_AWB_CCM_M(5), 0xfffd },
552 { MT9M114_CAM_AWB_CCM_M(6), 0xff9a },
553 { MT9M114_CAM_AWB_CCM_M(7), 0xfee7 },
554 { MT9M114_CAM_AWB_CCM_M(8), 0x02a8 },
555 { MT9M114_CAM_AWB_CCM_R(0), 0x01d9 },
556 { MT9M114_CAM_AWB_CCM_R(1), 0xff26 },
557 { MT9M114_CAM_AWB_CCM_R(2), 0xfff3 },
558 { MT9M114_CAM_AWB_CCM_R(3), 0xffb3 },
559 { MT9M114_CAM_AWB_CCM_R(4), 0x0132 },
560 { MT9M114_CAM_AWB_CCM_R(5), 0xffe8 },
561 { MT9M114_CAM_AWB_CCM_R(6), 0xffda },
562 { MT9M114_CAM_AWB_CCM_R(7), 0xfecd },
563 { MT9M114_CAM_AWB_CCM_R(8), 0x02c2 },
564 { MT9M114_CAM_AWB_CCM_L_RG_GAIN
, 0x0075 },
565 { MT9M114_CAM_AWB_CCM_L_BG_GAIN
, 0x011c },
566 { MT9M114_CAM_AWB_CCM_M_RG_GAIN
, 0x009a },
567 { MT9M114_CAM_AWB_CCM_M_BG_GAIN
, 0x0105 },
568 { MT9M114_CAM_AWB_CCM_R_RG_GAIN
, 0x00a4 },
569 { MT9M114_CAM_AWB_CCM_R_BG_GAIN
, 0x00ac },
570 { MT9M114_CAM_AWB_CCM_L_CTEMP
, 0x0a8c },
571 { MT9M114_CAM_AWB_CCM_M_CTEMP
, 0x0f0a },
572 { MT9M114_CAM_AWB_CCM_R_CTEMP
, 0x1964 },
573 { MT9M114_CAM_AWB_AWB_XSHIFT_PRE_ADJ
, 51 },
574 { MT9M114_CAM_AWB_AWB_YSHIFT_PRE_ADJ
, 60 },
575 { MT9M114_CAM_AWB_AWB_XSCALE
, 3 },
576 { MT9M114_CAM_AWB_AWB_YSCALE
, 2 },
577 { MT9M114_CAM_AWB_AWB_WEIGHTS(0), 0x0000 },
578 { MT9M114_CAM_AWB_AWB_WEIGHTS(1), 0x0000 },
579 { MT9M114_CAM_AWB_AWB_WEIGHTS(2), 0x0000 },
580 { MT9M114_CAM_AWB_AWB_WEIGHTS(3), 0xe724 },
581 { MT9M114_CAM_AWB_AWB_WEIGHTS(4), 0x1583 },
582 { MT9M114_CAM_AWB_AWB_WEIGHTS(5), 0x2045 },
583 { MT9M114_CAM_AWB_AWB_WEIGHTS(6), 0x03ff },
584 { MT9M114_CAM_AWB_AWB_WEIGHTS(7), 0x007c },
585 { MT9M114_CAM_AWB_K_R_L
, 0x80 },
586 { MT9M114_CAM_AWB_K_G_L
, 0x80 },
587 { MT9M114_CAM_AWB_K_B_L
, 0x80 },
588 { MT9M114_CAM_AWB_K_R_R
, 0x88 },
589 { MT9M114_CAM_AWB_K_G_R
, 0x80 },
590 { MT9M114_CAM_AWB_K_B_R
, 0x80 },
592 /* Low-Light Image Enhancements */
593 { MT9M114_CAM_LL_START_BRIGHTNESS
, 0x0020 },
594 { MT9M114_CAM_LL_STOP_BRIGHTNESS
, 0x009a },
595 { MT9M114_CAM_LL_START_GAIN_METRIC
, 0x0070 },
596 { MT9M114_CAM_LL_STOP_GAIN_METRIC
, 0x00f3 },
597 { MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE
, 0x20 },
598 { MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE
, 0x9a },
599 { MT9M114_CAM_LL_START_SATURATION
, 0x80 },
600 { MT9M114_CAM_LL_END_SATURATION
, 0x4b },
601 { MT9M114_CAM_LL_START_DESATURATION
, 0x00 },
602 { MT9M114_CAM_LL_END_DESATURATION
, 0xff },
603 { MT9M114_CAM_LL_START_DEMOSAICING
, 0x3c },
604 { MT9M114_CAM_LL_START_AP_GAIN
, 0x02 },
605 { MT9M114_CAM_LL_START_AP_THRESH
, 0x06 },
606 { MT9M114_CAM_LL_STOP_DEMOSAICING
, 0x64 },
607 { MT9M114_CAM_LL_STOP_AP_GAIN
, 0x01 },
608 { MT9M114_CAM_LL_STOP_AP_THRESH
, 0x0c },
609 { MT9M114_CAM_LL_START_NR_RED
, 0x3c },
610 { MT9M114_CAM_LL_START_NR_GREEN
, 0x3c },
611 { MT9M114_CAM_LL_START_NR_BLUE
, 0x3c },
612 { MT9M114_CAM_LL_START_NR_THRESH
, 0x0f },
613 { MT9M114_CAM_LL_STOP_NR_RED
, 0x64 },
614 { MT9M114_CAM_LL_STOP_NR_GREEN
, 0x64 },
615 { MT9M114_CAM_LL_STOP_NR_BLUE
, 0x64 },
616 { MT9M114_CAM_LL_STOP_NR_THRESH
, 0x32 },
617 { MT9M114_CAM_LL_START_CONTRAST_BM
, 0x0020 },
618 { MT9M114_CAM_LL_STOP_CONTRAST_BM
, 0x009a },
619 { MT9M114_CAM_LL_GAMMA
, 0x00dc },
620 { MT9M114_CAM_LL_START_CONTRAST_GRADIENT
, 0x38 },
621 { MT9M114_CAM_LL_STOP_CONTRAST_GRADIENT
, 0x30 },
622 { MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE
, 0x50 },
623 { MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE
, 0x19 },
624 { MT9M114_CAM_LL_START_FADE_TO_BLACK_LUMA
, 0x0230 },
625 { MT9M114_CAM_LL_STOP_FADE_TO_BLACK_LUMA
, 0x0010 },
626 { MT9M114_CAM_LL_CLUSTER_DC_TH_BM
, 0x01cd },
627 { MT9M114_CAM_LL_CLUSTER_DC_GATE_PERCENTAGE
, 0x05 },
628 { MT9M114_CAM_LL_SUMMING_SENSITIVITY_FACTOR
, 0x40 },
631 { MT9M114_CAM_AET_TARGET_AVERAGE_LUMA_DARK
, 0x1b },
632 { MT9M114_CAM_AET_AEMODE
, 0x00 },
633 { MT9M114_CAM_AET_TARGET_GAIN
, 0x0080 },
634 { MT9M114_CAM_AET_AE_MAX_VIRT_AGAIN
, 0x0100 },
635 { MT9M114_CAM_AET_BLACK_CLIPPING_TARGET
, 0x005a },
637 { MT9M114_CCM_DELTA_GAIN
, 0x05 },
638 { MT9M114_AE_TRACK_AE_TRACKING_DAMPENING_SPEED
, 0x20 },
640 /* Pixel array timings and integration time */
641 { MT9M114_CAM_SENSOR_CFG_ROW_SPEED
, 1 },
642 { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN
, 219 },
643 { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX
, 1459 },
644 { MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION
, 96 },
645 { MT9M114_CAM_SENSOR_CFG_REG_0_DATA
, 32 },
647 /* Miscellaneous settings */
648 { MT9M114_PAD_SLEW
, 0x0777 },
651 /* -----------------------------------------------------------------------------
652 * Hardware Configuration
655 /* Wait for a command to complete. */
656 static int mt9m114_poll_command(struct mt9m114
*sensor
, u32 command
)
662 for (i
= 0; i
< 100; ++i
) {
663 ret
= cci_read(sensor
->regmap
, MT9M114_COMMAND_REGISTER
, &value
,
668 if (!(value
& command
))
671 usleep_range(5000, 6000);
674 if (value
& command
) {
675 dev_err(&sensor
->client
->dev
, "Command %u completion timeout\n",
680 if (!(value
& MT9M114_COMMAND_REGISTER_OK
)) {
681 dev_err(&sensor
->client
->dev
, "Command %u failed\n", command
);
688 /* Wait for a state to be entered. */
689 static int mt9m114_poll_state(struct mt9m114
*sensor
, u32 state
)
695 for (i
= 0; i
< 100; ++i
) {
696 ret
= cci_read(sensor
->regmap
, MT9M114_SYSMGR_CURRENT_STATE
,
704 usleep_range(1000, 1500);
707 dev_err(&sensor
->client
->dev
, "Timeout waiting for state 0x%02x\n",
712 static int mt9m114_set_state(struct mt9m114
*sensor
, u8 next_state
)
716 /* Set the next desired state and start the state transition. */
717 cci_write(sensor
->regmap
, MT9M114_SYSMGR_NEXT_STATE
, next_state
, &ret
);
718 cci_write(sensor
->regmap
, MT9M114_COMMAND_REGISTER
,
719 MT9M114_COMMAND_REGISTER_OK
|
720 MT9M114_COMMAND_REGISTER_SET_STATE
, &ret
);
724 /* Wait for the state transition to complete. */
725 ret
= mt9m114_poll_command(sensor
, MT9M114_COMMAND_REGISTER_SET_STATE
);
732 static int mt9m114_initialize(struct mt9m114
*sensor
)
737 ret
= cci_multi_reg_write(sensor
->regmap
, mt9m114_init
,
738 ARRAY_SIZE(mt9m114_init
), NULL
);
740 dev_err(&sensor
->client
->dev
,
741 "Failed to initialize the sensor\n");
745 /* Configure the PLL. */
746 cci_write(sensor
->regmap
, MT9M114_CAM_SYSCTL_PLL_ENABLE
,
747 MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE
, &ret
);
748 cci_write(sensor
->regmap
, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N
,
749 MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor
->pll
.m
,
752 cci_write(sensor
->regmap
, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P
,
753 MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor
->pll
.p
), &ret
);
754 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_PIXCLK
,
755 sensor
->pixrate
, &ret
);
757 /* Configure the output mode. */
758 if (sensor
->bus_cfg
.bus_type
== V4L2_MBUS_CSI2_DPHY
) {
759 value
= MT9M114_CAM_PORT_PORT_SELECT_MIPI
760 | MT9M114_CAM_PORT_CHAN_NUM(0)
762 if (!(sensor
->bus_cfg
.bus
.mipi_csi2
.flags
&
763 V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK
))
764 value
|= MT9M114_CAM_PORT_CONT_MIPI_CLK
;
766 value
= MT9M114_CAM_PORT_PORT_SELECT_PARALLEL
769 cci_write(sensor
->regmap
, MT9M114_CAM_PORT_OUTPUT_CONTROL
, value
, &ret
);
773 ret
= mt9m114_set_state(sensor
, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE
);
777 ret
= mt9m114_set_state(sensor
, MT9M114_SYS_STATE_ENTER_SUSPEND
);
784 static int mt9m114_configure(struct mt9m114
*sensor
,
785 struct v4l2_subdev_state
*pa_state
,
786 struct v4l2_subdev_state
*ifp_state
)
788 const struct v4l2_mbus_framefmt
*pa_format
;
789 const struct v4l2_rect
*pa_crop
;
790 const struct mt9m114_format_info
*ifp_info
;
791 const struct v4l2_mbus_framefmt
*ifp_format
;
792 const struct v4l2_rect
*ifp_crop
;
793 const struct v4l2_rect
*ifp_compose
;
794 unsigned int hratio
, vratio
;
799 pa_format
= v4l2_subdev_state_get_format(pa_state
, 0);
800 pa_crop
= v4l2_subdev_state_get_crop(pa_state
, 0);
802 ifp_format
= v4l2_subdev_state_get_format(ifp_state
, 1);
803 ifp_info
= mt9m114_format_info(sensor
, 1, ifp_format
->code
);
804 ifp_crop
= v4l2_subdev_state_get_crop(ifp_state
, 0);
805 ifp_compose
= v4l2_subdev_state_get_compose(ifp_state
, 0);
807 ret
= cci_read(sensor
->regmap
, MT9M114_CAM_SENSOR_CONTROL_READ_MODE
,
812 ret
= cci_read(sensor
->regmap
, MT9M114_CAM_OUTPUT_FORMAT
,
813 &output_format
, NULL
);
817 hratio
= pa_crop
->width
/ pa_format
->width
;
818 vratio
= pa_crop
->height
/ pa_format
->height
;
821 * Pixel array crop and binning. The CAM_SENSOR_CFG_CPIPE_LAST_ROW
822 * register isn't clearly documented, but is always set to the number
823 * of active rows minus 4 divided by the vertical binning factor in all
824 * example sensor modes.
826 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_X_ADDR_START
,
827 pa_crop
->left
, &ret
);
828 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START
,
830 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_X_ADDR_END
,
831 pa_crop
->width
+ pa_crop
->left
- 1, &ret
);
832 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END
,
833 pa_crop
->height
+ pa_crop
->top
- 1, &ret
);
834 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW
,
835 (pa_crop
->height
- 4) / vratio
- 1, &ret
);
837 read_mode
&= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK
|
838 MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK
);
841 read_mode
|= MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SUMMING
;
843 read_mode
|= MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SUMMING
;
845 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CONTROL_READ_MODE
,
849 * Color pipeline (IFP) cropping and scaling. Subtract 4 from the left
850 * and top coordinates to compensate for the lines and columns removed
851 * by demosaicing that are taken into account in the crop rectangle but
852 * not in the hardware.
854 cci_write(sensor
->regmap
, MT9M114_CAM_CROP_WINDOW_XOFFSET
,
855 ifp_crop
->left
- 4, &ret
);
856 cci_write(sensor
->regmap
, MT9M114_CAM_CROP_WINDOW_YOFFSET
,
857 ifp_crop
->top
- 4, &ret
);
858 cci_write(sensor
->regmap
, MT9M114_CAM_CROP_WINDOW_WIDTH
,
859 ifp_crop
->width
, &ret
);
860 cci_write(sensor
->regmap
, MT9M114_CAM_CROP_WINDOW_HEIGHT
,
861 ifp_crop
->height
, &ret
);
863 cci_write(sensor
->regmap
, MT9M114_CAM_OUTPUT_WIDTH
,
864 ifp_compose
->width
, &ret
);
865 cci_write(sensor
->regmap
, MT9M114_CAM_OUTPUT_HEIGHT
,
866 ifp_compose
->height
, &ret
);
868 /* AWB and AE windows, use the full frame. */
869 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART
,
871 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART
,
873 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND
,
874 ifp_compose
->width
- 1, &ret
);
875 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND
,
876 ifp_compose
->height
- 1, &ret
);
878 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART
,
880 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART
,
882 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND
,
883 ifp_compose
->width
/ 5 - 1, &ret
);
884 cci_write(sensor
->regmap
, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND
,
885 ifp_compose
->height
/ 5 - 1, &ret
);
887 cci_write(sensor
->regmap
, MT9M114_CAM_CROP_CROPMODE
,
888 MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN
|
889 MT9M114_CAM_CROP_MODE_AE_AUTO_CROP_EN
, &ret
);
891 /* Set the media bus code. */
892 output_format
&= ~(MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_MASK
|
893 MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_MASK
|
894 MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK
|
895 MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES
|
896 MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE
);
897 output_format
|= ifp_info
->output_format
;
899 cci_write(sensor
->regmap
, MT9M114_CAM_OUTPUT_FORMAT
,
900 output_format
, &ret
);
905 static int mt9m114_set_frame_rate(struct mt9m114
*sensor
)
907 u16 frame_rate
= sensor
->ifp
.frame_rate
<< 8;
910 cci_write(sensor
->regmap
, MT9M114_CAM_AET_MIN_FRAME_RATE
,
912 cci_write(sensor
->regmap
, MT9M114_CAM_AET_MAX_FRAME_RATE
,
918 static int mt9m114_start_streaming(struct mt9m114
*sensor
,
919 struct v4l2_subdev_state
*pa_state
,
920 struct v4l2_subdev_state
*ifp_state
)
924 ret
= pm_runtime_resume_and_get(&sensor
->client
->dev
);
928 ret
= mt9m114_configure(sensor
, pa_state
, ifp_state
);
932 ret
= mt9m114_set_frame_rate(sensor
);
936 ret
= __v4l2_ctrl_handler_setup(&sensor
->pa
.hdl
);
940 ret
= __v4l2_ctrl_handler_setup(&sensor
->ifp
.hdl
);
945 * The Change-Config state is transient and moves to the streaming
946 * state automatically.
948 ret
= mt9m114_set_state(sensor
, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE
);
952 sensor
->streaming
= true;
957 pm_runtime_mark_last_busy(&sensor
->client
->dev
);
958 pm_runtime_put_autosuspend(&sensor
->client
->dev
);
963 static int mt9m114_stop_streaming(struct mt9m114
*sensor
)
967 sensor
->streaming
= false;
969 ret
= mt9m114_set_state(sensor
, MT9M114_SYS_STATE_ENTER_SUSPEND
);
971 pm_runtime_mark_last_busy(&sensor
->client
->dev
);
972 pm_runtime_put_autosuspend(&sensor
->client
->dev
);
977 /* -----------------------------------------------------------------------------
978 * Common Subdev Operations
981 static const struct media_entity_operations mt9m114_entity_ops
= {
982 .link_validate
= v4l2_subdev_link_validate
,
985 /* -----------------------------------------------------------------------------
986 * Pixel Array Control Operations
989 static inline struct mt9m114
*pa_ctrl_to_mt9m114(struct v4l2_ctrl
*ctrl
)
991 return container_of(ctrl
->handler
, struct mt9m114
, pa
.hdl
);
994 static int mt9m114_pa_g_ctrl(struct v4l2_ctrl
*ctrl
)
996 struct mt9m114
*sensor
= pa_ctrl_to_mt9m114(ctrl
);
1000 if (!pm_runtime_get_if_in_use(&sensor
->client
->dev
))
1004 case V4L2_CID_EXPOSURE
:
1005 ret
= cci_read(sensor
->regmap
,
1006 MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME
,
1014 case V4L2_CID_ANALOGUE_GAIN
:
1015 ret
= cci_read(sensor
->regmap
,
1016 MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN
,
1029 pm_runtime_mark_last_busy(&sensor
->client
->dev
);
1030 pm_runtime_put_autosuspend(&sensor
->client
->dev
);
1035 static int mt9m114_pa_s_ctrl(struct v4l2_ctrl
*ctrl
)
1037 struct mt9m114
*sensor
= pa_ctrl_to_mt9m114(ctrl
);
1038 const struct v4l2_mbus_framefmt
*format
;
1039 struct v4l2_subdev_state
*state
;
1043 /* V4L2 controls values are applied only when power is up. */
1044 if (!pm_runtime_get_if_in_use(&sensor
->client
->dev
))
1047 state
= v4l2_subdev_get_locked_active_state(&sensor
->pa
.sd
);
1048 format
= v4l2_subdev_state_get_format(state
, 0);
1051 case V4L2_CID_HBLANK
:
1052 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK
,
1053 ctrl
->val
+ format
->width
, &ret
);
1056 case V4L2_CID_VBLANK
:
1057 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES
,
1058 ctrl
->val
+ format
->height
, &ret
);
1061 case V4L2_CID_EXPOSURE
:
1062 cci_write(sensor
->regmap
,
1063 MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME
,
1067 case V4L2_CID_ANALOGUE_GAIN
:
1069 * The CAM_SENSOR_CONTROL_ANALOG_GAIN contains linear analog
1070 * gain values that are mapped to the GLOBAL_GAIN register
1071 * values by the sensor firmware.
1073 cci_write(sensor
->regmap
, MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN
,
1077 case V4L2_CID_HFLIP
:
1078 mask
= MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN
;
1079 ret
= cci_update_bits(sensor
->regmap
,
1080 MT9M114_CAM_SENSOR_CONTROL_READ_MODE
,
1081 mask
, ctrl
->val
? mask
: 0, NULL
);
1084 case V4L2_CID_VFLIP
:
1085 mask
= MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN
;
1086 ret
= cci_update_bits(sensor
->regmap
,
1087 MT9M114_CAM_SENSOR_CONTROL_READ_MODE
,
1088 mask
, ctrl
->val
? mask
: 0, NULL
);
1096 pm_runtime_mark_last_busy(&sensor
->client
->dev
);
1097 pm_runtime_put_autosuspend(&sensor
->client
->dev
);
1102 static const struct v4l2_ctrl_ops mt9m114_pa_ctrl_ops
= {
1103 .g_volatile_ctrl
= mt9m114_pa_g_ctrl
,
1104 .s_ctrl
= mt9m114_pa_s_ctrl
,
1107 static void mt9m114_pa_ctrl_update_exposure(struct mt9m114
*sensor
, bool manual
)
1110 * Update the volatile flag on the manual exposure and gain controls.
1111 * If the controls have switched to manual, read their current value
1112 * from the hardware to ensure that control read and write operations
1113 * will behave correctly
1116 mt9m114_pa_g_ctrl(sensor
->pa
.exposure
);
1117 sensor
->pa
.exposure
->cur
.val
= sensor
->pa
.exposure
->val
;
1118 sensor
->pa
.exposure
->flags
&= ~V4L2_CTRL_FLAG_VOLATILE
;
1120 mt9m114_pa_g_ctrl(sensor
->pa
.gain
);
1121 sensor
->pa
.gain
->cur
.val
= sensor
->pa
.gain
->val
;
1122 sensor
->pa
.gain
->flags
&= ~V4L2_CTRL_FLAG_VOLATILE
;
1124 sensor
->pa
.exposure
->flags
|= V4L2_CTRL_FLAG_VOLATILE
;
1125 sensor
->pa
.gain
->flags
|= V4L2_CTRL_FLAG_VOLATILE
;
1129 static void mt9m114_pa_ctrl_update_blanking(struct mt9m114
*sensor
,
1130 const struct v4l2_mbus_framefmt
*format
)
1132 unsigned int max_blank
;
1134 /* Update the blanking controls ranges based on the output size. */
1135 max_blank
= MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK_MAX
1137 __v4l2_ctrl_modify_range(sensor
->pa
.hblank
, MT9M114_MIN_HBLANK
,
1138 max_blank
, 1, MT9M114_DEF_HBLANK
);
1140 max_blank
= MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES_MAX
1142 __v4l2_ctrl_modify_range(sensor
->pa
.vblank
, MT9M114_MIN_VBLANK
,
1143 max_blank
, 1, MT9M114_DEF_VBLANK
);
1146 /* -----------------------------------------------------------------------------
1147 * Pixel Array Subdev Operations
1150 static inline struct mt9m114
*pa_to_mt9m114(struct v4l2_subdev
*sd
)
1152 return container_of(sd
, struct mt9m114
, pa
.sd
);
1155 static int mt9m114_pa_init_state(struct v4l2_subdev
*sd
,
1156 struct v4l2_subdev_state
*state
)
1158 struct v4l2_mbus_framefmt
*format
;
1159 struct v4l2_rect
*crop
;
1161 crop
= v4l2_subdev_state_get_crop(state
, 0);
1165 crop
->width
= MT9M114_PIXEL_ARRAY_WIDTH
;
1166 crop
->height
= MT9M114_PIXEL_ARRAY_HEIGHT
;
1168 format
= v4l2_subdev_state_get_format(state
, 0);
1170 format
->width
= MT9M114_PIXEL_ARRAY_WIDTH
;
1171 format
->height
= MT9M114_PIXEL_ARRAY_HEIGHT
;
1172 format
->code
= MEDIA_BUS_FMT_SGRBG10_1X10
;
1173 format
->field
= V4L2_FIELD_NONE
;
1174 format
->colorspace
= V4L2_COLORSPACE_RAW
;
1175 format
->ycbcr_enc
= V4L2_YCBCR_ENC_601
;
1176 format
->quantization
= V4L2_QUANTIZATION_FULL_RANGE
;
1177 format
->xfer_func
= V4L2_XFER_FUNC_NONE
;
1182 static int mt9m114_pa_enum_mbus_code(struct v4l2_subdev
*sd
,
1183 struct v4l2_subdev_state
*state
,
1184 struct v4l2_subdev_mbus_code_enum
*code
)
1186 if (code
->index
> 0)
1189 code
->code
= MEDIA_BUS_FMT_SGRBG10_1X10
;
1194 static int mt9m114_pa_enum_framesizes(struct v4l2_subdev
*sd
,
1195 struct v4l2_subdev_state
*state
,
1196 struct v4l2_subdev_frame_size_enum
*fse
)
1201 if (fse
->code
!= MEDIA_BUS_FMT_SGRBG10_1X10
)
1204 /* Report binning capability through frame size enumeration. */
1205 fse
->min_width
= MT9M114_PIXEL_ARRAY_WIDTH
/ (fse
->index
+ 1);
1206 fse
->max_width
= MT9M114_PIXEL_ARRAY_WIDTH
/ (fse
->index
+ 1);
1207 fse
->min_height
= MT9M114_PIXEL_ARRAY_HEIGHT
/ (fse
->index
+ 1);
1208 fse
->max_height
= MT9M114_PIXEL_ARRAY_HEIGHT
/ (fse
->index
+ 1);
1213 static int mt9m114_pa_set_fmt(struct v4l2_subdev
*sd
,
1214 struct v4l2_subdev_state
*state
,
1215 struct v4l2_subdev_format
*fmt
)
1217 struct mt9m114
*sensor
= pa_to_mt9m114(sd
);
1218 struct v4l2_mbus_framefmt
*format
;
1219 struct v4l2_rect
*crop
;
1220 unsigned int hscale
;
1221 unsigned int vscale
;
1223 crop
= v4l2_subdev_state_get_crop(state
, fmt
->pad
);
1224 format
= v4l2_subdev_state_get_format(state
, fmt
->pad
);
1226 /* The sensor can bin horizontally and vertically. */
1227 hscale
= DIV_ROUND_CLOSEST(crop
->width
, fmt
->format
.width
? : 1);
1228 vscale
= DIV_ROUND_CLOSEST(crop
->height
, fmt
->format
.height
? : 1);
1229 format
->width
= crop
->width
/ clamp(hscale
, 1U, 2U);
1230 format
->height
= crop
->height
/ clamp(vscale
, 1U, 2U);
1232 fmt
->format
= *format
;
1234 if (fmt
->which
== V4L2_SUBDEV_FORMAT_ACTIVE
)
1235 mt9m114_pa_ctrl_update_blanking(sensor
, format
);
1240 static int mt9m114_pa_get_selection(struct v4l2_subdev
*sd
,
1241 struct v4l2_subdev_state
*state
,
1242 struct v4l2_subdev_selection
*sel
)
1244 switch (sel
->target
) {
1245 case V4L2_SEL_TGT_CROP
:
1246 sel
->r
= *v4l2_subdev_state_get_crop(state
, sel
->pad
);
1249 case V4L2_SEL_TGT_CROP_DEFAULT
:
1250 case V4L2_SEL_TGT_CROP_BOUNDS
:
1251 case V4L2_SEL_TGT_NATIVE_SIZE
:
1254 sel
->r
.width
= MT9M114_PIXEL_ARRAY_WIDTH
;
1255 sel
->r
.height
= MT9M114_PIXEL_ARRAY_HEIGHT
;
1263 static int mt9m114_pa_set_selection(struct v4l2_subdev
*sd
,
1264 struct v4l2_subdev_state
*state
,
1265 struct v4l2_subdev_selection
*sel
)
1267 struct mt9m114
*sensor
= pa_to_mt9m114(sd
);
1268 struct v4l2_mbus_framefmt
*format
;
1269 struct v4l2_rect
*crop
;
1271 if (sel
->target
!= V4L2_SEL_TGT_CROP
)
1274 crop
= v4l2_subdev_state_get_crop(state
, sel
->pad
);
1275 format
= v4l2_subdev_state_get_format(state
, sel
->pad
);
1278 * Clamp the crop rectangle. The vertical coordinates must be even, and
1279 * the horizontal coordinates must be a multiple of 4.
1281 * FIXME: The horizontal coordinates must be a multiple of 8 when
1282 * binning, but binning is configured after setting the selection, so
1283 * we can't know tell here if it will be used.
1285 crop
->left
= ALIGN(sel
->r
.left
, 4);
1286 crop
->top
= ALIGN(sel
->r
.top
, 2);
1287 crop
->width
= clamp_t(unsigned int, ALIGN(sel
->r
.width
, 4),
1288 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH
,
1289 MT9M114_PIXEL_ARRAY_WIDTH
- crop
->left
);
1290 crop
->height
= clamp_t(unsigned int, ALIGN(sel
->r
.height
, 2),
1291 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT
,
1292 MT9M114_PIXEL_ARRAY_HEIGHT
- crop
->top
);
1296 /* Reset the format. */
1297 format
->width
= crop
->width
;
1298 format
->height
= crop
->height
;
1300 if (sel
->which
== V4L2_SUBDEV_FORMAT_ACTIVE
)
1301 mt9m114_pa_ctrl_update_blanking(sensor
, format
);
1306 static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops
= {
1307 .enum_mbus_code
= mt9m114_pa_enum_mbus_code
,
1308 .enum_frame_size
= mt9m114_pa_enum_framesizes
,
1309 .get_fmt
= v4l2_subdev_get_fmt
,
1310 .set_fmt
= mt9m114_pa_set_fmt
,
1311 .get_selection
= mt9m114_pa_get_selection
,
1312 .set_selection
= mt9m114_pa_set_selection
,
1315 static const struct v4l2_subdev_ops mt9m114_pa_ops
= {
1316 .pad
= &mt9m114_pa_pad_ops
,
1319 static const struct v4l2_subdev_internal_ops mt9m114_pa_internal_ops
= {
1320 .init_state
= mt9m114_pa_init_state
,
1323 static int mt9m114_pa_init(struct mt9m114
*sensor
)
1325 struct v4l2_ctrl_handler
*hdl
= &sensor
->pa
.hdl
;
1326 struct v4l2_subdev
*sd
= &sensor
->pa
.sd
;
1327 struct media_pad
*pads
= &sensor
->pa
.pad
;
1328 const struct v4l2_mbus_framefmt
*format
;
1329 struct v4l2_subdev_state
*state
;
1330 unsigned int max_exposure
;
1333 /* Initialize the subdev. */
1334 v4l2_subdev_init(sd
, &mt9m114_pa_ops
);
1335 sd
->internal_ops
= &mt9m114_pa_internal_ops
;
1336 v4l2_i2c_subdev_set_name(sd
, sensor
->client
, NULL
, " pixel array");
1338 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
1339 sd
->owner
= THIS_MODULE
;
1340 sd
->dev
= &sensor
->client
->dev
;
1341 v4l2_set_subdevdata(sd
, sensor
->client
);
1343 /* Initialize the media entity. */
1344 sd
->entity
.function
= MEDIA_ENT_F_CAM_SENSOR
;
1345 sd
->entity
.ops
= &mt9m114_entity_ops
;
1346 pads
[0].flags
= MEDIA_PAD_FL_SOURCE
;
1347 ret
= media_entity_pads_init(&sd
->entity
, 1, pads
);
1351 /* Initialize the control handler. */
1352 v4l2_ctrl_handler_init(hdl
, 7);
1354 /* The range of the HBLANK and VBLANK controls will be updated below. */
1355 sensor
->pa
.hblank
= v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1358 MT9M114_DEF_HBLANK
, 1,
1359 MT9M114_DEF_HBLANK
);
1360 sensor
->pa
.vblank
= v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1363 MT9M114_DEF_VBLANK
, 1,
1364 MT9M114_DEF_VBLANK
);
1367 * The maximum coarse integration time is the frame length in lines
1368 * minus two. The default is taken directly from the datasheet, but
1369 * makes little sense as auto-exposure is enabled by default.
1371 max_exposure
= MT9M114_PIXEL_ARRAY_HEIGHT
+ MT9M114_MIN_VBLANK
- 2;
1372 sensor
->pa
.exposure
= v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1373 V4L2_CID_EXPOSURE
, 1,
1374 max_exposure
, 1, 16);
1375 if (sensor
->pa
.exposure
)
1376 sensor
->pa
.exposure
->flags
|= V4L2_CTRL_FLAG_VOLATILE
;
1378 sensor
->pa
.gain
= v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1379 V4L2_CID_ANALOGUE_GAIN
, 1,
1381 if (sensor
->pa
.gain
)
1382 sensor
->pa
.gain
->flags
|= V4L2_CTRL_FLAG_VOLATILE
;
1384 v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1385 V4L2_CID_PIXEL_RATE
,
1386 sensor
->pixrate
, sensor
->pixrate
, 1,
1389 v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1392 v4l2_ctrl_new_std(hdl
, &mt9m114_pa_ctrl_ops
,
1401 sd
->state_lock
= hdl
->lock
;
1403 ret
= v4l2_subdev_init_finalize(sd
);
1407 /* Update the range of the blanking controls based on the format. */
1408 state
= v4l2_subdev_lock_and_get_active_state(sd
);
1409 format
= v4l2_subdev_state_get_format(state
, 0);
1410 mt9m114_pa_ctrl_update_blanking(sensor
, format
);
1411 v4l2_subdev_unlock_state(state
);
1413 sd
->ctrl_handler
= hdl
;
1418 v4l2_ctrl_handler_free(&sensor
->pa
.hdl
);
1419 media_entity_cleanup(&sensor
->pa
.sd
.entity
);
1423 static void mt9m114_pa_cleanup(struct mt9m114
*sensor
)
1425 v4l2_ctrl_handler_free(&sensor
->pa
.hdl
);
1426 media_entity_cleanup(&sensor
->pa
.sd
.entity
);
1429 /* -----------------------------------------------------------------------------
1430 * Image Flow Processor Control Operations
1433 static const char * const mt9m114_test_pattern_menu
[] = {
1438 "Fade-to-Gray Color Bars",
1439 "Walking Ones 10-bit",
1440 "Walking Ones 8-bit",
1443 /* Keep in sync with mt9m114_test_pattern_menu */
1444 static const unsigned int mt9m114_test_pattern_value
[] = {
1445 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID
,
1446 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID_BARS
,
1447 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_RANDOM
,
1448 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_FADING_BARS
,
1449 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_10B
,
1450 MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_8B
,
1453 static inline struct mt9m114
*ifp_ctrl_to_mt9m114(struct v4l2_ctrl
*ctrl
)
1455 return container_of(ctrl
->handler
, struct mt9m114
, ifp
.hdl
);
1458 static int mt9m114_ifp_s_ctrl(struct v4l2_ctrl
*ctrl
)
1460 struct mt9m114
*sensor
= ifp_ctrl_to_mt9m114(ctrl
);
1464 if (ctrl
->id
== V4L2_CID_EXPOSURE_AUTO
)
1465 mt9m114_pa_ctrl_update_exposure(sensor
,
1466 ctrl
->val
!= V4L2_EXPOSURE_AUTO
);
1468 /* V4L2 controls values are applied only when power is up. */
1469 if (!pm_runtime_get_if_in_use(&sensor
->client
->dev
))
1473 case V4L2_CID_AUTO_WHITE_BALANCE
:
1474 /* Control both the AWB mode and the CCM algorithm. */
1476 value
= MT9M114_CAM_AWB_MODE_AUTO
1477 | MT9M114_CAM_AWB_MODE_EXCLUSIVE_AE
;
1481 cci_write(sensor
->regmap
, MT9M114_CAM_AWB_AWBMODE
, value
, &ret
);
1484 value
= MT9M114_CCM_EXEC_CALC_CCM_MATRIX
| 0x22;
1488 cci_write(sensor
->regmap
, MT9M114_CCM_ALGO
, value
, &ret
);
1491 case V4L2_CID_EXPOSURE_AUTO
:
1492 if (ctrl
->val
== V4L2_EXPOSURE_AUTO
)
1493 value
= MT9M114_AE_TRACK_EXEC_AUTOMATIC_EXPOSURE
1498 cci_write(sensor
->regmap
, MT9M114_AE_TRACK_ALGO
, value
, &ret
);
1504 case V4L2_CID_TEST_PATTERN
:
1505 case V4L2_CID_TEST_PATTERN_RED
:
1506 case V4L2_CID_TEST_PATTERN_GREENR
:
1507 case V4L2_CID_TEST_PATTERN_BLUE
: {
1508 unsigned int pattern
= sensor
->ifp
.tpg
[MT9M114_TPG_PATTERN
]->val
;
1511 cci_write(sensor
->regmap
, MT9M114_CAM_MODE_SELECT
,
1512 MT9M114_CAM_MODE_SELECT_TEST_PATTERN
, &ret
);
1513 cci_write(sensor
->regmap
,
1514 MT9M114_CAM_MODE_TEST_PATTERN_SELECT
,
1515 mt9m114_test_pattern_value
[pattern
- 1], &ret
);
1516 cci_write(sensor
->regmap
,
1517 MT9M114_CAM_MODE_TEST_PATTERN_RED
,
1518 sensor
->ifp
.tpg
[MT9M114_TPG_RED
]->val
, &ret
);
1519 cci_write(sensor
->regmap
,
1520 MT9M114_CAM_MODE_TEST_PATTERN_GREEN
,
1521 sensor
->ifp
.tpg
[MT9M114_TPG_GREEN
]->val
, &ret
);
1522 cci_write(sensor
->regmap
,
1523 MT9M114_CAM_MODE_TEST_PATTERN_BLUE
,
1524 sensor
->ifp
.tpg
[MT9M114_TPG_BLUE
]->val
, &ret
);
1526 cci_write(sensor
->regmap
, MT9M114_CAM_MODE_SELECT
,
1527 MT9M114_CAM_MODE_SELECT_NORMAL
, &ret
);
1531 * A Config-Change needs to be issued for the change to take
1532 * effect. If we're not streaming ignore this, the change will
1533 * be applied when the stream is started.
1535 if (ret
|| !sensor
->streaming
)
1538 ret
= mt9m114_set_state(sensor
,
1539 MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE
);
1548 pm_runtime_mark_last_busy(&sensor
->client
->dev
);
1549 pm_runtime_put_autosuspend(&sensor
->client
->dev
);
1554 static const struct v4l2_ctrl_ops mt9m114_ifp_ctrl_ops
= {
1555 .s_ctrl
= mt9m114_ifp_s_ctrl
,
1558 /* -----------------------------------------------------------------------------
1559 * Image Flow Processor Subdev Operations
1562 static inline struct mt9m114
*ifp_to_mt9m114(struct v4l2_subdev
*sd
)
1564 return container_of(sd
, struct mt9m114
, ifp
.sd
);
1567 static int mt9m114_ifp_s_stream(struct v4l2_subdev
*sd
, int enable
)
1569 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1570 struct v4l2_subdev_state
*pa_state
;
1571 struct v4l2_subdev_state
*ifp_state
;
1575 return mt9m114_stop_streaming(sensor
);
1577 ifp_state
= v4l2_subdev_lock_and_get_active_state(&sensor
->ifp
.sd
);
1578 pa_state
= v4l2_subdev_lock_and_get_active_state(&sensor
->pa
.sd
);
1580 ret
= mt9m114_start_streaming(sensor
, pa_state
, ifp_state
);
1582 v4l2_subdev_unlock_state(pa_state
);
1583 v4l2_subdev_unlock_state(ifp_state
);
1588 static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev
*sd
,
1589 struct v4l2_subdev_state
*sd_state
,
1590 struct v4l2_subdev_frame_interval
*interval
)
1592 struct v4l2_fract
*ival
= &interval
->interval
;
1593 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1596 * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
1597 * subdev active state API.
1599 if (interval
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
1602 mutex_lock(sensor
->ifp
.hdl
.lock
);
1604 ival
->numerator
= 1;
1605 ival
->denominator
= sensor
->ifp
.frame_rate
;
1607 mutex_unlock(sensor
->ifp
.hdl
.lock
);
1612 static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev
*sd
,
1613 struct v4l2_subdev_state
*sd_state
,
1614 struct v4l2_subdev_frame_interval
*interval
)
1616 struct v4l2_fract
*ival
= &interval
->interval
;
1617 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1621 * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2
1622 * subdev active state API.
1624 if (interval
->which
!= V4L2_SUBDEV_FORMAT_ACTIVE
)
1627 mutex_lock(sensor
->ifp
.hdl
.lock
);
1629 if (ival
->numerator
!= 0 && ival
->denominator
!= 0)
1630 sensor
->ifp
.frame_rate
= min_t(unsigned int,
1631 ival
->denominator
/ ival
->numerator
,
1632 MT9M114_MAX_FRAME_RATE
);
1634 sensor
->ifp
.frame_rate
= MT9M114_MAX_FRAME_RATE
;
1636 ival
->numerator
= 1;
1637 ival
->denominator
= sensor
->ifp
.frame_rate
;
1639 if (sensor
->streaming
)
1640 ret
= mt9m114_set_frame_rate(sensor
);
1642 mutex_unlock(sensor
->ifp
.hdl
.lock
);
1647 static int mt9m114_ifp_init_state(struct v4l2_subdev
*sd
,
1648 struct v4l2_subdev_state
*state
)
1650 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1651 struct v4l2_mbus_framefmt
*format
;
1652 struct v4l2_rect
*crop
;
1653 struct v4l2_rect
*compose
;
1655 format
= v4l2_subdev_state_get_format(state
, 0);
1657 format
->width
= MT9M114_PIXEL_ARRAY_WIDTH
;
1658 format
->height
= MT9M114_PIXEL_ARRAY_HEIGHT
;
1659 format
->code
= MEDIA_BUS_FMT_SGRBG10_1X10
;
1660 format
->field
= V4L2_FIELD_NONE
;
1661 format
->colorspace
= V4L2_COLORSPACE_RAW
;
1662 format
->ycbcr_enc
= V4L2_YCBCR_ENC_601
;
1663 format
->quantization
= V4L2_QUANTIZATION_FULL_RANGE
;
1664 format
->xfer_func
= V4L2_XFER_FUNC_NONE
;
1666 crop
= v4l2_subdev_state_get_crop(state
, 0);
1670 crop
->width
= format
->width
- 8;
1671 crop
->height
= format
->height
- 8;
1673 compose
= v4l2_subdev_state_get_compose(state
, 0);
1677 compose
->width
= crop
->width
;
1678 compose
->height
= crop
->height
;
1680 format
= v4l2_subdev_state_get_format(state
, 1);
1682 format
->width
= compose
->width
;
1683 format
->height
= compose
->height
;
1684 format
->code
= mt9m114_default_format_info(sensor
)->code
;
1685 format
->field
= V4L2_FIELD_NONE
;
1686 format
->colorspace
= V4L2_COLORSPACE_SRGB
;
1687 format
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
1688 format
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
1689 format
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
1694 static int mt9m114_ifp_enum_mbus_code(struct v4l2_subdev
*sd
,
1695 struct v4l2_subdev_state
*state
,
1696 struct v4l2_subdev_mbus_code_enum
*code
)
1698 const unsigned int num_formats
= ARRAY_SIZE(mt9m114_format_infos
);
1699 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1700 unsigned int index
= 0;
1704 switch (code
->pad
) {
1706 if (code
->index
!= 0)
1709 code
->code
= mt9m114_format_infos
[num_formats
- 1].code
;
1713 if (sensor
->bus_cfg
.bus_type
== V4L2_MBUS_CSI2_DPHY
)
1714 flag
= MT9M114_FMT_FLAG_CSI2
;
1716 flag
= MT9M114_FMT_FLAG_PARALLEL
;
1718 for (i
= 0; i
< num_formats
; ++i
) {
1719 const struct mt9m114_format_info
*info
=
1720 &mt9m114_format_infos
[i
];
1722 if (info
->flags
& flag
) {
1723 if (index
== code
->index
) {
1724 code
->code
= info
->code
;
1739 static int mt9m114_ifp_enum_framesizes(struct v4l2_subdev
*sd
,
1740 struct v4l2_subdev_state
*state
,
1741 struct v4l2_subdev_frame_size_enum
*fse
)
1743 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1744 const struct mt9m114_format_info
*info
;
1749 info
= mt9m114_format_info(sensor
, fse
->pad
, fse
->code
);
1750 if (!info
|| info
->code
!= fse
->code
)
1753 if (fse
->pad
== 0) {
1754 fse
->min_width
= MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH
;
1755 fse
->max_width
= MT9M114_PIXEL_ARRAY_WIDTH
;
1756 fse
->min_height
= MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT
;
1757 fse
->max_height
= MT9M114_PIXEL_ARRAY_HEIGHT
;
1759 const struct v4l2_rect
*crop
;
1761 crop
= v4l2_subdev_state_get_crop(state
, 0);
1763 fse
->max_width
= crop
->width
;
1764 fse
->max_height
= crop
->height
;
1766 fse
->min_width
= fse
->max_width
/ 4;
1767 fse
->min_height
= fse
->max_height
/ 4;
1773 static int mt9m114_ifp_enum_frameintervals(struct v4l2_subdev
*sd
,
1774 struct v4l2_subdev_state
*state
,
1775 struct v4l2_subdev_frame_interval_enum
*fie
)
1777 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1778 const struct mt9m114_format_info
*info
;
1783 info
= mt9m114_format_info(sensor
, fie
->pad
, fie
->code
);
1784 if (!info
|| info
->code
!= fie
->code
)
1787 fie
->interval
.numerator
= 1;
1788 fie
->interval
.denominator
= MT9M114_MAX_FRAME_RATE
;
1793 static int mt9m114_ifp_set_fmt(struct v4l2_subdev
*sd
,
1794 struct v4l2_subdev_state
*state
,
1795 struct v4l2_subdev_format
*fmt
)
1797 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1798 struct v4l2_mbus_framefmt
*format
;
1800 format
= v4l2_subdev_state_get_format(state
, fmt
->pad
);
1802 if (fmt
->pad
== 0) {
1803 /* Only the size can be changed on the sink pad. */
1804 format
->width
= clamp(ALIGN(fmt
->format
.width
, 8),
1805 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH
,
1806 MT9M114_PIXEL_ARRAY_WIDTH
);
1807 format
->height
= clamp(ALIGN(fmt
->format
.height
, 8),
1808 MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT
,
1809 MT9M114_PIXEL_ARRAY_HEIGHT
);
1811 const struct mt9m114_format_info
*info
;
1813 /* Only the media bus code can be changed on the source pad. */
1814 info
= mt9m114_format_info(sensor
, 1, fmt
->format
.code
);
1816 format
->code
= info
->code
;
1818 /* If the output format is RAW10, bypass the scaler. */
1819 if (format
->code
== MEDIA_BUS_FMT_SGRBG10_1X10
)
1820 *format
= *v4l2_subdev_state_get_format(state
, 0);
1823 fmt
->format
= *format
;
1828 static int mt9m114_ifp_get_selection(struct v4l2_subdev
*sd
,
1829 struct v4l2_subdev_state
*state
,
1830 struct v4l2_subdev_selection
*sel
)
1832 const struct v4l2_mbus_framefmt
*format
;
1833 const struct v4l2_rect
*crop
;
1836 /* Crop and compose are only supported on the sink pad. */
1840 switch (sel
->target
) {
1841 case V4L2_SEL_TGT_CROP
:
1842 sel
->r
= *v4l2_subdev_state_get_crop(state
, 0);
1845 case V4L2_SEL_TGT_CROP_DEFAULT
:
1846 case V4L2_SEL_TGT_CROP_BOUNDS
:
1848 * The crop default and bounds are equal to the sink
1849 * format size minus 4 pixels on each side for demosaicing.
1851 format
= v4l2_subdev_state_get_format(state
, 0);
1855 sel
->r
.width
= format
->width
- 8;
1856 sel
->r
.height
= format
->height
- 8;
1859 case V4L2_SEL_TGT_COMPOSE
:
1860 sel
->r
= *v4l2_subdev_state_get_compose(state
, 0);
1863 case V4L2_SEL_TGT_COMPOSE_DEFAULT
:
1864 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
1866 * The compose default and bounds sizes are equal to the sink
1867 * crop rectangle size.
1869 crop
= v4l2_subdev_state_get_crop(state
, 0);
1872 sel
->r
.width
= crop
->width
;
1873 sel
->r
.height
= crop
->height
;
1884 static int mt9m114_ifp_set_selection(struct v4l2_subdev
*sd
,
1885 struct v4l2_subdev_state
*state
,
1886 struct v4l2_subdev_selection
*sel
)
1888 struct v4l2_mbus_framefmt
*format
;
1889 struct v4l2_rect
*crop
;
1890 struct v4l2_rect
*compose
;
1892 if (sel
->target
!= V4L2_SEL_TGT_CROP
&&
1893 sel
->target
!= V4L2_SEL_TGT_COMPOSE
)
1896 /* Crop and compose are only supported on the sink pad. */
1900 format
= v4l2_subdev_state_get_format(state
, 0);
1901 crop
= v4l2_subdev_state_get_crop(state
, 0);
1902 compose
= v4l2_subdev_state_get_compose(state
, 0);
1904 if (sel
->target
== V4L2_SEL_TGT_CROP
) {
1906 * Clamp the crop rectangle. Demosaicing removes 4 pixels on
1907 * each side of the image.
1909 crop
->left
= clamp_t(unsigned int, ALIGN(sel
->r
.left
, 2), 4,
1911 MT9M114_SCALER_CROPPED_INPUT_WIDTH
);
1912 crop
->top
= clamp_t(unsigned int, ALIGN(sel
->r
.top
, 2), 4,
1913 format
->height
- 4 -
1914 MT9M114_SCALER_CROPPED_INPUT_HEIGHT
);
1915 crop
->width
= clamp_t(unsigned int, ALIGN(sel
->r
.width
, 2),
1916 MT9M114_SCALER_CROPPED_INPUT_WIDTH
,
1917 format
->width
- 4 - crop
->left
);
1918 crop
->height
= clamp_t(unsigned int, ALIGN(sel
->r
.height
, 2),
1919 MT9M114_SCALER_CROPPED_INPUT_HEIGHT
,
1920 format
->height
- 4 - crop
->top
);
1924 /* Propagate to the compose rectangle. */
1925 compose
->width
= crop
->width
;
1926 compose
->height
= crop
->height
;
1929 * Clamp the compose rectangle. The scaler can only downscale.
1933 compose
->width
= clamp_t(unsigned int, ALIGN(sel
->r
.width
, 2),
1934 MT9M114_SCALER_CROPPED_INPUT_WIDTH
,
1936 compose
->height
= clamp_t(unsigned int, ALIGN(sel
->r
.height
, 2),
1937 MT9M114_SCALER_CROPPED_INPUT_HEIGHT
,
1943 /* Propagate the compose rectangle to the source format. */
1944 format
= v4l2_subdev_state_get_format(state
, 1);
1945 format
->width
= compose
->width
;
1946 format
->height
= compose
->height
;
1951 static void mt9m114_ifp_unregistered(struct v4l2_subdev
*sd
)
1953 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1955 v4l2_device_unregister_subdev(&sensor
->pa
.sd
);
1958 static int mt9m114_ifp_registered(struct v4l2_subdev
*sd
)
1960 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
1963 ret
= v4l2_device_register_subdev(sd
->v4l2_dev
, &sensor
->pa
.sd
);
1965 dev_err(&sensor
->client
->dev
,
1966 "Failed to register pixel array subdev\n");
1970 ret
= media_create_pad_link(&sensor
->pa
.sd
.entity
, 0,
1971 &sensor
->ifp
.sd
.entity
, 0,
1972 MEDIA_LNK_FL_ENABLED
|
1973 MEDIA_LNK_FL_IMMUTABLE
);
1975 dev_err(&sensor
->client
->dev
,
1976 "Failed to link pixel array to ifp\n");
1977 v4l2_device_unregister_subdev(&sensor
->pa
.sd
);
1984 static const struct v4l2_subdev_video_ops mt9m114_ifp_video_ops
= {
1985 .s_stream
= mt9m114_ifp_s_stream
,
1988 static const struct v4l2_subdev_pad_ops mt9m114_ifp_pad_ops
= {
1989 .enum_mbus_code
= mt9m114_ifp_enum_mbus_code
,
1990 .enum_frame_size
= mt9m114_ifp_enum_framesizes
,
1991 .enum_frame_interval
= mt9m114_ifp_enum_frameintervals
,
1992 .get_fmt
= v4l2_subdev_get_fmt
,
1993 .set_fmt
= mt9m114_ifp_set_fmt
,
1994 .get_selection
= mt9m114_ifp_get_selection
,
1995 .set_selection
= mt9m114_ifp_set_selection
,
1996 .get_frame_interval
= mt9m114_ifp_get_frame_interval
,
1997 .set_frame_interval
= mt9m114_ifp_set_frame_interval
,
2000 static const struct v4l2_subdev_ops mt9m114_ifp_ops
= {
2001 .video
= &mt9m114_ifp_video_ops
,
2002 .pad
= &mt9m114_ifp_pad_ops
,
2005 static const struct v4l2_subdev_internal_ops mt9m114_ifp_internal_ops
= {
2006 .init_state
= mt9m114_ifp_init_state
,
2007 .registered
= mt9m114_ifp_registered
,
2008 .unregistered
= mt9m114_ifp_unregistered
,
2011 static int mt9m114_ifp_init(struct mt9m114
*sensor
)
2013 struct v4l2_subdev
*sd
= &sensor
->ifp
.sd
;
2014 struct media_pad
*pads
= sensor
->ifp
.pads
;
2015 struct v4l2_ctrl_handler
*hdl
= &sensor
->ifp
.hdl
;
2016 struct v4l2_ctrl
*link_freq
;
2019 /* Initialize the subdev. */
2020 v4l2_i2c_subdev_init(sd
, sensor
->client
, &mt9m114_ifp_ops
);
2021 v4l2_i2c_subdev_set_name(sd
, sensor
->client
, NULL
, " ifp");
2023 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
2024 sd
->internal_ops
= &mt9m114_ifp_internal_ops
;
2026 /* Initialize the media entity. */
2027 sd
->entity
.function
= MEDIA_ENT_F_PROC_VIDEO_ISP
;
2028 sd
->entity
.ops
= &mt9m114_entity_ops
;
2029 pads
[0].flags
= MEDIA_PAD_FL_SINK
;
2030 pads
[1].flags
= MEDIA_PAD_FL_SOURCE
;
2031 ret
= media_entity_pads_init(&sd
->entity
, 2, pads
);
2035 sensor
->ifp
.frame_rate
= MT9M114_DEF_FRAME_RATE
;
2037 /* Initialize the control handler. */
2038 v4l2_ctrl_handler_init(hdl
, 8);
2039 v4l2_ctrl_new_std(hdl
, &mt9m114_ifp_ctrl_ops
,
2040 V4L2_CID_AUTO_WHITE_BALANCE
,
2042 v4l2_ctrl_new_std_menu(hdl
, &mt9m114_ifp_ctrl_ops
,
2043 V4L2_CID_EXPOSURE_AUTO
,
2044 V4L2_EXPOSURE_MANUAL
, 0,
2045 V4L2_EXPOSURE_AUTO
);
2047 link_freq
= v4l2_ctrl_new_int_menu(hdl
, &mt9m114_ifp_ctrl_ops
,
2049 sensor
->bus_cfg
.nr_of_link_frequencies
- 1,
2050 0, sensor
->bus_cfg
.link_frequencies
);
2052 link_freq
->flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
2054 v4l2_ctrl_new_std(hdl
, &mt9m114_ifp_ctrl_ops
,
2055 V4L2_CID_PIXEL_RATE
,
2056 sensor
->pixrate
, sensor
->pixrate
, 1,
2059 sensor
->ifp
.tpg
[MT9M114_TPG_PATTERN
] =
2060 v4l2_ctrl_new_std_menu_items(hdl
, &mt9m114_ifp_ctrl_ops
,
2061 V4L2_CID_TEST_PATTERN
,
2062 ARRAY_SIZE(mt9m114_test_pattern_menu
) - 1,
2063 0, 0, mt9m114_test_pattern_menu
);
2064 sensor
->ifp
.tpg
[MT9M114_TPG_RED
] =
2065 v4l2_ctrl_new_std(hdl
, &mt9m114_ifp_ctrl_ops
,
2066 V4L2_CID_TEST_PATTERN_RED
,
2068 sensor
->ifp
.tpg
[MT9M114_TPG_GREEN
] =
2069 v4l2_ctrl_new_std(hdl
, &mt9m114_ifp_ctrl_ops
,
2070 V4L2_CID_TEST_PATTERN_GREENR
,
2072 sensor
->ifp
.tpg
[MT9M114_TPG_BLUE
] =
2073 v4l2_ctrl_new_std(hdl
, &mt9m114_ifp_ctrl_ops
,
2074 V4L2_CID_TEST_PATTERN_BLUE
,
2077 v4l2_ctrl_cluster(ARRAY_SIZE(sensor
->ifp
.tpg
), sensor
->ifp
.tpg
);
2084 sd
->ctrl_handler
= hdl
;
2085 sd
->state_lock
= hdl
->lock
;
2087 ret
= v4l2_subdev_init_finalize(sd
);
2094 v4l2_ctrl_handler_free(&sensor
->ifp
.hdl
);
2095 media_entity_cleanup(&sensor
->ifp
.sd
.entity
);
2099 static void mt9m114_ifp_cleanup(struct mt9m114
*sensor
)
2101 v4l2_ctrl_handler_free(&sensor
->ifp
.hdl
);
2102 media_entity_cleanup(&sensor
->ifp
.sd
.entity
);
2105 /* -----------------------------------------------------------------------------
2109 static int mt9m114_power_on(struct mt9m114
*sensor
)
2113 /* Enable power and clocks. */
2114 ret
= regulator_bulk_enable(ARRAY_SIZE(sensor
->supplies
),
2119 ret
= clk_prepare_enable(sensor
->clk
);
2121 goto error_regulator
;
2123 /* Perform a hard reset if available, or a soft reset otherwise. */
2124 if (sensor
->reset
) {
2125 long freq
= clk_get_rate(sensor
->clk
);
2126 unsigned int duration
;
2129 * The minimum duration is 50 clock cycles, thus typically
2130 * around 2µs. Double it to be safe.
2132 duration
= DIV_ROUND_UP(2 * 50 * 1000000, freq
);
2134 gpiod_set_value(sensor
->reset
, 1);
2136 gpiod_set_value(sensor
->reset
, 0);
2139 * The power may have just been turned on, we need to wait for
2140 * the sensor to be ready to accept I2C commands.
2142 usleep_range(44500, 50000);
2144 cci_write(sensor
->regmap
, MT9M114_RESET_AND_MISC_CONTROL
,
2145 MT9M114_RESET_SOC
, &ret
);
2146 cci_write(sensor
->regmap
, MT9M114_RESET_AND_MISC_CONTROL
, 0,
2150 dev_err(&sensor
->client
->dev
, "Soft reset failed\n");
2156 * Wait for the sensor to be ready to accept I2C commands by polling the
2157 * command register to wait for initialization to complete.
2159 usleep_range(44500, 50000);
2161 ret
= mt9m114_poll_command(sensor
, MT9M114_COMMAND_REGISTER_SET_STATE
);
2165 if (sensor
->bus_cfg
.bus_type
== V4L2_MBUS_PARALLEL
) {
2167 * In parallel mode (OE set to low), the sensor will enter the
2168 * streaming state after initialization. Enter the standby
2169 * manually to stop streaming.
2171 ret
= mt9m114_set_state(sensor
,
2172 MT9M114_SYS_STATE_ENTER_STANDBY
);
2178 * Before issuing any Set-State command, we must ensure that the sensor
2179 * reaches the standby mode (either initiated manually above in
2180 * parallel mode, or automatically after reset in MIPI mode).
2182 ret
= mt9m114_poll_state(sensor
, MT9M114_SYS_STATE_STANDBY
);
2189 clk_disable_unprepare(sensor
->clk
);
2191 regulator_bulk_disable(ARRAY_SIZE(sensor
->supplies
), sensor
->supplies
);
2195 static void mt9m114_power_off(struct mt9m114
*sensor
)
2197 clk_disable_unprepare(sensor
->clk
);
2198 regulator_bulk_disable(ARRAY_SIZE(sensor
->supplies
), sensor
->supplies
);
2201 static int __maybe_unused
mt9m114_runtime_resume(struct device
*dev
)
2203 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
2204 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
2207 ret
= mt9m114_power_on(sensor
);
2211 ret
= mt9m114_initialize(sensor
);
2213 mt9m114_power_off(sensor
);
2220 static int __maybe_unused
mt9m114_runtime_suspend(struct device
*dev
)
2222 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
2223 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
2225 mt9m114_power_off(sensor
);
2230 static const struct dev_pm_ops mt9m114_pm_ops
= {
2231 SET_RUNTIME_PM_OPS(mt9m114_runtime_suspend
, mt9m114_runtime_resume
, NULL
)
2234 /* -----------------------------------------------------------------------------
2238 static int mt9m114_clk_init(struct mt9m114
*sensor
)
2240 unsigned int link_freq
;
2242 /* Hardcode the PLL multiplier and dividers to default settings. */
2248 * Calculate the pixel rate and link frequency. The CSI-2 bus is clocked
2249 * for 16-bit per pixel, transmitted in DDR over a single lane. For
2250 * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles.
2252 sensor
->pixrate
= clk_get_rate(sensor
->clk
) * sensor
->pll
.m
2253 / ((sensor
->pll
.n
+ 1) * (sensor
->pll
.p
+ 1));
2255 link_freq
= sensor
->bus_cfg
.bus_type
== V4L2_MBUS_CSI2_DPHY
2256 ? sensor
->pixrate
* 8 : sensor
->pixrate
* 2;
2258 if (sensor
->bus_cfg
.nr_of_link_frequencies
!= 1 ||
2259 sensor
->bus_cfg
.link_frequencies
[0] != link_freq
) {
2260 dev_err(&sensor
->client
->dev
, "Unsupported DT link-frequencies\n");
2267 static int mt9m114_identify(struct mt9m114
*sensor
)
2269 u64 major
, minor
, release
, customer
;
2273 ret
= cci_read(sensor
->regmap
, MT9M114_CHIP_ID
, &value
, NULL
);
2275 dev_err(&sensor
->client
->dev
, "Failed to read chip ID\n");
2279 if (value
!= 0x2481) {
2280 dev_err(&sensor
->client
->dev
, "Invalid chip ID 0x%04llx\n",
2285 cci_read(sensor
->regmap
, MT9M114_MON_MAJOR_VERSION
, &major
, &ret
);
2286 cci_read(sensor
->regmap
, MT9M114_MON_MINOR_VERSION
, &minor
, &ret
);
2287 cci_read(sensor
->regmap
, MT9M114_MON_RELEASE_VERSION
, &release
, &ret
);
2288 cci_read(sensor
->regmap
, MT9M114_CUSTOMER_REV
, &customer
, &ret
);
2290 dev_err(&sensor
->client
->dev
, "Failed to read version\n");
2294 dev_dbg(&sensor
->client
->dev
,
2295 "monitor v%llu.%llu.%04llx customer rev 0x%04llx\n",
2296 major
, minor
, release
, customer
);
2301 static int mt9m114_parse_dt(struct mt9m114
*sensor
)
2303 struct fwnode_handle
*fwnode
= dev_fwnode(&sensor
->client
->dev
);
2304 struct fwnode_handle
*ep
;
2307 ep
= fwnode_graph_get_next_endpoint(fwnode
, NULL
);
2309 dev_err(&sensor
->client
->dev
, "No endpoint found\n");
2313 sensor
->bus_cfg
.bus_type
= V4L2_MBUS_UNKNOWN
;
2314 ret
= v4l2_fwnode_endpoint_alloc_parse(ep
, &sensor
->bus_cfg
);
2315 fwnode_handle_put(ep
);
2317 dev_err(&sensor
->client
->dev
, "Failed to parse endpoint\n");
2321 switch (sensor
->bus_cfg
.bus_type
) {
2322 case V4L2_MBUS_CSI2_DPHY
:
2323 case V4L2_MBUS_PARALLEL
:
2327 dev_err(&sensor
->client
->dev
, "unsupported bus type %u\n",
2328 sensor
->bus_cfg
.bus_type
);
2336 v4l2_fwnode_endpoint_free(&sensor
->bus_cfg
);
2340 static int mt9m114_probe(struct i2c_client
*client
)
2342 struct device
*dev
= &client
->dev
;
2343 struct mt9m114
*sensor
;
2346 sensor
= devm_kzalloc(dev
, sizeof(*sensor
), GFP_KERNEL
);
2350 sensor
->client
= client
;
2352 sensor
->regmap
= devm_cci_regmap_init_i2c(client
, 16);
2353 if (IS_ERR(sensor
->regmap
)) {
2354 dev_err(dev
, "Unable to initialize I2C\n");
2358 ret
= mt9m114_parse_dt(sensor
);
2362 /* Acquire clocks, GPIOs and regulators. */
2363 sensor
->clk
= devm_clk_get(dev
, NULL
);
2364 if (IS_ERR(sensor
->clk
)) {
2365 ret
= PTR_ERR(sensor
->clk
);
2366 dev_err_probe(dev
, ret
, "Failed to get clock\n");
2370 sensor
->reset
= devm_gpiod_get_optional(dev
, "reset", GPIOD_OUT_LOW
);
2371 if (IS_ERR(sensor
->reset
)) {
2372 ret
= PTR_ERR(sensor
->reset
);
2373 dev_err_probe(dev
, ret
, "Failed to get reset GPIO\n");
2377 sensor
->supplies
[0].supply
= "vddio";
2378 sensor
->supplies
[1].supply
= "vdd";
2379 sensor
->supplies
[2].supply
= "vaa";
2381 ret
= devm_regulator_bulk_get(dev
, ARRAY_SIZE(sensor
->supplies
),
2384 dev_err_probe(dev
, ret
, "Failed to get regulators\n");
2388 ret
= mt9m114_clk_init(sensor
);
2393 * Identify the sensor. The driver supports runtime PM, but needs to
2394 * work when runtime PM is disabled in the kernel. To that end, power
2395 * the sensor on manually here, and initialize it after identification
2396 * to reach the same state as if resumed through runtime PM.
2398 ret
= mt9m114_power_on(sensor
);
2400 dev_err_probe(dev
, ret
, "Could not power on the device\n");
2404 ret
= mt9m114_identify(sensor
);
2406 goto error_power_off
;
2408 ret
= mt9m114_initialize(sensor
);
2410 goto error_power_off
;
2413 * Enable runtime PM with autosuspend. As the device has been powered
2414 * manually, mark it as active, and increase the usage count without
2415 * resuming the device.
2417 pm_runtime_set_active(dev
);
2418 pm_runtime_get_noresume(dev
);
2419 pm_runtime_enable(dev
);
2420 pm_runtime_set_autosuspend_delay(dev
, 1000);
2421 pm_runtime_use_autosuspend(dev
);
2423 /* Initialize the subdevices. */
2424 ret
= mt9m114_pa_init(sensor
);
2426 goto error_pm_cleanup
;
2428 ret
= mt9m114_ifp_init(sensor
);
2430 goto error_pa_cleanup
;
2432 ret
= v4l2_async_register_subdev(&sensor
->ifp
.sd
);
2434 goto error_ifp_cleanup
;
2437 * Decrease the PM usage count. The device will get suspended after the
2438 * autosuspend delay, turning the power off.
2440 pm_runtime_mark_last_busy(dev
);
2441 pm_runtime_put_autosuspend(dev
);
2446 mt9m114_ifp_cleanup(sensor
);
2448 mt9m114_pa_cleanup(sensor
);
2450 pm_runtime_disable(dev
);
2451 pm_runtime_put_noidle(dev
);
2453 mt9m114_power_off(sensor
);
2455 v4l2_fwnode_endpoint_free(&sensor
->bus_cfg
);
2459 static void mt9m114_remove(struct i2c_client
*client
)
2461 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
2462 struct mt9m114
*sensor
= ifp_to_mt9m114(sd
);
2463 struct device
*dev
= &client
->dev
;
2465 v4l2_async_unregister_subdev(&sensor
->ifp
.sd
);
2467 mt9m114_ifp_cleanup(sensor
);
2468 mt9m114_pa_cleanup(sensor
);
2469 v4l2_fwnode_endpoint_free(&sensor
->bus_cfg
);
2472 * Disable runtime PM. In case runtime PM is disabled in the kernel,
2473 * make sure to turn power off manually.
2475 pm_runtime_disable(dev
);
2476 if (!pm_runtime_status_suspended(dev
))
2477 mt9m114_power_off(sensor
);
2478 pm_runtime_set_suspended(dev
);
2481 static const struct of_device_id mt9m114_of_ids
[] = {
2482 { .compatible
= "onnn,mt9m114" },
2485 MODULE_DEVICE_TABLE(of
, mt9m114_of_ids
);
2487 static struct i2c_driver mt9m114_driver
= {
2490 .pm
= &mt9m114_pm_ops
,
2491 .of_match_table
= mt9m114_of_ids
,
2493 .probe
= mt9m114_probe
,
2494 .remove
= mt9m114_remove
,
2497 module_i2c_driver(mt9m114_driver
);
2499 MODULE_DESCRIPTION("onsemi MT9M114 Sensor Driver");
2500 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
2501 MODULE_LICENSE("GPL");