Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / media / pci / cx25821 / cx25821-gpio.c
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 }