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