Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /* Author: Andreas Helbech Kleist <andreaskleist@gmail.com> */
3 :
4 : #include <linux/device.h>
5 : #include <linux/i2c.h>
6 : #include <linux/mei_cl_bus.h>
7 : #include <linux/platform_device.h>
8 : #include <linux/pm_runtime.h>
9 : #include <linux/property.h>
10 : #include <linux/string.h>
11 : #include <linux/workqueue.h>
12 : #include <media/v4l2-fwnode.h>
13 :
14 : #include "ambu-ipu-bridge.h"
15 :
16 : #include "ipu4-compat.h"
17 :
18 : static struct ipu_bridge *static_bridge;
19 :
20 : static const struct mipi_bridge_config mipi_bridge_configs[] = {
21 : {
22 : .compatible = "ambu,tc358748",
23 : .i2c_addr = 0x0e,
24 : .i2c_adapter = 0,
25 : // ieib475_pll_configurations op_sys_clk from 4.19 driver
26 : .link_freq = 317250000,
27 : .mcsi_port = 0,
28 : .csi2_device = 0,
29 : },
30 : {
31 : .compatible = "ambu,tc358748",
32 : .i2c_addr = 0x0e,
33 : .i2c_adapter = 3,
34 : // ieib475_pll_configurations op_sys_clk from 4.19 driver
35 : .link_freq = 317250000,
36 : .mcsi_port = 1,
37 : .csi2_device = 4,
38 : },
39 :
40 : };
41 :
42 : static const struct ipu_property_names prop_names = {
43 : .clock_frequency = "clock-frequency",
44 : .bus_type = "bus-type",
45 : .data_lanes = "data-lanes",
46 : .remote_endpoint = "remote-endpoint",
47 : .link_frequencies = "link-frequencies",
48 : };
49 :
50 0 : static void ipu_bridge_create_fwnode_properties
51 : (struct ipu_sensor *sensor,
52 : struct ipu_bridge *bridge,
53 : const struct mipi_bridge_config *cfg)
54 : {
55 0 : sensor->prop_names = prop_names;
56 :
57 0 : sensor->local_ref[0] =
58 0 : SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_IPU_ENDPOINT]);
59 :
60 0 : sensor->remote_ref[0] =
61 0 : SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_SENSOR_ENDPOINT]);
62 :
63 0 : sensor->dev_properties[0] =
64 0 : PROPERTY_ENTRY_U32(sensor->prop_names.clock_frequency,
65 : cfg->link_freq);
66 :
67 0 : sensor->ep_properties[0] =
68 0 : PROPERTY_ENTRY_U32(sensor->prop_names.bus_type,
69 : V4L2_FWNODE_BUS_TYPE_CSI2_DPHY);
70 :
71 0 : sensor->ep_properties[1] =
72 0 : PROPERTY_ENTRY_U32_ARRAY_LEN(sensor->prop_names.data_lanes,
73 : bridge->data_lanes,
74 : sensor->lanes);
75 0 : sensor->ep_properties[2] =
76 0 : PROPERTY_ENTRY_REF_ARRAY(sensor->prop_names.remote_endpoint,
77 : sensor->local_ref);
78 :
79 : // TODO - does this need to be an array when we always have 1?
80 0 : sensor->ep_properties[3] =
81 0 : PROPERTY_ENTRY_U64_ARRAY_LEN(sensor->prop_names.link_frequencies,
82 : &cfg->link_freq,
83 : 1);
84 :
85 0 : sensor->ipu_properties[0] =
86 : PROPERTY_ENTRY_U32_ARRAY_LEN(sensor->prop_names.data_lanes,
87 : bridge->data_lanes,
88 : sensor->lanes);
89 0 : sensor->ipu_properties[1] =
90 0 : PROPERTY_ENTRY_REF_ARRAY(sensor->prop_names.remote_endpoint,
91 : sensor->remote_ref);
92 0 : }
93 :
94 0 : static void ipu_bridge_init_swnode_names(struct ipu_sensor *sensor)
95 : {
96 0 : snprintf(sensor->node_names.remote_port,
97 : sizeof(sensor->node_names.remote_port),
98 0 : SWNODE_GRAPH_PORT_NAME_FMT, sensor->link);
99 0 : snprintf(sensor->node_names.port,
100 : sizeof(sensor->node_names.port),
101 : SWNODE_GRAPH_PORT_NAME_FMT, 0); /* Always port 0 */
102 0 : snprintf(sensor->node_names.endpoint,
103 : sizeof(sensor->node_names.endpoint),
104 : SWNODE_GRAPH_ENDPOINT_NAME_FMT, 0); /* And endpoint 0 */
105 0 : }
106 :
107 : static void ipu_bridge_init_swnode_group(struct ipu_sensor *sensor)
108 : {
109 : struct software_node *nodes = sensor->swnodes;
110 :
111 0 : sensor->group[SWNODE_SENSOR_HID] = &nodes[SWNODE_SENSOR_HID];
112 0 : sensor->group[SWNODE_SENSOR_PORT] = &nodes[SWNODE_SENSOR_PORT];
113 0 : sensor->group[SWNODE_SENSOR_ENDPOINT] = &nodes[SWNODE_SENSOR_ENDPOINT];
114 0 : sensor->group[SWNODE_IPU_PORT] = &nodes[SWNODE_IPU_PORT];
115 0 : sensor->group[SWNODE_IPU_ENDPOINT] = &nodes[SWNODE_IPU_ENDPOINT];
116 : }
117 :
118 0 : static void ipu_bridge_create_connection_swnodes(struct ipu_bridge *bridge,
119 : struct ipu_sensor *sensor)
120 : {
121 0 : struct software_node *nodes = sensor->swnodes;
122 :
123 0 : ipu_bridge_init_swnode_names(sensor);
124 :
125 0 : nodes[SWNODE_SENSOR_HID] = NODE_SENSOR(sensor->name,
126 : sensor->dev_properties);
127 0 : nodes[SWNODE_SENSOR_PORT] = NODE_PORT(sensor->node_names.port,
128 : &nodes[SWNODE_SENSOR_HID]);
129 0 : nodes[SWNODE_SENSOR_ENDPOINT] =
130 0 : NODE_ENDPOINT(sensor->node_names.endpoint,
131 : &nodes[SWNODE_SENSOR_PORT],
132 : sensor->ep_properties);
133 0 : nodes[SWNODE_IPU_PORT] = NODE_PORT(sensor->node_names.remote_port,
134 : &bridge->ipu_hid_node);
135 0 : nodes[SWNODE_IPU_ENDPOINT] = NODE_ENDPOINT(sensor->node_names.endpoint,
136 : &nodes[SWNODE_IPU_PORT],
137 : sensor->ipu_properties);
138 :
139 : ipu_bridge_init_swnode_group(sensor);
140 0 : }
141 :
142 0 : static void ipu_bridge_unregister_sensors(struct ipu_bridge *bridge)
143 : {
144 : struct ipu_sensor *sensor;
145 : unsigned int i;
146 :
147 0 : for (i = 0; i < bridge->n_sensors; i++) {
148 : sensor = &bridge->sensors[i];
149 0 : i2c_unregister_device(sensor->i2c_dev);
150 0 : software_node_unregister_node_group(sensor->group);
151 : }
152 0 : }
153 :
154 : static struct i2c_client *
155 0 : ipu_bridge_init_i2c_dev(struct device *dev,
156 : const struct mipi_bridge_config *cfg,
157 : const struct software_node *swnode)
158 : {
159 : struct i2c_adapter *adapter;
160 : struct i2c_client *client;
161 0 : struct i2c_board_info info = {
162 0 : I2C_BOARD_INFO("ambu,tc358748", cfg->i2c_addr) };
163 :
164 : // TODO - when swnode is passed to i2c_new_device,
165 : // should it also be registered elsewhere?
166 0 : info.swnode = swnode;
167 :
168 0 : adapter = i2c_get_adapter(cfg->i2c_adapter);
169 0 : if (!adapter) {
170 0 : dev_err(dev, "Invalid I2C adapter %d for port %d",
171 : cfg->i2c_adapter, cfg->mcsi_port);
172 0 : return ERR_PTR(-EINVAL);
173 : }
174 :
175 0 : client = i2c_new_client_device(adapter, &info);
176 0 : i2c_put_adapter(adapter);
177 0 : return client;
178 : }
179 :
180 : static int
181 0 : ipu_bridge_setup_mipi_bridge(const struct mipi_bridge_config *cfg,
182 : struct ipu_bridge *bridge,
183 : struct device *dev)
184 : {
185 : struct ipu_sensor *sensor;
186 : int ret;
187 :
188 0 : if (bridge->n_sensors >= IPU_MAX_PORTS) {
189 0 : dev_err(dev, "Exceeded available IPU ports\n");
190 0 : return -EINVAL;
191 : }
192 :
193 0 : sensor = &bridge->sensors[bridge->n_sensors];
194 :
195 0 : sensor->lanes = 1; // from 4.19.217 dev_dbg(&csi2->isys->adev->dev,
196 : // "lane nr %d.\n", nlanes) => "lane nr 1."
197 0 : sensor->link = cfg->csi2_device;
198 :
199 0 : snprintf(sensor->name, sizeof(sensor->name), "%s-%u",
200 0 : cfg->compatible, cfg->mcsi_port);
201 :
202 0 : if (sensor->lanes > IPU_MAX_LANES) {
203 0 : dev_err(&sensor->i2c_dev->dev, "Number of lanes is invalid\n");
204 0 : return -EINVAL;
205 : }
206 :
207 0 : ipu_bridge_create_fwnode_properties(sensor, bridge, cfg);
208 0 : ipu_bridge_create_connection_swnodes(bridge, sensor);
209 :
210 0 : ret = software_node_register_node_group(sensor->group);
211 0 : if (ret)
212 : return ret;
213 :
214 : // HACK - This is probably not the right place to register this device
215 :
216 0 : sensor->i2c_dev =
217 0 : ipu_bridge_init_i2c_dev(dev, cfg,
218 0 : &sensor->swnodes[SWNODE_SENSOR_HID]);
219 0 : if (IS_ERR(sensor->i2c_dev)) {
220 0 : ret = PTR_ERR(sensor->i2c_dev);
221 0 : sensor->i2c_dev = NULL;
222 0 : goto err_free_swnodes;
223 : }
224 :
225 0 : dev_info(dev, "Found supported sensor %s\n",
226 : dev_name(&sensor->i2c_dev->dev));
227 :
228 0 : bridge->n_sensors++;
229 :
230 0 : return 0;
231 :
232 : err_free_swnodes:
233 0 : software_node_unregister_node_group(sensor->group);
234 0 : return ret;
235 : }
236 :
237 0 : static int ipu_bridge_setup_mipi_bridges(struct ipu_bridge *bridge,
238 : struct device *dev)
239 : {
240 : unsigned int i;
241 : int ret;
242 :
243 0 : for (i = 0; i < ARRAY_SIZE(mipi_bridge_configs); i++) {
244 0 : ret = ipu_bridge_setup_mipi_bridge(&mipi_bridge_configs[i],
245 : bridge, dev);
246 0 : if (ret)
247 0 : goto err_unregister_sensors;
248 : }
249 :
250 : return 0;
251 :
252 : err_unregister_sensors:
253 0 : ipu_bridge_unregister_sensors(bridge);
254 0 : return ret;
255 : }
256 :
257 : static int ipu_bridge_sensors_are_ready(void)
258 : {
259 : //TODO - is there anything we should do here
260 : // to find out if toshiba bridge is ready?
261 : return true;
262 : }
263 :
264 0 : int ambu_ipu_bridge_init(struct device *dev)
265 : {
266 : struct fwnode_handle *fwnode;
267 : struct ipu_bridge *bridge;
268 : unsigned int i;
269 : int ret;
270 :
271 : if (!ipu_bridge_sensors_are_ready())
272 : return -EPROBE_DEFER;
273 :
274 0 : static_bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
275 0 : if (!static_bridge)
276 : return -ENOMEM;
277 : // Use alias to avoid changing every line in this file
278 : bridge = static_bridge;
279 :
280 0 : strscpy(bridge->ipu_node_name, IPU_HID,
281 : sizeof(bridge->ipu_node_name));
282 0 : bridge->ipu_hid_node.name = bridge->ipu_node_name;
283 :
284 0 : ret = software_node_register(&bridge->ipu_hid_node);
285 0 : if (ret < 0) {
286 0 : dev_err(dev, "Failed to register the IPU HID node\n");
287 0 : goto err_free_bridge;
288 : }
289 :
290 : /*
291 : * Map the lane arrangement, which is fixed for the IPU3 (meaning we
292 : * only need one, rather than one per sensor). We include it as a
293 : * member of the struct ipu_bridge rather than a global variable so
294 : * that it survives if the module is unloaded along with the rest of
295 : * the struct.
296 : */
297 0 : for (i = 0; i < IPU_MAX_LANES; i++)
298 0 : bridge->data_lanes[i] = i + 1;
299 :
300 0 : ret = ipu_bridge_setup_mipi_bridges(bridge, dev);
301 0 : if (ret || bridge->n_sensors == 0)
302 0 : goto err_unregister_ipu;
303 :
304 0 : dev_info(dev, "Connected %d cameras\n", bridge->n_sensors);
305 :
306 0 : fwnode = software_node_fwnode(&bridge->ipu_hid_node);
307 0 : if (!fwnode) {
308 0 : dev_err(dev, "Error getting fwnode from ipu software_node\n");
309 : ret = -ENODEV;
310 0 : goto err_unregister_sensors;
311 : }
312 :
313 : // HACK - there appears to be no inverse of
314 : // set_secondary_fwnode, so we do this manually
315 0 : if (fwnode->secondary) {
316 0 : dev_err(dev, "Expected no fwnode->secondary, cannot proceed");
317 : ret = -ENOTUNIQ;
318 0 : goto err_unregister_sensors;
319 : }
320 0 : dev->fwnode->secondary = fwnode;
321 0 : return 0;
322 :
323 0 : err_unregister_sensors:
324 0 : ipu_bridge_unregister_sensors(bridge);
325 0 : err_unregister_ipu:
326 0 : software_node_unregister(&bridge->ipu_hid_node);
327 0 : err_free_bridge:
328 0 : kfree(bridge);
329 0 : static_bridge = NULL;
330 0 : return ret;
331 : }
332 : EXPORT_SYMBOL_NS_GPL(ambu_ipu_bridge_init, INTEL_IPU_BRIDGE);
333 :
334 0 : void ambu_ipu_bridge_uninit(struct device *dev)
335 : {
336 0 : dev->fwnode->secondary = NULL;
337 0 : ipu_bridge_unregister_sensors(static_bridge);
338 0 : software_node_unregister(&static_bridge->ipu_hid_node);
339 0 : kfree(static_bridge);
340 0 : static_bridge = NULL;
341 0 : }
342 : EXPORT_SYMBOL_NS_GPL(ambu_ipu_bridge_uninit, INTEL_IPU_BRIDGE);
343 : MODULE_LICENSE("GPL v2");
|