Merge tag 'mfd-next-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[linux-2.6-microblaze.git] / drivers / media / pci / intel / ipu3 / cio2-bridge.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dan Scally <djrscally@gmail.com> */
3
4 #include <linux/acpi.h>
5 #include <linux/device.h>
6 #include <linux/pci.h>
7 #include <linux/property.h>
8 #include <media/v4l2-fwnode.h>
9
10 #include "cio2-bridge.h"
11
12 /*
13  * Extend this array with ACPI Hardware IDs of devices known to be working
14  * plus the number of link-frequencies expected by their drivers, along with
15  * the frequency values in hertz. This is somewhat opportunistic way of adding
16  * support for this for now in the hopes of a better source for the information
17  * (possibly some encoded value in the SSDB buffer that we're unaware of)
18  * becoming apparent in the future.
19  *
20  * Do not add an entry for a sensor that is not actually supported.
21  */
22 static const struct cio2_sensor_config cio2_supported_sensors[] = {
23         /* Omnivision OV5693 */
24         CIO2_SENSOR_CONFIG("INT33BE", 0),
25         /* Omnivision OV2680 */
26         CIO2_SENSOR_CONFIG("OVTI2680", 0),
27 };
28
29 static const struct cio2_property_names prop_names = {
30         .clock_frequency = "clock-frequency",
31         .rotation = "rotation",
32         .bus_type = "bus-type",
33         .data_lanes = "data-lanes",
34         .remote_endpoint = "remote-endpoint",
35         .link_frequencies = "link-frequencies",
36 };
37
38 static int cio2_bridge_read_acpi_buffer(struct acpi_device *adev, char *id,
39                                         void *data, u32 size)
40 {
41         struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
42         union acpi_object *obj;
43         acpi_status status;
44         int ret = 0;
45
46         status = acpi_evaluate_object(adev->handle, id, NULL, &buffer);
47         if (ACPI_FAILURE(status))
48                 return -ENODEV;
49
50         obj = buffer.pointer;
51         if (!obj) {
52                 dev_err(&adev->dev, "Couldn't locate ACPI buffer\n");
53                 return -ENODEV;
54         }
55
56         if (obj->type != ACPI_TYPE_BUFFER) {
57                 dev_err(&adev->dev, "Not an ACPI buffer\n");
58                 ret = -ENODEV;
59                 goto out_free_buff;
60         }
61
62         if (obj->buffer.length > size) {
63                 dev_err(&adev->dev, "Given buffer is too small\n");
64                 ret = -EINVAL;
65                 goto out_free_buff;
66         }
67
68         memcpy(data, obj->buffer.pointer, obj->buffer.length);
69
70 out_free_buff:
71         kfree(buffer.pointer);
72         return ret;
73 }
74
75 static void cio2_bridge_create_fwnode_properties(
76         struct cio2_sensor *sensor,
77         struct cio2_bridge *bridge,
78         const struct cio2_sensor_config *cfg)
79 {
80         sensor->prop_names = prop_names;
81
82         sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_CIO2_ENDPOINT]);
83         sensor->remote_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_SENSOR_ENDPOINT]);
84
85         sensor->dev_properties[0] = PROPERTY_ENTRY_U32(
86                                         sensor->prop_names.clock_frequency,
87                                         sensor->ssdb.mclkspeed);
88         sensor->dev_properties[1] = PROPERTY_ENTRY_U8(
89                                         sensor->prop_names.rotation,
90                                         sensor->ssdb.degree);
91
92         sensor->ep_properties[0] = PROPERTY_ENTRY_U32(
93                                         sensor->prop_names.bus_type,
94                                         V4L2_FWNODE_BUS_TYPE_CSI2_DPHY);
95         sensor->ep_properties[1] = PROPERTY_ENTRY_U32_ARRAY_LEN(
96                                         sensor->prop_names.data_lanes,
97                                         bridge->data_lanes,
98                                         sensor->ssdb.lanes);
99         sensor->ep_properties[2] = PROPERTY_ENTRY_REF_ARRAY(
100                                         sensor->prop_names.remote_endpoint,
101                                         sensor->local_ref);
102
103         if (cfg->nr_link_freqs > 0)
104                 sensor->ep_properties[3] = PROPERTY_ENTRY_U64_ARRAY_LEN(
105                         sensor->prop_names.link_frequencies,
106                         cfg->link_freqs,
107                         cfg->nr_link_freqs);
108
109         sensor->cio2_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN(
110                                         sensor->prop_names.data_lanes,
111                                         bridge->data_lanes,
112                                         sensor->ssdb.lanes);
113         sensor->cio2_properties[1] = PROPERTY_ENTRY_REF_ARRAY(
114                                         sensor->prop_names.remote_endpoint,
115                                         sensor->remote_ref);
116 }
117
118 static void cio2_bridge_init_swnode_names(struct cio2_sensor *sensor)
119 {
120         snprintf(sensor->node_names.remote_port,
121                  sizeof(sensor->node_names.remote_port),
122                  SWNODE_GRAPH_PORT_NAME_FMT, sensor->ssdb.link);
123         snprintf(sensor->node_names.port,
124                  sizeof(sensor->node_names.port),
125                  SWNODE_GRAPH_PORT_NAME_FMT, 0); /* Always port 0 */
126         snprintf(sensor->node_names.endpoint,
127                  sizeof(sensor->node_names.endpoint),
128                  SWNODE_GRAPH_ENDPOINT_NAME_FMT, 0); /* And endpoint 0 */
129 }
130
131 static void cio2_bridge_create_connection_swnodes(struct cio2_bridge *bridge,
132                                                   struct cio2_sensor *sensor)
133 {
134         struct software_node *nodes = sensor->swnodes;
135
136         cio2_bridge_init_swnode_names(sensor);
137
138         nodes[SWNODE_SENSOR_HID] = NODE_SENSOR(sensor->name,
139                                                sensor->dev_properties);
140         nodes[SWNODE_SENSOR_PORT] = NODE_PORT(sensor->node_names.port,
141                                               &nodes[SWNODE_SENSOR_HID]);
142         nodes[SWNODE_SENSOR_ENDPOINT] = NODE_ENDPOINT(
143                                                 sensor->node_names.endpoint,
144                                                 &nodes[SWNODE_SENSOR_PORT],
145                                                 sensor->ep_properties);
146         nodes[SWNODE_CIO2_PORT] = NODE_PORT(sensor->node_names.remote_port,
147                                             &bridge->cio2_hid_node);
148         nodes[SWNODE_CIO2_ENDPOINT] = NODE_ENDPOINT(
149                                                 sensor->node_names.endpoint,
150                                                 &nodes[SWNODE_CIO2_PORT],
151                                                 sensor->cio2_properties);
152 }
153
154 static void cio2_bridge_unregister_sensors(struct cio2_bridge *bridge)
155 {
156         struct cio2_sensor *sensor;
157         unsigned int i;
158
159         for (i = 0; i < bridge->n_sensors; i++) {
160                 sensor = &bridge->sensors[i];
161                 software_node_unregister_nodes(sensor->swnodes);
162                 acpi_dev_put(sensor->adev);
163         }
164 }
165
166 static int cio2_bridge_connect_sensor(const struct cio2_sensor_config *cfg,
167                                       struct cio2_bridge *bridge,
168                                       struct pci_dev *cio2)
169 {
170         struct fwnode_handle *fwnode;
171         struct cio2_sensor *sensor;
172         struct acpi_device *adev;
173         int ret;
174
175         for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
176                 if (!adev->status.enabled) {
177                         acpi_dev_put(adev);
178                         continue;
179                 }
180
181                 if (bridge->n_sensors >= CIO2_NUM_PORTS) {
182                         acpi_dev_put(adev);
183                         dev_err(&cio2->dev, "Exceeded available CIO2 ports\n");
184                         return -EINVAL;
185                 }
186
187                 sensor = &bridge->sensors[bridge->n_sensors];
188                 sensor->adev = adev;
189                 strscpy(sensor->name, cfg->hid, sizeof(sensor->name));
190
191                 ret = cio2_bridge_read_acpi_buffer(adev, "SSDB",
192                                                    &sensor->ssdb,
193                                                    sizeof(sensor->ssdb));
194                 if (ret)
195                         goto err_put_adev;
196
197                 if (sensor->ssdb.lanes > CIO2_MAX_LANES) {
198                         dev_err(&adev->dev,
199                                 "Number of lanes in SSDB is invalid\n");
200                         ret = -EINVAL;
201                         goto err_put_adev;
202                 }
203
204                 cio2_bridge_create_fwnode_properties(sensor, bridge, cfg);
205                 cio2_bridge_create_connection_swnodes(bridge, sensor);
206
207                 ret = software_node_register_nodes(sensor->swnodes);
208                 if (ret)
209                         goto err_put_adev;
210
211                 fwnode = software_node_fwnode(&sensor->swnodes[
212                                                       SWNODE_SENSOR_HID]);
213                 if (!fwnode) {
214                         ret = -ENODEV;
215                         goto err_free_swnodes;
216                 }
217
218                 adev->fwnode.secondary = fwnode;
219
220                 dev_info(&cio2->dev, "Found supported sensor %s\n",
221                          acpi_dev_name(adev));
222
223                 bridge->n_sensors++;
224         }
225
226         return 0;
227
228 err_free_swnodes:
229         software_node_unregister_nodes(sensor->swnodes);
230 err_put_adev:
231         acpi_dev_put(sensor->adev);
232         return ret;
233 }
234
235 static int cio2_bridge_connect_sensors(struct cio2_bridge *bridge,
236                                        struct pci_dev *cio2)
237 {
238         unsigned int i;
239         int ret;
240
241         for (i = 0; i < ARRAY_SIZE(cio2_supported_sensors); i++) {
242                 const struct cio2_sensor_config *cfg =
243                         &cio2_supported_sensors[i];
244
245                 ret = cio2_bridge_connect_sensor(cfg, bridge, cio2);
246                 if (ret)
247                         goto err_unregister_sensors;
248         }
249
250         return 0;
251
252 err_unregister_sensors:
253         cio2_bridge_unregister_sensors(bridge);
254         return ret;
255 }
256
257 int cio2_bridge_init(struct pci_dev *cio2)
258 {
259         struct device *dev = &cio2->dev;
260         struct fwnode_handle *fwnode;
261         struct cio2_bridge *bridge;
262         unsigned int i;
263         int ret;
264
265         bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
266         if (!bridge)
267                 return -ENOMEM;
268
269         strscpy(bridge->cio2_node_name, CIO2_HID,
270                 sizeof(bridge->cio2_node_name));
271         bridge->cio2_hid_node.name = bridge->cio2_node_name;
272
273         ret = software_node_register(&bridge->cio2_hid_node);
274         if (ret < 0) {
275                 dev_err(dev, "Failed to register the CIO2 HID node\n");
276                 goto err_free_bridge;
277         }
278
279         /*
280          * Map the lane arrangement, which is fixed for the IPU3 (meaning we
281          * only need one, rather than one per sensor). We include it as a
282          * member of the struct cio2_bridge rather than a global variable so
283          * that it survives if the module is unloaded along with the rest of
284          * the struct.
285          */
286         for (i = 0; i < CIO2_MAX_LANES; i++)
287                 bridge->data_lanes[i] = i + 1;
288
289         ret = cio2_bridge_connect_sensors(bridge, cio2);
290         if (ret || bridge->n_sensors == 0)
291                 goto err_unregister_cio2;
292
293         dev_info(dev, "Connected %d cameras\n", bridge->n_sensors);
294
295         fwnode = software_node_fwnode(&bridge->cio2_hid_node);
296         if (!fwnode) {
297                 dev_err(dev, "Error getting fwnode from cio2 software_node\n");
298                 ret = -ENODEV;
299                 goto err_unregister_sensors;
300         }
301
302         set_secondary_fwnode(dev, fwnode);
303
304         return 0;
305
306 err_unregister_sensors:
307         cio2_bridge_unregister_sensors(bridge);
308 err_unregister_cio2:
309         software_node_unregister(&bridge->cio2_hid_node);
310 err_free_bridge:
311         kfree(bridge);
312
313         return ret;
314 }