1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Author: Dan Scally <djrscally@gmail.com> */
3 #ifndef __CIO2_BRIDGE_H
4 #define __CIO2_BRIDGE_H
5 
6 #include <linux/property.h>
7 #include <linux/types.h>
8 
9 #include "ipu3-cio2.h"
10 
11 struct i2c_client;
12 
13 #define CIO2_HID				"INT343E"
14 #define CIO2_MAX_LANES				4
15 #define MAX_NUM_LINK_FREQS			3
16 
17 /* Values are educated guesses as we don't have a spec */
18 #define CIO2_SENSOR_ROTATION_NORMAL		0
19 #define CIO2_SENSOR_ROTATION_INVERTED		1
20 
21 #define CIO2_SENSOR_CONFIG(_HID, _NR, ...)	\
22 	(const struct cio2_sensor_config) {	\
23 		.hid = _HID,			\
24 		.nr_link_freqs = _NR,		\
25 		.link_freqs = { __VA_ARGS__ }	\
26 	}
27 
28 #define NODE_SENSOR(_HID, _PROPS)		\
29 	(const struct software_node) {		\
30 		.name = _HID,			\
31 		.properties = _PROPS,		\
32 	}
33 
34 #define NODE_PORT(_PORT, _SENSOR_NODE)		\
35 	(const struct software_node) {		\
36 		.name = _PORT,			\
37 		.parent = _SENSOR_NODE,		\
38 	}
39 
40 #define NODE_ENDPOINT(_EP, _PORT, _PROPS)	\
41 	(const struct software_node) {		\
42 		.name = _EP,			\
43 		.parent = _PORT,		\
44 		.properties = _PROPS,		\
45 	}
46 
47 #define NODE_VCM(_TYPE)				\
48 	(const struct software_node) {		\
49 		.name = _TYPE,			\
50 	}
51 
52 enum cio2_sensor_swnodes {
53 	SWNODE_SENSOR_HID,
54 	SWNODE_SENSOR_PORT,
55 	SWNODE_SENSOR_ENDPOINT,
56 	SWNODE_CIO2_PORT,
57 	SWNODE_CIO2_ENDPOINT,
58 	/* Must be last because it is optional / maybe empty */
59 	SWNODE_VCM,
60 	SWNODE_COUNT
61 };
62 
63 /* Data representation as it is in ACPI SSDB buffer */
64 struct cio2_sensor_ssdb {
65 	u8 version;
66 	u8 sku;
67 	u8 guid_csi2[16];
68 	u8 devfunction;
69 	u8 bus;
70 	u32 dphylinkenfuses;
71 	u32 clockdiv;
72 	u8 link;
73 	u8 lanes;
74 	u32 csiparams[10];
75 	u32 maxlanespeed;
76 	u8 sensorcalibfileidx;
77 	u8 sensorcalibfileidxInMBZ[3];
78 	u8 romtype;
79 	u8 vcmtype;
80 	u8 platforminfo;
81 	u8 platformsubinfo;
82 	u8 flash;
83 	u8 privacyled;
84 	u8 degree;
85 	u8 mipilinkdefined;
86 	u32 mclkspeed;
87 	u8 controllogicid;
88 	u8 reserved1[3];
89 	u8 mclkport;
90 	u8 reserved2[13];
91 } __packed;
92 
93 struct cio2_property_names {
94 	char clock_frequency[16];
95 	char rotation[9];
96 	char orientation[12];
97 	char bus_type[9];
98 	char data_lanes[11];
99 	char remote_endpoint[16];
100 	char link_frequencies[17];
101 };
102 
103 struct cio2_node_names {
104 	char port[7];
105 	char endpoint[11];
106 	char remote_port[7];
107 };
108 
109 struct cio2_sensor_config {
110 	const char *hid;
111 	const u8 nr_link_freqs;
112 	const u64 link_freqs[MAX_NUM_LINK_FREQS];
113 };
114 
115 struct cio2_sensor {
116 	char name[ACPI_ID_LEN];
117 	struct acpi_device *adev;
118 	struct i2c_client *vcm_i2c_client;
119 
120 	/* SWNODE_COUNT + 1 for terminating empty node */
121 	struct software_node swnodes[SWNODE_COUNT + 1];
122 	struct cio2_node_names node_names;
123 
124 	struct cio2_sensor_ssdb ssdb;
125 	struct acpi_pld_info *pld;
126 
127 	struct cio2_property_names prop_names;
128 	struct property_entry ep_properties[5];
129 	struct property_entry dev_properties[5];
130 	struct property_entry cio2_properties[3];
131 	struct software_node_ref_args local_ref[1];
132 	struct software_node_ref_args remote_ref[1];
133 	struct software_node_ref_args vcm_ref[1];
134 };
135 
136 struct cio2_bridge {
137 	char cio2_node_name[ACPI_ID_LEN];
138 	struct software_node cio2_hid_node;
139 	u32 data_lanes[4];
140 	unsigned int n_sensors;
141 	struct cio2_sensor sensors[CIO2_NUM_PORTS];
142 };
143 
144 #endif
145