forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/ov772x.c
....@@ -21,6 +21,7 @@
2121 #include <linux/init.h>
2222 #include <linux/kernel.h>
2323 #include <linux/module.h>
24
+#include <linux/regmap.h>
2425 #include <linux/slab.h>
2526 #include <linux/v4l2-mediabus.h>
2627 #include <linux/videodev2.h>
....@@ -29,6 +30,7 @@
2930
3031 #include <media/v4l2-ctrls.h>
3132 #include <media/v4l2-device.h>
33
+#include <media/v4l2-event.h>
3234 #include <media/v4l2-image-sizes.h>
3335 #include <media/v4l2-subdev.h>
3436
....@@ -414,6 +416,7 @@
414416 struct v4l2_subdev subdev;
415417 struct v4l2_ctrl_handler hdl;
416418 struct clk *clk;
419
+ struct regmap *regmap;
417420 struct ov772x_camera_info *info;
418421 struct gpio_desc *pwdn_gpio;
419422 struct gpio_desc *rstb_gpio;
....@@ -549,51 +552,18 @@
549552 return container_of(sd, struct ov772x_priv, subdev);
550553 }
551554
552
-static int ov772x_read(struct i2c_client *client, u8 addr)
553
-{
554
- int ret;
555
- u8 val;
556
-
557
- ret = i2c_master_send(client, &addr, 1);
558
- if (ret < 0)
559
- return ret;
560
- ret = i2c_master_recv(client, &val, 1);
561
- if (ret < 0)
562
- return ret;
563
-
564
- return val;
565
-}
566
-
567
-static inline int ov772x_write(struct i2c_client *client, u8 addr, u8 value)
568
-{
569
- return i2c_smbus_write_byte_data(client, addr, value);
570
-}
571
-
572
-static int ov772x_mask_set(struct i2c_client *client, u8 command, u8 mask,
573
- u8 set)
574
-{
575
- s32 val = ov772x_read(client, command);
576
-
577
- if (val < 0)
578
- return val;
579
-
580
- val &= ~mask;
581
- val |= set & mask;
582
-
583
- return ov772x_write(client, command, val);
584
-}
585
-
586
-static int ov772x_reset(struct i2c_client *client)
555
+static int ov772x_reset(struct ov772x_priv *priv)
587556 {
588557 int ret;
589558
590
- ret = ov772x_write(client, COM7, SCCB_RESET);
559
+ ret = regmap_write(priv->regmap, COM7, SCCB_RESET);
591560 if (ret < 0)
592561 return ret;
593562
594563 usleep_range(1000, 5000);
595564
596
- return ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
565
+ return regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
566
+ SOFT_SLEEP_MODE);
597567 }
598568
599569 /*
....@@ -611,8 +581,8 @@
611581 if (priv->streaming == enable)
612582 goto done;
613583
614
- ret = ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE,
615
- enable ? 0 : SOFT_SLEEP_MODE);
584
+ ret = regmap_update_bits(priv->regmap, COM2, SOFT_SLEEP_MODE,
585
+ enable ? 0 : SOFT_SLEEP_MODE);
616586 if (ret)
617587 goto done;
618588
....@@ -657,7 +627,6 @@
657627 const struct ov772x_color_format *cfmt,
658628 const struct ov772x_win_size *win)
659629 {
660
- struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
661630 unsigned long fin = clk_get_rate(priv->clk);
662631 unsigned int best_diff;
663632 unsigned int fsize;
....@@ -723,11 +692,11 @@
723692 }
724693 }
725694
726
- ret = ov772x_write(client, COM4, com4 | COM4_RESERVED);
695
+ ret = regmap_write(priv->regmap, COM4, com4 | COM4_RESERVED);
727696 if (ret < 0)
728697 return ret;
729698
730
- ret = ov772x_write(client, CLKRC, clkrc | CLKRC_RESERVED);
699
+ ret = regmap_write(priv->regmap, CLKRC, clkrc | CLKRC_RESERVED);
731700 if (ret < 0)
732701 return ret;
733702
....@@ -788,8 +757,7 @@
788757 {
789758 struct ov772x_priv *priv = container_of(ctrl->handler,
790759 struct ov772x_priv, hdl);
791
- struct v4l2_subdev *sd = &priv->subdev;
792
- struct i2c_client *client = v4l2_get_subdevdata(sd);
760
+ struct regmap *regmap = priv->regmap;
793761 int ret = 0;
794762 u8 val;
795763
....@@ -808,27 +776,27 @@
808776 val = ctrl->val ? VFLIP_IMG : 0x00;
809777 if (priv->info && (priv->info->flags & OV772X_FLAG_VFLIP))
810778 val ^= VFLIP_IMG;
811
- return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
779
+ return regmap_update_bits(regmap, COM3, VFLIP_IMG, val);
812780 case V4L2_CID_HFLIP:
813781 val = ctrl->val ? HFLIP_IMG : 0x00;
814782 if (priv->info && (priv->info->flags & OV772X_FLAG_HFLIP))
815783 val ^= HFLIP_IMG;
816
- return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
784
+ return regmap_update_bits(regmap, COM3, HFLIP_IMG, val);
817785 case V4L2_CID_BAND_STOP_FILTER:
818786 if (!ctrl->val) {
819787 /* Switch the filter off, it is on now */
820
- ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
788
+ ret = regmap_update_bits(regmap, BDBASE, 0xff, 0xff);
821789 if (!ret)
822
- ret = ov772x_mask_set(client, COM8,
823
- BNDF_ON_OFF, 0);
790
+ ret = regmap_update_bits(regmap, COM8,
791
+ BNDF_ON_OFF, 0);
824792 } else {
825793 /* Switch the filter on, set AEC low limit */
826794 val = 256 - ctrl->val;
827
- ret = ov772x_mask_set(client, COM8,
828
- BNDF_ON_OFF, BNDF_ON_OFF);
795
+ ret = regmap_update_bits(regmap, COM8,
796
+ BNDF_ON_OFF, BNDF_ON_OFF);
829797 if (!ret)
830
- ret = ov772x_mask_set(client, BDBASE,
831
- 0xff, val);
798
+ ret = regmap_update_bits(regmap, BDBASE,
799
+ 0xff, val);
832800 }
833801
834802 return ret;
....@@ -841,18 +809,19 @@
841809 static int ov772x_g_register(struct v4l2_subdev *sd,
842810 struct v4l2_dbg_register *reg)
843811 {
844
- struct i2c_client *client = v4l2_get_subdevdata(sd);
812
+ struct ov772x_priv *priv = to_ov772x(sd);
845813 int ret;
814
+ unsigned int val;
846815
847816 reg->size = 1;
848817 if (reg->reg > 0xff)
849818 return -EINVAL;
850819
851
- ret = ov772x_read(client, reg->reg);
820
+ ret = regmap_read(priv->regmap, reg->reg, &val);
852821 if (ret < 0)
853822 return ret;
854823
855
- reg->val = (__u64)ret;
824
+ reg->val = (__u64)val;
856825
857826 return 0;
858827 }
....@@ -860,13 +829,13 @@
860829 static int ov772x_s_register(struct v4l2_subdev *sd,
861830 const struct v4l2_dbg_register *reg)
862831 {
863
- struct i2c_client *client = v4l2_get_subdevdata(sd);
832
+ struct ov772x_priv *priv = to_ov772x(sd);
864833
865834 if (reg->reg > 0xff ||
866835 reg->val > 0xff)
867836 return -EINVAL;
868837
869
- return ov772x_write(client, reg->reg, reg->val);
838
+ return regmap_write(priv->regmap, reg->reg, reg->val);
870839 }
871840 #endif
872841
....@@ -1005,7 +974,7 @@
1005974
1006975 static int ov772x_edgectrl(struct ov772x_priv *priv)
1007976 {
1008
- struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
977
+ struct regmap *regmap = priv->regmap;
1009978 int ret;
1010979
1011980 if (!priv->info)
....@@ -1019,19 +988,19 @@
1019988 * Remove it when manual mode.
1020989 */
1021990
1022
- ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
991
+ ret = regmap_update_bits(regmap, DSPAUTO, EDGE_ACTRL, 0x00);
1023992 if (ret < 0)
1024993 return ret;
1025994
1026
- ret = ov772x_mask_set(client,
1027
- EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
1028
- priv->info->edgectrl.threshold);
995
+ ret = regmap_update_bits(regmap, EDGE_TRSHLD,
996
+ OV772X_EDGE_THRESHOLD_MASK,
997
+ priv->info->edgectrl.threshold);
1029998 if (ret < 0)
1030999 return ret;
10311000
1032
- ret = ov772x_mask_set(client,
1033
- EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
1034
- priv->info->edgectrl.strength);
1001
+ ret = regmap_update_bits(regmap, EDGE_STRNGT,
1002
+ OV772X_EDGE_STRENGTH_MASK,
1003
+ priv->info->edgectrl.strength);
10351004 if (ret < 0)
10361005 return ret;
10371006
....@@ -1041,15 +1010,15 @@
10411010 *
10421011 * Set upper and lower limit.
10431012 */
1044
- ret = ov772x_mask_set(client,
1045
- EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
1046
- priv->info->edgectrl.upper);
1013
+ ret = regmap_update_bits(regmap, EDGE_UPPER,
1014
+ OV772X_EDGE_UPPER_MASK,
1015
+ priv->info->edgectrl.upper);
10471016 if (ret < 0)
10481017 return ret;
10491018
1050
- ret = ov772x_mask_set(client,
1051
- EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
1052
- priv->info->edgectrl.lower);
1019
+ ret = regmap_update_bits(regmap, EDGE_LOWER,
1020
+ OV772X_EDGE_LOWER_MASK,
1021
+ priv->info->edgectrl.lower);
10531022 if (ret < 0)
10541023 return ret;
10551024 }
....@@ -1061,12 +1030,11 @@
10611030 const struct ov772x_color_format *cfmt,
10621031 const struct ov772x_win_size *win)
10631032 {
1064
- struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
10651033 int ret;
10661034 u8 val;
10671035
10681036 /* Reset hardware. */
1069
- ov772x_reset(client);
1037
+ ov772x_reset(priv);
10701038
10711039 /* Edge Ctrl. */
10721040 ret = ov772x_edgectrl(priv);
....@@ -1074,32 +1042,32 @@
10741042 return ret;
10751043
10761044 /* Format and window size. */
1077
- ret = ov772x_write(client, HSTART, win->rect.left >> 2);
1045
+ ret = regmap_write(priv->regmap, HSTART, win->rect.left >> 2);
10781046 if (ret < 0)
10791047 goto ov772x_set_fmt_error;
1080
- ret = ov772x_write(client, HSIZE, win->rect.width >> 2);
1048
+ ret = regmap_write(priv->regmap, HSIZE, win->rect.width >> 2);
10811049 if (ret < 0)
10821050 goto ov772x_set_fmt_error;
1083
- ret = ov772x_write(client, VSTART, win->rect.top >> 1);
1051
+ ret = regmap_write(priv->regmap, VSTART, win->rect.top >> 1);
10841052 if (ret < 0)
10851053 goto ov772x_set_fmt_error;
1086
- ret = ov772x_write(client, VSIZE, win->rect.height >> 1);
1054
+ ret = regmap_write(priv->regmap, VSIZE, win->rect.height >> 1);
10871055 if (ret < 0)
10881056 goto ov772x_set_fmt_error;
1089
- ret = ov772x_write(client, HOUTSIZE, win->rect.width >> 2);
1057
+ ret = regmap_write(priv->regmap, HOUTSIZE, win->rect.width >> 2);
10901058 if (ret < 0)
10911059 goto ov772x_set_fmt_error;
1092
- ret = ov772x_write(client, VOUTSIZE, win->rect.height >> 1);
1060
+ ret = regmap_write(priv->regmap, VOUTSIZE, win->rect.height >> 1);
10931061 if (ret < 0)
10941062 goto ov772x_set_fmt_error;
1095
- ret = ov772x_write(client, HREF,
1063
+ ret = regmap_write(priv->regmap, HREF,
10961064 ((win->rect.top & 1) << HREF_VSTART_SHIFT) |
10971065 ((win->rect.left & 3) << HREF_HSTART_SHIFT) |
10981066 ((win->rect.height & 1) << HREF_VSIZE_SHIFT) |
10991067 ((win->rect.width & 3) << HREF_HSIZE_SHIFT));
11001068 if (ret < 0)
11011069 goto ov772x_set_fmt_error;
1102
- ret = ov772x_write(client, EXHCH,
1070
+ ret = regmap_write(priv->regmap, EXHCH,
11031071 ((win->rect.height & 1) << EXHCH_VSIZE_SHIFT) |
11041072 ((win->rect.width & 3) << EXHCH_HSIZE_SHIFT));
11051073 if (ret < 0)
....@@ -1108,15 +1076,14 @@
11081076 /* Set DSP_CTRL3. */
11091077 val = cfmt->dsp3;
11101078 if (val) {
1111
- ret = ov772x_mask_set(client,
1112
- DSP_CTRL3, UV_MASK, val);
1079
+ ret = regmap_update_bits(priv->regmap, DSP_CTRL3, UV_MASK, val);
11131080 if (ret < 0)
11141081 goto ov772x_set_fmt_error;
11151082 }
11161083
11171084 /* DSP_CTRL4: AEC reference point and DSP output format. */
11181085 if (cfmt->dsp4) {
1119
- ret = ov772x_write(client, DSP_CTRL4, cfmt->dsp4);
1086
+ ret = regmap_write(priv->regmap, DSP_CTRL4, cfmt->dsp4);
11201087 if (ret < 0)
11211088 goto ov772x_set_fmt_error;
11221089 }
....@@ -1132,13 +1099,12 @@
11321099 if (priv->hflip_ctrl->val)
11331100 val ^= HFLIP_IMG;
11341101
1135
- ret = ov772x_mask_set(client,
1136
- COM3, SWAP_MASK | IMG_MASK, val);
1102
+ ret = regmap_update_bits(priv->regmap, COM3, SWAP_MASK | IMG_MASK, val);
11371103 if (ret < 0)
11381104 goto ov772x_set_fmt_error;
11391105
11401106 /* COM7: Sensor resolution and output format control. */
1141
- ret = ov772x_write(client, COM7, win->com7_bit | cfmt->com7);
1107
+ ret = regmap_write(priv->regmap, COM7, win->com7_bit | cfmt->com7);
11421108 if (ret < 0)
11431109 goto ov772x_set_fmt_error;
11441110
....@@ -1151,10 +1117,11 @@
11511117 if (priv->band_filter_ctrl->val) {
11521118 unsigned short band_filter = priv->band_filter_ctrl->val;
11531119
1154
- ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, BNDF_ON_OFF);
1120
+ ret = regmap_update_bits(priv->regmap, COM8,
1121
+ BNDF_ON_OFF, BNDF_ON_OFF);
11551122 if (!ret)
1156
- ret = ov772x_mask_set(client, BDBASE,
1157
- 0xff, 256 - band_filter);
1123
+ ret = regmap_update_bits(priv->regmap, BDBASE,
1124
+ 0xff, 256 - band_filter);
11581125 if (ret < 0)
11591126 goto ov772x_set_fmt_error;
11601127 }
....@@ -1163,7 +1130,7 @@
11631130
11641131 ov772x_set_fmt_error:
11651132
1166
- ov772x_reset(client);
1133
+ ov772x_reset(priv);
11671134
11681135 return ret;
11691136 }
....@@ -1181,7 +1148,6 @@
11811148 sel->r.top = 0;
11821149 switch (sel->target) {
11831150 case V4L2_SEL_TGT_CROP_BOUNDS:
1184
- case V4L2_SEL_TGT_CROP_DEFAULT:
11851151 case V4L2_SEL_TGT_CROP:
11861152 sel->r.width = priv->win->rect.width;
11871153 sel->r.height = priv->win->rect.height;
....@@ -1277,12 +1243,12 @@
12771243 return ret;
12781244
12791245 /* Check and show product ID and manufacturer ID. */
1280
- pid = ov772x_read(client, PID);
1281
- if (pid < 0)
1282
- return pid;
1283
- ver = ov772x_read(client, VER);
1284
- if (ver < 0)
1285
- return ver;
1246
+ ret = regmap_read(priv->regmap, PID, &pid);
1247
+ if (ret < 0)
1248
+ return ret;
1249
+ ret = regmap_read(priv->regmap, VER, &ver);
1250
+ if (ret < 0)
1251
+ return ret;
12861252
12871253 switch (VERSION(pid, ver)) {
12881254 case OV7720:
....@@ -1298,12 +1264,12 @@
12981264 goto done;
12991265 }
13001266
1301
- midh = ov772x_read(client, MIDH);
1302
- if (midh < 0)
1303
- return midh;
1304
- midl = ov772x_read(client, MIDL);
1305
- if (midl < 0)
1306
- return midl;
1267
+ ret = regmap_read(priv->regmap, MIDH, &midh);
1268
+ if (ret < 0)
1269
+ return ret;
1270
+ ret = regmap_read(priv->regmap, MIDL, &midl);
1271
+ if (ret < 0)
1272
+ return ret;
13071273
13081274 dev_info(&client->dev,
13091275 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
....@@ -1322,6 +1288,9 @@
13221288 };
13231289
13241290 static const struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1291
+ .log_status = v4l2_ctrl_subdev_log_status,
1292
+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1293
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
13251294 #ifdef CONFIG_VIDEO_ADV_DEBUG
13261295 .g_register = ov772x_g_register,
13271296 .s_register = ov772x_s_register,
....@@ -1383,12 +1352,15 @@
13831352 * i2c_driver function
13841353 */
13851354
1386
-static int ov772x_probe(struct i2c_client *client,
1387
- const struct i2c_device_id *did)
1355
+static int ov772x_probe(struct i2c_client *client)
13881356 {
13891357 struct ov772x_priv *priv;
1390
- struct i2c_adapter *adapter = client->adapter;
13911358 int ret;
1359
+ static const struct regmap_config ov772x_regmap_config = {
1360
+ .reg_bits = 8,
1361
+ .val_bits = 8,
1362
+ .max_register = DSPAUTO,
1363
+ };
13921364
13931365 if (!client->dev.of_node && !client->dev.platform_data) {
13941366 dev_err(&client->dev,
....@@ -1396,21 +1368,22 @@
13961368 return -EINVAL;
13971369 }
13981370
1399
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1400
- dev_err(&adapter->dev,
1401
- "I2C-Adapter doesn't support SMBUS_BYTE_DATA\n");
1402
- return -EIO;
1403
- }
1404
-
14051371 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
14061372 if (!priv)
14071373 return -ENOMEM;
1374
+
1375
+ priv->regmap = devm_regmap_init_sccb(client, &ov772x_regmap_config);
1376
+ if (IS_ERR(priv->regmap)) {
1377
+ dev_err(&client->dev, "Failed to allocate register map\n");
1378
+ return PTR_ERR(priv->regmap);
1379
+ }
14081380
14091381 priv->info = client->dev.platform_data;
14101382 mutex_init(&priv->lock);
14111383
14121384 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1413
- priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1385
+ priv->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1386
+ V4L2_SUBDEV_FL_HAS_EVENTS;
14141387 v4l2_ctrl_handler_init(&priv->hdl, 3);
14151388 /* Use our mutex for the controls */
14161389 priv->hdl.lock = &priv->lock;
....@@ -1424,7 +1397,7 @@
14241397 priv->subdev.ctrl_handler = &priv->hdl;
14251398 if (priv->hdl.error) {
14261399 ret = priv->hdl.error;
1427
- goto error_mutex_destroy;
1400
+ goto error_ctrl_free;
14281401 }
14291402
14301403 priv->clk = clk_get(&client->dev, NULL);
....@@ -1473,7 +1446,6 @@
14731446 clk_put(priv->clk);
14741447 error_ctrl_free:
14751448 v4l2_ctrl_handler_free(&priv->hdl);
1476
-error_mutex_destroy:
14771449 mutex_destroy(&priv->lock);
14781450
14791451 return ret;
....@@ -1512,7 +1484,7 @@
15121484 .name = "ov772x",
15131485 .of_match_table = ov772x_of_match,
15141486 },
1515
- .probe = ov772x_probe,
1487
+ .probe_new = ov772x_probe,
15161488 .remove = ov772x_remove,
15171489 .id_table = ov772x_id,
15181490 };