1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Author: Dan Scally <djrscally@gmail.com> */
6 #include <linux/mod_devicetable.h>
7 #include <linux/property.h>
8 #include <linux/types.h>
9 #include <media/v4l2-fwnode.h>
11 #define IPU_HID "INT343E"
12 #define IPU_MAX_LANES 4
13 #define IPU_MAX_PORTS 4
14 #define MAX_NUM_LINK_FREQS 3
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
20 #define IPU_SENSOR_CONFIG(_HID, _NR, ...) \
21 (const struct ipu_sensor_config) { \
23 .nr_link_freqs = _NR, \
24 .link_freqs = { __VA_ARGS__ } \
27 #define NODE_SENSOR(_HID, _PROPS) \
28 (const struct software_node) { \
30 .properties = _PROPS, \
33 #define NODE_PORT(_PORT, _SENSOR_NODE) \
34 (const struct software_node) { \
36 .parent = _SENSOR_NODE, \
39 #define NODE_ENDPOINT(_EP, _PORT, _PROPS) \
40 (const struct software_node) { \
43 .properties = _PROPS, \
46 #define NODE_VCM(_TYPE) \
47 (const struct software_node) { \
51 enum ipu_sensor_swnodes
{
54 SWNODE_SENSOR_ENDPOINT
,
57 /* below are optional / maybe empty */
59 SWNODE_IVSC_SENSOR_PORT
,
60 SWNODE_IVSC_SENSOR_ENDPOINT
,
62 SWNODE_IVSC_IPU_ENDPOINT
,
67 /* Data representation as it is in ACPI SSDB buffer */
68 struct ipu_sensor_ssdb
{
80 u8 sensorcalibfileidx
;
81 u8 sensorcalibfileidxInMBZ
[3];
97 struct ipu_property_names
{
98 char clock_frequency
[16];
100 char orientation
[12];
103 char remote_endpoint
[16];
104 char link_frequencies
[17];
107 struct ipu_node_names
{
109 char ivsc_sensor_port
[7];
110 char ivsc_ipu_port
[7];
116 struct ipu_sensor_config
{
118 const u8 nr_link_freqs
;
119 const u64 link_freqs
[MAX_NUM_LINK_FREQS
];
123 /* append ssdb.link(u8) in "-%u" format as suffix of HID */
124 char name
[ACPI_ID_LEN
+ 4];
125 struct acpi_device
*adev
;
127 struct device
*csi_dev
;
128 struct acpi_device
*ivsc_adev
;
129 char ivsc_name
[ACPI_ID_LEN
+ 4];
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
;
140 enum v4l2_fwnode_orientation orientation
;
141 const char *vcm_type
;
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];
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];
158 typedef int (*ipu_parse_sensor_fwnode_t
)(struct acpi_device
*adev
,
159 struct ipu_sensor
*sensor
);
163 ipu_parse_sensor_fwnode_t parse_sensor_fwnode
;
164 char ipu_node_name
[ACPI_ID_LEN
];
165 struct software_node ipu_hid_node
;
167 unsigned int n_sensors
;
168 struct ipu_sensor sensors
[IPU_MAX_PORTS
];
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
);
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; }