xref: /aosp_15_r20/external/coreboot/src/drivers/intel/mipi_camera/camera.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <stdlib.h>
4 #include <acpi/acpi.h>
5 #include <acpi/acpi_device.h>
6 #include <acpi/acpigen.h>
7 #include <acpi/acpigen_pci.h>
8 #include <console/console.h>
9 #include <device/i2c_simple.h>
10 #include <device/device.h>
11 #include <device/pci_def.h>
12 #include <stdio.h>
13 
14 #include "chip.h"
15 
16 #define CSI2_DATA_STREAM_INTERFACE_GUID \
17 	GUID_INIT(0x8A395669, 0x11F7, 0x4EA9, \
18 	0x9C, 0x7D, 0x20, 0xEE, 0x0A, 0xB5, 0xCA, 0x40)
19 
20 #define SENSOR_NAME_UUID	"822ace8f-2814-4174-a56b-5f029fe079ee"
21 #define SENSOR_TYPE_UUID	"26257549-9271-4ca4-bb43-c4899d5a4881"
22 #define DEFAULT_ENDPOINT	0
23 #define DEFAULT_REMOTE_NAME	"\\_SB.PCI0.CIO2"
24 #define CIO2_PCI_DEV		0x14
25 #define CIO2_PCI_FN		0x3
26 #define POWER_RESOURCE_NAME	"PRIC"
27 #define GUARD_VARIABLE_FORMAT	"RES%1d"
28 #define ENABLE_METHOD_FORMAT	"ENB%1d"
29 #define DISABLE_METHOD_FORMAT	"DSB%1d"
30 #define UNKNOWN_METHOD_FORMAT	"UNK%1d"
31 #define CLK_ENABLE_METHOD	"MCON"
32 #define CLK_DISABLE_METHOD	"MCOF"
33 
34 static struct camera_resource_manager res_mgr;
35 
resource_set_action_type(struct resource_config * res_config,enum action_type action)36 static void resource_set_action_type(struct resource_config *res_config,
37 				     enum action_type action)
38 {
39 	if (res_config)
40 		res_config->action = action;
41 }
42 
resource_get_action_type(const struct resource_config * res_config)43 static enum action_type resource_get_action_type(const struct resource_config *res_config)
44 {
45 	return res_config ? res_config->action : UNKNOWN_ACTION;
46 }
47 
resource_get_ctrl_type(const struct resource_config * res_config)48 static enum ctrl_type resource_get_ctrl_type(const struct resource_config *res_config)
49 {
50 	return res_config ? res_config->type : UNKNOWN_CTRL;
51 }
52 
resource_set_clk_config(struct resource_config * res_config,const struct clk_config * clk_conf)53 static void resource_set_clk_config(struct resource_config *res_config,
54 				    const struct clk_config *clk_conf)
55 {
56 	if (res_config) {
57 		res_config->type = IMGCLK;
58 		res_config->clk_conf = clk_conf;
59 	}
60 }
61 
resource_clk_config(const struct resource_config * res_config)62 static const struct clk_config *resource_clk_config(const struct resource_config *res_config)
63 {
64 	return res_config ? res_config->clk_conf : NULL;
65 }
66 
resource_set_gpio_config(struct resource_config * res_config,const struct gpio_config * gpio_conf)67 static void resource_set_gpio_config(struct resource_config *res_config,
68 				     const struct gpio_config *gpio_conf)
69 {
70 	if (res_config) {
71 		res_config->type = GPIO;
72 		res_config->gpio_conf = gpio_conf;
73 	}
74 }
75 
resource_gpio_config(const struct resource_config * res_config)76 static const struct gpio_config *resource_gpio_config(const struct resource_config *res_config)
77 {
78 	return res_config ? res_config->gpio_conf : NULL;
79 }
80 
81 /*
82  * This implementation assumes there is only 1 endpoint at each end of every data port. It also
83  * assumes there are no clock lanes.  It also assumes that any VCM or NVM for a CAM is on the
84  * same I2C bus as the CAM.
85  */
86 
87 /*
88  * Adds settings for a CIO2 device (typically at "\_SB.PCI0.CIO2").  A _DSD is added that
89  * specifies a child table for each port (e.g., PRT0 for "port0" and PRT1 for "port1").  Each
90  * PRTx table specifies a table for each endpoint (though only 1 endpoint is supported by this
91  * implementation so the table only has an "endpoint0" that points to a EPx0 table). The EPx0
92  * table primarily describes the # of lanes in "data-lines" and specifies the name of the other
93  * side in "remote-endpoint" (the name is usually of the form "\_SB.PCI0.I2Cx.CAM0" for the
94  * first port/cam and "\_SB.PCI0.I2Cx.CAM1" if there's a second port/cam).
95  */
camera_fill_cio2(const struct device * dev)96 static void camera_fill_cio2(const struct device *dev)
97 {
98 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
99 	struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
100 	char *ep_table_name[MAX_PORT_ENTRIES] = {NULL};
101 	char *port_table_name[MAX_PORT_ENTRIES] = {NULL};
102 	char *port_name[MAX_PORT_ENTRIES] = {NULL};
103 	unsigned int i, j;
104 	char name[BUS_PATH_MAX];
105 	struct acpi_dp *ep_table = NULL;
106 	struct acpi_dp *port_table = NULL;
107 	struct acpi_dp *remote = NULL;
108 	struct acpi_dp *lanes = NULL;
109 
110 	for (i = 0; i < config->cio2_num_ports && i < MAX_PORT_ENTRIES; ++i) {
111 		snprintf(name, sizeof(name), "EP%u0", i);
112 		ep_table_name[i] = strdup(name);
113 		ep_table = acpi_dp_new_table(ep_table_name[i]);
114 		acpi_dp_add_integer(ep_table, "endpoint", 0);
115 		acpi_dp_add_integer(ep_table, "clock-lanes", 0);
116 
117 		if (config->cio2_lanes_used[i] > 0) {
118 			lanes = acpi_dp_new_table("data-lanes");
119 
120 			for (j = 1; j <= config->cio2_lanes_used[i] &&
121 			     j <= MAX_PORT_ENTRIES; ++j)
122 				acpi_dp_add_integer(lanes, NULL, j);
123 			acpi_dp_add_array(ep_table, lanes);
124 		}
125 
126 		if (config->cio2_lane_endpoint[i]) {
127 			remote = acpi_dp_new_table("remote-endpoint");
128 			acpi_dp_add_reference(remote, NULL, config->cio2_lane_endpoint[i]);
129 			acpi_dp_add_integer(remote, NULL, 0);
130 			acpi_dp_add_integer(remote, NULL, 0);
131 			acpi_dp_add_array(ep_table, remote);
132 		}
133 
134 		snprintf(name, sizeof(name), "PRT%u", i);
135 		port_table_name[i] = strdup(name);
136 		port_table = acpi_dp_new_table(port_table_name[i]);
137 		acpi_dp_add_integer(port_table, "port", config->cio2_prt[i]);
138 		acpi_dp_add_child(port_table, "endpoint0", ep_table);
139 
140 		snprintf(name, sizeof(name), "port%u", i);
141 		port_name[i] = strdup(name);
142 		acpi_dp_add_integer(dsd, "is_es",
143 			CONFIG(DRIVERS_INTEL_MIPI_SUPPORTS_PRE_PRODUCTION_SOC));
144 		acpi_dp_add_child(dsd, port_name[i], port_table);
145 	}
146 
147 	acpi_dp_write(dsd);
148 
149 	for (i = 0; i < config->cio2_num_ports; ++i) {
150 		free(ep_table_name[i]);
151 		free(port_table_name[i]);
152 		free(port_name[i]);
153 	}
154 }
155 
apply_pld_defaults(struct drivers_intel_mipi_camera_config * config)156 static void apply_pld_defaults(struct drivers_intel_mipi_camera_config *config)
157 {
158 	if (!config->pld.ignore_color)
159 		config->pld.ignore_color = 1;
160 
161 	if (!config->pld.visible)
162 		config->pld.visible = 1;
163 
164 	if (!config->pld.vertical_offset)
165 		config->pld.vertical_offset = 0xffff;
166 
167 	if (!config->pld.horizontal_offset)
168 		config->pld.horizontal_offset = 0xffff;
169 
170 	/*
171 	 * PLD_PANEL_TOP has a value of zero, so the following will change any instance of
172 	 * PLD_PANEL_TOP to PLD_PANEL_FRONT unless disable_pld_defaults is set.
173 	 */
174 	if (!config->pld.panel)
175 		config->pld.panel = PLD_PANEL_FRONT;
176 
177 	/*
178 	 * PLD_HORIZONTAL_POSITION_LEFT has a value of zero, so the following will change any
179 	 * instance of that value to PLD_HORIZONTAL_POSITION_CENTER unless disable_pld_defaults
180 	 * is set.
181 	 */
182 	if (!config->pld.horizontal_position)
183 		config->pld.horizontal_position = PLD_HORIZONTAL_POSITION_CENTER;
184 
185 	/*
186 	 * The desired default for |vertical_position| is PLD_VERTICAL_POSITION_UPPER, which
187 	 * has a value of zero so no work is needed to set a default. The same applies for
188 	 * setting |shape| to PLD_SHAPE_ROUND.
189 	 */
190 }
191 
camera_generate_pld(const struct device * dev)192 static void camera_generate_pld(const struct device *dev)
193 {
194 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
195 
196 	if (config->use_pld) {
197 		if (!config->disable_pld_defaults)
198 			apply_pld_defaults(config);
199 
200 		acpigen_write_pld(&config->pld);
201 	}
202 }
203 
address_for_dev_type(const struct device * dev,uint8_t dev_type)204 static uint32_t address_for_dev_type(const struct device *dev, uint8_t dev_type)
205 {
206 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
207 	uint16_t i2c_bus = dev->upstream ? dev->upstream->secondary : 0xFFFF;
208 	uint16_t i2c_addr;
209 
210 	switch (dev_type) {
211 	case DEV_TYPE_SENSOR:
212 		i2c_addr = dev->path.i2c.device;
213 		break;
214 	case DEV_TYPE_VCM:
215 		i2c_addr = config->vcm_address;
216 		break;
217 	case DEV_TYPE_ROM:
218 		i2c_addr = config->rom_address;
219 		break;
220 	default:
221 		return 0;
222 	}
223 
224 	return (((uint32_t)i2c_bus) << 24 | ((uint32_t)i2c_addr) << 8 | dev_type);
225 }
226 
camera_generate_dsm(const struct device * dev)227 static void camera_generate_dsm(const struct device *dev)
228 {
229 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
230 	int local1_ret = 1 + (config->ssdb.vcm_type ? 1 : 0) + (config->ssdb.rom_type ? 1 : 0);
231 	int next_local1 = 1;
232 	/* Method (_DSM, 4, NotSerialized) */
233 	acpigen_write_method("_DSM", 4);
234 
235 	/* ToBuffer (Arg0, Local0) */
236 	acpigen_write_to_buffer(ARG0_OP, LOCAL0_OP);
237 
238 	/* If (LEqual (Local0, ToUUID(uuid))) */
239 	acpigen_write_if();
240 	acpigen_emit_byte(LEQUAL_OP);
241 	acpigen_emit_byte(LOCAL0_OP);
242 	acpigen_write_uuid(SENSOR_NAME_UUID);
243 	acpigen_write_return_string(config->sensor_name ? config->sensor_name : "UNKNOWN");
244 	acpigen_pop_len();	/* If */
245 
246 	/* If (LEqual (Local0, ToUUID(uuid))) */
247 	acpigen_write_if();
248 	acpigen_emit_byte(LEQUAL_OP);
249 	acpigen_emit_byte(LOCAL0_OP);
250 	acpigen_write_uuid(SENSOR_TYPE_UUID);
251 	/* ToInteger (Arg2, Local1) */
252 	acpigen_write_to_integer(ARG2_OP, LOCAL1_OP);
253 
254 	/* If (LEqual (Local1, 1)) */
255 	acpigen_write_if_lequal_op_int(LOCAL1_OP, next_local1++);
256 	acpigen_write_return_integer(local1_ret);
257 	acpigen_pop_len();	/* If Arg2=1 */
258 
259 	/* If (LEqual (Local1, 2)) */
260 	acpigen_write_if_lequal_op_int(LOCAL1_OP, next_local1++);
261 	acpigen_write_return_integer(address_for_dev_type(dev, DEV_TYPE_SENSOR));
262 	acpigen_pop_len();	/* If Arg2=2 */
263 
264 	if (config->ssdb.vcm_type) {
265 		/* If (LEqual (Local1, 3)) */
266 		acpigen_write_if_lequal_op_int(LOCAL1_OP, next_local1++);
267 		acpigen_write_return_integer(address_for_dev_type(dev, DEV_TYPE_VCM));
268 		acpigen_pop_len();      /* If Arg2=3 */
269 	}
270 
271 	if (config->ssdb.rom_type) {
272 		/* If (LEqual (Local1, 3 or 4)) */
273 		acpigen_write_if_lequal_op_int(LOCAL1_OP, next_local1);
274 		acpigen_write_return_integer(address_for_dev_type(dev, DEV_TYPE_ROM));
275 		acpigen_pop_len();      /* If Arg2=3 or 4 */
276 	}
277 
278 	acpigen_pop_len();      /* If uuid */
279 
280 	/* Return (Buffer (One) { 0x0 }) */
281 	acpigen_write_return_singleton_buffer(0x0);
282 
283 	acpigen_pop_len();      /* Method _DSM */
284 }
285 
camera_fill_ssdb_defaults(struct drivers_intel_mipi_camera_config * config)286 static void camera_fill_ssdb_defaults(struct drivers_intel_mipi_camera_config *config)
287 {
288 	struct device *cio2 = pcidev_on_root(CIO2_PCI_DEV, CIO2_PCI_FN);
289 	struct drivers_intel_mipi_camera_config *cio2_config;
290 
291 	if (config->disable_ssdb_defaults)
292 		return;
293 
294 	guidcpy(&config->ssdb.csi2_data_stream_interface, &CSI2_DATA_STREAM_INTERFACE_GUID);
295 
296 	if (!config->ssdb.bdf_value)
297 		config->ssdb.bdf_value = PCI_DEVFN(CIO2_PCI_DEV, CIO2_PCI_FN);
298 
299 	if (!config->ssdb.platform)
300 		config->ssdb.platform = PLATFORM_SKC;
301 
302 	if (!config->ssdb.flash_support)
303 		config->ssdb.flash_support = FLASH_DISABLE;
304 
305 	if (!config->ssdb.privacy_led)
306 		config->ssdb.privacy_led = PRIVACY_LED_A_16mA;
307 
308 	if (!config->ssdb.mipi_define)
309 		config->ssdb.mipi_define = MIPI_INFO_ACPI_DEFINED;
310 
311 	if (!config->ssdb.mclk_speed)
312 		config->ssdb.mclk_speed = CLK_FREQ_19_2MHZ;
313 
314 	if (!config->ssdb.lanes_used) {
315 		cio2_config = cio2 ? cio2->chip_info : NULL;
316 
317 		if (!cio2_config) {
318 			printk(BIOS_ERR, "Failed to get CIO2 config\n");
319 		} else if (cio2_config->device_type != INTEL_ACPI_CAMERA_CIO2) {
320 			printk(BIOS_ERR, "Device type isn't CIO2: %u\n",
321 			       (u32)cio2_config->device_type);
322 		} else if (config->ssdb.link_used >= cio2_config->cio2_num_ports) {
323 			printk(BIOS_ERR, "%u exceeds CIO2's %u links\n",
324 			       (u32)config->ssdb.link_used,
325 			       (u32)cio2_config->cio2_num_ports);
326 		} else {
327 			config->ssdb.lanes_used =
328 				cio2_config->cio2_lanes_used[config->ssdb.link_used];
329 		}
330 	}
331 }
332 
333 /*
334  * Adds settings for a camera sensor device (typically at "\_SB.PCI0.I2Cx.CAMy"). The drivers
335  * for Linux tends to expect the camera sensor device and any related nvram / vcm devices to be
336  * separate ACPI devices, while the drivers for Windows want all of these to be grouped
337  * together in the camera sensor ACPI device. This implementation tries to satisfy both,
338  * though the unfortunate tradeoff is that the same I2C address for nvram and vcm is advertised
339  * by multiple devices in ACPI (via "_CRS"). The Windows driver can use the "_DSM" method to
340  * disambiguate the I2C resources in the camera sensor ACPI device.  Drivers for Windows
341  * typically query "SSDB" for configuration information (represented as a binary blob dump of
342  * struct), while Linux drivers typically consult individual parameters in "_DSD".
343  *
344  * The tree of tables in "_DSD" is analogous to what's used for the "CIO2" device.  The _DSD
345  * specifies a child table for the sensor's port (e.g., PRT0 for "port0"--this implementation
346  * assumes a camera only has 1 port). The PRT0 table specifies a table for each endpoint
347  * (though only 1 endpoint is supported by this implementation so the table only has an
348  * "endpoint0" that points to a EP00 table). The EP00 table primarily describes the # of lanes
349  * in "data-lines", a list of frequencies in "list-frequencies", and specifies the name of the
350  * other side in "remote-endpoint" (typically "\_SB.PCI0.CIO2").
351  */
camera_fill_sensor(const struct device * dev)352 static void camera_fill_sensor(const struct device *dev)
353 {
354 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
355 	struct acpi_dp *ep00 = NULL;
356 	struct acpi_dp *prt0 = NULL;
357 	struct acpi_dp *dsd = NULL;
358 	struct acpi_dp *remote = NULL;
359 	const char *vcm_name = NULL;
360 	struct acpi_dp *lens_focus = NULL;
361 	const char *remote_name;
362 	struct device *cio2 = pcidev_on_root(CIO2_PCI_DEV, CIO2_PCI_FN);
363 
364 	camera_generate_pld(dev);
365 
366 	camera_fill_ssdb_defaults(config);
367 
368 	/* _DSM */
369 	camera_generate_dsm(dev);
370 
371 	ep00 = acpi_dp_new_table("EP00");
372 	acpi_dp_add_integer(ep00, "endpoint", DEFAULT_ENDPOINT);
373 	acpi_dp_add_integer(ep00, "clock-lanes", 0);
374 
375 	if (config->ssdb.lanes_used > 0) {
376 		struct acpi_dp *lanes = acpi_dp_new_table("data-lanes");
377 		uint32_t i;
378 		for (i = 1; i <= config->ssdb.lanes_used; ++i)
379 			acpi_dp_add_integer(lanes, NULL, i);
380 		acpi_dp_add_array(ep00, lanes);
381 	}
382 
383 	if (config->num_freq_entries) {
384 		struct acpi_dp *freq = acpi_dp_new_table("link-frequencies");
385 		uint32_t i;
386 		for (i = 0; i < config->num_freq_entries && i < MAX_LINK_FREQ_ENTRIES; ++i)
387 			acpi_dp_add_integer(freq, NULL, config->link_freq[i]);
388 		acpi_dp_add_array(ep00, freq);
389 	}
390 
391 	remote = acpi_dp_new_table("remote-endpoint");
392 
393 	if (config->remote_name) {
394 		remote_name = config->remote_name;
395 	} else {
396 		if (cio2)
397 			remote_name = acpi_device_path(cio2);
398 		else
399 			remote_name = DEFAULT_REMOTE_NAME;
400 	}
401 
402 	acpi_dp_add_reference(remote, NULL, remote_name);
403 	acpi_dp_add_integer(remote, NULL, config->ssdb.link_used);
404 	acpi_dp_add_integer(remote, NULL, DEFAULT_ENDPOINT);
405 	acpi_dp_add_array(ep00, remote);
406 
407 	prt0 = acpi_dp_new_table("PRT0");
408 
409 	acpi_dp_add_integer(prt0, "port", 0);
410 	acpi_dp_add_child(prt0, "endpoint0", ep00);
411 	dsd = acpi_dp_new_table("_DSD");
412 
413 	acpi_dp_add_integer(dsd, "clock-frequency", config->ssdb.mclk_speed);
414 
415 	if (config->ssdb.degree)
416 		acpi_dp_add_integer(dsd, "rotation", 180);
417 
418 	if (config->ssdb.vcm_type) {
419 		if (config->vcm_name) {
420 			vcm_name = config->vcm_name;
421 		} else {
422 			const struct device_path path = {
423 				.type = DEVICE_PATH_I2C,
424 				.i2c.device = config->vcm_address,
425 			};
426 			struct device *vcm_dev = find_dev_path(dev->upstream, &path);
427 			struct drivers_intel_mipi_camera_config *vcm_config;
428 			vcm_config = vcm_dev ? vcm_dev->chip_info : NULL;
429 
430 			if (!vcm_config)
431 				printk(BIOS_ERR, "Failed to get VCM\n");
432 			else if (vcm_config->device_type != INTEL_ACPI_CAMERA_VCM)
433 				printk(BIOS_ERR, "Device isn't VCM\n");
434 			else
435 				vcm_name = acpi_device_path(vcm_dev);
436 		}
437 	}
438 
439 	if (vcm_name) {
440 		lens_focus = acpi_dp_new_table("lens-focus");
441 		acpi_dp_add_reference(lens_focus, NULL, vcm_name);
442 		acpi_dp_add_array(dsd, lens_focus);
443 	}
444 
445 	if (config->low_power_probe)
446 		acpi_dp_add_integer(dsd, "i2c-allow-low-power-probe", 0x01);
447 
448 	acpi_dp_add_child(dsd, "port0", prt0);
449 	acpi_dp_write(dsd);
450 
451 	acpigen_write_method_serialized("SSDB", 0);
452 	acpigen_write_return_byte_buffer((uint8_t *)&config->ssdb, sizeof(config->ssdb));
453 	acpigen_pop_len(); /* Method */
454 
455 	/* Fill Power Sequencing Data */
456 	if (config->num_pwdb_entries > 0) {
457 		acpigen_write_method_serialized("PWDB", 0);
458 		acpigen_write_return_byte_buffer((uint8_t *)&config->pwdb,
459 						 sizeof(struct intel_pwdb) *
460 						 config->num_pwdb_entries);
461 		acpigen_pop_len(); /* Method */
462 	}
463 }
464 
camera_fill_nvm(const struct device * dev)465 static void camera_fill_nvm(const struct device *dev)
466 {
467 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
468 	struct acpi_dp *dsd;
469 
470 	if (!config->nvm_compat)
471 		return;
472 
473 	dsd = acpi_dp_new_table("_DSD");
474 
475 	/* It might be possible to default size or width based on type. */
476 	if (!config->disable_nvm_defaults && !config->nvm_pagesize)
477 		config->nvm_pagesize = 1;
478 
479 	if (!config->disable_nvm_defaults && !config->nvm_readonly)
480 		config->nvm_readonly = 1;
481 
482 	if (config->nvm_size)
483 		acpi_dp_add_integer(dsd, "size", config->nvm_size);
484 
485 	if (config->nvm_pagesize)
486 		acpi_dp_add_integer(dsd, "pagesize", config->nvm_pagesize);
487 
488 	if (config->nvm_readonly)
489 		acpi_dp_add_integer(dsd, "read-only", config->nvm_readonly);
490 
491 	if (config->nvm_width)
492 		acpi_dp_add_integer(dsd, "address-width", config->nvm_width);
493 
494 	acpi_dp_add_string(dsd, "compatible", config->nvm_compat);
495 
496 	if (config->low_power_probe)
497 		acpi_dp_add_integer(dsd, "i2c-allow-low-power-probe", 0x01);
498 
499 	acpi_dp_write(dsd);
500 }
501 
camera_fill_vcm(const struct device * dev)502 static void camera_fill_vcm(const struct device *dev)
503 {
504 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
505 	struct acpi_dp *dsd;
506 
507 	if (!config->vcm_compat)
508 		return;
509 
510 	dsd = acpi_dp_new_table("_DSD");
511 	acpi_dp_add_string(dsd, "compatible", config->vcm_compat);
512 
513 	if (config->low_power_probe)
514 		acpi_dp_add_integer(dsd, "i2c-allow-low-power-probe", 0x01);
515 
516 	acpi_dp_write(dsd);
517 }
518 
get_resource_index(const struct resource_config * res_config)519 static int get_resource_index(const struct resource_config *res_config)
520 {
521 	enum ctrl_type type = resource_get_ctrl_type(res_config);
522 	const struct clk_config *clk_config;
523 	const struct gpio_config *gpio_config;
524 	unsigned int i;
525 	uint8_t res_id;
526 
527 	switch (type) {
528 	case IMGCLK:
529 		clk_config = resource_clk_config(res_config);
530 		res_id = clk_config->clknum;
531 		break;
532 	case GPIO:
533 		gpio_config = resource_gpio_config(res_config);
534 		res_id = gpio_config->gpio_num;
535 		break;
536 	default:
537 		printk(BIOS_ERR, "Unsupported power operation: %x\n"
538 				 "OS camera driver will likely not work", type);
539 		return -1;
540 	}
541 
542 	for (i = 0; i < res_mgr.cnt; i++)
543 		if (res_mgr.resource[i].type == type && res_mgr.resource[i].id == res_id)
544 			return i;
545 
546 	return -1;
547 }
548 
add_guarded_method_namestring(struct resource_config * res_config,int res_index)549 static void add_guarded_method_namestring(struct resource_config *res_config, int res_index)
550 {
551 	char method_name[ACPI_NAME_BUFFER_SIZE];
552 	enum action_type action = resource_get_action_type(res_config);
553 
554 	switch (action) {
555 	case ENABLE:
556 		snprintf(method_name, sizeof(method_name), ENABLE_METHOD_FORMAT, res_index);
557 		break;
558 	case DISABLE:
559 		snprintf(method_name, sizeof(method_name), DISABLE_METHOD_FORMAT, res_index);
560 		break;
561 	default:
562 		snprintf(method_name, sizeof(method_name), UNKNOWN_METHOD_FORMAT, res_index);
563 		printk(BIOS_ERR, "Unsupported resource action: %x\n", action);
564 	}
565 
566 	acpigen_emit_namestring(method_name);
567 }
568 
call_guarded_method(struct resource_config * res_config)569 static void call_guarded_method(struct resource_config *res_config)
570 {
571 	int res_index;
572 
573 	if (res_config == NULL)
574 		return;
575 
576 	res_index = get_resource_index(res_config);
577 
578 	if (res_index != -1)
579 		add_guarded_method_namestring(res_config, res_index);
580 }
581 
add_clk_op(const struct clk_config * clk_config,enum action_type action)582 static void add_clk_op(const struct clk_config *clk_config, enum action_type action)
583 {
584 	if (clk_config == NULL)
585 		return;
586 
587 	switch (action) {
588 	case ENABLE:
589 		acpigen_write_if();
590 		acpigen_emit_ext_op(COND_REFOF_OP);
591 		acpigen_emit_string(CLK_ENABLE_METHOD);
592 		acpigen_emit_namestring(CLK_ENABLE_METHOD);
593 		acpigen_write_integer(clk_config->clknum);
594 		acpigen_write_integer(clk_config->freq);
595 		acpigen_pop_len(); /* CondRefOf */
596 		break;
597 	case DISABLE:
598 		acpigen_write_if();
599 		acpigen_emit_ext_op(COND_REFOF_OP);
600 		acpigen_emit_string(CLK_DISABLE_METHOD);
601 		acpigen_emit_namestring(CLK_DISABLE_METHOD);
602 		acpigen_write_integer(clk_config->clknum);
603 		acpigen_pop_len(); /* CondRefOf */
604 		break;
605 	default:
606 		acpigen_write_debug_string("Unsupported clock action");
607 		printk(BIOS_ERR, "Unsupported clock action: %x\n"
608 				 "OS camera driver will likely not work", action);
609 	}
610 }
611 
add_gpio_op(const struct gpio_config * gpio_config,enum action_type action)612 static void add_gpio_op(const struct gpio_config *gpio_config, enum action_type action)
613 {
614 	if (gpio_config == NULL)
615 		return;
616 
617 	switch (action) {
618 	case ENABLE:
619 		acpigen_soc_set_tx_gpio(gpio_config->gpio_num);
620 		break;
621 	case DISABLE:
622 		acpigen_soc_clear_tx_gpio(gpio_config->gpio_num);
623 		break;
624 	default:
625 		acpigen_write_debug_string("Unsupported GPIO action");
626 		printk(BIOS_ERR, "Unsupported GPIO action: %x\n"
627 				 "OS camera driver will likely not work\n", action);
628 	}
629 }
630 
add_power_operation(const struct resource_config * res_config)631 static void add_power_operation(const struct resource_config *res_config)
632 {
633 	const struct clk_config *clk_config;
634 	const struct gpio_config *gpio_config;
635 	enum ctrl_type type = resource_get_ctrl_type(res_config);
636 	enum action_type action = resource_get_action_type(res_config);
637 
638 	if (res_config == NULL)
639 		return;
640 
641 	switch (type) {
642 	case IMGCLK:
643 		clk_config = resource_clk_config(res_config);
644 		add_clk_op(clk_config, action);
645 		break;
646 	case GPIO:
647 		gpio_config = resource_gpio_config(res_config);
648 		add_gpio_op(gpio_config, action);
649 		break;
650 	default:
651 		printk(BIOS_ERR, "Unsupported power operation: %x\n"
652 				 "OS camera driver will likely not work\n", type);
653 		break;
654 	}
655 }
656 
write_guard_variable(uint8_t res_index)657 static void write_guard_variable(uint8_t res_index)
658 {
659 	char varname[ACPI_NAME_BUFFER_SIZE];
660 
661 	snprintf(varname, sizeof(varname), GUARD_VARIABLE_FORMAT, res_index);
662 	acpigen_write_name_integer(varname, 0);
663 }
664 
write_enable_method(struct resource_config * res_config,uint8_t res_index)665 static void write_enable_method(struct resource_config *res_config, uint8_t res_index)
666 {
667 	char method_name[ACPI_NAME_BUFFER_SIZE];
668 	char varname[ACPI_NAME_BUFFER_SIZE];
669 
670 	snprintf(varname, sizeof(varname), GUARD_VARIABLE_FORMAT, res_index);
671 
672 	snprintf(method_name, sizeof(method_name), ENABLE_METHOD_FORMAT, res_index);
673 
674 	acpigen_write_method_serialized(method_name, 0);
675 	acpigen_write_if_lequal_namestr_int(varname, 0);
676 	resource_set_action_type(res_config, ENABLE);
677 	add_power_operation(res_config);
678 	acpigen_pop_len(); /* if */
679 
680 	acpigen_emit_byte(INCREMENT_OP);
681 	acpigen_emit_namestring(varname);
682 	acpigen_pop_len(); /* method_name */
683 }
684 
write_disable_method(struct resource_config * res_config,uint8_t res_index)685 static void write_disable_method(struct resource_config *res_config, uint8_t res_index)
686 {
687 	char method_name[ACPI_NAME_BUFFER_SIZE];
688 	char varname[ACPI_NAME_BUFFER_SIZE];
689 
690 	snprintf(varname, sizeof(varname), GUARD_VARIABLE_FORMAT, res_index);
691 
692 	snprintf(method_name, sizeof(method_name), DISABLE_METHOD_FORMAT, res_index);
693 
694 	acpigen_write_method_serialized(method_name, 0);
695 	acpigen_write_if();
696 	acpigen_emit_byte(LGREATER_OP);
697 	acpigen_emit_namestring(varname);
698 	acpigen_write_integer(0x0);
699 	acpigen_emit_byte(DECREMENT_OP);
700 	acpigen_emit_namestring(varname);
701 	acpigen_pop_len(); /* if */
702 
703 	acpigen_write_if_lequal_namestr_int(varname, 0);
704 	resource_set_action_type(res_config, DISABLE);
705 	add_power_operation(res_config);
706 	acpigen_pop_len(); /* if */
707 	acpigen_pop_len(); /* method_name */
708 }
709 
add_guarded_operations(const struct drivers_intel_mipi_camera_config * config,const struct operation_seq * seq)710 static void add_guarded_operations(const struct drivers_intel_mipi_camera_config *config,
711 				   const struct operation_seq *seq)
712 {
713 	unsigned int i;
714 	uint8_t index;
715 	uint8_t res_id;
716 	struct resource_config res_config;
717 	int res_index;
718 
719 	for (i = 0; i < seq->ops_cnt && i < MAX_PWR_OPS; i++) {
720 		index = seq->ops[i].index;
721 		switch (seq->ops[i].type) {
722 		case IMGCLK:
723 			res_id = config->clk_panel.clks[index].clknum;
724 			resource_set_clk_config(&res_config, &config->clk_panel.clks[index]);
725 			break;
726 		case GPIO:
727 			res_id = config->gpio_panel.gpio[index].gpio_num;
728 			resource_set_gpio_config(&res_config, &config->gpio_panel.gpio[index]);
729 			break;
730 		default:
731 			printk(BIOS_ERR, "Unsupported power operation: %x\n"
732 					 "OS camera driver will likely not work\n",
733 					 seq->ops[i].type);
734 			return;
735 		}
736 
737 		res_index = get_resource_index(&res_config);
738 
739 		if (res_index == -1) {
740 			if (res_mgr.cnt >= MAX_GUARDED_RESOURCES) {
741 				printk(BIOS_ERR, "Unable to add guarded camera resource\n"
742 						 "OS camera driver will likely not work\n");
743 				return;
744 			}
745 
746 			res_mgr.resource[res_mgr.cnt].id = res_id;
747 			res_mgr.resource[res_mgr.cnt].type = seq->ops[i].type;
748 
749 			write_guard_variable(res_mgr.cnt);
750 			write_enable_method(&res_config, res_mgr.cnt);
751 			write_disable_method(&res_config, res_mgr.cnt);
752 
753 			res_mgr.cnt++;
754 		}
755 	}
756 }
757 
fill_power_res_sequence(struct drivers_intel_mipi_camera_config * config,struct operation_seq * seq)758 static void fill_power_res_sequence(struct drivers_intel_mipi_camera_config *config,
759 				    struct operation_seq *seq)
760 {
761 	struct resource_config res_config;
762 	unsigned int i;
763 	uint8_t index;
764 
765 	for (i = 0; i < seq->ops_cnt && i < MAX_PWR_OPS; i++) {
766 		index = seq->ops[i].index;
767 
768 		switch (seq->ops[i].type) {
769 		case IMGCLK:
770 			resource_set_clk_config(&res_config, &config->clk_panel.clks[index]);
771 			break;
772 		case GPIO:
773 			resource_set_gpio_config(&res_config, &config->gpio_panel.gpio[index]);
774 			break;
775 		default:
776 			printk(BIOS_ERR, "Unsupported power operation: %x\n"
777 					 "OS camera driver will likely not work\n",
778 					 seq->ops[i].type);
779 			return;
780 		}
781 
782 		resource_set_action_type(&res_config, seq->ops[i].action);
783 		call_guarded_method(&res_config);
784 		if (seq->ops[i].delay_ms)
785 			acpigen_write_sleep(seq->ops[i].delay_ms);
786 	}
787 }
788 
write_pci_camera_device(const struct device * dev)789 static void write_pci_camera_device(const struct device *dev)
790 {
791 	if (dev->path.type != DEVICE_PATH_PCI) {
792 		printk(BIOS_ERR, "CIO2/IMGU devices require PCI\n");
793 		return;
794 	}
795 
796 	acpigen_write_device(acpi_device_name(dev));
797 	acpigen_write_ADR_pci_device(dev);
798 	acpigen_write_name_string("_DDN", "Camera and Imaging Subsystem");
799 }
800 
write_i2c_camera_device(const struct device * dev,const char * scope)801 static void write_i2c_camera_device(const struct device *dev, const char *scope)
802 {
803 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
804 	struct acpi_i2c i2c = {
805 		.address = dev->path.i2c.device,
806 		.mode_10bit = dev->path.i2c.mode_10bit,
807 		.speed = I2C_SPEED_FAST,
808 		.resource = scope,
809 	};
810 
811 	acpigen_write_device(acpi_device_name(dev));
812 
813 	/* add power resource */
814 	if (config->has_power_resource) {
815 		acpigen_write_power_res(POWER_RESOURCE_NAME, 0, 0, NULL, 0);
816 		acpigen_write_name_integer("STA", 0);
817 		acpigen_write_STA_ext("STA");
818 
819 		acpigen_write_method_serialized("_ON", 0);
820 		acpigen_write_if();
821 		acpigen_emit_byte(LEQUAL_OP);
822 		acpigen_emit_namestring("STA");
823 		acpigen_write_integer(0);
824 
825 		fill_power_res_sequence(config, &config->on_seq);
826 
827 		acpigen_write_store_op_to_namestr(1, "STA");
828 		acpigen_pop_len(); /* if */
829 		acpigen_pop_len(); /* _ON */
830 
831 		/* _OFF operations */
832 		acpigen_write_method_serialized("_OFF", 0);
833 		acpigen_write_if();
834 		acpigen_emit_byte(LEQUAL_OP);
835 		acpigen_emit_namestring("STA");
836 		acpigen_write_integer(1);
837 
838 		fill_power_res_sequence(config, &config->off_seq);
839 
840 		acpigen_write_store_op_to_namestr(0, "STA");
841 		acpigen_pop_len(); /* if */
842 		acpigen_pop_len(); /* _ON */
843 
844 		acpigen_pop_len(); /* Power Resource */
845 	}
846 
847 	if (config->device_type == INTEL_ACPI_CAMERA_SENSOR)
848 		acpigen_write_name_integer("_ADR", 0);
849 
850 	if (config->acpi_hid)
851 		acpigen_write_name_string("_HID", config->acpi_hid);
852 	else if (config->device_type == INTEL_ACPI_CAMERA_VCM ||
853 		 config->device_type == INTEL_ACPI_CAMERA_NVM)
854 		acpigen_write_name_string("_HID", ACPI_DT_NAMESPACE_HID);
855 
856 	acpigen_write_name_integer("_UID", config->acpi_uid);
857 	acpigen_write_name_string("_DDN", config->chip_name);
858 	acpigen_write_STA(acpi_device_status(dev));
859 	acpigen_write_method("_DSC", 0);
860 	acpigen_write_return_integer(config->max_dstate_for_probe);
861 	acpigen_pop_len(); /* Method _DSC */
862 
863 	/* Resources */
864 	acpigen_write_name("_CRS");
865 	acpigen_write_resourcetemplate_header();
866 	acpi_device_write_i2c(&i2c);
867 
868 	/*
869 	 * The optional vcm/nvram devices are presumed to be on the same I2C bus as the camera
870 	 * sensor.
871 	 */
872 	if (config->device_type == INTEL_ACPI_CAMERA_SENSOR &&
873 	    config->ssdb.vcm_type && config->vcm_address) {
874 		struct acpi_i2c i2c_vcm = i2c;
875 		i2c_vcm.address = config->vcm_address;
876 		acpi_device_write_i2c(&i2c_vcm);
877 	}
878 
879 	if (config->device_type == INTEL_ACPI_CAMERA_SENSOR &&
880 	    config->ssdb.rom_type && config->rom_address) {
881 		struct acpi_i2c i2c_rom = i2c;
882 		i2c_rom.address = config->rom_address;
883 		acpi_device_write_i2c(&i2c_rom);
884 	}
885 
886 	acpigen_write_resourcetemplate_footer();
887 }
888 
write_camera_device_common(const struct device * dev)889 static void write_camera_device_common(const struct device *dev)
890 {
891 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
892 
893 	/* Mark it as Camera related device */
894 	if (config->device_type == INTEL_ACPI_CAMERA_CIO2 ||
895 	    config->device_type == INTEL_ACPI_CAMERA_IMGU ||
896 	    config->device_type == INTEL_ACPI_CAMERA_SENSOR ||
897 	    config->device_type == INTEL_ACPI_CAMERA_VCM) {
898 		acpigen_write_name_integer("CAMD", config->device_type);
899 	}
900 
901 	if (config->pr0 || config->has_power_resource) {
902 		acpigen_write_name("_PR0");
903 		acpigen_write_package(1);
904 		if (config->pr0)
905 			acpigen_emit_namestring(config->pr0); /* External power resource */
906 		else
907 			acpigen_emit_namestring(POWER_RESOURCE_NAME);
908 
909 		acpigen_pop_len(); /* _PR0 */
910 	}
911 
912 	switch (config->device_type) {
913 	case INTEL_ACPI_CAMERA_CIO2:
914 		camera_fill_cio2(dev);
915 		break;
916 	case INTEL_ACPI_CAMERA_SENSOR:
917 		camera_fill_sensor(dev);
918 		break;
919 	case INTEL_ACPI_CAMERA_VCM:
920 		camera_fill_vcm(dev);
921 		break;
922 	case INTEL_ACPI_CAMERA_NVM:
923 		camera_fill_nvm(dev);
924 		break;
925 	default:
926 		break;
927 	}
928 }
929 
camera_fill_ssdt(const struct device * dev)930 static void camera_fill_ssdt(const struct device *dev)
931 {
932 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
933 	const char *scope = NULL;
934 	const struct device *pdev;
935 
936 	if (config->has_power_resource) {
937 		pdev = dev->upstream->dev;
938 		if (!pdev || !pdev->enabled)
939 			return;
940 
941 		scope = acpi_device_scope(pdev);
942 		if (!scope)
943 			return;
944 
945 		acpigen_write_scope(scope);
946 		add_guarded_operations(config, &config->on_seq);
947 		add_guarded_operations(config, &config->off_seq);
948 		acpigen_pop_len(); /* Guarded power resource operations scope */
949 	}
950 
951 	switch (dev->path.type) {
952 	case DEVICE_PATH_I2C:
953 		scope = acpi_device_scope(dev);
954 		if (!scope)
955 			return;
956 
957 		acpigen_write_scope(scope);
958 		write_i2c_camera_device(dev, scope);
959 		break;
960 	case DEVICE_PATH_GENERIC:
961 		pdev = dev->upstream->dev;
962 		scope = acpi_device_scope(pdev);
963 		if (!scope)
964 			return;
965 
966 		acpigen_write_scope(scope);
967 		write_pci_camera_device(pdev);
968 		break;
969 	default:
970 		printk(BIOS_ERR, "Unsupported device type: %x\n"
971 				 "OS camera driver will likely not work\n", dev->path.type);
972 		return;
973 	}
974 
975 	write_camera_device_common(dev);
976 
977 	acpigen_pop_len(); /* Device */
978 	acpigen_pop_len(); /* Scope */
979 
980 	if (dev->path.type == DEVICE_PATH_PCI) {
981 		printk(BIOS_INFO, "%s: %s PCI address 0%x\n", acpi_device_path(dev),
982 		       dev->chip_ops->name, dev->path.pci.devfn);
983 	} else {
984 		printk(BIOS_INFO, "%s: %s I2C address 0%xh\n", acpi_device_path(dev),
985 		       dev->chip_ops->name, dev->path.i2c.device);
986 	}
987 }
988 
camera_acpi_name(const struct device * dev)989 static const char *camera_acpi_name(const struct device *dev)
990 {
991 	const char *prefix = NULL;
992 	static char name[ACPI_NAME_BUFFER_SIZE];
993 	struct drivers_intel_mipi_camera_config *config = dev->chip_info;
994 
995 	if (config->acpi_name)
996 		return config->acpi_name;
997 
998 	switch (config->device_type) {
999 	case INTEL_ACPI_CAMERA_CIO2:
1000 		return "CIO2";
1001 	case INTEL_ACPI_CAMERA_IMGU:
1002 		return "IMGU";
1003 	case INTEL_ACPI_CAMERA_PMIC:
1004 		return "PMIC";
1005 	case INTEL_ACPI_CAMERA_SENSOR:
1006 		prefix = "CAM";
1007 		break;
1008 	case INTEL_ACPI_CAMERA_VCM:
1009 		prefix = "VCM";
1010 		break;
1011 	case INTEL_ACPI_CAMERA_NVM:
1012 		prefix = "NVM";
1013 		break;
1014 	default:
1015 		printk(BIOS_ERR, "Invalid device type: %x\n", config->device_type);
1016 		return NULL;
1017 	}
1018 
1019 	/*
1020 	 * The camera # knows which link # they use, so that's used as the basis for the
1021 	 * instance #. The VCM and NVM don't have this information, so the best we can go on is
1022 	 * the _UID.
1023 	 */
1024 	snprintf(name, sizeof(name), "%s%1u", prefix,
1025 		 config->device_type == INTEL_ACPI_CAMERA_SENSOR ?
1026 		 config->ssdb.link_used : config->acpi_uid);
1027 	return name;
1028 }
1029 
1030 static struct device_operations camera_ops = {
1031 	.read_resources		= noop_read_resources,
1032 	.set_resources		= noop_set_resources,
1033 	.acpi_name		= camera_acpi_name,
1034 	.acpi_fill_ssdt		= camera_fill_ssdt,
1035 };
1036 
camera_enable(struct device * dev)1037 static void camera_enable(struct device *dev)
1038 {
1039 	dev->ops = &camera_ops;
1040 }
1041 
1042 struct chip_operations drivers_intel_mipi_camera_ops = {
1043 	.name = "Intel MIPI Camera Device",
1044 	.enable_dev = camera_enable
1045 };
1046