2 * Copyright 2012-15 Advanced Micro Devices, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
27 * Pre-requisites: headers required by header of this unit
30 #include <linux/slab.h>
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"
42 #include "gpio_service.h"
45 * Post-requisites: headers required by this unit
55 struct 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)
60 struct gpio_service *service;
63 service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);
70 if (!dal_hw_translate_init(&service->translate, dce_version_major,
76 if (!dal_hw_factory_init(&service->factory, dce_version_major,
82 /* allocate and initialize busyness storage */
88 uint32_t number_of_bits =
89 service->factory.number_of_pins[index_of_id];
93 service->busyness[index_of_id] =
94 kcalloc(number_of_bits, sizeof(char),
97 if (!service->busyness[index_of_id]) {
103 service->busyness[index_of_id][i] = 0;
105 } while (i < number_of_bits);
107 service->busyness[index_of_id] = NULL;
111 } while (index_of_id < GPIO_ID_COUNT);
117 while (index_of_id) {
119 kfree(service->busyness[index_of_id]);
128 struct gpio *dal_gpio_service_create_irq(
129 struct gpio_service *service,
136 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) {
137 ASSERT_CRITICAL(false);
141 return dal_gpio_create_irq(service, id, en);
144 void dal_gpio_service_destroy(
145 struct gpio_service **ptr)
152 /* free business storage */
154 uint32_t index_of_id = 0;
157 kfree((*ptr)->busyness[index_of_id]);
160 } while (index_of_id < GPIO_ID_COUNT);
173 static bool is_pin_busy(
174 const struct gpio_service *service,
178 return service->busyness[id][en];
181 static void set_pin_busy(
182 struct gpio_service *service,
186 service->busyness[id][en] = true;
189 static void set_pin_free(
190 struct gpio_service *service,
194 service->busyness[id][en] = false;
197 enum gpio_result dal_gpio_service_lock(
198 struct gpio_service *service,
202 if (!service->busyness[id]) {
203 ASSERT_CRITICAL(false);
204 return GPIO_RESULT_OPEN_FAILED;
207 set_pin_busy(service, id, en);
208 return GPIO_RESULT_OK;
211 enum gpio_result dal_gpio_service_unlock(
212 struct gpio_service *service,
216 if (!service->busyness[id]) {
217 ASSERT_CRITICAL(false);
218 return GPIO_RESULT_OPEN_FAILED;
221 set_pin_free(service, id, en);
222 return GPIO_RESULT_OK;
225 enum gpio_result dal_gpio_service_open(
226 struct gpio_service *service,
230 struct hw_gpio_pin **ptr)
232 struct hw_gpio_pin *pin;
234 if (!service->busyness[id]) {
235 ASSERT_CRITICAL(false);
236 return GPIO_RESULT_OPEN_FAILED;
239 if (is_pin_busy(service, id, en)) {
240 ASSERT_CRITICAL(false);
241 return GPIO_RESULT_DEVICE_BUSY;
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);
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);
255 case GPIO_ID_GENERIC:
256 pin = service->factory.funcs->create_generic(
257 service->ctx, id, en);
260 pin = service->factory.funcs->create_hpd(
261 service->ctx, id, en);
262 service->factory.funcs->define_hpd_registers(pin, en);
265 pin = service->factory.funcs->create_sync(
266 service->ctx, id, en);
269 pin = service->factory.funcs->create_gsl(
270 service->ctx, id, en);
273 ASSERT_CRITICAL(false);
274 return GPIO_RESULT_NON_SPECIFIC_ERROR;
278 ASSERT_CRITICAL(false);
279 return GPIO_RESULT_NON_SPECIFIC_ERROR;
282 if (!pin->funcs->open(pin, mode)) {
283 ASSERT_CRITICAL(false);
284 dal_gpio_service_close(service, &pin);
285 return GPIO_RESULT_OPEN_FAILED;
288 set_pin_busy(service, id, en);
290 return GPIO_RESULT_OK;
293 void dal_gpio_service_close(
294 struct gpio_service *service,
295 struct hw_gpio_pin **ptr)
297 struct hw_gpio_pin *pin;
300 ASSERT_CRITICAL(false);
307 set_pin_free(service, pin->id, pin->en);
309 pin->funcs->close(pin);
311 pin->funcs->destroy(ptr);
316 enum dc_irq_source dal_irq_get_source(
317 const struct gpio *irq)
319 enum gpio_id id = dal_gpio_get_id(irq);
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));
329 return DC_IRQ_SOURCE_INVALID;
333 enum dc_irq_source dal_irq_get_rx_source(
334 const struct gpio *irq)
336 enum gpio_id id = dal_gpio_get_id(irq);
340 return (enum dc_irq_source)(DC_IRQ_SOURCE_HPD1RX +
341 dal_gpio_get_enum(irq));
343 return DC_IRQ_SOURCE_INVALID;
347 enum gpio_result dal_irq_setup_hpd_filter(
349 struct gpio_hpd_config *config)
351 struct gpio_config_data config_data;
354 return GPIO_RESULT_INVALID_DATA;
356 config_data.type = GPIO_CONFIG_TYPE_HPD;
357 config_data.config.hpd = *config;
359 return dal_gpio_set_config(irq, &config_data);
364 * Creation and destruction
367 struct gpio *dal_gpio_create_irq(
368 struct gpio_service *service,
376 case GPIO_ID_GPIO_PAD:
380 ASSERT_CRITICAL(false);
384 irq = dal_gpio_create(
385 service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
390 ASSERT_CRITICAL(false);
394 void dal_gpio_destroy_irq(
398 ASSERT_CRITICAL(false);
402 dal_gpio_close(*irq);
403 dal_gpio_destroy(irq);
409 struct ddc *dal_gpio_create_ddc(
410 struct gpio_service *service,
413 struct gpio_ddc_hw_info *info)
419 if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en))
422 ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL);
429 ddc->pin_data = dal_gpio_create(
430 service, GPIO_ID_DDC_DATA, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
432 if (!ddc->pin_data) {
437 ddc->pin_clock = dal_gpio_create(
438 service, GPIO_ID_DDC_CLOCK, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);
440 if (!ddc->pin_clock) {
445 ddc->hw_info = *info;
447 ddc->ctx = service->ctx;
452 dal_gpio_destroy(&ddc->pin_data);
460 void dal_gpio_destroy_ddc(
469 dal_gpio_destroy(&(*ddc)->pin_data);
470 dal_gpio_destroy(&(*ddc)->pin_clock);
476 enum gpio_result dal_ddc_open(
479 enum gpio_ddc_config_type config_type)
481 enum gpio_result result;
483 struct gpio_config_data config_data;
484 struct hw_gpio *hw_data;
485 struct hw_gpio *hw_clock;
487 result = dal_gpio_open_ex(ddc->pin_data, mode);
489 if (result != GPIO_RESULT_OK) {
494 result = dal_gpio_open_ex(ddc->pin_clock, mode);
496 if (result != GPIO_RESULT_OK) {
501 /* DDC clock and data pins should belong
502 * to the same DDC block id,
503 * we use the data pin to set the pad mode. */
505 if (mode == GPIO_MODE_INPUT)
506 /* this is from detect_sink_type,
507 * we need extra delay there */
508 config_data.type = GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE;
510 config_data.type = GPIO_CONFIG_TYPE_DDC;
512 config_data.config.ddc.type = config_type;
514 hw_data = FROM_HW_GPIO_PIN(ddc->pin_data->pin);
515 hw_clock = FROM_HW_GPIO_PIN(ddc->pin_clock->pin);
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;
520 result = dal_gpio_set_config(ddc->pin_data, &config_data);
522 if (result == GPIO_RESULT_OK)
527 dal_gpio_close(ddc->pin_clock);
530 dal_gpio_close(ddc->pin_data);
535 enum gpio_result dal_ddc_change_mode(
539 enum gpio_result result;
541 enum gpio_mode original_mode =
542 dal_gpio_get_mode(ddc->pin_data);
544 result = dal_gpio_change_mode(ddc->pin_data, mode);
546 /* [anaumov] DAL2 code returns GPIO_RESULT_NON_SPECIFIC_ERROR
547 * in case of failures;
548 * set_mode() is so that, in case of failure,
549 * we must explicitly set original mode */
551 if (result != GPIO_RESULT_OK)
554 result = dal_gpio_change_mode(ddc->pin_clock, mode);
556 if (result == GPIO_RESULT_OK)
559 dal_gpio_change_mode(ddc->pin_clock, original_mode);
562 dal_gpio_change_mode(ddc->pin_data, original_mode);
567 enum gpio_ddc_line dal_ddc_get_line(
568 const struct ddc *ddc)
570 return (enum gpio_ddc_line)dal_gpio_get_enum(ddc->pin_data);
573 enum gpio_result dal_ddc_set_config(
575 enum gpio_ddc_config_type config_type)
577 struct gpio_config_data config_data;
579 config_data.type = GPIO_CONFIG_TYPE_DDC;
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;
585 return dal_gpio_set_config(ddc->pin_data, &config_data);
591 dal_gpio_close(ddc->pin_clock);
592 dal_gpio_close(ddc->pin_data);