OSDN Git Service

Add rtl8821ce driver version 5.5.2
[android-x86/external-kernel-drivers.git] / rtl8821ce / hal / halmac / halmac_88xx / halmac_gpio_88xx.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2016 - 2018 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15
16 #include "halmac_gpio_88xx.h"
17
18 #if HALMAC_88XX_SUPPORT
19
20 /**
21  * pinmux_wl_led_mode_88xx() -control wlan led gpio function
22  * @adapter : the adapter of halmac
23  * @mode : wlan led mode
24  * Author : Ivan Lin
25  * Return : enum halmac_ret_status
26  * More details of status code can be found in prototype document
27  */
28 enum halmac_ret_status
29 pinmux_wl_led_mode_88xx(struct halmac_adapter *adapter,
30                         enum halmac_wlled_mode mode)
31 {
32         u8 value8;
33         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
34
35         PLTFM_MSG_TRACE("[TRACE]%s ===>\n", __func__);
36
37         value8 = HALMAC_REG_R8(REG_LED_CFG + 2);
38         value8 &= ~(BIT(6));
39         value8 |= BIT(3);
40         value8 &= ~(BIT(0) | BIT(1) | BIT(2));
41
42         switch (mode) {
43         case HALMAC_WLLED_MODE_TRX:
44                 value8 |= 2;
45                 break;
46         case HALMAC_WLLED_MODE_TX:
47                 value8 |= 4;
48                 break;
49         case HALMAC_WLLED_MODE_RX:
50                 value8 |= 6;
51                 break;
52         case HALMAC_WLLED_MODE_SW_CTRL:
53                 value8 |= 0;
54                 break;
55         default:
56                 return HALMAC_RET_SWITCH_CASE_ERROR;
57         }
58
59         HALMAC_REG_W8(REG_LED_CFG + 2, value8);
60
61         PLTFM_MSG_TRACE("[TRACE]%s <===\n", __func__);
62
63         return HALMAC_RET_SUCCESS;
64 }
65
66 /**
67  * pinmux_wl_led_sw_ctrl_88xx() -control wlan led on/off
68  * @adapter : the adapter of halmac
69  * @on : on(1), off(0)
70  * Author : Ivan Lin
71  * Return : enum halmac_ret_status
72  * More details of status code can be found in prototype document
73  */
74 void
75 pinmux_wl_led_sw_ctrl_88xx(struct halmac_adapter *adapter, u8 on)
76 {
77         u8 value8;
78         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
79
80         value8 = HALMAC_REG_R8(REG_LED_CFG + 2);
81         value8 = (on == 0) ? value8 | BIT(3) : value8 & ~(BIT(3));
82
83         HALMAC_REG_W8(REG_LED_CFG + 2, value8);
84 }
85
86 /**
87  * pinmux_sdio_int_polarity_88xx() -control sdio int polarity
88  * @adapter : the adapter of halmac
89  * @low_active : low active(1), high active(0)
90  * Author : Ivan Lin
91  * Return : enum halmac_ret_status
92  * More details of status code can be found in prototype document
93  */
94 void
95 pinmux_sdio_int_polarity_88xx(struct halmac_adapter *adapter, u8 low_active)
96 {
97         u8 value8;
98         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
99
100         value8 = HALMAC_REG_R8(REG_SYS_SDIO_CTRL + 2);
101         value8 = (low_active == 0) ? value8 | BIT(3) : value8 & ~(BIT(3));
102
103         HALMAC_REG_W8(REG_SYS_SDIO_CTRL + 2, value8);
104 }
105
106 /**
107  * pinmux_gpio_mode_88xx() -control gpio io mode
108  * @adapter : the adapter of halmac
109  * @gpio_id : gpio0~15(0~15)
110  * @output : output(1), input(0)
111  * Author : Ivan Lin
112  * Return : enum halmac_ret_status
113  * More details of status code can be found in prototype document
114  */
115 enum halmac_ret_status
116 pinmux_gpio_mode_88xx(struct halmac_adapter *adapter, u8 gpio_id, u8 output)
117 {
118         u16 value16;
119         u8 in_out;
120         u32 offset;
121         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
122
123         if (gpio_id <= 7)
124                 offset = REG_GPIO_PIN_CTRL + 2;
125         else if (gpio_id >= 8 && gpio_id <= 15)
126                 offset = REG_GPIO_EXT_CTRL + 2;
127         else
128                 return HALMAC_RET_WRONG_GPIO;
129
130         in_out = (output == 0) ? 0 : 1;
131         gpio_id &= (8 - 1);
132
133         value16 = HALMAC_REG_R16(offset);
134         value16 &= ~((1 << gpio_id) | (1 << gpio_id << 8));
135         value16 |= (in_out << gpio_id);
136         HALMAC_REG_W16(offset, value16);
137
138         return HALMAC_RET_SUCCESS;
139 }
140
141 /**
142  * pinmux_gpio_output_88xx() -control gpio output high/low
143  * @adapter : the adapter of halmac
144  * @gpio_id : gpio0~15(0~15)
145  * @high : high(1), low(0)
146  * Author : Ivan Lin
147  * Return : enum halmac_ret_status
148  * More details of status code can be found in prototype document
149  */
150 enum halmac_ret_status
151 pinmux_gpio_output_88xx(struct halmac_adapter *adapter, u8 gpio_id, u8 high)
152 {
153         u8 value8;
154         u8 hi_low;
155         u32 offset;
156         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
157
158         if (gpio_id <= 7)
159                 offset = REG_GPIO_PIN_CTRL + 1;
160         else if (gpio_id >= 8 && gpio_id <= 15)
161                 offset = REG_GPIO_EXT_CTRL + 1;
162         else
163                 return HALMAC_RET_WRONG_GPIO;
164
165         hi_low = (high == 0) ? 0 : 1;
166         gpio_id &= (8 - 1);
167
168         value8 = HALMAC_REG_R8(offset);
169         value8 &= ~(1 << gpio_id);
170         value8 |= (hi_low << gpio_id);
171         HALMAC_REG_W8(offset, value8);
172
173         return HALMAC_RET_SUCCESS;
174 }
175
176 /**
177  * halmac_pinmux_status_88xx() -get current gpio status(high/low)
178  * @adapter : the adapter of halmac
179  * @pin_id : 0~15(0~15)
180  * @phigh : high(1), low(0)
181  * Author : Ivan Lin
182  * Return : enum halmac_ret_status
183  * More details of status code can be found in prototype document
184  */
185 enum halmac_ret_status
186 pinmux_pin_status_88xx(struct halmac_adapter *adapter, u8 pin_id, u8 *high)
187 {
188         u8 value8;
189         u32 offset;
190         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
191
192         if (pin_id <= 7)
193                 offset = REG_GPIO_PIN_CTRL;
194         else if (pin_id >= 8 && pin_id <= 15)
195                 offset = REG_GPIO_EXT_CTRL;
196         else
197                 return HALMAC_RET_WRONG_GPIO;
198
199         pin_id &= (8 - 1);
200
201         value8 = HALMAC_REG_R8(offset);
202         *high = (value8 & (1 << pin_id)) >> pin_id;
203
204         return HALMAC_RET_SUCCESS;
205 }
206
207 enum halmac_ret_status
208 pinmux_parser_88xx(struct halmac_adapter *adapter,
209                    const struct halmac_gpio_pimux_list *list, u32 size,
210                    u32 gpio_id, u32 *cur_func)
211 {
212         u32 i;
213         u8 value8;
214         const struct halmac_gpio_pimux_list *cur_list = list;
215         enum halmac_gpio_cfg_state *state;
216         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
217
218         state = &adapter->halmac_state.gpio_cfg_state;
219
220         if (*state == HALMAC_GPIO_CFG_STATE_BUSY)
221                 return HALMAC_RET_BUSY_STATE;
222
223         *state = HALMAC_GPIO_CFG_STATE_BUSY;
224
225         for (i = 0; i < size; i++) {
226                 if (gpio_id != cur_list->id) {
227                         PLTFM_MSG_ERR("[ERR]offset:%X, value:%X, func:%X\n",
228                                       cur_list->offset, cur_list->value,
229                                       cur_list->func);
230                         PLTFM_MSG_ERR("[ERR]id1 : %X, id2 : %X\n",
231                                       gpio_id, cur_list->id);
232                         *state = HALMAC_GPIO_CFG_STATE_IDLE;
233                         return HALMAC_RET_GET_PINMUX_ERR;
234                 }
235                 value8 = HALMAC_REG_R8(cur_list->offset);
236                 value8 &= cur_list->msk;
237                 if (value8 == cur_list->value) {
238                         *cur_func = cur_list->func;
239                         break;
240                 }
241                 cur_list++;
242         }
243
244         *state = HALMAC_GPIO_CFG_STATE_IDLE;
245
246         if (i == size)
247                 return HALMAC_RET_GET_PINMUX_ERR;
248
249         return HALMAC_RET_SUCCESS;
250 }
251
252 enum halmac_ret_status
253 pinmux_switch_88xx(struct halmac_adapter *adapter,
254                    const struct halmac_gpio_pimux_list *list, u32 size,
255                    u32 gpio_id, enum halmac_gpio_func gpio_func)
256 {
257         u32 i;
258         u8 value8;
259         u16 switch_func;
260         const struct halmac_gpio_pimux_list *cur_list = list;
261         enum halmac_gpio_cfg_state *state;
262         struct halmac_api *api = (struct halmac_api *)adapter->halmac_api;
263
264         state = &adapter->halmac_state.gpio_cfg_state;
265
266         if (*state == HALMAC_GPIO_CFG_STATE_BUSY)
267                 return HALMAC_RET_BUSY_STATE;
268
269         switch (gpio_func) {
270         case HALMAC_GPIO_FUNC_WL_LED:
271                 switch_func = HALMAC_WL_LED;
272                 break;
273         case HALMAC_GPIO_FUNC_SDIO_INT:
274                 switch_func = HALMAC_SDIO_INT;
275                 break;
276         case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
277         case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
278                 switch_func = HALMAC_GPIO13_14_WL_CTRL_EN;
279                 break;
280         case HALMAC_GPIO_FUNC_SW_IO_0:
281         case HALMAC_GPIO_FUNC_SW_IO_1:
282         case HALMAC_GPIO_FUNC_SW_IO_2:
283         case HALMAC_GPIO_FUNC_SW_IO_3:
284         case HALMAC_GPIO_FUNC_SW_IO_4:
285         case HALMAC_GPIO_FUNC_SW_IO_5:
286         case HALMAC_GPIO_FUNC_SW_IO_6:
287         case HALMAC_GPIO_FUNC_SW_IO_7:
288         case HALMAC_GPIO_FUNC_SW_IO_8:
289         case HALMAC_GPIO_FUNC_SW_IO_9:
290         case HALMAC_GPIO_FUNC_SW_IO_10:
291         case HALMAC_GPIO_FUNC_SW_IO_11:
292         case HALMAC_GPIO_FUNC_SW_IO_12:
293         case HALMAC_GPIO_FUNC_SW_IO_13:
294         case HALMAC_GPIO_FUNC_SW_IO_14:
295         case HALMAC_GPIO_FUNC_SW_IO_15:
296                 switch_func = HALMAC_SW_IO;
297                 break;
298         default:
299                 return HALMAC_RET_SWITCH_CASE_ERROR;
300         }
301
302         for (i = 0; i < size; i++) {
303                 if (gpio_id != cur_list->id) {
304                         PLTFM_MSG_ERR("[ERR]offset:%X, value:%X, func:%X\n",
305                                       cur_list->offset, cur_list->value,
306                                       cur_list->func);
307                         PLTFM_MSG_ERR("[ERR]id1 : %X, id2 : %X\n",
308                                       gpio_id, cur_list->id);
309                         return HALMAC_RET_GET_PINMUX_ERR;
310                 }
311
312                 if (switch_func == cur_list->func)
313                         break;
314
315                 cur_list++;
316         }
317
318         if (i == size) {
319                 PLTFM_MSG_ERR("[ERR]gpio func error:%X %X\n",
320                               gpio_id, cur_list->id);
321                 return HALMAC_RET_GET_PINMUX_ERR;
322         }
323
324         *state = HALMAC_GPIO_CFG_STATE_BUSY;
325
326         cur_list = list;
327         for (i = 0; i < size; i++) {
328                 value8 = HALMAC_REG_R8(cur_list->offset);
329                 value8 &= ~(cur_list->msk);
330
331                 if (switch_func == cur_list->func) {
332                         value8 |= (cur_list->value & cur_list->msk);
333                         HALMAC_REG_W8(cur_list->offset, value8);
334                         break;
335                 }
336
337                 value8 |= (~cur_list->value & cur_list->msk);
338                 HALMAC_REG_W8(cur_list->offset, value8);
339
340                 cur_list++;
341         }
342
343         *state = HALMAC_GPIO_CFG_STATE_IDLE;
344
345         return HALMAC_RET_SUCCESS;
346 }
347
348 enum halmac_ret_status
349 pinmux_record_88xx(struct halmac_adapter *adapter,
350                    enum halmac_gpio_func gpio_func, u8 val)
351 {
352         switch (gpio_func) {
353         case HALMAC_GPIO_FUNC_WL_LED:
354                 adapter->pinmux_info.wl_led = val;
355                 break;
356         case HALMAC_GPIO_FUNC_SDIO_INT:
357                 adapter->pinmux_info.sdio_int = val;
358                 break;
359         case HALMAC_GPIO_FUNC_BT_HOST_WAKE1:
360                 adapter->pinmux_info.bt_host_wake = val;
361                 break;
362         case HALMAC_GPIO_FUNC_BT_DEV_WAKE1:
363                 adapter->pinmux_info.bt_dev_wake = val;
364                 break;
365         case HALMAC_GPIO_FUNC_SW_IO_0:
366                 adapter->pinmux_info.sw_io_0 = val;
367                 break;
368         case HALMAC_GPIO_FUNC_SW_IO_1:
369                 adapter->pinmux_info.sw_io_1 = val;
370                 break;
371         case HALMAC_GPIO_FUNC_SW_IO_2:
372                 adapter->pinmux_info.sw_io_2 = val;
373                 break;
374         case HALMAC_GPIO_FUNC_SW_IO_3:
375                 adapter->pinmux_info.sw_io_3 = val;
376                 break;
377         case HALMAC_GPIO_FUNC_SW_IO_4:
378                 adapter->pinmux_info.sw_io_4 = val;
379                 break;
380         case HALMAC_GPIO_FUNC_SW_IO_5:
381                 adapter->pinmux_info.sw_io_5 = val;
382                 break;
383         case HALMAC_GPIO_FUNC_SW_IO_6:
384                 adapter->pinmux_info.sw_io_6 = val;
385                 break;
386         case HALMAC_GPIO_FUNC_SW_IO_7:
387                 adapter->pinmux_info.sw_io_7 = val;
388                 break;
389         case HALMAC_GPIO_FUNC_SW_IO_8:
390                 adapter->pinmux_info.sw_io_8 = val;
391                 break;
392         case HALMAC_GPIO_FUNC_SW_IO_9:
393                 adapter->pinmux_info.sw_io_9 = val;
394                 break;
395         case HALMAC_GPIO_FUNC_SW_IO_10:
396                 adapter->pinmux_info.sw_io_10 = val;
397                 break;
398         case HALMAC_GPIO_FUNC_SW_IO_11:
399                 adapter->pinmux_info.sw_io_11 = val;
400                 break;
401         case HALMAC_GPIO_FUNC_SW_IO_12:
402                 adapter->pinmux_info.sw_io_12 = val;
403                 break;
404         case HALMAC_GPIO_FUNC_SW_IO_13:
405                 adapter->pinmux_info.sw_io_13 = val;
406                 break;
407         case HALMAC_GPIO_FUNC_SW_IO_14:
408                 adapter->pinmux_info.sw_io_14 = val;
409                 break;
410         case HALMAC_GPIO_FUNC_SW_IO_15:
411                 adapter->pinmux_info.sw_io_15 = val;
412                 break;
413         default:
414                 return HALMAC_RET_GET_PINMUX_ERR;
415         }
416
417         return HALMAC_RET_SUCCESS;
418 }
419
420 #endif /* HALMAC_88XX_SUPPORT */