1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 2010-015, Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  */
15 
16 #include "system_global.h"
17 
18 #ifndef ISP2401
19 
20 #include "input_system.h"
21 #include <type_support.h>
22 #include "gp_device.h"
23 
24 #include "assert_support.h"
25 
26 #ifndef __INLINE_INPUT_SYSTEM__
27 #include "input_system_private.h"
28 #endif /* __INLINE_INPUT_SYSTEM__ */
29 
30 #define ZERO (0x0)
31 #define ONE  (1U)
32 
33 static const isp2400_ib_buffer_t   IB_BUFFER_NULL = {0, 0, 0 };
34 
35 static input_system_err_t input_system_configure_channel(
36     const channel_cfg_t		channel);
37 
38 static input_system_err_t input_system_configure_channel_sensor(
39     const channel_cfg_t		channel);
40 
41 static input_system_err_t input_buffer_configuration(void);
42 
43 static input_system_err_t configuration_to_registers(void);
44 
45 static void receiver_rst(const rx_ID_t ID);
46 static void input_system_network_rst(const input_system_ID_t ID);
47 
48 static void capture_unit_configure(
49     const input_system_ID_t			ID,
50     const sub_system_ID_t			sub_id,
51     const isp2400_ib_buffer_t *const cfg);
52 
53 static void acquisition_unit_configure(
54     const input_system_ID_t			ID,
55     const sub_system_ID_t			sub_id,
56     const isp2400_ib_buffer_t *const cfg);
57 
58 static void ctrl_unit_configure(
59     const input_system_ID_t			ID,
60     const sub_system_ID_t			sub_id,
61     const ctrl_unit_cfg_t *const cfg);
62 
63 static void input_system_network_configure(
64     const input_system_ID_t			ID,
65     const input_system_network_cfg_t *const cfg);
66 
67 // MW: CSI is previously named as "rx" short for "receiver"
68 static input_system_err_t set_csi_cfg(
69     csi_cfg_t *const lhs,
70     const csi_cfg_t *const rhs,
71     input_system_config_flags_t *const flags);
72 
73 static input_system_err_t set_source_type(
74     input_system_source_t *const lhs,
75     const input_system_source_t				rhs,
76     input_system_config_flags_t *const flags);
77 
78 static input_system_err_t input_system_multiplexer_cfg(
79     input_system_multiplex_t *const lhs,
80     const input_system_multiplex_t			rhs,
81     input_system_config_flags_t *const flags);
82 
83 static inline void capture_unit_get_state(
84     const input_system_ID_t			ID,
85     const sub_system_ID_t			sub_id,
86     capture_unit_state_t			*state);
87 
88 static inline void acquisition_unit_get_state(
89     const input_system_ID_t			ID,
90     const sub_system_ID_t			sub_id,
91     acquisition_unit_state_t		*state);
92 
93 static inline void ctrl_unit_get_state(
94     const input_system_ID_t			ID,
95     const sub_system_ID_t			sub_id,
96     ctrl_unit_state_t				*state);
97 
98 static inline void mipi_port_get_state(
99     const rx_ID_t					ID,
100     const enum mipi_port_id			port_ID,
101     mipi_port_state_t				*state);
102 
103 static inline void rx_channel_get_state(
104     const rx_ID_t					ID,
105     const unsigned int				ch_id,
106     rx_channel_state_t				*state);
107 
108 static void gp_device_rst(const gp_device_ID_t		ID);
109 
110 static void input_selector_cfg_for_sensor(const gp_device_ID_t	ID);
111 
112 static void input_switch_rst(const gp_device_ID_t	ID);
113 
114 static void input_switch_cfg(
115     const gp_device_ID_t				ID,
116     const input_switch_cfg_t *const cfg
117 );
118 
input_system_get_state(const input_system_ID_t ID,input_system_state_t * state)119 void input_system_get_state(
120     const input_system_ID_t			ID,
121     input_system_state_t			*state)
122 {
123 	sub_system_ID_t	sub_id;
124 
125 	assert(ID < N_INPUT_SYSTEM_ID);
126 	assert(state);
127 
128 	state->str_multicastA_sel = input_system_sub_system_reg_load(ID,
129 				    GPREGS_UNIT0_ID,
130 				    HIVE_ISYS_GPREG_MULTICAST_A_IDX);
131 	state->str_multicastB_sel = input_system_sub_system_reg_load(ID,
132 				    GPREGS_UNIT0_ID,
133 				    HIVE_ISYS_GPREG_MULTICAST_B_IDX);
134 	state->str_multicastC_sel = input_system_sub_system_reg_load(ID,
135 				    GPREGS_UNIT0_ID,
136 				    HIVE_ISYS_GPREG_MULTICAST_C_IDX);
137 	state->str_mux_sel = input_system_sub_system_reg_load(ID,
138 			     GPREGS_UNIT0_ID,
139 			     HIVE_ISYS_GPREG_MUX_IDX);
140 	state->str_mon_status = input_system_sub_system_reg_load(ID,
141 				GPREGS_UNIT0_ID,
142 				HIVE_ISYS_GPREG_STRMON_STAT_IDX);
143 	state->str_mon_irq_cond = input_system_sub_system_reg_load(ID,
144 				  GPREGS_UNIT0_ID,
145 				  HIVE_ISYS_GPREG_STRMON_COND_IDX);
146 	state->str_mon_irq_en = input_system_sub_system_reg_load(ID,
147 				GPREGS_UNIT0_ID,
148 				HIVE_ISYS_GPREG_STRMON_IRQ_EN_IDX);
149 	state->isys_srst = input_system_sub_system_reg_load(ID,
150 			   GPREGS_UNIT0_ID,
151 			   HIVE_ISYS_GPREG_SRST_IDX);
152 	state->isys_slv_reg_srst = input_system_sub_system_reg_load(ID,
153 				   GPREGS_UNIT0_ID,
154 				   HIVE_ISYS_GPREG_SLV_REG_SRST_IDX);
155 	state->str_deint_portA_cnt = input_system_sub_system_reg_load(ID,
156 				     GPREGS_UNIT0_ID,
157 				     HIVE_ISYS_GPREG_REG_PORT_A_IDX);
158 	state->str_deint_portB_cnt = input_system_sub_system_reg_load(ID,
159 				     GPREGS_UNIT0_ID,
160 				     HIVE_ISYS_GPREG_REG_PORT_B_IDX);
161 
162 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
163 	     sub_id++) {
164 		capture_unit_get_state(ID, sub_id,
165 				       &state->capture_unit[sub_id - CAPTURE_UNIT0_ID]);
166 	}
167 	for (sub_id = ACQUISITION_UNIT0_ID;
168 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
169 		acquisition_unit_get_state(ID, sub_id,
170 					   &state->acquisition_unit[sub_id - ACQUISITION_UNIT0_ID]);
171 	}
172 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
173 	     sub_id++) {
174 		ctrl_unit_get_state(ID, sub_id,
175 				    &state->ctrl_unit_state[sub_id - CTRL_UNIT0_ID]);
176 	}
177 
178 	return;
179 }
180 
receiver_get_state(const rx_ID_t ID,receiver_state_t * state)181 void receiver_get_state(
182     const rx_ID_t				ID,
183     receiver_state_t			*state)
184 {
185 	enum mipi_port_id	port_id;
186 	unsigned int	ch_id;
187 
188 	assert(ID < N_RX_ID);
189 	assert(state);
190 
191 	state->fs_to_ls_delay = (uint8_t)receiver_reg_load(ID,
192 				_HRT_CSS_RECEIVER_FS_TO_LS_DELAY_REG_IDX);
193 	state->ls_to_data_delay = (uint8_t)receiver_reg_load(ID,
194 				  _HRT_CSS_RECEIVER_LS_TO_DATA_DELAY_REG_IDX);
195 	state->data_to_le_delay = (uint8_t)receiver_reg_load(ID,
196 				  _HRT_CSS_RECEIVER_DATA_TO_LE_DELAY_REG_IDX);
197 	state->le_to_fe_delay = (uint8_t)receiver_reg_load(ID,
198 				_HRT_CSS_RECEIVER_LE_TO_FE_DELAY_REG_IDX);
199 	state->fe_to_fs_delay = (uint8_t)receiver_reg_load(ID,
200 				_HRT_CSS_RECEIVER_FE_TO_FS_DELAY_REG_IDX);
201 	state->le_to_fs_delay = (uint8_t)receiver_reg_load(ID,
202 				_HRT_CSS_RECEIVER_LE_TO_LS_DELAY_REG_IDX);
203 	state->is_two_ppc = (bool)receiver_reg_load(ID,
204 			    _HRT_CSS_RECEIVER_TWO_PIXEL_EN_REG_IDX);
205 	state->backend_rst = receiver_reg_load(ID,
206 					       _HRT_CSS_RECEIVER_BACKEND_RST_REG_IDX);
207 	state->raw18 = (uint16_t)receiver_reg_load(ID,
208 		       _HRT_CSS_RECEIVER_RAW18_REG_IDX);
209 	state->force_raw8 = (bool)receiver_reg_load(ID,
210 			    _HRT_CSS_RECEIVER_FORCE_RAW8_REG_IDX);
211 	state->raw16 = (uint16_t)receiver_reg_load(ID,
212 		       _HRT_CSS_RECEIVER_RAW16_REG_IDX);
213 
214 	for (port_id = (enum mipi_port_id)0; port_id < N_MIPI_PORT_ID; port_id++) {
215 		mipi_port_get_state(ID, port_id,
216 				    &state->mipi_port_state[port_id]);
217 	}
218 	for (ch_id = 0U; ch_id < N_RX_CHANNEL_ID; ch_id++) {
219 		rx_channel_get_state(ID, ch_id,
220 				     &state->rx_channel_state[ch_id]);
221 	}
222 
223 	state->be_gsp_acc_ovl = receiver_reg_load(ID,
224 				_HRT_CSS_RECEIVER_BE_GSP_ACC_OVL_REG_IDX);
225 	state->be_srst = receiver_reg_load(ID,
226 					   _HRT_CSS_RECEIVER_BE_SRST_REG_IDX);
227 	state->be_is_two_ppc = receiver_reg_load(ID,
228 			       _HRT_CSS_RECEIVER_BE_TWO_PPC_REG_IDX);
229 	state->be_comp_format0 = receiver_reg_load(ID,
230 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG0_IDX);
231 	state->be_comp_format1 = receiver_reg_load(ID,
232 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG1_IDX);
233 	state->be_comp_format2 = receiver_reg_load(ID,
234 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG2_IDX);
235 	state->be_comp_format3 = receiver_reg_load(ID,
236 				 _HRT_CSS_RECEIVER_BE_COMP_FORMAT_REG3_IDX);
237 	state->be_sel = receiver_reg_load(ID,
238 					  _HRT_CSS_RECEIVER_BE_SEL_REG_IDX);
239 	state->be_raw16_config = receiver_reg_load(ID,
240 				 _HRT_CSS_RECEIVER_BE_RAW16_CONFIG_REG_IDX);
241 	state->be_raw18_config = receiver_reg_load(ID,
242 				 _HRT_CSS_RECEIVER_BE_RAW18_CONFIG_REG_IDX);
243 	state->be_force_raw8 = receiver_reg_load(ID,
244 			       _HRT_CSS_RECEIVER_BE_FORCE_RAW8_REG_IDX);
245 	state->be_irq_status = receiver_reg_load(ID,
246 			       _HRT_CSS_RECEIVER_BE_IRQ_STATUS_REG_IDX);
247 	state->be_irq_clear = receiver_reg_load(ID,
248 						_HRT_CSS_RECEIVER_BE_IRQ_CLEAR_REG_IDX);
249 
250 	return;
251 }
252 
is_mipi_format_yuv420(const mipi_format_t mipi_format)253 bool is_mipi_format_yuv420(
254     const mipi_format_t			mipi_format)
255 {
256 	bool	is_yuv420 = (
257 				(mipi_format == MIPI_FORMAT_YUV420_8) ||
258 				(mipi_format == MIPI_FORMAT_YUV420_10) ||
259 				(mipi_format == MIPI_FORMAT_YUV420_8_SHIFT) ||
260 				(mipi_format == MIPI_FORMAT_YUV420_10_SHIFT));
261 	/* MIPI_FORMAT_YUV420_8_LEGACY is not YUV420 */
262 
263 	return is_yuv420;
264 }
265 
receiver_set_compression(const rx_ID_t ID,const unsigned int cfg_ID,const mipi_compressor_t comp,const mipi_predictor_t pred)266 void receiver_set_compression(
267     const rx_ID_t			ID,
268     const unsigned int		cfg_ID,
269     const mipi_compressor_t		comp,
270     const mipi_predictor_t		pred)
271 {
272 	const unsigned int		field_id = cfg_ID % N_MIPI_FORMAT_CUSTOM;
273 	const unsigned int		ch_id = cfg_ID / N_MIPI_FORMAT_CUSTOM;
274 	hrt_data			val;
275 	hrt_address			addr = 0;
276 	hrt_data			reg;
277 
278 	assert(ID < N_RX_ID);
279 	assert(cfg_ID < N_MIPI_COMPRESSOR_CONTEXT);
280 	assert(field_id < N_MIPI_FORMAT_CUSTOM);
281 	assert(ch_id < N_RX_CHANNEL_ID);
282 	assert(comp < N_MIPI_COMPRESSOR_METHODS);
283 	assert(pred < N_MIPI_PREDICTOR_TYPES);
284 
285 	val = (((uint8_t)pred) << 3) | comp;
286 
287 	switch (ch_id) {
288 	case 0:
289 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX :
290 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
291 		break;
292 	case 1:
293 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX :
294 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
295 		break;
296 	case 2:
297 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX :
298 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
299 		break;
300 	case 3:
301 		addr = ((field_id < 6) ? _HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX :
302 			_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
303 		break;
304 	default:
305 		/* should not happen */
306 		assert(false);
307 		return;
308 	}
309 
310 	reg = ((field_id < 6) ? (val << (field_id * 5)) : (val << ((
311 		    field_id - 6) * 5)));
312 	receiver_reg_store(ID, addr, reg);
313 
314 	return;
315 }
316 
receiver_port_enable(const rx_ID_t ID,const enum mipi_port_id port_ID,const bool cnd)317 void receiver_port_enable(
318     const rx_ID_t			ID,
319     const enum mipi_port_id		port_ID,
320     const bool			cnd)
321 {
322 	hrt_data	reg = receiver_port_reg_load(ID, port_ID,
323 			  _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
324 
325 	if (cnd) {
326 		reg |= 0x01;
327 	} else {
328 		reg &= ~0x01;
329 	}
330 
331 	receiver_port_reg_store(ID, port_ID,
332 				_HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX, reg);
333 	return;
334 }
335 
is_receiver_port_enabled(const rx_ID_t ID,const enum mipi_port_id port_ID)336 bool is_receiver_port_enabled(
337     const rx_ID_t			ID,
338     const enum mipi_port_id		port_ID)
339 {
340 	hrt_data	reg = receiver_port_reg_load(ID, port_ID,
341 			  _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
342 	return ((reg & 0x01) != 0);
343 }
344 
receiver_irq_enable(const rx_ID_t ID,const enum mipi_port_id port_ID,const rx_irq_info_t irq_info)345 void receiver_irq_enable(
346     const rx_ID_t			ID,
347     const enum mipi_port_id		port_ID,
348     const rx_irq_info_t		irq_info)
349 {
350 	receiver_port_reg_store(ID,
351 				port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX, irq_info);
352 	return;
353 }
354 
receiver_get_irq_info(const rx_ID_t ID,const enum mipi_port_id port_ID)355 rx_irq_info_t receiver_get_irq_info(
356     const rx_ID_t			ID,
357     const enum mipi_port_id		port_ID)
358 {
359 	return receiver_port_reg_load(ID,
360 				      port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
361 }
362 
receiver_irq_clear(const rx_ID_t ID,const enum mipi_port_id port_ID,const rx_irq_info_t irq_info)363 void receiver_irq_clear(
364     const rx_ID_t			ID,
365     const enum mipi_port_id		port_ID,
366     const rx_irq_info_t		irq_info)
367 {
368 	receiver_port_reg_store(ID,
369 				port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX, irq_info);
370 	return;
371 }
372 
capture_unit_get_state(const input_system_ID_t ID,const sub_system_ID_t sub_id,capture_unit_state_t * state)373 static inline void capture_unit_get_state(
374     const input_system_ID_t			ID,
375     const sub_system_ID_t			sub_id,
376     capture_unit_state_t			*state)
377 {
378 	assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <= CAPTURE_UNIT2_ID));
379 	assert(state);
380 
381 	state->StartMode = input_system_sub_system_reg_load(ID,
382 			   sub_id,
383 			   CAPT_START_MODE_REG_ID);
384 	state->Start_Addr = input_system_sub_system_reg_load(ID,
385 			    sub_id,
386 			    CAPT_START_ADDR_REG_ID);
387 	state->Mem_Region_Size = input_system_sub_system_reg_load(ID,
388 				 sub_id,
389 				 CAPT_MEM_REGION_SIZE_REG_ID);
390 	state->Num_Mem_Regions = input_system_sub_system_reg_load(ID,
391 				 sub_id,
392 				 CAPT_NUM_MEM_REGIONS_REG_ID);
393 //	AM: Illegal read from following registers.
394 	/*	state->Init = input_system_sub_system_reg_load(ID,
395 			sub_id,
396 			CAPT_INIT_REG_ID);
397 		state->Start = input_system_sub_system_reg_load(ID,
398 			sub_id,
399 			CAPT_START_REG_ID);
400 		state->Stop = input_system_sub_system_reg_load(ID,
401 			sub_id,
402 			CAPT_STOP_REG_ID);
403 	*/
404 	state->Packet_Length = input_system_sub_system_reg_load(ID,
405 			       sub_id,
406 			       CAPT_PACKET_LENGTH_REG_ID);
407 	state->Received_Length = input_system_sub_system_reg_load(ID,
408 				 sub_id,
409 				 CAPT_RECEIVED_LENGTH_REG_ID);
410 	state->Received_Short_Packets = input_system_sub_system_reg_load(ID,
411 					sub_id,
412 					CAPT_RECEIVED_SHORT_PACKETS_REG_ID);
413 	state->Received_Long_Packets = input_system_sub_system_reg_load(ID,
414 				       sub_id,
415 				       CAPT_RECEIVED_LONG_PACKETS_REG_ID);
416 	state->Last_Command = input_system_sub_system_reg_load(ID,
417 			      sub_id,
418 			      CAPT_LAST_COMMAND_REG_ID);
419 	state->Next_Command = input_system_sub_system_reg_load(ID,
420 			      sub_id,
421 			      CAPT_NEXT_COMMAND_REG_ID);
422 	state->Last_Acknowledge = input_system_sub_system_reg_load(ID,
423 				  sub_id,
424 				  CAPT_LAST_ACKNOWLEDGE_REG_ID);
425 	state->Next_Acknowledge = input_system_sub_system_reg_load(ID,
426 				  sub_id,
427 				  CAPT_NEXT_ACKNOWLEDGE_REG_ID);
428 	state->FSM_State_Info = input_system_sub_system_reg_load(ID,
429 				sub_id,
430 				CAPT_FSM_STATE_INFO_REG_ID);
431 
432 	return;
433 }
434 
acquisition_unit_get_state(const input_system_ID_t ID,const sub_system_ID_t sub_id,acquisition_unit_state_t * state)435 static inline void acquisition_unit_get_state(
436     const input_system_ID_t			ID,
437     const sub_system_ID_t			sub_id,
438     acquisition_unit_state_t		*state)
439 {
440 	assert(sub_id == ACQUISITION_UNIT0_ID);
441 	assert(state);
442 
443 	state->Start_Addr = input_system_sub_system_reg_load(ID,
444 			    sub_id,
445 			    ACQ_START_ADDR_REG_ID);
446 	state->Mem_Region_Size = input_system_sub_system_reg_load(ID,
447 				 sub_id,
448 				 ACQ_MEM_REGION_SIZE_REG_ID);
449 	state->Num_Mem_Regions = input_system_sub_system_reg_load(ID,
450 				 sub_id,
451 				 ACQ_NUM_MEM_REGIONS_REG_ID);
452 //	AM: Illegal read from following registers.
453 	/*	state->Init = input_system_sub_system_reg_load(ID,
454 			sub_id,
455 			ACQ_INIT_REG_ID);
456 	*/
457 	state->Received_Short_Packets = input_system_sub_system_reg_load(ID,
458 					sub_id,
459 					ACQ_RECEIVED_SHORT_PACKETS_REG_ID);
460 	state->Received_Long_Packets = input_system_sub_system_reg_load(ID,
461 				       sub_id,
462 				       ACQ_RECEIVED_LONG_PACKETS_REG_ID);
463 	state->Last_Command = input_system_sub_system_reg_load(ID,
464 			      sub_id,
465 			      ACQ_LAST_COMMAND_REG_ID);
466 	state->Next_Command = input_system_sub_system_reg_load(ID,
467 			      sub_id,
468 			      ACQ_NEXT_COMMAND_REG_ID);
469 	state->Last_Acknowledge = input_system_sub_system_reg_load(ID,
470 				  sub_id,
471 				  ACQ_LAST_ACKNOWLEDGE_REG_ID);
472 	state->Next_Acknowledge = input_system_sub_system_reg_load(ID,
473 				  sub_id,
474 				  ACQ_NEXT_ACKNOWLEDGE_REG_ID);
475 	state->FSM_State_Info = input_system_sub_system_reg_load(ID,
476 				sub_id,
477 				ACQ_FSM_STATE_INFO_REG_ID);
478 	state->Int_Cntr_Info = input_system_sub_system_reg_load(ID,
479 			       sub_id,
480 			       ACQ_INT_CNTR_INFO_REG_ID);
481 
482 	return;
483 }
484 
ctrl_unit_get_state(const input_system_ID_t ID,const sub_system_ID_t sub_id,ctrl_unit_state_t * state)485 static inline void ctrl_unit_get_state(
486     const input_system_ID_t			ID,
487     const sub_system_ID_t			sub_id,
488     ctrl_unit_state_t			*state)
489 {
490 	assert(sub_id == CTRL_UNIT0_ID);
491 	assert(state);
492 
493 	state->captA_start_addr = input_system_sub_system_reg_load(ID,
494 				  sub_id,
495 				  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID);
496 	state->captB_start_addr = input_system_sub_system_reg_load(ID,
497 				  sub_id,
498 				  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID);
499 	state->captC_start_addr = input_system_sub_system_reg_load(ID,
500 				  sub_id,
501 				  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID);
502 	state->captA_mem_region_size = input_system_sub_system_reg_load(ID,
503 				       sub_id,
504 				       ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID);
505 	state->captB_mem_region_size = input_system_sub_system_reg_load(ID,
506 				       sub_id,
507 				       ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID);
508 	state->captC_mem_region_size = input_system_sub_system_reg_load(ID,
509 				       sub_id,
510 				       ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID);
511 	state->captA_num_mem_regions = input_system_sub_system_reg_load(ID,
512 				       sub_id,
513 				       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID);
514 	state->captB_num_mem_regions = input_system_sub_system_reg_load(ID,
515 				       sub_id,
516 				       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID);
517 	state->captC_num_mem_regions = input_system_sub_system_reg_load(ID,
518 				       sub_id,
519 				       ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID);
520 	state->acq_start_addr = input_system_sub_system_reg_load(ID,
521 				sub_id,
522 				ISYS_CTRL_ACQ_START_ADDR_REG_ID);
523 	state->acq_mem_region_size = input_system_sub_system_reg_load(ID,
524 				     sub_id,
525 				     ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID);
526 	state->acq_num_mem_regions = input_system_sub_system_reg_load(ID,
527 				     sub_id,
528 				     ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID);
529 //	AM: Illegal read from following registers.
530 	/*	state->ctrl_init = input_system_sub_system_reg_load(ID,
531 			sub_id,
532 			ISYS_CTRL_INIT_REG_ID);
533 	*/
534 	state->last_cmd = input_system_sub_system_reg_load(ID,
535 			  sub_id,
536 			  ISYS_CTRL_LAST_COMMAND_REG_ID);
537 	state->next_cmd = input_system_sub_system_reg_load(ID,
538 			  sub_id,
539 			  ISYS_CTRL_NEXT_COMMAND_REG_ID);
540 	state->last_ack = input_system_sub_system_reg_load(ID,
541 			  sub_id,
542 			  ISYS_CTRL_LAST_ACKNOWLEDGE_REG_ID);
543 	state->next_ack = input_system_sub_system_reg_load(ID,
544 			  sub_id,
545 			  ISYS_CTRL_NEXT_ACKNOWLEDGE_REG_ID);
546 	state->top_fsm_state = input_system_sub_system_reg_load(ID,
547 			       sub_id,
548 			       ISYS_CTRL_FSM_STATE_INFO_REG_ID);
549 	state->captA_fsm_state = input_system_sub_system_reg_load(ID,
550 				 sub_id,
551 				 ISYS_CTRL_CAPT_A_FSM_STATE_INFO_REG_ID);
552 	state->captB_fsm_state = input_system_sub_system_reg_load(ID,
553 				 sub_id,
554 				 ISYS_CTRL_CAPT_B_FSM_STATE_INFO_REG_ID);
555 	state->captC_fsm_state = input_system_sub_system_reg_load(ID,
556 				 sub_id,
557 				 ISYS_CTRL_CAPT_C_FSM_STATE_INFO_REG_ID);
558 	state->acq_fsm_state = input_system_sub_system_reg_load(ID,
559 			       sub_id,
560 			       ISYS_CTRL_ACQ_FSM_STATE_INFO_REG_ID);
561 	state->capt_reserve_one_mem_region = input_system_sub_system_reg_load(ID,
562 					     sub_id,
563 					     ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID);
564 
565 	return;
566 }
567 
mipi_port_get_state(const rx_ID_t ID,const enum mipi_port_id port_ID,mipi_port_state_t * state)568 static inline void mipi_port_get_state(
569     const rx_ID_t				ID,
570     const enum mipi_port_id			port_ID,
571     mipi_port_state_t			*state)
572 {
573 	int	i;
574 
575 	assert(ID < N_RX_ID);
576 	assert(port_ID < N_MIPI_PORT_ID);
577 	assert(state);
578 
579 	state->device_ready = receiver_port_reg_load(ID,
580 			      port_ID, _HRT_CSS_RECEIVER_DEVICE_READY_REG_IDX);
581 	state->irq_status = receiver_port_reg_load(ID,
582 			    port_ID, _HRT_CSS_RECEIVER_IRQ_STATUS_REG_IDX);
583 	state->irq_enable = receiver_port_reg_load(ID,
584 			    port_ID, _HRT_CSS_RECEIVER_IRQ_ENABLE_REG_IDX);
585 	state->timeout_count = receiver_port_reg_load(ID,
586 			       port_ID, _HRT_CSS_RECEIVER_TIMEOUT_COUNT_REG_IDX);
587 	state->init_count = (uint16_t)receiver_port_reg_load(ID,
588 			    port_ID, _HRT_CSS_RECEIVER_INIT_COUNT_REG_IDX);
589 	state->raw16_18 = (uint16_t)receiver_port_reg_load(ID,
590 			  port_ID, _HRT_CSS_RECEIVER_RAW16_18_DATAID_REG_IDX);
591 	state->sync_count = receiver_port_reg_load(ID,
592 			    port_ID, _HRT_CSS_RECEIVER_SYNC_COUNT_REG_IDX);
593 	state->rx_count = receiver_port_reg_load(ID,
594 			  port_ID, _HRT_CSS_RECEIVER_RX_COUNT_REG_IDX);
595 
596 	for (i = 0; i < MIPI_4LANE_CFG ; i++) {
597 		state->lane_sync_count[i] = (uint8_t)((state->sync_count) >> (i * 8));
598 		state->lane_rx_count[i] = (uint8_t)((state->rx_count) >> (i * 8));
599 	}
600 
601 	return;
602 }
603 
rx_channel_get_state(const rx_ID_t ID,const unsigned int ch_id,rx_channel_state_t * state)604 static inline void rx_channel_get_state(
605     const rx_ID_t					ID,
606     const unsigned int				ch_id,
607     rx_channel_state_t				*state)
608 {
609 	int	i;
610 
611 	assert(ID < N_RX_ID);
612 	assert(ch_id < N_RX_CHANNEL_ID);
613 	assert(state);
614 
615 	switch (ch_id) {
616 	case 0:
617 		state->comp_scheme0 = receiver_reg_load(ID,
618 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG0_IDX);
619 		state->comp_scheme1 = receiver_reg_load(ID,
620 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC0_REG1_IDX);
621 		break;
622 	case 1:
623 		state->comp_scheme0 = receiver_reg_load(ID,
624 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG0_IDX);
625 		state->comp_scheme1 = receiver_reg_load(ID,
626 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC1_REG1_IDX);
627 		break;
628 	case 2:
629 		state->comp_scheme0 = receiver_reg_load(ID,
630 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG0_IDX);
631 		state->comp_scheme1 = receiver_reg_load(ID,
632 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC2_REG1_IDX);
633 		break;
634 	case 3:
635 		state->comp_scheme0 = receiver_reg_load(ID,
636 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG0_IDX);
637 		state->comp_scheme1 = receiver_reg_load(ID,
638 							_HRT_CSS_RECEIVER_2400_COMP_SCHEME_VC3_REG1_IDX);
639 		break;
640 	}
641 
642 	/* See Table 7.1.17,..., 7.1.24 */
643 	for (i = 0; i < 6; i++) {
644 		u8	val = (uint8_t)((state->comp_scheme0) >> (i * 5)) & 0x1f;
645 
646 		state->comp[i] = (mipi_compressor_t)(val & 0x07);
647 		state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3);
648 	}
649 	for (i = 6; i < N_MIPI_FORMAT_CUSTOM; i++) {
650 		u8	val = (uint8_t)((state->comp_scheme0) >> ((i - 6) * 5)) & 0x1f;
651 
652 		state->comp[i] = (mipi_compressor_t)(val & 0x07);
653 		state->pred[i] = (mipi_predictor_t)((val & 0x18) >> 3);
654 	}
655 
656 	return;
657 }
658 
659 // MW: "2400" in the name is not good, but this is to avoid a naming conflict
660 static input_system_cfg2400_t config;
661 
receiver_rst(const rx_ID_t ID)662 static void receiver_rst(
663     const rx_ID_t				ID)
664 {
665 	enum mipi_port_id		port_id;
666 
667 	assert(ID < N_RX_ID);
668 
669 // Disable all ports.
670 	for (port_id = MIPI_PORT0_ID; port_id < N_MIPI_PORT_ID; port_id++) {
671 		receiver_port_enable(ID, port_id, false);
672 	}
673 
674 	// AM: Additional actions for stopping receiver?
675 
676 	return;
677 }
678 
679 //Single function to reset all the devices mapped via GP_DEVICE.
gp_device_rst(const gp_device_ID_t ID)680 static void gp_device_rst(const gp_device_ID_t		ID)
681 {
682 	assert(ID < N_GP_DEVICE_ID);
683 
684 	gp_device_reg_store(ID, _REG_GP_SYNCGEN_ENABLE_ADDR, ZERO);
685 	// gp_device_reg_store(ID, _REG_GP_SYNCGEN_FREE_RUNNING_ADDR, ZERO);
686 	// gp_device_reg_store(ID, _REG_GP_SYNCGEN_PAUSE_ADDR, ONE);
687 	// gp_device_reg_store(ID, _REG_GP_NR_FRAMES_ADDR, ZERO);
688 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
689 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_PIX_ADDR, ZERO);
690 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_NR_LINES_ADDR, ZERO);
691 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_HBLANK_CYCLES_ADDR, ZERO);
692 	// gp_device_reg_store(ID, _REG_GP_SYNGEN_VBLANK_CYCLES_ADDR, ZERO);
693 // AM: Following calls cause strange warnings. Probably they should not be initialized.
694 //	gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ZERO);
695 //	gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ZERO);
696 //	gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ZERO);
697 //	gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ZERO);
698 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_ADDR, ZERO);
699 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_ENABLE_B_ADDR, ZERO);
700 	gp_device_reg_store(ID, _REG_GP_ISEL_LFSR_RESET_VALUE_ADDR, ZERO);
701 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_ADDR, ZERO);
702 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_ENABLE_B_ADDR, ZERO);
703 	gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_MASK_ADDR, ZERO);
704 	gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_MASK_ADDR, ZERO);
705 	gp_device_reg_store(ID, _REG_GP_ISEL_XY_CNT_MASK_ADDR, ZERO);
706 	gp_device_reg_store(ID, _REG_GP_ISEL_HOR_CNT_DELTA_ADDR, ZERO);
707 	gp_device_reg_store(ID, _REG_GP_ISEL_VER_CNT_DELTA_ADDR, ZERO);
708 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_MODE_ADDR, ZERO);
709 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED1_ADDR, ZERO);
710 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN1_ADDR, ZERO);
711 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE1_ADDR, ZERO);
712 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_RED2_ADDR, ZERO);
713 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_GREEN2_ADDR, ZERO);
714 	gp_device_reg_store(ID, _REG_GP_ISEL_TPG_BLUE2_ADDR, ZERO);
715 	//gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
716 	//gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
717 	gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
718 	gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
719 	gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
720 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_HOR_CNT_ADDR, ZERO);
721 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_VER_CNT_ADDR, ZERO);
722 	//	gp_device_reg_store(ID, _REG_GP_SYNCGEN_FRAME_CNT_ADDR, ZERO);
723 	gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR,
724 			    ZERO); // AM: Maybe this soft reset is not safe.
725 
726 	return;
727 }
728 
input_selector_cfg_for_sensor(const gp_device_ID_t ID)729 static void input_selector_cfg_for_sensor(const gp_device_ID_t ID)
730 {
731 	assert(ID < N_GP_DEVICE_ID);
732 
733 	gp_device_reg_store(ID, _REG_GP_ISEL_SOF_ADDR, ONE);
734 	gp_device_reg_store(ID, _REG_GP_ISEL_EOF_ADDR, ONE);
735 	gp_device_reg_store(ID, _REG_GP_ISEL_SOL_ADDR, ONE);
736 	gp_device_reg_store(ID, _REG_GP_ISEL_EOL_ADDR, ONE);
737 	gp_device_reg_store(ID, _REG_GP_ISEL_CH_ID_ADDR, ZERO);
738 	gp_device_reg_store(ID, _REG_GP_ISEL_FMT_TYPE_ADDR, ZERO);
739 	gp_device_reg_store(ID, _REG_GP_ISEL_DATA_SEL_ADDR, ZERO);
740 	gp_device_reg_store(ID, _REG_GP_ISEL_SBAND_SEL_ADDR, ZERO);
741 	gp_device_reg_store(ID, _REG_GP_ISEL_SYNC_SEL_ADDR, ZERO);
742 	gp_device_reg_store(ID, _REG_GP_SOFT_RESET_ADDR, ZERO);
743 
744 	return;
745 }
746 
input_switch_rst(const gp_device_ID_t ID)747 static void input_switch_rst(const gp_device_ID_t ID)
748 {
749 	int addr;
750 
751 	assert(ID < N_GP_DEVICE_ID);
752 
753 	// Initialize the data&hsync LUT.
754 	for (addr = _REG_GP_IFMT_input_switch_lut_reg0;
755 	     addr <= _REG_GP_IFMT_input_switch_lut_reg7; addr += SIZEOF_HRT_REG) {
756 		gp_device_reg_store(ID, addr, ZERO);
757 	}
758 
759 	// Initialize the vsync LUT.
760 	gp_device_reg_store(ID,
761 			    _REG_GP_IFMT_input_switch_fsync_lut,
762 			    ZERO);
763 
764 	return;
765 }
766 
input_switch_cfg(const gp_device_ID_t ID,const input_switch_cfg_t * const cfg)767 static void input_switch_cfg(
768     const gp_device_ID_t			ID,
769     const input_switch_cfg_t *const cfg)
770 {
771 	int addr_offset;
772 
773 	assert(ID < N_GP_DEVICE_ID);
774 	assert(cfg);
775 
776 	// Initialize the data&hsync LUT.
777 	for (addr_offset = 0; addr_offset < N_RX_CHANNEL_ID * 2; addr_offset++) {
778 		assert(addr_offset * SIZEOF_HRT_REG + _REG_GP_IFMT_input_switch_lut_reg0 <=
779 		       _REG_GP_IFMT_input_switch_lut_reg7);
780 		gp_device_reg_store(ID,
781 				    _REG_GP_IFMT_input_switch_lut_reg0 + addr_offset * SIZEOF_HRT_REG,
782 				    cfg->hsync_data_reg[addr_offset]);
783 	}
784 
785 	// Initialize the vsync LUT.
786 	gp_device_reg_store(ID,
787 			    _REG_GP_IFMT_input_switch_fsync_lut,
788 			    cfg->vsync_data_reg);
789 
790 	return;
791 }
792 
input_system_network_rst(const input_system_ID_t ID)793 static void input_system_network_rst(const input_system_ID_t ID)
794 {
795 	unsigned int sub_id;
796 
797 	// Reset all 3 multicasts.
798 	input_system_sub_system_reg_store(ID,
799 					  GPREGS_UNIT0_ID,
800 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
801 					  INPUT_SYSTEM_DISCARD_ALL);
802 	input_system_sub_system_reg_store(ID,
803 					  GPREGS_UNIT0_ID,
804 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
805 					  INPUT_SYSTEM_DISCARD_ALL);
806 	input_system_sub_system_reg_store(ID,
807 					  GPREGS_UNIT0_ID,
808 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
809 					  INPUT_SYSTEM_DISCARD_ALL);
810 
811 	// Reset stream mux.
812 	input_system_sub_system_reg_store(ID,
813 					  GPREGS_UNIT0_ID,
814 					  HIVE_ISYS_GPREG_MUX_IDX,
815 					  N_INPUT_SYSTEM_MULTIPLEX);
816 
817 	// Reset 3 capture units.
818 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
819 	     sub_id++) {
820 		input_system_sub_system_reg_store(ID,
821 						  sub_id,
822 						  CAPT_INIT_REG_ID,
823 						  1U << CAPT_INIT_RST_REG_BIT);
824 	}
825 
826 	// Reset acquisition unit.
827 	for (sub_id = ACQUISITION_UNIT0_ID;
828 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
829 		input_system_sub_system_reg_store(ID,
830 						  sub_id,
831 						  ACQ_INIT_REG_ID,
832 						  1U << ACQ_INIT_RST_REG_BIT);
833 	}
834 
835 	// DMA unit reset is not needed.
836 
837 	// Reset controller units.
838 	// NB: In future we need to keep part of ctrl_state for split capture and
839 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
840 	     sub_id++) {
841 		input_system_sub_system_reg_store(ID,
842 						  sub_id,
843 						  ISYS_CTRL_INIT_REG_ID,
844 						  1U); //AM: Is there any named constant?
845 	}
846 
847 	return;
848 }
849 
850 // Function that resets current configuration.
input_system_configuration_reset(void)851 input_system_err_t input_system_configuration_reset(void)
852 {
853 	unsigned int i;
854 
855 	receiver_rst(RX0_ID);
856 
857 	input_system_network_rst(INPUT_SYSTEM0_ID);
858 
859 	gp_device_rst(GP_DEVICE0_ID);
860 
861 	input_switch_rst(GP_DEVICE0_ID);
862 
863 	//target_rst();
864 
865 	// Reset IRQ_CTRLs.
866 
867 	// Reset configuration data structures.
868 	for (i = 0; i < N_CHANNELS; i++) {
869 		config.ch_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
870 		config.target_isp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
871 		config.target_sp_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
872 		config.target_strm2mem_flags[i] = INPUT_SYSTEM_CFG_FLAG_RESET;
873 	}
874 
875 	for (i = 0; i < N_CSI_PORTS; i++) {
876 		config.csi_buffer_flags[i]	 = INPUT_SYSTEM_CFG_FLAG_RESET;
877 		config.multicast[i]		 = INPUT_SYSTEM_DISCARD_ALL;
878 	}
879 
880 	config.source_type_flags				 = INPUT_SYSTEM_CFG_FLAG_RESET;
881 	config.acquisition_buffer_unique_flags	 = INPUT_SYSTEM_CFG_FLAG_RESET;
882 	config.unallocated_ib_mem_words			 = IB_CAPACITY_IN_WORDS;
883 	//config.acq_allocated_ib_mem_words		 = 0;
884 
885 	// Set the start of the session cofiguration.
886 	config.session_flags = INPUT_SYSTEM_CFG_FLAG_REQUIRED;
887 
888 	return INPUT_SYSTEM_ERR_NO_ERROR;
889 }
890 
891 // MW: Comments are good, but doxygen is required, place it at the declaration
892 // Function that appends the channel to current configuration.
input_system_configure_channel(const channel_cfg_t channel)893 static input_system_err_t input_system_configure_channel(
894     const channel_cfg_t		channel)
895 {
896 	input_system_err_t error = INPUT_SYSTEM_ERR_NO_ERROR;
897 	// Check if channel is not already configured.
898 	if (config.ch_flags[channel.ch_id] & INPUT_SYSTEM_CFG_FLAG_SET) {
899 		return INPUT_SYSTEM_ERR_CHANNEL_ALREADY_SET;
900 	} else {
901 		switch (channel.source_type) {
902 		case INPUT_SYSTEM_SOURCE_SENSOR:
903 			error = input_system_configure_channel_sensor(channel);
904 			break;
905 		case INPUT_SYSTEM_SOURCE_TPG:
906 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
907 			break;
908 		case INPUT_SYSTEM_SOURCE_PRBS:
909 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
910 			break;
911 		case INPUT_SYSTEM_SOURCE_FIFO:
912 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
913 			break;
914 		default:
915 			return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
916 			break;
917 		}
918 
919 		if (error != INPUT_SYSTEM_ERR_NO_ERROR) return error;
920 		// Input switch channel configurations must be combined in united config.
921 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2]
922 		    =
923 			channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[0];
924 		config.input_switch_cfg.hsync_data_reg[channel.source_cfg.csi_cfg.csi_port * 2 +
925 											   1] =
926 							       channel.target_cfg.input_switch_channel_cfg.hsync_data_reg[1];
927 		config.input_switch_cfg.vsync_data_reg |=
928 		    (channel.target_cfg.input_switch_channel_cfg.vsync_data_reg & 0x7) <<
929 		    (channel.source_cfg.csi_cfg.csi_port * 3);
930 
931 		// Other targets are just copied and marked as set.
932 		config.target_isp[channel.source_cfg.csi_cfg.csi_port] =
933 		    channel.target_cfg.target_isp_cfg;
934 		config.target_sp[channel.source_cfg.csi_cfg.csi_port] =
935 		    channel.target_cfg.target_sp_cfg;
936 		config.target_strm2mem[channel.source_cfg.csi_cfg.csi_port] =
937 		    channel.target_cfg.target_strm2mem_cfg;
938 		config.target_isp_flags[channel.source_cfg.csi_cfg.csi_port] |=
939 		    INPUT_SYSTEM_CFG_FLAG_SET;
940 		config.target_sp_flags[channel.source_cfg.csi_cfg.csi_port] |=
941 		    INPUT_SYSTEM_CFG_FLAG_SET;
942 		config.target_strm2mem_flags[channel.source_cfg.csi_cfg.csi_port] |=
943 		    INPUT_SYSTEM_CFG_FLAG_SET;
944 
945 		config.ch_flags[channel.ch_id] = INPUT_SYSTEM_CFG_FLAG_SET;
946 	}
947 	return INPUT_SYSTEM_ERR_NO_ERROR;
948 }
949 
950 // Function that partitions input buffer space with determining addresses.
input_buffer_configuration(void)951 static input_system_err_t input_buffer_configuration(void)
952 {
953 	u32 current_address    = 0;
954 	u32 unallocated_memory = IB_CAPACITY_IN_WORDS;
955 
956 	isp2400_ib_buffer_t	candidate_buffer_acq  = IB_BUFFER_NULL;
957 	u32 size_requested;
958 	input_system_config_flags_t	acq_already_specified = INPUT_SYSTEM_CFG_FLAG_RESET;
959 	input_system_csi_port_t port;
960 
961 	for (port = INPUT_SYSTEM_PORT_A; port < N_INPUT_SYSTEM_PORTS; port++) {
962 		csi_cfg_t source = config.csi_value[port];//.csi_cfg;
963 
964 		if (config.csi_flags[port] & INPUT_SYSTEM_CFG_FLAG_SET) {
965 			// Check and set csi buffer in input buffer.
966 			switch (source.buffering_mode) {
967 			case INPUT_SYSTEM_FIFO_CAPTURE:
968 			case INPUT_SYSTEM_XMEM_ACQUIRE:
969 				config.csi_buffer_flags[port] =
970 				    INPUT_SYSTEM_CFG_FLAG_BLOCKED; // Well, not used.
971 				break;
972 
973 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
974 			case INPUT_SYSTEM_SRAM_BUFFERING:
975 			case INPUT_SYSTEM_XMEM_BUFFERING:
976 			case INPUT_SYSTEM_XMEM_CAPTURE:
977 				size_requested = source.csi_buffer.mem_reg_size *
978 						 source.csi_buffer.nof_mem_regs;
979 				if (source.csi_buffer.mem_reg_size > 0
980 				    && source.csi_buffer.nof_mem_regs > 0
981 				    && size_requested <= unallocated_memory
982 				   ) {
983 					config.csi_buffer[port].mem_reg_addr = current_address;
984 					config.csi_buffer[port].mem_reg_size = source.csi_buffer.mem_reg_size;
985 					config.csi_buffer[port].nof_mem_regs = source.csi_buffer.nof_mem_regs;
986 					current_address		+= size_requested;
987 					unallocated_memory	-= size_requested;
988 					config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_SET;
989 				} else {
990 					config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
991 					return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
992 				}
993 				break;
994 
995 			default:
996 				config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
997 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
998 				break;
999 			}
1000 
1001 			// Check acquisition buffer specified but set it later since it has to be unique.
1002 			switch (source.buffering_mode) {
1003 			case INPUT_SYSTEM_FIFO_CAPTURE:
1004 			case INPUT_SYSTEM_SRAM_BUFFERING:
1005 			case INPUT_SYSTEM_XMEM_CAPTURE:
1006 				// Nothing to do.
1007 				break;
1008 
1009 			case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1010 			case INPUT_SYSTEM_XMEM_BUFFERING:
1011 			case INPUT_SYSTEM_XMEM_ACQUIRE:
1012 				if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_RESET) {
1013 					size_requested = source.acquisition_buffer.mem_reg_size
1014 							 * source.acquisition_buffer.nof_mem_regs;
1015 					if (source.acquisition_buffer.mem_reg_size > 0
1016 					    && source.acquisition_buffer.nof_mem_regs > 0
1017 					    && size_requested <= unallocated_memory
1018 					   ) {
1019 						candidate_buffer_acq = source.acquisition_buffer;
1020 						acq_already_specified = INPUT_SYSTEM_CFG_FLAG_SET;
1021 					}
1022 				} else {
1023 					// Check if specified acquisition buffer is the same as specified before.
1024 					if (source.acquisition_buffer.mem_reg_size != candidate_buffer_acq.mem_reg_size
1025 					    || source.acquisition_buffer.nof_mem_regs !=  candidate_buffer_acq.nof_mem_regs
1026 					   ) {
1027 						config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1028 						return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1029 					}
1030 				}
1031 				break;
1032 
1033 			default:
1034 				return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1035 				break;
1036 			}
1037 		} else {
1038 			config.csi_buffer_flags[port] = INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1039 		}
1040 	} // end of for ( port )
1041 
1042 	// Set the acquisition buffer at the end.
1043 	size_requested = candidate_buffer_acq.mem_reg_size *
1044 			 candidate_buffer_acq.nof_mem_regs;
1045 	if (acq_already_specified == INPUT_SYSTEM_CFG_FLAG_SET
1046 	    && size_requested <= unallocated_memory) {
1047 		config.acquisition_buffer_unique.mem_reg_addr = current_address;
1048 		config.acquisition_buffer_unique.mem_reg_size =
1049 		    candidate_buffer_acq.mem_reg_size;
1050 		config.acquisition_buffer_unique.nof_mem_regs =
1051 		    candidate_buffer_acq.nof_mem_regs;
1052 		current_address		+= size_requested;
1053 		unallocated_memory	-= size_requested;
1054 		config.acquisition_buffer_unique_flags = INPUT_SYSTEM_CFG_FLAG_SET;
1055 
1056 		assert(current_address <= IB_CAPACITY_IN_WORDS);
1057 	}
1058 
1059 	return INPUT_SYSTEM_ERR_NO_ERROR;
1060 }
1061 
capture_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const isp2400_ib_buffer_t * const cfg)1062 static void capture_unit_configure(
1063     const input_system_ID_t			ID,
1064     const sub_system_ID_t			sub_id,
1065     const isp2400_ib_buffer_t *const cfg)
1066 {
1067 	assert(ID < N_INPUT_SYSTEM_ID);
1068 	assert(/*(sub_id >= CAPTURE_UNIT0_ID) &&*/ (sub_id <=
1069 		CAPTURE_UNIT2_ID)); // Commented part is always true.
1070 	assert(cfg);
1071 
1072 	input_system_sub_system_reg_store(ID,
1073 					  sub_id,
1074 					  CAPT_START_ADDR_REG_ID,
1075 					  cfg->mem_reg_addr);
1076 	input_system_sub_system_reg_store(ID,
1077 					  sub_id,
1078 					  CAPT_MEM_REGION_SIZE_REG_ID,
1079 					  cfg->mem_reg_size);
1080 	input_system_sub_system_reg_store(ID,
1081 					  sub_id,
1082 					  CAPT_NUM_MEM_REGIONS_REG_ID,
1083 					  cfg->nof_mem_regs);
1084 
1085 	return;
1086 }
1087 
acquisition_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const isp2400_ib_buffer_t * const cfg)1088 static void acquisition_unit_configure(
1089     const input_system_ID_t			ID,
1090     const sub_system_ID_t			sub_id,
1091     const isp2400_ib_buffer_t *const cfg)
1092 {
1093 	assert(ID < N_INPUT_SYSTEM_ID);
1094 	assert(sub_id == ACQUISITION_UNIT0_ID);
1095 	assert(cfg);
1096 
1097 	input_system_sub_system_reg_store(ID,
1098 					  sub_id,
1099 					  ACQ_START_ADDR_REG_ID,
1100 					  cfg->mem_reg_addr);
1101 	input_system_sub_system_reg_store(ID,
1102 					  sub_id,
1103 					  ACQ_NUM_MEM_REGIONS_REG_ID,
1104 					  cfg->nof_mem_regs);
1105 	input_system_sub_system_reg_store(ID,
1106 					  sub_id,
1107 					  ACQ_MEM_REGION_SIZE_REG_ID,
1108 					  cfg->mem_reg_size);
1109 
1110 	return;
1111 }
1112 
ctrl_unit_configure(const input_system_ID_t ID,const sub_system_ID_t sub_id,const ctrl_unit_cfg_t * const cfg)1113 static void ctrl_unit_configure(
1114     const input_system_ID_t			ID,
1115     const sub_system_ID_t			sub_id,
1116     const ctrl_unit_cfg_t *const cfg)
1117 {
1118 	assert(ID < N_INPUT_SYSTEM_ID);
1119 	assert(sub_id == CTRL_UNIT0_ID);
1120 	assert(cfg);
1121 
1122 	input_system_sub_system_reg_store(ID,
1123 					  sub_id,
1124 					  ISYS_CTRL_CAPT_START_ADDR_A_REG_ID,
1125 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_addr);
1126 	input_system_sub_system_reg_store(ID,
1127 					  sub_id,
1128 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_A_REG_ID,
1129 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].mem_reg_size);
1130 	input_system_sub_system_reg_store(ID,
1131 					  sub_id,
1132 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_A_REG_ID,
1133 					  cfg->buffer_mipi[CAPTURE_UNIT0_ID].nof_mem_regs);
1134 
1135 	input_system_sub_system_reg_store(ID,
1136 					  sub_id,
1137 					  ISYS_CTRL_CAPT_START_ADDR_B_REG_ID,
1138 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_addr);
1139 	input_system_sub_system_reg_store(ID,
1140 					  sub_id,
1141 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_B_REG_ID,
1142 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].mem_reg_size);
1143 	input_system_sub_system_reg_store(ID,
1144 					  sub_id,
1145 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_B_REG_ID,
1146 					  cfg->buffer_mipi[CAPTURE_UNIT1_ID].nof_mem_regs);
1147 
1148 	input_system_sub_system_reg_store(ID,
1149 					  sub_id,
1150 					  ISYS_CTRL_CAPT_START_ADDR_C_REG_ID,
1151 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_addr);
1152 	input_system_sub_system_reg_store(ID,
1153 					  sub_id,
1154 					  ISYS_CTRL_CAPT_MEM_REGION_SIZE_C_REG_ID,
1155 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].mem_reg_size);
1156 	input_system_sub_system_reg_store(ID,
1157 					  sub_id,
1158 					  ISYS_CTRL_CAPT_NUM_MEM_REGIONS_C_REG_ID,
1159 					  cfg->buffer_mipi[CAPTURE_UNIT2_ID].nof_mem_regs);
1160 
1161 	input_system_sub_system_reg_store(ID,
1162 					  sub_id,
1163 					  ISYS_CTRL_ACQ_START_ADDR_REG_ID,
1164 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_addr);
1165 	input_system_sub_system_reg_store(ID,
1166 					  sub_id,
1167 					  ISYS_CTRL_ACQ_MEM_REGION_SIZE_REG_ID,
1168 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].mem_reg_size);
1169 	input_system_sub_system_reg_store(ID,
1170 					  sub_id,
1171 					  ISYS_CTRL_ACQ_NUM_MEM_REGIONS_REG_ID,
1172 					  cfg->buffer_acquire[ACQUISITION_UNIT0_ID - ACQUISITION_UNIT0_ID].nof_mem_regs);
1173 	input_system_sub_system_reg_store(ID,
1174 					  sub_id,
1175 					  ISYS_CTRL_CAPT_RESERVE_ONE_MEM_REGION_REG_ID,
1176 					  0);
1177 	return;
1178 }
1179 
input_system_network_configure(const input_system_ID_t ID,const input_system_network_cfg_t * const cfg)1180 static void input_system_network_configure(
1181     const input_system_ID_t				ID,
1182     const input_system_network_cfg_t *const cfg)
1183 {
1184 	u32 sub_id;
1185 
1186 	assert(ID < N_INPUT_SYSTEM_ID);
1187 	assert(cfg);
1188 
1189 	// Set all 3 multicasts.
1190 	input_system_sub_system_reg_store(ID,
1191 					  GPREGS_UNIT0_ID,
1192 					  HIVE_ISYS_GPREG_MULTICAST_A_IDX,
1193 					  cfg->multicast_cfg[CAPTURE_UNIT0_ID]);
1194 	input_system_sub_system_reg_store(ID,
1195 					  GPREGS_UNIT0_ID,
1196 					  HIVE_ISYS_GPREG_MULTICAST_B_IDX,
1197 					  cfg->multicast_cfg[CAPTURE_UNIT1_ID]);
1198 	input_system_sub_system_reg_store(ID,
1199 					  GPREGS_UNIT0_ID,
1200 					  HIVE_ISYS_GPREG_MULTICAST_C_IDX,
1201 					  cfg->multicast_cfg[CAPTURE_UNIT2_ID]);
1202 
1203 	// Set stream mux.
1204 	input_system_sub_system_reg_store(ID,
1205 					  GPREGS_UNIT0_ID,
1206 					  HIVE_ISYS_GPREG_MUX_IDX,
1207 					  cfg->mux_cfg);
1208 
1209 	// Set capture units.
1210 	for (sub_id = CAPTURE_UNIT0_ID; sub_id < CAPTURE_UNIT0_ID + N_CAPTURE_UNIT_ID;
1211 	     sub_id++) {
1212 		capture_unit_configure(ID,
1213 				       sub_id,
1214 				       &cfg->ctrl_unit_cfg[ID].buffer_mipi[sub_id - CAPTURE_UNIT0_ID]);
1215 	}
1216 
1217 	// Set acquisition units.
1218 	for (sub_id = ACQUISITION_UNIT0_ID;
1219 	     sub_id < ACQUISITION_UNIT0_ID + N_ACQUISITION_UNIT_ID; sub_id++) {
1220 		acquisition_unit_configure(ID,
1221 					   sub_id,
1222 					   &cfg->ctrl_unit_cfg[sub_id - ACQUISITION_UNIT0_ID].buffer_acquire[sub_id -
1223 						   ACQUISITION_UNIT0_ID]);
1224 	}
1225 
1226 	// No DMA configuration needed. Ctrl_unit will fully control it.
1227 
1228 	// Set controller units.
1229 	for (sub_id = CTRL_UNIT0_ID; sub_id < CTRL_UNIT0_ID + N_CTRL_UNIT_ID;
1230 	     sub_id++) {
1231 		ctrl_unit_configure(ID,
1232 				    sub_id,
1233 				    &cfg->ctrl_unit_cfg[sub_id - CTRL_UNIT0_ID]);
1234 	}
1235 
1236 	return;
1237 }
1238 
configuration_to_registers(void)1239 static input_system_err_t configuration_to_registers(void)
1240 {
1241 	input_system_network_cfg_t input_system_network_cfg;
1242 	int i;
1243 
1244 	assert(config.source_type_flags & INPUT_SYSTEM_CFG_FLAG_SET);
1245 
1246 	switch (config.source_type) {
1247 	case INPUT_SYSTEM_SOURCE_SENSOR:
1248 
1249 		// Determine stream multicasts setting based on the mode of csi_cfg_t.
1250 		// AM: This should be moved towards earlier function call, e.g. in
1251 		// the commit function.
1252 		for (i = MIPI_PORT0_ID; i < N_MIPI_PORT_ID; i++) {
1253 			if (config.csi_flags[i] & INPUT_SYSTEM_CFG_FLAG_SET) {
1254 				switch (config.csi_value[i].buffering_mode) {
1255 				case INPUT_SYSTEM_FIFO_CAPTURE:
1256 					config.multicast[i] = INPUT_SYSTEM_CSI_BACKEND;
1257 					break;
1258 
1259 				case INPUT_SYSTEM_XMEM_CAPTURE:
1260 				case INPUT_SYSTEM_SRAM_BUFFERING:
1261 				case INPUT_SYSTEM_XMEM_BUFFERING:
1262 					config.multicast[i] = INPUT_SYSTEM_INPUT_BUFFER;
1263 					break;
1264 
1265 				case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1266 					config.multicast[i] = INPUT_SYSTEM_MULTICAST;
1267 					break;
1268 
1269 				case INPUT_SYSTEM_XMEM_ACQUIRE:
1270 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1271 					break;
1272 
1273 				default:
1274 					config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1275 					return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1276 					//break;
1277 				}
1278 			} else {
1279 				config.multicast[i] = INPUT_SYSTEM_DISCARD_ALL;
1280 			}
1281 
1282 			input_system_network_cfg.multicast_cfg[i] = config.multicast[i];
1283 
1284 		} // for
1285 
1286 		input_system_network_cfg.mux_cfg = config.multiplexer;
1287 
1288 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1289 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT0_ID] =
1290 							       config.csi_buffer[MIPI_PORT0_ID];
1291 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1292 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT1_ID] =
1293 							       config.csi_buffer[MIPI_PORT1_ID];
1294 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1295 						       CTRL_UNIT0_ID].buffer_mipi[CAPTURE_UNIT2_ID] =
1296 							       config.csi_buffer[MIPI_PORT2_ID];
1297 		input_system_network_cfg.ctrl_unit_cfg[CTRL_UNIT0_ID -
1298 						       CTRL_UNIT0_ID].buffer_acquire[ACQUISITION_UNIT0_ID -
1299 							       ACQUISITION_UNIT0_ID] =
1300 								       config.acquisition_buffer_unique;
1301 
1302 		// First set input network around CSI receiver.
1303 		input_system_network_configure(INPUT_SYSTEM0_ID, &input_system_network_cfg);
1304 
1305 		// Set the CSI receiver.
1306 		//...
1307 		break;
1308 
1309 	case INPUT_SYSTEM_SOURCE_TPG:
1310 
1311 		break;
1312 
1313 	case INPUT_SYSTEM_SOURCE_PRBS:
1314 
1315 		break;
1316 
1317 	case INPUT_SYSTEM_SOURCE_FIFO:
1318 		break;
1319 
1320 	default:
1321 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1322 		break;
1323 
1324 	} // end of switch (source_type)
1325 
1326 	// Set input selector.
1327 	input_selector_cfg_for_sensor(GP_DEVICE0_ID);
1328 
1329 	// Set input switch.
1330 	input_switch_cfg(GP_DEVICE0_ID, &config.input_switch_cfg);
1331 
1332 	// Set input formatters.
1333 	// AM: IF are set dynamically.
1334 	return INPUT_SYSTEM_ERR_NO_ERROR;
1335 }
1336 
1337 // Function that applies the whole configuration.
input_system_configuration_commit(void)1338 input_system_err_t input_system_configuration_commit(void)
1339 {
1340 	// The last configuration step is to configure the input buffer.
1341 	input_system_err_t error = input_buffer_configuration();
1342 
1343 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
1344 		return error;
1345 	}
1346 
1347 	// Translate the whole configuration into registers.
1348 	error = configuration_to_registers();
1349 	if (error != INPUT_SYSTEM_ERR_NO_ERROR) {
1350 		return error;
1351 	}
1352 
1353 	// Translate the whole configuration into ctrl commands etc.
1354 
1355 	return INPUT_SYSTEM_ERR_NO_ERROR;
1356 }
1357 
1358 // FIFO
1359 
input_system_csi_fifo_channel_cfg(u32 ch_id,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,target_cfg2400_t target)1360 input_system_err_t	input_system_csi_fifo_channel_cfg(
1361     u32		ch_id,
1362     input_system_csi_port_t	port,
1363     backend_channel_cfg_t	backend_ch,
1364     target_cfg2400_t	target
1365 )
1366 {
1367 	channel_cfg_t channel;
1368 
1369 	channel.ch_id	= ch_id;
1370 	channel.backend_ch	= backend_ch;
1371 	channel.source_type = INPUT_SYSTEM_SOURCE_SENSOR;
1372 	//channel.source
1373 	channel.source_cfg.csi_cfg.csi_port			= port;
1374 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_FIFO_CAPTURE;
1375 	channel.source_cfg.csi_cfg.csi_buffer			= IB_BUFFER_NULL;
1376 	channel.source_cfg.csi_cfg.acquisition_buffer	= IB_BUFFER_NULL;
1377 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
1378 
1379 	channel.target_cfg	= target;
1380 	return input_system_configure_channel(channel);
1381 }
1382 
input_system_csi_fifo_channel_with_counting_cfg(u32 ch_id,u32 nof_frames,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,target_cfg2400_t target)1383 input_system_err_t	input_system_csi_fifo_channel_with_counting_cfg(
1384     u32				ch_id,
1385     u32				nof_frames,
1386     input_system_csi_port_t			port,
1387     backend_channel_cfg_t			backend_ch,
1388     u32				csi_mem_reg_size,
1389     u32				csi_nof_mem_regs,
1390     target_cfg2400_t			target
1391 )
1392 {
1393 	channel_cfg_t channel;
1394 
1395 	channel.ch_id	= ch_id;
1396 	channel.backend_ch	= backend_ch;
1397 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1398 	//channel.source
1399 	channel.source_cfg.csi_cfg.csi_port			= port;
1400 	channel.source_cfg.csi_cfg.buffering_mode	=
1401 	    INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING;
1402 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1403 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1404 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1405 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
1406 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1407 
1408 	channel.target_cfg	= target;
1409 	return input_system_configure_channel(channel);
1410 }
1411 
1412 // SRAM
1413 
input_system_csi_sram_channel_cfg(u32 ch_id,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,target_cfg2400_t target)1414 input_system_err_t	input_system_csi_sram_channel_cfg(
1415     u32				ch_id,
1416     input_system_csi_port_t			port,
1417     backend_channel_cfg_t			backend_ch,
1418     u32				csi_mem_reg_size,
1419     u32				csi_nof_mem_regs,
1420     //	uint32_t				acq_mem_reg_size,
1421     //	uint32_t				acq_nof_mem_regs,
1422     target_cfg2400_t			target
1423 )
1424 {
1425 	channel_cfg_t channel;
1426 
1427 	channel.ch_id	= ch_id;
1428 	channel.backend_ch	= backend_ch;
1429 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1430 	//channel.source
1431 	channel.source_cfg.csi_cfg.csi_port			= port;
1432 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_SRAM_BUFFERING;
1433 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1434 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1435 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1436 	channel.source_cfg.csi_cfg.acquisition_buffer			= IB_BUFFER_NULL;
1437 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= 0;
1438 
1439 	channel.target_cfg	= target;
1440 	return input_system_configure_channel(channel);
1441 }
1442 
1443 //XMEM
1444 
1445 // Collects all parameters and puts them in channel_cfg_t.
input_system_csi_xmem_channel_cfg(u32 ch_id,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,u32 acq_mem_reg_size,u32 acq_nof_mem_regs,target_cfg2400_t target,uint32_t nof_xmem_buffers)1446 input_system_err_t	input_system_csi_xmem_channel_cfg(
1447     u32				ch_id,
1448     input_system_csi_port_t			port,
1449     backend_channel_cfg_t			backend_ch,
1450     u32				csi_mem_reg_size,
1451     u32				csi_nof_mem_regs,
1452     u32				acq_mem_reg_size,
1453     u32				acq_nof_mem_regs,
1454     target_cfg2400_t			target,
1455     uint32_t				nof_xmem_buffers
1456 )
1457 {
1458 	channel_cfg_t channel;
1459 
1460 	channel.ch_id	= ch_id;
1461 	channel.backend_ch	= backend_ch;
1462 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1463 	//channel.source
1464 	channel.source_cfg.csi_cfg.csi_port			= port;
1465 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_BUFFERING;
1466 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1467 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1468 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1469 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1470 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1471 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1472 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_xmem_buffers;
1473 
1474 	channel.target_cfg	= target;
1475 	return input_system_configure_channel(channel);
1476 }
1477 
input_system_csi_xmem_acquire_only_channel_cfg(u32 ch_id,u32 nof_frames,input_system_csi_port_t port,backend_channel_cfg_t backend_ch,u32 acq_mem_reg_size,u32 acq_nof_mem_regs,target_cfg2400_t target)1478 input_system_err_t	input_system_csi_xmem_acquire_only_channel_cfg(
1479     u32				ch_id,
1480     u32				nof_frames,
1481     input_system_csi_port_t			port,
1482     backend_channel_cfg_t			backend_ch,
1483     u32				acq_mem_reg_size,
1484     u32				acq_nof_mem_regs,
1485     target_cfg2400_t			target)
1486 {
1487 	channel_cfg_t channel;
1488 
1489 	channel.ch_id	= ch_id;
1490 	channel.backend_ch	= backend_ch;
1491 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1492 	//channel.source
1493 	channel.source_cfg.csi_cfg.csi_port			= port;
1494 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_ACQUIRE;
1495 	channel.source_cfg.csi_cfg.csi_buffer		= IB_BUFFER_NULL;
1496 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1497 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1498 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1499 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1500 
1501 	channel.target_cfg	= target;
1502 	return input_system_configure_channel(channel);
1503 }
1504 
input_system_csi_xmem_capture_only_channel_cfg(u32 ch_id,u32 nof_frames,input_system_csi_port_t port,u32 csi_mem_reg_size,u32 csi_nof_mem_regs,u32 acq_mem_reg_size,u32 acq_nof_mem_regs,target_cfg2400_t target)1505 input_system_err_t	input_system_csi_xmem_capture_only_channel_cfg(
1506     u32				ch_id,
1507     u32				nof_frames,
1508     input_system_csi_port_t			port,
1509     u32				csi_mem_reg_size,
1510     u32				csi_nof_mem_regs,
1511     u32				acq_mem_reg_size,
1512     u32				acq_nof_mem_regs,
1513     target_cfg2400_t			target)
1514 {
1515 	channel_cfg_t channel;
1516 
1517 	channel.ch_id	= ch_id;
1518 	//channel.backend_ch	= backend_ch;
1519 	channel.source_type		= INPUT_SYSTEM_SOURCE_SENSOR;
1520 	//channel.source
1521 	channel.source_cfg.csi_cfg.csi_port			= port;
1522 	//channel.source_cfg.csi_cfg.backend_ch		= backend_ch;
1523 	channel.source_cfg.csi_cfg.buffering_mode	= INPUT_SYSTEM_XMEM_CAPTURE;
1524 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_size		= csi_mem_reg_size;
1525 	channel.source_cfg.csi_cfg.csi_buffer.nof_mem_regs		= csi_nof_mem_regs;
1526 	channel.source_cfg.csi_cfg.csi_buffer.mem_reg_addr		= 0;
1527 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_size	= acq_mem_reg_size;
1528 	channel.source_cfg.csi_cfg.acquisition_buffer.nof_mem_regs	= acq_nof_mem_regs;
1529 	channel.source_cfg.csi_cfg.acquisition_buffer.mem_reg_addr	= 0;
1530 	channel.source_cfg.csi_cfg.nof_xmem_buffers	= nof_frames;
1531 
1532 	channel.target_cfg	= target;
1533 	return input_system_configure_channel(channel);
1534 }
1535 
1536 // Non - CSI
1537 
input_system_prbs_channel_cfg(u32 ch_id,u32 nof_frames,u32 seed,u32 sync_gen_width,u32 sync_gen_height,u32 sync_gen_hblank_cycles,u32 sync_gen_vblank_cycles,target_cfg2400_t target)1538 input_system_err_t	input_system_prbs_channel_cfg(
1539     u32		ch_id,
1540     u32		nof_frames,//not used yet
1541     u32		seed,
1542     u32		sync_gen_width,
1543     u32		sync_gen_height,
1544     u32		sync_gen_hblank_cycles,
1545     u32		sync_gen_vblank_cycles,
1546     target_cfg2400_t	target
1547 )
1548 {
1549 	channel_cfg_t channel;
1550 
1551 	(void)nof_frames;
1552 
1553 	channel.ch_id	= ch_id;
1554 	channel.source_type = INPUT_SYSTEM_SOURCE_PRBS;
1555 
1556 	channel.source_cfg.prbs_cfg.seed = seed;
1557 	channel.source_cfg.prbs_cfg.sync_gen_cfg.width		= sync_gen_width;
1558 	channel.source_cfg.prbs_cfg.sync_gen_cfg.height		= sync_gen_height;
1559 	channel.source_cfg.prbs_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1560 	channel.source_cfg.prbs_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1561 
1562 	channel.target_cfg	= target;
1563 
1564 	return input_system_configure_channel(channel);
1565 }
1566 
input_system_tpg_channel_cfg(u32 ch_id,u32 nof_frames,u32 x_mask,u32 y_mask,u32 x_delta,u32 y_delta,u32 xy_mask,u32 sync_gen_width,u32 sync_gen_height,u32 sync_gen_hblank_cycles,u32 sync_gen_vblank_cycles,target_cfg2400_t target)1567 input_system_err_t	input_system_tpg_channel_cfg(
1568     u32		ch_id,
1569     u32		nof_frames,//not used yet
1570     u32		x_mask,
1571     u32		y_mask,
1572     u32		x_delta,
1573     u32		y_delta,
1574     u32		xy_mask,
1575     u32		sync_gen_width,
1576     u32		sync_gen_height,
1577     u32		sync_gen_hblank_cycles,
1578     u32		sync_gen_vblank_cycles,
1579     target_cfg2400_t	target
1580 )
1581 {
1582 	channel_cfg_t channel;
1583 
1584 	(void)nof_frames;
1585 
1586 	channel.ch_id	= ch_id;
1587 	channel.source_type		= INPUT_SYSTEM_SOURCE_TPG;
1588 
1589 	channel.source_cfg.tpg_cfg.x_mask	= x_mask;
1590 	channel.source_cfg.tpg_cfg.y_mask	= y_mask;
1591 	channel.source_cfg.tpg_cfg.x_delta	= x_delta;
1592 	channel.source_cfg.tpg_cfg.y_delta	= y_delta;
1593 	channel.source_cfg.tpg_cfg.xy_mask	= xy_mask;
1594 	channel.source_cfg.tpg_cfg.sync_gen_cfg.width		= sync_gen_width;
1595 	channel.source_cfg.tpg_cfg.sync_gen_cfg.height		= sync_gen_height;
1596 	channel.source_cfg.tpg_cfg.sync_gen_cfg.hblank_cycles	= sync_gen_hblank_cycles;
1597 	channel.source_cfg.tpg_cfg.sync_gen_cfg.vblank_cycles	= sync_gen_vblank_cycles;
1598 
1599 	channel.target_cfg	= target;
1600 	return input_system_configure_channel(channel);
1601 }
1602 
1603 // MW: Don't use system specific names, (even in system specific files) "cfg2400" -> cfg
input_system_gpfifo_channel_cfg(u32 ch_id,u32 nof_frames,target_cfg2400_t target)1604 input_system_err_t	input_system_gpfifo_channel_cfg(
1605     u32		ch_id,
1606     u32		nof_frames, //not used yet
1607 
1608     target_cfg2400_t	target)
1609 {
1610 	channel_cfg_t channel;
1611 
1612 	(void)nof_frames;
1613 
1614 	channel.ch_id	= ch_id;
1615 	channel.source_type	= INPUT_SYSTEM_SOURCE_FIFO;
1616 
1617 	channel.target_cfg	= target;
1618 	return input_system_configure_channel(channel);
1619 }
1620 
1621 ///////////////////////////////////////////////////////////////////////////
1622 //
1623 // Private specialized functions for channel setting.
1624 //
1625 ///////////////////////////////////////////////////////////////////////////
1626 
1627 // Fills the parameters to config.csi_value[port]
input_system_configure_channel_sensor(const channel_cfg_t channel)1628 static input_system_err_t input_system_configure_channel_sensor(
1629     const channel_cfg_t channel)
1630 {
1631 	const u32 port = channel.source_cfg.csi_cfg.csi_port;
1632 	input_system_err_t status = INPUT_SYSTEM_ERR_NO_ERROR;
1633 
1634 	input_system_multiplex_t mux;
1635 
1636 	if (port >= N_INPUT_SYSTEM_PORTS)
1637 		return INPUT_SYSTEM_ERR_GENERIC;
1638 
1639 	//check if port > N_INPUT_SYSTEM_MULTIPLEX
1640 
1641 	status = set_source_type(&config.source_type, channel.source_type,
1642 				 &config.source_type_flags);
1643 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1644 
1645 	// Check for conflicts on source (implicitly on multicast, capture unit and input buffer).
1646 
1647 	status = set_csi_cfg(&config.csi_value[port], &channel.source_cfg.csi_cfg,
1648 			     &config.csi_flags[port]);
1649 	if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1650 
1651 	switch (channel.source_cfg.csi_cfg.buffering_mode) {
1652 	case INPUT_SYSTEM_FIFO_CAPTURE:
1653 
1654 		// Check for conflicts on mux.
1655 		mux = INPUT_SYSTEM_MIPI_PORT0 + port;
1656 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1657 						      &config.multiplexer_flags);
1658 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1659 		config.multicast[port] = INPUT_SYSTEM_CSI_BACKEND;
1660 
1661 		// Shared resource, so it should be blocked.
1662 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1663 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1664 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1665 
1666 		break;
1667 	case INPUT_SYSTEM_SRAM_BUFFERING:
1668 
1669 		// Check for conflicts on mux.
1670 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1671 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1672 						      &config.multiplexer_flags);
1673 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1674 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1675 
1676 		// Shared resource, so it should be blocked.
1677 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1678 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1679 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1680 
1681 		break;
1682 	case INPUT_SYSTEM_XMEM_BUFFERING:
1683 
1684 		// Check for conflicts on mux.
1685 		mux = INPUT_SYSTEM_ACQUISITION_UNIT;
1686 		status = input_system_multiplexer_cfg(&config.multiplexer, mux,
1687 						      &config.multiplexer_flags);
1688 		if (status != INPUT_SYSTEM_ERR_NO_ERROR) return status;
1689 		config.multicast[port] = INPUT_SYSTEM_INPUT_BUFFER;
1690 
1691 		// Shared resource, so it should be blocked.
1692 		//config.mux_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1693 		//config.csi_buffer_flags[port] |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1694 		//config.acquisition_buffer_unique_flags |= INPUT_SYSTEM_CFG_FLAG_BLOCKED;
1695 
1696 		break;
1697 	case INPUT_SYSTEM_FIFO_CAPTURE_WITH_COUNTING:
1698 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1699 		break;
1700 	case INPUT_SYSTEM_XMEM_CAPTURE:
1701 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1702 		break;
1703 	case INPUT_SYSTEM_XMEM_ACQUIRE:
1704 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1705 		break;
1706 	default:
1707 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1708 		break;
1709 	}
1710 	return INPUT_SYSTEM_ERR_NO_ERROR;
1711 }
1712 
1713 // Test flags and set structure.
set_source_type(input_system_source_t * const lhs,const input_system_source_t rhs,input_system_config_flags_t * const flags)1714 static input_system_err_t set_source_type(
1715     input_system_source_t *const lhs,
1716     const input_system_source_t			rhs,
1717     input_system_config_flags_t *const flags)
1718 {
1719 	// MW: Not enough asserts
1720 	assert(lhs);
1721 	assert(flags);
1722 
1723 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1724 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1725 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1726 	}
1727 
1728 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1729 		// Check for consistency with already set value.
1730 		if ((*lhs) == (rhs)) {
1731 			return INPUT_SYSTEM_ERR_NO_ERROR;
1732 		} else {
1733 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1734 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1735 		}
1736 	}
1737 	// Check the value (individually).
1738 	if (rhs >= N_INPUT_SYSTEM_SOURCE) {
1739 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1740 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1741 	}
1742 	// Set the value.
1743 	*lhs = rhs;
1744 
1745 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1746 	return INPUT_SYSTEM_ERR_NO_ERROR;
1747 }
1748 
1749 // Test flags and set structure.
set_csi_cfg(csi_cfg_t * const lhs,const csi_cfg_t * const rhs,input_system_config_flags_t * const flags)1750 static input_system_err_t set_csi_cfg(
1751     csi_cfg_t *const lhs,
1752     const csi_cfg_t *const rhs,
1753     input_system_config_flags_t *const flags)
1754 {
1755 	u32 memory_required;
1756 	u32 acq_memory_required;
1757 
1758 	assert(lhs);
1759 	assert(flags);
1760 
1761 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1762 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1763 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1764 	}
1765 
1766 	if (*flags & INPUT_SYSTEM_CFG_FLAG_SET) {
1767 		// check for consistency with already set value.
1768 		if (/*lhs->backend_ch == rhs.backend_ch
1769 			&&*/ lhs->buffering_mode == rhs->buffering_mode
1770 		    && lhs->csi_buffer.mem_reg_size == rhs->csi_buffer.mem_reg_size
1771 		    && lhs->csi_buffer.nof_mem_regs  == rhs->csi_buffer.nof_mem_regs
1772 		    && lhs->acquisition_buffer.mem_reg_size == rhs->acquisition_buffer.mem_reg_size
1773 		    && lhs->acquisition_buffer.nof_mem_regs  == rhs->acquisition_buffer.nof_mem_regs
1774 		    && lhs->nof_xmem_buffers  == rhs->nof_xmem_buffers
1775 		) {
1776 			return INPUT_SYSTEM_ERR_NO_ERROR;
1777 		} else {
1778 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1779 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1780 		}
1781 	}
1782 	// Check the value (individually).
1783 	// no check for backend_ch
1784 	// no check for nof_xmem_buffers
1785 	memory_required = rhs->csi_buffer.mem_reg_size * rhs->csi_buffer.nof_mem_regs;
1786 	acq_memory_required = rhs->acquisition_buffer.mem_reg_size *
1787 			      rhs->acquisition_buffer.nof_mem_regs;
1788 	if (rhs->buffering_mode >= N_INPUT_SYSTEM_BUFFERING_MODE
1789 	    ||
1790 	    // Check if required memory is available in input buffer (SRAM).
1791 	    (memory_required + acq_memory_required) > config.unallocated_ib_mem_words
1792 
1793 	   ) {
1794 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1795 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1796 	}
1797 	// Set the value.
1798 	//lhs[port]->backend_ch		= rhs.backend_ch;
1799 	lhs->buffering_mode	= rhs->buffering_mode;
1800 	lhs->nof_xmem_buffers = rhs->nof_xmem_buffers;
1801 
1802 	lhs->csi_buffer.mem_reg_size = rhs->csi_buffer.mem_reg_size;
1803 	lhs->csi_buffer.nof_mem_regs  = rhs->csi_buffer.nof_mem_regs;
1804 	lhs->acquisition_buffer.mem_reg_size = rhs->acquisition_buffer.mem_reg_size;
1805 	lhs->acquisition_buffer.nof_mem_regs  = rhs->acquisition_buffer.nof_mem_regs;
1806 	// ALX: NB: Here we just set buffer parameters, but still not allocate it
1807 	// (no addresses determined). That will be done during commit.
1808 
1809 	//  FIXIT:	acq_memory_required is not deducted, since it can be allocated multiple times.
1810 	config.unallocated_ib_mem_words -= memory_required;
1811 //assert(config.unallocated_ib_mem_words >=0);
1812 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1813 	return INPUT_SYSTEM_ERR_NO_ERROR;
1814 }
1815 
1816 // Test flags and set structure.
input_system_multiplexer_cfg(input_system_multiplex_t * const lhs,const input_system_multiplex_t rhs,input_system_config_flags_t * const flags)1817 static input_system_err_t input_system_multiplexer_cfg(
1818     input_system_multiplex_t *const lhs,
1819     const input_system_multiplex_t		rhs,
1820     input_system_config_flags_t *const flags)
1821 {
1822 	assert(lhs);
1823 	assert(flags);
1824 
1825 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_BLOCKED) {
1826 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1827 		return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1828 	}
1829 
1830 	if ((*flags) & INPUT_SYSTEM_CFG_FLAG_SET) {
1831 		// Check for consistency with already set value.
1832 		if ((*lhs) == (rhs)) {
1833 			return INPUT_SYSTEM_ERR_NO_ERROR;
1834 		} else {
1835 			*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1836 			return INPUT_SYSTEM_ERR_CONFLICT_ON_RESOURCE;
1837 		}
1838 	}
1839 	// Check the value (individually).
1840 	if (rhs >= N_INPUT_SYSTEM_MULTIPLEX) {
1841 		*flags |= INPUT_SYSTEM_CFG_FLAG_CONFLICT;
1842 		return INPUT_SYSTEM_ERR_PARAMETER_NOT_SUPPORTED;
1843 	}
1844 	// Set the value.
1845 	*lhs = rhs;
1846 
1847 	*flags |= INPUT_SYSTEM_CFG_FLAG_SET;
1848 	return INPUT_SYSTEM_ERR_NO_ERROR;
1849 }
1850 #endif
1851