1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Driver for the Conexant CX25821 PCIe bridge
4  *
5  *  Copyright (C) 2009 Conexant Systems Inc.
6  *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
7  */
8 
9 #include <linux/module.h>
10 #include "cx25821.h"
11 
12 /********************* GPIO stuffs *********************/
13 void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
14 				   int pin_number, int pin_logic_value)
15 {
16 	int bit = pin_number;
17 	u32 gpio_oe_reg = GPIO_LO_OE;
18 	u32 gpio_register = 0;
19 	u32 value = 0;
20 
21 	/* Check for valid pinNumber */
22 	if (pin_number >= 47)
23 		return;
24 
25 	if (pin_number > 31) {
26 		bit = pin_number - 31;
27 		gpio_oe_reg = GPIO_HI_OE;
28 	}
29 	/* Here we will make sure that the GPIOs 0 and 1 are output. keep the
30 	 * rest as is */
31 	gpio_register = cx_read(gpio_oe_reg);
32 
33 	if (pin_logic_value == 1)
34 		value = gpio_register | Set_GPIO_Bit(bit);
35 	else
36 		value = gpio_register & Clear_GPIO_Bit(bit);
37 
38 	cx_write(gpio_oe_reg, value);
39 }
40 EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
41 
42 static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
43 					   int pin_number, int pin_logic_value)
44 {
45 	int bit = pin_number;
46 	u32 gpio_reg = GPIO_LO;
47 	u32 value = 0;
48 
49 	/* Check for valid pinNumber */
50 	if (pin_number >= 47)
51 		return;
52 
53 	/* change to output direction */
54 	cx25821_set_gpiopin_direction(dev, pin_number, 0);
55 
56 	if (pin_number > 31) {
57 		bit = pin_number - 31;
58 		gpio_reg = GPIO_HI;
59 	}
60 
61 	value = cx_read(gpio_reg);
62 
63 	if (pin_logic_value == 0)
64 		value &= Clear_GPIO_Bit(bit);
65 	else
66 		value |= Set_GPIO_Bit(bit);
67 
68 	cx_write(gpio_reg, value);
69 }
70 
71 void cx25821_gpio_init(struct cx25821_dev *dev)
72 {
73 	if (dev == NULL)
74 		return;
75 
76 	switch (dev->board) {
77 	case CX25821_BOARD_CONEXANT_ATHENA10:
78 	default:
79 		/* set GPIO 5 to select the path for Medusa/Athena */
80 		cx25821_set_gpiopin_logicvalue(dev, 5, 1);
81 		msleep(20);
82 		break;
83 	}
84 
85 }
86