Lines Matching +full:lens +full:- +full:focus

1 // SPDX-License-Identifier: GPL-2.0
9 #include <media/v4l2-fwnode.h>
11 #include "cio2-bridge.h"
15 * plus the number of link-frequencies expected by their drivers, along with
35 .clock_frequency = "clock-frequency",
38 .bus_type = "bus-type",
39 .data_lanes = "data-lanes",
40 .remote_endpoint = "remote-endpoint",
41 .link_frequencies = "link-frequencies",
64 status = acpi_evaluate_object(adev->handle, id, NULL, &buffer); in cio2_bridge_read_acpi_buffer()
66 return -ENODEV; in cio2_bridge_read_acpi_buffer()
70 dev_err(&adev->dev, "Couldn't locate ACPI buffer\n"); in cio2_bridge_read_acpi_buffer()
71 return -ENODEV; in cio2_bridge_read_acpi_buffer()
74 if (obj->type != ACPI_TYPE_BUFFER) { in cio2_bridge_read_acpi_buffer()
75 dev_err(&adev->dev, "Not an ACPI buffer\n"); in cio2_bridge_read_acpi_buffer()
76 ret = -ENODEV; in cio2_bridge_read_acpi_buffer()
80 if (obj->buffer.length > size) { in cio2_bridge_read_acpi_buffer()
81 dev_err(&adev->dev, "Given buffer is too small\n"); in cio2_bridge_read_acpi_buffer()
82 ret = -EINVAL; in cio2_bridge_read_acpi_buffer()
86 memcpy(data, obj->buffer.pointer, obj->buffer.length); in cio2_bridge_read_acpi_buffer()
95 switch (sensor->ssdb.degree) { in cio2_bridge_parse_rotation()
101 dev_warn(&sensor->adev->dev, in cio2_bridge_parse_rotation()
103 sensor->ssdb.degree); in cio2_bridge_parse_rotation()
110 switch (sensor->pld->panel) { in cio2_bridge_parse_orientation()
121 dev_warn(&sensor->adev->dev, "Unknown _PLD panel value %d\n", in cio2_bridge_parse_orientation()
122 sensor->pld->panel); in cio2_bridge_parse_orientation()
138 sensor->prop_names = prop_names; in cio2_bridge_create_fwnode_properties()
140 sensor->local_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_CIO2_ENDPOINT]); in cio2_bridge_create_fwnode_properties()
141 sensor->remote_ref[0] = SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_SENSOR_ENDPOINT]); in cio2_bridge_create_fwnode_properties()
143 sensor->dev_properties[0] = PROPERTY_ENTRY_U32( in cio2_bridge_create_fwnode_properties()
144 sensor->prop_names.clock_frequency, in cio2_bridge_create_fwnode_properties()
145 sensor->ssdb.mclkspeed); in cio2_bridge_create_fwnode_properties()
146 sensor->dev_properties[1] = PROPERTY_ENTRY_U32( in cio2_bridge_create_fwnode_properties()
147 sensor->prop_names.rotation, in cio2_bridge_create_fwnode_properties()
149 sensor->dev_properties[2] = PROPERTY_ENTRY_U32( in cio2_bridge_create_fwnode_properties()
150 sensor->prop_names.orientation, in cio2_bridge_create_fwnode_properties()
152 if (sensor->ssdb.vcmtype) { in cio2_bridge_create_fwnode_properties()
153 sensor->vcm_ref[0] = in cio2_bridge_create_fwnode_properties()
154 SOFTWARE_NODE_REFERENCE(&sensor->swnodes[SWNODE_VCM]); in cio2_bridge_create_fwnode_properties()
155 sensor->dev_properties[3] = in cio2_bridge_create_fwnode_properties()
156 PROPERTY_ENTRY_REF_ARRAY("lens-focus", sensor->vcm_ref); in cio2_bridge_create_fwnode_properties()
159 sensor->ep_properties[0] = PROPERTY_ENTRY_U32( in cio2_bridge_create_fwnode_properties()
160 sensor->prop_names.bus_type, in cio2_bridge_create_fwnode_properties()
162 sensor->ep_properties[1] = PROPERTY_ENTRY_U32_ARRAY_LEN( in cio2_bridge_create_fwnode_properties()
163 sensor->prop_names.data_lanes, in cio2_bridge_create_fwnode_properties()
164 bridge->data_lanes, in cio2_bridge_create_fwnode_properties()
165 sensor->ssdb.lanes); in cio2_bridge_create_fwnode_properties()
166 sensor->ep_properties[2] = PROPERTY_ENTRY_REF_ARRAY( in cio2_bridge_create_fwnode_properties()
167 sensor->prop_names.remote_endpoint, in cio2_bridge_create_fwnode_properties()
168 sensor->local_ref); in cio2_bridge_create_fwnode_properties()
170 if (cfg->nr_link_freqs > 0) in cio2_bridge_create_fwnode_properties()
171 sensor->ep_properties[3] = PROPERTY_ENTRY_U64_ARRAY_LEN( in cio2_bridge_create_fwnode_properties()
172 sensor->prop_names.link_frequencies, in cio2_bridge_create_fwnode_properties()
173 cfg->link_freqs, in cio2_bridge_create_fwnode_properties()
174 cfg->nr_link_freqs); in cio2_bridge_create_fwnode_properties()
176 sensor->cio2_properties[0] = PROPERTY_ENTRY_U32_ARRAY_LEN( in cio2_bridge_create_fwnode_properties()
177 sensor->prop_names.data_lanes, in cio2_bridge_create_fwnode_properties()
178 bridge->data_lanes, in cio2_bridge_create_fwnode_properties()
179 sensor->ssdb.lanes); in cio2_bridge_create_fwnode_properties()
180 sensor->cio2_properties[1] = PROPERTY_ENTRY_REF_ARRAY( in cio2_bridge_create_fwnode_properties()
181 sensor->prop_names.remote_endpoint, in cio2_bridge_create_fwnode_properties()
182 sensor->remote_ref); in cio2_bridge_create_fwnode_properties()
187 snprintf(sensor->node_names.remote_port, in cio2_bridge_init_swnode_names()
188 sizeof(sensor->node_names.remote_port), in cio2_bridge_init_swnode_names()
189 SWNODE_GRAPH_PORT_NAME_FMT, sensor->ssdb.link); in cio2_bridge_init_swnode_names()
190 snprintf(sensor->node_names.port, in cio2_bridge_init_swnode_names()
191 sizeof(sensor->node_names.port), in cio2_bridge_init_swnode_names()
193 snprintf(sensor->node_names.endpoint, in cio2_bridge_init_swnode_names()
194 sizeof(sensor->node_names.endpoint), in cio2_bridge_init_swnode_names()
201 struct software_node *nodes = sensor->swnodes; in cio2_bridge_create_connection_swnodes()
205 nodes[SWNODE_SENSOR_HID] = NODE_SENSOR(sensor->name, in cio2_bridge_create_connection_swnodes()
206 sensor->dev_properties); in cio2_bridge_create_connection_swnodes()
207 nodes[SWNODE_SENSOR_PORT] = NODE_PORT(sensor->node_names.port, in cio2_bridge_create_connection_swnodes()
210 sensor->node_names.endpoint, in cio2_bridge_create_connection_swnodes()
212 sensor->ep_properties); in cio2_bridge_create_connection_swnodes()
213 nodes[SWNODE_CIO2_PORT] = NODE_PORT(sensor->node_names.remote_port, in cio2_bridge_create_connection_swnodes()
214 &bridge->cio2_hid_node); in cio2_bridge_create_connection_swnodes()
216 sensor->node_names.endpoint, in cio2_bridge_create_connection_swnodes()
218 sensor->cio2_properties); in cio2_bridge_create_connection_swnodes()
219 if (sensor->ssdb.vcmtype) in cio2_bridge_create_connection_swnodes()
221 NODE_VCM(cio2_vcm_types[sensor->ssdb.vcmtype - 1]); in cio2_bridge_create_connection_swnodes()
229 if (!sensor->ssdb.vcmtype) in cio2_bridge_instantiate_vcm_i2c_client()
232 snprintf(name, sizeof(name), "%s-VCM", acpi_dev_name(sensor->adev)); in cio2_bridge_instantiate_vcm_i2c_client()
234 strscpy(board_info.type, cio2_vcm_types[sensor->ssdb.vcmtype - 1], in cio2_bridge_instantiate_vcm_i2c_client()
236 board_info.swnode = &sensor->swnodes[SWNODE_VCM]; in cio2_bridge_instantiate_vcm_i2c_client()
238 sensor->vcm_i2c_client = in cio2_bridge_instantiate_vcm_i2c_client()
239 i2c_acpi_new_device_by_fwnode(acpi_fwnode_handle(sensor->adev), in cio2_bridge_instantiate_vcm_i2c_client()
241 if (IS_ERR(sensor->vcm_i2c_client)) { in cio2_bridge_instantiate_vcm_i2c_client()
242 dev_warn(&sensor->adev->dev, "Error instantiation VCM i2c-client: %ld\n", in cio2_bridge_instantiate_vcm_i2c_client()
243 PTR_ERR(sensor->vcm_i2c_client)); in cio2_bridge_instantiate_vcm_i2c_client()
244 sensor->vcm_i2c_client = NULL; in cio2_bridge_instantiate_vcm_i2c_client()
253 for (i = 0; i < bridge->n_sensors; i++) { in cio2_bridge_unregister_sensors()
254 sensor = &bridge->sensors[i]; in cio2_bridge_unregister_sensors()
255 software_node_unregister_nodes(sensor->swnodes); in cio2_bridge_unregister_sensors()
256 ACPI_FREE(sensor->pld); in cio2_bridge_unregister_sensors()
257 acpi_dev_put(sensor->adev); in cio2_bridge_unregister_sensors()
258 i2c_unregister_device(sensor->vcm_i2c_client); in cio2_bridge_unregister_sensors()
272 for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { in cio2_bridge_connect_sensor()
273 if (!adev->status.enabled) in cio2_bridge_connect_sensor()
276 if (bridge->n_sensors >= CIO2_NUM_PORTS) { in cio2_bridge_connect_sensor()
278 dev_err(&cio2->dev, "Exceeded available CIO2 ports\n"); in cio2_bridge_connect_sensor()
279 return -EINVAL; in cio2_bridge_connect_sensor()
282 sensor = &bridge->sensors[bridge->n_sensors]; in cio2_bridge_connect_sensor()
283 strscpy(sensor->name, cfg->hid, sizeof(sensor->name)); in cio2_bridge_connect_sensor()
286 &sensor->ssdb, in cio2_bridge_connect_sensor()
287 sizeof(sensor->ssdb)); in cio2_bridge_connect_sensor()
291 if (sensor->ssdb.vcmtype > ARRAY_SIZE(cio2_vcm_types)) { in cio2_bridge_connect_sensor()
292 dev_warn(&adev->dev, "Unknown VCM type %d\n", in cio2_bridge_connect_sensor()
293 sensor->ssdb.vcmtype); in cio2_bridge_connect_sensor()
294 sensor->ssdb.vcmtype = 0; in cio2_bridge_connect_sensor()
297 status = acpi_get_physical_device_location(adev->handle, &sensor->pld); in cio2_bridge_connect_sensor()
299 ret = -ENODEV; in cio2_bridge_connect_sensor()
303 if (sensor->ssdb.lanes > CIO2_MAX_LANES) { in cio2_bridge_connect_sensor()
304 dev_err(&adev->dev, in cio2_bridge_connect_sensor()
306 ret = -EINVAL; in cio2_bridge_connect_sensor()
313 ret = software_node_register_nodes(sensor->swnodes); in cio2_bridge_connect_sensor()
317 fwnode = software_node_fwnode(&sensor->swnodes[ in cio2_bridge_connect_sensor()
320 ret = -ENODEV; in cio2_bridge_connect_sensor()
324 sensor->adev = acpi_dev_get(adev); in cio2_bridge_connect_sensor()
325 adev->fwnode.secondary = fwnode; in cio2_bridge_connect_sensor()
329 dev_info(&cio2->dev, "Found supported sensor %s\n", in cio2_bridge_connect_sensor()
332 bridge->n_sensors++; in cio2_bridge_connect_sensor()
338 software_node_unregister_nodes(sensor->swnodes); in cio2_bridge_connect_sensor()
340 ACPI_FREE(sensor->pld); in cio2_bridge_connect_sensor()
370 * on -EPROBE_DEFER for this, since the consumer<->supplier relations between
372 * passed as board-data to the PMIC drivers. Since -PROBE_DEFER does not work
373 * for the clks/regulators the VCM i2c-clients must not be instantiated until
377 * acpi_dev_ready_for_enumeration() helper, like the i2c-core-acpi code does
390 for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) { in cio2_bridge_sensors_are_ready()
391 if (!adev->status.enabled) in cio2_bridge_sensors_are_ready()
404 struct device *dev = &cio2->dev; in cio2_bridge_init()
411 return -EPROBE_DEFER; in cio2_bridge_init()
415 return -ENOMEM; in cio2_bridge_init()
417 strscpy(bridge->cio2_node_name, CIO2_HID, in cio2_bridge_init()
418 sizeof(bridge->cio2_node_name)); in cio2_bridge_init()
419 bridge->cio2_hid_node.name = bridge->cio2_node_name; in cio2_bridge_init()
421 ret = software_node_register(&bridge->cio2_hid_node); in cio2_bridge_init()
435 bridge->data_lanes[i] = i + 1; in cio2_bridge_init()
438 if (ret || bridge->n_sensors == 0) in cio2_bridge_init()
441 dev_info(dev, "Connected %d cameras\n", bridge->n_sensors); in cio2_bridge_init()
443 fwnode = software_node_fwnode(&bridge->cio2_hid_node); in cio2_bridge_init()
446 ret = -ENODEV; in cio2_bridge_init()
457 software_node_unregister(&bridge->cio2_hid_node); in cio2_bridge_init()