3
3
4
4
#include <asm/unaligned.h>
5
5
#include <linux/acpi.h>
6
+ #include <linux/clk.h>
6
7
#include <linux/delay.h>
8
+ #include <linux/gpio/consumer.h>
7
9
#include <linux/i2c.h>
8
10
#include <linux/module.h>
9
11
#include <linux/pm_runtime.h>
12
+ #include <linux/regulator/consumer.h>
10
13
#include <media/v4l2-ctrls.h>
11
14
#include <media/v4l2-device.h>
12
15
#include <media/v4l2-fwnode.h>
18
21
#define OV8856_LINK_FREQ_360MHZ 360000000ULL
19
22
#define OV8856_LINK_FREQ_180MHZ 180000000ULL
20
23
#define OV8856_SCLK 144000000ULL
21
- #define OV8856_MCLK 19200000
24
+ #define OV8856_XVCLK_19_2 19200000
22
25
#define OV8856_DATA_LANES 4
23
26
#define OV8856_RGB_DEPTH 10
24
27
64
67
65
68
#define to_ov8856 (_sd ) container_of(_sd, struct ov8856, sd)
66
69
70
+ static const char * const ov8856_supply_names [] = {
71
+ "dovdd" , /* Digital I/O power */
72
+ "avdd" , /* Analog power */
73
+ "dvdd" , /* Digital core power */
74
+ };
75
+
67
76
enum {
68
77
OV8856_LINK_FREQ_720MBPS ,
69
78
OV8856_LINK_FREQ_360MBPS ,
@@ -566,6 +575,10 @@ struct ov8856 {
566
575
struct media_pad pad ;
567
576
struct v4l2_ctrl_handler ctrl_handler ;
568
577
578
+ struct clk * xvclk ;
579
+ struct gpio_desc * reset_gpio ;
580
+ struct regulator_bulk_data supplies [ARRAY_SIZE (ov8856_supply_names )];
581
+
569
582
/* V4L2 Controls */
570
583
struct v4l2_ctrl * link_freq ;
571
584
struct v4l2_ctrl * pixel_rate ;
@@ -908,6 +921,57 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable)
908
921
return ret ;
909
922
}
910
923
924
+ static int __ov8856_power_on (struct ov8856 * ov8856 )
925
+ {
926
+ struct i2c_client * client = v4l2_get_subdevdata (& ov8856 -> sd );
927
+ int ret ;
928
+
929
+ if (is_acpi_node (dev_fwnode (& client -> dev )))
930
+ return 0 ;
931
+
932
+ ret = clk_prepare_enable (ov8856 -> xvclk );
933
+ if (ret < 0 ) {
934
+ dev_err (& client -> dev , "failed to enable xvclk\n" );
935
+ return ret ;
936
+ }
937
+
938
+ if (ov8856 -> reset_gpio ) {
939
+ gpiod_set_value_cansleep (ov8856 -> reset_gpio , 1 );
940
+ usleep_range (1000 , 2000 );
941
+ }
942
+
943
+ ret = regulator_bulk_enable (ARRAY_SIZE (ov8856_supply_names ),
944
+ ov8856 -> supplies );
945
+ if (ret < 0 ) {
946
+ dev_err (& client -> dev , "failed to enable regulators\n" );
947
+ goto disable_clk ;
948
+ }
949
+
950
+ gpiod_set_value_cansleep (ov8856 -> reset_gpio , 0 );
951
+ usleep_range (1500 , 1800 );
952
+
953
+ return 0 ;
954
+
955
+ disable_clk :
956
+ gpiod_set_value_cansleep (ov8856 -> reset_gpio , 1 );
957
+ clk_disable_unprepare (ov8856 -> xvclk );
958
+
959
+ return ret ;
960
+ }
961
+
962
+ static void __ov8856_power_off (struct ov8856 * ov8856 )
963
+ {
964
+ struct i2c_client * client = v4l2_get_subdevdata (& ov8856 -> sd );
965
+
966
+ if (is_acpi_node (dev_fwnode (& client -> dev )))
967
+ return ;
968
+
969
+ gpiod_set_value_cansleep (ov8856 -> reset_gpio , 1 );
970
+ regulator_bulk_disable (ARRAY_SIZE (ov8856_supply_names ),
971
+ ov8856 -> supplies );
972
+ clk_disable_unprepare (ov8856 -> xvclk );
973
+ }
974
+
911
975
static int __maybe_unused ov8856_suspend (struct device * dev )
912
976
{
913
977
struct i2c_client * client = to_i2c_client (dev );
@@ -918,6 +982,7 @@ static int __maybe_unused ov8856_suspend(struct device *dev)
918
982
if (ov8856 -> streaming )
919
983
ov8856_stop_streaming (ov8856 );
920
984
985
+ __ov8856_power_off (ov8856 );
921
986
mutex_unlock (& ov8856 -> mutex );
922
987
923
988
return 0 ;
@@ -931,6 +996,8 @@ static int __maybe_unused ov8856_resume(struct device *dev)
931
996
int ret ;
932
997
933
998
mutex_lock (& ov8856 -> mutex );
999
+
1000
+ __ov8856_power_on (ov8856 );
934
1001
if (ov8856 -> streaming ) {
935
1002
ret = ov8856_start_streaming (ov8856 );
936
1003
if (ret ) {
@@ -1092,29 +1159,53 @@ static int ov8856_identify_module(struct ov8856 *ov8856)
1092
1159
return 0 ;
1093
1160
}
1094
1161
1095
- static int ov8856_check_hwcfg ( struct device * dev )
1162
+ static int ov8856_get_hwcfg ( struct ov8856 * ov8856 , struct device * dev )
1096
1163
{
1097
1164
struct fwnode_handle * ep ;
1098
1165
struct fwnode_handle * fwnode = dev_fwnode (dev );
1099
1166
struct v4l2_fwnode_endpoint bus_cfg = {
1100
1167
.bus_type = V4L2_MBUS_CSI2_DPHY
1101
1168
};
1102
- u32 mclk ;
1169
+ u32 xvclk_rate ;
1103
1170
int ret ;
1104
1171
unsigned int i , j ;
1105
1172
1106
1173
if (!fwnode )
1107
1174
return - ENXIO ;
1108
1175
1109
- ret = fwnode_property_read_u32 (fwnode , "clock-frequency" , & mclk );
1176
+ ret = fwnode_property_read_u32 (fwnode , "clock-frequency" , & xvclk_rate );
1110
1177
if (ret )
1111
1178
return ret ;
1112
1179
1113
- if (mclk != OV8856_MCLK ) {
1114
- dev_err (dev , "external clock %d is not supported" , mclk );
1115
- return - EINVAL ;
1180
+ if (!is_acpi_node (fwnode )) {
1181
+ ov8856 -> xvclk = devm_clk_get (dev , "xvclk" );
1182
+ if (IS_ERR (ov8856 -> xvclk )) {
1183
+ dev_err (dev , "could not get xvclk clock (%pe)\n" ,
1184
+ ov8856 -> xvclk );
1185
+ return PTR_ERR (ov8856 -> xvclk );
1186
+ }
1187
+
1188
+ clk_set_rate (ov8856 -> xvclk , xvclk_rate );
1189
+ xvclk_rate = clk_get_rate (ov8856 -> xvclk );
1116
1190
}
1117
1191
1192
+ if (xvclk_rate != OV8856_XVCLK_19_2 )
1193
+ dev_warn (dev , "external clock rate %u is unsupported" ,
1194
+ xvclk_rate );
1195
+
1196
+ ov8856 -> reset_gpio = devm_gpiod_get_optional (dev , "reset" ,
1197
+ GPIOD_OUT_LOW );
1198
+ if (IS_ERR (ov8856 -> reset_gpio ))
1199
+ return PTR_ERR (ov8856 -> reset_gpio );
1200
+
1201
+ for (i = 0 ; i < ARRAY_SIZE (ov8856_supply_names ); i ++ )
1202
+ ov8856 -> supplies [i ].supply = ov8856_supply_names [i ];
1203
+
1204
+ ret = devm_regulator_bulk_get (dev , ARRAY_SIZE (ov8856_supply_names ),
1205
+ ov8856 -> supplies );
1206
+ if (ret )
1207
+ return ret ;
1208
+
1118
1209
ep = fwnode_graph_get_next_endpoint (fwnode , NULL );
1119
1210
if (!ep )
1120
1211
return - ENXIO ;
@@ -1169,6 +1260,8 @@ static int ov8856_remove(struct i2c_client *client)
1169
1260
pm_runtime_disable (& client -> dev );
1170
1261
mutex_destroy (& ov8856 -> mutex );
1171
1262
1263
+ __ov8856_power_off (ov8856 );
1264
+
1172
1265
return 0 ;
1173
1266
}
1174
1267
@@ -1177,22 +1270,29 @@ static int ov8856_probe(struct i2c_client *client)
1177
1270
struct ov8856 * ov8856 ;
1178
1271
int ret ;
1179
1272
1180
- ret = ov8856_check_hwcfg (& client -> dev );
1273
+ ov8856 = devm_kzalloc (& client -> dev , sizeof (* ov8856 ), GFP_KERNEL );
1274
+ if (!ov8856 )
1275
+ return - ENOMEM ;
1276
+
1277
+ ret = ov8856_get_hwcfg (ov8856 , & client -> dev );
1181
1278
if (ret ) {
1182
- dev_err (& client -> dev , "failed to check HW configuration: %d" ,
1279
+ dev_err (& client -> dev , "failed to get HW configuration: %d" ,
1183
1280
ret );
1184
1281
return ret ;
1185
1282
}
1186
1283
1187
- ov8856 = devm_kzalloc (& client -> dev , sizeof (* ov8856 ), GFP_KERNEL );
1188
- if (!ov8856 )
1189
- return - ENOMEM ;
1190
-
1191
1284
v4l2_i2c_subdev_init (& ov8856 -> sd , client , & ov8856_subdev_ops );
1285
+
1286
+ ret = __ov8856_power_on (ov8856 );
1287
+ if (ret ) {
1288
+ dev_err (& client -> dev , "failed to power on\n" );
1289
+ return ret ;
1290
+ }
1291
+
1192
1292
ret = ov8856_identify_module (ov8856 );
1193
1293
if (ret ) {
1194
1294
dev_err (& client -> dev , "failed to find sensor: %d" , ret );
1195
- return ret ;
1295
+ goto probe_power_off ;
1196
1296
}
1197
1297
1198
1298
mutex_init (& ov8856 -> mutex );
@@ -1238,6 +1338,9 @@ static int ov8856_probe(struct i2c_client *client)
1238
1338
v4l2_ctrl_handler_free (ov8856 -> sd .ctrl_handler );
1239
1339
mutex_destroy (& ov8856 -> mutex );
1240
1340
1341
+ probe_power_off :
1342
+ __ov8856_power_off (ov8856 );
1343
+
1241
1344
return ret ;
1242
1345
}
1243
1346
@@ -1254,11 +1357,18 @@ static const struct acpi_device_id ov8856_acpi_ids[] = {
1254
1357
MODULE_DEVICE_TABLE (acpi , ov8856_acpi_ids );
1255
1358
#endif
1256
1359
1360
+ static const struct of_device_id ov8856_of_match [] = {
1361
+ { .compatible = "ovti,ov8856" },
1362
+ { /* sentinel */ }
1363
+ };
1364
+ MODULE_DEVICE_TABLE (of , ov8856_of_match );
1365
+
1257
1366
static struct i2c_driver ov8856_i2c_driver = {
1258
1367
.driver = {
1259
1368
.name = "ov8856" ,
1260
1369
.pm = & ov8856_pm_ops ,
1261
1370
.acpi_match_table = ACPI_PTR (ov8856_acpi_ids ),
1371
+ .of_match_table = ov8856_of_match ,
1262
1372
},
1263
1373
.probe_new = ov8856_probe ,
1264
1374
.remove = ov8856_remove ,
0 commit comments