1 /*
2  * Copyright 2012-15 Advanced Micro Devices, Inc.
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
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.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 #include <linux/slab.h>
27 
28 #include "dm_services.h"
29 
30 #include "include/gpio_types.h"
31 #include "hw_gpio.h"
32 #include "hw_generic.h"
33 
34 #include "reg_helper.h"
35 #include "generic_regs.h"
36 
37 #undef FN
38 #define FN(reg_name, field_name) \
39 	generic->shifts->field_name, generic->masks->field_name
40 
41 #define CTX \
42 	generic->base.base.ctx
43 #define REG(reg)\
44 	(generic->regs->reg)
45 
46 static void dal_hw_generic_construct(
47 	struct hw_generic *pin,
48 	enum gpio_id id,
49 	uint32_t en,
50 	struct dc_context *ctx)
51 {
52 	dal_hw_gpio_construct(&pin->base, id, en, ctx);
53 }
54 
55 static void dal_hw_generic_destruct(
56 	struct hw_generic *pin)
57 {
58 	dal_hw_gpio_destruct(&pin->base);
59 }
60 
61 static void destroy(
62 	struct hw_gpio_pin **ptr)
63 {
64 	struct hw_generic *generic = HW_GENERIC_FROM_BASE(*ptr);
65 
66 	dal_hw_generic_destruct(generic);
67 
68 	kfree(generic);
69 
70 	*ptr = NULL;
71 }
72 
73 static enum gpio_result set_config(
74 	struct hw_gpio_pin *ptr,
75 	const struct gpio_config_data *config_data)
76 {
77 	struct hw_generic *generic = HW_GENERIC_FROM_BASE(ptr);
78 
79 	if (!config_data)
80 		return GPIO_RESULT_INVALID_DATA;
81 
82 	REG_UPDATE_2(mux,
83 		GENERIC_EN, config_data->config.generic_mux.enable_output_from_mux,
84 		GENERIC_SEL, config_data->config.generic_mux.mux_select);
85 
86 	return GPIO_RESULT_OK;
87 }
88 
89 static const struct hw_gpio_pin_funcs funcs = {
90 	.destroy = destroy,
91 	.open = dal_hw_gpio_open,
92 	.get_value = dal_hw_gpio_get_value,
93 	.set_value = dal_hw_gpio_set_value,
94 	.set_config = set_config,
95 	.change_mode = dal_hw_gpio_change_mode,
96 	.close = dal_hw_gpio_close,
97 };
98 
99 static void construct(
100 	struct hw_generic *generic,
101 	enum gpio_id id,
102 	uint32_t en,
103 	struct dc_context *ctx)
104 {
105 	dal_hw_generic_construct(generic, id, en, ctx);
106 	generic->base.base.funcs = &funcs;
107 }
108 
109 struct hw_gpio_pin *dal_hw_generic_create(
110 	struct dc_context *ctx,
111 	enum gpio_id id,
112 	uint32_t en)
113 {
114 	struct hw_generic *generic;
115 
116 	if (id != GPIO_ID_GENERIC) {
117 		ASSERT_CRITICAL(false);
118 		return NULL;
119 	}
120 
121 	if ((en < GPIO_GENERIC_MIN) || (en > GPIO_GENERIC_MAX)) {
122 		ASSERT_CRITICAL(false);
123 		return NULL;
124 	}
125 
126 	generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL);
127 	if (!generic) {
128 		ASSERT_CRITICAL(false);
129 		return NULL;
130 	}
131 
132 	construct(generic, id, en, ctx);
133 	return &generic->base.base;
134 }
135