0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include "dm_services.h"
0031 #include "include/gpio_interface.h"
0032 #include "include/gpio_service_interface.h"
0033 #include "hw_translate.h"
0034 #include "hw_factory.h"
0035
0036
0037
0038
0039
0040 #include "gpio_service.h"
0041
0042
0043
0044
0045
0046 #include "hw_gpio.h"
0047
0048
0049
0050
0051
0052
0053 struct gpio_service *dal_gpio_service_create(
0054 enum dce_version dce_version,
0055 enum dce_environment dce_environment,
0056 struct dc_context *ctx)
0057 {
0058 struct gpio_service *service;
0059 uint32_t index_of_id;
0060
0061 service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);
0062
0063 if (!service) {
0064 BREAK_TO_DEBUGGER();
0065 return NULL;
0066 }
0067
0068 if (!dal_hw_translate_init(&service->translate, dce_version,
0069 dce_environment)) {
0070 BREAK_TO_DEBUGGER();
0071 goto failure_1;
0072 }
0073
0074 if (!dal_hw_factory_init(&service->factory, dce_version,
0075 dce_environment)) {
0076 BREAK_TO_DEBUGGER();
0077 goto failure_1;
0078 }
0079
0080
0081 {
0082 index_of_id = 0;
0083 service->ctx = ctx;
0084
0085 do {
0086 uint32_t number_of_bits =
0087 service->factory.number_of_pins[index_of_id];
0088 uint32_t i = 0;
0089
0090 if (number_of_bits) {
0091 service->busyness[index_of_id] =
0092 kcalloc(number_of_bits, sizeof(char),
0093 GFP_KERNEL);
0094
0095 if (!service->busyness[index_of_id]) {
0096 BREAK_TO_DEBUGGER();
0097 goto failure_2;
0098 }
0099
0100 do {
0101 service->busyness[index_of_id][i] = 0;
0102 ++i;
0103 } while (i < number_of_bits);
0104 } else {
0105 service->busyness[index_of_id] = NULL;
0106 }
0107
0108 ++index_of_id;
0109 } while (index_of_id < GPIO_ID_COUNT);
0110 }
0111
0112 return service;
0113
0114 failure_2:
0115 while (index_of_id) {
0116 --index_of_id;
0117 kfree(service->busyness[index_of_id]);
0118 }
0119
0120 failure_1:
0121 kfree(service);
0122
0123 return NULL;
0124 }
0125
0126 struct gpio *dal_gpio_service_create_irq(
0127 struct gpio_service *service,
0128 uint32_t offset,
0129 uint32_t mask)
0130 {
0131 enum gpio_id id;
0132 uint32_t en;
0133
0134 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
0135 ASSERT_CRITICAL(false);
0136 return NULL;
0137 }
0138
0139 return dal_gpio_create_irq(service, id, en);
0140 }
0141
0142 struct gpio *dal_gpio_service_create_generic_mux(
0143 struct gpio_service *service,
0144 uint32_t offset,
0145 uint32_t mask)
0146 {
0147 enum gpio_id id;
0148 uint32_t en;
0149 struct gpio *generic;
0150
0151 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
0152 ASSERT_CRITICAL(false);
0153 return NULL;
0154 }
0155
0156 generic = dal_gpio_create(
0157 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
0158
0159 return generic;
0160 }
0161
0162 void dal_gpio_destroy_generic_mux(
0163 struct gpio **mux)
0164 {
0165 if (!mux || !*mux) {
0166 ASSERT_CRITICAL(false);
0167 return;
0168 }
0169
0170 dal_gpio_destroy(mux);
0171 kfree(*mux);
0172
0173 *mux = NULL;
0174 }
0175
0176 struct gpio_pin_info dal_gpio_get_generic_pin_info(
0177 struct gpio_service *service,
0178 enum gpio_id id,
0179 uint32_t en)
0180 {
0181 struct gpio_pin_info pin;
0182
0183 if (service->translate.funcs->id_to_offset) {
0184 service->translate.funcs->id_to_offset(id, en, &pin);
0185 } else {
0186 pin.mask = 0xFFFFFFFF;
0187 pin.offset = 0xFFFFFFFF;
0188 }
0189
0190 return pin;
0191 }
0192
0193 void dal_gpio_service_destroy(
0194 struct gpio_service **ptr)
0195 {
0196 if (!ptr || !*ptr) {
0197 BREAK_TO_DEBUGGER();
0198 return;
0199 }
0200
0201
0202 {
0203 uint32_t index_of_id = 0;
0204
0205 do {
0206 kfree((*ptr)->busyness[index_of_id]);
0207
0208 ++index_of_id;
0209 } while (index_of_id < GPIO_ID_COUNT);
0210 }
0211
0212 kfree(*ptr);
0213
0214 *ptr = NULL;
0215 }
0216
0217 enum gpio_result dal_mux_setup_config(
0218 struct gpio *mux,
0219 struct gpio_generic_mux_config *config)
0220 {
0221 struct gpio_config_data config_data;
0222
0223 if (!config)
0224 return GPIO_RESULT_INVALID_DATA;
0225
0226 config_data.config.generic_mux = *config;
0227 config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX;
0228
0229 return dal_gpio_set_config(mux, &config_data);
0230 }
0231
0232
0233
0234
0235
0236
0237 static bool is_pin_busy(
0238 const struct gpio_service *service,
0239 enum gpio_id id,
0240 uint32_t en)
0241 {
0242 return service->busyness[id][en];
0243 }
0244
0245 static void set_pin_busy(
0246 struct gpio_service *service,
0247 enum gpio_id id,
0248 uint32_t en)
0249 {
0250 service->busyness[id][en] = true;
0251 }
0252
0253 static void set_pin_free(
0254 struct gpio_service *service,
0255 enum gpio_id id,
0256 uint32_t en)
0257 {
0258 service->busyness[id][en] = false;
0259 }
0260
0261 enum gpio_result dal_gpio_service_lock(
0262 struct gpio_service *service,
0263 enum gpio_id id,
0264 uint32_t en)
0265 {
0266 if (!service->busyness[id]) {
0267 ASSERT_CRITICAL(false);
0268 return GPIO_RESULT_OPEN_FAILED;
0269 }
0270
0271 set_pin_busy(service, id, en);
0272 return GPIO_RESULT_OK;
0273 }
0274
0275 enum gpio_result dal_gpio_service_unlock(
0276 struct gpio_service *service,
0277 enum gpio_id id,
0278 uint32_t en)
0279 {
0280 if (!service->busyness[id]) {
0281 ASSERT_CRITICAL(false);
0282 return GPIO_RESULT_OPEN_FAILED;
0283 }
0284
0285 set_pin_free(service, id, en);
0286 return GPIO_RESULT_OK;
0287 }
0288
0289 enum gpio_result dal_gpio_service_open(
0290 struct gpio *gpio)
0291 {
0292 struct gpio_service *service = gpio->service;
0293 enum gpio_id id = gpio->id;
0294 uint32_t en = gpio->en;
0295 enum gpio_mode mode = gpio->mode;
0296
0297 struct hw_gpio_pin **pin = &gpio->pin;
0298
0299
0300 if (!service->busyness[id]) {
0301 ASSERT_CRITICAL(false);
0302 return GPIO_RESULT_OPEN_FAILED;
0303 }
0304
0305 if (is_pin_busy(service, id, en)) {
0306 ASSERT_CRITICAL(false);
0307 return GPIO_RESULT_DEVICE_BUSY;
0308 }
0309
0310 switch (id) {
0311 case GPIO_ID_DDC_DATA:
0312 *pin = service->factory.funcs->get_ddc_pin(gpio);
0313 service->factory.funcs->define_ddc_registers(*pin, en);
0314 break;
0315 case GPIO_ID_DDC_CLOCK:
0316 *pin = service->factory.funcs->get_ddc_pin(gpio);
0317 service->factory.funcs->define_ddc_registers(*pin, en);
0318 break;
0319 case GPIO_ID_GENERIC:
0320 *pin = service->factory.funcs->get_generic_pin(gpio);
0321 service->factory.funcs->define_generic_registers(*pin, en);
0322 break;
0323 case GPIO_ID_HPD:
0324 *pin = service->factory.funcs->get_hpd_pin(gpio);
0325 service->factory.funcs->define_hpd_registers(*pin, en);
0326 break;
0327
0328
0329 case GPIO_ID_SYNC:
0330 case GPIO_ID_GSL:
0331 break;
0332 default:
0333 ASSERT_CRITICAL(false);
0334 return GPIO_RESULT_NON_SPECIFIC_ERROR;
0335 }
0336
0337 if (!*pin) {
0338 ASSERT_CRITICAL(false);
0339 return GPIO_RESULT_NON_SPECIFIC_ERROR;
0340 }
0341
0342 if (!(*pin)->funcs->open(*pin, mode)) {
0343 ASSERT_CRITICAL(false);
0344 dal_gpio_service_close(service, pin);
0345 return GPIO_RESULT_OPEN_FAILED;
0346 }
0347
0348 set_pin_busy(service, id, en);
0349 return GPIO_RESULT_OK;
0350 }
0351
0352 void dal_gpio_service_close(
0353 struct gpio_service *service,
0354 struct hw_gpio_pin **ptr)
0355 {
0356 struct hw_gpio_pin *pin;
0357
0358 if (!ptr) {
0359 ASSERT_CRITICAL(false);
0360 return;
0361 }
0362
0363 pin = *ptr;
0364
0365 if (pin) {
0366 set_pin_free(service, pin->id, pin->en);
0367
0368 pin->funcs->close(pin);
0369
0370 *ptr = NULL;
0371 }
0372 }
0373
0374 enum dc_irq_source dal_irq_get_source(
0375 const struct gpio *irq)
0376 {
0377 enum gpio_id id = dal_gpio_get_id(irq);
0378
0379 switch (id) {
0380 case GPIO_ID_HPD:
0381 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1 +
0382 dal_gpio_get_enum(irq));
0383 case GPIO_ID_GPIO_PAD:
0384 return (enum dc_irq_source)(DC_IRQ_SOURCE_GPIOPAD0 +
0385 dal_gpio_get_enum(irq));
0386 default:
0387 return DC_IRQ_SOURCE_INVALID;
0388 }
0389 }
0390
0391 enum dc_irq_source dal_irq_get_rx_source(
0392 const struct gpio *irq)
0393 {
0394 enum gpio_id id = dal_gpio_get_id(irq);
0395
0396 switch (id) {
0397 case GPIO_ID_HPD:
0398 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX +
0399 dal_gpio_get_enum(irq));
0400 default:
0401 return DC_IRQ_SOURCE_INVALID;
0402 }
0403 }
0404
0405 enum gpio_result dal_irq_setup_hpd_filter(
0406 struct gpio *irq,
0407 struct gpio_hpd_config *config)
0408 {
0409 struct gpio_config_data config_data;
0410
0411 if (!config)
0412 return GPIO_RESULT_INVALID_DATA;
0413
0414 config_data.type = GPIO_CONFIG_TYPE_HPD;
0415 config_data.config.hpd = *config;
0416
0417 return dal_gpio_set_config(irq, &config_data);
0418 }
0419
0420
0421
0422
0423
0424
0425 struct gpio *dal_gpio_create_irq(
0426 struct gpio_service *service,
0427 enum gpio_id id,
0428 uint32_t en)
0429 {
0430 struct gpio *irq;
0431
0432 switch (id) {
0433 case GPIO_ID_HPD:
0434 case GPIO_ID_GPIO_PAD:
0435 break;
0436 default:
0437 id = GPIO_ID_HPD;
0438 ASSERT_CRITICAL(false);
0439 return NULL;
0440 }
0441
0442 irq = dal_gpio_create(
0443 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
0444
0445 if (irq)
0446 return irq;
0447
0448 ASSERT_CRITICAL(false);
0449 return NULL;
0450 }
0451
0452 void dal_gpio_destroy_irq(
0453 struct gpio **irq)
0454 {
0455 if (!irq || !*irq) {
0456 ASSERT_CRITICAL(false);
0457 return;
0458 }
0459
0460 dal_gpio_destroy(irq);
0461 kfree(*irq);
0462
0463 *irq = NULL;
0464 }
0465
0466 struct ddc *dal_gpio_create_ddc(
0467 struct gpio_service *service,
0468 uint32_t offset,
0469 uint32_t mask,
0470 struct gpio_ddc_hw_info *info)
0471 {
0472 enum gpio_id id;
0473 uint32_t en;
0474 struct ddc *ddc;
0475
0476 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
0477 return NULL;
0478
0479 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL);
0480
0481 if (!ddc) {
0482 BREAK_TO_DEBUGGER();
0483 return NULL;
0484 }
0485
0486 ddc->pin_data = dal_gpio_create(
0487 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
0488
0489 if (!ddc->pin_data) {
0490 BREAK_TO_DEBUGGER();
0491 goto failure_1;
0492 }
0493
0494 ddc->pin_clock = dal_gpio_create(
0495 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
0496
0497 if (!ddc->pin_clock) {
0498 BREAK_TO_DEBUGGER();
0499 goto failure_2;
0500 }
0501
0502 ddc->hw_info = *info;
0503
0504 ddc->ctx = service->ctx;
0505
0506 return ddc;
0507
0508 failure_2:
0509 dal_gpio_destroy(&ddc->pin_data);
0510
0511 failure_1:
0512 kfree(ddc);
0513
0514 return NULL;
0515 }
0516
0517 void dal_gpio_destroy_ddc(
0518 struct ddc **ddc)
0519 {
0520 if (!ddc || !*ddc) {
0521 BREAK_TO_DEBUGGER();
0522 return;
0523 }
0524
0525 dal_ddc_close(*ddc);
0526 dal_gpio_destroy(&(*ddc)->pin_data);
0527 dal_gpio_destroy(&(*ddc)->pin_clock);
0528 kfree(*ddc);
0529
0530 *ddc = NULL;
0531 }
0532
0533 enum gpio_result dal_ddc_open(
0534 struct ddc *ddc,
0535 enum gpio_mode mode,
0536 enum gpio_ddc_config_type config_type)
0537 {
0538 enum gpio_result result;
0539
0540 struct gpio_config_data config_data;
0541 struct hw_gpio *hw_data;
0542 struct hw_gpio *hw_clock;
0543
0544 result = dal_gpio_open_ex(ddc->pin_data, mode);
0545
0546 if (result != GPIO_RESULT_OK) {
0547 BREAK_TO_DEBUGGER();
0548 return result;
0549 }
0550
0551 result = dal_gpio_open_ex(ddc->pin_clock, mode);
0552
0553 if (result != GPIO_RESULT_OK) {
0554 BREAK_TO_DEBUGGER();
0555 goto failure;
0556 }
0557
0558
0559
0560
0561
0562 if (mode == GPIO_MODE_INPUT)
0563
0564
0565 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
0566 else
0567 config_data.type = GPIO_CONFIG_TYPE_DDC;
0568
0569 config_data.config.ddc.type = config_type;
0570
0571 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin);
0572 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin);
0573
0574 config_data.config.ddc.data_en_bit_present = hw_data->store.en != 0;
0575 config_data.config.ddc.clock_en_bit_present = hw_clock->store.en != 0;
0576
0577 result = dal_gpio_set_config(ddc->pin_data, &config_data);
0578
0579 if (result == GPIO_RESULT_OK)
0580 return result;
0581
0582 BREAK_TO_DEBUGGER();
0583
0584 dal_gpio_close(ddc->pin_clock);
0585
0586 failure:
0587 dal_gpio_close(ddc->pin_data);
0588
0589 return result;
0590 }
0591
0592 enum gpio_result dal_ddc_change_mode(
0593 struct ddc *ddc,
0594 enum gpio_mode mode)
0595 {
0596 enum gpio_result result;
0597
0598 enum gpio_mode original_mode =
0599 dal_gpio_get_mode(ddc->pin_data);
0600
0601 result = dal_gpio_change_mode(ddc->pin_data, mode);
0602
0603
0604
0605
0606
0607
0608 if (result != GPIO_RESULT_OK)
0609 goto failure;
0610
0611 result = dal_gpio_change_mode(ddc->pin_clock, mode);
0612
0613 if (result == GPIO_RESULT_OK)
0614 return result;
0615
0616 dal_gpio_change_mode(ddc->pin_clock, original_mode);
0617
0618 failure:
0619 dal_gpio_change_mode(ddc->pin_data, original_mode);
0620
0621 return result;
0622 }
0623
0624 enum gpio_ddc_line dal_ddc_get_line(
0625 const struct ddc *ddc)
0626 {
0627 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
0628 }
0629
0630 enum gpio_result dal_ddc_set_config(
0631 struct ddc *ddc,
0632 enum gpio_ddc_config_type config_type)
0633 {
0634 struct gpio_config_data config_data;
0635
0636 config_data.type = GPIO_CONFIG_TYPE_DDC;
0637
0638 config_data.config.ddc.type = config_type;
0639 config_data.config.ddc.data_en_bit_present = false;
0640 config_data.config.ddc.clock_en_bit_present = false;
0641
0642 return dal_gpio_set_config(ddc->pin_data, &config_data);
0643 }
0644
0645 void dal_ddc_close(
0646 struct ddc *ddc)
0647 {
0648 if (ddc != NULL) {
0649 dal_gpio_close(ddc->pin_clock);
0650 dal_gpio_close(ddc->pin_data);
0651 }
0652 }
0653