1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Author: Dan Scally <djrscally@gmail.com> */ 3 #ifndef __IPU_BRIDGE_H 4 #define __IPU_BRIDGE_H 5 6 #include <linux/property.h> 7 #include <linux/types.h> 8 #include <media/v4l2-fwnode.h> 9 10 #define IPU_HID "INT343E" 11 #define IPU_MAX_LANES 4 12 #define IPU_MAX_PORTS 4 13 #define MAX_NUM_LINK_FREQS 3 14 15 /* Values are educated guesses as we don't have a spec */ 16 #define IPU_SENSOR_ROTATION_NORMAL 0 17 #define IPU_SENSOR_ROTATION_INVERTED 1 18 19 #define IPU_SENSOR_CONFIG(_HID, _NR, ...) \ 20 (const struct ipu_sensor_config) { \ 21 .hid = _HID, \ 22 .nr_link_freqs = _NR, \ 23 .link_freqs = { __VA_ARGS__ } \ 24 } 25 26 #define NODE_SENSOR(_HID, _PROPS) \ 27 (const struct software_node) { \ 28 .name = _HID, \ 29 .properties = _PROPS, \ 30 } 31 32 #define NODE_PORT(_PORT, _SENSOR_NODE) \ 33 (const struct software_node) { \ 34 .name = _PORT, \ 35 .parent = _SENSOR_NODE, \ 36 } 37 38 #define NODE_ENDPOINT(_EP, _PORT, _PROPS) \ 39 (const struct software_node) { \ 40 .name = _EP, \ 41 .parent = _PORT, \ 42 .properties = _PROPS, \ 43 } 44 45 #define NODE_VCM(_TYPE) \ 46 (const struct software_node) { \ 47 .name = _TYPE, \ 48 } 49 50 enum ipu_sensor_swnodes { 51 SWNODE_SENSOR_HID, 52 SWNODE_SENSOR_PORT, 53 SWNODE_SENSOR_ENDPOINT, 54 SWNODE_IPU_PORT, 55 SWNODE_IPU_ENDPOINT, 56 /* below are optional / maybe empty */ 57 SWNODE_IVSC_HID, 58 SWNODE_IVSC_SENSOR_PORT, 59 SWNODE_IVSC_SENSOR_ENDPOINT, 60 SWNODE_IVSC_IPU_PORT, 61 SWNODE_IVSC_IPU_ENDPOINT, 62 SWNODE_VCM, 63 SWNODE_COUNT 64 }; 65 66 /* Data representation as it is in ACPI SSDB buffer */ 67 struct ipu_sensor_ssdb { 68 u8 version; 69 u8 sku; 70 u8 guid_csi2[16]; 71 u8 devfunction; 72 u8 bus; 73 u32 dphylinkenfuses; 74 u32 clockdiv; 75 u8 link; 76 u8 lanes; 77 u32 csiparams[10]; 78 u32 maxlanespeed; 79 u8 sensorcalibfileidx; 80 u8 sensorcalibfileidxInMBZ[3]; 81 u8 romtype; 82 u8 vcmtype; 83 u8 platforminfo; 84 u8 platformsubinfo; 85 u8 flash; 86 u8 privacyled; 87 u8 degree; 88 u8 mipilinkdefined; 89 u32 mclkspeed; 90 u8 controllogicid; 91 u8 reserved1[3]; 92 u8 mclkport; 93 u8 reserved2[13]; 94 } __packed; 95 96 struct ipu_property_names { 97 char clock_frequency[16]; 98 char rotation[9]; 99 char orientation[12]; 100 char bus_type[9]; 101 char data_lanes[11]; 102 char remote_endpoint[16]; 103 char link_frequencies[17]; 104 }; 105 106 struct ipu_node_names { 107 char port[7]; 108 char ivsc_sensor_port[7]; 109 char ivsc_ipu_port[7]; 110 char endpoint[11]; 111 char remote_port[7]; 112 char vcm[16]; 113 }; 114 115 struct ipu_sensor_config { 116 const char *hid; 117 const u8 nr_link_freqs; 118 const u64 link_freqs[MAX_NUM_LINK_FREQS]; 119 }; 120 121 struct ipu_sensor { 122 /* append ssdb.link(u8) in "-%u" format as suffix of HID */ 123 char name[ACPI_ID_LEN + 4]; 124 struct acpi_device *adev; 125 126 struct device *csi_dev; 127 struct acpi_device *ivsc_adev; 128 char ivsc_name[ACPI_ID_LEN + 4]; 129 130 /* SWNODE_COUNT + 1 for terminating NULL */ 131 const struct software_node *group[SWNODE_COUNT + 1]; 132 struct software_node swnodes[SWNODE_COUNT]; 133 struct ipu_node_names node_names; 134 135 u8 link; 136 u8 lanes; 137 u32 mclkspeed; 138 u32 rotation; 139 enum v4l2_fwnode_orientation orientation; 140 const char *vcm_type; 141 142 struct ipu_property_names prop_names; 143 struct property_entry ep_properties[5]; 144 struct property_entry dev_properties[5]; 145 struct property_entry ipu_properties[3]; 146 struct property_entry ivsc_properties[1]; 147 struct property_entry ivsc_sensor_ep_properties[4]; 148 struct property_entry ivsc_ipu_ep_properties[4]; 149 150 struct software_node_ref_args local_ref[1]; 151 struct software_node_ref_args remote_ref[1]; 152 struct software_node_ref_args vcm_ref[1]; 153 struct software_node_ref_args ivsc_sensor_ref[1]; 154 struct software_node_ref_args ivsc_ipu_ref[1]; 155 }; 156 157 typedef int (*ipu_parse_sensor_fwnode_t)(struct acpi_device *adev, 158 struct ipu_sensor *sensor); 159 160 struct ipu_bridge { 161 struct device *dev; 162 ipu_parse_sensor_fwnode_t parse_sensor_fwnode; 163 char ipu_node_name[ACPI_ID_LEN]; 164 struct software_node ipu_hid_node; 165 u32 data_lanes[4]; 166 unsigned int n_sensors; 167 struct ipu_sensor sensors[IPU_MAX_PORTS]; 168 }; 169 170 #if IS_ENABLED(CONFIG_IPU_BRIDGE) 171 int ipu_bridge_init(struct device *dev, 172 ipu_parse_sensor_fwnode_t parse_sensor_fwnode); 173 int ipu_bridge_parse_ssdb(struct acpi_device *adev, struct ipu_sensor *sensor); 174 int ipu_bridge_instantiate_vcm(struct device *sensor); 175 #else 176 /* Use a define to avoid the @parse_sensor_fwnode argument getting evaluated */ 177 #define ipu_bridge_init(dev, parse_sensor_fwnode) (0) 178 static inline int ipu_bridge_instantiate_vcm(struct device *s) { return 0; } 179 #endif 180 181 #endif 182