Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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
 51enum 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 */
 68struct 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
 97struct 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
107struct 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
116struct ipu_sensor_config {
117	const char *hid;
118	const u8 nr_link_freqs;
119	const u64 link_freqs[MAX_NUM_LINK_FREQS];
120};
121
122struct 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
158typedef int (*ipu_parse_sensor_fwnode_t)(struct acpi_device *adev,
159					 struct ipu_sensor *sensor);
160
161struct 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)
172int ipu_bridge_init(struct device *dev,
173		    ipu_parse_sensor_fwnode_t parse_sensor_fwnode);
174int ipu_bridge_parse_ssdb(struct acpi_device *adev, struct ipu_sensor *sensor);
175int 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)
179static inline int ipu_bridge_instantiate_vcm(struct device *s) { return 0; }
180#endif
181
182#endif