1/*
2 *  Driver for the Conexant CX25821 PCIe bridge
3 *
4 *  Copyright (C) 2009 Conexant Systems Inc.
5 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 *  This program is free software; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation; either version 2 of the License, or
10 *  (at your option) any later version.
11 *
12 *  This program is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *
16 *  GNU General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License
19 *  along with this program; if not, write to the Free Software
20 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include "cx25821.h"
25
26/********************* GPIO stuffs *********************/
27void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
28				   int pin_number, int pin_logic_value)
29{
30	int bit = pin_number;
31	u32 gpio_oe_reg = GPIO_LO_OE;
32	u32 gpio_register = 0;
33	u32 value = 0;
34
35	/* Check for valid pinNumber */
36	if (pin_number >= 47)
37		return;
38
39	if (pin_number > 31) {
40		bit = pin_number - 31;
41		gpio_oe_reg = GPIO_HI_OE;
42	}
43	/* Here we will make sure that the GPIOs 0 and 1 are output. keep the
44	 * rest as is */
45	gpio_register = cx_read(gpio_oe_reg);
46
47	if (pin_logic_value == 1)
48		value = gpio_register | Set_GPIO_Bit(bit);
49	else
50		value = gpio_register & Clear_GPIO_Bit(bit);
51
52	cx_write(gpio_oe_reg, value);
53}
54EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
55
56static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
57					   int pin_number, int pin_logic_value)
58{
59	int bit = pin_number;
60	u32 gpio_reg = GPIO_LO;
61	u32 value = 0;
62
63	/* Check for valid pinNumber */
64	if (pin_number >= 47)
65		return;
66
67	/* change to output direction */
68	cx25821_set_gpiopin_direction(dev, pin_number, 0);
69
70	if (pin_number > 31) {
71		bit = pin_number - 31;
72		gpio_reg = GPIO_HI;
73	}
74
75	value = cx_read(gpio_reg);
76
77	if (pin_logic_value == 0)
78		value &= Clear_GPIO_Bit(bit);
79	else
80		value |= Set_GPIO_Bit(bit);
81
82	cx_write(gpio_reg, value);
83}
84
85void cx25821_gpio_init(struct cx25821_dev *dev)
86{
87	if (dev == NULL)
88		return;
89
90	switch (dev->board) {
91	case CX25821_BOARD_CONEXANT_ATHENA10:
92	default:
93		/* set GPIO 5 to select the path for Medusa/Athena */
94		cx25821_set_gpiopin_logicvalue(dev, 5, 1);
95		mdelay(20);
96		break;
97	}
98
99}
100