.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for the OV5645 camera sensor. |
---|
3 | 4 | * |
---|
.. | .. |
---|
14 | 15 | */ |
---|
15 | 16 | |
---|
16 | 17 | /* |
---|
17 | | - * This program is free software; you can redistribute it and/or modify |
---|
18 | | - * it under the terms of the GNU General Public License as published by |
---|
19 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
20 | | - * (at your option) any later version. |
---|
21 | | - |
---|
22 | | - * This program is distributed in the hope that it will be useful, |
---|
23 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
24 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
25 | | - * GNU General Public License for more details. |
---|
26 | 18 | */ |
---|
27 | 19 | |
---|
28 | 20 | #include <linux/bitops.h> |
---|
.. | .. |
---|
41 | 33 | #include <media/v4l2-ctrls.h> |
---|
42 | 34 | #include <media/v4l2-fwnode.h> |
---|
43 | 35 | #include <media/v4l2-subdev.h> |
---|
44 | | - |
---|
45 | | -#define OV5645_VOLTAGE_ANALOG 2800000 |
---|
46 | | -#define OV5645_VOLTAGE_DIGITAL_CORE 1500000 |
---|
47 | | -#define OV5645_VOLTAGE_DIGITAL_IO 1800000 |
---|
48 | 36 | |
---|
49 | 37 | #define OV5645_SYSTEM_CTRL0 0x3008 |
---|
50 | 38 | #define OV5645_SYSTEM_CTRL0_START 0x02 |
---|
.. | .. |
---|
73 | 61 | #define OV5645_SDE_SAT_U 0x5583 |
---|
74 | 62 | #define OV5645_SDE_SAT_V 0x5584 |
---|
75 | 63 | |
---|
| 64 | +/* regulator supplies */ |
---|
| 65 | +static const char * const ov5645_supply_name[] = { |
---|
| 66 | + "vdddo", /* Digital I/O (1.8V) supply */ |
---|
| 67 | + "vdda", /* Analog (2.8V) supply */ |
---|
| 68 | + "vddd", /* Digital Core (1.5V) supply */ |
---|
| 69 | +}; |
---|
| 70 | + |
---|
| 71 | +#define OV5645_NUM_SUPPLIES ARRAY_SIZE(ov5645_supply_name) |
---|
| 72 | + |
---|
76 | 73 | struct reg_value { |
---|
77 | 74 | u16 reg; |
---|
78 | 75 | u8 val; |
---|
.. | .. |
---|
97 | 94 | struct v4l2_rect crop; |
---|
98 | 95 | struct clk *xclk; |
---|
99 | 96 | |
---|
100 | | - struct regulator *io_regulator; |
---|
101 | | - struct regulator *core_regulator; |
---|
102 | | - struct regulator *analog_regulator; |
---|
| 97 | + struct regulator_bulk_data supplies[OV5645_NUM_SUPPLIES]; |
---|
103 | 98 | |
---|
104 | 99 | const struct ov5645_mode_info *current_mode; |
---|
105 | 100 | |
---|
.. | .. |
---|
546 | 541 | }, |
---|
547 | 542 | }; |
---|
548 | 543 | |
---|
549 | | -static int ov5645_regulators_enable(struct ov5645 *ov5645) |
---|
550 | | -{ |
---|
551 | | - int ret; |
---|
552 | | - |
---|
553 | | - ret = regulator_enable(ov5645->io_regulator); |
---|
554 | | - if (ret < 0) { |
---|
555 | | - dev_err(ov5645->dev, "set io voltage failed\n"); |
---|
556 | | - return ret; |
---|
557 | | - } |
---|
558 | | - |
---|
559 | | - ret = regulator_enable(ov5645->analog_regulator); |
---|
560 | | - if (ret) { |
---|
561 | | - dev_err(ov5645->dev, "set analog voltage failed\n"); |
---|
562 | | - goto err_disable_io; |
---|
563 | | - } |
---|
564 | | - |
---|
565 | | - ret = regulator_enable(ov5645->core_regulator); |
---|
566 | | - if (ret) { |
---|
567 | | - dev_err(ov5645->dev, "set core voltage failed\n"); |
---|
568 | | - goto err_disable_analog; |
---|
569 | | - } |
---|
570 | | - |
---|
571 | | - return 0; |
---|
572 | | - |
---|
573 | | -err_disable_analog: |
---|
574 | | - regulator_disable(ov5645->analog_regulator); |
---|
575 | | -err_disable_io: |
---|
576 | | - regulator_disable(ov5645->io_regulator); |
---|
577 | | - |
---|
578 | | - return ret; |
---|
579 | | -} |
---|
580 | | - |
---|
581 | | -static void ov5645_regulators_disable(struct ov5645 *ov5645) |
---|
582 | | -{ |
---|
583 | | - int ret; |
---|
584 | | - |
---|
585 | | - ret = regulator_disable(ov5645->core_regulator); |
---|
586 | | - if (ret < 0) |
---|
587 | | - dev_err(ov5645->dev, "core regulator disable failed\n"); |
---|
588 | | - |
---|
589 | | - ret = regulator_disable(ov5645->analog_regulator); |
---|
590 | | - if (ret < 0) |
---|
591 | | - dev_err(ov5645->dev, "analog regulator disable failed\n"); |
---|
592 | | - |
---|
593 | | - ret = regulator_disable(ov5645->io_regulator); |
---|
594 | | - if (ret < 0) |
---|
595 | | - dev_err(ov5645->dev, "io regulator disable failed\n"); |
---|
596 | | -} |
---|
597 | | - |
---|
598 | 544 | static int ov5645_write_reg(struct ov5645 *ov5645, u16 reg, u8 val) |
---|
599 | 545 | { |
---|
600 | 546 | u8 regbuf[3]; |
---|
.. | .. |
---|
693 | 639 | { |
---|
694 | 640 | int ret; |
---|
695 | 641 | |
---|
696 | | - ret = ov5645_regulators_enable(ov5645); |
---|
697 | | - if (ret < 0) { |
---|
| 642 | + ret = regulator_bulk_enable(OV5645_NUM_SUPPLIES, ov5645->supplies); |
---|
| 643 | + if (ret < 0) |
---|
698 | 644 | return ret; |
---|
699 | | - } |
---|
700 | 645 | |
---|
701 | 646 | ret = clk_prepare_enable(ov5645->xclk); |
---|
702 | 647 | if (ret < 0) { |
---|
703 | 648 | dev_err(ov5645->dev, "clk prepare enable failed\n"); |
---|
704 | | - ov5645_regulators_disable(ov5645); |
---|
| 649 | + regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); |
---|
705 | 650 | return ret; |
---|
706 | 651 | } |
---|
707 | 652 | |
---|
.. | .. |
---|
721 | 666 | gpiod_set_value_cansleep(ov5645->rst_gpio, 1); |
---|
722 | 667 | gpiod_set_value_cansleep(ov5645->enable_gpio, 0); |
---|
723 | 668 | clk_disable_unprepare(ov5645->xclk); |
---|
724 | | - ov5645_regulators_disable(ov5645); |
---|
| 669 | + regulator_bulk_disable(OV5645_NUM_SUPPLIES, ov5645->supplies); |
---|
725 | 670 | } |
---|
726 | 671 | |
---|
727 | 672 | static int ov5645_s_power(struct v4l2_subdev *sd, int on) |
---|
.. | .. |
---|
887 | 832 | return ret; |
---|
888 | 833 | } |
---|
889 | 834 | |
---|
890 | | -static struct v4l2_ctrl_ops ov5645_ctrl_ops = { |
---|
| 835 | +static const struct v4l2_ctrl_ops ov5645_ctrl_ops = { |
---|
891 | 836 | .s_ctrl = ov5645_s_ctrl, |
---|
892 | 837 | }; |
---|
893 | 838 | |
---|
.. | .. |
---|
1104 | 1049 | .pad = &ov5645_subdev_pad_ops, |
---|
1105 | 1050 | }; |
---|
1106 | 1051 | |
---|
1107 | | -static int ov5645_probe(struct i2c_client *client, |
---|
1108 | | - const struct i2c_device_id *id) |
---|
| 1052 | +static int ov5645_probe(struct i2c_client *client) |
---|
1109 | 1053 | { |
---|
1110 | 1054 | struct device *dev = &client->dev; |
---|
1111 | 1055 | struct device_node *endpoint; |
---|
1112 | 1056 | struct ov5645 *ov5645; |
---|
1113 | 1057 | u8 chip_id_high, chip_id_low; |
---|
| 1058 | + unsigned int i; |
---|
1114 | 1059 | u32 xclk_freq; |
---|
1115 | 1060 | int ret; |
---|
1116 | 1061 | |
---|
.. | .. |
---|
1137 | 1082 | return ret; |
---|
1138 | 1083 | } |
---|
1139 | 1084 | |
---|
1140 | | - if (ov5645->ep.bus_type != V4L2_MBUS_CSI2) { |
---|
| 1085 | + if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) { |
---|
1141 | 1086 | dev_err(dev, "invalid bus type, must be CSI2\n"); |
---|
1142 | 1087 | return -EINVAL; |
---|
1143 | 1088 | } |
---|
.. | .. |
---|
1168 | 1113 | return ret; |
---|
1169 | 1114 | } |
---|
1170 | 1115 | |
---|
1171 | | - ov5645->io_regulator = devm_regulator_get(dev, "vdddo"); |
---|
1172 | | - if (IS_ERR(ov5645->io_regulator)) { |
---|
1173 | | - dev_err(dev, "cannot get io regulator\n"); |
---|
1174 | | - return PTR_ERR(ov5645->io_regulator); |
---|
1175 | | - } |
---|
| 1116 | + for (i = 0; i < OV5645_NUM_SUPPLIES; i++) |
---|
| 1117 | + ov5645->supplies[i].supply = ov5645_supply_name[i]; |
---|
1176 | 1118 | |
---|
1177 | | - ret = regulator_set_voltage(ov5645->io_regulator, |
---|
1178 | | - OV5645_VOLTAGE_DIGITAL_IO, |
---|
1179 | | - OV5645_VOLTAGE_DIGITAL_IO); |
---|
1180 | | - if (ret < 0) { |
---|
1181 | | - dev_err(dev, "cannot set io voltage\n"); |
---|
| 1119 | + ret = devm_regulator_bulk_get(dev, OV5645_NUM_SUPPLIES, |
---|
| 1120 | + ov5645->supplies); |
---|
| 1121 | + if (ret < 0) |
---|
1182 | 1122 | return ret; |
---|
1183 | | - } |
---|
1184 | | - |
---|
1185 | | - ov5645->core_regulator = devm_regulator_get(dev, "vddd"); |
---|
1186 | | - if (IS_ERR(ov5645->core_regulator)) { |
---|
1187 | | - dev_err(dev, "cannot get core regulator\n"); |
---|
1188 | | - return PTR_ERR(ov5645->core_regulator); |
---|
1189 | | - } |
---|
1190 | | - |
---|
1191 | | - ret = regulator_set_voltage(ov5645->core_regulator, |
---|
1192 | | - OV5645_VOLTAGE_DIGITAL_CORE, |
---|
1193 | | - OV5645_VOLTAGE_DIGITAL_CORE); |
---|
1194 | | - if (ret < 0) { |
---|
1195 | | - dev_err(dev, "cannot set core voltage\n"); |
---|
1196 | | - return ret; |
---|
1197 | | - } |
---|
1198 | | - |
---|
1199 | | - ov5645->analog_regulator = devm_regulator_get(dev, "vdda"); |
---|
1200 | | - if (IS_ERR(ov5645->analog_regulator)) { |
---|
1201 | | - dev_err(dev, "cannot get analog regulator\n"); |
---|
1202 | | - return PTR_ERR(ov5645->analog_regulator); |
---|
1203 | | - } |
---|
1204 | | - |
---|
1205 | | - ret = regulator_set_voltage(ov5645->analog_regulator, |
---|
1206 | | - OV5645_VOLTAGE_ANALOG, |
---|
1207 | | - OV5645_VOLTAGE_ANALOG); |
---|
1208 | | - if (ret < 0) { |
---|
1209 | | - dev_err(dev, "cannot set analog voltage\n"); |
---|
1210 | | - return ret; |
---|
1211 | | - } |
---|
1212 | 1123 | |
---|
1213 | 1124 | ov5645->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); |
---|
1214 | 1125 | if (IS_ERR(ov5645->enable_gpio)) { |
---|
.. | .. |
---|
1373 | 1284 | .of_match_table = of_match_ptr(ov5645_of_match), |
---|
1374 | 1285 | .name = "ov5645", |
---|
1375 | 1286 | }, |
---|
1376 | | - .probe = ov5645_probe, |
---|
| 1287 | + .probe_new = ov5645_probe, |
---|
1377 | 1288 | .remove = ov5645_remove, |
---|
1378 | 1289 | .id_table = ov5645_id, |
---|
1379 | 1290 | }; |
---|