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