1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/slab.h>
31
32#include "dm_services.h"
33#include "include/gpio_interface.h"
34#include "include/gpio_service_interface.h"
35#include "hw_translate.h"
36#include "hw_factory.h"
37
38
39
40
41
42#include "gpio_service.h"
43
44
45
46
47
48#include "hw_gpio.h"
49
50
51
52
53
54
55struct gpio_service *dal_gpio_service_create(
56 enum dce_version dce_version_major,
57 enum dce_version dce_version_minor,
58 struct dc_context *ctx)
59{
60 struct gpio_service *service;
61 uint32_t index_of_id;
62
63 service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);
64
65 if (!service) {
66 BREAK_TO_DEBUGGER();
67 return NULL;
68 }
69
70 if (!dal_hw_translate_init(&service->translate, dce_version_major,
71 dce_version_minor)) {
72 BREAK_TO_DEBUGGER();
73 goto failure_1;
74 }
75
76 if (!dal_hw_factory_init(&service->factory, dce_version_major,
77 dce_version_minor)) {
78 BREAK_TO_DEBUGGER();
79 goto failure_1;
80 }
81
82
83 {
84 index_of_id = 0;
85 service->ctx = ctx;
86
87 do {
88 uint32_t number_of_bits =
89 service->factory.number_of_pins[index_of_id];
90 uint32_t i = 0;
91
92 if (number_of_bits) {
93 service->busyness[index_of_id] =
94 kcalloc(number_of_bits, sizeof(char),
95 GFP_KERNEL);
96
97 if (!service->busyness[index_of_id]) {
98 BREAK_TO_DEBUGGER();
99 goto failure_2;
100 }
101
102 do {
103 service->busyness[index_of_id][i] = 0;
104 ++i;
105 } while (i < number_of_bits);
106 } else {
107 service->busyness[index_of_id] = NULL;
108 }
109
110 ++index_of_id;
111 } while (index_of_id < GPIO_ID_COUNT);
112 }
113
114 return service;
115
116failure_2:
117 while (index_of_id) {
118 --index_of_id;
119 kfree(service->busyness[index_of_id]);
120 }
121
122failure_1:
123 kfree(service);
124
125 return NULL;
126}
127
128struct gpio *dal_gpio_service_create_irq(
129 struct gpio_service *service,
130 uint32_t offset,
131 uint32_t mask)
132{
133 enum gpio_id id;
134 uint32_t en;
135
136 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
137 ASSERT_CRITICAL(false);
138 return NULL;
139 }
140
141 return dal_gpio_create_irq(service, id, en);
142}
143
144void dal_gpio_service_destroy(
145 struct gpio_service **ptr)
146{
147 if (!ptr || !*ptr) {
148 BREAK_TO_DEBUGGER();
149 return;
150 }
151
152
153 {
154 uint32_t index_of_id = 0;
155
156 do {
157 kfree((*ptr)->busyness[index_of_id]);
158
159 ++index_of_id;
160 } while (index_of_id < GPIO_ID_COUNT);
161 }
162
163 kfree(*ptr);
164
165 *ptr = NULL;
166}
167
168
169
170
171
172
173static bool is_pin_busy(
174 const struct gpio_service *service,
175 enum gpio_id id,
176 uint32_t en)
177{
178 return service->busyness[id][en];
179}
180
181static void set_pin_busy(
182 struct gpio_service *service,
183 enum gpio_id id,
184 uint32_t en)
185{
186 service->busyness[id][en] = true;
187}
188
189static void set_pin_free(
190 struct gpio_service *service,
191 enum gpio_id id,
192 uint32_t en)
193{
194 service->busyness[id][en] = false;
195}
196
197enum gpio_result dal_gpio_service_lock(
198 struct gpio_service *service,
199 enum gpio_id id,
200 uint32_t en)
201{
202 if (!service->busyness[id]) {
203 ASSERT_CRITICAL(false);
204 return GPIO_RESULT_OPEN_FAILED;
205 }
206
207 set_pin_busy(service, id, en);
208 return GPIO_RESULT_OK;
209}
210
211enum gpio_result dal_gpio_service_unlock(
212 struct gpio_service *service,
213 enum gpio_id id,
214 uint32_t en)
215{
216 if (!service->busyness[id]) {
217 ASSERT_CRITICAL(false);
218 return GPIO_RESULT_OPEN_FAILED;
219 }
220
221 set_pin_free(service, id, en);
222 return GPIO_RESULT_OK;
223}
224
225enum gpio_result dal_gpio_service_open(
226 struct gpio_service *service,
227 enum gpio_id id,
228 uint32_t en,
229 enum gpio_mode mode,
230 struct hw_gpio_pin **ptr)
231{
232 struct hw_gpio_pin *pin;
233
234 if (!service->busyness[id]) {
235 ASSERT_CRITICAL(false);
236 return GPIO_RESULT_OPEN_FAILED;
237 }
238
239 if (is_pin_busy(service, id, en)) {
240 ASSERT_CRITICAL(false);
241 return GPIO_RESULT_DEVICE_BUSY;
242 }
243
244 switch (id) {
245 case GPIO_ID_DDC_DATA:
246 pin = service->factory.funcs->create_ddc_data(
247 service->ctx, id, en);
248 service->factory.funcs->define_ddc_registers(pin, en);
249 break;
250 case GPIO_ID_DDC_CLOCK:
251 pin = service->factory.funcs->create_ddc_clock(
252 service->ctx, id, en);
253 service->factory.funcs->define_ddc_registers(pin, en);
254 break;
255 case GPIO_ID_GENERIC:
256 pin = service->factory.funcs->create_generic(
257 service->ctx, id, en);
258 break;
259 case GPIO_ID_HPD:
260 pin = service->factory.funcs->create_hpd(
261 service->ctx, id, en);
262 service->factory.funcs->define_hpd_registers(pin, en);
263 break;
264 case GPIO_ID_SYNC:
265 pin = service->factory.funcs->create_sync(
266 service->ctx, id, en);
267 break;
268 case GPIO_ID_GSL:
269 pin = service->factory.funcs->create_gsl(
270 service->ctx, id, en);
271 break;
272 default:
273 ASSERT_CRITICAL(false);
274 return GPIO_RESULT_NON_SPECIFIC_ERROR;
275 }
276
277 if (!pin) {
278 ASSERT_CRITICAL(false);
279 return GPIO_RESULT_NON_SPECIFIC_ERROR;
280 }
281
282 if (!pin->funcs->open(pin, mode)) {
283 ASSERT_CRITICAL(false);
284 dal_gpio_service_close(service, &pin);
285 return GPIO_RESULT_OPEN_FAILED;
286 }
287
288 set_pin_busy(service, id, en);
289 *ptr = pin;
290 return GPIO_RESULT_OK;
291}
292
293void dal_gpio_service_close(
294 struct gpio_service *service,
295 struct hw_gpio_pin **ptr)
296{
297 struct hw_gpio_pin *pin;
298
299 if (!ptr) {
300 ASSERT_CRITICAL(false);
301 return;
302 }
303
304 pin = *ptr;
305
306 if (pin) {
307 set_pin_free(service, pin->id, pin->en);
308
309 pin->funcs->close(pin);
310
311 pin->funcs->destroy(ptr);
312 }
313}
314
315
316enum dc_irq_source dal_irq_get_source(
317 const struct gpio *irq)
318{
319 enum gpio_id id = dal_gpio_get_id(irq);
320
321 switch (id) {
322 case GPIO_ID_HPD:
323 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 +
324 dal_gpio_get_enum(irq));
325 case GPIO_ID_GPIO_PAD:
326 return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 +
327 dal_gpio_get_enum(irq));
328 default:
329 return DC_IRQ_SOURCE_INVALID;
330 }
331}
332
333enum dc_irq_source dal_irq_get_rx_source(
334 const struct gpio *irq)
335{
336 enum gpio_id id = dal_gpio_get_id(irq);
337
338 switch (id) {
339 case GPIO_ID_HPD:
340 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX +
341 dal_gpio_get_enum(irq));
342 default:
343 return DC_IRQ_SOURCE_INVALID;
344 }
345}
346
347enum gpio_result dal_irq_setup_hpd_filter(
348 struct gpio *irq,
349 struct gpio_hpd_config *config)
350{
351 struct gpio_config_data config_data;
352
353 if (!config)
354 return GPIO_RESULT_INVALID_DATA;
355
356 config_data.type = GPIO_CONFIG_TYPE_HPD;
357 config_data.config.hpd = *config;
358
359 return dal_gpio_set_config(irq, &config_data);
360}
361
362
363
364
365
366
367struct gpio *dal_gpio_create_irq(
368 struct gpio_service *service,
369 enum gpio_id id,
370 uint32_t en)
371{
372 struct gpio *irq;
373
374 switch (id) {
375 case GPIO_ID_HPD:
376 case GPIO_ID_GPIO_PAD:
377 break;
378 default:
379 id = GPIO_ID_HPD;
380 ASSERT_CRITICAL(false);
381 return NULL;
382 }
383
384 irq = dal_gpio_create(
385 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
386
387 if (irq)
388 return irq;
389
390 ASSERT_CRITICAL(false);
391 return NULL;
392}
393
394void dal_gpio_destroy_irq(
395 struct gpio **irq)
396{
397 if (!irq || !*irq) {
398 ASSERT_CRITICAL(false);
399 return;
400 }
401
402 dal_gpio_close(*irq);
403 dal_gpio_destroy(irq);
404 kfree(*irq);
405
406 *irq = NULL;
407}
408
409struct ddc *dal_gpio_create_ddc(
410 struct gpio_service *service,
411 uint32_t offset,
412 uint32_t mask,
413 struct gpio_ddc_hw_info *info)
414{
415 enum gpio_id id;
416 uint32_t en;
417 struct ddc *ddc;
418
419 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
420 return NULL;
421
422 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL);
423
424 if (!ddc) {
425 BREAK_TO_DEBUGGER();
426 return NULL;
427 }
428
429 ddc->pin_data = dal_gpio_create(
430 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
431
432 if (!ddc->pin_data) {
433 BREAK_TO_DEBUGGER();
434 goto failure_1;
435 }
436
437 ddc->pin_clock = dal_gpio_create(
438 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
439
440 if (!ddc->pin_clock) {
441 BREAK_TO_DEBUGGER();
442 goto failure_2;
443 }
444
445 ddc->hw_info = *info;
446
447 ddc->ctx = service->ctx;
448
449 return ddc;
450
451failure_2:
452 dal_gpio_destroy(&ddc->pin_data);
453
454failure_1:
455 kfree(ddc);
456
457 return NULL;
458}
459
460void dal_gpio_destroy_ddc(
461 struct ddc **ddc)
462{
463 if (!ddc || !*ddc) {
464 BREAK_TO_DEBUGGER();
465 return;
466 }
467
468 dal_ddc_close(*ddc);
469 dal_gpio_destroy(&(*ddc)->pin_data);
470 dal_gpio_destroy(&(*ddc)->pin_clock);
471 kfree(*ddc);
472
473 *ddc = NULL;
474}
475
476enum gpio_result dal_ddc_open(
477 struct ddc *ddc,
478 enum gpio_mode mode,
479 enum gpio_ddc_config_type config_type)
480{
481 enum gpio_result result;
482
483 struct gpio_config_data config_data;
484 struct hw_gpio *hw_data;
485 struct hw_gpio *hw_clock;
486
487 result = dal_gpio_open_ex(ddc->pin_data, mode);
488
489 if (result != GPIO_RESULT_OK) {
490 BREAK_TO_DEBUGGER();
491 return result;
492 }
493
494 result = dal_gpio_open_ex(ddc->pin_clock, mode);
495
496 if (result != GPIO_RESULT_OK) {
497 BREAK_TO_DEBUGGER();
498 goto failure;
499 }
500
501
502
503
504
505 if (mode == GPIO_MODE_INPUT)
506
507
508 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
509 else
510 config_data.type = GPIO_CONFIG_TYPE_DDC;
511
512 config_data.config.ddc.type = config_type;
513
514 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin);
515 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin);
516
517 config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0;
518 config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0;
519
520 result = dal_gpio_set_config(ddc->pin_data, &config_data);
521
522 if (result == GPIO_RESULT_OK)
523 return result;
524
525 BREAK_TO_DEBUGGER();
526
527 dal_gpio_close(ddc->pin_clock);
528
529failure:
530 dal_gpio_close(ddc->pin_data);
531
532 return result;
533}
534
535enum gpio_result dal_ddc_change_mode(
536 struct ddc *ddc,
537 enum gpio_mode mode)
538{
539 enum gpio_result result;
540
541 enum gpio_mode original_mode =
542 dal_gpio_get_mode(ddc->pin_data);
543
544 result = dal_gpio_change_mode(ddc->pin_data, mode);
545
546
547
548
549
550
551 if (result != GPIO_RESULT_OK)
552 goto failure;
553
554 result = dal_gpio_change_mode(ddc->pin_clock, mode);
555
556 if (result == GPIO_RESULT_OK)
557 return result;
558
559 dal_gpio_change_mode(ddc->pin_clock, original_mode);
560
561failure:
562 dal_gpio_change_mode(ddc->pin_data, original_mode);
563
564 return result;
565}
566
567enum gpio_ddc_line dal_ddc_get_line(
568 const struct ddc *ddc)
569{
570 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
571}
572
573enum gpio_result dal_ddc_set_config(
574 struct ddc *ddc,
575 enum gpio_ddc_config_type config_type)
576{
577 struct gpio_config_data config_data;
578
579 config_data.type = GPIO_CONFIG_TYPE_DDC;
580
581 config_data.config.ddc.type = config_type;
582 config_data.config.ddc.data_en_bit_present = false;
583 config_data.config.ddc.clock_en_bit_present = false;
584
585 return dal_gpio_set_config(ddc->pin_data, &config_data);
586}
587
588void dal_ddc_close(
589 struct ddc *ddc)
590{
591 dal_gpio_close(ddc->pin_clock);
592 dal_gpio_close(ddc->pin_data);
593}
594
595