hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/media/i2c/imx219.c
....@@ -89,6 +89,12 @@
8989
9090 #define IMX219_REG_ORIENTATION 0x0172
9191
92
+/* Binning Mode */
93
+#define IMX219_REG_BINNING_MODE 0x0174
94
+#define IMX219_BINNING_NONE 0x0000
95
+#define IMX219_BINNING_2X2 0x0101
96
+#define IMX219_BINNING_2X2_ANALOG 0x0303
97
+
9298 /* Test Pattern Control */
9399 #define IMX219_REG_TEST_PATTERN 0x0600
94100 #define IMX219_TEST_PATTERN_DISABLE 0
....@@ -143,6 +149,58 @@
143149
144150 /* Default register values */
145151 struct imx219_reg_list reg_list;
152
+
153
+ /* 2x2 binning is used */
154
+ bool binning;
155
+};
156
+
157
+static const struct imx219_reg imx219_common_regs[] = {
158
+ {0x0100, 0x00}, /* Mode Select */
159
+
160
+ /* To Access Addresses 3000-5fff, send the following commands */
161
+ {0x30eb, 0x0c},
162
+ {0x30eb, 0x05},
163
+ {0x300a, 0xff},
164
+ {0x300b, 0xff},
165
+ {0x30eb, 0x05},
166
+ {0x30eb, 0x09},
167
+
168
+ /* PLL Clock Table */
169
+ {0x0301, 0x05}, /* VTPXCK_DIV */
170
+ {0x0303, 0x01}, /* VTSYSCK_DIV */
171
+ {0x0304, 0x03}, /* PREPLLCK_VT_DIV 0x03 = AUTO set */
172
+ {0x0305, 0x03}, /* PREPLLCK_OP_DIV 0x03 = AUTO set */
173
+ {0x0306, 0x00}, /* PLL_VT_MPY */
174
+ {0x0307, 0x39},
175
+ {0x030b, 0x01}, /* OP_SYS_CLK_DIV */
176
+ {0x030c, 0x00}, /* PLL_OP_MPY */
177
+ {0x030d, 0x72},
178
+
179
+ /* Undocumented registers */
180
+ {0x455e, 0x00},
181
+ {0x471e, 0x4b},
182
+ {0x4767, 0x0f},
183
+ {0x4750, 0x14},
184
+ {0x4540, 0x00},
185
+ {0x47b4, 0x14},
186
+ {0x4713, 0x30},
187
+ {0x478b, 0x10},
188
+ {0x478f, 0x10},
189
+ {0x4793, 0x10},
190
+ {0x4797, 0x0e},
191
+ {0x479b, 0x0e},
192
+
193
+ /* Frame Bank Register Group "A" */
194
+ {0x0162, 0x0d}, /* Line_Length_A */
195
+ {0x0163, 0x78},
196
+ {0x0170, 0x01}, /* X_ODD_INC_A */
197
+ {0x0171, 0x01}, /* Y_ODD_INC_A */
198
+
199
+ /* Output setup registers */
200
+ {0x0114, 0x01}, /* CSI 2-Lane Mode */
201
+ {0x0128, 0x00}, /* DPHY Auto Mode */
202
+ {0x012a, 0x18}, /* EXCK_Freq */
203
+ {0x012b, 0x00},
146204 };
147205
148206 /*
....@@ -151,17 +209,6 @@
151209 * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
152210 */
153211 static const struct imx219_reg mode_3280x2464_regs[] = {
154
- {0x0100, 0x00},
155
- {0x30eb, 0x0c},
156
- {0x30eb, 0x05},
157
- {0x300a, 0xff},
158
- {0x300b, 0xff},
159
- {0x30eb, 0x05},
160
- {0x30eb, 0x09},
161
- {0x0114, 0x01},
162
- {0x0128, 0x00},
163
- {0x012a, 0x18},
164
- {0x012b, 0x00},
165212 {0x0164, 0x00},
166213 {0x0165, 0x00},
167214 {0x0166, 0x0c},
....@@ -174,53 +221,13 @@
174221 {0x016d, 0xd0},
175222 {0x016e, 0x09},
176223 {0x016f, 0xa0},
177
- {0x0170, 0x01},
178
- {0x0171, 0x01},
179
- {0x0174, 0x00},
180
- {0x0175, 0x00},
181
- {0x0301, 0x05},
182
- {0x0303, 0x01},
183
- {0x0304, 0x03},
184
- {0x0305, 0x03},
185
- {0x0306, 0x00},
186
- {0x0307, 0x39},
187
- {0x030b, 0x01},
188
- {0x030c, 0x00},
189
- {0x030d, 0x72},
190224 {0x0624, 0x0c},
191225 {0x0625, 0xd0},
192226 {0x0626, 0x09},
193227 {0x0627, 0xa0},
194
- {0x455e, 0x00},
195
- {0x471e, 0x4b},
196
- {0x4767, 0x0f},
197
- {0x4750, 0x14},
198
- {0x4540, 0x00},
199
- {0x47b4, 0x14},
200
- {0x4713, 0x30},
201
- {0x478b, 0x10},
202
- {0x478f, 0x10},
203
- {0x4793, 0x10},
204
- {0x4797, 0x0e},
205
- {0x479b, 0x0e},
206
- {0x0162, 0x0d},
207
- {0x0163, 0x78},
208228 };
209229
210230 static const struct imx219_reg mode_1920_1080_regs[] = {
211
- {0x0100, 0x00},
212
- {0x30eb, 0x05},
213
- {0x30eb, 0x0c},
214
- {0x300a, 0xff},
215
- {0x300b, 0xff},
216
- {0x30eb, 0x05},
217
- {0x30eb, 0x09},
218
- {0x0114, 0x01},
219
- {0x0128, 0x00},
220
- {0x012a, 0x18},
221
- {0x012b, 0x00},
222
- {0x0162, 0x0d},
223
- {0x0163, 0x78},
224231 {0x0164, 0x02},
225232 {0x0165, 0xa8},
226233 {0x0166, 0x0a},
....@@ -233,51 +240,13 @@
233240 {0x016d, 0x80},
234241 {0x016e, 0x04},
235242 {0x016f, 0x38},
236
- {0x0170, 0x01},
237
- {0x0171, 0x01},
238
- {0x0174, 0x00},
239
- {0x0175, 0x00},
240
- {0x0301, 0x05},
241
- {0x0303, 0x01},
242
- {0x0304, 0x03},
243
- {0x0305, 0x03},
244
- {0x0306, 0x00},
245
- {0x0307, 0x39},
246
- {0x030b, 0x01},
247
- {0x030c, 0x00},
248
- {0x030d, 0x72},
249243 {0x0624, 0x07},
250244 {0x0625, 0x80},
251245 {0x0626, 0x04},
252246 {0x0627, 0x38},
253
- {0x455e, 0x00},
254
- {0x471e, 0x4b},
255
- {0x4767, 0x0f},
256
- {0x4750, 0x14},
257
- {0x4540, 0x00},
258
- {0x47b4, 0x14},
259
- {0x4713, 0x30},
260
- {0x478b, 0x10},
261
- {0x478f, 0x10},
262
- {0x4793, 0x10},
263
- {0x4797, 0x0e},
264
- {0x479b, 0x0e},
265
- {0x0162, 0x0d},
266
- {0x0163, 0x78},
267247 };
268248
269249 static const struct imx219_reg mode_1640_1232_regs[] = {
270
- {0x0100, 0x00},
271
- {0x30eb, 0x0c},
272
- {0x30eb, 0x05},
273
- {0x300a, 0xff},
274
- {0x300b, 0xff},
275
- {0x30eb, 0x05},
276
- {0x30eb, 0x09},
277
- {0x0114, 0x01},
278
- {0x0128, 0x00},
279
- {0x012a, 0x18},
280
- {0x012b, 0x00},
281250 {0x0164, 0x00},
282251 {0x0165, 0x00},
283252 {0x0166, 0x0c},
....@@ -290,53 +259,13 @@
290259 {0x016d, 0x68},
291260 {0x016e, 0x04},
292261 {0x016f, 0xd0},
293
- {0x0170, 0x01},
294
- {0x0171, 0x01},
295
- {0x0174, 0x01},
296
- {0x0175, 0x01},
297
- {0x0301, 0x05},
298
- {0x0303, 0x01},
299
- {0x0304, 0x03},
300
- {0x0305, 0x03},
301
- {0x0306, 0x00},
302
- {0x0307, 0x39},
303
- {0x030b, 0x01},
304
- {0x030c, 0x00},
305
- {0x030d, 0x72},
306262 {0x0624, 0x06},
307263 {0x0625, 0x68},
308264 {0x0626, 0x04},
309265 {0x0627, 0xd0},
310
- {0x455e, 0x00},
311
- {0x471e, 0x4b},
312
- {0x4767, 0x0f},
313
- {0x4750, 0x14},
314
- {0x4540, 0x00},
315
- {0x47b4, 0x14},
316
- {0x4713, 0x30},
317
- {0x478b, 0x10},
318
- {0x478f, 0x10},
319
- {0x4793, 0x10},
320
- {0x4797, 0x0e},
321
- {0x479b, 0x0e},
322
- {0x0162, 0x0d},
323
- {0x0163, 0x78},
324266 };
325267
326268 static const struct imx219_reg mode_640_480_regs[] = {
327
- {0x0100, 0x00},
328
- {0x30eb, 0x05},
329
- {0x30eb, 0x0c},
330
- {0x300a, 0xff},
331
- {0x300b, 0xff},
332
- {0x30eb, 0x05},
333
- {0x30eb, 0x09},
334
- {0x0114, 0x01},
335
- {0x0128, 0x00},
336
- {0x012a, 0x18},
337
- {0x012b, 0x00},
338
- {0x0162, 0x0d},
339
- {0x0163, 0x78},
340269 {0x0164, 0x03},
341270 {0x0165, 0xe8},
342271 {0x0166, 0x08},
....@@ -349,35 +278,10 @@
349278 {0x016d, 0x80},
350279 {0x016e, 0x01},
351280 {0x016f, 0xe0},
352
- {0x0170, 0x01},
353
- {0x0171, 0x01},
354
- {0x0174, 0x03},
355
- {0x0175, 0x03},
356
- {0x0301, 0x05},
357
- {0x0303, 0x01},
358
- {0x0304, 0x03},
359
- {0x0305, 0x03},
360
- {0x0306, 0x00},
361
- {0x0307, 0x39},
362
- {0x030b, 0x01},
363
- {0x030c, 0x00},
364
- {0x030d, 0x72},
365281 {0x0624, 0x06},
366282 {0x0625, 0x68},
367283 {0x0626, 0x04},
368284 {0x0627, 0xd0},
369
- {0x455e, 0x00},
370
- {0x471e, 0x4b},
371
- {0x4767, 0x0f},
372
- {0x4750, 0x14},
373
- {0x4540, 0x00},
374
- {0x47b4, 0x14},
375
- {0x4713, 0x30},
376
- {0x478b, 0x10},
377
- {0x478f, 0x10},
378
- {0x4793, 0x10},
379
- {0x4797, 0x0e},
380
- {0x479b, 0x0e},
381285 };
382286
383287 static const struct imx219_reg raw8_framefmt_regs[] = {
....@@ -483,6 +387,7 @@
483387 .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
484388 .regs = mode_3280x2464_regs,
485389 },
390
+ .binning = false,
486391 },
487392 {
488393 /* 1080P 30fps cropped */
....@@ -499,6 +404,7 @@
499404 .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs),
500405 .regs = mode_1920_1080_regs,
501406 },
407
+ .binning = false,
502408 },
503409 {
504410 /* 2x2 binned 30fps mode */
....@@ -515,6 +421,7 @@
515421 .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs),
516422 .regs = mode_1640_1232_regs,
517423 },
424
+ .binning = true,
518425 },
519426 {
520427 /* 640x480 30fps mode */
....@@ -531,6 +438,7 @@
531438 .num_of_regs = ARRAY_SIZE(mode_640_480_regs),
532439 .regs = mode_640_480_regs,
533440 },
441
+ .binning = true,
534442 },
535443 };
536444
....@@ -969,6 +877,35 @@
969877 return -EINVAL;
970878 }
971879
880
+static int imx219_set_binning(struct imx219 *imx219)
881
+{
882
+ if (!imx219->mode->binning) {
883
+ return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
884
+ IMX219_REG_VALUE_16BIT,
885
+ IMX219_BINNING_NONE);
886
+ }
887
+
888
+ switch (imx219->fmt.code) {
889
+ case MEDIA_BUS_FMT_SRGGB8_1X8:
890
+ case MEDIA_BUS_FMT_SGRBG8_1X8:
891
+ case MEDIA_BUS_FMT_SGBRG8_1X8:
892
+ case MEDIA_BUS_FMT_SBGGR8_1X8:
893
+ return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
894
+ IMX219_REG_VALUE_16BIT,
895
+ IMX219_BINNING_2X2_ANALOG);
896
+
897
+ case MEDIA_BUS_FMT_SRGGB10_1X10:
898
+ case MEDIA_BUS_FMT_SGRBG10_1X10:
899
+ case MEDIA_BUS_FMT_SGBRG10_1X10:
900
+ case MEDIA_BUS_FMT_SBGGR10_1X10:
901
+ return imx219_write_reg(imx219, IMX219_REG_BINNING_MODE,
902
+ IMX219_REG_VALUE_16BIT,
903
+ IMX219_BINNING_2X2);
904
+ }
905
+
906
+ return -EINVAL;
907
+}
908
+
972909 static const struct v4l2_rect *
973910 __imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg,
974911 unsigned int pad, enum v4l2_subdev_format_whence which)
....@@ -1032,6 +969,13 @@
1032969 return ret;
1033970 }
1034971
972
+ /* Send all registers that are common to all modes */
973
+ ret = imx219_write_regs(imx219, imx219_common_regs, ARRAY_SIZE(imx219_common_regs));
974
+ if (ret) {
975
+ dev_err(&client->dev, "%s failed to send mfg header\n", __func__);
976
+ goto err_rpm_put;
977
+ }
978
+
1035979 /* Apply default values of current mode */
1036980 reg_list = &imx219->mode->reg_list;
1037981 ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs);
....@@ -1047,6 +991,13 @@
1047991 goto err_rpm_put;
1048992 }
1049993
994
+ ret = imx219_set_binning(imx219);
995
+ if (ret) {
996
+ dev_err(&client->dev, "%s failed to set binning: %d\n",
997
+ __func__, ret);
998
+ goto err_rpm_put;
999
+ }
1000
+
10501001 /* Apply customized values from user */
10511002 ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
10521003 if (ret)